pax_global_header00006660000000000000000000000064136153146350014521gustar00rootroot0000000000000052 comment=17c9a343229639521b16102e12d52778003a8efa dwarfutils-20200114/000077500000000000000000000000001361531463500141405ustar00rootroot00000000000000dwarfutils-20200114/AUTHORS000066400000000000000000000000451361531463500152070ustar00rootroot00000000000000David Anderson Carlos Alberto Enciso dwarfutils-20200114/CMakeLists.txt000066400000000000000000000313121361531463500167000ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.2) project(libdwarf C CXX) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include_directories( ${CMAKE_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 snprintf=_snprintf) endif() endmacro() # set target folder on IDE macro(set_folder target folder) set_target_properties(${target} PROPERTIES FOLDER ${folder}) endmacro() # set source groups on IDE macro(set_source_group list_name group_name) set(${list_name} ${ARGN}) source_group(${group_name} FILES ${ARGN}) endmacro() # view folders on supported IDEs set_property(GLOBAL PROPERTY USE_FOLDERS ON) # used when finding libelf # tells cmake to look in 64bit first (cmake # 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) include(CheckIncludeFile) include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckSymbolExists) set(VERSION 20191022) set(PACKAGE_VERSION "\"${VERSION}\"") set(PACKAGE_NAME "libdwarf" ) ###set(VERSION ${PACKAGE_VERSION} ) set(PACKAGE_STRING "\"${PACKAGE_NAME} ${VERSION}\"") string(REGEX REPLACE "[\"]" "" tarname1 "${PACKAGE_STRING}" ) string(REGEX REPLACE "[^a-zA-Z0-9_]" "-" tarname "${tarname1}" ) set(PACKAGE_TARNAME "\"${tarname}\"" ) ###set(PACKAGE_VERSION "\"${PACKAGE_VERSION}\"") test_big_endian(isBigEndian) if (${isBigEndian}) 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( "stdlib.h" HAVE_STDLIB_H ) check_include_file( "string.h" HAVE_STRING_H ) check_include_file( "memory.h" HAVE_MEMORY_H ) check_include_file( "strings.h" HAVE_STRINGS_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 ) check_include_file( "stdafx.h" HAVE_STDAFX_H ) check_include_file( "Windows.h" HAVE_WINDOWS_H ) check_include_file( "elf.h" HAVE_ELF_H ) check_include_file( "libelf.h" HAVE_LIBELF_H ) check_include_file( "libelf/libelf.h" HAVE_LIBELF_LIBELF_H) check_include_file( "alloca.h" HAVE_ALLOCA_H ) check_include_file( "elfaccess.h" HAVE_ELFACCESS_H) check_include_file( "sys/elf_386.h" HAVE_SYS_ELF_386_H ) check_include_file( "sys/elf_amd64.h" HAVE_SYS_ELF_AMD64_H) check_include_file( "sys/elf_sparc.h" HAVE_SYS_ELF_SPARC_H) check_include_file( "sys/ia64/elf.h" HAVE_SYS_IA64_ELF_H ) 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() # It's not really setting the location of libelfheader, # it is really # either elf.h, or if that is missing # it is assuming elf.h data is in the supplied libelf. if(HAVE_ELF_H) set(HAVE_LOCATION_OF_LIBELFHEADER "") elseif(HAVE_LIBELF_H) set(HAVE_LOCATION_OF_LIBELFHEADER "") elseif(HAVE_LIBELF_LIBELF_H) set(HAVE_LOCATION_OF_LIBELFHEADER "") endif() if(HAVE_LIBELF_H) set(JUST_LIBELF "") set(PLAIN_JUST_LIBELF "libelf.h") elseif(HAVE_LIBELF_LIBELF_H) set(JUST_LIBELF "") set(PLAIN_JUST_LIBELF "libelf/libelf.h") endif() if (HAVE_LIBELF_H OR HAVE_LIBELF_LIBELF_H) set (CMAKE_REQUIRED_LIBRARIES elf) message(STATUS "libelf header ${PLAIN_JUST_LIBELF} checking for elf64_getehdr") check_symbol_exists( elf64_getehdr ${PLAIN_JUST_LIBELF} HAVE_ELF64_GETEHDR) message(STATUS "libelf header ${PLAIN_JUST_LIBELF} checking for elf64_getshdr") check_symbol_exists( elf64_getshdr ${PLAIN_JUST_LIBELF} HAVE_ELF64_GETSHDR) set (CMAKE_REQUIRED_LIBRARIES) endif() option(DWARF_WITH_LIBELF "Use libelf (default is YES)" TRUE) message(STATUS "Building using libelf... ${DWARF_WITH_LIBELF}") if (DWARF_WITH_LIBELF AND NOT HAVE_LIBELF_H AND NOT HAVE_LIBELF_LIBELF_H) set(DWARF_WITH_LIBELF OFF) endif () if (DWARF_WITH_LIBELF) message(STATUS "checking using HAVE_ELF_H ... ${HAVE_ELF_H}") message(STATUS "checking using elf header ... ${HAVE_LOCATION_OF_LIBELFHEADER}") message(STATUS "checking using libelf header ... ${JUST_LIBELF}") check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { Elf64_Rel *p; int i; i = p->r_info; return 0; }" HAVE_ELF64_R_INFO) check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { Elf64_Rela p; p.r_offset = 1; return 0; }" HAVE_ELF64_RELA) check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { Elf64_Sym p; p.st_info = 1; return 0; }" HAVE_ELF64_SYM) check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { int p; p = 0; return 0; }" HAVE_RAW_LIBELF_OK) # This is attempting do determine that with GNU_SOURCE # we have off64_t. The autoconf version is not attemping # to set HAVE_LIBELF_OFF64_OK at present. check_c_source_compiles(" #define _GNU_SOURCE 1 #include ${JUST_LIBELF} int main() { off64_t p; p = 0; return 0; }" HAVE_LIBELF_OFF64_OK) check_c_source_compiles(" #include ${JUST_LIBELF} /* This must be at global scope */ struct _Elf; typedef struct _Elf Elf; struct _Elf *a = 0; int main() { int i = 12; return 0; }" HAVE_STRUCT_UNDERSCORE_ELF) endif() message(STATUS "Assuming struct Elf for the default libdwarf.h") # Because cmake treats ; in an interesting way attempting # to read/update/write Elf to _Elf fails badly: semicolons vanish. # So for _Elf use a pre-prepared version. if(HAVE_STRUCT_UNDERSCORE_ELF AND DWARF_WITH_LIBELF) message(STATUS "Found struct _Elf in ${JUST_LIBELF}") message(STATUS "Using struct _Elf in libdwarf.h") configure_file(libdwarf/generated_libdwarf.h.in libdwarf/libdwarf.h COPYONLY) else() configure_file(libdwarf/libdwarf.h.in libdwarf/libdwarf.h COPYONLY) message(STATUS "${JUST_LIBELF} does not have struct _Elf") message(STATUS "Using struct Elf in libdwarf.h") endif() check_c_source_runs(" 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}") # checking for ia 64 types, which might be enums, # using HAVE_R_IA_64_DIR32LSB # to stand in for a small set. check_c_source_compiles(" #include ${HAVE_LOCATION_OF_LIBELFHEADER} int main() { int p; p = R_IA_64_DIR32LSB; return 0; }" HAVE_R_IA_64_DIR32LSB) 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}") check_c_source_compiles([=[ #include #include int main() { int i; regex_t r; int cflags = REG_EXTENDED; const char *s = "abc"; i = regcomp(&r,s,cflags); regfree(&r); return 0; } ]=] HAVE_REGEX) set(CMAKE_REQUIRED_LIBRARIES z) check_c_source_compiles( [=[ #include "zlib.h" 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 ) set(CMAKE_REQUIRED_LIBRARIES) if (HAVE_ZLIB) # For linking in libz set(DW_FZLIB "z") endif() 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 default-disabled shared option(BUILD_SHARED "build shared library libdwarf.so and use it if present" FALSE) option(BUILD_NON_SHARED "build archive library libdwarf.a" TRUE) # This adds compiler option -Wall (gcc compiler warnings) option(WALL "Add -Wall" 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) set(DW_FWALL ${DW_FWALLXX} -Wpointer-arith -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wextra -Wcomment -Wformat -Wpedantic -Wuninitialized -Wno-long-long -Wshadow -Werror ) message(STATUS "Compiler warning options... YES ${DW_FWALL}") else() unset(DW_FWALL ) message(STATUS "Compiler warning options... NO") endif() option(HAVE_CUSTOM_LIBELF "Have a custom libelf library (default is NO)" FALSE) message(STATUS "Including a custom libelf library... ${HAVE_CUSTOM_LIBELF}") option(HAVE_NONSTANDARD_PRINTF_64_FORMAT "Use a special printf format for 64bit (default is NO)" FALSE) message(STATUS "Checking enable non standard printf... ${HAVE_NONSTANDARD_PRINTF_64_FORMAT}") 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 # This changes the gennames option from -s to -t # though in 2019 builds we no longer run gennames. option(NAMES_TABLE "string functions implemented as binary search (default is with C switch)" TRUE) if(NAMES_TABLE) set(dwarf_namestable "-s") else() set(dwarf_namestable "-t") endif() option(HAVE_WINDOWS_PATH "Detect certain Windows paths as full paths (default is NO)" FALSE) message(STATUS "Checking enable windows path... ${HAVE_WINDOWS_PATH}") option(HAVE_OLD_FRAME_CFA_COL "Use HAVE_OLD_FRAME_CFA_COL (default is to use new DW_FRAME_CFA_COL3)" FALSE) message(STATUS "Checking enable old frame columns... ${HAVE_OLD_FRAME_CFA_COL}") # See pro_init(), HAVE_DWARF2_99_EXTENSION also generates # 32bit offset dwarf unless DW_DLC_OFFSET_SIZE_64 flag passed to # pro_init. option(HAVE_SGI_IRIX_OFFSETS "Force producer to SGI IRIX offset dwarf" FALSE) message(STATUS "Checking producer generates SGI IRIX output... ${HAVE_SGI_IRIX_OFFSETS}") option(HAVE_STRICT_DWARF2_32BIT_OFFSET "Force producer to generate only DWARF format 32bit" FALSE) set(HAVE_DWARF2_99_EXTENSION NOT ${HAVE_STRICT_DWARF2_32BIT_OFFSET}) message(STATUS "Checking producer generates only 32bit... ${HAVE_STRICT_DWARF2_32BIT_OFFSET}") # This references cmake/FindLibElf.cmake. See cmake documentation. find_package(LibElf REQUIRED) list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBELF_INCLUDE_DIRS}) configure_file(config.h.in.cmake config.h) if(BUILD_NON_SHARED) set(DWARF_TARGETS dwarf-static) set(DWARF_TYPES STATIC) set(dwarf-target dwarf-static) endif() if(BUILD_SHARED) list(APPEND DWARF_TARGETS dwarf-shared) list(APPEND DWARF_TYPES SHARED) set(dwarf-target dwarf-shared) endif() add_subdirectory(libdwarf) add_subdirectory(dwarfdump) if ( BUILD_DWARFGEN ) if ( DWARF_WITH_LIBELF ) add_subdirectory(dwarfgen) else () message(STATUS "Not building dwarfgen because libelf is not available" ) endif () endif() if ( BUILD_DWARFEXAMPLE ) add_subdirectory(dwarfexample) endif() message(STATUS "Install prefix ... ${CMAKE_INSTALL_PREFIX}" ) add_custom_target(dd DEPENDS ${DWARF_TARGETS} dwarfdump) dwarfutils-20200114/COPYING000066400000000000000000000010341361531463500151710ustar00rootroot00000000000000 COPYING June 23 2018 The source code in the libdwarf directory is LGPL version 2.1. See libdwarf/LIBDWARFCOPYRIGHT libdwarf/LGPL.txt The source code in the dwarfdump directory is generally GPL version 2. See dwarfdump/COPYING dwarfdump/DWARFDUMPCOPYRIGHT dwarfdump/GPL.txt a The source code in the dwarfgen directory has the BSD3 copyright. See dwarfgen/COPYING The source code in the dwarfexample has the BSD3 copyright. The source code in the tsearch directory has the BSD3 copyright. dwarfutils-20200114/ChangeLog000066400000000000000000000001511361531463500157070ustar00rootroot000000000000002020-01-05 David Anderson * configure.ac: Version string now 20200114 * configure: Regenerated. dwarfutils-20200114/ChangeLog2018000066400000000000000000000074451361531463500162370ustar00rootroot000000000000002018-12-19 David Anderson * configure.ac: Updated version to 20181218. 2018-11-29 David Anderson * configure.ac: Updated version to 20181129. 2018-11-04 David Anderson * configure.ac: Updated version to 20181123. 2018-11-05 David Anderson * configure.ac: Updated version to 20181105. Fixing magic-number dectection for mach-o and pe. 2018-10-23 David Anderson * configure.ac: Updated version to 20181022. 2018-10-20 David Anderson * configure.ac: Updated version to 20181020. 2018-10-15 David Anderson * configure.ac: Updated version to 20181015. * configure: Regenerated. 2018-10-14 David Anderson * configure.ac: Updated version to 20181014. * configure: Regenerated. 2018-09-21 David Anderson * configure.ac: Updated version to 20180920 * Makefile.am: Added tsearch (directory) and configure.cmake to the files put in a 'make dist' distribution so cmake works with a released tar.gz. 2018-09-12 David Anderson * configure.ac: Updated version to 20180912 * configure. Regenerated. Version now 20180912 2018-09-11 David Anderson * configure.ac: Restored the configure option --enable-nonstandardprintf which sets the config.h HAVE_NONSTANDARD_PRINTF_64_FORMAT variable for those needing it. See libdwarf/libdwarf.h.in for its use. * configure. Regenerated. Version now 20180910 2018-09-02 David Anderson * README: noted the example install commands for libelf and zlib work on 18.04 Ubuntu as well as 16.04. * configure.ac: Updated version to 20180901. Corrected a couple of typos in the summary output of configure. * configure: Regenerated. 2018-08-24 David Anderson * README: Moved comments about common build problems to the beginning of the text. Removed trailing whitespace. 2018-08-23 David Anderson * README: Added mention of the aclocal-missing configure/ build problem and the simple action to fix it. 2018-08-21 David Anderson * configure.ac: Version 20180821. --enable-wall did not show up in the output and wound up ignored. * configure: Regenerated. 2018-08-14 David Anderson * configure.ac: Version 20180814. Fixed small Makefile.am omissions in dwarfdump and libdwarf. * configure: Regenerated. 2018-08-09 David Anderson * configure.ac: Version 20180809 * configure: Regenerated. 2018-08-06 David Anderson * configure.ac: Version now 20180808. * Makefile.am: Corrected references to runtest.sh * configure: Regenerated. 2018-08-06 David Anderson * configure.ac: Version now 20180806. 2018-08-05 David Anderson * configure.ac: Version now 20180805. * configure: Regenerated. 2018-08-02 David Anderson * configure.ac: Deleted unneeded variables. Now env vars like CFLAGS work in standard fashion. Updated version to 20180801 * configure: Regenerated 2018-08-02 David Anderson * README: Added and corrected some details of the new configure. 2018-07-31 David Anderson * configure.ac: Fix the .so version number fields to be 1 0 0, not 1 5 0 version is now hand typed in, not generated by current date * Makefile.am: Now reflects renaming of CPLIBDWARFTAR to CPTARTOWEBDIR add runtests.sh to files in distribution * configure: regenerated 2018-07-23 David Anderson * configure.ac: Reintroduced CXX -wno-long-long to avoid spurious warnings from C++ when using --enable-wall. * configure: Regenerated. 2018-07-22 David Anderson * configure.ac: Complete the handling of --enable-sanitize. 2018-07-19 David Anderson * NEWS, README: Updated to match the new configure code. * configure.ac: Now configure is created by autoreconf -vif and the only configure.ac is here in the same directory as this ChangeLog. dwarfutils-20200114/INSTALL000066400000000000000000000366141361531463500152030ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. dwarfutils-20200114/Makefile.am000066400000000000000000000042601361531463500161760ustar00rootroot00000000000000###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_DWARFGEN_TRUE@am__append_1 = dwarfgen ###if HAVE_LIBELF ###SUBDIRS += dwarfgen ###endif ###if HAVE_LIBELF_LIBELF ###SUBDIRS += dwarfgen ###endif @HAVE_DWARFEXAMPLE_TRUE@am__append_2 = dwarfexample subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = libdwarf dwarfdump dwarfgen dwarfexample am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ COPYING ChangeLog INSTALL NEWS README ar-lib compile \ config.guess config.sub install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = libdwarf dwarfdump $(am__append_1) $(am__append_2) DISTCLEANFILES = \ libdwarf/libdwarf.h MAINTAINERCLEANFILES = \ Makefile.in \ aclocal.m4 \ ar-lib \ compile \ config.guess \ config.h.in \ config.h.in~ \ config.sub \ configure \ depcomp \ install-sh \ ltmain.sh \ m4/libtool.m4 \ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ m4/lt~obsolete.m4 \ missing \ $(distdir).tar.gz \ $(distdir).tar.xz EXTRA_DIST = \ appveyor.yml \ bugxml \ ChangeLog \ ChangeLog2018 \ cmake \ CMakeLists.txt \ codingstyle.txt \ config.h.in.cmake \ dwarfdump/runtests.sh \ libdwarf/runtests.sh \ README.md \ scripts/baseconfig.h \ scripts/BLDLIBDWARF \ scripts/BLDLIBDWARFTAR \ scripts/BLDTESTDIR \ scripts/buildandreleasetest.sh \ scripts/buildstandardsource.sh \ scripts/ChangeLog \ scripts/ChangeLog2018 \ scripts/CLEANUP \ scripts/conddef.py \ scripts/CPTARTOWEBDIR \ scripts/CPTOPUBLIC \ scripts/CREATINGARELEASE \ scripts/dateorder \ scripts/ddbuild.sh \ scripts/FIX-CONFIGURE-TIMES \ scripts/fixlibdwarfelf.sh \ scripts/funcfinderhdr.py \ scripts/funcfindermm.py \ scripts/funcfindersrcs.py \ scripts/GETTOTOP \ scripts/libbuild.sh \ scripts/REBLDLIBDWARF \ scripts/RUNPY \ scripts/SETUP_MASTER_TREE \ scripts/UPDATEDWARFDUMPVERSION.sh \ scripts/UPD.awk \ tsearch/ChangeLog \ tsearch/ChangeLog2014 \ tsearch/ChangeLog2015 \ tsearch/ChangeLog2016 \ tsearch/ChangeLog2017 \ tsearch/ChangeLog2018 \ tsearch/config.h \ tsearch/dwarf_incl.h \ tsearch/dwarf_tsearchbal.c \ tsearch/dwarf_tsearchbin.c \ tsearch/dwarf_tsearch.c \ tsearch/dwarf_tsearchepp.c \ tsearch/dwarf_tsearch.h \ tsearch/dwarf_tsearchhash.c \ tsearch/dwarf_tsearchred.c \ tsearch/ESSAY.txt \ tsearch/Makefile \ tsearch/README \ tsearch/RUNTEST \ tsearch/scripts \ tsearch/tsearch.c \ tsearch/tsearchlibtimes.csv \ tsearch/tsearchlibtimes.ods \ tsearch/tsearch_tester.c all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am .PRECIOUS: Makefile # AUTHORS, ChangeLog and COPYING must be present # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dwarfutils-20200114/NEWS000066400000000000000000000150331361531463500146410ustar00rootroot000000000000002019-11-04: The code (dwarfdump/libdwarf), regressiontests, and readelfobj directories and all their tests are known to work on Linux(Ubuntu on x86_64 and i686), FreeBSD, MacOS Catalina (with Apple Command Line Tools), and IBM s390 (Big Endian!) running Ubuntu Linux. On Windows-MinGW the full regression tests have not been tested, but 'make check' works for dwarfdump/libdwarf (the current dwarfdump make check actually does run dwarfdump and checks that dwarfdump basically works). 2019-04-16: Now a --disable-libelf configure/build of libdwarf/dwarfdump can read elf, mach-o DSYM, and PE executable/dll object files. Such a build will not need or use libelf or elf.h . The dwarfdump options that display Elf section headers or relocation record data are not available in a --disable-libelf build. Nor is dwarfdump's support of reading archive files available in a --disable-libelf build. This libdwarf detects corrupt Elf object files much sooner than before, but does not explain what the corruption really is. Use GNU readelf (or readelfobj, a project on sourceforge) to get more detail about the problems found. See https://www.prevanders.net/dwarf.html for the git clone command for readelfobj. With --disable-libelf the --enable-dwarfgen option does not work: the dwarfgen build will fail. 2019-02-18: For building on machines without a usable elf.h or libelf but possibly with a libelf.h visible, --disable-libelf ensures the build won't use libelf or elf.h anywhere. -lz will be done if zlib.h is visible, independent of libelf, libelf.h, and elf.h 2019-02-08: If one has a standard Bourne shell (sh) available (such as sh on MacOS and sh in MinGW on Windows) one may be able to build libdwarf and dwarfdump natively and they can read Mach-o dSYM and PE object files to access DWARF information. This has NOT been tested under MacOS, so will likely fail on MacOS. No elf.h, libelf.h or zlib.h should be present. For example, the following is known to work under MinGW and this general plan applies to all builds including all builds with elf.h and libelf: mkdir test cd test #(copy the source tree into test, if from git #the name of the top level will likely be 'code') cd code sh -x scripts/FIX-CONFIGURE-TIMES cd .. mkdir bld cd bld ../code/configure (choose your preferred options here) make 2019-01-15: The pre-build dwarf_names.[hc] and the tag related files are now part of the standard build so there is no longer any two-stage aspect of the build. The build simply compiles files in the distribution. If you use git to access the source be sure to sh scripts/FIX-CONFIGURE-TIMES to adjust the file timestamps as having timestamps in the right relationships is vital and git does not maintain timestamps. The script is always safe to run. It takes about 30 seconds. 2018-12-22: The complicated process of building certain .c and .h files has been relegated to the few people updating files libdwarf/libdwarf.h.in, libdwarf/dwarf_errmsg_list.h, dwarfdump/tag_attr_ext.list,dwarfdump/tag_attr.list, dwarfdump/tag_tree_ext.list, and dwarfdump/tag_tree.list. For everyone else the build is simply compiling the .c and .h files in the distribution. Simpler. sh scripts/buildstandardsource.sh creates these files. 2018-10-22: dwarfdump can now dump mach-o (MacOS) dSYM dwarf. All the usual libdwarf interfaces work. A new libdwarf initialization call dwarf_init_path() may be convenient for you to use. 2018-08-05: dwarfdump.conf is now installed by make install in /shared/libdwarf/dwarfdump . Any dwarfdump.conf or .dwarfdump.conf in your $HOME directory will be found before the one in shared. The file is only opened when one wants a more accurate register naming in frame reports (the default is just to name things r54 etc, choosing the right abi with -x abi= can be helpful at times). 2018-06-24: The configure has been completely rewritten to follow current standards and practices. For simple builds the standard ./configure make works as always, but the generated libdwarf.a appears in libdwarf/.libs/libdwarf.a , as does the shared object if "./configure --enable-shared" is used. To build dwarfgen one adds the configure option --enable-dwarfgen instead of using 'make all'. To build the example code one adds the configure option --enable-dwarfexample instead of using 'make all'. "mkdir /tmp/bld ; cd /tmp/bld ; /configure" continues to work, as does configure --host= . 2018-06-14: A small simplification of build options simplifies building across different environments. If your environment needs to use the non-standard elf_open() call instead of unix/linux open() then do /configure --enable-elf-open which sets HAVE_ELF_OPEN in config.h. 2018-03-27: All the DWARF5 FORMs appear to be dealt with. It's now possible to cross-compile libdwarf and dwarfdump. See the README. 2016-11-30: An alternative build mechanism using cmake is now in the source tree. The builds for product testing continue to be done using configure && make. 2016-09-20: --enable-sanitize option added to configure. This builds with -fsanitize=address to check for out of bounds memory access. 2016-09-05: dwarfexample/simpleexample.c now has a simple option letting one extract all .debug_info, .debug_types strings into a file by themselves in case one wanted to examine string frequencies, for example. 2016-06-01: Now we use DW_VERSION_DATE_STR for dates everywhere instead of __DATE__ __TIME__ so a repeated build gets identical object output. DW_VERSION_DATE_STR is updated by UPDATEDWARFDUMPVERSION.sh wherever that string is needed. 2015-11-26: If DWARF section data you intend to read with libdwarf is compressed by zlib (a section name like .zdebug_info indicates such compression) libdwarf etc will need zlib's headers and archive or shared-library at build and link time. If you do not have zlib everything will compile fine and will work on ordinary DWARF sections but libdwarf will not be able to read .zdebug_ compressed sections. zlib.h is the main zlib header and libz.a is the most likely zlib library you will encounter. 2015-11-15: It is now possible to build outside of the source tree. See README. So configure.in changed a little. 2015-01-13: Removed dwarfdump2 and references to it. dwarfdump has the (tsearch) features needed so the C++ version no longer a benefit. dwarfutils-20200114/README000066400000000000000000000207441361531463500150270ustar00rootroot00000000000000As of September 29, 2018 you will find difficulties on FreeBSD 11.2 running make, as default make is not gnu-make compatible. The 2018 configure change to fully use autoconf/automake requires GNU make to build executables. ========== sh scripts/FIX-CONFIGURE-TIMES Because git does not record timestamps and sometimes a copy will lose the timestamps on the build files, it is usually necessary to sh scripts/FIX-CONFIGURE-TIMES at the top of the source tree before using configure. See the example scripts below. ========== BUILD PROBLEM SOLUTION: FIX-CONFIGURE-TIMES Because git does not record timestamps and sometimes a copy will lose the timestamps on the build files, the advice here is something you are likely to need to follow. From the top-level source do sh scripts/FIX-CONFIGURE-TIMES (before running configure) to fix the important timestamps. The command is safe to run at any time. The command checks that it is being run from an appropriate libdwarf top-level directory before doing anything. One clue the script is needed is the following warning. "WARNING: 'aclocal-1.15' is missing on your system." ========= End of aclocal issue... ========== CONFUSING BUILD PROBLEM If you do a full or partial in-source-tree build (see below) and then attempt an out-of-source-tree build you will get very confusing messages about build problems. Just ensure that the source tree is 'clean' (as by 'make distclean' or other means) before you attempt an out-of-source-tree build (see below for details). ========= End of confusing build problem ========= gcc under MinGW on windows The configure option --disable-libelf is no longer needed (but is allowed). Under MinGW the gcc CFLAGS -DHAVE_WINDOWS_H -DHAVE_NONSTANDARD_PRINTF_64_FORMAT \ -fno-dwarf2-cfi-asm have helped some people, though for my MinGW tests these are not necessary or appropriate. We have had success with MinGW without setting CFLAGS with (to save space in this example we do not show checking for errors): The option --enable-wall is optional. src=/path/to/code cd $src sh scripts/FIX-CONFIGURE-TIMES make distclean bld=/tmp/dwbld rm -rf $bld mkdir $bld cd $bld $src/configure --enable-wall \ --disable-libelf --enable-nonstandardprintf make check ========= End ofgcc under MinGW on windows ========= Standard Builds non-Windows Standard builds are done by configure/make as described below. Cross-Compiles are described below, see CROSS COMPILES. One need not --enable-dwarfgen --enable-dwarfexample. The option --enable-wall is also optional. BUILDING in UNIX/Linux src=/path/to/code cd $src sh scripts/FIX-CONFIGURE-TIMES make distclean bld=/tmp/dwbld rm -rf $bld mkdir $bld cd $bld $src/configure --enable-wall --enable-dwarfgen --enable-dwarfexample make check BUILDING in MacOS (tried on Catalina) Same as linux but as standard the Apple Command Line Tools provide no libelf (we don't need it). So the final two steps are: $src/configure --enable-wall --disable-libelf make check ========= End of Standard Builds non-Windows LIBRARY AND HEADER REQUIREMENTS zlib has to be installed to handle zlib compressed sections (common in linux, not normally found with Windows). in Ubuntu 16.04 and 18.04, install using: sudo apt-get install zlib1g zlib1g-dev zlib is available in source from http://zlib.net libelf is available in source from http://www.mr511.de/software/ and https://github.com/vtorri/libelf though libelf is not (as of May 2019) not needed. NOTE: When building out of source tree the source tree must be cleaned of any files created by a build in the source tree (just in case you tried that) before doing the out-of-source build. That's whe examples above do a 'make distclean'. BUILDING ALL THE TOOLS To build all the tools (including dwarfgen and dwarfexample) use a different configure command: ./configure --enable-dwarfgen --enable-dwarfexample ; make To see all the available options to configure do ./configure --help By default configure compiles and uses libdwarf.a. With ./configure --enable-shared both libdwarf.a and libdwarf.so are built. The runtimes built will reference libdwarf.so. With ./configure --enable-shared --disable-nonshared libdwarf.so is built and used; libdwarf.a is not built. THE USUAL ENVIRONMENT VARIABLES The following default to sensible values you may set environment variables as usual with GNU configure. CPPFLAGS CFLAGS LDFLAGS DEBUGGING MAKE To see what compile/link commands are actually being used by the generated Makefiles try V=1, as in make V=1 INSTALL AND UNINSTALL The default install is to /usr/local To change the install location use --prefix. For example: mkdir /tmp/testinst configure --prefix=/tmp/testinst So 'make install' (sudo make install) installs into /usr/local/bin, /usr/local/lib, /usr/local/include, and /usr/local/share/libdwarf. Doing 'make uninstall' (sudo make uninstall) deletes what 'make install' added but does not delete the /usr/local/share/libdwarf directory that the 'make install' created. CHECKING FOR MEMORY CORRUPTION Recent gcc has some checks that can be done at runtime. -fsanitize=address -fsanitize=leak -fsanitize=undefined which are turned on here by '/configure --enable-sanitize'. The --enable-sanitize option unlikely to work when cross-compiling. CROSS-COMPILES For those wishing to build libdwarf (and possibly dwarfdump) for a different host machine than the build machine it is now possible to do that. It has been tested with host and target set to an ARM with build on X86_64. See https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html for standard GNU usage of build, host, and target. See also: https://www.gnu.org/software/autoconf/manual/\ autoconf.html#Specifying-Target-Triplets The autoconf documentation strongly suggests adding --build to the configure commands and in the example below adding --build=i686-pc-linux-gnu is known to work on the test machine. The following is an example. Currently configure figures out the build environment for itself so we don't use --build here. On build machine: sudo apt-get install gcc-arm-linux-gnueabihf # Install libelf and zlib (libz) into # the gcc cross-build tree too. # I cheated: copied from arm machine into # gcc-arm-linux-gnueabihf. mkdir emptycross cd emptycross git clone git://git.code.sf.net/p/libdwarf/code cd code ./configure --host=arm-linux-gnueabihf make # done Doing a build on Ubuntu 18.04 (X86_64 environment) of a 32-bit libdwarf/dwarfdump requires some care. Doing sudo apt install gcc-6-multilib helps. It is a requirement that the build and host machines match with respect to the existence of system headers and of libraries. It seems necessary, in /usr/lib/i386-linux-gnu/ , to sudo cp libelf.so.1 libelf.so so the linker can find 32-bit libelf. In addition, one must build zlib for the host (if you have zlib in the build environment) (see above for the zlib source link) with CFLAGS=-m32 ./configure make sudo cp libz.a /usr/lib/i386-linux-gnu/ sudo cp libz.so /usr/lib/i386-linux-gnu/ #building libdwarf/dwarfdump in the source for no good reason: ./configure --host=i386-linux-gnu \ --build=x86_64-pc-linux-gnu \ CFLAGS="-O2 -m32" ------------------ notes on updating ------ To update configure after hand updating a Makefile.am or the configure.ac do the following command at the top level (where this file is): autoreconf -vif You will need the autotools installed including autoconf, automake, and libtool to run autoreconf. To run the basic checks of libdwarf/dwarfdump, first do ./configure make Then make check A further set of tests is available vi sh scripts/buildandreleasetest.sh which does configure, make check, make install (in temporary directories), make dist, and cmake. This script will not work on Windows. A full set of tests is sh scripts/run-all-tests.sh which requires the regressiontests directory also be present and if readelfobj is present will run its 'make check'. These tests outside the scope of this README. This script will not work on Windows. To create a release file on Linux do: ./configure --enable-dwarfexample --enable-dwarfgen make make dist will generate a libdwarf-yyyymmdd.tar.gz file with the files needed in a release scripts/CPTARTOWEBDIR is an example of generating fingerprints for the release file and copying the file. See the configure.ac for the version used. For example: 'm4_define([v_date], [20190505])])' David Anderson. Updated 7 November 2019 dwarfutils-20200114/README.md000066400000000000000000000015141361531463500154200ustar00rootroot00000000000000[![Travis Build Status](https://travis-ci.org/dvirtz/libdwarf.svg?branch=cmake)](https://travis-ci.org/dvirtz/libdwarf) [![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/oxh8pg7hsuav2jrl?svg=true)](https://ci.appveyor.com/project/dvirtz/libdwarf) # This is README.md ## BUILDING To just build libdwarf and dwarfdump, if the source tree is in `/a/b/libdwarf-1` ### Using CMake August 23 2018 and the following seems to work: rm -rf /tmp/bld mkdir /tmp/bld cd /tmp/bld cmake /a/b/libdwarf-1 # The following does not necessarily work. ? To build using CMake one might do * `cd /a/b/libdwarf-1` * configure: `cmake . -B_Release -DCMAKE_BUILD_TYPE=Release` * build: `cmake --build _Release --target dd` * (optionally install): `sudo cmake --build _Release --target install` # for autotools builds, see README dwarfutils-20200114/aclocal.m4000066400000000000000000001264351361531463500160130ustar00rootroot00000000000000# generated automatically by aclocal 1.15.1 -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/dw_compiler.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) dwarfutils-20200114/appveyor.yml000066400000000000000000000025461361531463500165370ustar00rootroot00000000000000environment: global: LIBELF_INSTALL_PREFIX: "C:/libelf" matrix: - platform: Win32 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015" CMAKE_OPTIONS: "" - platform: Win32 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015" CMAKE_OPTIONS: "-DBUILD_SHARED=ON" - platform: Win32 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015" CMAKE_OPTIONS: "-DBUILD_SHARED=ON -DBUILD_NON_SHARED=OFF" - platform: x64 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64" CMAKE_OPTIONS: "" - platform: x64 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64" CMAKE_OPTIONS: "-DBUILD_SHARED=ON" - platform: x64 CMAKE_GENERATOR_NAME: "Visual Studio 14 2015 Win64" CMAKE_OPTIONS: "-DBUILD_SHARED=ON -DBUILD_NON_SHARED=OFF" configuration: Release install: - git clone https://github.com/dvirtz/libelf.git - cd libelf - git checkout cmake - cmake . -B_build -G "%CMAKE_GENERATOR_NAME%" -DCMAKE_INSTALL_PREFIX=%LIBELF_INSTALL_PREFIX% - cmake --build _build --config %CONFIGURATION% - cmake --build _build --config %CONFIGURATION% --target INSTALL - cd .. build_script: - cmake . -B_build -G "%CMAKE_GENERATOR_NAME%" -DLIBELF_ROOT=%LIBELF_INSTALL_PREFIX% %OPTIONS% - cmake --build _build --config %CONFIGURATION% test_script: - cmake --build _build --config %CONFIGURATION% --target RUN_TESTS dwarfutils-20200114/ar-lib000077500000000000000000000133021361531463500152330ustar00rootroot00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2012-03-01.08; # UTC # Copyright (C) 2010-2017 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <yz

 zz

nz z>&z&"z"z r )findjoin)lineaZinhtmlinpreZoutils2cr*/home/davea/dwarf/code/bugxml/bugrecord.pyxmlize#s>         rcCsHd}d}t|dkr(d|dd}|Sd|d}||7}|d7}|S)Nrr rz

:z

z: )len)namerroutrrrparalineIs  rcCsbd}t|dkr$d|dd}|Sd|d}x$|D]}t|d|\}}||7}q6W|d7}|S)Nrrz

rz

z: r)rr)rlinesrrZlinfrrr paralinesTs    rcCsP|dkrd|dd}n2t|dkrrz

rz: )r)rstrrrrrpara`s  rc@seZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#S)$ bugrecordcCsJ|j|_d|_d|_d|_g|_d|_g|_d|_g|_ d|_ d|_ dS)Nr ) strip_id_cve _datereported _reportedby_vulnerability_product _description _datefixed _references _gitfixid _tarrelease)selfZdwidrrr__init__ls zbugrecord.__init__cCs0|jdkr"td|j|tjd|j|_dS)Nr zDuplicate cve r)r#printsysexitr!)r-Zpubidrrrsetcveys  zbugrecord.setcvecCs0|jdkr"td|j|tjd|j|_dS)Nr zDuplicate datereported r)r$r/r0r1r!)r-reprrrsetdatereported~s  zbugrecord.setdatereportedcCs0|jdkr"td|j|tjd|j|_dS)Nr zDuplicate reportedby r)r%r/r0r1r!)r-r3rrr setreportedbys  zbugrecord.setreportedbycCs0t|jdkr&td|j|tjd||_dS)NrzDuplicate vulnerability r)rr&r/r0r1)r-Zvulnrrrsetvulnerabilitys zbugrecord.setvulnerabilitycCs4t|jdkr&td|j|tjd|j|_dS)NrzDuplicate product r)rr'r/r0r1r!)r-prrr setproducts zbugrecord.setproductcCs0t|jdkr&td|j|tjd||_dS)NrzDuplicate description r)rr(r/r0r1)r-drrrsetdescriptions zbugrecord.setdescriptioncCs4t|jdkr&td|j|tjd|j|_dS)NrzDuplicate datefixed r)rr)r/r0r1r!)r-r9rrr setdatefixeds zbugrecord.setdatefixedcCs0t|jdkr&td|j|tjd||_dS)NrzDuplicate references r)rr*r/r0r1)r-rrrr setreferencess zbugrecord.setreferencescCs4t|jdkr&td|j|tjd|j|_dS)NrzDuplicate gitfixid r)rr+r/r0r1r!)r-grrr setgitfixids zbugrecord.setgitfixidcCs4t|jdkr&td|j|tjd|j|_dS)NrzDuplicate tarrelease r)rr,r/r0r1r!)r-r>rrr settarreleases zbugrecord.settarreleasecCsT|dkrt|dSt|dkr2t||ddSt|x|D] }t|q@WdS)Nrr)r/r)r-titlerrrrrplists  zbugrecord.plistcCstdtd|jtd|jtd|jtd|j|jd|jtd|j|jd|jtd |j |jd |j td |j td |j dS) Nr zid:zcve:z datereported:z reportedby:zvulnerability:zproduct:z description:z datefixed:z references:z gitfixid:z tarrelease:) r/r"r#r$r%rBr&r'r(r)r*r+r,)r-rrrprintbugs       zbugrecord.printbugcCsdj|j}djd|d|jdg}|g}d}t|jd|\}}td|}||g7}t|jd|\}}td|}||g7}t|jd|\}}td |}||g7}t|jd|\}}td |}||g7}td |j}||g7}t|j d|\}}td |}||g7}td |j }||g7}t|j d|\}}td|}||g7}td|j }||g7}t|j d|\}}td|}||g7}t|jd|\}}td|}||g7}d}||g7}|S)Nr z

z

rridZcveZ datereportedZ reportedbyZ vulnerabilityproductZ descriptionZ datefixedZ referencesZgitfixidZ tarreleasez!

[top]

)r r"rrr#r$r%rr&r'r(r)r*r+r,)r-Zs5ttxtrsZinprrr generate_htmlsJ                        zbugrecord.generate_htmlcCs0|}|j}t|dkr ||7}||d7}|S)Nrr)r!r)r-startmaintermrrrrrparaxmls   zbugrecord.paraxmlc CsR|}d}x8|D]0}|j}t|d|\}}t|dkr||7}qW||d7}|S)Nrrr)rstriprr) r-rJrKrLrrxrrFrrrparaxmlNs    zbugrecord.paraxmlNcCsg}d}||g7}d}t|jd|\}}|jd|d}t|jd|\}}|jd|d}||g7}t|jd|\}}|jd|d}||g7}t|jd|\}}|jd |d }||g7}t|jd|\}}|jd |d }||g7}|j}|jd |d}||g7}|j }|jd|d}||g7}t|j d|\}}|jd|d}||g7}|j }|jd|d}||g7}t|j d|\}}|jd|d}||g7}t|j d|\}}|jd|d}||g7}d}||g7}|S)Nzrzzzzzzz z z z zzz zz z z z z z z z z)rr"rMr#r$r%r'r&rPr(r)r*r+r,)r-rGrFrrHr7rrr generate_xmlsN            zbugrecord.generate_xmlN)__name__ __module__ __qualname__r.r2r4r5r6r8r:r;r=r?r@rBrCrIrMrPrQrrrrr js"  6 r )r0rrrrr rrrrs &   dwarfutils-20200114/bugxml/bugrecord.py000077500000000000000000000213461361531463500177750ustar00rootroot00000000000000#!/usr/bin/python3 # Copyright (c) 2016-2016 David Anderson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the example nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. import sys # Use only
 or 
all by itself in data.xml. # No other data on either of such lines. # All the lines between these two markers should be # shown in individual lines. def xmlize(linea,inhtml,inpre): outi = [] l = linea if l.find("
") != -1:
     if inhtml == 'y':
       s2 = '

' +l + '\n' else: s2 = l + '\n' inpre = 'y' return s2,inpre if l.find("
") != -1: if inhtml == 'y': s2 = l + '\n' + "

" else: s2 = l + '\n' inpre = 'n' return s2, inpre if inpre == 'y' and inhtml == 'n': outi += [""] for c in l: if c == '<': outi += ["<"] elif c == '>': outi += [">"] elif c == "&": outi += ["&"] #elif c == "'": # outi += ["'"] elif c == '"': outi += ["""] else: outi += [c] if inpre == 'y' and inhtml == 'n': outi += [""] outi += ["\n"] s2 = ''.join(outi) return s2,inpre def paraline(name,linea): inpre = 'n' out = '' if len(linea) <1: out = "

" + name + ":"+ "

" return out out = "

" + name + ": " out +=linea out += "

" return out; def paralines(name,lines): inpre = 'n' if len(lines) <1: out = "

" + name + ":"+ "

" return out out = "

" + name + ": " for lin in lines: f,inpre = xmlize(lin,'y',inpre) out += f out += "

" return out; def para(name,str): if str == None: out = "

" + name + ":"+ "

" elif len(str) > 0: out = "

" + name + ": " + str + "

" else: out = "

" + name + ":"+ "

" return out class bugrecord: def __init__(self,dwid): self._id= dwid.strip() self._cve = '' self._datereported = '' self._reportedby = '' self._vulnerability = [] self._product = '' self._description = [] self._datefixed = '' self._references = [] self._gitfixid = '' self._tarrelease = '' def setcve(self,pubid): if self._cve != '': print("Duplicate cve ",self._cve,pubid) sys.exit(1) self._cve = pubid.strip() def setdatereported(self,rep): if self._datereported != '': print("Duplicate datereported ",self._datereported,rep) sys.exit(1) self._datereported = rep.strip() def setreportedby(self,rep): if self._reportedby != '': print("Duplicate reportedby ",self._reportedby,rep) sys.exit(1) self._reportedby = rep.strip() def setvulnerability(self,vuln): if len(self._vulnerability) != 0: print("Duplicate vulnerability ",self._vulnerability,vuln) sys.exit(1) self._vulnerability = vuln def setproduct(self,p): if len(self._product) != 0: print("Duplicate product ",self._product,p) sys.exit(1) self._product = p.strip() def setdescription(self,d): if len(self._description) != 0: print("Duplicate description ",self._description,d) sys.exit(1) self._description = d def setdatefixed(self,d): if len(self._datefixed) != 0: print("Duplicate datefixed ",self._datefixed,d) sys.exit(1) self._datefixed = d.strip() def setreferences(self,r): if len(self._references) != 0: print("Duplicate references ",self._references,r) sys.exit(1) self._references = r def setgitfixid(self,g): if len(self._gitfixid) != 0: print("Duplicate gitfixid ",self._gitfixid,g) sys.exit(1) self._gitfixid = g.strip() def settarrelease(self,g): if len(self._tarrelease) != 0: print("Duplicate tarrelease ",self._tarrelease,g) sys.exit(1) self._tarrelease = g.strip() def plist(self,title,lines): if lines == None: print(title) return if len(lines) == 1: print(title,lines[0]) return print(title) for l in lines: print(l) def printbug(self): print("") print("id:",self._id) print("cve:",self._cve) print("datereported:",self._datereported) print("reportedby:",self._reportedby) self.plist("vulnerability:",self._vulnerability) print("product:",self._product) self.plist("description:",self._description) print("datefixed:",self._datefixed) self.plist("references:",self._references) print("gitfixid:",self._gitfixid) print("tarrelease:",self._tarrelease) def generate_html(self): s5= ''.join(self._id) t = ''.join(['

',self._id,'

']) txt = [t] inpre = 'n' s,inp= xmlize(self._id,'y',inpre) t = paraline("id",s) txt += [t] s,inp= xmlize(self._cve,'y',inpre) t = paraline("cve",s) txt += [t] s,inp= xmlize(self._datereported,'y',inpre) t = paraline("datereported",s) txt += [t] s,inp= xmlize(self._reportedby,'y',inpre) t = paraline("reportedby",s) txt += [t] #MULTI t = paralines("vulnerability",self._vulnerability) txt += [t] s,inp= xmlize(self._product,'y',inpre) t = paraline("product",s) txt += [t] #MULTI t = paralines("description",self._description) txt += [t] s,inp= xmlize(self._datefixed,'y',inpre) t = paraline("datefixed",s) txt += [t] #MULTI t = paralines("references",self._references) txt += [t] s,inp= xmlize(self._gitfixid,'y',inpre) t = paraline("gitfixid",s) txt += [t] s,inp= xmlize(self._tarrelease,'y',inpre) t = paraline("tarrelease",s) txt += [t] t = '

[top]

' txt += [t] return txt def paraxml(self,start,main,term): # For single line xml remove the newline from the main text line. out = start l=main.strip() if len(l) > 0: out += l out += term + "\n" return out def paraxmlN(self,start,main,term): # For multi line xml leave newlines present. out = start inpre = 'n' for x in main: l=x.rstrip() t,inpre = xmlize(l,'n',inpre); if len(t) > 0: out += t out += term + "\n" return out def generate_xml(self): txt=[] t = '' txt += [t] inpre = 'n' s,inpre= xmlize(self._id,'n',inpre) s = self.paraxml('',s,'') s,inpre= xmlize(self._cve,'n',inpre) t = self.paraxml('',s,'') txt += [t] s,inpre= xmlize(self._datereported,'n',inpre) t = self.paraxml('',s,'') txt += [t]; s,inpre= xmlize(self._reportedby,'n',inpre) t = self.paraxml('',s,'') txt += [t]; s,inpre= xmlize(self._product,'n',inpre) t = self.paraxml('',s,'') txt += [t]; #MULTI p = self._vulnerability t = self.paraxmlN("",p,"") txt += [t] #MULTI p = self._description t = self.paraxmlN("",p,"") txt += [t] s,inpre= xmlize(self._datefixed,'n',inpre) t = self.paraxml('',s,'') txt += [t]; #MULTI p = self._references t = self.paraxmlN("",p,"") txt += [t] s,inpre= xmlize(self._gitfixid,'n',inpre) t = self.paraxml('',s,'') txt += [t]; s,inpre= xmlize(self._tarrelease,'n',inpre) t = self.paraxml('',s,'') txt += [t]; t = '' txt += [t]; return txt dwarfutils-20200114/bugxml/data.template000066400000000000000000000001641361531463500201050ustar00rootroot00000000000000id: cve: datereported: reportedby: vulnerability: product: description: datefixed: references: gitfixid: endrec: dwarfutils-20200114/bugxml/data.txt000066400000000000000000001246271361531463500171240ustar00rootroot00000000000000 id: DW201801-001 cve: datereported: 2018-01-28 reportedby: Agostino Sarubbo vulnerability: Incorrect frame section can crash dwarfdump product: dwarfdump description: A carefully crafted object with an invalid frame section set of initial-instructions can crash the frame-instructions decode in dwarfdump. In addition, a couple places in libdwarf are not as careful in checking frame data as they should be. A segmentation-fault/core-dump is possible. datefixed: 2018-01-29 references: sarubbo-11/testcase{1,2,3,4,5}.bin gitfixid: 7af0ecddfafed88446969cbf8c888356ad485d99 tarrelease: 2018-01-29 endrec: DW201801-001 id: DW201712-001 cve: datereported: 2017-12-01 reportedby: Agostino Sarubbo vulnerability: Incorrect frame section could let caller crash product: libdwarf description: A carefully crafted object with an invalid frame section can result in passing back data to a caller of dwarf_get_fde_augmentation_data() is erroneous and will result in the caller reference off the end of the frame section. A segmentation-fault/core-dump is possible. datefixed: 2017-12-01 references: sarubbo-10/1.crashes.bin gitfixid: 329ea8e56bc9550260cae6e2e9756bfbe7e2ff6d tarrelease: endrec: DW201712-001 id: DW201711-002 cve: datereported: 2017-11-08 reportedby: Agostino Sarubbo vulnerability: Incorrect line table section could crash caller product: libdwarf description: An carefully crafted object with a invalid line table section crafted to end early at a particular point resulted in dereferencing outside the line table from libdwarf/dwarf_line_table_reader_common.c . A segmentation-fault/core-dump is possible. datefixed: 2017-11-08 references: regressiontests/sarubbo-9/3.crashes.bin gitfixid: a1644f4dde7dd5990537ff7ad22a9e94b8723186 tarrelease: endrec: DW201711-002 id: DW201711-001 cve: datereported: 2017-11-01 reportedby: Agostino Sarubbo vulnerability: Incorrect frame section could crash caller product: libdwarf description: A carefully crafted object with a resulting invalid frame section with DW_CFA_advance_loc1 implying data off-the-end-of-section will dereference an invalid pointer. A segmentation fault and core dump is possible. Corrected code checks now. datefixed: 2017-11-02 references: regressiontests/sarubbo-8/1.crashes.bin gitfixid: 44349d7991e44dd3751794f76537cabcf65ee28d tarrelease: endrec: DW201711-001 id: DW201709-001 cve: datereported: 2017-09-19 reportedby: Agostino Sarubbo vulnerability: Incorrect abbrev section could crash caller. product: libdwarf description: A fuzzed object with a resulting invalid abbrev section where the end of section follows an abbrev tag would dereference a non-existent has-child byte. datefixed: 2017-09-26 references: regressiontests/sarubbo-3/1.crashes.bin gitfixid: bcc2e33908e669bacd397e3c941ffd1db3005d17 tarrelease: endrec: DW201709-001 id: DW201706-001 cve: CVE-2017-9998 datereported: 2017-06-28 reportedby: team OWL337 vulnerability: Addition overflow in libdwarf leads to segmentation violation product: libdwarf description: A fuzzed object with a resulting invalid value can overflow when added to a valid pointer (depending on how the runtime memory is laid out) and thereafter a dereference results in a segmentation violation).
 see
  https://bugzilla.redhat.com/show_bug.cgi?id=1465756
  for contact information of those finding the bug.
  Fabian Wolff sent email and provided
  the link to the web page.
 
datefixed: 2017-07-06 references: regressiontests/wolff/POC1 gitfixid: e91681e8841291f57386f26a90897fd1dcf92a6e tarrelease: endrec: DW201706-001 id: DW201703-007 cve: datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in strncmp (libelf bug) product: libdwarf (libelf) description: 7/7. A heap overflow in strncmp() is due to libelf failing to check arguments to elf_ strptr. This is not a bug in libdwarf, it is a libelf bug. A pointer for being in bounds (in a few places in this function) and a failure in a check in dwarf_attr_list(). The test object is intentionally corrupted (fuzzed).
 A portion of sanitizer output with Ubuntu 14.04:
 ==180133==ERROR: AddressSanitizer: heap-buffer-overflow 
   on address 0x60d00000cff1 at pc 0x0000004476f4 
   bp 0x7fff87dd7dd0 sp 0x7fff87dd7590
 READ of size 8 at 0x60d00000cff1 thread T0
    #0 0x4476f3 in __interceptor_strncmp (/home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/dwarfdump+0x4476f3)
    #1 0x7992ae in this_section_dwarf_relevant /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_init_finish.c:608:13
    #2 0x781064 in _dwarf_setup /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_init_finish.c:722:14
    #3 0x77d59c in dwarf_object_init /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_init_finish.c:922:20

 With Ubuntu 16.04 libelf dwarfdump gets:
 ERROR:  dwarf_elf_init:  DW_DLE_ELF_STRPTR_ERROR (30) 
 a call to elf_strptr() failed trying to get a section name
 
datefixed: references: regressiontests/marcel/crash7 gitfixid: tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-007 id: DW201703-006 cve: CVE-2017-9052 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in dwarf_formsdata product: libdwarf description: 6/7. A heap overflow in dwarf_formsdata() is due to a failure to check a pointer for being in bounds (in a few places in this function) and a failure in a check in dwarf_attr_list(). The test object is intentionally corrupted (fuzzed).
 A portion of sanitizer output with Ubuntu 14.04:
 ==180130==ERROR: AddressSanitizer: heap-buffer-overflow 
  on address 0x61100000589c at pc 0x0000006cab95 
  bp 0x7fff749aab10 sp 0x7fff749aab08
 READ of size 1 at 0x61100000589c thread T0
    #0 0x6cab94 in dwarf_formsdata /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_form.c:937:9
    #1 0x567daf in get_small_encoding_integer_and_name /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:1533:16
    #2 0x562f28 in get_attr_value /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:5030:24
    #3 0x555f86 in print_attribute /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:3357:13

 After fixes applied dwarfdump says:
 ERROR:  dwarf_attrlist:  DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION(281)
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash6 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-006 id: DW201703-005 cve: CVE-2017-9053 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in _dwarf_read_loc_expr_op() product: libdwarf description: 5/7. A heap overflow in _dwarf_read_loc_expr_op() is due to a failure to check a pointer for being in bounds (in a few places in this function). The test object is intentionally corrupted (fuzzed).
 A portion of sanitizer output with Ubuntu 14.04:
 ==180112==ERROR: AddressSanitizer: heap-buffer-overflow 
  on address 0x60800000bf72 at pc 0x00000084dd52 
  bp 0x7ffc12136fd0 sp 0x7ffc12136fc8
 READ of size 1 at 0x60800000bf72 thread T0
    #0 0x84dd51 in _dwarf_read_loc_expr_op /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/./dwarf_loc.c:250:9
    #1 0x841f16 in _dwarf_get_locdesc_c /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/./dwarf_loc2.c:109:15
    #2 0x837d08 in dwarf_get_loclist_c /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/./dwarf_loc2.c:685:18
    #3 0x57dff2 in get_location_list /home/ubuntu/subjects/
       build-asan/libdwarf/dwarfdump/print_die.c:3812:16

 After fixes applied dwarfdump says:
 ERROR:  dwarf_get_loclist_c:  DW_DLE_LOCEXPR_OFF_SECTION_END 
 (343) Corrupt dwarf
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash5 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-005 id: DW201703-004 cve: datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in set_up_section strlen product: libdwarf (libelf) description: 4/7. An apparent heap overflow that gives the appearance of being in libdwarf is due to libelf call elf_strptr() failing to fully check that its arguments make sense. This is not a bug in libdwarf, it is a libelf bug. The test object is intentionally corrupted (fuzzed). The submission was with Ubuntu 14.04. With Ubuntu 16.04 there is no sanitizer error report.

 A portion of sanitizer output with Ubuntu 14.04:
 ==180109==ERROR: AddressSanitizer: heap-buffer-overflow 
   on address 0x60b00000b000 at pc 0x00000048fd12 
   bp 0x7fff4ad31ef0 sp 0x7fff4ad316b0
 READ of size 16 at 0x60b00000b000 thread T0
    #0 0x48fd11 in __interceptor_strlen (/home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/dwarfdump+0x48fd11)
    #1 0x7a84a4 in set_up_section /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:285:27
    #2 0x79aaa5 in enter_section_in_de_debug_sections_array /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:355:5
    #3 0x78170b in _dwarf_setup /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:746:19

 With Ubuntu 16.04 libelf one gets:
 ERROR:  dwarf_elf_init:  DW_DLE_ELF_STRPTR_ERROR (30) 
 a call to elf_strptr() failed trying to get a section name
 
datefixed: references: regressiontests/marcel/crash4 gitfixid: tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-004 id: DW201703-003 cve: datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in strcmp product: libdwarf (libelf) description: 3/7. An apparent heap overflow that gives the appearance of being in libdwarf is due to libelf call elf_strptr() failing to fully check that its arguments make sense. This is not a bug in libdwarf, it is a libelf bug. The test object is intentionally corrupted (fuzzed). The submission was with Ubuntu 14.04. With Ubuntu 16.04 there is no sanitizer error report.

 A portion of sanitizer output with Ubuntu 14.04:
  ==180106==ERROR: AddressSanitizer: heap-buffer-overflow 
    on address 0x60f00000ef09 at pc 0x000000447300 
    bp 0x7ffc667dce10 sp 0x7ffc667dc5d0
  READ of size 4 at 0x60f00000ef09 thread T0
    #0 0x4472ff in __interceptor_strcmp (/home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/dwarfdump+0x4472ff)
    #1 0x79938f in this_section_dwarf_relevant /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:612:12
    #2 0x781064 in _dwarf_setup /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:722:14
    #3 0x77d59c in dwarf_object_init /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_init_finish.c:922:20
    #4 0x899d4f in dwarf_elf_init_file_ownership /

  With Ubuntu 16.04 libelf one gets:
  ERROR:  dwarf_elf_init:  DW_DLE_ELF_STRPTR_ERROR (30) 
  a call to elf_strptr() failed trying to get a section name
 
datefixed: references: regressiontests/marcel/crash3 gitfixid: tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-003 id: DW201703-002 cve: CVE-2017-9054 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in _dwarf_decode_s_leb128_chk() product: libdwarf description: 2/7. In _dwarf_decode_s_leb128_chk() a byte pointer was dereferenced just before was checked as being in bounds. The test object is intentionally corrupted (fuzzed).

 A portion of sanitizer output:
  .debug_line: line number info for a single cu
  ==180103==ERROR: AddressSanitizer: heap-buffer-overflow 
    on address 0x610000007ffc at pc 0x0000007b0f5b 
    bp 0x7ffe06bbf510 sp 0x7ffe06bbf508
  READ of size 1 at 0x610000007ffc thread T0
    #0 0x7b0f5a in _dwarf_decode_s_leb128_chk /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/dwarf_leb.c:304:9
    #1 0x7e753e in read_line_table_program /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/./
       dwarf_line_table_reader_common.c:1167:17
    #2 0x7d7fe3 in _dwarf_internal_srclines /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/./dwarf_line.c:690:15
    #3 0x7f9dbb in dwarf_srclines_b /home/ubuntu/
       subjects/build-asan/libdwarf/libdwarf/./dwarf_line.c:944:12
    #4 0x5caaa5 in print_line_numbers_this_cu /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_lines.c:762:16

  After fix applied one gets:
  ERROR:  dwarf_srclines:  DW_DLE_LEB_IMPROPER (329) 
  Runs off end of section or CU
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash2 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-002 id: DW201703-001 cve: CVE-2017-9055 datereported: 2017-03-21 reportedby: Marcel Bohme and Van-Thuan Pham vulnerability: Heap overflow in dwarf_formsdata product: libdwarf description: 1/7. In dwarf_formsdata() a few data types were not checked as being in bounds. The test object is intentionally corrupted (fuzzed).

 A portion of sanitizer output:
 LOCAL_SYMBOLS:
 < 1><0x0000002f>    DW_TAG_subprogram

 ==180088==ERROR: AddressSanitizer: heap-buffer-overflow on 
  address 0x60800000bf72 at pc 0x0000006cab95 bp 
  0x7fff31425830 sp 0x7fff31425828
  READ of size 1 at 0x60800000bf72 thread T0
    #0 0x6cab94 in dwarf_formsdata /home/ubuntu/subjects/
       build-asan/libdwarf/libdwarf/dwarf_form.c:937:9
    #1 0x567daf in get_small_encoding_integer_and_name /home/
       ubuntu/subjects/build-asan/libdwarf/dwarfdump/print_die.c:1533:16
    #2 0x576f38 in check_for_type_unsigned /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_die.c:4301:11
    #3 0x56ad8c in formxdata_print_value /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_die.c:4374:39
    #4 0x5643be in get_attr_value /home/ubuntu/
       subjects/build-asan/libdwarf/dwarfdump/print_die.c:5140:24
    #5 0x555f86 in print_attribute /home/ubuntu/subjects/build
  ...

  After fixes applied dwarfdump gets:
  ERROR:  dwarf_attrlist:  DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION(281)
 
datefixed: 2017-03-21 references: regressiontests/marcel/crash1 gitfixid: cc37d6917011733d776ae228af4e5d6abe9613c1 tarrelease: libdwarf-20160507.tar.gz endrec: DW201703-001 id: DW201611-006 cve: CVE-2016-9480 datereported: 2016-11-14 reportedby: Puzzor (Shi Ji) vulnerability: Heap buffer overflow product: libdwarf description: An object with corrupt contents causes a memory reference out of bounds, a heap buffer overflow reference.
 heap-buffer-overflow in dwarf_util.c:208 for val_ptr

 # Version
 bb9a3492ac5713bed9cf3ae58ddb7afa6e9e98f8
 (in regression tests here named  heap_buf_overflow.o)


 # ASAN Output
 <0> tag: 17 DW_TAG_compile_unit  name: "strstrnocase.c" FORM 0xe "DW_FORM_strp"
 <1> tag: 46 DW_TAG_subprogram  name: "is_strstrnocase" FORM 0xe "DW_FORM_strp"
 =================
 ==1666==ERROR: AddressSanitizer: heap-buffer-overflow on address 
   0xb5846db9 at p
 c 0x080b3a1b bp 0xbfa75d18 sp 0xbfa75d08
 READ of size 1 at 0xb5846db9 thread T0
    #0 0x80b3a1a in _dwarf_get_size_of_val /home/puzzor/libdwarf-code/
        libdwarf/dwarf_util.c:208
    #1 0x8056602 in _dwarf_next_die_info_ptr /home/puzzor/libdwarf-code/
        libdwarf/dwarf_die_deliv.c:1353
    #2 0x8057f4b in dwarf_child /home/puzzor/libdwarf-code/libdwarf/
       dwarf_die_de liv.c:1688
    #3 0x804b5fa in get_die_and_siblings simplereader.c:637
    #4 0x804b65c in get_die_and_siblings simplereader.c:643
    #5 0x804b3f3 in read_cu_list simplereader.c:611
    #6 0x804aeae in main simplereader.c:533
    #7 0xb6ffe275 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18275)
    #8 0x80491c0  (/home/puzzor/libdwarf-code/dwarfexample/simplereader+
         0x80491c 0)

 0xb5846db9 is located 0 bytes to the right of 249-byte region 
    [0xb5846cc0,0xb5846db9)
 allocated by thread T0 here:
    #0 0xb727fae4 in __interceptor_malloc (/usr/lib/i386-linux-gnu/libasan.so.
       3+ 0xc3ae4)
    #1 0xb71a9b98  (/usr/lib/i386-linux-gnu/libelf.so.1+0x9b98)
 
For the orignal bug report see
 https://sourceforge.net/p/libdwarf/bugs/5/
 
datefixed: 2016-11-16 references: regressiontests/puzzor/heap_buf_overflow.o gitfixid: 5dd64de047cd5ec479fb11fe7ff2692fd819e5e5 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201611-005 cve: datereported: 2016-11-11 reportedby: Agostino Sarubbo vulnerability: negation of -9223372036854775808 cannot be represented in type product: libdwarf description: With the right bit pattern in a signed leb number the signed leb decode would execute an unary minus with undefined effect. This is not known to generate an incorrect value, but it could, one supposes. datefixed: 2016-11-11 references: regressiontests/sarubbo-2/00050-libdwarf-negate-itself gitfixid: 4f19e1050cd8e9ddf2cb6caa061ff2fec4c9b5f9 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201611-004 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: Heap overflow in dwarf_skim_forms() product: libdwarf description: If a non-terminated string in a DWARF5 macro section ends a section it can result in accessing memory not in the application. dwarf_macro5.c(in _dwarf_skim_forms()). datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00027-libdwarf-heapoverflow-_dwarf_skim_forms gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 endrec: id: DW201611-003 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: Bad aranges length leads to overflow and bad pointer product: libdwarf description: in dwarf_arange.c(dwarf_get_aranges_list) an aranges header with corrupt data could, with an overflowing calculation, result in pointers to invalid or inappropriate memory being dereferenced. datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00026-libdwarf-heapoverflow-dwarf_get_aranges_list gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 tarrelease: libdwarf-20170416.tar.gz endrec: id: DW201611-002 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: heap overflow in get_attr_value product: libdwarf description: Libdwarf failed to check for a bogus length in dwarf_form.c (dwarf_formblock()) resulting in a pointer pointing outside of the intended memory region. Anything could happen in the subsequent use of the bogus pointer.
 0x61300000de1c is located 0 bytes to the right of 348-byte region 
 [0x61300000dcc0,0x61300000de1c) 
 allocated by thread T0 here: 
   #0 0x4c0ad8 in malloc /var/tmp/portage/sys-devel/llvm-3.8.1-
 r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52 
   #1 0x7f883cfc6206 in __libelf_set_rawdata_wrlock /tmp/portage/dev-
 libs/elfutils-0.166/work/elfutils-0.166/libelf/elf_getdata.c:318
 
datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00025-libdwarf-heapoverflow-get_attr_value gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 tarrelease: libdwarf-20170416.tar.gz endrec: id: DW201611-001 cve: datereported: 2016-11-02 reportedby: Agostino Sarubbo vulnerability: Memory allocation failure in do_decompress_zlib product: libdwarf description: In decompressing a zlib compressed section if the decompressed section size is nonsense (too large) an attempted malloc will fail and could let an exception propagate to callers.
  ==27994==WARNING: AddressSanitizer failed to allocate 0x62696c2f7273752f
  bytes ==27994==AddressSanitizer's allocator is terminating the process
  instead of returning 0
  ...
   #6 0x4c0ab1 in malloc /var/tmp/portage/sys-devel/llvm-3.8.1-
r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:53
#7 0x5b582e in do_decompress_zlib
/tmp/dwarf-20161021/libdwarf/dwarf_init_finish.c:1085:12
   #8 0x5b582e in _dwarf_load_section
/tmp/dwarf-20161021/libdwarf/dwarf_init_finish.c:1159
   #9 0x5bb479 in dwarf_srcfiles
/tmp/dwarf-20161021/libdwarf/./dwarf_line.c:336:11
   #10 0x5145cd in print_one_die_section
 
datefixed: 2016-11-04 references: regressiontests/sarubbo-2/00024-libdwarf-memalloc-do_decompress_zlib gitfixid: 583f8834083b5ef834c497f5b47797e16101a9a6 tarrelease: libdwarf-20170416.tar.gz endrec: id: DW201609-004 cve: datereported: 20160917 reportedby: Puzzor vulnerability: libdwarf 20160613 Out-of-Bounds read product: libdwarf description: read line table program Out-of-Bounds read line_ptr in dwarf_line_table_reader_common.c:1433 Out-of-Bounds read See:
 https://bugzilla.redhat.com/show_bug.cgi?id=1377015
 https://sourceforge.net/p/libdwarf/bugs/4/
 
 # Address Sanitizer Output
 ==27763==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf4603f84 at pc 0x8408ede bp 0xffff6518 sp 0xffff6510
 READ of size 1 at 0xf4603f84 thread T0
 #0 0x8408edd in read_line_table_program /home/puzzor/test-fuzzing/code/libdwarf/./dwarf_line_table_reader_common.c:1433
 #1 0x83f716c in _dwarf_internal_srclines /home/puzzor/test-fuzzing/code/libdwarf/./dwarf_line.c:690
 #2 0x841436c in dwarf_srclines_b /home/puzzor/test-fuzzing/code/libdwarf/./dwarf_line.c:944
 #3 0x81fbc28 in print_line_numbers_this_cu /home/puzzor/test-fuzzing/code/dwarfdump/print_lines.c:763
 #4 0x815c191 in print_one_die_section /home/puzzor/test-fuzzing/code/dwarfdump/print_die.c:850
 #5 0x81565c1 in print_infos /home/puzzor/test-fuzzing/code/dwarfdump
 
datefixed: 20160923 references: regressiontests/DW201609-004/poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201609-003 cve: CVE-2016-7410 datereported: 20160913 reportedby: https://marc.info/?l=oss-security&m=147391785920048&w=2 vulnerability: libdwarf 20160613 heap-buffer-overflow product: libdwarf description: With AddressSanitizer, we found a Heap-Buffer-overflow in the latest release version of dwarfdump. The crash output is as follows:
  See also:
  https://marc.info/?l=oss-security&m=147378394815872&w=2
  The testcase poc is from this web page.
  
  ==17411==ERROR: AddressSanitizer: heap-buffer-overflow on address
  0xf3808904 at pc 0x80a6f76 bp 0xffb95e78 sp 0xffb95a5c
  READ of size 4 at 0xf3808904 thread T0
  ==17411==WARNING: Trying to symbolize code, but external symbolizer is
  not initialized!
    #0 0x80a6f75 in __interceptor_memcpy ??:?
    #1 0x8426c3b in _dwarf_read_loc_section
  /home/starlab/fuzzing/dwarf-20160613/libdwarf/./dwarf_loc.c:919
    #2 0x84250e2 in _dwarf_get_loclist_count
  /home/starlab/fuzzing/dwarf-20160613/libdwarf/./dwarf_loc.c:970
    #3 0x8438826 in dwarf_get_loclist_c
  /home/starlab/fuzzing/dwarf-20160613/libdwarf/./dwarf_loc2.c:551
    #4 0x81a1be8 in get_location_list
  /home/starlab/fuzzing/dwarf-20160613/dwarfdump/print_die.c:3523
    #5 0x816e1a2 in print_attribute
  
_dwarf_get_loclist_header_start() is not cautious about values in the header being absurdly large. Unclear as yet if this is the problem but it is a potential problem (fixed for next release).
  Address Sanitizer in gcc reproduces the report.
  In _dwarf_read_loc_section() the simple calculation of
  loc_section_end was wrong, so end-of section was
  incorrect for the local reads.
  With that fixed we get DW_DLE_READ_LITTLEENDIAN_ERROR when
  libdwarf attempts to read off end of section.
  
datefixed: 20160923 references: regressiontests/DW201609-003/poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201609-002 cve: CVE-2016-7511 datereported: 20160918 reportedby: Shi Ji (@Puzzor) vulnerability: libdwarf 20160613 Integer Overflow product: libdwarf description: In dwarf_get_size_of_val() with fuzzed DWARF data we get a SEGV.
  See
  https://sourceforge.net/p/libdwarf/bugs/3/
  
  ==6825== ERROR: AddressSanitizer: SEGV on unknown address 0x0583903c (pc 0xb61f1a98 sp 0xbfa388b4 bp 0xbfa38d08 T0)
  AddressSanitizer can not provide additional info.
  #1 0xb61e3c0b (/usr/lib/i386-linux-gnu/libasan.so.0+0xdc0b)
  #2 0x80a21b1 in _dwarf_get_size_of_val /home/fuzzing/fuzzing/dwarf-20160613/libdwarf/dwarf_util.c:210
  #3 0x8054214 in _dwarf_next_die_info_ptr /home/fuzzing/fuzzing/dwarf-20160613/libdwarf/dwarf_die_deliv.c:1340
  #4 0x80557a5 in dwarf_child /home/fuzzing/fuzzing/dwarf-20160613/libdwarf/dwarf_die_deliv.c:1640
  #5 0x804b23f in get_die_and_siblings /home/fuzzing/fuzzing/dwarf-20160613/dwarfexample/./simplereader.c:573
  
_dwarf_make_CU_Context() is insufficiently cautious about the length of a CU being absurd. Unclear as yet if this is the problem but it is a problem and is fixed for next release. datefixed: 20160923 references: regressiontests/DW201609-002/DW201609-002-poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201609-001 cve: datereported: 20160916 reportedby: STARLAB https://sourceforge.net/p/libdwarf/bugs/2/ vulnerability: libdwarf 20160613 die_info_ptr in dwarf_die_deliv.c: 1533 Out-Of_bounds product: libdwarf description: At line 1533 of dwarf_die_deliv.c a pointer dereference is done with a pointer pointing past the end of the CU data.
 see
 https://sourceforge.net/p/libdwarf/bugs/2/
 
 ==8054==ERROR: AddressSanitizer: heap-buffer-overflow on 
    address 0xf4c027ab at pc 0x819e4a4 bp 0xff88eb38 sp 0xff88eb30
 READ of size 1 at 0xf4c027ab thread T0
 #0 0x819e4a3 in dwarf_siblingof_b /home/starlab/fuzzing/dwarf-20160613/libdwarf/dwarf_die_deliv.c:1533
 #1 0x8116201 in print_die_and_children_internal /home/starlab/fuzzing/dwarf-20160613/dwarfdump/print_die.c:1157
 Bug report on sourceforge.net bug list for libdwarf.
 The bad pointer dereference is due to libdwarf 
 not noticing that the DWARF in that file is corrupt.
 In addtion
 The code was not noticing that it could dereference
 a pointer that pointed out of bounds in the end-sibling-list
 loop. 
 
 The example from the bug report (DW201609-001-poc) has
 the same problem.
 dwarfdump now reports DW_DLE_SIBLING_LIST_IMPROPER
 on both test2.o and DW201609-001-poc.
 
datefixed: 20160917 references: regressiontests/DW201609-001/test2.o regressiontests/DW201609-001/DW201609-001-poc gitfixid: 3767305debcba8bd7e1c483ae48c509d25399252 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-019 cve: CVE-2016-5028 datereported: 20160523 reportedby: Yue Liu vulnerability: Null dereference in print_frame_inst_bytes (dwarfdump) product: libdwarf description: The null dereference is due to a corrupted object file. Libdwarf was not dealing with empty (bss-like) sections since it really did not expect to see such in sections it reads! Now libdwarf catches the object error so dwarfdump sees the section as empty (as indeed it is!). datefixed: 20160523 references: regressiontests/liu/NULLdeference0522c.elf gitfixid: a55b958926cc67f89a512ed30bb5a22b0adb10f4 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-018 cve: CVE-2016-5029 datereported: 20160522 reportedby: Yue Liu vulnerability: Null dereference in create_fullest_file_path(). product: libdwarf description: The null dereference in create_fullest_file_path() causes a crash. This is due to corrupted dwarf and the fix detects this corruption and if that null string pointer happens undetected a static string is substituted so readers can notice the situation.
  202             }
 203             if (dirno > 0 && fe->fi_dir_index > 0) {
 204                 inc_dir_name = (char *) 
                         line_context->lc_include_directories[
 205                     fe->fi_dir_index - 1];
 206                 incdirnamelen = strlen(inc_dir_name);  <- $pc
 207             }
 208             full_name = (char *) _dwarf_get_alloc(dbg, 

 #0  create_fullest_file_path (dbg=,
 fe=0x68d510, line_context=0x68c4f0, name_ptr_out=, error=0x7fffffffe2b8) at ./dwarf_line.c:206

 #1  0x00007ffff7b6d3f9 in dwarf_filename (context=, fileno_in=, ret_filename=0x7fffffffe280,
 error=0x7fffffffe2b8) at ./dwarf_line.c:1418

 #2  dwarf_linesrc (line=,
 ret_linesrc=, error=) at
 ./dwarf_line.c:1436
 
datefixed: 20160522 references: regressiontests/liu/NULLdereference0522.elf gitfixid: acae971371daa23a19358bc62204007d258fbc5e tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-017 cve: CVE-2016-5030 datereported: 20160519 reportedby: Yue Liu vulnerability: Null dereference bug in _dwarf_calculate_info_section_end_ptr(). product: libdwarf description: NULL dereference bug in _dwarf_calculate_info_section_end_ptr().
 1742         Dwarf_Off off2 = 0;
 1743         Dwarf_Small *dataptr = 0;
 1744     
 1745         dbg = context->cc_dbg;
 1746         dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:                 <- $pc
 1747             dbg->de_debug_types.dss_data;
 1748         off2 = context->cc_debug_offset;
 1749         info_start = dataptr + off2;
 1750         info_end = info_start + context->cc_length +
 
 #0  _dwarf_calculate_info_section_end_ptr
 (context=context@entry=0x0) at dwarf_query.c:1746
 
 #1  0x00002aaaaace307d in
 _dwarf_extract_string_offset_via_str_offsets
 (dbg=dbg@entry=0x655a70, info_data_ptr=0x6629f0
 "", attrnum=attrnum@entry=121,
 attrform=attrform@entry=26, cu_context=0x0,
 str_sect_offset_out=str_sect_offset_out@entry=0x7fffffffd718,
 error=error@entry=0x7fffffffd878) at dwarf_form.c:1099
 
 #2  0x00002aaaaacf4ed7 in dwarf_get_macro_defundef
 (macro_context=macro_context@entry=0x65b790,
 op_number=op_number@entry=1,
 line_number=line_number@entry=0x7fffffffd858,
 index=index@entry=0x7fffffffd860,
 offset=offset@entry=0x7fffffffd868,
 forms_count=forms_count@entry=0x7fffffffd7ce,
 macro_string=macro_string@entry=0x7fffffffd870,
 error=error@entry=0x7fffffffd878) at dwarf_macro5.c:557
 
 ------
 
 _dwarf_calculate_info_section_end_ptr (context=context@entry=0x0) at 
   dwarf_query.c:1746
 1746        dataptr = context->cc_is_info? dbg->de_debug_info.dss_data:
 gef> p/x $rdi
 $4 = 0x0
 
datefixed: 20160522 references: regressiontests/liu/NULLdereference0519.elf gitfixid: 6fa3f710ee6f21bba7966b963033a91d77c952bd tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-016 cve: datereported: 20160519 reportedby: Yue Liu vulnerability: Invalid dwarf leads to dwarfdump crash in print_frame_inst_bytes. product: dwarfdump description: Corrupted dwarf crashes dwarfdump
 1297         }
 1298         len = len_in;
 1299         endpoint = instp + len;
 1300         for (; len > 0;) {
 1301             unsigned char ibyte = *instp;           <- $pc
 1302             int top = ibyte & 0xc0;
 1303             int bottom = ibyte & 0x3f;
 1304             int delta = 0;
 1305             int reg = 0;

 #0  print_frame_inst_bytes (dbg=dbg@entry=0x655ca0,
 cie_init_inst=, len_in=,
 data_alignment_factor=-4, code_alignment_factor=4,
 addr_size=addr_size@entry=4, offset_size=4, version=3,
 config_data=config_data@entry=0x63cda0 )
 at print_frames.c:1301

 #1  0x000000000041b70c in print_one_cie
 (dbg=dbg@entry=0x655ca0, cie=,
 cie_index=cie_index@entry=2, address_size=,
 config_data=config_data@entry=0x63cda0 )
 at print_frames.c:1161

 #2  0x000000000041cf52 in print_frames (dbg=0x655ca0,
 print_debug_frame=print_debug_frame@entry=1, print_eh_frame=0,
 config_data=config_data@entry=0x63cda0 )
 at print_frames.c:2229

 gef> p/x $r13
 $1 = 0x4bcad8
 gef> p/x *$r13
 Cannot access memory at address 0x4bcad8
 
datefixed: 20160522 references: regressiontests/liu/OOB_READ0519.elf gitfixid: 6fa3f710ee6f21bba7966b963033a91d77c952bd tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-015 cve: CVE-2016-5031 datereported: 20160517 reportedby: Yue Liu vulnerability: OOB read bug in print_frame_inst_bytes() product: libdwarf description: Test object shows an invalid read in print_frame_inst_bytes().
 1294         for (; len > 0;) {
 1295             unsigned char ibyte = *instp;           <- $pc
 1296             int top = ibyte & 0xc0;

 #0  print_frame_inst_bytes (dbg=dbg@entry=0x654c80, 
    cie_init_inst=, len=503715, data_alignment_factor=-4, 
    code_alignment_factor=1, addr_size=addr_size@entry=4, offset_size=4, 
    version=3, config_data=config_data@entry=0x63bda0 
    ) at print_frames.c:1295
 #1  0x000000000041b64c in print_one_cie (dbg=dbg@entry=0x654c80, 
    cie=, cie_index=cie_index@entry=1, 
    address_size=, config_data=
    config_data@entry=0x63bda0 ) at print_frames.c:1161
 #2  0x000000000041ce92 in print_frames (dbg=0x654c80, 
    print_debug_frame=print_debug_frame@entry=1, print_eh_frame=0, 
    config_data=config_data@entry=0x63bda0 ) 
    at print_frames.c:2209

 gef> x/10x $r13
 0x5e7981:       Cannot access memory at address 0x5e7981
 gef> p/x $r13
 $14 = 0x5e7981
 
datefixed: 20150518 references: regressiontests/liu/OOB0517_03.elf gitfixid: ac6673e32f3443a5d36c2217cb814000930b2c54 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-014 cve: CVE-2016-5032 datereported: 20160517 reportedby: Yue Liu vulnerability: OOB read bug in dwarf_get_xu_hash_entry() product: libdwarf description: Test object shows an invalid read in dwarf_get _xu_hash_entry, lin 211.
 #0  dwarf_get_xu_hash_entry (xuhdr=xuhdr@entry=0x657360, 
    index=index@entry=2897626028, hash_value=
    hash_value@entry=0x7fffffffd5b0, 
    index_to_sections=index_to_sections@entry=0x7fffffffd5a8, 
    err=err@entry=0x7fffffffdb08) at dwarf_xu_index.c:211
 #1  0x00002aaaaacfd05e in _dwarf_search_fission_for_key (
    dbg=0x654a50, error=0x7fffffffdb08, percu_index_out=,
    key_in=0x7fffffffd670, xuhdr=0x657360) at dwarf_xu_index.c:363
 #2  dwarf_get_debugfission_for_key (dbg=dbg@entry=0x654a50, 
    key=key@entry=0x7fffffffd670, key_type=key_type@entry=0x2aaaaad15e2a 
    "tu", percu_out=percu_out@entry=0x65a830, 
    error=error@entry=0x7fffffffdb08) at dwarf_xu_index.c:577
 
datefixed: 20150518 references: regressiontests/liu/OOB0517_02.elf gitfixid: ac6673e32f3443a5d36c2217cb814000930b2c54 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-013 cve: CVE-2016-5033 datereported: 20160517 reportedby: Yue Liu vulnerability: OOB read bug in print_exprloc_content product: libdwarf description: Test object shows an invalid write in print_exprloc_content.
 #0  print_exprloc_content (dbg=dbg@entry=0x654ea0, 
    die=die@entry=0x65b110, attrib=attrib@entry=0x65b590, 
    esbp=esbp@entry=0x7fffffffcef0, showhextoo=1) at print_die.c:4182
 #1  0x0000000000412fb1 in get_attr_value (dbg=dbg@entry=0x654ea0, 
    tag=, die=die@entry=0x65b110, 
    dieprint_cu_goffset=dieprint_cu_goffset@entry=11, 
    attrib=attrib@entry=0x65b590, srcfiles=srcfiles@entry=0x0, 
    cnt=cnt@entry=0, esbp=esbp@entry=0x7fffffffcef0, show_form=0, 
    local_verbose=0) at print_die.c:4972
 
datefixed: 20150518 references: regressiontests/liu/OOB0517_01.elf gitfixid: ac6673e32f3443a5d36c2217cb814000930b2c54 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-012 cve: CVE-2016-5034 datereported: 20160513 reportedby: Yue Liu vulnerability: OOB write. From relocation records product: libdwarf description: Test object shows an invalid write in dwarf_elf_access.c (when doing the relocations). Adding the relocation value to anything overflowed and disguised the bad relocation record. With a 32bit kernel build the test could show a double-free and coredump due to the unchecked invalid writes from relocations. datefixed: 20160517 references: regressiontests/liu/HeapOverflow0513.elf gitfixid: 10ca310f64368dc083efacac87732c02ef560a92 tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-011 cve: CVE-2016-5035 datereported: 20160506 reportedby: Yue Liu vulnerability: OOB read bug in _dwarf_read_line_table_header product: libdwarf description: Test object shows null dereference at line 62 of dwarf_line_table_reader.c. Frame code and linetable code was not noticing data corruption. datefixed: 20160512 references: regressiontests/liu/OOB_read4.elf gitfixid: 82d8e007851805af0dcaaff41f49a2d48473334b tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-010 cve: CVE-2016-5036 datereported: 20160506 reportedby: Yue Liu vulnerability: OOB read bug in dump_block product: libdwarf description: Test object shows null dereverence at line 186 of dump_block() in print_sections.c Frame code was not noticing frame data corruption. datefixed: 20160512 references: regressiontests/liu/OOB_read3.elf regressiontests/liu/OOB_read3_02.elf gitfixid: 82d8e007851805af0dcaaff41f49a2d48473334b tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-009 cve: CVE-2016-5037 datereported: 20160505 reportedby: Yue Liu vulnerability: NULL dereference in _dwarf_load_section product: libdwarf description: Test object shows null dereverence at line 1010 if(!strncmp("ZLIB",(const char *)src,4)) { in dwarf_init_finish.c The zlib code was not checking for a corrupted length-value. datefixed: 20160506 references: regressiontests/liu/NULLderefer0505_01.elf gitfixid: b6ec2dfd850929821626ea63fb0a752076a3c08a tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-008 cve: CVE-2016-5038 datereported: 20160505 reportedby: Yue Liu vulnerability: OOB read in dwarf_get_macro_startend_file() product: libdwarf description: Test object shows out of bound read. OOB at: line 772 *src_file_name = macro_context->mc_srcfiles[trueindex]; in dwarf_macro5.c A string offset into .debug_str is outside the bounds of the .debug_str section. datefixed: 20160512 references: regressiontests/liu/OOB0505_02.elf regressiontests/liu/OOB0505_02_02.elf gitfixid: 82d8e007851805af0dcaaff41f49a2d48473334b tarrelease: libdwarf-20160923.tar.gz endrec: id: DW201605-007 cve: CVE-2016-5039 datereported: 20160505 reportedby: Yue Liu vulnerability: OOB read bug in get_attr_value() product: libdwarf description: Test object shows out of bound read. Object had data all-bits-on so the existing length check did not work due to wraparound. Added a check not susceptible to that error (DW_DLE_FORM_BLOCK_LENGTH_ERROR). datefixed: 20160506 references: regressiontests/liu/OOB0505_01.elf gitfixid: eb1472afac95031d0c9dd8c11d527b865fe7deb8 gittag: 20160507 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-006 cve: datereported: 20160505 reportedby: Yue Liu vulnerability: Two Heap-Overflow bug product: libdwarf description: Two test objects showing a heap overflow in libdwarf when using dwarfdump. It seems that these were fixed by the previous git update. Neither gdb nor valgrind find any errors when building with yesterday's commit. datefixed: 20160504 references: regressiontests/liu/free_invalid_address.elf regressiontests/liu/heapoverflow01b.elf gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-001 cve: CVE-2016-5044 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in a duplicate free() in libdwarf and the calling application will crash. product: libdwarf description: In file dwarf_elf_access.c:1071
 WRITE_UNALIGNED(dbg,target_section + offset,
     &outval,sizeof(outval),reloc_size);
 
A crafted ELF file may lead to a large offset value, which bigger than the size of target_section heap chunk, then this WRITE_UNALIGNED() function will write the value of &outval out of the heap chunk. offset is a 64bit unsigned int value, so this is more than a heap overflow bug, but also a Out-of-Bound write bug. So WRITE_UNALIGNED() need more strictly checking to prevent this. datefixed: 20160504 references: regressiontests/liu/heapoverflow01.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332141
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f gittag: 20160507 tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-002 cve: CVE-2016-5043 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in a read outside the bounds of in memory data so the calling application can crash. product: libdwarf description: Out of bound read bug in libdwarf git code. dwarf_dealloc() did not check the Dwarf_Ptr space argument before using it. This will lead to a out-of-bound read bug.
 backtrace:
 #0  dwarf_dealloc (dbg=dbg@entry=0x655f30, space=0xa0,
 alloc_type=alloc_type@entry=1) at dwarf_alloc.c:477
 #1  0x00002aaaaacf3296 in dealloc_srcfiles
 (dbg=0x655f30, srcfiles=0x66b8f0, srcfiles_count=17) at
 dwarf_macro5.c:1025 #2  0x00002aaaaacf50e6 in dealloc_srcfiles
 (srcfiles_count=, srcfiles=,
 dbg=) at dwarf_macro5.c:1021 -----

 gef> p &r->rd_dbg
 $14 = (void **) 0x90
 
datefixed: 20160504 references: regressiontests/liu/outofbound01.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332144
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-003 cve: CVE-2016-5042 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in an infinite loop that eventually crashes the application. product: libdwarf description: In dwarf_get_aranges_list() an invalid count will iterate, reading from memory addresses that increase till it all fails. datefixed: 20160504 references: regressiontests/liu/infiniteloop.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332145
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-004 cve: CVE-2016-5041 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in a null dereference reading debugging information entries which crashes the application. product: libdwarf description: If no DW_AT_name is present in a debugging information entry using DWARF5 macros a null dereference in dwarf_macro5.c will crash the application. datefixed: 20160504 references: regressiontests/liu/null01.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332148
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: id: DW201605-005 cve: CVE-2016-5040 datereported: 20160502 reportedby: Yue Liu vulnerability: A specially crafted DWARF section results in reading a compilation unit header that crashes the application. product: libdwarf description: If the data read for a compilation unit header contains a too large length value the library will read outside of its bounds and crash the application. datefixed: 20160504 references: regressiontests/liu/null02.elf
 https://bugzilla.redhat.com/show_bug.cgi?id=1332149
 
gitfixid: 98a3da1e8237fe0d45b67ef77f3fa5ed9ff0215f tarrelease: libdwarf-20160507.tar.gz endrec: dwarfutils-20200114/bugxml/readbugs.py000077500000000000000000000153141361531463500176130ustar00rootroot00000000000000#!/usr/bin/python3 # Copyright (c) 2016-2016 David Anderson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the example nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY # OF SUCH DAMAGE. import os import sys sys.path.append(os.path.abspath("/home/davea/dwarf/code/bugxml")) import bugrecord def ignore_this_line(d,inrecord): if len(d) < 1: if inrecord == "y": return "n" else: return "y" s = str(d) if s[0] == '#': return "y" return "n" def closeouttext(bugrec,intext,text,linecount): if intext == 'd': bugrec.setdescription(text) return elif intext == 'v': bugrec.setvulnerability(text) return elif intext == 'r': bugrec.setreferences(text) return if intext == "": return print("bogus closeout line at line ",linecount) sys.exit(1) def readbugs(iname): name = iname if len(name) == 0: name = "/home/davea/dwarf/code/bugxml/data.txt" try: file = open(name,"r") except IOError as message: print("failed to open ",name, message) inrecord = "n" linecount = 0 text = [] usedid ={} intext = '' bugrec = '' buglist = [] while 1: try: rec = file.readline() except EOFError: break if len(rec) < 1: # eof break linecount += 1 if ignore_this_line(rec,inrecord) == "y": continue rec = rec.rstrip() if inrecord == "n": if len(rec) == 0: continue if rec.find(":") == -1: print("bogus non-blank line at line ",linecount) sys.exit(1) if inrecord == "y" and len(rec) > 0: # A multi line entry may have ":" in it. if intext != "" and rec[0] == ' ': s3 = ''.join(rec) text += [s3] continue low = rec.find(":") fldname = rec[0:low+1] fldval = rec[low+1:] if fldname == "id:": if inrecord == "y": print("bogus id: at line ",linecount) sys.exit(1) inrecord = "y" f = fldval.strip() if f in usedid: print("Duplicate Key:",f,"Giving up.") sys.exit(1) usedid[f] = 1 s4= ''.join(fldval) bugrec = bugrecord.bugrecord(s4) elif fldname == "cve:": closeouttext(bugrec,intext,text,linecount), intext = "" text = [] s4= ''.join(fldval) bugrec.setcve(s4) elif fldname == "datereported:": closeouttext(bugrec,intext,text,linecount), intext = "" text = [] s4= ''.join(fldval) bugrec.setdatereported(s4) elif fldname == "reportedby:": closeouttext(bugrec,intext,text,linecount), intext = "" text = [] s4= ''.join(fldval) bugrec.setreportedby(s4) elif fldname == "vulnerability:": closeouttext(bugrec,intext,text,linecount), intext = 'v' text = [] if len(fldval) > 0: s4= ''.join(fldval) text = [s4] elif fldname == "product:": closeouttext(bugrec,intext,text,linecount), intext = "" text = [] s4= ''.join(fldval) bugrec.setproduct(s4) elif fldname == "description:": closeouttext(bugrec,intext,text,linecount), text = [] intext = 'd' if len(fldval) > 0: s4= ''.join(fldval) text = [s4] elif fldname == "datefixed:": closeouttext(bugrec,intext,text,linecount), text = [] intext = "" s4= ''.join(fldval) bugrec.setdatefixed(s4) elif fldname == "references:": closeouttext(bugrec,intext,text,linecount), text = [] intext = 'r' if len(fldval) > 0: s4= ''.join(fldval) text = [s4] elif fldname == "gitfixid:": closeouttext(bugrec,intext,text,linecount), text = [] intext = "" s4= ''.join(fldval) bugrec.setgitfixid(s4) elif fldname == "tarrelease:": closeouttext(bugrec,intext,text,linecount), text = [] intext = "" s4= ''.join(fldval) bugrec.settarrelease(s4) elif fldname == "endrec:": closeouttext(bugrec,intext,text,linecount), text = [] if inrecord == "n": print("bogus endrec: at line ",linecount) sys.exit(1) buglist += [bugrec] inrecord = "n" text = [] intext = "" inrecord = "n" file.close() return buglist def sort_by_id(myl): """ Sort the list of objects by name. """ auxiliary = [ ( x._id, x) for x in myl ] auxiliary.sort() return [ x[1] for x in auxiliary ] def write_line(file,l): file.write(l + "\n") def write_all_lines(file,txt): for t in txt: write_line(file,t) def generatehtml(list2,name): try: file = open(name,"w") except IOError as message: print("failed to open ",name, message) sys.exit(1) for b in list2: txt=b.generate_html() write_all_lines(file,txt) write_line(file,"") write_line(file,"") file.close() def generatexml(list2,name): try: file = open(name,"w") except IOError as message: print("failed to open ",name, message) sys.exit(1) t = '' write_line(file,t) write_line(file,"") for b in list2: txt=b.generate_xml() write_all_lines(file,txt) write_line(file,"") file.close() if __name__ == '__main__': list = readbugs("") list2 = sort_by_id(list) list2.reverse() #for b in list2: # b.printbug() generatehtml(list2,"./dwarfbugtail") generatexml(list2,"./dwarfbuglohi.xml") list2.reverse() generatehtml(list2,"./dwarfbuglohitail") dwarfutils-20200114/cmake/000077500000000000000000000000001361531463500152205ustar00rootroot00000000000000dwarfutils-20200114/cmake/FindLibElf.cmake000066400000000000000000000034511361531463500201630ustar00rootroot00000000000000# - Try to find libelf # Referenced by the find_package() command from the top-level # CMakeLists.txt. # Once done this will define # # LIBELF_FOUND - system has libelf # LIBELF_INCLUDE_DIRS - the libelf include directory # LIBELF_LIBRARIES - Link these to use libelf # LIBELF_DEFINITIONS - Compiler switches required for using libelf # # This module reads hints about search locations from variables: # # LIBELF_ROOT - Preferred installation prefix # # Copyright (c) 2008 Bernhard Walle # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # if (NOT DWARF_WITH_LIBELF) return() endif () if (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS) set (LibElf_FIND_QUIETLY TRUE) endif (LIBELF_LIBRARIES AND LIBELF_INCLUDE_DIRS) find_path (LIBELF_INCLUDE_DIRS NAMES libelf/libelf.h libelf.h HINTS ${LIBELF_ROOT} PATH_SUFFIXES include libelf/include ) if (NOT LIBELF_INCLUDE_DIRS) set (DWARF_WITH_LIBELF OFF) return () endif() find_library (LIBELF_LIBRARIES NAMES elf libelf HINTS ${LIBELF_ROOT} PATH_SUFFIXES lib libelf/lib ) if (NOT LIBELF_LIBRARIES) set (DWARF_WITH_LIBELF OFF) return () endif() include (FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBELF_FOUND to TRUE if all listed variables are TRUE FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibElf DEFAULT_MSG LIBELF_LIBRARIES LIBELF_INCLUDE_DIRS) set(CMAKE_REQUIRED_LIBRARIES elf) include(CheckCSourceCompiles) check_c_source_compiles("#include int main() { Elf *e = (Elf*)0; size_t sz; elf_getshdrstrndx(e, &sz); return 0; }" ELF_GETSHDRSTRNDX) unset(CMAKE_REQUIRED_LIBRARIES) mark_as_advanced(LIBELF_INCLUDE_DIRS LIBELF_LIBRARIES ELF_GETSHDRSTRNDX) dwarfutils-20200114/codingstyle.txt000066400000000000000000000273301361531463500172320ustar00rootroot00000000000000Latest update: 30 March 2018 Adapted from the Cairo coding style document Libdwarf/dwarfdump coding style. This document is intended to be a short description of the preferred coding style for the cairo source code. Good style requires good taste, which means this can't all be reduced to automated rules, and there are exceptions. We want the code to be easy to understand and maintain, and consistent style plays an important part in that, even if some of the specific details seem trivial. If nothing else, this document gives a place to put consistent answers for issues that would otherwise be arbitrary. Most of the guidelines here are demonstrated by examples, (which means this document is quicker to read than it might appear given its length). Most of the examples are positive examples that you should imitate. The few negative examples are clearly marked with a comment of /* Yuck! */. Please don't submit code for libdwarf that looks like any of these. Indentation ----------- Each new level is indented 4 more spaces than the previous level: if (condition) { do_something(); } Done solely with space characters. The simple project on sourceforge.net, dicheck-da, detects all instances of tabs, improper indentation and line-ending whitespace. Tab characters -------------- The tab character must never appear. Braces ------ Most of the code in cairo uses bracing in the style of K&R: if (condition) { do_this(); do_that(); } else { do_the_other(); } and that is the preferred style. Even if all of the substatements of an if statement are single statements, the optional braces must always appear. if (condition) { do_this(); } else { do_that(); } Never if (condition) /* Yuck */ do_this(); /* Yuck */ else /* Yuck */ do_the_other(); /* Yuck */ Note that this last example also shows a situation in which the opening brace can be on its own line, though usually it looks like this example. The following can be difficult to read. if (condition && other_condition && yet_another) { /* But we usually do put the brace here */ do_something(); } Whitespace ---------- Separate logically distinct chunks with a single newline. This obviously applies between functions, but also applies within a function or block and can even be used to good effect within a structure definition. But don't get carried away with blank lines: struct _Dwarf_Data_s { struct Something_s op; double tolerance; Dwarf_Unsigned line_width; Dwarf_Unsigned line_height; Dwarf_Unsigned line_thickness; /* Notice the _s on struct declarations And notice indent of this comment and the blank line above this comment to make it clear the comment applies to fill_rule. */ struct Reg_Struct_s fill_rule; Dwarf_Signed distance_from_end; ... }; Never use a space before a function-call left parenthesis or a macro-call left parenthesis. Don't eliminate newlines just because things would still fit on one line. This breaks the expected visual structure of the code making it much harder to read and understand: (); /* Yuck! */ Eliminate trailing whitespace on any line. Also, avoid putting initial or final blank lines into any file, and never use multiple blank lines instead of a single blank line. Use dicheck (see above) to find trailing whitespace and indentation inconsistencies. You might find the git-stripspace utility helpful which acts as a filter to remove trailing whitespace as well as initial, final, and duplicate blank lines. As a special case of the bracing and whitespace guidelines, function definitions in libdwarf should always take the following form: int my_function (Dwarf_Debug dbg, Dwarf_Unsigned second_arg, Dwarf_Unsigned* ret_value; Dwarf_Error *error) { do_my_things(); /* The meaning of life */ *ret_value = 42; return DW_DLV_OK; } And in dwarfdump, etc, the code tends to follow this form too (but far from always). Function prototypes inside libdwarf headers (as opposed to .c files) usually have the return type (and associated specifiers and qualifiers) the same line as the function name. If the line gets long addtional lines are appropriate. Function prototypes inside libdwarf.h always comment out argument names (but not types) to preserve the caller's macro namespace. Because it is a public header, unlike all the other headers in libdwarf/dwarfdump/simpleexample. In .c files the function name starts a line as shown above. Notice, above, how a too-long argument line gets folded with standard indentation(4). Break up long lines (> ~72 characters) and use whitespace to align things nicely. For example the arguments in a long list to a function call should all (but the first) be aligned with each other: align_function_arguments (argument_the_first, argument_the_second, argument_the_third); And as a special rule, in a function prototype, (as well as in the definition), whitespace should be inserted between the parameter types and names so that the names are aligned: void align_parameter_names_in_prototypes (const char *char_star_arg, int int_arg, double *double_star_arg, double double_arg); Parameters with a * prefix are aligned one character to the left so that the actual names are aligned. Struct Format and Content ------------------------- Usually, avoid adding a comment alongside declarations unless it is a very short comment. The following example uses meaningless x y z field names (sorry), but but does show a short prefix related to the struct name. Generally struct members should have a prefix common to that struct and hopefully distinct from other struct declarations. This short prefix makes it much easier to find all uses of a particular field in the code (with grep). struct Dwarf_Nothing_Special_s { int ns_x; /* usually avoid comment here this is Yuck! and this is even worse as continuation. Yuck! */ /* Comment here about y with blank line above and belows to make it clear which line referred to. */ unsigned ns_y; unsigned ns_z; }; Managing nested blocks ---------------------- Long blocks that are deeply nested make the code very hard to read. Fortunately such blocks often indicate logically distinct chunks of functionality that are begging to be split into their own functions. Please listen to the blocks when they beg. You will notice many exceptions to this in the code, unfortunately. In other cases, gratuitous nesting comes about because the primary functionality gets buried in a nested block rather than living at the primary level where it belongs. Consider the following: foo = malloc (sizeof (foo_t)); if (foo) { /* Yuck! The error return becomes hard to see. */ ... /* lots of code to initialize foo */ ... return DW_DLV_OK; } _dwarf_error(dbg,error,DW_DLE_MALLOC_RETURNS_NULL); return DW_DLV_ERROR; This kind of gratuitous nesting can be avoided by following a pattern of handling exceptional cases early and returning: foo = malloc (sizeof (foo_t)); /* A test foo == NULL is fine but the following is better as there is no danger of turning == into = by accident. */ if (!foo) { _dwarf_error(dbg,error,DW_DLE_MALLOC_RETURNS_NULL); return DW_DLV_ERROR; } ... lots of code to initialize foo */ return DW_DLV_OK; The return statement is often the best thing to use in a pattern like this. If it's not available due to additional nesting above which require some cleanup after the current block, then consider splitting the current block into a new function before using goto. Test or Loop with Side Effect ----------------------------- Never do: if ((foo = malloc (sizeof (foo_t)))) { or if (foo = malloc (sizeof (foo_t))) { as the reader has to think carefully about it, whereas foo = malloc (sizeof (foo_t)); if (foo) { is more transparent (in some sense) and makes it easier to stop( in debugger) or add a printf in case this is a point where things might be going wrong somehow. Also see "Managing nested blocks" just above. Macro Tests Commented --------------------- #ifdef SOME_MACRO #else /* !SOME_MACRO */ #endif /* !SOME_MACRO */ #ifdef OTHER_MACRO #endif /* OTHER_MACRO */ The comments add clarity when one is not familiar with code in the area but are not required if the #else #endif are within a couple lines of the #if(def). In a spot with nested #if(def) the comments become necessary to avoid confusing the reader. There is nothing wrong with adding them everywhere. Lookup Tables ----------------- Any situation requiring a lookup table should use one or the other tsearch functions. The practical ones are dwarf_tsearchhash.c and dwarf_tsearchbal.c. dwarfdump and libdwarf each use one of them and only one of them. See the tsearch directory to see the full set available. These use the traditional UNIX tsearch arguments and return values even though those are not good designs by current standards. Expanded to have destroy() functions whose prototype was copied from GNU man pages. GNU libc has much nicer (in the sense of much nicer interface designs) non-standard tsearch functions, but we've ignored those to keep to the official Single Unix Specification standard interfaces. Libdwarf Namespace ----------------- In libdwarf we are careful to name things visible to callers (and in libdwarf.h) starting with with dwarf (for public stuff) or _dwarf (for functions in the library not intended for public use. Structs begin with Dwarf. Macros begin with DW (dwarf.h is full of those!). Memory allocation ----------------- In general, be wary of performing any arithmetic operations in an argument to malloc. You should explicitly check for integer overflow yourself in any more complex situations. In libdwarf most allocations use _dwarf_alloc() instead of malloc. And the tables of valid types (which are predefined in libdwarf) allow for constructor/destructor functions. The _dwarf_alloc() code keeps a record of what is allocated so a careless user can simply call dwarf_finish() at the end and all the allocated data will be freed that was not already freed via user calls to dwarf_dealloc(). Checking For Overflow --------------------- Libdwarf and dwarfdump are often dealing with offsets and indexes read from disk object files and all such should be checked before use. That approach means that dwarfdump (and libdwarf callers in general) need not check the things that libdwarf has returned (at least those libdwarf could check). When it is possible that X +Y might overflow make every effort to check X an Y independently before attempting an addition. If you are confident X and Y are sensible (given available data like section sizes) you can add them and then determine if the sum (say an offset) is still within the relevant section or data-item usable range. There are many libdwarf-internal functions to read data from an object, and all of them require an end-pointer argument so the code can easly check for corrupt object-file or DWARF values without duplicating the error-code-setting. Dwarfdump Flags Data --------------------- Dwarfdump has a large number of options and nearly all the option values are recorded as fields in a single global structure glflags (see dwarfdump.c). Option data not in that structure should be moved into it, in general. This makes it much simpler to find instances using flags and to know, reading dwarfdump source, when flags are being referred to.. The text in this document (not the examples!) was formatted with the vi command "!}fmt -64"...without the quotes. dwarfutils-20200114/compile000077500000000000000000000162451361531463500155260ustar00rootroot00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2014 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dwarfutils-20200114/config.guess000077500000000000000000001263731361531463500164740ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval "$set_cc_for_build" cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" # If ldd exists, use it to detect musl libc. if command -v ldd >/dev/null && \ ldd --version 2>&1 | grep -q ^musl then LIBC=musl fi ;; esac # Note: order is significant - the case branches are not exclusive. case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ [ "$TARGET_BINARY_INTERFACE"x = x ] then echo m88k-dg-dgux"$UNAME_RELEASE" else echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) case "$UNAME_MACHINE" in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) if objdump -f /bin/sh | grep -q elf32-x86-64; then echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 else echo "$UNAME_MACHINE"-pc-linux-"$LIBC" fi exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; NSV-*:NONSTOP_KERNEL:*:*) echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dwarfutils-20200114/config.h.in000066400000000000000000000124521361531463500161670ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Set to 1 as we are building with libelf */ #undef DWARF_WITH_LIBELF /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define 1 if including a custom libelf library */ #undef HAVE_CUSTOM_LIBELF /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Set to 1 if the elf64_getehdr function is in libelf. */ #undef HAVE_ELF64_GETEHDR /* Set to 1 if the elf64_getshdr function is in libelf. */ #undef HAVE_ELF64_GETSHDR /* Set to 1 if Elf64_Rela defined in elf.h. */ #undef HAVE_ELF64_RELA /* Set to 1 if Elf64_Rel structure as r_info field. */ #undef HAVE_ELF64_R_INFO /* Set to 1 if Elf64_Sym defined in elf.h. */ #undef HAVE_ELF64_SYM /* Define to 1 if you have the header file. */ #undef HAVE_ELFACCESS_H /* Define to 1 if you have the header file. */ #undef HAVE_ELF_H /* Define to 1 if the system has the type `intptr_t'. */ #undef HAVE_INTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBELF_H /* Define to 1 if you have the header file. */ #undef HAVE_LIBELF_LIBELF_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define 1 if need nonstandard printf format for 64bit */ #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT /* Set to 1 if old frame columns are enabled. */ #undef HAVE_OLD_FRAME_CFA_COL /* Set to 1 if regex is usable. */ #undef HAVE_REGEX /* Define to 1 if you have the header file. */ #undef HAVE_REGEX_H /* Define to 1 if you have the header file. */ #undef HAVE_SGIDEFS_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ELF_386_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ELF_AMD64_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ELF_SPARC_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IA64_ELF_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if the system has the type `uintptr_t'. */ #undef HAVE_UINTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Set to 1 if __attribute__ ((unused)) is available. */ #undef HAVE_UNUSED_ATTRIBUTE /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* Define 1 if want to allow Windows full path detection */ #undef HAVE_WINDOWS_PATH /* Set to 1 if zlib decompression is available. */ #undef HAVE_ZLIB /* Define to 1 if you have the header file. */ #undef HAVE_ZLIB_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Set to 1 if bigendian build */ #undef WORDS_BIGENDIAN /* Define to the type of a signed integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef intptr_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t dwarfutils-20200114/config.h.in.cmake000066400000000000000000000134431361531463500172470ustar00rootroot00000000000000 /* Define if building universal (internal helper macro) */ #cmakedefine AC_APPLE_UNIVERSAL_BUILD 1 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #cmakedefine CRAY_STACKSEG_END 1 /* Define to 1 if using `alloca.c'. */ #cmakedefine C_ALLOCA 1 /* Set to 1 as we are building with libelf */ #cmakedefine DWARF_WITH_LIBELF /* Define to 1 if you have `alloca', as a function or macro. */ #cmakedefine HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #cmakedefine HAVE_ALLOCA_H 1 /* Define 1 if including a custom libelf library */ #cmakedefine HAVE_CUSTOM_LIBELF 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H 1 /* Set to 1 if the elf64_getehdr function is in libelf. */ #cmakedefine HAVE_ELF64_GETEHDR 1 /* Set to 1 if the elf64_getshdr function is in libelf. */ #cmakedefine HAVE_ELF64_GETSHDR 1 /* Set to 1 if Elf64_Rela defined in elf.h. */ #cmakedefine HAVE_ELF64_RELA 1 /* Set to 1 if Elf64_Rel structure as r_info field. */ #cmakedefine HAVE_ELF64_R_INFO 1 /* Set to 1 if Elf64_Sym defined in elf.h. */ #cmakedefine HAVE_ELF64_SYM 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ELFACCESS_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ELF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LIBELF_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LIBELF_LIBELF_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 /* Define 1 if need nonstandard printf format for 64bit */ #cmakedefine HAVE_NONSTANDARD_PRINTF_64_FORMAT 1 /* Set to 1 if old frame columns are enabled. */ #cmakedefine HAVE_OLD_FRAME_CFA_COL 1 /* Set to 1 if regex is usable. */ #cmakedefine HAVE_REGEX 1 /* Set to 1 if big endian . */ #cmakedefine WORDS_BIGENDIAN 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_REGEX_H 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_STDLIB_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_STRING_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ELF_386_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ELF_AMD64_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_ELF_SPARC_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_IA64_ELF_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 if the system does not define it. */ #cmakedefine uintptr_t ${uintptr_t} #cmakedefine intptr_t ${intptr_t} /* 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 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_WINDOWS_H 1 /* Define 1 if want to allow Windows full path detection */ #cmakedefine HAVE_WINDOWS_PATH 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 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #cmakedefine LT_OBJDIR 1 /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #cmakedefine NO_MINUS_C_MINUS_O 1 /* Name of package */ #cmakedefine PACKAGE /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME libdwarf /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING "${PACKAGE_NAME} ${VERSION}" /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME /* Define to the home page for this package. */ #cmakedefine PACKAGE_URL "${tarname}" ) /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #cmakedefine STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} /* Version number of package */ #cmakedefine VERSION ${VERSION} /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # cmakedefine WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to `unsigned int' if does not define. */ #undef size_t dwarfutils-20200114/config.sub000077500000000000000000001064501361531463500161310ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo "$1" | sed 's/-[^-]*$//'` if [ "$basic_machine" != "$1" ] then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2*) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsv-tandem) basic_machine=nsv-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh5el) basic_machine=sh5le-unknown ;; simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; x64) basic_machine=x86_64-pc ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases that might get confused # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # es1800 is here to avoid being matched by es* (a different OS) -es1800*) os=-ose ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -xray | -os68k* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4*) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $basic_machine in arm*) os=-eabi ;; *) os=-elf ;; esac ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; pru-*) os=-elf ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac echo "$basic_machine$os" exit # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dwarfutils-20200114/configure000077500000000000000000023753551361531463500160730ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for libdwarf 20200114. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and libdwarf-list -at- $0: linuxmail -dot- org about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libdwarf' PACKAGE_TARNAME='libdwarf' PACKAGE_VERSION='20200114' PACKAGE_STRING='libdwarf 20200114' PACKAGE_BUGREPORT='libdwarf-list -at- linuxmail -dot- org' PACKAGE_URL='' ac_unique_file="configure.ac" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS ALLOCA DWARF_CFLAGS_WARN DWARF_CXXFLAGS_WARN struct_elf DWARF_LIBS CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX release_info version_info CPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED LIBTOOL OBJDUMP DLLTOOL AS AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC ac_ct_AR AR HAVE_WIN32_FALSE HAVE_WIN32_TRUE host_os host_vendor host_cpu host build_os build_vendor build_cpu build dwarf_namestable HAVE_DWARFEXAMPLE_FALSE HAVE_DWARFEXAMPLE_TRUE HAVE_DWARFGEN_FALSE HAVE_DWARFGEN_TRUE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dwarfgen enable_dwarfexample enable_sanitize enable_oldframecol enable_namestable enable_libelf enable_windowspath enable_wall enable_nonstandardprintf enable_havecustomlibelf enable_dependency_tracking enable_silent_rules enable_shared enable_static with_pic enable_fast_install with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CPP CXX CXXFLAGS CCC CXXCPP DWARF_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libdwarf 20200114 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libdwarf] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libdwarf 20200114:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-dwarfgen enable dwarfgen compilation [default=no] --enable-dwarfexample enable dwarfexample compilation [default=no] --enable-sanitize enable sanitize compiler option [default=no] --enable-oldframecol enable old frame columns [default=no] --enable-namestable enable name string functions implemented as binary search (default is with C switch) [default=no] --disable-libelf disable use of libelf (default is enable) [default=yes] --enable-windowspath Detect certain Windows paths as full paths (default is NO) --enable-wall enable -Wall and other options [default=no] --enable-nonstandardprintf Use a special printf format for 64bit (default is NO) --enable-havecustomlibelf including a custom libelf library (default is NO) --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-shared[=PKGS] build shared libraries [default=no] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor DWARF_LIBS linker flags when linking libdwarf Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libdwarf configure 20200114 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ----------------------------------------------------- ## ## Report this to libdwarf-list -at- linuxmail -dot- org ## ## ----------------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libdwarf $as_me 20200114, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" ### Additional options to configure # Check whether --enable-dwarfgen was given. if test "${enable_dwarfgen+set}" = set; then : enableval=$enable_dwarfgen; if test "x${enableval}" = "xyes"; then : enable_dwarfgen="yes" else enable_dwarfgen="no" fi else enable_dwarfgen="no" fi if test "x${enable_dwarfgen}" = "xyes"; then HAVE_DWARFGEN_TRUE= HAVE_DWARFGEN_FALSE='#' else HAVE_DWARFGEN_TRUE='#' HAVE_DWARFGEN_FALSE= fi # Check whether --enable-dwarfexample was given. if test "${enable_dwarfexample+set}" = set; then : enableval=$enable_dwarfexample; if test "x${enableval}" = "xyes"; then : enable_dwarfexample="yes" else enable_dwarfexample="no" fi else enable_dwarfexample="no" fi if test "x${enable_dwarfexample}" = "xyes"; then HAVE_DWARFEXAMPLE_TRUE= HAVE_DWARFEXAMPLE_FALSE='#' else HAVE_DWARFEXAMPLE_TRUE='#' HAVE_DWARFEXAMPLE_FALSE= fi # Check whether --enable-sanitize was given. if test "${enable_sanitize+set}" = set; then : enableval=$enable_sanitize; if test "x${enableval}" = "xyes"; then : enable_sanitize="yes" else enable_sanitize="no" fi else enable_sanitize="no" fi # Check whether --enable-oldframecol was given. if test "${enable_oldframecol+set}" = set; then : enableval=$enable_oldframecol; if test "x${enableval}" = "xyes"; then : enable_oldframecol="yes" else enable_oldframecol="no" fi else enable_oldframecol="no" fi if test "x${enable_oldframecol}" = "xyes"; then : $as_echo "#define HAVE_OLD_FRAME_CFA_COL 1" >>confdefs.h fi # Check whether --enable-namestable was given. if test "${enable_namestable+set}" = set; then : enableval=$enable_namestable; if test "x${enableval}" = "xyes"; then : enable_namestable="yes" else enable_namestable="no" fi else enable_namestable="no" fi if test "x${enable_namestable}" = "xyes"; then : dwarf_namestable=-s else dwarf_namestable=-t fi # Check whether --enable-libelf was given. if test "${enable_libelf+set}" = set; then : enableval=$enable_libelf; if test "x${enableval}" = "xyes"; then : dwarf_with_libelf="yes" else dwarf_with_libelf="no" fi else dwarf_with_libelf="yes" fi # Check whether --enable-windowspath was given. if test "${enable_windowspath+set}" = set; then : enableval=$enable_windowspath; $as_echo "#define HAVE_WINDOWS_PATH 1" >>confdefs.h enable_windowspath="yes" else enable_windowspath="no" fi # Check whether --enable-wall was given. if test "${enable_wall+set}" = set; then : enableval=$enable_wall; if test "x${enableval}" = "xyes"; then : enable_wall="yes" else enable_wall="no" fi else enable_wall="no" fi # Check whether --enable-nonstandardprintf was given. if test "${enable_nonstandardprintf+set}" = set; then : enableval=$enable_nonstandardprintf; $as_echo "#define HAVE_NONSTANDARD_PRINTF_64_FORMAT 1" >>confdefs.h enable_nonstandardprintf="yes" else enable_nonstandardprintf="no" fi # Check whether --enable-havecustomlibelf was given. if test "${enable_havecustomlibelf+set}" = set; then : enableval=$enable_havecustomlibelf; $as_echo "#define HAVE_CUSTOM_LIBELF 1" >>confdefs.h enable_havecustomlibelf="yes" else enable_havecustomlibelf="no" fi ### Default options with respect to host ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac have_win32="no" case "$host_os" in mingw*) have_win32="yes" ;; esac if test "x${have_win32}" = "xyes"; then HAVE_WIN32_TRUE= HAVE_WIN32_FALSE='#' else HAVE_WIN32_TRUE='#' HAVE_WIN32_FALSE= fi ### Checks for programs # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac ### We don't use dist-xz *.xz output from make dist, ### so don't mention it. am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libdwarf' VERSION='20200114' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.6' macro_revision='2.4.6' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 $as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 $as_echo_n "checking for a working dd... " >&6; } if ${ac_cv_path_lt_DD+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in dd; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 $as_echo "$ac_cv_path_lt_DD" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 $as_echo_n "checking how to truncate binary pipes... " >&6; } if ${lt_cv_truncate_bin+:} false; then : $as_echo_n "(cached) " >&6 else printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 $as_echo "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012][,.]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 $as_echo "$AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AS+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 $as_echo "$ac_ct_AS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else enable_shared=no fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else enable_static=yes fi enable_dlopen=no # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else pic_mode=default fi # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 $as_echo_n "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test "${with_aix_soname+set}" = set; then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else if ${lt_cv_with_aix_soname+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 $as_echo "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report what library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: version_info="1:0:0" release_info="" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if ${ac_cv_prog_CXXCPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath__CXX+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test no = "$hard_links"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 $as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x$CC" != xcc; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h fi ###PKG_PROG_PKG_CONFIG Intentionally not using pkg-config ### Checks for libraries ### Checks for header files ### MacOS does not have malloc.h for ac_header in unistd.h sys/types.h regex.h malloc.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ### for uintptr_t for ac_header in stdint.h inttypes.h stddef.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in windows.h do : ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" if test "x$ac_cv_header_windows_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_WINDOWS_H 1 _ACEOF fi done for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF fi done if test "x${ac_cv_header_zlib_h}" = "xyes"; then : have_pc_zlib="yes" ; echo "have zlib" ; DWARF_LIBS="${DWARF_LIBS} -lz" else have_pc_zlib="no" ; echo "no zlib" fi ### for use in casts to uint to avoid 32bit warnings. ### Also needed by C++ cstdint ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : $as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h else for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define uintptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" if test "x$ac_cv_type_intptr_t" = xyes; then : $as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h else for ac_type in 'int' 'long int' 'long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat >>confdefs.h <<_ACEOF #define intptr_t $ac_type _ACEOF ac_type= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test -z "$ac_type" && break done fi ### Now we know uintptr_t is either in stdint.h or ### is defined in config.h by configure. # test Elf headers in the preprocessor path search CPPFLAGS_save=${CPPFLAGS} ### we set $dwarf_with_libelf above. if test $dwarf_with_libelf = "yes" ; then for ac_header in sgidefs.h do : ac_fn_c_check_header_mongrel "$LINENO" "sgidefs.h" "ac_cv_header_sgidefs_h" "$ac_includes_default" if test "x$ac_cv_header_sgidefs_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SGIDEFS_H 1 _ACEOF fi done for ac_header in libelf.h libelf/libelf.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in elf.h elfaccess.h sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h sys/ia64/elf.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ### if no libelf.h add no -lelf and turn off ### libelf recognition. if test "x${ac_cv_header_libelf_h}" != "xyes" -a "x${ac_cv_header_libelf_libelf_h}" != "xyes" ; then : dwarf_with_libelf="no" echo "no libelf headers, no libelf" else DWARF_LIBS="${DWARF_LIBS} -lelf" dwarf_with_libelf="yes" echo "Allowing use of libelf." $as_echo "#define DWARF_WITH_LIBELF 1" >>confdefs.h fi ### begin checking for Elf structs # Elf64_Rela in elf.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rela p; p.r_offset = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_RELA 1" >>confdefs.h have_elf64_rela="yes" else have_elf64_rela="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x${have_elf64_rela}" = "xno"; then : CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rela p; p.r_offset = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_RELA 1" >>confdefs.h have_elf64_rela="yes" else have_elf64_rela="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS=${CPPFLAGS_save} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Elf64_Rela in elf.h" >&5 $as_echo_n "checking for Elf64_Rela in elf.h... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_elf64_rela}" >&5 $as_echo "${have_elf64_rela}" >&6; } # Elf64_Rel in elf.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rel p; p.r_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_R_INFO 1" >>confdefs.h have_elf64_rel="yes" else have_elf64_rel="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x${have_elf64_rel}" = "xno"; then : CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Rel p; p.r_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_R_INFO 1" >>confdefs.h have_elf64_rel="yes" else have_elf64_rel="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS=${CPPFLAGS_save} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Elf64_Rel in elf.h" >&5 $as_echo_n "checking for Elf64_Rel in elf.h... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_elf64_rel}" >&5 $as_echo "${have_elf64_rel}" >&6; } # Elf64_Sym in elf.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Sym p; p.st_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_SYM 1" >>confdefs.h have_elf64_sym="yes" else have_elf64_sym="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "x${have_elf64_sym}" = "xno"; then : CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif int main () { Elf64_Sym p; p.st_info = 1; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ELF64_SYM 1" >>confdefs.h have_elf64_sym="yes" else have_elf64_sym="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS=${CPPFLAGS_save} fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Elf64_Sym in elf.h" >&5 $as_echo_n "checking for Elf64_Sym in elf.h... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_elf64_sym}" >&5 $as_echo "${have_elf64_sym}" >&6; } ### end checking for Elf structs ### Checks for Elf structures # test if struct _Elf is used instead of struct Elf cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif /* This must be at global scope */ struct _Elf; typedef struct _Elf Elf; int main () { struct _Elf *a = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_struct__elf="yes" struct_elf="struct _Elf" else have_struct__elf="no" struct_elf="struct Elf" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct _Elf is used" >&5 $as_echo_n "checking whether struct _Elf is used... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_struct__elf}" >&5 $as_echo "${have_struct__elf}" >&6; } else ### end where dwarf_with_libelf == "no" via ### --disable-libelf have_struct__elf="no" struct_elf="struct Elf" have_elf64_rela="no" have_elf64_rel="no" have_elf64_sym="no" fi ### Checks for compiler characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac # gcc accepts even totally bogus -Wno flags. Other compilers..no # -Wno-long-long suppresses warnings on 'long long' # -Wno-pedantic-ms-format (which only exists in mingw) # suppresses warnings about I64 printf format. if test "x$enable_wall" = "xyes" ; then : cxx_compiler_flags="-Wall -Wextra -Wno-unused-private-field -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror" c_compiler_flags="-Wall -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Wmissing-prototypes -Wdeclaration-after-statement -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs -Werror" fi if test "x$enable_nonstandardprintf" = "xyes" ; then : cxx_compiler_flags="$cxx_compiler_flags -Wno-pedantic-ms-format" c_compiler_flags="$c_compiler_flags -Wno-pedantic-ms-format" fi option="${cxx_compiler_flags}" CXXFLAGS_save="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${option}" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports ${cxx_compiler_flags}" >&5 $as_echo_n "checking whether the C++ compiler supports ${cxx_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CXXFLAGS="${CXXFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CXXFLAGS_WARN="${DWARF_CXXFLAGS_WARN} ${cxx_compiler_flags}" fi if test "${have_flag}" != "yes"; then : option="${cxx_compiler_flags}" CXXFLAGS_save="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${option}" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports ${cxx_compiler_flags}" >&5 $as_echo_n "checking whether the C++ compiler supports ${cxx_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CXXFLAGS="${CXXFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CXXFLAGS_WARN="${DWARF_CXXFLAGS_WARN} ${cxx_compiler_flags}" fi fi option="${c_compiler_flags}" CFLAGS_save="${CFLAGS}" CFLAGS="${CFLAGS} ${option}" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler supports ${c_compiler_flags}" >&5 $as_echo_n "checking whether the C compiler supports ${c_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CFLAGS="${CFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CFLAGS_WARN="${DWARF_CFLAGS_WARN} ${c_compiler_flags}" fi if test "${have_flag}" != "yes"; then : option="${c_compiler_flags}" CFLAGS_save="${CFLAGS}" CFLAGS="${CFLAGS} ${option}" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler supports ${c_compiler_flags}" >&5 $as_echo_n "checking whether the C compiler supports ${c_compiler_flags}... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_flag="yes" else have_flag="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_flag}" >&5 $as_echo "${have_flag}" >&6; } ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CFLAGS="${CFLAGS_save}" if test "x${have_flag}" = "xyes"; then : DWARF_CFLAGS_WARN="${DWARF_CFLAGS_WARN} ${c_compiler_flags}" fi fi # unused attribute cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ static unsigned int foo(unsigned int x, __attribute__ ((unused)) int y){ unsigned int x2 = x + 1; return x2; } int goo() { unsigned int y = 0; y = foo(12, y); } int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : have_unused="yes" $as_echo "#define HAVE_UNUSED_ATTRIBUTE 1" >>confdefs.h else have_unused="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \"unused\" attribute is available" >&5 $as_echo_n "checking whether \"unused\" attribute is available... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_unused}" >&5 $as_echo "${have_unused}" >&6; } # sanitize if test "x${enable_sanitize}" = "xyes"; then : CFLAGS_save=${CFLAGS} CFLAGS="${CFLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined" DWARF_CFLAGS= cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : enable_sanitize="yes" DWARF_CFLAGS="$DWARF_CFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined" LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined" else enable_sanitize="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS="${CFLAGS_save} ${DWARF_CFLAGS}" DWARF_CFLAGS= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sanitize options are used" >&5 $as_echo_n "checking whether sanitize options are used... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${enable_sanitize}" >&5 $as_echo "${enable_sanitize}" >&6; } ### Checks for linker characteristics ### Checks for library functions ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi if test $dwarf_with_libelf = "yes" ; then # elf64_getehdr CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS}" LIBS_save=${LIBS} LIBS="${LIBS} ${DWARF_LIBS}" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing elf64_getehdr" >&5 $as_echo_n "checking for library containing elf64_getehdr... " >&6; } if ${ac_cv_search_elf64_getehdr+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char elf64_getehdr (); int main () { return elf64_getehdr (); ; return 0; } _ACEOF for ac_lib in '' elf; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_elf64_getehdr=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_elf64_getehdr+:} false; then : break fi done if ${ac_cv_search_elf64_getehdr+:} false; then : else ac_cv_search_elf64_getehdr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_elf64_getehdr" >&5 $as_echo "$ac_cv_search_elf64_getehdr" >&6; } ac_res=$ac_cv_search_elf64_getehdr if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_getehdr="yes" $as_echo "#define HAVE_ELF64_GETEHDR 1" >>confdefs.h else have_getehdr="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing elf64_getshdr" >&5 $as_echo_n "checking for library containing elf64_getshdr... " >&6; } if ${ac_cv_search_elf64_getshdr+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char elf64_getshdr (); int main () { return elf64_getshdr (); ; return 0; } _ACEOF for ac_lib in '' elf; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_elf64_getshdr=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_elf64_getshdr+:} false; then : break fi done if ${ac_cv_search_elf64_getshdr+:} false; then : else ac_cv_search_elf64_getshdr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_elf64_getshdr" >&5 $as_echo "$ac_cv_search_elf64_getshdr" >&6; } ac_res=$ac_cv_search_elf64_getshdr if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_getshdr="yes" $as_echo "#define HAVE_ELF64_GETSHDR 1" >>confdefs.h else have_getshdr="no" fi CPPFLAGS=${CPPFLAGS_save} LIBS=${LIBS_save} else have_getehdr="no" have_getshdr="no" fi if test "x${have_pc_zlib}" = "xno" -a "x${have_zlib}" = "xyes"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing z" >&5 $as_echo_n "checking for library containing z... " >&6; } if ${ac_cv_search_z+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char z (); int main () { return z (); ; return 0; } _ACEOF for ac_lib in '' have_zlib="yes"; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_z=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_z+:} false; then : break fi done if ${ac_cv_search_z+:} false; then : else ac_cv_search_z=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_z" >&5 $as_echo "$ac_cv_search_z" >&6; } ac_res=$ac_cv_search_z if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_zlib="no" fi fi if test "x${have_pc_zlib}" = "xyes" -o "x${have_zlib}" = "xyes"; then : have_zlib="yes" $as_echo "#define HAVE_ZLIB 1" >>confdefs.h else have_zlib="no" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_REGEX_H # include #endif int main () { int i; regex_t r; int cflags = REG_EXTENDED; const char *s = "abc"; i = regcomp(&r,s,cflags); regfree(&r); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_REGEX 1" >>confdefs.h have_regex="yes" else have_regex="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for regex library" >&5 $as_echo_n "checking for regex library... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${have_regex}" >&5 $as_echo "${have_regex}" >&6; } ### Checks for system services ac_config_files="$ac_config_files Makefile libdwarf/Makefile dwarfdump/Makefile dwarfgen/Makefile dwarfexample/Makefile" ### libdwarf needs to be adjusted to support struct Elf ### or struct _Elf, whichever the system defines in libelf. ac_config_commands="$ac_config_commands libdwarf/libdwarf.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${HAVE_DWARFGEN_TRUE}" && test -z "${HAVE_DWARFGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DWARFGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DWARFEXAMPLE_TRUE}" && test -z "${HAVE_DWARFEXAMPLE_FALSE}"; then as_fn_error $? "conditional \"HAVE_DWARFEXAMPLE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_WIN32_TRUE}" && test -z "${HAVE_WIN32_FALSE}"; then as_fn_error $? "conditional \"HAVE_WIN32\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libdwarf $as_me 20200114, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libdwarf config.status 20200114 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in AS \ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' haself=${have_struct__elf} top=${ac_pwd} src=${srcdir} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libdwarf/Makefile") CONFIG_FILES="$CONFIG_FILES libdwarf/Makefile" ;; "dwarfdump/Makefile") CONFIG_FILES="$CONFIG_FILES dwarfdump/Makefile" ;; "dwarfgen/Makefile") CONFIG_FILES="$CONFIG_FILES dwarfgen/Makefile" ;; "dwarfexample/Makefile") CONFIG_FILES="$CONFIG_FILES dwarfexample/Makefile" ;; "libdwarf/libdwarf.h") CONFIG_COMMANDS="$CONFIG_COMMANDS libdwarf/libdwarf.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; "libdwarf/libdwarf.h":C) sh $src/scripts/fixlibdwarfelf.sh $haself $src $top ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi echo echo "$PACKAGE $VERSION" echo echo "Configuration Options Summary:" echo echo " BuildOS..............: ${build_os}" echo " HostOS...............: ${host_os}" echo echo " shared library.......: ${enable_shared}" echo " static library.......: ${enable_static}" echo echo " zlib support.........: ${have_zlib}" echo " sanitize support.....: ${enable_sanitize}" echo " BuildOS-BigEndian....: ${ac_cv_c_bigendian}" echo echo " libdwarf.............: always" echo " old frame column...: ${enable_oldframecol}" echo " names table........: ${enable_namestable}" echo " elf64_getehdr......: ${have_getehdr}" echo " elf64_getshdr......: ${have_getshdr}" echo " Elf64_Rela.........: ${have_elf64_rela}" echo " Elf64_Sym..........: ${have_elf64_sym}" echo " Elf spelled........: ${struct_elf}" echo " libelf.............: ${dwarf_with_libelf}" echo " Windows path corr..: ${enable_windowspath}" echo " Nonstandardprintf..: ${enable_nonstandardprintf}" echo " Custom libelf......: ${enable_havecustomlibelf}" echo " dwarfdump............: always" echo " elf64_getehdr......: ${have_getehdr}" echo " Elf64_Rel (r_info).: ${have_elf64_rel}" echo " regex..............: ${have_regex}" echo " dwarfgen.............: ${enable_dwarfgen}" echo " dwarfexample.........: ${enable_dwarfexample}" echo echo "Compilation............: make (or gmake)" echo " CPPFLAGS.............: $CPPFLAGS" echo " CFLAGS...............: $CFLAGS ${c_compiler_flags}" echo " LDFLAGS..............: $LDFLAGS" echo " LIBS.................: $LIBS" echo " DWARF_LIBS...........: $DWARF_LIBS" echo echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" echo " prefix...............: $prefix" echo dwarfutils-20200114/configure.ac000066400000000000000000000421101361531463500164240ustar00rootroot00000000000000###Copyright (C) 2018 Vincent Torri ###This code is public domain and can be freely used or copied. dnl defines the version name of the libdwarf.so m4_define([v_maj], [1]) m4_define([v_min], [0]) m4_define([v_mic], [0]) ###m4_define([v_ver], [v_maj.v_min.v_mic]) ###Returning to older version, .so.1 m4_define([v_ver], [v_maj]) m4_define([v_rel], []) m4_define([lt_cur], [m4_eval(v_maj + v_min)]) m4_define([lt_rev], [v_mic]) m4_define([lt_age], [v_min]) ### Sets the release name. ###m4_define([v_date], [m4_esyscmd_s([date "+%Y%m%d"])]) m4_define([v_date], [20200114])]) AC_PREREQ([2.52]) ### 2nd arg to AC_INIT is the version 'number'. AC_INIT([libdwarf], [v_date], [libdwarf-list -at- linuxmail -dot- org]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIRS([m4]) ### Additional options to configure AC_ARG_ENABLE([dwarfgen], [AS_HELP_STRING([--enable-dwarfgen], [enable dwarfgen compilation @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_dwarfgen="yes"], [enable_dwarfgen="no"]) ], [enable_dwarfgen="no"]) AM_CONDITIONAL([HAVE_DWARFGEN], [test "x${enable_dwarfgen}" = "xyes"]) AC_ARG_ENABLE([dwarfexample], [AS_HELP_STRING([--enable-dwarfexample], [enable dwarfexample compilation @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_dwarfexample="yes"], [enable_dwarfexample="no"]) ], [enable_dwarfexample="no"]) AM_CONDITIONAL([HAVE_DWARFEXAMPLE], [test "x${enable_dwarfexample}" = "xyes"]) AC_ARG_ENABLE([sanitize], [AS_HELP_STRING([--enable-sanitize], [enable sanitize compiler option @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_sanitize="yes"], [enable_sanitize="no"]) ], [enable_sanitize="no"]) AC_ARG_ENABLE([oldframecol], [AS_HELP_STRING([--enable-oldframecol], [enable old frame columns @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_oldframecol="yes"], [enable_oldframecol="no"]) ], [enable_oldframecol="no"]) AS_IF( [test "x${enable_oldframecol}" = "xyes"], [AC_DEFINE( [HAVE_OLD_FRAME_CFA_COL], [1], [Set to 1 if old frame columns are enabled.])]) AC_ARG_ENABLE([namestable], [AS_HELP_STRING([--enable-namestable], [enable name string functions implemented as binary search (default is with C switch) @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_namestable="yes"], [enable_namestable="no"]) ], [enable_namestable="no"]) AS_IF( [test "x${enable_namestable}" = "xyes"], [AC_SUBST([dwarf_namestable], [-s])], [AC_SUBST([dwarf_namestable], [-t])]) AC_ARG_ENABLE([libelf], [AS_HELP_STRING([--disable-libelf], [disable use of libelf (default is enable) @<:@default=yes@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [dwarf_with_libelf="yes"], [dwarf_with_libelf="no"]) ], [dwarf_with_libelf="yes"]) AC_ARG_ENABLE([windowspath], [AS_HELP_STRING([--enable-windowspath], [Detect certain Windows paths as full paths (default is NO)])], [ AC_DEFINE([HAVE_WINDOWS_PATH],[1], [Define 1 if want to allow Windows full path detection] ) [enable_windowspath="yes"] ], [ enable_windowspath="no" ]) AC_ARG_ENABLE([wall], [AS_HELP_STRING([--enable-wall], [enable -Wall and other options @<:@default=no@:>@])], [ AS_IF( [test "x${enableval}" = "xyes"], [enable_wall="yes"], [enable_wall="no"]) ], [enable_wall="no"]) AC_ARG_ENABLE(nonstandardprintf,AS_HELP_STRING([--enable-nonstandardprintf], [Use a special printf format for 64bit (default is NO)]), [ AC_DEFINE([HAVE_NONSTANDARD_PRINTF_64_FORMAT],[1], [Define 1 if need nonstandard printf format for 64bit] ) [enable_nonstandardprintf="yes"] ], [enable_nonstandardprintf="no"]) AC_ARG_ENABLE(havecustomlibelf,AS_HELP_STRING([--enable-havecustomlibelf], [including a custom libelf library (default is NO)]), [ AC_DEFINE([HAVE_CUSTOM_LIBELF],[1], [Define 1 if including a custom libelf library] ) [enable_havecustomlibelf="yes"] ], [enable_havecustomlibelf="no"]) ### Default options with respect to host AC_CANONICAL_HOST have_win32="no" case "$host_os" in mingw*) have_win32="yes" ;; esac AM_CONDITIONAL([HAVE_WIN32], [test "x${have_win32}" = "xyes"]) ### Checks for programs AM_PROG_AR ### We don't use dist-xz *.xz output from make dist, ### so don't mention it. AM_INIT_AUTOMAKE([1.6]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) LT_INIT([win32-dll disable-shared static]) version_info="lt_cur:lt_rev:lt_age" release_info="v_rel" AC_SUBST([version_info]) AC_SUBST([release_info]) AC_PROG_CC AC_PROG_CXX AC_PROG_CC_C_O ###PKG_PROG_PKG_CONFIG Intentionally not using pkg-config ### Checks for libraries AC_SUBST([DWARF_LIBS]) AC_ARG_VAR([DWARF_LIBS], [linker flags when linking libdwarf]) ### Checks for header files ### MacOS does not have malloc.h AC_CHECK_HEADERS([unistd.h sys/types.h regex.h malloc.h]) ### for uintptr_t AC_CHECK_HEADERS([stdint.h inttypes.h stddef.h]) AC_CHECK_HEADERS([windows.h]) AC_CHECK_HEADERS([zlib.h]) AS_IF( [test "x${ac_cv_header_zlib_h}" = "xyes"], [ have_pc_zlib="yes" ; echo "have zlib" ; DWARF_LIBS="${DWARF_LIBS} -lz" ], [ have_pc_zlib="no" ; echo "no zlib" ]) ### for use in casts to uint to avoid 32bit warnings. ### Also needed by C++ cstdint AC_TYPE_UINTPTR_T AC_TYPE_INTPTR_T ### Now we know uintptr_t is either in stdint.h or ### is defined in config.h by configure. # test Elf headers in the preprocessor path search CPPFLAGS_save=${CPPFLAGS} ### we set $dwarf_with_libelf above. if test $dwarf_with_libelf = "yes" ; then AC_CHECK_HEADERS([sgidefs.h]) AC_CHECK_HEADERS([libelf.h libelf/libelf.h]) AC_CHECK_HEADERS([elf.h elfaccess.h sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h sys/ia64/elf.h]) ### if no libelf.h add no -lelf and turn off ### libelf recognition. AS_IF([test "x${ac_cv_header_libelf_h}" != "xyes" -a "x${ac_cv_header_libelf_libelf_h}" != "xyes" ], [ dwarf_with_libelf="no" echo "no libelf headers, no libelf" ], [ DWARF_LIBS="${DWARF_LIBS} -lelf" dwarf_with_libelf="yes" echo "Allowing use of libelf." AC_DEFINE([DWARF_WITH_LIBELF],[1], [Set to 1 as we are building with libelf]) ]) ### begin checking for Elf structs # Elf64_Rela in elf.h AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rela p; p.r_offset = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_RELA], [1], [Set to 1 if Elf64_Rela defined in elf.h.]) have_elf64_rela="yes" ], [have_elf64_rela="no"]) AS_IF( [test "x${have_elf64_rela}" = "xno"], [ CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rela p; p.r_offset = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_RELA], [1], [Set to 1 if Elf64_Rela defined in elf.h.]) have_elf64_rela="yes" ], [have_elf64_rela="no"]) CPPFLAGS=${CPPFLAGS_save} ]) AC_MSG_CHECKING([for Elf64_Rela in elf.h]) AC_MSG_RESULT([${have_elf64_rela}]) # Elf64_Rel in elf.h AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rel p; p.r_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_R_INFO], [1], [Set to 1 if Elf64_Rel structure as r_info field.]) have_elf64_rel="yes" ], [have_elf64_rel="no"]) AS_IF( [test "x${have_elf64_rel}" = "xno"], [ CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Rel p; p.r_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_R_INFO], [1], [Set to 1 if Elf64_Rel structure as r_info field.]) have_elf64_rel="yes" ], [have_elf64_rel="no"]) CPPFLAGS=${CPPFLAGS_save} ]) AC_MSG_CHECKING([for Elf64_Rel in elf.h]) AC_MSG_RESULT([${have_elf64_rel}]) # Elf64_Sym in elf.h AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Sym p; p.st_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_SYM], [1], [Set to 1 if Elf64_Sym defined in elf.h.]) have_elf64_sym="yes" ], [have_elf64_sym="no"]) AS_IF( [test "x${have_elf64_sym}" = "xno"], [ CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS} -D__LIBELF64" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_ELF_H # include #endif #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif ]], [[ Elf64_Sym p; p.st_info = 1; ]]) ], [ AC_DEFINE([HAVE_ELF64_SYM], [1], [Set to 1 if Elf64_Sym defined in elf.h.]) have_elf64_sym="yes" ], [have_elf64_sym="no"]) CPPFLAGS=${CPPFLAGS_save} ]) AC_MSG_CHECKING([for Elf64_Sym in elf.h]) AC_MSG_RESULT([${have_elf64_sym}]) ### end checking for Elf structs ### Checks for Elf structures # test if struct _Elf is used instead of struct Elf AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_LIBELF_H # include #endif #ifdef HAVE_LIBELF_LIBELF_H # include #endif /* This must be at global scope */ struct _Elf; typedef struct _Elf Elf; ]], [[ struct _Elf *a = 0; ]]) ], [ have_struct__elf="yes" struct_elf="struct _Elf" ], [ have_struct__elf="no" struct_elf="struct Elf" ]) AC_MSG_CHECKING([whether struct _Elf is used]) AC_MSG_RESULT([${have_struct__elf}]) else ### end where dwarf_with_libelf == "no" via ### --disable-libelf have_struct__elf="no" struct_elf="struct Elf" have_elf64_rela="no" have_elf64_rel="no" have_elf64_sym="no" fi AC_SUBST([struct_elf]) ### Checks for compiler characteristics AC_C_BIGENDIAN([AC_DEFINE([WORDS_BIGENDIAN], [1], [Set to 1 if bigendian build])],,) # gcc accepts even totally bogus -Wno flags. Other compilers..no # -Wno-long-long suppresses warnings on 'long long' # -Wno-pedantic-ms-format (which only exists in mingw) # suppresses warnings about I64 printf format. AS_IF( [ test "x$enable_wall" = "xyes" ], [ cxx_compiler_flags="-Wall -Wextra -Wno-unused-private-field -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror" c_compiler_flags="-Wall -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Wmissing-prototypes -Wdeclaration-after-statement -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs -Werror" ] ) AS_IF( [ test "x$enable_nonstandardprintf" = "xyes" ], [ cxx_compiler_flags="$cxx_compiler_flags -Wno-pedantic-ms-format" c_compiler_flags="$c_compiler_flags -Wno-pedantic-ms-format" ] ) DWARF_CHECK_CXX_COMPILER_FLAGS([${cxx_compiler_flags}]) DWARF_CHECK_C_COMPILER_FLAGS([${c_compiler_flags}]) # unused attribute AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ static unsigned int foo(unsigned int x, __attribute__ ((unused)) int y){ unsigned int x2 = x + 1; return x2; } int goo() { unsigned int y = 0; y = foo(12, y); } ]], [[ ]]) ], [ have_unused="yes" AC_DEFINE( [HAVE_UNUSED_ATTRIBUTE], [1], [Set to 1 if __attribute__ ((unused)) is available.]) ], [have_unused="no"]) AC_MSG_CHECKING([whether "unused" attribute is available]) AC_MSG_RESULT([${have_unused}]) # sanitize AS_IF( [test "x${enable_sanitize}" = "xyes"], [ CFLAGS_save=${CFLAGS} CFLAGS="${CFLAGS} -fsanitize=address -fsanitize=leak -fsanitize=undefined" DWARF_CFLAGS= AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]], [[]])], [ enable_sanitize="yes" DWARF_CFLAGS="$DWARF_CFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined" LDFLAGS="$LDFLAGS -fsanitize=address -fsanitize=leak -fsanitize=undefined" ], [enable_sanitize="no"]) CFLAGS="${CFLAGS_save} ${DWARF_CFLAGS}" DWARF_CFLAGS= ]) AC_MSG_CHECKING([whether sanitize options are used]) AC_MSG_RESULT([${enable_sanitize}]) ### Checks for linker characteristics ### Checks for library functions AC_FUNC_ALLOCA if test $dwarf_with_libelf = "yes" ; then # elf64_getehdr CPPFLAGS_save=${CPPFLAGS} CPPFLAGS="${CPPFLAGS}" LIBS_save=${LIBS} LIBS="${LIBS} ${DWARF_LIBS}" AC_SEARCH_LIBS( [elf64_getehdr], [elf], [ have_getehdr="yes" AC_DEFINE( [HAVE_ELF64_GETEHDR], [1], [Set to 1 if the elf64_getehdr function is in libelf.]) ], [have_getehdr="no"]) AC_SEARCH_LIBS( [elf64_getshdr], [elf], [ have_getshdr="yes" AC_DEFINE( [HAVE_ELF64_GETSHDR], [1], [Set to 1 if the elf64_getshdr function is in libelf.]) ], [have_getshdr="no"]) CPPFLAGS=${CPPFLAGS_save} LIBS=${LIBS_save} else have_getehdr="no" have_getshdr="no" fi AS_IF( [test "x${have_pc_zlib}" = "xno" -a "x${have_zlib}" = "xyes"], [AC_SEARCH_LIBS([z], [have_zlib="yes"], [have_zlib="no"])]) AS_IF( [test "x${have_pc_zlib}" = "xyes" -o "x${have_zlib}" = "xyes"], [ have_zlib="yes" AC_DEFINE([HAVE_ZLIB], [1], [Set to 1 if zlib decompression is available.]) ], [ have_zlib="no" ]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [[ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_REGEX_H # include #endif ]], [[ int i; regex_t r; int cflags = REG_EXTENDED; const char *s = "abc"; i = regcomp(&r,s,cflags); regfree(&r); ]]) ], [ AC_DEFINE([HAVE_REGEX], [1], [Set to 1 if regex is usable.]) have_regex="yes" ], [have_regex="no"]) AC_MSG_CHECKING([for regex library]) AC_MSG_RESULT([${have_regex}]) ### Checks for system services AC_CONFIG_FILES([ Makefile libdwarf/Makefile dwarfdump/Makefile dwarfgen/Makefile dwarfexample/Makefile ]) ### libdwarf needs to be adjusted to support struct Elf ### or struct _Elf, whichever the system defines in libelf. AC_CONFIG_COMMANDS([libdwarf/libdwarf.h], [ sh $src/scripts/fixlibdwarfelf.sh $haself $src $top ], [ haself=${have_struct__elf} top=${ac_pwd} src=${srcdir} ] ) AC_OUTPUT echo echo "$PACKAGE $VERSION" echo echo "Configuration Options Summary:" echo echo " BuildOS..............: ${build_os}" echo " HostOS...............: ${host_os}" echo echo " shared library.......: ${enable_shared}" echo " static library.......: ${enable_static}" echo echo " zlib support.........: ${have_zlib}" echo " sanitize support.....: ${enable_sanitize}" echo " BuildOS-BigEndian....: ${ac_cv_c_bigendian}" echo echo " libdwarf.............: always" echo " old frame column...: ${enable_oldframecol}" echo " names table........: ${enable_namestable}" echo " elf64_getehdr......: ${have_getehdr}" echo " elf64_getshdr......: ${have_getshdr}" echo " Elf64_Rela.........: ${have_elf64_rela}" echo " Elf64_Sym..........: ${have_elf64_sym}" echo " Elf spelled........: ${struct_elf}" echo " libelf.............: ${dwarf_with_libelf}" echo " Windows path corr..: ${enable_windowspath}" echo " Nonstandardprintf..: ${enable_nonstandardprintf}" echo " Custom libelf......: ${enable_havecustomlibelf}" echo " dwarfdump............: always" echo " elf64_getehdr......: ${have_getehdr}" echo " Elf64_Rel (r_info).: ${have_elf64_rel}" echo " regex..............: ${have_regex}" echo " dwarfgen.............: ${enable_dwarfgen}" echo " dwarfexample.........: ${enable_dwarfexample}" echo echo "Compilation............: make (or gmake)" echo " CPPFLAGS.............: $CPPFLAGS" echo " CFLAGS...............: $CFLAGS ${c_compiler_flags}" echo " LDFLAGS..............: $LDFLAGS" echo " LIBS.................: $LIBS" echo " DWARF_LIBS...........: $DWARF_LIBS" echo echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')" echo " prefix...............: $prefix" echo dwarfutils-20200114/depcomp000077500000000000000000000560171361531463500155260ustar00rootroot00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2016-01-11.22; # UTC # Copyright (C) 1999-2017 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: dwarfutils-20200114/dwarfdump/000077500000000000000000000000001361531463500161315ustar00rootroot00000000000000dwarfutils-20200114/dwarfdump/CMakeLists.txt000066400000000000000000000162041361531463500206740ustar00rootroot00000000000000 set_source_group(SOURCES "Source Files" addrmap.c checkutil.c dwarfdump.c dwconf.c helpertree.c glflags.c command_options.c compiler_info.c dwarf_names.c macrocheck.c print_abbrevs.c print_aranges.c print_debugfission.c print_die.c print_dnames.c print_frames.c print_gdbindex.c print_lines.c print_locs.c print_macro.c print_macros.c print_pubnames.c print_ranges.c print_reloc.c print_str_offsets.c print_sections.c print_section_groups.c print_static_funcs.c print_static_vars.c print_strings.c print_types.c print_weaknames.c sanitized.c section_bitmaps.c strstrnocase.c true_section_name.c uri.c dwgetopt.c makename.c naming.c common.c esb.c dwarf_tsearchbal.c) set_source_group(HEADERS "Header Files" addrmap.h checkutil.h common.h dwconf.h command_options.h compiler_info.h dwarf_names.h dwconf_using_functions.h esb_using_functions.h dwarfdump-ta-ext-table.h dwarfdump-ta-table.h dwarfdump-tt-ext-table.h dwarfdump-tt-table.h dwgetopt.h esb.h glflags.h globals.h macrocheck.h defined_types.h makename.h dwarf_tsearch.h print_frames.h print_reloc.h print_reloc_decls.h section_bitmaps.h uri.h) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) add_executable(dwarfdump ${SOURCES} ${HEADERS} ${CONFIGURATION_FILES}) set_folder(dwarfdump dwarfdump) target_compile_definitions(dwarfdump PRIVATE "CONFPREFIX=${CMAKE_INSTALL_PREFIX}/lib") target_compile_options(dwarfdump PRIVATE ${DW_FWALL}) target_link_libraries(dwarfdump PRIVATE ${dwarf-target} ${DW_FZLIB}) # Plain GNU C dash E does not work on a .list, # so copy to a .c name to run # the following four table creations. set(SELFTEST "-DSELFTEST") if (DO_TESTING) set_source_group(GETOPTEST_SOURCES "Source Files" getopttest.c dwgetopt.c) add_executable(selfgetopttest ${GETOPTEST_SOURCES}) target_compile_options(selfgetopttest PRIVATE ${DW_FWALL}) add_test(NAME selfgetopttest COMMAND selfgetopttest) endif() if (DO_TESTING) set_source_group(TESTESB_SOURCES "Source Files" esb.c testesb.c dwarf_tsearchbal.c) add_executable(selftestesb ${TESTESB_SOURCES}) target_compile_options(selftestesb PRIVATE ${SELFTEST} ) target_compile_options(selftestesb PRIVATE ${DW_FWALL}) add_test(NAME selftestesb COMMAND selftestesb) endif() if (DO_TESTING) set_source_group(TESTESB_SOURCES "Source Files" getopttest.c dwgetopt.c) add_executable(selfgetopttestnat ${GETOPTEST_SOURCES}) target_compile_options(selfgetopttestnat PRIVATE ${DW_FWALL}) if(UNIX) target_compile_definitions(selfgetopttestnat PRIVATE GETOPT_FROM_SYSTEM) endif() foreach(i 1 2 3 5 6 7 8 9 10) add_test(NAME selfgetopttestnat${i} COMMAND selfgetopttestnat -c ${i}) endforeach() endif() if (DO_TESTING) set_source_group(MAKENAME_SOURCES "Source Files" makename_test.c esb.c dwarf_tsearchbal.c makename.c) add_executable(selfmakename ${MAKENAME_SOURCES}) target_compile_options(selfmakename PRIVATE ${DW_FWALL}) target_compile_options(selfmakename PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfmakename PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfmakename COMMAND selfmakename) endif() if (DO_TESTING) set_source_group(HELPERTREE_SOURCES "Source Files" helpertree_test.c helpertree.c dwarf_tsearchbal.c) add_executable(selfhelpertree ${HELPERTREE_SOURCES}) target_compile_options(selfhelpertree PRIVATE ${DW_FWALL}) target_compile_options(selfhelpertree PRIVATE "-I${CMAKE_SOURCE_DIR}/dwarfdump") target_compile_options(selfhelpertree PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfhelpertree PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfhelpertree COMMAND selfhelpertree) endif() if (DO_TESTING) set_source_group(SELFMC_SOURCES "Source Files" macrocheck.c esb.c dwarf_tsearchbal.c) add_executable(selfmc ${SELFMC_SOURCES} ) target_compile_options(selfmc PRIVATE ${SELFTEST} ) target_compile_options(selfmc PRIVATE ${DW_FWALL}) target_compile_options(selfmc PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfmc PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfmc COMMAND selfmc) endif() if (DO_TESTING) set_source_group(SELFESB_SOURCES "Source Files" testesb.c esb.c) add_executable(selfesb ${SELFESB_SOURCES}) target_compile_options(selfesb PRIVATE ${SELFTEST} ) target_compile_options(selfesb PRIVATE ${DW_FWALL}) target_compile_options(selfmakename PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfmakename PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfesb COMMAND selfesb) endif() if (DO_TESTING) set_source_group(SECTIONBITMAPS_SOURCES "Source Files" section_bitmaps.c section_bitmaps_test.c ) add_executable(selfsectionbitmaps ${SECTIONBITMAPS_SOURCES}) target_compile_options(selfsectionbitmaps PRIVATE ${SELFTEST} ) target_compile_options(selfsectionbitmaps PRIVATE ${DW_FWALL}) target_compile_options(selfsectionbitmaps PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfsectionbitmaps PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfsectionbitmaps COMMAND selfsectionbitmaps) endif() if (DO_TESTING) set_source_group(SELFPRINTRELOC_SOURCES "Source Files" esb.c print_reloc_test.c) add_executable(selfprintreloc ${SELFPRINTRELOC_SOURCES}) # We need access to a few relocation-data libdwarf headers target_compile_options(selfprintreloc PRIVATE ${SELFTEST} ) target_compile_options(selfprintreloc PRIVATE ${DW_FWALL}) target_compile_options(selfprintreloc PRIVATE "-I${CMAKE_SOURCE_DIR}/libdwarf") target_compile_options(selfprintreloc PRIVATE "-I${CMAKE_BINARY_DIR}/libdwarf") add_test(NAME selfprintreloc COMMAND selfprintreloc) endif() if (DO_TESTING) set(peobj "${CMAKE_SOURCE_DIR}/dwarfdump/testobjLE32PE.exe") set(pebase "${CMAKE_SOURCE_DIR}/dwarfdump/testobjLE32PE.base") set(execpedd "${CMAKE_BINARY_DIR}/dwarfdump/dwarfdump") add_test(NAME selfdwarfdumppe COMMAND sh -c "${execpedd} ${peobj} | head -500 >junk.testoutpe ; diff ${pebase} junk.testoutpe" ) endif() if (DO_TESTING) set(elfobj "${CMAKE_SOURCE_DIR}/dwarfdump/testuriLE64ELf.obj") set(elfbase "${CMAKE_SOURCE_DIR}/dwarfdump/testuriLE64ELf.base") set(execelfdd "${CMAKE_BINARY_DIR}/dwarfdump/dwarfdump") add_test(NAME selfdwarfdumpelf COMMAND sh -c "${execelfdd} ${elfobj} | head -500 > junk.testoutelf ; diff ${elfbase} junk.testoutelf" ) endif() if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set(SUFFIX 64) endif() set(LIBDIR lib${SUFFIX}) set(BINDIR bin${SUFFIX}) install(TARGETS dwarfdump DESTINATION RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR} ARCHIVE DESTINATION ${LIBDIR}) install(FILES dwarfdump.conf DESTINATION ${LIBDIR}) install(FILES dwarfdump.1 DESTINATION share/man/man1) dwarfutils-20200114/dwarfdump/CODINGSTYLE000066400000000000000000000030071361531463500176400ustar00rootroot00000000000000This document is a brief description of the main coding style conventions in dwarfdump. Many of them will be obvious from the code, but over time some accidental diffences crept in. Code should be indented in multiples of 4 spaces, and tabs should not be used to indent the source code. Use the dicheck program to check indenting. The struct naming convention is 'struct my_struct_s' for the struct defined here (meaning the name should end with _s). It is better to not do struct typedefs of local structs. Coders should type 'struct mystruct_s'. Readability is much more important than brevity. Any data or function not referenced outside the defining source file should be declared 'static'. Any duplicated code is a candidate for refactoring into a subprogram. Function names should be all lower case with underbars with the goal that statements and comments 'read well'. Variables should be lower-case with underbars for readability. It's ok for a small loop with counters to use single letter names like i or k or m. Structure members should have a struct-specific 2-character prefix to the name (followed by an underbar). That makes it much easier to grep for uses of members. Try to keep lines under 80 characters in length. Ensure every if() has {} to enclose the actions. Use libdwarf.h types for all the data objects you define, though sometimes an 'unsigned' or 'int' or 'size_t' is ok in restricted circumstances. Dwarf_Unsigned and Dwarf_Signed are the preferred integer types for general use. ------------ dwarfutils-20200114/dwarfdump/COPYING000066400000000000000000000017541361531463500171730ustar00rootroot00000000000000 David Anderson: December 2006 The code in the dwarfdump directory is (if you look in each file) covered by the GPL (not the LGPL). The DWARFDUMPCOPYRIGHT file, though, said (before December 24, 2006) the copyright is LGPL. There is no doubt in my (David Anderson) mind that the intent was always that dwarfdump be GPL and the copyright markings in each file are correct. There are three files marked with the LGPL: tag_tree.list tag_attr.list acconfig.h. These markings are left as is and these are are therefore LGPL files. The DWARFDUMPCOPYRIGHT file now (Dec 24 2006) has both copyrights and an explanation of where each applies. ------------------------------------------- The text present for years, thru Dec 23, 2006: The files: dwarfdump.c and all the .h and .c files in this implementation of dwarfdump are copyrighted according to the file DWARFDUMPCOPYRIGHT. $Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/COPYING,v $ $Revision: 1.1 $ $Date: 2001/01/16 17:47:55 $ dwarfutils-20200114/dwarfdump/ChangeLog000066400000000000000000000017071361531463500177100ustar00rootroot000000000000002020-01-14: * dwarf_names.c,dwarf_names.h,dwarfdump-ta-ext-table.h, dwarfdump-ta-table.h,dwarfdump-tt-ext-table.h,dwarfdump-tt-table.h: Updated version string. 2020-01-05: * dwconf.c: Fix CoveritySan CID 206594 resource leak if an error reading dwarfdump.conf. * sanitized.c(no_questionable_chars): Fixed CoverityScan CID 206595. The code was failing to sanitize % characters: the test for % has been moved up a few lines. do_sanity_insert() had the same problem with %. Fixed. And do_sanity_insert() had a final line of unreachable code; now fixed by simplifying the code (an ASSERT added in a comment). Coverity Scan CID 206596. * print_die.c(traverse_one_die): Was failing to check for the normal dwarf return int and letting next code deal with the fallout (and leak an error record). Now we check and avoid any leak or surprise. Coverity Scan CID 20659 dwarfutils-20200114/dwarfdump/ChangeLog2006000066400000000000000000000335011361531463500202150ustar00rootroot000000000000002006-12-24 David Anderson * DWARFDUMPCOPYRIGHT: Added GPL copyright text with explanation of the intended content. * COPYING: added text explaining confusion of GPL vs LGPL. Thanks to Chris Quenelle for pointing out the disconnect between DWARFDUMPCOPYRIGHT and the source files in dwarfdump. 2006-12-21 David Anderson * tag_tree.list: add tags to make allowed list more complete. Omission noticed by Marcel Mettes. 2006-06-14 David Anderson * print_frames.c: Clean up printing of augmentation data by eliminating dangling 0x (for eh_frame). 2006-04-28 David Anderson * dwarfdump.conf: Now has x86_64 register names. x86_64 with help from Tom Hughes (verified from independent sources). Added m68k register names and refined x86 list by looking at various information-sources. 2006-04-18 David Anderson * *.c: Ran indent so all now follow a standard look. * dwconf.c: Added fclose(conf_stream). 2006-04-18 David Anderson * dwarfdump.c: Forgot to call key new functions for handling variable-size frame data and different frame rule initialization value. * dwconf.c: Add a default print for CFA in case of an omission in dwarfdump.conf. * dwarfdump.conf: Move setup and rename the ABIs slightly. 2006-04-17 David Anderson * dwarfdump.conf: Correct typos. Remove some register names. * dwarfdump.c: Fix compiler warnings, fix -x option usage message. * dwconf.h: Fix compiler warnings by changing types. * dwconf.c: Change error checking so we check all errors, do not stop at first error. Ran indent. Added code to check for extra junk after operand(s). * print_frames.c: Fix compiler warnings. * Makefile.in: get used in install rule and creating places to search for dwarfdump.conf 2006-04-16 David Anderson * dwarfdump.conf: New dwarfdump configuration file. Makes using frame information easy to read and correct for any ABI/ISA without rebuilding dwarfdump. * Makefile.in: Added new files dwconf.h dwconf.c * dwconf.h dwconf.c: New files implement reading dwarfdump.conf and help print_frames.c print frame information correctly for ABIs specified at runtime. * dwarfdump.1: document -x commands. * globals.h: Minor changes to support dwarfdump.conf * print_frames.c: Major changes to support a run-time description of the frames info and dwarfdump.conf. * print_frames.h: Changes to support a run-time description of the frames info and dwarfdump.conf. * print_sections.c: Minor tweaks to support a run-time description of the frames info and dwarfdump.conf. 2006-03-31 David Anderson * Makefile.in globals.h print_sections.c: Refer to new print_frames.h print_frames.c. * print_frames.h print_frames.c: Extract cie, fde printing to separate file, separating loop logic from the printing of an entry from the loop. 2006-03-31 David Anderson * dwarfdump.c global.h print_sections.c: Preparing for dwarf3 frame interface. * print_die.c: Corrects handling of DW_AT_encoding (etc) value. 2006-03-29 David Anderson * print_sections.c: define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES at compile time to turn off the MIPS register names printing. Instead (aside from cfa) use a name like r4 (where the DWARF register number follows the letter 'r'). Indent. Initialize some local variables at declarations. 2006-03-13 David Anderson * print_sections.c: Now gets gnu eh_augmentation data by calling dwarf_get_cie_augmentation_data() or dwarf_get_fde_augmentation_data() and prints it (use -v to see cie data). Now prints DWARF3 frame information. 2006-03-08 David Anderson * print_sections.c: Add 'break;' at line 710. Thanks to Richard Stuckey for noticing. 2005-12-01 David Anderson * dwarf_names.awk: use snprintf instead of sprintf for safety. 2005-12-01 David Anderson * Makefile.in: Build attr/tag trees with individual commands to catch build errors. * tag_attr.c,tag_tree.c: Verify that tables fit in the generated C code and check for format errors in the *.list files. * tag_attr.list, tag_tree.list: Added some valid entries. * globals.h: add DWARF_ERROR3 macro for better diagnostics. * print_die.c: Show both sides of questionable tag relation in CHECK -k diagnostic output. 2005-11-25 David Anderson * print_die.c: DW_AT_stride_size changed to DW_AT_bit_stride, added DW_AT_byte_stride. * tag_attr.c,tag_tree.c: fixed array size now a #define for readability. * tag_attr.list: Added DWARF3 attributes, also new TAGs. * tag_tree.list: Added DWARF3 TAGs. 2005-11-08 David Anderson * makename.c: remove non-standard malloc.h include, stdlib.h suffices and is already included. 2005-10-24 David Anderson * tag_attr.c tag_tree.c: added DWARF3 TAGs to string array. 2005-08-01 David Anderson * Makefile.in: Add esb.o and test rule (test code for esb.c). * dwarfdump.c: Remove old static buffer initialization. * print_die.c: Use esb now, avoid crash due to long loclist overrunning static buffer. Uses snprintf now, not sprintf. snprintf is for safety. * esb.h esb.c: Adding extensible string buffer (esb) code. * testesb.c: Test code for esb.c. * print_reloc.c: size field is now Elf64_Xword for Elf64 as Elf64_Word is only 32 bits. 2005-07-15 David Anderson * dwarfdump.c: Add print of .debug_pubtypes, remove erroneous dealloc after dwarf_formstring() call. * globals.h: Add declarations for .debug_pubtypes print. Add declaration for full dealloc. * print_die.c: Remove erroneous dealloc after dwarf_formstring() call. * print_exception_tables.c: Call dwarf_fde_cie_list_dealloc() for complete dealloc. * print_sections.c: Remove incorrect dealloc() call. Add calls to new dealloc routines. Add support of .debug_pubtypes print. 2005-07-14 David Anderson * print_sections.c (print_line_numbers_this_cu): Use new dwarf_srclines_dealloc() for deallocation after dwarf_srclines() called. 2005-04-13 David Anderson * print_sections.c: Factors out common print code into a new routine. Avoid indexing past end of register names array. Adds checks and prints so that certain errors in pubnames-like sections are printed usefully (and dwarfdump then stops if libdwarf gave an error). 2005-03-21 David Anderson * dwarfdump.c: Add -F flag to request .eh_frame section print. Changed -f flag meaning to print .debug_frame only. -a flag no longer prints .debug_frame by default. * print_sections.c: avoid printing an eh_frame we don't understand. Add new information per CU when printing line info: specifically the line section offset. * globals.h: Added arguments to print_frames() for -F flag. 2005-03-18 David Anderson * print_sections.c: Correct macro section printing. 2004-10-28 David Anderson * DWARFDUMPCOPYRIGHT config.h defs.h dwarfdump.c globals.h makename.c makename.h print_die.c print_exception_tables.c print_reloc.c print_sections.c tag_attr.c tag_attr.list tag_tree.c tag_tree.list: Copyright update, SGI corporate address change. 2004-10-26 David Anderson * acconfig.h: removed. Was old style autoconf usage. * configure.in: Updated AC_DEFINE usage, adding args 2 & 3. * config.guess: Updated. timestamp='2004-06-11'. * config.sub: Updated. timestamp='2004-03-12'. * configure config.h.in: regenerated with autoconf 2.58. 2004-05-14 David Anderson * print_die.c (print_die_and_children): Change to iteration on siblings (still recursing on children). 2004-03-30 David Anderson * dwarfdump.c (main): getopt() string should contain k:g not kg: Thanks to Peter Seiderer for pointing this out. 2003-12-31 David Anderson * README: Added configure example. * Makefile.in: Removed bogus LIBS line, updated copyright date. * acconfig.h: Added LGPL copyright to match libdwarf Silly, but it matches libdwarf version boilerplate. * config.guess config.sub: new versions from automake-1.6. * config.h.in configure: Regenerated. 2003-10-06 David Anderson * dwarfdump.c print_sections.c: applied indent(1). * print_die.c: applied indent and added ; after invocations of macros PUSH_DIE_STACK POP_DIE_STACK SPACE as these were confusing indent a bit. The indent control file .indent.pro contained: -bad -bap -nbbo -br -ce -brs -l72 -lc72 -hnl -nprs -fca -i4 -lp -psl -npcs 2003-10-02 David Anderson * dwarfdump.c: Add -g to indicate use of older location entry code in libdwarf. So dwarf_loclist and dwarf_loclist_n are testable. * globals.h: Added use_old_dwarf_loclist flag so one can choose the old dwarf_loclist() interface. For testing. * print_die.c: Rearranged to avoid code duplication. Now supports .debug_loc fully. * print_sections.c: Prints .debug_loc now. 2003-09-29 David Anderson * print_die.c: with -v, print 'loclist' start and end addr and also a hint that DW_FORM_indirect is used. No change for normal output (for now). 2003-05-19 David Anderson * dwarfdump.c call dwarf_srcfiles() to get file names per cu and pass down to die print routines. Removed incorrect tests for when to print ".debug_info", leaving simpler test. * print_die.c globals.h: print file name (from line info) with DW_AT_decl_file, adding data from dwarf_srcfiles to argument list of a few routines to make that possible. * print_sections.c: moved "line number info" string print so it prints for -v as well as normal line ouput. 2002-10-23 Amaury Le Leyzour amaury@sgi.com * print_sections.c (print_weaknames): Changed DW_DLA_TYPENAME to DW_DLA_WEAK at dwarf_dealloc(). 2002-10-22 Tom Hughes * print_sections.c: macro printing now supported. * dwarfdump.c: removed erroneous dwarf_dealloc() of string returned by dwarf_errmsg(). 2002-11-22 David Anderson * dwarf_names.awk at_list.awk: Allow an name to have two spellings so the historical name preserved yet the dwarf3 version is supported. First name seen is used/reported by dwarfdump. * dwarf.h: DW_TAG_template_type_param(eter) DW_TAG_template_value_param(eter) DW_AT_namelist_itm(s) are the ones with alternate spellings now. Added Universal Parallel C TAGs/Attributes in user namespace. * tag_attr.c tag_attr.list tag_tree.c tag_tree.list: Use the DW_TAG_template_* dwarf3 spellings. 2002-05-08 David Anderson * tag_attr.list dwarf.h: DW_AT_namelist_items is wrong, changed to DW_AT_namelist_item 2002-04-29 Stephen Clarke * dwarfdump.c (main): #ifdef for __CYGWIN__ on open(). 2001-06-14 David Anderson * print_sections.c: Calling the new libdwarf function dwarf_get_arange_cu_header_offset() so we can print the cu header offset for aranges. 2000-07-14 Fred Fish * configure.in (LOCATION_OF_LIBELFHEADER): Fix typo for configure variable to be tested and enclose libelf/libelf.h in <>. * configure: Regenerated. 2000-07-10 Fred Fish * Makefile.in (install): Install dwarfdump.1 from $(srcdir). 2000 June 12 davea@sgi.com print_sections.c the DW_CFA_offset_extended print did not multiply by data-alignment factor in the -v -v detailed output. And the offsets used %2d when the values were unsigned int, so now %2u. And not all cfa prints of values had necessarily a type to match %llu or %lld where required. Depended on the size of Dwarf_Signed and Dwarf_Unsigned. So now explicitly use cast to the right type to match the % format. 2000 April 13 davea@sgi.com print_sections.c - 1.56 - A single byte of zero is a perfectly legitmate null abbreviation entry (in .debug_abbrev) now we print those directly and avoid a warning from dwarfdump print_die.c - 1.42 - Explain what combo checker is doing and make it more maintainable (and fix bug which would not be hit, but was real enough (in combo checker), using too large a number as highest tag number). tag_tree.list - 1.2 - Add valid parent/child relationships so checker does not report valid entries as bogus. 2000 Feb 24 Jason Merrill noticed that gcc did not like gcc -E foo.list, so incorporated his fix so now the Makefile.in makes a link and does gcc -E _tmp.c 2000 Jan 26 elena.demikhovsky@intel.com noticed that 3 statements in print_sections.c got warnings from the compiler she was using. Simple casts (provided by her) fixed these. 1999 July 21 davea@sgi.com print_sections changed to allow printing of dwarf-ish egcs c++ .eh_frame data 1999 June 14 Fred Fish fnf@ninemoons.com contributed autoconf'ing of the libdwarf and dwarfdump source. 1999 June 10 ChangeLog started. davea@sgi.com David Anderson dwarfutils-20200114/dwarfdump/ChangeLog2007000066400000000000000000000132311361531463500202140ustar00rootroot000000000000002007-12-09 DavidAnderson * print_sections.c print_frames.c: Forgot to commit yesterday. yesterday's commit includes renaming _dwarf_fde_section_offset _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines to dwarf_* form while retaining support for the now obsolete _dwarf_* form. 2007-12-08 DavidAnderson * config.h.in, configure.in: Latest linux libelf.h requires _GNU_SOURCE to get off64_t defined so dwarfdump compiles. Only define _GNU_SOURCE if libelf.h defines off64_t. Regenerated configure. * config.guess, config.sub: Updated to 2.61 * acconfig.h: Deleted, removing autoconf complaint. 2007-10-15 DavidAnderson * print_die.c (clean_up_die_esb): New function cleans up malloc space. * print_reloc.c (clean_up_syms_malloc_data): New function cleans up malloc space. * dwarfdump.c (main): Call new cleanup functions at end. * globals.h: Declare new cleanup functions. 2007-09-04 DavidAnderson * print_die.c (print_attribute): For DWARF4: DW_AT_high_pc: add qualifier to value when the value is an offset from DW_AT_low_pc (thus not itself a address). Update the address of the FSF. * print_frames.h DWARFDUMPCOPYRIGHT print_sections.c print_reloc.c dwarfdump.c tag_tree.c tag_attr.c esb.c esb.h makename.c acconfig.h dwconf.c makename.h dwconf.h globals.h print_frames.c: Update the address of the FSF. 2007-07-03 DavidAnderson * print_sections.c (dump_block): Removed superfluous return byte from printed characters. Removed unused variables. * print_die.c: A little refactoring for clarity. * globals.h: dwarfdump_print_one_locdesc() is now a global-to-dwarfdump function. * print_frames.c: Now (with -v) prints dwarf expression bytes in frame expressions readably. 2007-07-02 DavidAnderson * dwarfdump.c: Add new -R option for 'generic' register sets. * dwarfdump.1: document -R, add new -x documentation. * dwconf.c: Set up -R configuration. Slight revision of register printing code. * dwconf.h: Interface to register name printing simplified. * print_frames.c: Use the simpler register name interface. * dwarfdump.conf: Add new 'generic' abi for up to 1000 registers. 2007-07-01 DavidAnderson * print_frames.c: For DW_CFA_def_cfa_sf & DW_CFA_def_cfa_offset_sf print a computed data alignment factor. 2007-06-29 DavidAnderson * dwarfdump.1: Corrected spelling error. 2007-05-25 DavidAnderson * dwconf.h dwconf.c: Changed field name to cf_named_regs_table_size as old name was less than clear. * dwarfdump.c: Call frame table setup with cf_table_entry_count not cf_named_regs_table_size. The newly renamed field makes it clearer the call was wrong. 2007-05-04 DavidAnderson * print_die.c: printing of global offset of DIEs with -G is now more in the style of previous output. 2007-04-18 Chris Quenelle * Makefile.in: - use $(srcdir) for files in source directory - support running rules in parallel by - use different tmp file names in different rules. - use more accurate target for dwarf_names.{c,h} * dwarf_names.awk: Enhance script to be able to generate either #define-style headers or enum-style headers * dwarfdump.c: dump most everything by default if no arguments are given to dwarfdump. This seems to be a more useful default than showing nothing at all. Also add a -G option to show the (G)lobal section offset for each die within an a.out. If you think you're seeing data corruption inside a .debug_info section, this is a useful option to have. * print_die.c: Support compressed integer blocks. This is an array (DW_FORM_block) of LEB numbers used as part of a Sun extension, DW_AT_SUN_func_offsets. Also add support for a new dwarf enum DW_ATCF_xxxx. This is used in DW_AT_SUN_cf_kind. Also, fix DW_AT_upper_bound so it can be a constant or a location list. DW_AT_count and DW_AT_data_member_location should also be fixed eventually. * print_sections.c: Changes to support zero-padding in the middle of section data. Change offset labels to be a little more clear. Not sure about the get_str failure. * tag_tree.list: DW_TAG_compile_unit can contain a DW_TAG_namespace 2007-04-10 David Anderson * print_reloc.c dwarfdump.c print_frames.c: Unified copyright to the SGI form. No copyright change. 2007-04-06 David Anderson * print_die.c (print_die_and_children): Increase static depth of die stack. Notice if it overflows and print error. 2007-02-23 David Anderson * print_reloc.c: 2 lines added (long) cast in printf and made %3ld instead of %3d to fix compiler warning. * print_frames.c: newline was missing from the output. Thanks to Chris Quenelle for noticing. 2007-02-20 David Anderson * print_frame.c (print_frame_inst_bytes): Fixed an off by one error (several places) when printing dwarf expressions and added commentary about it. Thanks to Julian Seward for pointing out it was off by one. * dwarfdump.c (print_error): added fflush of stdout, stderr where we are going to exit right away anyway. dwarfutils-20200114/dwarfdump/ChangeLog2008000066400000000000000000000117541361531463500202250ustar00rootroot000000000000002008-12-30 David Anderson * tag_attr.list: Mark DW_AT_artificial as sensible on DW_TAG_variable. * dwarfdump.1: Document -N option to print .debug_ranges. * Makefile.in: add new source header files * dwarfdump.c: Implement -N to print .debug_ranges. * print_sections.c: Allow more flexible printing of function names for .debug_frame section. With -N, print .debug_ranges. * print_die.c: Print .debug_ranges details. * print_frames.c: Delete useless comment. * globals.h: Allow re-use of debug_ranges formatting code. * Makefile.in: Make the header dependency list more complete. * makename.h: Comment tweaked. 2008-12-08 David Anderson * print_die.c: the -M option now also prints the form number (after the form name). And -v prints the DIE abbreviation code, the index into the relevant abbreviation table. * globals.h: Removed unused global variable. * dwarfdump.c: Removed unused global variable. * dwarfdump.1: document -M and the new -v features. 2008-12-07 David Anderson * print_reloc.c (print_relocinfo): Removed unused local variable. 2008-11-19 David Anderson * globals.h: Added new boolean to support -M. * dwarfdump.1: Mentioning the -M option. * dwarfdump.c: Implementing -M, which has each attribute line show the name of the form. * print_die.c: Implementing -M option. 2008-10-12 David Anderson * dwarfdump.conf: Adding power pc register names and table size for use with -x abi=ppc . 2008-08-13 David Anderson * dwarfdump.1: When no options (just object files) present all sections print, now we say that. Renamed fields in synopsis for readability. 2008-06-23 David Anderson * print_reloc.c (print_reloc_information_64): Was testing sym_data_entry_count one place where sym_data_64_entry_count should have been tested. Thanks to Carlos Alberto Enciso for noticing. 2008-06-17 David Anderson * print_die.c: Add to dwarf_formstring failure message. * README: Correct email: the old sgi.com address is no longer correct. 2008-06-13 David Anderson * dwconf.c: Fix an off-by-one condition where we could index off the end of the cf_regs array in printing a register name. 2008-04-12 David Anderson * print_reloc.c: Verify stringtab exists and is large enough before indexing into it to get a string in printing relocations. (Providing default name "" so it's evident from the output that we used a default name string). 2008-04-09 David Anderson * print_sections.c (get_fde_proc_name): Initialize some local variables at declaration. The function is very slow and needs a replacement. * print_die.c: Fixes a typo in a comment. * dwarfdump.c: Added -n option to suppress function name search when printing FDEs. Current dwarfdump is n-squared at least getting those names, this is a bandage-type-workaround when there are so many FDEs the slowness is painful. * globals.h: Support for -n option. * print_frames.c: Support for -n option. 2008-04-08 David Anderson * dwarfdump.c: Added -H option for testing (it limits the run length). And the support for -H in printing DIEs. * globals.h: Added extern for -H option declaration. * print_sections.c: Added -H option support to limit frames printing. 2008-04-04 David Anderson * print_die.c (tag_tree_combination, tag_attr_combination): Ensure we do not index off the end of the -k checking arrays. * print_sections.c: Increase the size of a local variable,. 2008-03-03 David Anderson * dwarfdump.1: Add description of -ka option. * print_frames.h print_sections.c testesb.c print_die.c print_reloc.c dwarfdump.c tag_tree.c tag_attr.c esb.c esb.h makename.c dwconf.c makename.h dwconf.h globals.h print_frames.c: Change tabs to spaces with expand(1). 2008-03-03 David Anderson * print_die.c: Now check that DW_AT_decl_file and DW_AT_call_file indexes are valid and count instances of the attribute and errors found in it. * dwarfdump.c: With -ka and -ky now check that DW_AT_decl_file and DW_AT_call_file indexes are valid and warn if bad. Thanks to Carlos Alberto Enciso for the suggestion. * globals.h: Declare new fields for the DW_AT_decl_file DW_AT_call_file checks. 2008-02-26 David Anderson * print_die.c (get_attr_value): Print DW_AT_call_file, DW_AT_call_line, DW_AT_call_column nicely. dwarfutils-20200114/dwarfdump/ChangeLog2009000066400000000000000000000353001361531463500202170ustar00rootroot000000000000002009-12-30 DavidAnderson * configure: Regenerated with autoconf 2.64. * config.guess, config.sub: Delete these, best not to have them. 2009-11-24 DavidAnderson * tag_common.h: Updated 'standard tag table row' and tag table column maximums now the DWARF4 entries are in the .list files. Removed dos 'CR' characters at line ends. * tag_tree.list, tag_attr.list: Added various DWARF4 entries and added DW_TAG_enumeration_type under DW_TAG_union_type. 2009-11-17 DavidAnderson * dwarfdump.1: Document the -u option more fully. * print_die.c: Check for both info_flag and cu_name_flag to decide when to print DIEs. 2009-10-12 DavidAnderson * dwarfdump.c: Updated dwarfdump version string to today. 2009-09-30 DavidAnderson * dwarfdump.c: Added globals for aranges checking and to print the resulting error count. * print_aranges.c: Added checking that all 3 ways of computing a cu_die_offset from an arange get the same offset (checked with -r -ka). * print_frames.c: DW_CFA_cfa_offset_extended_sf corrected to DW_CFA_offset_extended_sf. 2009-09-01 DavidAnderson * tag_tree.list: We add DW_TAG_class_type as a valid child of a DW_TAG_union_type. 2009-08-05 DavidAnderson * gennames.c: Change include from getopt.h to unistd.h so the code is more universally compilable. 2009-07-24: David Anderson * tag_attr.c: Remove duplicate include of naming.h. 2009-06-23: David Anderson * strstrnocase.c: Corrected typo in TEST code and added a new test. 2009-06-22: David Anderson * Makefile.in: switched to personally written string comparison, strstrnocase.c. * stristr.c: deleted. * strstrnocase.c: New code, written by me so no license issues. * print_die.c: Call is_strstrnocase(), the new function. * dwarfdump.1: More fully document -S. * globals.h: Create extern for is_strstrnocase(). 2009-06-18: David Anderson * configure: Regenerated. * Makefile.in: Add stristr.o * stristr.c: public domain source added to dwarfdump * print_die.c: Add code and arguments to support -S. * print_lines.c: print_one_die argument list changed, added the require argument.. * dwarfdump.c: Added the -S option. * configure.in: Add test to set HAVE_REGEX for the -S option. * dwarfdump.1: Document the -S options. * config.h.in: Set the default HAVE_REGEX * globals.h: Add -S globals, change the print_one_die() prototype to support -S. * print_aranges.c: Alter the print_one_die calls added to support -S. 2009-06-06: David Anderson * naming.c,naming.h: New files that implement the ellipsis functionality of dwarfdump and defer to libdwarf to get the names of the TAGs, attributes, FORMs, etc. * gennames.c: This file has moved to libdwarf, no longer present in dwarfdump. * esb.h, esb.c: Change certain char* arguments to const char* to avoid compiler warnings. * print_static_vars.c,print_static_funcs.c, print_sections.c,print_strings.c, print_locs.c, print_lines.c, print_pubnames.c,print_ranges.c, print_macros.c,print_types.c,tag_common.c, print_weaknames.c, print_aranges.c: Include changed from dwarf_names.h to naming.h * tag_common.h: Removed the tag_name array, libdwarf provides the TAG, ATTR, etc name strings now. * dwarfdump.c: Updated DWARFDUMP_VERSION string. * tag_tree.c,tag_attr.c: Include changed from dwarf_names.h to naming.h. simplified long complicated lines, remove dbg argument to get_TAG_name. * print_die.c,print_abbrevs.c: Include changed from dwarf_names.h to naming.h. Calls to get_TAG_name (etc) no longer have a dbg argument. * Makefile.in: We no longer build generated file names.c, we build naming.c (hand coded, not generated). 2009-05-07: David Anderson * dwarfdump.cc: updated DWARF_VERSION string. * Makefile.in: dwarf_names* are now generated by C, so 'clean' now cleans them out. 2009-05-04: David Anderson * common.h, common.c: Extracted simple utility routines into their own files. * dwarf_names.awk, at_list.awk: deleted. gennames.c replaces these. * tag_common.c, tag_common.h: Removed the simple utility routines from these files to simplify dependencies. * tag_attr.c, tag_tree.c: Include new common.h. * print_frames.c: Adding address_size argument to call. * print_frames.h: Adding new address_size argument to get_string_from_locs() declaration. * print_locs.c: Gets and uses CU-specific address_size. * print_ranges.c: Adding commentary. * print_die.c: adding DIE argument to ensure correct address size used for the CU in question. * Makefile.in: Now handles common.* and gennames.c changes. * gennames.c: New code emitting string 'get name' source. Replaces awk source. 2009-04-04: David Anderson * Makefile.in: clean up 'clean' and 'distclean' so that distributed files are not cleaned out by 'clean' and all generated files (even those shipped in distribution) are cleaned out by distclean. * dwarfdump.c: Now calls the new libdwarf function dwarf_set_frame_cfa_value() and other such functions to specify all the values libdwarf needs. * dwarfdump.conf: Sets the cfa_reg: value to a new higher value (1436) to avoid conflict with largest known register count. * dwconf.h: Corrected commentary on DW_FRAME_CFA_COL3. * dwconf.c: Now uses DW_FRAME_CFA_COL3 as default for interface 3, rather than a directly typed number. Sets undefined-value and same-value pseudo-register numbers. 2009-04-03: David Anderson * dwarfdump.1: Amplified -R and -x abi= documentation. * dwarfdump.conf: Added generic500 generic100 abis. 2009-03-29: David Anderson * print_die.c: Moved print_infos() to here. * dwarfdump.c: Moved print_infos() out of here. * globals.h: Declarations changed to allow moving print_infos(). * dwarf_names.awk: Eliminate a pointless space before a newline in the generated code. * print_locs.c: Add -v section offset output to loclist printing of the debug_loc section so the entries can be matched to loclist printing initiated from .debug_info. 2009-03-24: David Anderson * README: Would be nice if all could use dwarfdump2, not this C dwarfdump. * dwconf.c: Initialize new frame regs configure data and parse it in the .conf file. Fixed old formatting mistakes. * dwconf.h: Add new fields to frame regs configure struct. Make -R be 1200 regs so that -R covers all the currently popular ABIs. * print_die.c, print_lines.c, print_frames.c: Change %# to 0x% so that zero prints with leading 0x consistently. * dwarfdump.c: -R is now 1200 registers. So config function changed and usage message needed update. * dwarfdump.1: Change -R to 1200 and document -C. * dwarfdump.conf: Add same_val_reg: and undefined_val_reg: initial values where needed or interesting. * print_macros.c: Fix old formatting mistake. 2009-03-23: David Anderson * print_sections.h: New file for print_*.c sources. * dwarfdump.1: Added -C documentation. * Makefile.in: updated 'mandir' so it works with current configure (so now make install properly installs the man page). * print_sections.c: Moved get_fde_proc_name() and related code to print_frames.c, where it is referenced. * dwarfdump.c: No longer turn on info_flag with -f or -F. Moved the Usage strings into a string table and loop through to print them. * globals.h: Removed get_fde_proc_name() declaration. * print_frames.c: Added get_fde_proc_name() here and removed the 'inlined:' from the abstract origin name. 2009-03-20: David Anderson * print_static_vars.c, print_static_funcs.c, print_strings.c, print_locs.c, print_pubnames.c, print_lines.c, print_ranges.c, print_abbrevs.c, print_macros.c, print_types.c, print_weaknames.c, print_aranges.c: Moved the print_* functions from print_sections.c into individual sourcefiles. * Makefile.in: Now lists the new sourcefiles. * print_sections.c: Deleted code moved to individual sourcefiles. Added code to try to find the name from a DW_AT_abstract_origin DIE when a subprogram DIE itself has no DW_AT_name; * dwarfdump.c: Remove unused local variables. Use DWARFDUMP_VERSION #define to set version string. * tag_tree.c: Fix && || problem with parentheses. * tag_attr.c: Fix && || problem with parentheses. * print_frames.c: Moved the 'print_frames' function itself from print_sections.c to here. 2009-03-17: David Anderson * globals.h: Created predicate function should_skip_this_cu() predicate function. Eliminating code duplication. * print_frames.c: Fix a hex value output to have a leading 0x as all hex values should (when printed). * print_sections.c: Call should_skip_this_cu(), which replaces duplicate code. Fix the arange print: now the hex value has a leading 0x as all hex values should. get_proc_name() had local variable funcnamefound initialized incorrectly, now is set to 0 as it should be. get_nested_proc_name() now initializes string buffers. get_fde_proc_name() now initializes its string buffer. Surprisingly things worked adequately before in spite of the errors. * dwarfdump.c: Call should_skip_this_cu(). Implementation of that new function is in this source file. 2009-03-16: David Anderson * print_frames.c:DW_CFA_restore output had a spurious newline. Removed 2 pointless blank lines an initialized 2 local variables. * print_sections.c: Removed a pointless redeclaration of a function in libdwarf.h. check_info_offset_sanity() was missing a return statement in one place, which could lead to spurious extra (and silly) error text. 2009-03-09: David Anderson * print_die.c: Make a comment easier to understand. 2009-02-28: David Anderson * Makefile.in: add tmp-*.tmp to the 'clean' rule. 2009-02-17: David Anderson * print_sections.c,print_die.c,tag_common.c,print_frames.c: C99 in-line declarations and // comments are not intended here, this removes a few that were introduced accidentally. 2009-02-16: David Anderson * Makefile.in: Removed some use of awk and simplified some shell scripting here. renamed temp files, no longer named with underbars, they uniformly start with 'tmp-'. * print_sections.c: Added the new argument required by the updated dwarf_names.c functions argument lists. * tag_tree_ext.list: List 'common extensions' of tag->tag relationships. * tag_attr_ext.list: List 'common extensions' of tag->attr relationships. * print_die.c: New 'common extension' tables used for checking tag->tag and tag->attr relationships unless turned off with -C. * dwarf_names.awk: Removed tabs so generated names.c not so spread out. Added argument to the generated functions so tag_tree.c, tag_attr.c can use these generated functions nicely. * dwarfdump.c: Adding -C option, which exposes some 'common extensions' of dwarf uses as DWARF CHECK (-ka) warnings. By default these extensions not reported as warnings. * tag_tree.c: Now generates base and extensions tables. Code in common with tag_attr.c is in tag_common* files. * tag_attr.c: Now generates base and extensions tables. Code in common with tag_tree.c is in tag_common* files. * tag_common.c, tag_common.h: New files with the common data extracted from tag_tree.c and tag_attr.c * globals.h: global flag added for -C. 2009-02-14: David Anderson * configure.in: Define --enable-nonstandardprintf * config.h.in: new #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT * configure: Regenerated. * config.guess, config.sub: Latest version from GNU. * Makefile.in: Referenced configure variable to avoid irritating message at configure time. * README: document --enable-nonstandardprintf * print_sections.c, print_die.c, print_reloc.c, dwarfdump.c, dwconf.c, print_frames.c: Use libdwarf.h DW_PR_ printf macros for for better portability. 2009-02-13: David Anderson * print_sections.c: Ensure we are checking line table header correctness whichever line-table-print code is being used. Allow ARM line header table (which has a bug) to be used. * dwarfdump.c: Print lines_result total with checking on. * globals.h: Add lines_result global to count line botches. 2009-02-11: David Anderson * print_sections.c, print_die.c: DWARF_CHECK_ERROR* macros now get the count struct passed in. * tag_tree.c, tag_attr.c: Add a comment in the output identifying the output as generated code and with the generation date/time inserted. * globals.h: Accept the struct in DWARF_CHECK_ERROR* macros so we can update the error count in the macro. 2009-01-31: David Anderson * Makefile.in: Remove compilation of _tag_attr_table.c and _tag_tree_table.c as those are #included in print_die.c, not separately compiled. * print_frames.c: A formerly-static function now called from another file, so declare it here. * print_sections.c: Improve the printing of the .debug_loc section. * print_die.c: A couple of errors were missing their error count increment. * tag_attr.list tag_tree.list: Some normal relationships were left out of the tables: fixed now. dwarfutils-20200114/dwarfdump/ChangeLog2010000066400000000000000000000124501361531463500202100ustar00rootroot000000000000002010-09-30 DavidAnderson * dwarfdump.c: Now -a no longer implies -c because the -c option is not guaranteed to work by the DWARF spec, nor is -c really necessary. * README: More tweaks on the 'install' issue. 2010-09-29 DavidAnderson * README, Makefile.in: Amplified make install instructions. 2010-09-20 DavidAnderson * print_die.c: If a location form is wrong report an error but continue operating. * dwarfdump.c: Implement print_error_and_continue(). Fix mistakes in usage message. * globals.h: Declare print_error_and_continue(). 2010-04-04 DavidAnderson * dwarfdump.c: New version date. * configure: regenerated. * addrmap.c: Added a comment to mention that tdestroy is GNU only, POSIX does not mention a way to delete the tsearch tree. Hence the code does #define USE_GNU 1 to expose the tdestroy function prototype. 2010-04-03 DavidAnderson * print_frames.h: Added new arguments to a function to get better function names printing. * configure.in: Added test for tsearch functions so dwarfdump will still compile if they are not present. See HAVE_TSEARCH macro. * configure: regenerated. * Makefile.in: Now names object for addrmap.c * addrmap.c: New file to map pc address to function names so fde printing gets functions named properly (using tsearch). * addrmap.h: New file to map pc address to function names so fde printing gets functions named properly (using tsearch). * print_lines.c: Correct the calculation of the number of error checks. * dwarfdump.c: Added fdes error check print. * config.h.in: Now handles the HAVE_TSEARCH macro. * globals.h: Added declarations for the fde error check globals. * print_frames.c: Now uses addrmap.h functions to do a better job of printing function names in the frame output. 2010-03-31 DavidAnderson * dwarfdump.1: Added some text about 'harmless' errors. * dwarfdump.c: Change the size of the harmless error list to 50. Change harmless error reporting to be associated with -k flags. * dwconf.c: Initialize uninitialized fields to satisfy a compiler warning. * globals.h: Declarations added for 'harmless' error reporting. * print_die.c: Added commentary. * print_frames.cc: Change harmless error reporting to be associated with -k flags. * print_aranges.c: Now calls dwarf_get_arange_info_b() allowing proper printing of DWARF4 segment-sensitive aranges. Change harmless error reporting to be associated with -k flags. 2010-03-28 DavidAnderson * dwarf_globals.h: Added interface to print_any_harmless_errors(). * dwarfdump.c: Added print_any_harmless_errors() implementation and we call it just before closing libdwarf. * print_frames.c: Call print_any_harmless_errors after getting cie/fde list. * dwarfdump.conf: Add abi named 'arm' for Arm users. * print_die.c: Initialize a local string pointer to NULL at the point of definition. 2010-02-14 DavidAnderson * print_die.c: Add newer DW_OP operators, remove bogus test of DW_OP_nop as the highest valid operator. Add table of DW_OPs to simplify testing for zero-operand operators. Revise so that the FORM of all attributes print with -M. Move a local variable declaration to the front of a block to match C 1990 rules. String searches now also match on attribute name. * tag_attr.list: Updated copyright. * dwarfdump.c: Remove a switch FALL THROUGH in the 'g' case. * tag_tree_ext.list, tag_attr_ext.list: Added GNU template parameter tags, attributes. Updated copyright. * tag_tree.list: Added template parameter tags. Added entry for nested classes. Updated copyright. * tag_common.h: Increased STD_TAG_TABLE_COLUMNS and EXT_ATTR_TABLE_COLS. 2010-01-30 DavidAnderson * print_die.c: Changed the spelling of one 'DW_AT_type offset does not point to type info' error message so one can distinguish which check lead to the message. 2010-01-26 DavidAnderson * dwarfdump.1, dwconf.c, dwconf.h, dwarfdump.conf: The default frame values in frame output are now generic registers like r0 to r99 instead of MIPS register names. For the MIPS register names use '-x abi=mips'. * print_frames.c: Added commentary. 2010-01-17 DavidAnderson * print_die.c: The special case DW_AT_SUN_func_offsets now prints identically in dwarfdump and dwarfdump2. 2010-01-03 DavidAnderson * tag_common.c, common.h, common.c: Remove line terminator characters. Update copyright year. * All other files: Update copyright year. dwarfutils-20200114/dwarfdump/ChangeLog2011000066400000000000000000000375311361531463500202200ustar00rootroot000000000000002011-12-14 DavidAnderson * print_die.c: Add support for newer DW_OP_GNU_* . 2011-12-13 DavidAnderson * dwarfdump.c, common.c: Update version string. * tag_attr_ext.list, tag_common.h: New information on GNU attributes meant allowing a larger row count. 2011-12-13 DavidAnderson * tag_common.h: A new attr in the .list means increasing the column count. 2011-12-13 DavidAnderson * print_lines.c: Now prints no-column as 0 not -1. And prints the DWARF3/4 line table values when present. * tag_attr_ext.list: Add a GNU extension. 2011-10-30 DavidAnderson * configure.in: Removed a couple bogus lines which were reporting strange shell errors. * configure: Regenerated. * dwarfdump.c: Refine the error outputs so bogus reports do not print. Refactor the debuginfo/types prints for better reporting of errors. * globals.h: Refactoring meant changing one prototype here, the print_infos() prototype. * print_die.c: Refactor the debuginfo/types prints for better reporting of errors. Remove an 'error' report about DW_DLE_REF_SIG8_NOT_HANDLED. It's unclear what we might want to do here in future, but an error report is misleading. 2011-10-29 DavidAnderson * dwarfdump.c, common.c: Update version strings. 2011-10-29 DavidAnderson * dwarfdump.c: Reset the CU hints at each new section. Set up reloc flags so debug_types gets relocated if necessary. * globals.h: Add DEBUG_TYPES for the .debug_types section. Add a type-unit signature pretty-printer function. Add DW_SECTION_REL_DEBUG_TYPES so debug_types can be relocated. * print_reloc.c: Add entries so debug_types can get relocated. * print_die.c: Now we handle both debug_info and debug_types sections. Moved some CU header print operations to little helper functions to clarify the code. Refactored print_infos() to deal with debug_types and debug_info. Using the new libdwarf functions that allow debug_types. * print_lines.c: Delete unused local variable and its setting code. 2011-10-26 DavidAnderson * Makefile.in, README: Added Make settings of PREINCS POSTINCS PRELIBS, POSTLIBS to simplify building when libdwarf or libelf are not in the normal locations. Documented usable ways to deal with unusual situations at build time. 2011-10-24 DavidAnderson * common.c: Update version string. * dwarfdump.c: Update version string. To get '-c cu-name' to work we need to set a local flag which is now set. * dwarfdump.1: Clearly identify the command line options where URI style input is expected. 2011-10-23 DavidAnderson * dwarfdump.c: Fix omission of a 'break' statement for case 'q'. 2011-10-23 DavidAnderson * dwarfdump.1: Now command line input strings are translated from uri-style * dwarfdump.c: Translate input strings to from uri style to characters. Fix indentation mistakes. Fix constness issues on character strings. * dwconf.c: Fix constness issues on character strings. * dwconf.h: Fix constness issues on character strings. * globals.h: Fix constness issues on character strings. * makename.c: Fix constness issues on character strings. * makename.h: Fix constness issues on character strings. * uri.c: Fix indentation mistakes. 2011-10-22 DavidAnderson * common.c :Update version string. * dwarfdump.c: Update version string. Do not set ranges_flag with -a because that is unsafe to print seperately in general. * dwarfdump.1: Rewrite the man page for completeness and accuracy. 2011-10-11 DavidAnderson * common.c: Update version string. * dwarfdump.c: Update version string and translate -S strings from uri-style to standard strings so spaces and other standard characters are easily represented (no quoting problems). Update version string. * print_die.c: For -S -W we were printing the wrong die-level. * uri.h,uri.c: Add the translate_from_uri() function. Fix some of the tests in uri.c to match to- and from-uri. 2011-10-09 DavidAnderson * common.c, dwarfdump.c: Update version strings. 2011-10-09 DavidAnderson * dwconf.c,print_die.c, print_frames.c: Fix bad indentation. 2011-10-09 DavidAnderson * print_die.c (get_location_list): Tests for DW_DLV_ERROR were written without {}, added in the braces. 2011-10-08 DavidAnderson * dwarfdump.cc: If doing any relevant checking, instantiate all three possibly-usable BucketGroup objects. That makes it simpler to avoid a coredump when the user provides a nonsensical option set -- at a cost of a very small amount of memory. 2011-10-06 DavidAnderson * dwarfdump.c: Removed a newline in a printf to match dwarfdump2. Calls of get_attr_value() now have extra argument, so fix them. * dwarfdump.conf: Having 'mips' be an ABI which really reflected the IRIX abi and IRIX compilers was a mistake. Now that abi works for modern MIPS. * globals.h: get_attr_value() adds an argument. * print_die.c: Expanded the error messages in a couple type_offset_result checks. Worked around the global nature of esb_base by saving it locally while we recursively traverse DW_AT_type like things looking for bad references. Added a 'verbose' argument a few places so (at a critical point) show_form_itself won't add a form string when we really don't want it to. * print_static_funcs.c: Fixed an error string so it says static funcs, not pubnames. * print_lines.c: Ensure we only check for errors when we request such checking. * print_reloc.c: Ensure we don't index off the end of scn_names. Deal with missing names and bad symbol indexes consistently. When working with a .rela, report name as the section name instead of calling it .rel in the relocations output. 2011-10-05 DavidAnderson * dwarfdump.c: Increased COMPILER_TABLE_MAX for better reporting. Provide a 'HARMLESS ERROR' title in output if there are any such. One issue is (for relocatable objects) libdwarf attempts to continue even if relocations fail, and a relocation failure is now counted as a harmless error (even if it turns out to be harmful!). When sorting compilers_detected, use the producer name to sort when error counts are identical. If the compiler table fills up, print a note. With -ka, no longer explicitly turn check_frames_extended off, it is off already unless the user turned it on explicitly with -kxe. * print_die.c: The check for a file number (decl_file) was simply wrong. Made some detail changes to reporting. * print_frames.c: Added comments about the inefficiency for getting function names when printing frames (dwarfdump2 does not suffer the same inefficiency). * print_locs.c: Do not use a side effect for updating the index before printing in print_locs(). 2011-10-03 DavidAnderson * dwarfdump.c: for -kF, add check_lines. Ensure uniformity in the usage-text ending. * print_lines.c: Ensure lines printing suppresses some error reporting when appropriate. 2011-10-03 DavidAnderson * print_die.c: Fix the formx code by removing recently-added use of llabs(). Fix format botch, and correct small error string mistakes. Empty esb_extra string when it is no longer valid. 2011-10-03 DavidAnderson * dwarfdump.c: Minor formatting changes. * print_die.c: Initialize some local varables at definition. Ensure that we do not get a FORM name in a name string (so a test works right). And also ensure a FORM name does not get into a compiler-target setting. Refine the formx_print_value() so it is more complete (like dwarfdump2). Ensure show_form_itself() uses the argument, not a global, for the show-form test. * naming.c: Introduce a {} pair on an 'if' to reduce the possibility of future errors. * print_pubnames.c: Add error details to match dwarfdump2. * print_ranges.c: If not printing, return immediately. * print_reloc.c: A test was coded with = where == was needed. * print_types.c: Move local variable definitions to the block they are used in. 2011-09-29 DavidAnderson * dwarfdump.c: Amplifying the -n help string. * print_abbrev.c: Adding the standard test of the section print option before printing the header line for the abbrevs section. * print_die.c: Added a {} pair to avoid eventual bug. * print_frames.c: Reformatted a comment for readability. * print_lines.c: Added a status test for consistency with the rest of the code. * print_reloc.c: One of the assign-and-test removal changes in the previous changes was wrong. 2011-09-26 DavidAnderson * dwarfdump.c: Removed duplicate usage_text strings. * print_reloc.c: In case we don't have ELF64 headers, do the last-best-hope internal define in the right place so it actually helps. For some local variables, ensure they have values defined at the definition point. Switch some assign-and-test into two lines. 2011-09-20 DavidAnderson * Makefile.in: Fixed typo in comment. * common.c: Use snprintf, not sprintf. Updated version string. * dwarfdump.c: Correct typo and move usage_text to a source position corresponding to that in dwarfdump.cc. Updated version string. 2011-09-16 DavidAnderson * dwarfdump.c, common.c: Update version string. 2011-09-15 DavidAnderson * dwarfdump.c, common.c: Update version string. 2011-09-14 DavidAnderson * dwarfdump.c, common.c: Update version string. 2011-09-08 DavidAnderson * config.h, configure.in, dwconf.c, globals.h: Switch compile dependency to configure time HAVE_STDAFX_H instead a system-dependent ifdef. * configure: regenerate. 2011-09-08 DavidAnderson * print_frames.c: Ensure each tsearch tree pointer is zeroed after emptying the tree. * addrmap.c: Now we actually free all the records, we were misusing tsearch a little bit. 2011-09-05 DavidAnderson * print_frames.c: Now only check duplicate fdes if checking frames. * dwarfdump.conf: Updated to use address_size and includeabi. * dwconf.h, dwconf.c: Adding configure keywords address_size and includeabi. 2011-09-02 DavidAnderson * common.c,dwarfdump.c: Update version string. 2011-06-07 DavidAnderson * dwarfdump.c,common.c: Updated version string. * dwarfdump.c: Refactor setting of do_print_dwarf and do_check_dwarf into a function. Ensure that one of the refactored new functions is called in every case an option requires such call. Ensured indents ok. * print_lines.c (print_line_numbers_this_cu): When not checking added a check to insure we don't try to call a checking-related function. 2011-06-07 DavidAnderson * CODINGSTYLE: Added this new document. * common.c: Updated version string. * dwarfdump.c: Updated version string, fixed indentation. * print_lines.c: Two line table checks moved from decl_file to line_table sections of the summary report and both now show the possibly-wrong pc. Since one is not necessarily a bug, the wording of the message now has 'possibly' in it. * print_die.c: Reinitialize subprogram-relative pc high/low seen_PU_high_address whenever compilation unit changes, and use that field to avoid an erroneous comparison (when checking for an error). Fix some indentation errors introduced recently. 2011-06-06 DavidAnderson * dwarfdump.c: Changed the missing-producer-attribute default string used in summary/error outputs to "" so it is this string clearer. 2011-06-06 DavidAnderson * print_die.c: Now we strip off quotes dwarfdump added so -S match=main and the like work. 2011-06-06 DavidAnderson * common.c: Updated version string. * dwarfdump.c: Updated version string. * print_die.c: Corrected handling of DW_AT_data_member_location. Corrected handling of 'class constant' function formxdata_print_value() so it does not leak memory. 2011-06-05 DavidAnderson * dwarfdump.c: Updated version string. Now -kd forces a summary error report, always. Even if no errors found or even checked-for. * common.c: Updated version string. 2011-06-05 DavidAnderson * dwarfdump.c,print_aranges.c,print_reloc.c: A few indents did not match the standard multiple-of-4-spaces. Corrected. 2011-06-03 DavidAnderson * checkutil.c (ProcessBucketGroup): Deleted unused local variables. * common.c: Updated version string. * dwarfdump.1: Made the -k discussion more complete and accurate. Most option details are in the dwarfdump help/usage message, not in dwarfdump.1, to keep the man page small. * dwarfdump.c: Updated version string. Made more variables static in recognition they are only touched in this file. Added {} on some if statements to make the body clear. Parenthesized a complex test with && || to clarify intent. Added sanity testing of the 'current compiler' count and its use. * globals.h: Added safe_strcpy() prototype as it is used by multiple source files so we need a visible prototype. * print_aranges.c: Add 'arange end' printing (it is a real DWARF record type, so should be printed). Add a test to avoid duplicated die printing and error-counting when it is not requested. * print_die.c: An = in an if corrected to ==. Parenthesized a complex test with && || to clarify intent. Deleted an unused local variable. * print_lines.c: Deleted unused local variables. Added {} for each struct in an array so the initialization gets done right. * tag_attr.c: Deleted an unused local variable. * tag_tree.c: Deleted an unused local variable. 2011-04-23 DavidAnderson * dwarfdump.c, common.c: Updated DWARF_VERSION string. 2011-01-04 DavidAnderson * print_frames.h print_static_vars.c Makefile.in print_static_funcs.c print_sections.c print_strings.c print_locs.c print_die.c print_reloc.c print_reloc.h print_lines.c print_pubnames.c dwarfdump.c strstrnocase.c tag_tree.c print_ranges.c print_abbrevs.c print_macros.c configure.in tag_attr.c dwarfdump.1 naming.c esb.c checkutil.c makename.c dwconf.c print_types.c checkutil.h tag_tree.list print_weaknames.c globals.h common.c print_frames.c print_aranges.c common.h: New correctness tests and new formatting of various reports. dwarfutils-20200114/dwarfdump/ChangeLog2012000066400000000000000000000144371361531463500202210ustar00rootroot000000000000002012-11-29 David Anderson * dwarfdump.c, common.c: Update version string. * dwarfdump.c, print_die.c: Now all follow dicheck indent rules. 2012-11-29 David Anderson * dwarfdump.c, common.c: Update version string. 2012-11-27 David Anderson * dwarfdump.c, common.c: Update version string. 2012-11-20 David Anderson * dwarfdump.c, common.c: Update version string. * print_reloc.c: Inserted missing 'const' qualifiers fixing 3 compiler warnings. 2012-11-17 David Anderson * configure regenerated with autoconf 2.69 * dwarfdump.c, common.c: Update version string. 2012-11-17 David Anderson * addrmap.c,checkutil.c,common.c,dwarfdump.c,dwconf.c, globals.h,naming.c,print_aranges.c,print_die.c,print_frames.c, print_locs.c,print_ranges.c,print_reloc.c,print_reloc.h, print_strings.c,strstrnocase.c,tag_attr.c,tag_common.c, tag_tree.c,uri.c, tag_attr_ext.list,tag_attr.list,tag_tree_ext.list, tag_tree.list : Update copyright year. 2012-11-15 CarlosAlbertoEnciso * addrmap.c: Consistent layout for if statements. * checkutil.c: Incorrect string prefix for .text linkonce section name, is '.text.' for the applicable linke once sections, not simply '.text' Added print of internal (debugging dwarfdump) data not previously printed. * common.c: Consistent layout for if statements. Include "config.h". Minor layout change for #ifdef _DEBUG. Add HAVE_STDAFX_H check. * dwarfdump.1: Changes for new options: -E*, -h, -ls, -kE, plus some minor typo corrections. * dwarfdump.c: Consistent layout for if, for statements. Expand -E option to print the full information for the ELF header (32-bit and 64-bit) to include additional fields (e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum, e_shstrndx). Also, depending on the additional option to -E, the index, address, size and name for sections is printed. The additional option follow the convention used for -o option and can include any of the letters: hliaprfoRstxd. -Eh print information for the ELF header -E{liaprfoRs} print information for debug related sections -Ex print information for .text section -Ed same as -E{liaprfoRstx}. -E print the ELF header and the info for all available sections. New option: -kE, the attribute encodings are checked to see if they can use fewer bytes when encoded using LEB128. Expand -l option to print line information with no offsets values (-ls). Useful for comparisons. Expand -S option to print number of occurrences for the searched pattern (-Sv. Remove support for internally quoted strings. Remove extra 'break' for case 'o' in 'process_args'. Include the value zero for -# (internal debug level) Fix layout for 'qsort_compare_compiler' and use compiler name in the sort to get a stable sort. Now that name strings are not qoted internally, ensure that we do not expect such quotes in checking compiler names. * dwconf.c: Consistent layout for if statements. * globals.h: Add externs and defines for the items newly needed globally. * naming.c: Consistent layout for if, for statements. * print_aranges.c: Consistent layout for if statements. * print_die.c: Consistent layout for if, for and switch statements. Remove unused symbols 'seen_PU_base_address', 'seen_PU_high_address'. Rename 'errno' to 'dwerrno' to avoid conflict with system symbol. Missing DWARF_CHECK_COUNT and DWARF_CHECK_ERROR when testing self references category. Support for counting number of occurrences of the pattern being searched (See -S option). Add support for new option -kE; the atrribute encodings are checked to see if they can use fewer bytes when encoded using LEB128. New functions 'check_attributes_encoding', 'print_attributes_encoding' and new data structure 'a_attr_encoding' were created. Include DW_TAG_template_alias in the function 'get_attr_value' as it refers to a type in the case of checks for type offsets. Remove support for internally quoted strings. Add space so DW_OP_bregx prints more readably. * print_frames.c: Consistent layout for if statements. * print_lines.c: Consistent layout for if statements. Implement the ability to print line information with no offset values (useful when comparisons are required, as the pc values can change but the basic line information remains the same). Minor layout changes. * print_locs.c: Consistent layout for if statements. * print_ranges.c: Consistent layout for if and for statements. * print_reloc.c: Consistent layout for if statements. Move names for relocation types to individual header files based on architecture (ARM, MIPS, PPC, PPC64, X86_64). Fix incorrect layout for 'set_relocation_table_names' function. Use condition compilation symbols (DWARF_RELOC_MIPS, DWARF_RELOC_PPC, DWARF_RELOC_PPC64, DWARF_RELOC_ARM, DWARF_RELOC_X86_64)in the function 'set_relocation_table_names' to get relocation table information. Add support for X86_64 architecture. * print_reloc.h: Move definitions for relocation types to individual header files based on architecture (ARM, MIPS, PPC, PPC64, X86_64). * print_strings.c: Consistent layout for if statements. * strstrnocase.c: Consistent layout for if and for statements. * tag_attr.c: Consistent layout for if and for statements. * tag_attr.list: Add some missing attributes and the complete set for DW_TAG_rvalue_reference_type; remove a duplicated DW_AT_name. * tag_common.c: Consistent layout for if statements. * tag_tree.c: Consistent layout for if and for statements. * tag_tree.list: Missing DW_TAG_union_type to allow verification of nested unions. * uri.c: Consistent layout for if and for statements. 2012-04-10 DavidAnderson * dwarfdump.c, common.c: Updated version string. dwarfutils-20200114/dwarfdump/ChangeLog2013000066400000000000000000000103061361531463500202110ustar00rootroot000000000000002013-10-17 David Anderson * print_types.c: Remove pointless blank line. 2013-08-15 David Anderson * dwarfdump.c: Now calls dwarf_register_printf_callback() so dwarf_print_lines() output is shown (if dwarfdump wants it shown). Update version string. * common.c: Update version string. 2013-08-13 David Anderson * esb.c: Add 1 so the esb_append_printf has room for the NUL byte. * print_die.c: Clarified a comment about DW_AT_high_pc and FORM class constant. Fixed indent error. * dwarfdump.c: Fixed indent error. 2013-08-08 David Anderson * print_reloc.c: Removed duplicated call to get_scndata(). 2013-08-07 David Anderson * dwarfdump.c: Changed non-fatal error messages to write to stdout instead of stderr. Making it much easier to have a usable output-with-errors in case of redirection. Updated version string. * checkutil.c: If a certain pointer not set, just do nothing, there is no reason to abort. Added in a missing [ in a debug printf. * common.c: Updated version string. 2013-07-30 David Anderson * common.c,dwarfdump.c: updated version string. 2013-02-05 David Anderson * dwarfdump.c: Update version string. get_producer_name() now uses struct esb_s; * common.c: Update version string. * print_die.c: Check DW_AT_sibling values for sanity, and when something quite wrong is found, print an error and stop. get_producer_name() now uses struct esb_s; Added sibling_die_global_offset_ to die_stack_data_s so we can check sibling attribute values. get_attr_value() now uses esb_s pointer. * globals.h: get_producer_name() now uses struct esb_s; * print_aranges.c, print_pubnames.c:get_producer_name() now uses struct esb_s; * dwconf.c: The use of esb_s means we need to consider an empty config-file-path as no path and look in default places. We cannot just test for null pointer. 2013-02-04 David Anderson * dwarfdump/addrmap.c: Forgot to remove the addr_map_destroy() implementation in #ifndef HAVE_TSEARCH. Now it is removed. 2013-02-03 David Anderson * dwarfdump/addrmap.c: Implement HAVE_TDESTROY. tdestroy() is GNU only. Now we allow tsearch without tdestroy even though that means leaking every tsearch map we build. dwarfdump2 has no such leak. * dwarfdump/config.h.in: Add HAVE_TDESTROY. * dwarfdump/configure: Regenerate. * dwarfdump/configure.in: Test for tdestroy() function. * dwarfdump/print_frames.c: Zero out the map pointer. 2013-02-01 David Anderson * print_die.c: Replaced use of makename (which did malloc) with use of struct esb_s, avoiding a serious memory leak. Completely removed static struct variables esb_base and esb_extra, ensuring die string print-data is not corrupted by recursive calls. * dwarfdump.c, common.c: Update version string. 2013-01-26 David Anderson * dwarfdump.c, common.c: Update version string. * print_die.c: Print DW_OP_GNU_const_type properly using the binary-compatibility version of Dwarf_Loc. 2013-01-25 David Anderson * dwarfdump.c, common.c: Update version string. * print_die.c: Print DW_OP_GNU_const_type properly. 2013-01-16 David Anderson * dwconf.c: Changed table size to unsigned to eliminate signed/unsigned comparison warnings. * dwconf.h: Changed struct fields to unsigned to eliminate signed/unsigned comparison warnings. * esb.c: Checked for negative vfprintf return to avoid (hopefully impossible) error from crashing the program, and fix comparison warnings. * print_die.c: Changed counts to unsigned to fix signed/unsigned comparison warnings. * print_frames.c: Changed counts to unsigned to fix signed/unsigned comparison warnings. * print_reloc.c: Changed table sizes to unsigned to fix signed/unsigned comparison warnings. * tag_tree.c, tag_attr.c: Changed table sizes to unsigned to fix signed/unsigned comparison warnings. 2013-01-16 David Anderson * dwarfdump.c, common.c: Update version string. dwarfutils-20200114/dwarfdump/ChangeLog2014000066400000000000000000000166121361531463500202200ustar00rootroot000000000000002014-12-31 David Anderson * dwarfdump.c, common.c: Updated version string. 2014-12-28 David Anderson * dwarfdump.c, common.c: Updated version string. 2014-08-15 David Anderson * print_die.c(print_one_die_section): A c99-ism of declarations mixed with statements was present. Moved declaration of 'res' up a few lines. 2014-08-05 David Anderson * print_gdbindex.c: A couple places: Fixed indents on a comment. 2014-08-05 David Anderson * dwarfdump.c, common.c: Updated version string. 2014-08-04 David Anderson * dwarfdump.1: Mention -I option. * dwarfdump.c: Add -I to help output. * print_gdbindex.c: Add cu_list_len argument to print_culist_array so it can pass back the culist length for use by symboltable code. So symboltable code can know what indexes are type units and which compilation units. 2014-08-03 David Anderson * dwarfdump.c: Corrected typo in comment. * print_debugfission.c: Removed trailing whitespace. Fixed some small mistakes in the output. * print_die.c: Removed trailing whitespace. Fixed the section name. It was showing .debug_types when not wanted. 2014-08-02 David Anderson * print_debugfission.c, print_gdbindex.c: Use the section name strings returned by section-open for object files that have them (like Elf). 2014-07-12 David Anderson * print_die.c: Using a new interface to print the actual section name, not just .debug_info or .debug_types. dwarf_get_die_section_name(); * dwarfdump.c: Corrected a comment relating to .gdb_index and .debug_[ct]u_index sections * debugfission.c: Fix indentation mistakes. 2014-07-11 David Anderson * print_debugfission.c: Prints the offset and size tables. 2014-07-10 David Anderson * print_debugfission.c: Prints the hash table values of the .debug_tu_index and .debug_cu_index sections. 2014-07-09 David Anderson * print_debugfission.c: Removed trailing whitespace characters. 2014-07-09 David Anderson * Makefile.n: Add print_debugfission.o to the list. * globals.h: Add print_debugfission_index() interface. * print_debugfission.c: New file beginning to support print of .debug_tu_index and .debug_cu_index sections (DWARF5). 2014-07-02 David Anderson * dwarfdump.c: A missing comma after DW_SECTNAME_GDB_INDEX lead to a core dump. * print_die.c: The printf format for a warning message was messed up. Fixed. 2014-07-01 David Anderson * dwarfdump.c, print_gdbindex.c: Fixed indentation and trailing whitespaces. 2014-07-01 David Anderson * print_gdbindex.c: Now prints gdb_index symboltable. 2014-06-30 David Anderson * print_gdbindex.c: Add types printing. Add addressarea printing. 2014-06-29 David Anderson * print_gdbindex.c: Call latest libdwarf interfaces. Fix the formatting a bit. 2014-06-28 David Anderson * Makefile.in: Add print_dgbindex.o to objects list. * dwarfdump.1: Add -I to options list (for gdb_index section). * dwarfdump.c: Add gdbindex_flag and a call to print_gdb_index(). * globals.h: Add DW_HDR_GDB_INDEX to flags. * print_gdbindex.c: New file, prints .gdb_index section if the section is present in an object. 2014-05-20 David Anderson * dwarfdump.c, common.c: Updated version string. * print_die.c: now the dwo_id value prints as hex. 2014-05-19 David Anderson * dwarfdump.cc, common.cc: Updated version string. 2014-05-19 David Anderson * print_die.c: Removed two unused local variables. 2014-05-18 David Anderson * dwarfdump.c,print_die.c: Fixed indent errors and removed trailing whitespace. 2014-05-14 David Anderson * print_die.c: Complete printing of DW_FORM_GNU_str_index, DW_FORM_GNU_addr_index, DW_FORM_addrx, DW_FORM_constx. * print_frames.c: Now supports DW_FORM_GNU_addr_index, DW_FORM_addrx, DW_FORM_constx. * dwarfdump.c: Update version string. Trivial text realignment of argument strings in print_error() and print_error_and_continue(). * common.c: Update version string. 2014-05-11 David Anderson * print_die.c: Add printing of DW_FORM_GNU_str_index, partial of DW_FORM_GNU_addr_index. Support for DW_OP_GNU_const_index too. * dwarfdump.c: Trivial change to error strings so each is unique. Update version string. * common.c: Update version string. 2014-04-15 David Anderson * uri.c(hexdig): was testing 0, fixed to be '0'. 2014-04-14 David Anderson * dwarfdump.c,common.c: Update version string. 2014-04-12 David Anderson * dwarfdump.c,common.c: Update version string. 2014-02-13 David Anderson * dwarfdump.cc: Minor changes in the commentary relating to the search paths for dwarfdump.conf. No code changed. 2014-02-08 David Anderson * dwarfdump.c,common.c: Update version string. 2014-02-08 David Anderson * Makefile.in: Having a single rule build two independent things interacted badly with make -j 2 , so now each rule just builds a single target (see tag*.list builds). 2014-02-02 David Anderson * tag_attr.list,tag_attr_ext.list,tag_tree.list,tag_tree_ext.list: Removed trailing whitespace. 2014-01-31 David Anderson * addrmap.c: Forgot to add include of dwarf_tsearch.h here. Added. * dwarfdump.c, common.c: Updated version string. 2014-01-30 David Anderson * print_die.c: Add limited support for DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. 2014-01-29 David Anderson * addrmap.c addrmap.h checkutil.c,checkutil.h, common.c common.h,dwarf_tsearch.h,dwarfdump.c,dwconf.c, dwconf.h,esb.c,esb.h,globals.h,makename.h,naming.c,naming.h: Remove trailing whitespace. * print_abbrevs.c,print_aranges.c,print_die.c,print_frames.c, print_frames.h, print_lines.c,print_locs.c,print_macros.c,print_pubnames.c, print_ranges.c, print_reloc.c,print_reloc.h,print_sections.c,print_sections.h, print_static_funcs.c, print_static_vars.c,print_strings.c,print_types.c, print_weaknames.c,strstrnocase.c, tag_attr.c,tag_common.c,tag_common.h,tag_tree.c, testesb.c,uri.c,uri.h,uritablebuild.c: Remove trailing whitespace. 2014-01-29 David Anderson * dwarf_tsearchbal.c,dwarf_tsearch.h: New source files. * print_frames.c: dwarf_tsearch now built in, we are no longer using libc tsearch. * addrmap.c: Now uses dwarf_tsearch. * configure.in, config.h.in: No longer need HAVE_TSEARCH or HAVE_TDESTROY * configure: regenerated 2014-01-10 David Anderson * dwarfdump.c: Change // comments to /* */ comments. * makename.c: Delete blank line and trailing space. Add cast so gcc -ansi compiles without complaint. * print_die.c, uri.c: Change // comments to /* */ comments. * tag_attr.c: Add getopt.h include so gcc -ansi compiles without complaint. * tag_tree.c: Add getopt.h and string.h include so gcc -ansi compiles without complaint. Add cast so strdup call to avoid warning. * addr_map.c: Add cast so strdup call does not cause warning gcc -ansi. 2014-01-04 David Anderson * dwarfdump.c: Initialize a local variable to zero and move a declaration (avoiding a c99-ism, the code is not supposed to be using c99 features). dwarfutils-20200114/dwarfdump/ChangeLog2015000066400000000000000000000512211361531463500202140ustar00rootroot000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-12-19 David Anderson * dwarfdump.c: Now we print macros alone by CU with -m (at least for DWARF5 macro format) * print_lines.c(print_source_intro): Minor local variable ordering change. * print_macro.c(print_source_intro): Minor local variable ordering change. 2015-12-19 David Anderson * print_macro.c: Print the actual macro offset size we will use. 2015-12-18 David Anderson * dwarfdump.c,globals.h print_die.c,print_lines.c, print_macro.c,print_pubnames.c,print_ranges.c: Removed globals elf_max_address and elf_address_size in favor of local variables and new global function get_address_size_and_max(). 2015-12-16 David Anderson * print_aranges.c, print_die.c: Ensure the four error-reporting globals DIE_[CU_][global_]_offset are set properly. 2015-12-16 David Anderson * common.c: Update version string. * dwarfdump.c: Update version string. Fix PRINT_CU_INFO() to do what was intended (and not have a side effect). * print_aranges.c: Folded a too-long line. * print_die.c: Folded a line so both offsets listed on same line. * print_macro.c: moved macro_context call above the print of ".debug_macro" so if the section does not exist we print nothing. 2015-12-15 David Anderson * print_macro.c: Much of printing DWARF5 macros now works. 2015-12-13 David Anderson * print_macro.c: Call new function dwarf_get_macro_ops_count() and print returned values. 2015-12-12 David Anderson * print_macro.c: Now does -vv intro with cu_die print too. * print_macros.c: Only print .debug_macro name if there are some. 2015-12-11 David Anderson * naming.h,naming.c: Added get_MACRO_name(). * print_macro.c: Now reads and prints macro5 header. 2015-12-11 David Anderson * esb.c: esb_append now checks for NULL string pointer. Added comment esb functions do NOT check for NULL pointers generally. 2015-12-10 David Anderson * esb.c: esb_get_copy() failed to account for the trailing NUL. esb_get_copy was not being tested by SELFTEST. Fixed both issues. 2015-12-08 David Anderson * common.c,dwarfdump.c: Update version string. * print_frames.c: Fix trailing whitespace. Implement an attempt at DW_CFA_METAWARE_info. 2015-12-08 David Anderson * print_frames.c: Fix indents and remove trailing whitespace. Add comments: Errors in DIE info just result in omitting procedure names, no warning/errors. * dwarfdump.c: Deleted Elf64_Ehdr *eh64 declaration that can never be used. 2015-11-30 David Anderson * print_frames.c: Remove trailing whitespace. 2015-11-30 David Anderson * Makefile.in: Add print_macro.o to build list. * dwarfdump.c: Add macro_flag flag to signal print of DWARF5 debug_macro data. * globals.h: Export new macro print function. * print_die.c: Call new macro print function, skip that attr in checking-only run.. 2015-11-28 David Anderson * globals.h: Added DEBUG_FRAME_EH_GNU define for consistency.. * print_frames.c: use the new dwarf_get_frame_section_name() and dwarf_get_frame_section_name_eh_gnu() functions for section names. * print_lines.c: Use the new dwarf_get_line_section_name_from_die() function for the section name. * print_locs.c,print_macros.c,print_pubnames.c,print_static_funcs.c, print_types.c,print_weaknames.c: Added comments. These are places where the section is either obsolete or the section name is rarely of any use. 2015-11-27 David Anderson * dwarfdump.1: Mentions that with zdebug sections offsets refer to expanded object section, not compressed section. * print_aranges.c,print_die.c,print_lines.c,print_ranges.c, print_strings.c: Get the real section name from libdwarf. 2015-11-26 David Anderson * common.c,dwarfdump.c: Updated version string. * config.h.in, configure.in, Makefile.in: Deals with zlib when present. 2015-11-15 David Anderson * Makefile.in: Now supports building in a clean separate directory. 2015-11-11 David Anderson * print_abbrevs.c(dwarf_get_array_info): Initialize local variable. * print_die.c(get_location_list): Initialize local variable.: * dwarf_loc.h: Add declaration of _dwarf_loc_block_sanity_check(). * dwarf_loc.c: Call new function _dwarf_loc_block_sanity_check * dwarf_loc2.c: Implement and call new function _dwarf_loc_block_sanity_check to avoid duplicating code. 2015-11-07 David Anderson * dwarfdump.1: Documented -x line5=. * dwarfdump.c: Revised -g so it no longer turns on -i. Revised the meaning of -g to mean use old loclist interfaces (for testing the older interfaces with dwarfdump). * print_die.c(get_small_encoding_integer_and_name): a dwarf_dealloc referenced err whereas *err was correct. Revised loclist output making it look a bit like DWARF5 even for DWARF2,3,4 output. Reads better, I think. * print_locs.c: -l gets a 'no longer supported' message as it was never safe to do anyway. 2015-11-01 David Anderson * configure.in: Add -O0 to --enable-wall. So if a coredump during debugging gdb will work really well. * configure: Regenerated. * print_frames.c: Ommitted a 'return' statement so some output duplicated. Added in the missing return. 2015-11-01 David Anderson * Makefile.in, configure.in: Implement --enable-wall for compile-time checking. * configure: Regenerate. * print_die.c: Add DWARF5 DW_OPs and .debug_loc.dwo loclists are handled. Now uses either latest (DWARF5) interfaces or earlier, repurposing the old -g option to select. * print_frames.c,print_frames.h: Printing expressions (in .debug_frame, .eh_frame) now honors -g so DWARF5 expressions handled. * print_lines.c: Fixed some formatting. * print_locs.c: Changes reflecting code calling into print_frames.c 2015-10-26 David Anderson * print_die.c: Removed debug printf.Corrected DW_OP_GNU_const_type handling (cannot be fully reported for certain new location operators). 2015-10-15 David Anderson * print_die.c: Added DW_FORM_strp_sup, same idea as DW_FORM_GNU_strp_alt. 2015-10-15 David Anderson * dwarfdump.c: Add enum line_flag_type_e so we can test all the srclines interfaces (4 of them). Expand -x for that too. * print_die.c: Support DW_FORM_GNU_strp_alt. * print_lines.c: Update for old and new srclines interfaces. * globals.h: Added the enum line_flag_e variable for recording -x line5= value. 2015-10-06 David Anderson * dwarfdump.c: Now allow selecting alternate line table reading code so line table routines can be tested thoroughly. * print_lines.c: Uses one of the selected line table routine sets. Adds new line access routine calls to test those too. * globals.h: Declares new flag line_skeleton_flag; * print_die.c: Moved a local declaration to where it is used. Added a missing DW_DLV_ERROR check so in case of error we do not leak memory. 2015-09-26 David Anderson * dwarfdump.c, common.c: Update version string. * print_lines.c: Added local variables for clarity in a call, changed the dwarf_srclines_dealloc() location to fully clean up after a two-level line table srcfiles call. 2015-09-26 David Anderson * dwarfdump.c, common.c: Update version string. 2015-09-24 David Anderson * dwarfdump.c, common.c: Update version string. * print_lines.c: IA in line header hint is really spelled IS. Fixed now. * dwarf_elf_access.c: Added R_IA64* and R_390 relocation ifdefs for cases where they are not in a test machines elf.h or the like. 2015-09-23 David Anderson * print_lines.c: Removed accidental newline from output. 2015-09-22 David Anderson * print_die.c: Removed trailing whitespace and fixed indentation mistake. * print_lines.c: Fixed indentation and inconsistencies in spelling line table field hints. Leaving IA as has been for a long time though it should be spelled IS. 2015-09-19 David Anderson * print_lines.c: Tweaking two-level line table code, mostly comments.. 2015-09-17 David Anderson * print_lines.c: Adding handling of experimental two-level line table. 2015-09-15 Carlos Alberto Enciso * common.c: For Windows version, add a symbol with the release date (taken from the distributed compressed archive), to be used by print_version_details() for better tracking of versions. * print_die.c: The text search (-S), now follows the DW_AT_specification and the DW_AT_abstract_origin attributes, to get the associated name; this finds the declaration and definitions DIEs for a member functions or the abstract and concrete instance DIEs for inlined functions. Fix some C99 issues with local variable declarations in get_attr_value(). * print_aranges.c: Add an extra newline in print_aranges(). 2015-09-15 David Anderson * print_die.c: for case DW_AT_dwo_id a c99-ism has been changed to be like C89. 2015-09-14 David Anderson * dwarfdump.c: Remove trailing space. * print_frames.c, globals.h: print_frame_inst_bytes() defined and used in one file, so made a static function, removed from globals.h 2015-09-13 David Anderson * dwarfdump.c, common.c: Update version string. 2015-09-11 David Anderson * dwarfdump.c: Update usage message to mention -x tied= and update version strings. * common.c: Update version string. 2015-09-11 David Anderson * dwarfdump.c: Fixed copy/paste errors so DebugFission code works (see tieddbg in the source). 2015-09-11 David Anderson * dwarfdump.c, dwarfdump.1: Added -x tied= option so one can get .debug_addr data when referencing a .dwp or .dwo. Tieing these together. * print_die.c: Fixed indent errors. 2015-09-05 David Anderson * tag_attr.list,tag_attr_ext.list,tag_tree.list: removed trailing whitespace. 2015-07-12 David Anderson * dwarfdump.c: Use dwoptind dwoptarg, not optind, optarg * dwgetopt.c,dwgetopt.h,dwgetopttest.c,tag_attr.c, tag_tree.c: Use dwoptind dwoptarg etc, not optind, optarg, optopt op6error etc. * print_die.c: updated commentary. 2015-05-07 David Anderson * common.c, dwarfdump.c: Update version string. * print_die.c: Print DW_AT_dwo_id properly as a Dwarf_Sig8 value. 2015-05-03 David Anderson * print_die.c: Print the fission data from the index section when we print cu header, not when printing cu DIE. Moved cu header/cu die print code to functions, simplifying calling code. 2015-05-01 David Anderson * tag_attr.list: Added a DW_AT_signature and moved a couple attributes to match the standard-document order of attributes. 2015-03-10 David Anderson * dwarfdump.c: Update version string. * common.c: Update version string. * dwgetopt.c: Was mishandling options missing their required argument and coredumping dwarfdump. * getopttest.c: Added new tests to ensure we have the dwgetopt() fixes working properly. * Makefile.in: Added new test runs to 'make test'. * print_die.c, print_lines.c: Removed instances of trailing whitespace. 2015-03-09 David Anderson * Makefile.in: added new tests of dwgetopt. Runs not only dwgetopt but system getopt. * dwarfdump.c: New function set_checks_off() so if printing we don't do checks (intended to be this way for a long time now). Updated version string. * common.c: Updated version string. * print_die.c: Was not always recognizing unit DIES DW_TAG_partial_unit or DW_TAG_type_unit where it saw DW_TAG_compile_unit. Now does so. * dwgetopt.c: Errors could lead to dwarfdump coredump. Fixed. * getopttest.c: Added several new tests. Now one can run single tests and run against either getopt or dwgetopt (set at compile time of getopttest.c). 2015-03-03 David Anderson * tag_attr.list: Removed DW_AT_sibling from DW_TAG_partial_unit. DW_TAG_compile_unit. Removed DW_AT_containing_type from DW_TAG_subprogram, DW_TAG_structure_type. * dwarfdump.c,common.c: Update version strings. * print_die.c: Fix indent mistakes. Add comment in _dwarf_print_one_expr_op() that one error is not presently realizable (FreeBSD compiler noticed the situation). * print_ranges.c: Fix indent mistakes. * tag_attr.c: Remove trailing whitespace from a #include line. 2015-03-03 Carlos Alberto Enciso * dwarfdump.c: Add allocate_range_array_info(), release_range_array_info() calls to help fix range checking. * globals.h: Add declarations of range checking functions. * print_die.c: Add check_range_array_info() call. Add record_range_array_info_entry() call. Move all the range check code out of print_die.c. Add handling of high_pc as an offset, not just as a value. * print_ranges.c: Delete unneeded includes. Add check_ranges_list() implementation moved from print_die.c. Add new ranges check functions. Range check error messages now appear later in the output, though the content is identical. * tag_attr_ext.list: Add DW_TAG_GNU_call_site and DW_TAG_GNU_call_site_parameter tag attr combinations. * tag_tree_ext.list: Add DW_TAG_GNU_call_site DW_TAG_call_site_parameter 2015-02-22 David Anderson * configure.in: removed getopt.h from tests, we use local dwgetopt now. * dwgetopt.h: Function name is dwgetopt. Prototype named right now. Copied from libdwarf dwgetopt.h * configure: regenerated * Makefile.in: build dwgetopt.o * dwgetopt.c: Copied from libdwarf source. * tag_attr.c,tag_tree.c: Now call dwgetopt() instead of getopt(). 2015-02-04 David Anderson * common.c,dwarfdump.c:Updated version string. * print_debugfission.c: Now we are using a Dwarf_Sig8 for fission hash so we introduce an esb_s to do the formatting. * tag_attr.c: Now we format a more detailed message when we detect an insufficient static tag_attr or tag_tree array instance. It's code only used at build time so just giving up is fine: someone changed dwarf.h. * tag_attr.list: Adding new TAGs and new Attrs from DWARF5. Since the DWARF5 standard not yet final these could change! * tag_attr_ext.list: Added new GNU attributes. * tag_common.h: updated DW_TAG_last and DW_AT_last STD_TAG_TABLE_ROWS STD_ATTR_TABLE_COLUMNS values due to dwarf.h updates. * tag_tree.list: New entries from DWARF5. 2015-01-31 David Anderson * DWARFDUMPCOPYRIGHT: updated to reflect changes today. Old versions of the copyright notices still shown here. * common.c,dwarfdump.c,dwconf.c,esb.c,makename.c,naming.c, print_abbrevs.c,print_aranges.c,print_die.c,print_frames.c, print_lines.c,print_locs.c,print_macros.c,print_pubnames.c, print_ranges.c,print_reloc.c,print_sections.c,print_static_funcs.c, print_static_vars.c,print_strings.c,print_types.c,print_weaknames.c, strstrnocase.c,tag_attr.c,tag_attr.list,tag_attr_ext.list, tag_common.c,tag_tree.c,tag_tree.list,tag_tree_ext.list, uri.c,uritablebuild.c: Removed obsolete SGI postal address and web references. 2015-01-31 David Anderson * common.h,dwconf.h,esb.h,globals.h,makename.h,naming.h, print_frames.h,print_reloc.h,print_sections.h,tag_common.h,uri.h: The address and URI for SGI is obsolete and there is no replacement so deleted some lines from the copyright statements. 2015-01-30 David Anderson * common.c,dwarfdump.c: Update version string. * globals.h: Added format_sig8_string() to global functions. * print_debug_fission.c: Updated .debug_cu/tu_index hash signature code to match libdwarf (Dwarf_Sig8, not Dwarf_Unsigned). Allow for missing hash (?). * print_die.c: Use format_sig8_string(). 2015-01-29 David Anderson * print_die.c: Two places used C99-only variable declaration. Moved declarations up to conform to C90. 2015-01-24 David Anderson * dwgetopt.c,dwgetopt.h: Using NetBSD getopt source with modifications to support :: for uniform behavior for all users. Not all getopt are the same. Named dwgetopt(). * dwgetopttest.c: Does tests of dwgetopt() for conformance with dwarfdump requirements. See 'make selftest'. * Makefile.in: Now has selftest for dwgetopt and links dwgetopt.o into dwarfdump. * esb.c: Now prints PASS on success and counts errors. * dwarfdump.c: Now calls dwgetopt and includes dwgetopt.h Added a new global so we recognize where needed not to do some checks when checking ( for debugfission some things not sensible). * globals.h: Removed cu_offset (not needed) and added suppress_checking_on_dwp flags. * print_die.c:renamed cu_offset to be a static: dieprint_cu_offset Reset it when finished with a CU. (-k checks got into trouble when both .debug_info and .debug_types present). 2015-01-21 David Anderson * common.c, dwarfdump.c: Update version string. * print_die.c: For a DW_FORM_ref_sig8 type signature value, if not printing the actual FORM print so the hex value makes sense. It is obviously not a .debug_info global offset. Now prints debug fission (dwp) information for each CU with such. 2015-01-18 David Anderson * common.c, dwarfdump.c: Update version string. 2015-01-15 David Anderson * dwarfdump.c: dump_unique_errors_table() ifdef out of normal compiles, it is unused. Unused local variables removed. Update version string. * esb.c: Moved stdarg.h include just after stdio.h include for positioning consistency. * globals.h: Added stdarg.h include just after stdio.h include as we use va_list a lot and so stdarg.h is required. * print_debugfission.c: Remove two unused local variables. * print_frames.c: Remove trailing whitespace. * tag_attr.c: #include stdarg.h. Add {} to array initializers output to avoid compiler warning. * tag_common.c: Move stdarg.h include to just after stdio.h for positioning consistency. Update version string. * tag_tree.c: Revised include order to start with globals.h and to not duplicate includes of stdio.h etc. Add {} to array initializers output to avoid compiler warning. * testesb.c: Add include of stdarg.h. 2015-01-12 David Anderson * tag_common.c: Add comments about va_start, va_end. * esb.c: Add comments about va_start, va_end. Add va_end in the selftest code. * common.c: Update version string. * dwarfdump.c: Update version string. Add va_end() and comments about va_end. 2015-01-08 David Anderson and Carlos Alberto Enciso * Makefile.in: add selftest: rule, which tests esb.c * dwarfdump.c: Add new options -O file=path, -kD -kG -ku kuf. New checking and reporting features intended to give a report on attribute and tag usage. Update version string. * common.c: Update version string. * esb.c, esb.h: Added new interface using stdarg. Added self-test feature. * dwarf_makename.c: new #pragma (not Linux/Unix related). * print_die.c: Implements collecting the new statistics dwarfdump reports. * print_lines.c: New statistics collected. * tag_attr.c: New checks for the tag/attr table correctness. * tag_attr.list: Fixes duplicated entries. * tag_attr.list_ext: Adds APPLE attribute DW_AT_APPLE_optimized that llvm emits. * tag_common.c: bad_line_input() now allows stdarg calls so its easier to emit good error messages. * tag_common.h: bad_line_input() arg list changed a little. Stdarg now. * tag_tree.c: New tag tree checking done. New statistics available. * tag_tree.list: Adds DW_TAG_unspecified_type, DW_TAG_rvalue_reference_type, DW_TAG_restrict_type. * tag_tree_ext.list: Adds DW_TAG_GNU_template_template_parameter. Fixes duplication of entries. 2015-01-05 David Anderson * dwarfdump.c: Don't call dwarf_finish() if the dwarf-init call failed. * common.c,dwarfdump.c: Updated version string. 2015-01-01 David Anderson * A new year begins. dwarfutils-20200114/dwarfdump/ChangeLog2016000066400000000000000000000601271361531463500202220ustar00rootroot000000000000002016-11-24 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version strings. 2016-11-24 David Anderson * Makefile.in: Clean *~ 2016-11-22 David Anderson * print_abbrevs.c: Some -k abbrev warnings did not make it clear that they were checking against a heuristic sanity-check value for the maximum number of attributes, not a genuine maximum. 2016-11-22 David Anderson * tag_attr.c: Remove bogus blank line with trailing spaces. 2016-11-11 David Anderson * print_frames.c: Apply fix to local_dwarf_decode_s_leb128_chk so it matches libdwarf dwarf_leb.c. A fix for certain bit pattern provoking undefined behavior in C.. 2016-11-01 David Anderson * tag_attr.c,tag_common.h,tag_attr_ext.list: Adding Ada GNAT gcc attributes DW_AT_GNU_numerator, DW_AT_GNU_denominator, DW_AT_GNU_bias in the extended table for checking. 2016-10-21 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version strings. 2016-09-30 David Anderson * configure.in: Add additional -fsanitize tests to --enable-sanitize option. * configure: Regenerated. * print_die.c: Ensure << applied to unsigned to avoid undefined operation. We were getting officially undefined behavior. * tag_attr_ext.list: Removed trailing whitespace from two lines. 2016-09-30 David Anderson * makename.c: The unused static function value_hashfunc() has been removed. * tag_attr.c, tag_tree.c: Changed (1<form with in an error message. * print_frames.c: Now checks for bogus expression block lengths and bogus LEB values. LEB reading functions now here and static functions. * print_sections.c: Moved leb reading functions to print_frames.c 2016-05-07 David Anderson * dwarfdump.c, common.c: Update version string. * print_frames.c: For local variable added initialization-at-definition. 2016-05-06 David Anderson * sanitized.c: Fixed trailing whitespace and added 'static' to local function definition. 2016-05-05 David Anderson * Makefile.in: Added sanitized.o to objects to build. * dwarfdump.1: Document '-x nosanitizestrings'. * dwarfdump.c: Set internal flag based on '-x nosanitizestrings'. * globals.h: add extern for the flag no_sanitize_string_garbage and the sanitized() interface. * print_die.c,print_frames.c,print_lines.c, print_macro.c, print_macros.c : Call sanitized() on some strings. * sanitized.c: Changes control characters int output to %xx uri-style (by default). See '-x nosanitizestrings'. 2016-05-03 David Anderson * dwarfdump.c: revise print_error_maybe_continue() to print additional useful data. * print_die.c: If dwarf_srcfiles() gets DW_DLV_NO_ENTRY do not print a warning. Normal to have no DW_AT_stmt_list. * print_lines.c: Fix column header 'row' changed to 'lno'. Refine a CHECK message to say a DW_LNE_end_sequence does not exactly match function high address. It is not an error, just something about how the code was emitted. 2016-04-30 David Anderson * dwarfdump.c, common.c: Update version string. 2016-04-27 David Anderson * dwarfdump.c, common.c: Update version string. 2016-04-27 David Anderson * dwarfdump.c: Update version string. Remove a field from printf on error as that duplicates the error number in the error string. 2016-04-25 David Anderson * esb.c, dwarfdump.c: Fix a couple indent mistakes. 2016-04-25 David Anderson * esb.h, esb.c: The typedef for 'string' is now gone, it was never helpful.. * dwarfdump.c: Remove 'string' use. * dwgetopt.c: Moved test-only function to getopttest.c. Added (void) argument to a the functions with no arguments. * getopttest.c: Repaired failures to to renaming to dwoptind etc and added the test-only function from dwgetopt.c * globals.h: Removed 'string' typedef. * print_die.c,print_frames.c, print_lines.c, print_strings.c, tag_attr.c, tag_tree.c: Removed use of 'string' type, use plain old char*. 2016-04-21 Carlos Alberto Enciso Printing using the 'esb' module was broken. It seems to work because the default internal buffer size (240), was big enough to receive the resulting output. * esb.c, esb.h: Missing prefix 'esb' for 'allocate_more'. Initial buffer size reduced to 16. New function 'esb_open_null_device': open 'null' device. New function 'esb_close_null_device': close 'null' device. New function 'esb_allocate_more_if_needed': allocate more space if required, leaving the contents unchanged, so the caller, does not need to worry about it. There are 2 cases: Windows: use the 'null' device to get the required space UNIX: use a big buffer (512). But if the result is bigger, the original problem will be shown. The function 'esb_append_printf_ap', now takes care of increasing the buffer if needed. * dwarfdump.c: In the case of windows, open and close the 'null' device, in order to setup the esb module. 2016-04-21 Carlos Alberto Enciso * globals.h: Do not define 'string' for a C++ build; it clashes with the 'std::string'. * print_die.c: Minor typo error. 2016-04-21 Carlos Alberto Enciso * For a WINDOWS version, display the 32/64 bits configuration. 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-03-17 David Anderson * print_die.c(print_one_die_section): One dieprint_cu_goffset Dwarf_Unsigned->Dwarf_Off. 2016-03-12 David Anderson * print_abbrevs.c(print_abbrevs): Printed output of an abbrev with code and tag but no attributes was simply wrong. Now fixed. Now avoids printing children flag on a null abbrev (a NUL byte meaning no abbrev is there at all, ending a list of abbrevs). * print_die.c: it was difficult, even with -G -v, to identify the actual offset (in .debug_abbrev) of the abbreviations. Now -i -G -v gives a bit more data on abbreviations. 2016-03-09 David Anderson * dwarfdump.c,globals.h,print_aranges.c,print_die.c,print_frames.c, print_lines.c,print_macro.c,print_pubnames.c: Remove the global dieprint_cu_offset, use local vars and pass around instead. Ensure the traverse() logic when checking type references do not evaluate references to other sections. Many argument lists got an additional argument or two. 2016-03-07 David Anderson * dwarfdump.c: Update version string. Added CU_low_address so CU_base_address is properly used only for the DWARF CU 'base address' notion. Print CU_low_address in PRINT_CU_INFO(). * common.c: Update version string * globals.h: New macro DROP_ERROR_INSTANCE(d,r,e) improves consistency where we need to drop a Dwarf_Error instance. * print_die.c: Support for CU_low_address. Use DROP_ERROR_INSTANCE where appropriate. * print_frames.c: Use DROP_ERROR_INSTANCE where appropriate. 2016-03-03 Carlos Alberto-Enciso * dwarfdump.c: Missing '_' just for consistency. Print any harmless errors only the required in command line * globals.h: Unused declaration. * print_die.c: When displaying a DW_AT_type offset error, uses the standard 0xdddddddd format. Wrap to 80 columns, a long line. 2016-02-17 Carlos Alberto-Enciso * dwarfdump/tag_attr_ext.list,dwarfdump/tag_common.h, dwarfdump/tag_tree_ext.list: Tighten up the list limits and add commentary about the list limits. 2016-02-14 DavidAnderson * dwarfdump.c,common.c: Updated version strings. * print_die.c,print_strings.c: fixed indent errors. 2016-02-14 Carlos Alberto-Enciso * tag_attr_ext.list, tag_tree_ext.list: Adding DW_TAG_GNU_template_parameter_pack,DW_TAG_GNU_formal_parameter_pack. * tag_tree.c: Printed wrong name from tag-tree table in a comment. * tag_common.h: Ext tag table rows count was higher than needed. Ext attr table rows increased to 11. 2016-02-13 David Anderson * dwarfdump.c,globals.h,print_aranges.c,print_die.c, print_frames.c,print_lines.c,print_locs.c,print_macro.c, print_pubnames.c,print_reloc.ckprint_static_funcs.c, print_static_vars.c,print_strings.c,print_types.c, print_weaknames.c: Removed global Dwarf_Error err and provided local Dwarf_Error as needed. 2016-02-13 David Anderson * configure.in: Add -Wshadow to --enable-shared. Add else and cross-compile [] to the AC_TRY_RUN * configure: Regenerate. * dwarf_tsearchbal.c: Delete shadowed variable p, we use the original instead. * dwarfdump.c: Rename variables to avoid confusing duplicated names (found by -Wshadow). #if 0 the unused function old_get_cu_name(), which should get deleted. * globals.h: Fixed prototypes, #if 0 prototype of the unused function old_get_cu_name(). * print_abbrevs.c, print_aranges.c,print_debugfission.c, print_die.c,print_frames.c, print_gdbindex.c, print_lines.c, print_pubnames.c, print_ranges.c, print_sections.c, tag_attr.c, tag_tree.c: Add local Dwarf_Error and rename variables to avoid shadowing confusion. 2016-02-10 David Anderson * globals.h: Change enum val from std to singledw5. Some compilation environments reserve 'std'. * dwarfdump.c,print_lines.c: Use the new spelling. 2016-02-10 David Anderson * common.c,dwarfdump.c: Update version string. 2016-02-07 David Anderson * common.c,dwarfdump.c: Update version string. 2016-02-06 David Anderson * print_die.c,tag_attr.c,tag_tree.c: Remove trailing whitespace. 2016-02-06 David Anderson * warningcontrol.h: Defines UNUSEDARG macro as needed. * common.c,dwarf_tsearchbal.c,dwarfdump.c,globals.h, macrocheck.c: Now use UNUSEDARG macro so known-unused args do not cause spurious warnings. * configure.in: Sets HAVE_UNUSED_ATTRIBUTE if the compiler in use supports __attribute ((unused)). So we can have lots of warnings turned on without seeing the warnings we wish to ignore for now. * configure,config.h.in: Regenerated. 2016-02-06 David Anderson * print_frames.c: Was printing cie index, not fde index, in the fde output. Now prints more sensibly. Now tests do_print_dwarf, the flag it should have been using, to decide whether to print. 2016-02-02 David Anderson * dwarfdump.c: Get section sizes so we can do a better sanity check on ofsets (ie, call dwarf_get_section_max_offsets_c()). Check DWARF2 macros for sanity just as we do DWARF5 macros. Read DWARF2 macros per-cu, not as a standalone section. Add global data section_high_offsets_global, a struct with all known section sizes. * macrocheck.c: New section size argument for more complete size analysis. * globals.h: Declarations for section_high_offsets_global. * macrocheck.h: Update prototype of print_macro_statistics(). * print_die.c: Drop section-as-a-whole macro reporting for macinfo in favor of reporting per CU. * print_macros.c: Allow for print and check runs (not both at once). 2016-01-28 David Anderson * dwarfdump.c,common.c: Update version string. * print_die.c: Changed the most frequent global die offset values to print as GOFF=0x... for uniformity with -G and space saving from the string 'global die offset'. 2016-01-27 David Anderson * print_die.c: Added a helpertree find call on typedieoffset which is really a better check for known signed/unsigned. 2016-01-26 David Anderson * dwarfdump.c,common.c: Update version string. 2016-01-26 David Anderson * Makefile.in: Added helpertree.h, and .c. * dwarfdump.c: Added include helpertree.h * print_die.c: Now attempts (harder) to figure out if a constant is really signed or insigned when printing it. Fixes annoyance with printing attributes longer than 27 characters. Unifies a number of printf-style calls into functions, reducing the number of statically visible calls to sprintf. Attempts to remember whether some things are explicitly typed as signed or unsigned. * helpertree.h, helpertree.c: New. Simple use of tsearch to memo-ize signedness. 2016-01-20 * configure.in: Added more compiler optiosn to --enable-wall * configure: Regenerated * dwarf_tsearchbal.c: Fixed warnings. * dwarfdump.c: Fixed warnings. * dwconf.c: Fixed warnings. * dwconf.h: Fixed warnings. * esb.c: Fixed warnings. * globals.h: Fixed warnings. * print_debugfission.c: Fixed warnings. * print_die.c: Fixed warnings. * print_frames.c: Fixed warnings. * print_sections.c: Fixed warnings. 2016-01-20 * macrocheck.c: Remove trailing whitespace. * print_lines.c: Only print line context record if we do_print_dwarf is non-zero. The directory index was printing as 0 in the line_context record. Was a typo in the printf, now fixed. 2016-01-20 * configure.in: Now --enable-wall adds -Wdeclaration-after-statement etc. * configure: Regenerated. * dwarfdump.c: Now all functions have visible prototypes, no (). * dwconf.c: Now local func declared static. * dwgetopt.c: Added include dwgetopt.h. Unused function #if 0 so invisible. * globals.h: Now all functions have prototypes, no (). * macrocheck.c: Removed unused locals. Fixed a dwarf_twalk call to *tree (not just tree). * naming.c: Added include naming.h. * print_gdbindex.c: Made local function static. * tag_attr.c,tag_common.c: Made local function static. 2016-01-19 David Anderson * dwarf_tsearchbal.c: Deleted the unused function rotatex(). * dwarfdump.c: Remove duplicate trailing ; * esb.c(esb_append): Straighten out the logic and avoid doing append if the to-be-appended string is empty. * globals.h Add ifdef __cplusplus for extern "C". * esb.h,naming.h: Idempotent #ifndef and __cplusplus extern "C" added. * print_frames.c: Ensure local var starts at zero. Move statement to below declarations. * print_lines.c: Ensure declarations before executable statements. 2016-01-19 David Anderson * print_frames.c: Fix trailing whitespace and indentation. 2016-01-19 David Anderson * print_die.c,tag_tree.c: Change statement ;; by removing second semicolon. 2016-01-17 David Anderson * common.c: Update version string * dwarfdump.c: Made reset_overall_CU_error_data() a global. We now try to show CU name etc on case there is an error reading frame data. Update version strin. Added DEBUG_FRAME DEBUG_FRAME_EH to the PRINT_CU_INFO() tests. New function: load_CU_error_data(). * print_frames.c: Now uses a local Dwarf_Error in a few places (CU names for frames) instead of the global 'err' so we do not get the errors mixed up. We now try to show CU name etc on case there is an error reading frame data. 2016-01-14 David Anderson * common.c: Update version string. * dwarfdump.c: Update version string. Include macrocheck.h. Delete one accidental blank line. * dwarf_tsearchbal.c: Added comment about compiler warning. * dwarf_macrocheck.c: Added missing return statement. Removed trailing whitespace. Fixed broken qsort_compare() * macrocheck.h: Fixed trailing whitespace. * print_abbrevs.c: Generalized an attribute count warning a bit (see GENERAL_MAX_ATTRIB_COUNT). Fixed the code handling the abbrev_array to be correct and a bit simpler. Added new abbreviations tests. * print_die.c: Include macrocheck.h. Fix trailing whitespace. 2016-01-12 David Anderson * common.c: Update version string. * dwarfdump.c: Update version string. * print_abbrevs.c: If an abbreviation number is a bit goofy, accomodate it so we do not write to memory we did not allocate. It will be caught a bit later in the run as an invalid DIE or abbreviation. * print_die.c: When we switch sections inside a DIE print save and restore current_section_id to get the best reporting on errors/checks. 2016-01-12 David Anderson * common.c,dwarfdump.c: Update version string. 2016-01-12 David Anderson * Makefile.in: Adding macrocheck.h, and .c. Adding selftest of macrocheck.c. * dwarfdump.c: Now handles imported DWARF5 macros and adds support for -kw for macro section checking. * globals.h: Adding check_macros flag and macro_check_tree declaration and print_macros_5style_this_cu() declaration.. * print_die.c: Now prints imported macros using print_macros_5style_this_cu(). * print_macro.c: Now deals with imported macro units using macrocheck.c and .h. Fixed bug for DW_MACRO_define/undef where we did improper string validity check. dwarfutils-20200114/dwarfdump/ChangeLog2017000066400000000000000000000263171361531463500202260ustar00rootroot000000000000002017-12-01 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-11-20 David Anderson * configure.in: Just do TRY_COMPILE instead of TRY_RUN to avoid issues in a cross-compile. * configure: Regenerated. 2017-10-20 David Anderson * print_die.c: Now handles DW_FORM_data16. 2017-10-16 David Anderson * dwarfdump.c,globals.h,print_ranges.c,print_section_groups.c: a large group of per-object totals/values were not free()d or zeroed for each member of an archive. Some of the zero/free() was moved from the end of main() to be done per-object and some were simply never completely reset before. These problems were only visible when running dwarfdump on an archive. 2017-10-15 David Anderson * dwarfdump.c: Added a call to destruct_abbrev_array() per object so the archive case can work properly with -ka. * dwgetopt.c: Unused local variable 'found' deleted. * print_abbrevs.c: Now -ka can handle bogus large abbreviation number without crashing when checking abbreviations.. 2017-10-15 David Anderson * dwgetopt.c,dwgetopt.h: Now handles simple long argument names cases. * getopttest.c: Added tests of long (--) argument names. 2017-10-13 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-10-12 David Anderson * dwarfdump.c: Now more careful with archive names presented by libelf and Elf_Arhdr. 2017-10-12 David Anderson * print_section_groups.c: Added a cast on a free() call to avoid a compiler warning. * dwarfdump.c: On an archive (.a) dwarfdump would print a useless warning on encountering a special / or // member. Now just skips those, and if some other member is not an object dwarfdump prints a more useful message to identify the particular member. * print_die.c: The attributes_encoding_table was not getting reset properly in the case of reading an archive, and that is now fixed. 2017-10-05 David Anderson * tag_attr.list: Changed the spelling from DW_AT_ranges_base to the final DWARF5 spelling, DW_AT_rnglists_base. 2017-10-05 David Anderson * dwconf.c: Open the config file "r", not "rw". 2017-09-26 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-08-22 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-08-21 David Anderson * CMakeLists.txt: Fix the TAG_TREE_SOURCES and TAG_ATTR_SOURCES entries. * Makefile.in: Fix a misuse of LD_LIBRARY_PATH and use LIBDWARF_PATH as the path to libdwarf.so. * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. * common.c: #include changes help for builds on Windows. Rename a parameter to avoid accidental name-shadowing. * configure.cmake: Fix ac_check_lib() uses. * dwarfdump.c,dwconf.c,esb.c: Modify #ifdefs to ease building on Windows. * getopttest.c: Cast/printf changes avoid warnings on 32 and 64 bit builds. * macrocheck.c: An extra newline makes the 'make test' output easier to understand. * testesb.c: The check() function is local, so call it 'static' to avoid a compiler warning. 2017-07-24 David Anderson * configure.in, configure.cmake, config.h.in: Renamed LOCATION_OF_LIBELFHEADER to HAVE_LOCATION_OF_LIBELFHEADER for consistency with config.h.in generally. * configure: Regenerated 2017-07-24 David Anderson * configure.in, configure.cmake: Consistent use of LOCATION_OF_LIBELFHEADER so Windows can build libdwarf with configure or cmake. * configure: Regenerated 2017-07-09 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-05-28 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-05-28 David Anderson * macrocheck.c: Trivial revision of main() declaration to our standard format. * print_reloc.c: We were reading one-past the end of symtab entries(now fixed). Now relocation sections show the Elf section index and we print them in order as in the object file (earlier it printed in a fixed order not related to the object file). Deleted the rel/rela section name arrays, we already have the section name at hand. 2017-05-27 David Anderson * esb.c: For selftest now indents report lines to make it easier to see the overview pass/fail. * Makefile.in,macrocheck.c,print_reloc.c: Makes macrocheck self test results clearer (pass/fail) and adds a check on the array of relocation section data in print_reloc.c. 2017-05-26 David Anderson * section_bitmaps.h,section_bitmaps.c: Added comments. 2017-05-25 David Anderson * common.c,tag_attr.c,tag_tree.c: Update version string. * dwarfdump.c: Update version string. Instead of using bitmaps for printing sections and relocations use char arrays instead. Faster, easier to read, and much easier to expand to the longer lists of sections. By using fixed size arrays for this the compiler can check for simple errors. * print_reloc.c: Moved #defines over to section_bitmap.h Arrays are now fixed size to give compiler the ability to notice simple coding errors. Added the new DWARF5 sections to lists of what is to print. We do not use zero as a section number so we add an unused zero element to each array. * print_reloc.h: Made idempotent with ifndef. * section_bitmaps.c: Now uses the char array id and indexes starting at 1 (per the #defines in section_bitmaps.h). Revised the code in 'make selftest' to do more complete checking. * section_bitmaps.h: Now all the REL and RELA #defines are here so it's easy to see them all at once. Now using indexes starting at 1, not bitfields. Faster,simpler, and for a given dwarfdump run the switch from bitmaps will expand static data by well under 20 bytes total. 2017-05-18 David Anderson * dwarfdump.c: Fixed a small memory leak in special_program_name(). Deleted four lines of test code that never got removed. 2017-05-17 David Anderson * CMakeLists.txt: Add section_bitmaps.h,.c. * Makefile.in: Add section_bitmaps.o, section_bitmaps.h. Add section_bitmaps 'make selftest' rules. * section_bitmaps.h, section_bitmaps.c: The bit field code used to control the -E option set was out of date and difficult to get right. Now 'make selftest' ensures that the bits match up with the strings. * glflags.h, glflags.c: Fixed the misnamed gf_type_flag to be gf_types_flag. * globals.h: Move defines to section_bitmaps.h * common.c: Use sanitized() on incoming strings we print. * print_aranges.c,print_debugfission.c: Names from elf now get sanitized() for printing. * print_section_groups.c: Improved one interface. * print_die.c: Critical fixes so we get the section names on output when we want them, and sanitized(). * common.c, print_aranges.c, print_debugfission.c,print_ranges.c, print_strings.c: Calling sanitized() to ensure printf safety. * print_section_groups.c: Revised function interface. Do not use May 13 interface. * print_die.c: Crucial revision so DWARF4 debug_types prints. * dwarfdump.c: Revised flags so the gf_section_groups_flag works. Revised the section bitmaps code. * print_section_groups.c: Delete a printf left in for debugging. 2017-05-13 David Anderson * CMakeLists.txt, Makefile.in: Mention new print_section_groups.c or .o. * dwarfdump.c: Add needed section names in print_object_header() data. Implement glflags.gf_section_groups_flag. * print_section_groups.c: New, implementing handling of section groups (aka COMDAT). 2017-04-20 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-17 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-16 David Anderson * CMakeLists.txt: Added in new files glflangs.c, .h 2017-04-12 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-06 David Anderson * Makefile.in: Add glflags.o. Instead of dozens of boolean variables, a struct with the booleans makes understanding them much easier. * glflags.h, glflags.c: define and initialize all these flags and settings. * dwarfdump.c: Use the new glflags.h setting fields. Add one new one for debug_names (nothing useful implemented yet). * globals.h: Remove the flag global extern lines. * naming.c,print_abbrevs.c, print_aranges.c, print_die.c, print_frames.c, print_gdbindex.c, print_lines.c, print locs.c, print_macro.c, print_macros.c, print_pubnames.c, print_ranges.c, print_static_funcs.c, print_static_vars.c, print_strings.c, print_types.c, print_weaknames.c: Using the new flag globals as glflags.gf_ * print_dnames.c: New for .debug_names printing. 2017-04-06 David Anderson * dwarfdump.c, Makefile.in, globals.h: This is a small start on dealing with DWARF5 .debug_names. 2017-04-02 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-04-02 David Anderson * dwarfdump.c: If printing group 2 (DWARF5 dwo sections) ensure that printing of those sections only possible in group 1 is turned off. 2017-03-30 David Anderson 2017-03-30 David Anderson * dwarfdump.1: Documenting the new -x groupnumber= option. * dwarfdump.c: Adding groupnumber option support. * sanitized.c: Removed trailing whitespace 2017-03-24 David Anderson * dwarfdump.c: Now argv[0] is checked before setting the program_name global variable. If it contains /dwarfdump.O that part of the string is shortened to /dwarfdump. Doing this removes a need for the regressiontests to use sed and shortens the regressiontests runtime on a one machine from 77 minutes to 23 minutes. 2017-03-23 David Anderson * common.c, dwarfdump.c, tag_attr.c, tag_tree.c:Update version string. 2017-03-21 David Anderson * sanitized.c: Now all non-ascii bytes are changed to %xx and a % input character is changed to %xx too iso-8859 and for html are now sanitized using URI %xx notation so the printf output looks sensible. These usually represent a corrupted string in an object file. 2017-03-21 David Anderson * print_die.c: Added casts to call args match with the function declaration. So a fussy compiler will be less likely to complain. * sanitized.c: Added explicit initializers to global variables. Moved a static var to the function that uses it. 2017-01-31 David Anderson * esb.c(esb_force_allocation): Code was wrong all this time. Fixed and corrected commentary. Updated copyright. 2017-01-30 David Anderson * esb.c(esb_force_allocation): Add commentary about to clarify the purpose of the function. 2017-01-23 David Anderson * dwarf_tsearchbal.c(dwarf_tsearch): In memory exhausted situation the function could leak a little bit of memory. dwarfutils-20200114/dwarfdump/ChangeLog2018000066400000000000000000000641231361531463500202240ustar00rootroot000000000000002018-12-24 David Anderson * dwarfdump.1: Clarifying the effect of any - or -- option on the output of dwarfdump. 2018-12-21 David Anderson * command_options.c: Reformat a few lines of the usage text so it all prints in around 70 characters without overlap. 2018-12-20 David Anderson * dwarfdump.1: Clarifying: the abi=ppc etc options are only made use of if -a, -F, or -f (or the long versions of these) are used. 2018-12-20 David Anderson * dwarfdump.c,dwconf_using_functions.h,esb_using_functions.h: Removing trailing whitespace,empty last lines. 2018-12-20 David Anderson * globals.h: Removed include of * esb.c: Now includes 2018-12-20 David Anderson * print_frames.c: Now properly deals with endian mismatch in printing frame instruction details and avoids requiring we have a precise definiion of type lengths. * CMakeLists.txt,Makefile.am: Adding memcpy_swap.h. New header. 2018-12-19 David Anderson * CMakeLists.txt: Now has dwconf_using_functions.h and esb_using_functions.h listed so cmake works. * Makefile.am: Added new header dwconf_using_functions.h * dwarfdump.c: Includes new header. * globals.h: Remove dwconf_s forward decl, remove dwconf-using functions. * dwconf_using_functions.h: New, has the function declarations removed from globals.h * print_abbrevs.c,print_aranges.c, print_dnames.c, print_lines.c,print_locs.c,print_macro.c, print_macros.c,print_pubnames.c,print_section_groups.c, print_sections.c,print_static_funcs.c, print_static_vars.c,print_str_offsets.c, print_strings.c,print_types.c,print_weaknames.c: Removed include of "dwconf.h" * print_frames.c: Includes new header dwconf_using_functions.h. 2018-12-19 David Anderson * Makefile.am: Added new header esb_using_functions.h with content extracted from globals.h. * globals.h: Remove forward decl of esb_s and remove functions using that to esb_using_functions.h * dwarfdump.c,print_abbrevs.c,print_aranges.c, print_debugfission.c,print_die.c,print_dnames.c, print_frames.c,print_gdbindex.c,print_lines.c, print_locs.c,print_macro.c,print_macros.c,print_pubnames.c, print_ranges.c,print_static_funcs.c,print_static_vars.c, print_str_offsets.c,print_strings.c,print_types.c, print_weaknames.c,print_true_section_name.c: Include esb_using_functions.h 2018-12-19 David Anderson * globals.h: Removed an include of section_bitmaps.h and duplicate lines about UNUSEDARG. * command_options.c: Now includes section_bitmaps.h. * section_bitmaps.c: Now includes section_bitmaps.h. 2018-12-19 David Anderson * dwarfdump.c: Moved elf-header printing to print_reloc.c (print_object_header()). Removed elf argument from print_object_header(). * globals.h: Removed elf argument from print_object_header(). * print_reloc.c: Now all the elf header/sym/reloc printing is in this one file. 2018-12-19 David Anderson * dwarfdump.c: Now uses the new libdwarf function dwarf_errmsg_by_number() so we get more specific messages about problems when all we have is an errorcode. 2018-12-07 David Anderson * dwarfdump.1: -E missed its long-form (--elf) and -h (--help) was improperly documented. 2018-11-26 David Anderson * dwarfdump.c: Now dumps DWARF from PE objects. 2018-11-01 David Anderson * strstrnocase.c had include which is now "globals.h" as it was always supposed to be. 2018-10-30 David Anderson * dwarfdump.1: Now shows long and short options. For a few options it references the help file. * command_options.c: The available help options are now -h and --help, and both report the new options list with both short and long options shown. 2018-10-26 David Anderson * dwarfdump.c: A single instance of a malloc in main() had no associated free(). Memory Leak of a couple hundred bytes exactly once per run of dwarfdump. Now we free(). 2018-10-19 David Anderson * command_options.c,glflags.c,glflags.h: New option --file-use-no-libelf, function arg_file_use_no_libelf(), glflags.gf_file_use_no_libelf now exist. * dwarfdump.c: process_one_file() and main() are refactored to allow additional object files. 2018-09-29 David Anderson * command_options.c: Fixed indent issues. 2018-09-26 Carlos Alberto Enciso * command_options.c: At this point, the regression test pass, with the exception of 2 test cases, that verify the output from the '-h' option, which fails due to missing options in the usage data. 2018-09-25 Carlos Alberto Enciso * command_options.c: Add support for long name options that expect an argument by using the same code from the short options. 2018-09-25 Carlos Alberto Enciso * command_options.c: Add -he and --help-extended to display usage for the long name options. 2018-09-24 Carlos Alberto Enciso * command_options.c: Add support for long name options. 2018-09-24 Carlos Alberto Enciso * command_options.c: Add missing desriptions in the usage message for -q, -U, -x line5 and -x noprintsettinggroups. 2018-09-24 Carlos Alberto Enciso * command_options.c: Add missing desriptions in the usage message for -EI, -Em and -kw. 2018-09-20 Carlos Alberto Enciso * command_options.c: Move the code associated with each sub-option, to an individual function. Preliminary work for the implementation of long name options. 2018-09-19 Carlos Alberto Enciso * command_options.c: Move the code associated with each option, to an individual function. Preliminary work for the implementation of long name options. * glflags.h, glflags.c: New field to record the full program name. It is used by the '-V' option. 2018-09-21 David Anderson * Makefile.am: Ensured cmake files get into distributions. and the CODINGSTYLE text too. 2018-09-12 David Anderson * esb.c: Corrected the use of HAVE_NONSTANDARD_PRINTF_64_FORMAT. 2018-09-11 David Anderson & Carlos Alberto Enciso * dwconf.c: Fixed typo in a comment. * dwarf_tsearchbal.c: int->size_t three places. A couple too-long lines indented. Matches tsearch directory version now. * esb.c: The test for _WIN32 in looking at printf formats also allows config.h define HAVE_NONSTANDARD_PRINTF_64_FORMAT. 2018-09-11 David Anderson & Carlos Alberto Enciso * dwarfdump.c: Simplify the WIN32 code redirecting stderr to stdout as earlier workarounds no longer needed. Printing of parts of an Elf32 header had the wrong printf format-- fixed. * print_die.c: An implicit fallthrough to case DW_AT_LOCATION about line 2943 generates a warning with --enable-wall so added a comment to make it clear to readers this is intended. 2018-09-02 David Anderson * Makefile.am: Changed the way to build tag_tree and tag_attr executables to the automake way, eliminating make warnings when building. * Makefile.in: regenerated. 2018-08-23 David Anderson * CMakeLists.txt: Adjusted to fit new/changed file names. 2018-08-21 David Anderson * Makefile.am: Now honors --enable-wall * print_die.c,print_ranges.c,print_strings.c: Removed unused variables. * print_dnames.c: Removed unused variables and fixed the section-name print (.debug_str-> .debug_names). 2018-08-14 David Anderson * Makefile.am: CPPFLAGS_FOR_BUILD a few places it was accidentally omitted. 2018-08-09 David Anderson * Makefile.am: Added AM_TESTS_ENVIRONMENT enabling make check from any build directory. Also,add getopttest.c and testesb.c to the files in a release so make check can work * runtests.sh: Handle the environment variable AM_TESTS_ENVIRONMENT sets: DWTOPSRCDIR 2018-08-08 David Anderson * Makefile.am: corrected dwarfdump_DATA reference to be dwarfdumpdev_DATA 2018-08-07 David Anderson * dwconf.c: Removed trailing whitespace. * globals.h: Added DWARF_SECNAME_BUFFER_SIZE define (space for a small string) so if it need change there is just one place to change it. Used in many files with esb_constructor_fixed().. * print_abbrevs.c,print_die.c,print_locs.c,print_strings.c: Refactored the section name printing into a function and call after calling libdwarf so the interesting section compression info is available to print. * print_aranges.c,print_pubnames.c, print_ranges.c, print_static_funcs.c,print_static_vars.c,print_weaknames.c: Moved a libdwarf call above the section name print so the interesting section compression info is available to print. * print_dnames.c,print_frames.c: Removed trailing whitespace, use DWARF_SECNAME_BUFFER_SIZE. * print_gdbindex.c,print_lines.c,print_macro.c, print_macros.c,print_str_offsets.c: Use DWARF_SECNAME_BUFFER_SIZE . * true_section_name.c: Now prints compression values. 2018-08-06 David Anderson * globals.h: Added DWARF_SECNAME_BUFFER_SIZE for the esb preallocation of section names. * print_abbrevs.c,print_aranges.c,print_debugfission.c, print_die.c,print_dnames.c,print_frames.c, print_gdbindex.c,print_lines.c,print_locs.c,print_macro.c, print_macros.c,print_pubnames.c,print_ranges.c, print_static_funcs.c,print_static_vars.c,print_str_offsets.c, print_strings.c,print_types.c,print_weaknames.c: Now uses DWARF_SECNAME_BUFFER_SIZE instead of plain 40. * print_die.c: In print_ranges_list_to_extra() we do not want the section name to have the compressed-notes appear. * print_lines.c: In print_line_numbers_this_cu() we do not want the section name to have the compressed-notes appear. * print_ranges.c: In check_ranges_list() we do not want the section name to have the compressed-notes appear. * true_section_name.c: Added a pointer argument to get_true_section_name() so it returns three distinct compression flags. one for .zdebug*, one for SHF_COMPRESSED, and one for a ZLIB initial byte group in the section. 2018-08-05 David Anderson * Makefile.am: Fixed dwarfdump_CFLAGS to set CONFPREFIX * command_options.c Fixed config_file_defaults[] to honor CONFPREFIX sensibly. * globals.h: Declares get_true_section_name(), a new function/refactoring so section names print more usefully. * true_section_name.c: New. Implements get_true_section_name(). * print_abbrevs.c, print_aranges.c, print_debugfission.c, print_die.c, print_dnames.c, print_frames.c, print_gdbindex.c, print_lines.c, print_locs.c, print_macro.c, print_macros.c, print_pubnames.c, print_ranges.c, print_static_funcs.c, print_static_vars.c, print_str_offsets.c, print_strings.c, print_types.c, print_weaknames.c. 2018-08-02 David Anderson * Makefile.am: Removed unused variables and references to them. * Makefile.in: Regenerated (usually won't mention this). 2018-07-31 David Anderson * command_options.c: New option --print-debug-names. * print_dnames.c: Giving print_debug_names() some content. 2018-07-30 David Anderson * command_options.c: For abbreviation checking also try running print_abbrevs() with its checks. * print_abbrevs.c: If checking turn off normal printing, just print checking issues. 2018-07-30 David Anderson * tag_attr.list,tag_attr_ext.list,tag_common.h,tag_tree.list, tag_tree_ext.list: Some important relationships needed to be added to avoid -ka warnings about normal DWARF. And the table sizes are just a tiny bit bigger. 2018-07-13 David Anderson * Makefile.am: Add dwarfdump.1 to output. Move COPYRIGHT and a few files out of the installed set, leaving just dwarfdump.1, and libdwarf*pdf in /usr/local/share. * command_options.c: Removed duplicate extern declaration of dwoptind. 2018-07-16 David Anderson * dwarf_tsearch.h: Corrected web-reference links in the comments. * uritableblebuild.c: Changed some commentary to have shorter line lengths. Added comment explaining how the source was used in creating uri.c . * common.c: Refines the ifdef HAVE_STDAFX_H. * dwarf_tsearch.h: Remove obsolete link in comment and substitute a valid link. * dwarf_tsearchbal.c: Remove include of dwarf_incl.h and use config.h to set UNUSEDARG as appropriate. * dwconf.c,globals.h: Refines the ifdef HAVE_STDAFX_H. * uritablebuild.c: Reformat initial comments to fit on shorter lines. 2018-07-16 David Anderson * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-06-21 David Anderson * esb.c: For _WIN32 a closing } was missing int two places. Fixed. 2018-06-19 David Anderson * common.c: Added missing ; for Windows code * dwconf.c: ifdef _WIN32, not a HAVE* name. Spell include windows.h not Windows.h for maximum compatibility. 2018-06-13 David Anderson * Remove mention of HAVE_NONSTANDARD_PRINTF. 2018-06-13 David Anderson * configure.ac: New option --enable-elf-open setting HAVE_ELF_OPEN * config.h.in: HAVE_ELF_OPEN * configure.ac: Regenerated. * dwarfdump.c: Now uses open() unless HAVE_ELF_OPEN is explicitly set. 2018-06-10 David Anderson * checkutil.c: Fixed indentation mistake. * common.c: Removed trailing blank. 2018-06-10 David Anderson * checkutil.c: snprintf-> esb * common.c: snprint -> printf * dwarf_tsearchbal.c: snprintf -> sprintf, it is safe. * naming.c: snprintf-> esb. * print_die.c: Trimmed the size of a buffer in a safe sprintf use. * esb.c: Modified to remove an implementation-defined conversion issue. 2018-06-10 David Anderson * esb.c: Added checks so passing %s to _d or _u gets a useful output (an ESBERR string). * print_abbrevs.c,print_die.c,print_lines.c: Converted all sprintf to the new esb_append_printf_s,i,u. 2018-06-09 David Anderson * esb.c: Fixed an issue printing the most-negative integer. * print_die.c: Now all the relevant places avoid s[n]printf. 2018-06-09 David Anderson * esb.c, testesb.c: These now support and test %+d. * print_die.c: Used esb_constructor_fixed() and esb_append_printf_s,_i,_u(), replacing many s[n]printf. 2018-06-08 David Anderson * Makefile.in: Altered the esb testing lines. * testesb.c: Now this is the esb test code. * esb.c: Removed test code, moved to testesb.c. Added esb_append_printf_s(), esb_append_printf_i() and esb_append_printf_u() to get faster formatting without any varargs. 2018-06-07 David Anderson * print_frames.c: Vincent T. noticed unnecessary and/or incorrect casts, here fixed. Also fixed some too-long lines -- changed the existing line break to a better place. 2018-06-05 David Anderson * dwarfdump.c: Remove erroneous _MSC_VER per Carlos Alberto Enciso. Change WIN32 to _WIN32. 2018-05-26 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Remove DW_VERSION_DATE_STR and #include ../libdwarf/libdwarf_version.h to provide it. 2018-05-26 David Anderson * dwarfdump.c,tag_attr.c,tag_tree.c, common.c: Update version string 2018-05-23 David Anderson * esb.c, esb.h: Added esb_constructor_fixed() and new fields in esb_s to support use of a static buffer so normally no malloc needed when using the esb. * print_frames.c: Changed, where appropriate, to use esb_constructor_fixed. * dwarfdump/sanitized.c: The static initializer of all zero needed update for the new esb_s declaration. 2018-05-22 David Anderson * glflags.h, glflags.c: set_checks_off(void) needed the (void) as argument to be a C90 prototype. 2018-05-22 David Anderson * esb.c: Changed INITIAL_ALLOC to 100 as experiments show that a length in a range near 100 gives the best runtimes, by 10-20% user time. 2018-05-22 David Anderson * glflags.c: Removed the c99 'for (int i=0;' and declare the 'i' separately. 2018-05-20 David Anderson * dwarfdump.c: Change strcpy to safe_strcpy. Comment a safe sprintf call. * glflags.c: Change strcpy to safe_strcpy and fix indents. * dwconf.c: Change strcpy to safe_strcpy. * print_frames.c: Change snprintf to esb_append. Change the name of a local pointer to make it clearer it is not the same as other similar local variables. Use esb instead of char *, Change strcpy to safe_strcpy (and eliminate strcat). * print_gdbindex.c: Reinserted return statement that was accidentally dropped. * print_lines.c,print_macros.c: Remove trailing whitespace. * print_ranges.c: Remove trailing whitespace. * tag_attr.c: Remove unused 'len' local variable, 3 places. 2018-05-19 David Anderson * print_die.c,print_lines.c,print_macros.c,print_gdbindex.c, print_pubnames.c,print_ranges.c: Replace snprintf with esb_append_printf. * sanitized.c: Deleted a function call and snprintf with simple esb_append_printf. 2018-05-17 David Anderson * Makefile.in: Adding esb.c to build time of tag_tree_build and tag_attr_build. See besb.o * config.h.in: #undef for HAVE_VSNPRINTF and HAVE_SNPRINTF * configure: regenerated * configure.ac: Added AC_CHECK_FUNCS(snprintf), AC_CHECK_FUNCS(vsnprintf) * esb.c: Removed static buffers. No longer needed. Allocated extra byte in esb_force_allocation() and in calls to esb_allocate_more. Checks HAVE_VSNPRINTF. Added extra checks of esb_append_printf(). Moved one static function up in the source to eliminate an explicit prototype. * esb.h: Added comments documenting esb_s field use. * print_die.c,print_reloc.c,tag_attr.c, tag_tree.c,uri.c: Removed snprintf,sprintf. Using esb_append_printf. * makename.c: Removed noise from selftest, just print pass/fail. 2018-05-16 David Anderson * dwarfdump.c,esb.c,esb.h,globals.h: Removed of C99 vsnprintf and completely removed esb_printf_append_ap() from esb. 2018-05-15 David Anderson * tmp-tt-table.c,tmp-ta-table.c,tmp-ta-ext-table.c, tmp-tt-ext-table.c: All endings changed from .c to .h as these are all used via #include. * Makefile.in: Reflect the .c->.h change for these files. * checkutil.c,dwarf_tsearch.h,dwarf_tsearchbal.c, glflags.c,naming.c,naming.h,print_debugfission.c, print_die.c,print_frames.c,print_gdbindex.c,print_macros.c, print_pubnames.c,print_reloc.h,print_sections.c, print_static_vars.c,uri.c,uritablebuild.c: Removed trailing blank lines. 2018-05-15 David Anderson * command_options.c: Removed an extra break on option -ER that was an accident. It's been broken for quite a long time. section_map[DW_HDR_DEBUG_RNGLISTS]=TRUE, applicable to DWARF5, was getting ignored due to the mistake. This has to do with printing section header information. 2018-05-14 David Anderson * command_options.c,compiler_info.c,print_frames.c: Fix indents, remove trailing whitespace. 2018-05-14 David Anderson * dwarfdump.c,tag_attr.c,tag_tree.c, common.c: Update version string 2018-05-14 David Anderson * print_frames.c: Validate augmentation bytes from eh_frame to catch bogus augmentation length. 2018-05-14 David Anderson * dwarfdump.c: gcc caught a memset given a pointer as the size. Fixed. * naming.c: Needed #ifndef TRIVIAL_NAMING around skipunder() to compile without warnings. * section_bitmaps.c, section_bitmaps.h: Needed (void) as function argument list, for example set_all_sections_on(void) . 2018-05-14 Carlos Alberto Enciso * Rename producer_info.[ch] to compiler_info.[ch]. 2018-05-11 Carlos Alberto Enciso * New files: command_options.c,command_options.h Command line arguments processing; the original code moved from dwarfdump.c. * New files: producer_info.c,producer_info.h Record statistics about the producers (compilers). The original code moved from dwarfdump.c. * glflags.c,glflags.h,globals.h: Moved the remaining individual global flags and what they control into glflags.h. * section_bitmaps.c,section_bitmaps.h: process the header and relocation maps. Original code moved from dwarfdump.c * dwarfdump.c: Moved the code for command line arguments processing to command_options.c and producer_info.c. * print_reloc.c,sanitized.h,defined_types.h,dwconf.c,print_aranges.c Minor changes due to refactoring of the command line and producer refactoring. 2018-05-09 David Anderson * common.c,dwarfdump.c,glflags.c,glflags.h,print_aranges.c, print_die.c: Fixed indents to match dicheck requirements and removed some trailing whitespace. 2018-05-01 Carlos Alberto Enciso * common.c,dwarfdump.c,dwconf.c,glflags.c,glflags.h,globals.h, naming.c,print_abbrevs.c,print_aranges.c,print_die.c, print_dnames.c,print_frames.c,print_gdbindex.c,print_lines.c, print_locs.c,print_macro.c,print_macros.c,print_pubnames.c, print_ranges.c,print_static_funcs.c,print_static_vars.c, print_strings.c,print_weaknames.c,tag_attr.c,tag_tree.c: Moved the remaining individual global flags and what they control into glflags.h, making it easier to understand what one is looking at when reading the code. 2018-04-22 David Anderson * print_str_offsets.c: Created consistent terminology for the parts of a table and reflecting that in the table output. The DWARF5 standard uses more than one set of terms for the section contents. * dwarfdump.c,tag_attr.c,tag_tree.c: Update version string * common.c: Update version string. Now that usage text in full is only on request it now becomes stdout instead of stderr. 2018-04-19 David Anderson * Makefile.in: Added additional lines to test native getopt_long to verify dwgetopt_long works consistently with GNU getopt_long (for the features tested, anyway). * dwgetopt.c: Better checking for dwgetopt_long correctness. * getopttest.c: Added tests and revised the checking to avoid nasty corner cases. 2018-04-17 David Anderson * dwarfdump.c, dwarfdump.1: The -h option has not been supported for years (it printed an IRIX table of no interest now) so now -h means print the help message showing the options available. * dwgetopt.c: Now prints the name of any incorrect long-option it sees and prints if user-specified =arg on a long option violates requirements . For either returns -1. Should have done that all along. * getopttest.c: Added tests and revised the checking functions to show all the relevant data if a test fails. Added line number of the original test to the output so it's easier to find the actual test. 2018-04-16 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version string 2018-04-14 David Anderson * dwarfdump.1: Add --print-str-offsets. * dwarfdump.c: Add --print-str-offsets to the usage text. 2018-04-13 David Anderson * CMakeLists.txt: Added new source files to cmake info. 2018-04-13 David Anderson * common.c,tag_attr.c,tag_tree.c: Updated version string. * configure.ac: Added a comment about HAVE_LOCATION_OF_LIBELFHEADER * dwarfdump.c: Added support for option --print_str_offsets to print .debug_str_offsets. Updated version string. * glflags.h: Added new flag: boolean gf_print_str_offsets. * globals.h: Added print function print_str_offsets_section() to interfaces. * print_str_offsets.c: New code to print the .debug_str_offsets section independent of anything else. * Makefile.in: Added print_str_offsets.o to targets. 2018-04-06 David Anderson * configure.ac: Previous recent change introduced a mistake. Now we set HAVE_ELF64_R_INFO as intended all along. * configure: Regenerated 2018-04-02 David Anderson * CMakeLists.txt: Added defined_types.h to the set_source_group HEADERS list, but cmake is not currently working with libdwarf or dwarfdump. * configure.ac: Removed AC_CHECK_LIB and replaced with the newer AC_SEARCH_LIBS. Removed two cases using HAVE_LOCATION_OF_LIBELF_HEADER that never worked, it seems. * configure: Regenerated 2018-03-29 David Anderson * configure.ac: Corrected AC_CHECK_HEADERS use. Removed AC_TRY_COMPILE in favor of AC_COMPILE_IFELSE. Revamped checks for libelf and zlib. * configure: regenerated * config.h.in: regenerated 2018-03-28 David Anderson * configure.in renamed configure.ac 2018-03-27 David Anderson * configure.in: Cross compiling tested, working. * configure: regenerated. 2018-03-25 David Anderson * configure.in: Support for cross compiling * configure: regenerated. * Makefile.in: Support for cross compiling 2018-03-25 David Anderson * defined_types.h,dwarfdump/dwarfdump.c,esb.c,esb.h, globals.h,print_aranges.c,print_die.c,print_frames.c, print_lines.c,print_macro.c,print_macros.c, print_ranges.c, sanitized.c,sanitized.h,uri.h: Updated copyright year on the merged changes. * getopttest.c: Fixed compiler warnings (this is just for selftest, not usually compiled). 2018-03-25 Carlos Alberto Enciso: * many: Merged header simplifications into master. 2018-03-24 David Anderson * print_lines.c: Now uses dwarf_srclines_files_indexes() to simplify printing of DWARF2,3,4 and 5 line headers in a simple uniform way. 2018-03-22 David Anderson * print_lines.c: Now works with DWARF5 line table, showing correct file index for all versions. 2018-03-21 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Updated version string. 2018-03-21 David Anderson * print_die.c: Add support for DWARF5 FORMs. * print_lines.c: Fix a too-long line. 2018-01-29 David Anderson * print_frames.c: When printing detailed frame data ensure we check for corrupt data. 2018-01-29 David Anderson * common.c,dwarfdump.c,tag_attr.c,tag_tree.c: Update version string dwarfutils-20200114/dwarfdump/DWARFDUMPCOPYRIGHT000066400000000000000000000075061361531463500207060ustar00rootroot00000000000000 ========The dwarfdump copyright======= The full text of the GPL version 2 is provided in the file GPL.txt. See the end of this file for January 2015 changes. Nearly all the files in this directory have contained a GPL copyright, not an LGPL copyright, for years. The following is an example of that copyright as used in the dwarfdump source, and is what SGI always intended (in David Anderson's opinion) to have present in the DWARFDUMPCOPYRIGHT file. (tag_tree.list tag_attr.list acconfig.h have long been marked LGPL and therefore the LGPL copyright, not GPL, applies to those three files.) This GPL copyright text added here to DWARFDUMPCOPYRIGHT Dec 4, 2006 Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan The following was the entire content of this file before December 24 2006, Being the LGPL text this is in conflict with the individual source files and I (David Anderson) believe the source file copyright was intended for dwarfdump not the LGPL source directly following this note. However the 3 files tag_tree.list tag_attr.list acconfig.h have long been marked LGPL and the following copyright applies to those three. Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan As of 31 January 2015 the lines with http://www.sgi.com and oss.sgi.com have been removed. sgi.com is readily found on the web and oss.sgi.com no longer exists. No one from SGI still contributes to dwarfdump. dwarfutils-20200114/dwarfdump/GPL.txt000066400000000000000000000431031361531463500173150ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. dwarfutils-20200114/dwarfdump/Makefile.am000066400000000000000000000053101361531463500201640ustar00rootroot00000000000000###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = dwarfdump$(EXEEXT) subdir = dwarfdump ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(dwarfdumpdevdir)" PROGRAMS = $(bin_PROGRAMS) am_dwarfdump_OBJECTS = dwarfdump-addrmap.$(OBJEXT) \ dwarfdump-checkutil.$(OBJEXT) \ dwarfdump-command_options.$(OBJEXT) dwarfdump-common.$(OBJEXT) \ dwarfdump-compiler_info.$(OBJEXT) \ dwarfdump-dwarfdump.$(OBJEXT) dwarfdump-dwarf_names.$(OBJEXT) \ dwarfdump-dwarf_tsearchbal.$(OBJEXT) \ dwarfdump-dwconf.$(OBJEXT) dwarfdump-dwgetopt.$(OBJEXT) \ dwarfdump-esb.$(OBJEXT) dwarfdump-glflags.$(OBJEXT) \ dwarfdump-helpertree.$(OBJEXT) dwarfdump-macrocheck.$(OBJEXT) \ dwarfdump-makename.$(OBJEXT) dwarfdump-naming.$(OBJEXT) \ dwarfdump-print_abbrevs.$(OBJEXT) \ dwarfdump-print_aranges.$(OBJEXT) \ dwarfdump-print_debugfission.$(OBJEXT) \ dwarfdump-print_die.$(OBJEXT) dwarfdump-print_dnames.$(OBJEXT) \ dwarfdump-print_frames.$(OBJEXT) \ dwarfdump-print_gdbindex.$(OBJEXT) \ dwarfdump-print_lines.$(OBJEXT) dwarfdump-print_locs.$(OBJEXT) \ dwarfdump-print_macro.$(OBJEXT) \ dwarfdump-print_macros.$(OBJEXT) \ dwarfdump-print_pubnames.$(OBJEXT) \ dwarfdump-print_ranges.$(OBJEXT) \ dwarfdump-print_reloc.$(OBJEXT) \ dwarfdump-print_section_groups.$(OBJEXT) \ dwarfdump-print_sections.$(OBJEXT) \ dwarfdump-print_static_funcs.$(OBJEXT) \ dwarfdump-print_static_vars.$(OBJEXT) \ dwarfdump-print_str_offsets.$(OBJEXT) \ dwarfdump-print_strings.$(OBJEXT) \ dwarfdump-print_types.$(OBJEXT) \ dwarfdump-print_weaknames.$(OBJEXT) \ dwarfdump-sanitized.$(OBJEXT) \ dwarfdump-section_bitmaps.$(OBJEXT) \ dwarfdump-strstrnocase.$(OBJEXT) \ dwarfdump-true_section_name.$(OBJEXT) dwarfdump-uri.$(OBJEXT) dwarfdump_OBJECTS = $(am_dwarfdump_OBJECTS) dwarfdump_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = dwarfdump_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dwarfdump_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(dwarfdump_SOURCES) DIST_SOURCES = $(dwarfdump_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(dwarfdumpdev_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver COPYING ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in AUTOMAKE_OPTIONS = subdir-objects dwarfdump_SOURCES = \ addrmap.c \ addrmap.h \ checkutil.c \ checkutil.h \ command_options.c \ command_options.h \ common.c \ common.h \ compiler_info.c \ compiler_info.h \ defined_types.h \ dwarfdump.c \ dwarfdump-tt-table.h\ dwarfdump-ta-table.h\ dwarfdump-tt-ext-table.h\ dwarfdump-ta-ext-table.h\ dwarf_names.c \ dwarf_names.h \ dwarf_tsearchbal.c \ dwarf_tsearch.h \ dwconf.c \ dwconf.h \ dwconf_using_functions.h \ dwgetopt.c \ dwgetopt.h \ esb.c \ esb.h \ esb_using_functions.h \ glflags.c \ glflags.h \ globals.h \ helpertree.c \ helpertree.h \ macrocheck.c \ macrocheck.h \ makename.c \ makename.h \ naming.c \ naming.h \ print_abbrevs.c \ print_aranges.c \ print_debugfission.c \ print_die.c \ print_dnames.c \ print_frames.c \ print_frames.h \ print_gdbindex.c \ print_lines.c \ print_locs.c \ print_macro.c \ print_macros.c \ print_pubnames.c \ print_ranges.c \ print_reloc.c \ print_reloc.h \ print_section_groups.c \ print_sections.c \ print_sections.h \ print_static_funcs.c \ print_static_vars.c \ print_str_offsets.c \ print_strings.c \ print_types.c \ print_weaknames.c \ sanitized.c \ sanitized.h \ section_bitmaps.c \ section_bitmaps.h \ strstrnocase.c \ true_section_name.c \ tag_common.h \ uri.c \ uri.h \ warningcontrol.h dwarfdump_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf dwarfdump_CFLAGS = $(DWARF_CFLAGS_WARN) "-DCONFPREFIX=@prefix@/share/dwarfdump" dwarfdump_LDADD = \ $(top_builddir)/libdwarf/libdwarf.la \ @DWARF_LIBS@ TESTS = runtests.sh AM_TESTS_ENVIRONMENT = DWTOPSRCDIR='$(top_srcdir)'; export DWTOPSRCDIR ; DWCOMPILERFLAGS='$(DWARF_CFLAGS_WARN)'; export DWCOMPILERFLAGS ; man_MANS = dwarfdump.1 dwarfdumpdevdir = $(datadir)/dwarfdump dwarfdumpdev_DATA = dwarfdump.conf EXTRA_DIST = \ $(man_MANS) \ COPYING \ DWARFDUMPCOPYRIGHT \ GPL.txt \ ChangeLog \ ChangeLog2006 \ ChangeLog2007 \ ChangeLog2008 \ ChangeLog2009 \ ChangeLog2010 \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CMakeLists.txt \ NEWS \ README \ README.testcases \ CODINGSTYLE \ print_reloc_decls.h \ makename_test.c \ section_bitmaps_test.c \ helpertree_test.c \ print_reloc_test.c \ getopttest.c \ tag_common.c \ testesb.c \ test-mach-o-32.dSYM \ test-mach-o-32.base \ testobjLE32PE.exe \ testuriLE64ELf.obj \ testobjLE32PE.base \ testuriLE64ELf.base \ testobjLE32PE.test.c \ $(dwarfdumpdev_DATA) \ tag_attr.c \ tag_tree.c \ tag_attr.list \ tag_attr_ext.list \ tag_tree.list \ tag_tree_ext.list CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu dwarfdump/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu dwarfdump/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list dwarfdump$(EXEEXT): $(dwarfdump_OBJECTS) $(dwarfdump_DEPENDENCIES) $(EXTRA_dwarfdump_DEPENDENCIES) @rm -f dwarfdump$(EXEEXT) $(AM_V_CCLD)$(dwarfdump_LINK) $(dwarfdump_OBJECTS) $(dwarfdump_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-addrmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-checkutil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-command_options.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-compiler_info.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwarf_names.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwarfdump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-dwgetopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-esb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-glflags.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-helpertree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-macrocheck.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-makename.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-naming.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_abbrevs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_aranges.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_debugfission.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_die.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_dnames.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_frames.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_gdbindex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_lines.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_locs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_macro.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_macros.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_pubnames.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_ranges.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_reloc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_section_groups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_sections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_static_funcs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_static_vars.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_str_offsets.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_strings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_types.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-print_weaknames.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-sanitized.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-section_bitmaps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-strstrnocase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-true_section_name.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfdump-uri.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< dwarfdump-addrmap.o: addrmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-addrmap.o -MD -MP -MF $(DEPDIR)/dwarfdump-addrmap.Tpo -c -o dwarfdump-addrmap.o `test -f 'addrmap.c' || echo '$(srcdir)/'`addrmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-addrmap.Tpo $(DEPDIR)/dwarfdump-addrmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='addrmap.c' object='dwarfdump-addrmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-addrmap.o `test -f 'addrmap.c' || echo '$(srcdir)/'`addrmap.c dwarfdump-addrmap.obj: addrmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-addrmap.obj -MD -MP -MF $(DEPDIR)/dwarfdump-addrmap.Tpo -c -o dwarfdump-addrmap.obj `if test -f 'addrmap.c'; then $(CYGPATH_W) 'addrmap.c'; else $(CYGPATH_W) '$(srcdir)/addrmap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-addrmap.Tpo $(DEPDIR)/dwarfdump-addrmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='addrmap.c' object='dwarfdump-addrmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-addrmap.obj `if test -f 'addrmap.c'; then $(CYGPATH_W) 'addrmap.c'; else $(CYGPATH_W) '$(srcdir)/addrmap.c'; fi` dwarfdump-checkutil.o: checkutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-checkutil.o -MD -MP -MF $(DEPDIR)/dwarfdump-checkutil.Tpo -c -o dwarfdump-checkutil.o `test -f 'checkutil.c' || echo '$(srcdir)/'`checkutil.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-checkutil.Tpo $(DEPDIR)/dwarfdump-checkutil.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='checkutil.c' object='dwarfdump-checkutil.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-checkutil.o `test -f 'checkutil.c' || echo '$(srcdir)/'`checkutil.c dwarfdump-checkutil.obj: checkutil.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-checkutil.obj -MD -MP -MF $(DEPDIR)/dwarfdump-checkutil.Tpo -c -o dwarfdump-checkutil.obj `if test -f 'checkutil.c'; then $(CYGPATH_W) 'checkutil.c'; else $(CYGPATH_W) '$(srcdir)/checkutil.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-checkutil.Tpo $(DEPDIR)/dwarfdump-checkutil.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='checkutil.c' object='dwarfdump-checkutil.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-checkutil.obj `if test -f 'checkutil.c'; then $(CYGPATH_W) 'checkutil.c'; else $(CYGPATH_W) '$(srcdir)/checkutil.c'; fi` dwarfdump-command_options.o: command_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-command_options.o -MD -MP -MF $(DEPDIR)/dwarfdump-command_options.Tpo -c -o dwarfdump-command_options.o `test -f 'command_options.c' || echo '$(srcdir)/'`command_options.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-command_options.Tpo $(DEPDIR)/dwarfdump-command_options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='command_options.c' object='dwarfdump-command_options.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-command_options.o `test -f 'command_options.c' || echo '$(srcdir)/'`command_options.c dwarfdump-command_options.obj: command_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-command_options.obj -MD -MP -MF $(DEPDIR)/dwarfdump-command_options.Tpo -c -o dwarfdump-command_options.obj `if test -f 'command_options.c'; then $(CYGPATH_W) 'command_options.c'; else $(CYGPATH_W) '$(srcdir)/command_options.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-command_options.Tpo $(DEPDIR)/dwarfdump-command_options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='command_options.c' object='dwarfdump-command_options.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-command_options.obj `if test -f 'command_options.c'; then $(CYGPATH_W) 'command_options.c'; else $(CYGPATH_W) '$(srcdir)/command_options.c'; fi` dwarfdump-common.o: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-common.o -MD -MP -MF $(DEPDIR)/dwarfdump-common.Tpo -c -o dwarfdump-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-common.Tpo $(DEPDIR)/dwarfdump-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='dwarfdump-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c dwarfdump-common.obj: common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-common.obj -MD -MP -MF $(DEPDIR)/dwarfdump-common.Tpo -c -o dwarfdump-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-common.Tpo $(DEPDIR)/dwarfdump-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='common.c' object='dwarfdump-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi` dwarfdump-compiler_info.o: compiler_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-compiler_info.o -MD -MP -MF $(DEPDIR)/dwarfdump-compiler_info.Tpo -c -o dwarfdump-compiler_info.o `test -f 'compiler_info.c' || echo '$(srcdir)/'`compiler_info.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-compiler_info.Tpo $(DEPDIR)/dwarfdump-compiler_info.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compiler_info.c' object='dwarfdump-compiler_info.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-compiler_info.o `test -f 'compiler_info.c' || echo '$(srcdir)/'`compiler_info.c dwarfdump-compiler_info.obj: compiler_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-compiler_info.obj -MD -MP -MF $(DEPDIR)/dwarfdump-compiler_info.Tpo -c -o dwarfdump-compiler_info.obj `if test -f 'compiler_info.c'; then $(CYGPATH_W) 'compiler_info.c'; else $(CYGPATH_W) '$(srcdir)/compiler_info.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-compiler_info.Tpo $(DEPDIR)/dwarfdump-compiler_info.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='compiler_info.c' object='dwarfdump-compiler_info.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-compiler_info.obj `if test -f 'compiler_info.c'; then $(CYGPATH_W) 'compiler_info.c'; else $(CYGPATH_W) '$(srcdir)/compiler_info.c'; fi` dwarfdump-dwarfdump.o: dwarfdump.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarfdump.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwarfdump.Tpo -c -o dwarfdump-dwarfdump.o `test -f 'dwarfdump.c' || echo '$(srcdir)/'`dwarfdump.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarfdump.Tpo $(DEPDIR)/dwarfdump-dwarfdump.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfdump.c' object='dwarfdump-dwarfdump.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarfdump.o `test -f 'dwarfdump.c' || echo '$(srcdir)/'`dwarfdump.c dwarfdump-dwarfdump.obj: dwarfdump.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarfdump.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwarfdump.Tpo -c -o dwarfdump-dwarfdump.obj `if test -f 'dwarfdump.c'; then $(CYGPATH_W) 'dwarfdump.c'; else $(CYGPATH_W) '$(srcdir)/dwarfdump.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarfdump.Tpo $(DEPDIR)/dwarfdump-dwarfdump.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfdump.c' object='dwarfdump-dwarfdump.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarfdump.obj `if test -f 'dwarfdump.c'; then $(CYGPATH_W) 'dwarfdump.c'; else $(CYGPATH_W) '$(srcdir)/dwarfdump.c'; fi` dwarfdump-dwarf_names.o: dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_names.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_names.Tpo -c -o dwarfdump-dwarf_names.o `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_names.Tpo $(DEPDIR)/dwarfdump-dwarf_names.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_names.c' object='dwarfdump-dwarf_names.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_names.o `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c dwarfdump-dwarf_names.obj: dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_names.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_names.Tpo -c -o dwarfdump-dwarf_names.obj `if test -f 'dwarf_names.c'; then $(CYGPATH_W) 'dwarf_names.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_names.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_names.Tpo $(DEPDIR)/dwarfdump-dwarf_names.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_names.c' object='dwarfdump-dwarf_names.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_names.obj `if test -f 'dwarf_names.c'; then $(CYGPATH_W) 'dwarf_names.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_names.c'; fi` dwarfdump-dwarf_tsearchbal.o: dwarf_tsearchbal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_tsearchbal.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo -c -o dwarfdump-dwarf_tsearchbal.o `test -f 'dwarf_tsearchbal.c' || echo '$(srcdir)/'`dwarf_tsearchbal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tsearchbal.c' object='dwarfdump-dwarf_tsearchbal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_tsearchbal.o `test -f 'dwarf_tsearchbal.c' || echo '$(srcdir)/'`dwarf_tsearchbal.c dwarfdump-dwarf_tsearchbal.obj: dwarf_tsearchbal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwarf_tsearchbal.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo -c -o dwarfdump-dwarf_tsearchbal.obj `if test -f 'dwarf_tsearchbal.c'; then $(CYGPATH_W) 'dwarf_tsearchbal.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_tsearchbal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Tpo $(DEPDIR)/dwarfdump-dwarf_tsearchbal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tsearchbal.c' object='dwarfdump-dwarf_tsearchbal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwarf_tsearchbal.obj `if test -f 'dwarf_tsearchbal.c'; then $(CYGPATH_W) 'dwarf_tsearchbal.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_tsearchbal.c'; fi` dwarfdump-dwconf.o: dwconf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwconf.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwconf.Tpo -c -o dwarfdump-dwconf.o `test -f 'dwconf.c' || echo '$(srcdir)/'`dwconf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwconf.Tpo $(DEPDIR)/dwarfdump-dwconf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwconf.c' object='dwarfdump-dwconf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwconf.o `test -f 'dwconf.c' || echo '$(srcdir)/'`dwconf.c dwarfdump-dwconf.obj: dwconf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwconf.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwconf.Tpo -c -o dwarfdump-dwconf.obj `if test -f 'dwconf.c'; then $(CYGPATH_W) 'dwconf.c'; else $(CYGPATH_W) '$(srcdir)/dwconf.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwconf.Tpo $(DEPDIR)/dwarfdump-dwconf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwconf.c' object='dwarfdump-dwconf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwconf.obj `if test -f 'dwconf.c'; then $(CYGPATH_W) 'dwconf.c'; else $(CYGPATH_W) '$(srcdir)/dwconf.c'; fi` dwarfdump-dwgetopt.o: dwgetopt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwgetopt.o -MD -MP -MF $(DEPDIR)/dwarfdump-dwgetopt.Tpo -c -o dwarfdump-dwgetopt.o `test -f 'dwgetopt.c' || echo '$(srcdir)/'`dwgetopt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwgetopt.Tpo $(DEPDIR)/dwarfdump-dwgetopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwgetopt.c' object='dwarfdump-dwgetopt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwgetopt.o `test -f 'dwgetopt.c' || echo '$(srcdir)/'`dwgetopt.c dwarfdump-dwgetopt.obj: dwgetopt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-dwgetopt.obj -MD -MP -MF $(DEPDIR)/dwarfdump-dwgetopt.Tpo -c -o dwarfdump-dwgetopt.obj `if test -f 'dwgetopt.c'; then $(CYGPATH_W) 'dwgetopt.c'; else $(CYGPATH_W) '$(srcdir)/dwgetopt.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-dwgetopt.Tpo $(DEPDIR)/dwarfdump-dwgetopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwgetopt.c' object='dwarfdump-dwgetopt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-dwgetopt.obj `if test -f 'dwgetopt.c'; then $(CYGPATH_W) 'dwgetopt.c'; else $(CYGPATH_W) '$(srcdir)/dwgetopt.c'; fi` dwarfdump-esb.o: esb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-esb.o -MD -MP -MF $(DEPDIR)/dwarfdump-esb.Tpo -c -o dwarfdump-esb.o `test -f 'esb.c' || echo '$(srcdir)/'`esb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-esb.Tpo $(DEPDIR)/dwarfdump-esb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='esb.c' object='dwarfdump-esb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-esb.o `test -f 'esb.c' || echo '$(srcdir)/'`esb.c dwarfdump-esb.obj: esb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-esb.obj -MD -MP -MF $(DEPDIR)/dwarfdump-esb.Tpo -c -o dwarfdump-esb.obj `if test -f 'esb.c'; then $(CYGPATH_W) 'esb.c'; else $(CYGPATH_W) '$(srcdir)/esb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-esb.Tpo $(DEPDIR)/dwarfdump-esb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='esb.c' object='dwarfdump-esb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-esb.obj `if test -f 'esb.c'; then $(CYGPATH_W) 'esb.c'; else $(CYGPATH_W) '$(srcdir)/esb.c'; fi` dwarfdump-glflags.o: glflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-glflags.o -MD -MP -MF $(DEPDIR)/dwarfdump-glflags.Tpo -c -o dwarfdump-glflags.o `test -f 'glflags.c' || echo '$(srcdir)/'`glflags.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-glflags.Tpo $(DEPDIR)/dwarfdump-glflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glflags.c' object='dwarfdump-glflags.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-glflags.o `test -f 'glflags.c' || echo '$(srcdir)/'`glflags.c dwarfdump-glflags.obj: glflags.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-glflags.obj -MD -MP -MF $(DEPDIR)/dwarfdump-glflags.Tpo -c -o dwarfdump-glflags.obj `if test -f 'glflags.c'; then $(CYGPATH_W) 'glflags.c'; else $(CYGPATH_W) '$(srcdir)/glflags.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-glflags.Tpo $(DEPDIR)/dwarfdump-glflags.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='glflags.c' object='dwarfdump-glflags.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-glflags.obj `if test -f 'glflags.c'; then $(CYGPATH_W) 'glflags.c'; else $(CYGPATH_W) '$(srcdir)/glflags.c'; fi` dwarfdump-helpertree.o: helpertree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-helpertree.o -MD -MP -MF $(DEPDIR)/dwarfdump-helpertree.Tpo -c -o dwarfdump-helpertree.o `test -f 'helpertree.c' || echo '$(srcdir)/'`helpertree.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-helpertree.Tpo $(DEPDIR)/dwarfdump-helpertree.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpertree.c' object='dwarfdump-helpertree.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-helpertree.o `test -f 'helpertree.c' || echo '$(srcdir)/'`helpertree.c dwarfdump-helpertree.obj: helpertree.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-helpertree.obj -MD -MP -MF $(DEPDIR)/dwarfdump-helpertree.Tpo -c -o dwarfdump-helpertree.obj `if test -f 'helpertree.c'; then $(CYGPATH_W) 'helpertree.c'; else $(CYGPATH_W) '$(srcdir)/helpertree.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-helpertree.Tpo $(DEPDIR)/dwarfdump-helpertree.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpertree.c' object='dwarfdump-helpertree.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-helpertree.obj `if test -f 'helpertree.c'; then $(CYGPATH_W) 'helpertree.c'; else $(CYGPATH_W) '$(srcdir)/helpertree.c'; fi` dwarfdump-macrocheck.o: macrocheck.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-macrocheck.o -MD -MP -MF $(DEPDIR)/dwarfdump-macrocheck.Tpo -c -o dwarfdump-macrocheck.o `test -f 'macrocheck.c' || echo '$(srcdir)/'`macrocheck.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-macrocheck.Tpo $(DEPDIR)/dwarfdump-macrocheck.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='macrocheck.c' object='dwarfdump-macrocheck.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-macrocheck.o `test -f 'macrocheck.c' || echo '$(srcdir)/'`macrocheck.c dwarfdump-macrocheck.obj: macrocheck.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-macrocheck.obj -MD -MP -MF $(DEPDIR)/dwarfdump-macrocheck.Tpo -c -o dwarfdump-macrocheck.obj `if test -f 'macrocheck.c'; then $(CYGPATH_W) 'macrocheck.c'; else $(CYGPATH_W) '$(srcdir)/macrocheck.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-macrocheck.Tpo $(DEPDIR)/dwarfdump-macrocheck.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='macrocheck.c' object='dwarfdump-macrocheck.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-macrocheck.obj `if test -f 'macrocheck.c'; then $(CYGPATH_W) 'macrocheck.c'; else $(CYGPATH_W) '$(srcdir)/macrocheck.c'; fi` dwarfdump-makename.o: makename.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-makename.o -MD -MP -MF $(DEPDIR)/dwarfdump-makename.Tpo -c -o dwarfdump-makename.o `test -f 'makename.c' || echo '$(srcdir)/'`makename.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-makename.Tpo $(DEPDIR)/dwarfdump-makename.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='makename.c' object='dwarfdump-makename.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-makename.o `test -f 'makename.c' || echo '$(srcdir)/'`makename.c dwarfdump-makename.obj: makename.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-makename.obj -MD -MP -MF $(DEPDIR)/dwarfdump-makename.Tpo -c -o dwarfdump-makename.obj `if test -f 'makename.c'; then $(CYGPATH_W) 'makename.c'; else $(CYGPATH_W) '$(srcdir)/makename.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-makename.Tpo $(DEPDIR)/dwarfdump-makename.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='makename.c' object='dwarfdump-makename.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-makename.obj `if test -f 'makename.c'; then $(CYGPATH_W) 'makename.c'; else $(CYGPATH_W) '$(srcdir)/makename.c'; fi` dwarfdump-naming.o: naming.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-naming.o -MD -MP -MF $(DEPDIR)/dwarfdump-naming.Tpo -c -o dwarfdump-naming.o `test -f 'naming.c' || echo '$(srcdir)/'`naming.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-naming.Tpo $(DEPDIR)/dwarfdump-naming.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='naming.c' object='dwarfdump-naming.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-naming.o `test -f 'naming.c' || echo '$(srcdir)/'`naming.c dwarfdump-naming.obj: naming.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-naming.obj -MD -MP -MF $(DEPDIR)/dwarfdump-naming.Tpo -c -o dwarfdump-naming.obj `if test -f 'naming.c'; then $(CYGPATH_W) 'naming.c'; else $(CYGPATH_W) '$(srcdir)/naming.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-naming.Tpo $(DEPDIR)/dwarfdump-naming.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='naming.c' object='dwarfdump-naming.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-naming.obj `if test -f 'naming.c'; then $(CYGPATH_W) 'naming.c'; else $(CYGPATH_W) '$(srcdir)/naming.c'; fi` dwarfdump-print_abbrevs.o: print_abbrevs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_abbrevs.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_abbrevs.Tpo -c -o dwarfdump-print_abbrevs.o `test -f 'print_abbrevs.c' || echo '$(srcdir)/'`print_abbrevs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_abbrevs.Tpo $(DEPDIR)/dwarfdump-print_abbrevs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_abbrevs.c' object='dwarfdump-print_abbrevs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_abbrevs.o `test -f 'print_abbrevs.c' || echo '$(srcdir)/'`print_abbrevs.c dwarfdump-print_abbrevs.obj: print_abbrevs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_abbrevs.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_abbrevs.Tpo -c -o dwarfdump-print_abbrevs.obj `if test -f 'print_abbrevs.c'; then $(CYGPATH_W) 'print_abbrevs.c'; else $(CYGPATH_W) '$(srcdir)/print_abbrevs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_abbrevs.Tpo $(DEPDIR)/dwarfdump-print_abbrevs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_abbrevs.c' object='dwarfdump-print_abbrevs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_abbrevs.obj `if test -f 'print_abbrevs.c'; then $(CYGPATH_W) 'print_abbrevs.c'; else $(CYGPATH_W) '$(srcdir)/print_abbrevs.c'; fi` dwarfdump-print_aranges.o: print_aranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_aranges.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_aranges.Tpo -c -o dwarfdump-print_aranges.o `test -f 'print_aranges.c' || echo '$(srcdir)/'`print_aranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_aranges.Tpo $(DEPDIR)/dwarfdump-print_aranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_aranges.c' object='dwarfdump-print_aranges.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_aranges.o `test -f 'print_aranges.c' || echo '$(srcdir)/'`print_aranges.c dwarfdump-print_aranges.obj: print_aranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_aranges.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_aranges.Tpo -c -o dwarfdump-print_aranges.obj `if test -f 'print_aranges.c'; then $(CYGPATH_W) 'print_aranges.c'; else $(CYGPATH_W) '$(srcdir)/print_aranges.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_aranges.Tpo $(DEPDIR)/dwarfdump-print_aranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_aranges.c' object='dwarfdump-print_aranges.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_aranges.obj `if test -f 'print_aranges.c'; then $(CYGPATH_W) 'print_aranges.c'; else $(CYGPATH_W) '$(srcdir)/print_aranges.c'; fi` dwarfdump-print_debugfission.o: print_debugfission.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debugfission.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_debugfission.Tpo -c -o dwarfdump-print_debugfission.o `test -f 'print_debugfission.c' || echo '$(srcdir)/'`print_debugfission.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debugfission.Tpo $(DEPDIR)/dwarfdump-print_debugfission.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debugfission.c' object='dwarfdump-print_debugfission.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debugfission.o `test -f 'print_debugfission.c' || echo '$(srcdir)/'`print_debugfission.c dwarfdump-print_debugfission.obj: print_debugfission.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_debugfission.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_debugfission.Tpo -c -o dwarfdump-print_debugfission.obj `if test -f 'print_debugfission.c'; then $(CYGPATH_W) 'print_debugfission.c'; else $(CYGPATH_W) '$(srcdir)/print_debugfission.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_debugfission.Tpo $(DEPDIR)/dwarfdump-print_debugfission.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_debugfission.c' object='dwarfdump-print_debugfission.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_debugfission.obj `if test -f 'print_debugfission.c'; then $(CYGPATH_W) 'print_debugfission.c'; else $(CYGPATH_W) '$(srcdir)/print_debugfission.c'; fi` dwarfdump-print_die.o: print_die.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_die.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_die.Tpo -c -o dwarfdump-print_die.o `test -f 'print_die.c' || echo '$(srcdir)/'`print_die.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_die.Tpo $(DEPDIR)/dwarfdump-print_die.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_die.c' object='dwarfdump-print_die.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_die.o `test -f 'print_die.c' || echo '$(srcdir)/'`print_die.c dwarfdump-print_die.obj: print_die.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_die.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_die.Tpo -c -o dwarfdump-print_die.obj `if test -f 'print_die.c'; then $(CYGPATH_W) 'print_die.c'; else $(CYGPATH_W) '$(srcdir)/print_die.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_die.Tpo $(DEPDIR)/dwarfdump-print_die.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_die.c' object='dwarfdump-print_die.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_die.obj `if test -f 'print_die.c'; then $(CYGPATH_W) 'print_die.c'; else $(CYGPATH_W) '$(srcdir)/print_die.c'; fi` dwarfdump-print_dnames.o: print_dnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_dnames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_dnames.Tpo -c -o dwarfdump-print_dnames.o `test -f 'print_dnames.c' || echo '$(srcdir)/'`print_dnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_dnames.Tpo $(DEPDIR)/dwarfdump-print_dnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_dnames.c' object='dwarfdump-print_dnames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_dnames.o `test -f 'print_dnames.c' || echo '$(srcdir)/'`print_dnames.c dwarfdump-print_dnames.obj: print_dnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_dnames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_dnames.Tpo -c -o dwarfdump-print_dnames.obj `if test -f 'print_dnames.c'; then $(CYGPATH_W) 'print_dnames.c'; else $(CYGPATH_W) '$(srcdir)/print_dnames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_dnames.Tpo $(DEPDIR)/dwarfdump-print_dnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_dnames.c' object='dwarfdump-print_dnames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_dnames.obj `if test -f 'print_dnames.c'; then $(CYGPATH_W) 'print_dnames.c'; else $(CYGPATH_W) '$(srcdir)/print_dnames.c'; fi` dwarfdump-print_frames.o: print_frames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_frames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_frames.Tpo -c -o dwarfdump-print_frames.o `test -f 'print_frames.c' || echo '$(srcdir)/'`print_frames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_frames.Tpo $(DEPDIR)/dwarfdump-print_frames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_frames.c' object='dwarfdump-print_frames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_frames.o `test -f 'print_frames.c' || echo '$(srcdir)/'`print_frames.c dwarfdump-print_frames.obj: print_frames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_frames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_frames.Tpo -c -o dwarfdump-print_frames.obj `if test -f 'print_frames.c'; then $(CYGPATH_W) 'print_frames.c'; else $(CYGPATH_W) '$(srcdir)/print_frames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_frames.Tpo $(DEPDIR)/dwarfdump-print_frames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_frames.c' object='dwarfdump-print_frames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_frames.obj `if test -f 'print_frames.c'; then $(CYGPATH_W) 'print_frames.c'; else $(CYGPATH_W) '$(srcdir)/print_frames.c'; fi` dwarfdump-print_gdbindex.o: print_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_gdbindex.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_gdbindex.Tpo -c -o dwarfdump-print_gdbindex.o `test -f 'print_gdbindex.c' || echo '$(srcdir)/'`print_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_gdbindex.Tpo $(DEPDIR)/dwarfdump-print_gdbindex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_gdbindex.c' object='dwarfdump-print_gdbindex.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_gdbindex.o `test -f 'print_gdbindex.c' || echo '$(srcdir)/'`print_gdbindex.c dwarfdump-print_gdbindex.obj: print_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_gdbindex.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_gdbindex.Tpo -c -o dwarfdump-print_gdbindex.obj `if test -f 'print_gdbindex.c'; then $(CYGPATH_W) 'print_gdbindex.c'; else $(CYGPATH_W) '$(srcdir)/print_gdbindex.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_gdbindex.Tpo $(DEPDIR)/dwarfdump-print_gdbindex.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_gdbindex.c' object='dwarfdump-print_gdbindex.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_gdbindex.obj `if test -f 'print_gdbindex.c'; then $(CYGPATH_W) 'print_gdbindex.c'; else $(CYGPATH_W) '$(srcdir)/print_gdbindex.c'; fi` dwarfdump-print_lines.o: print_lines.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_lines.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_lines.Tpo -c -o dwarfdump-print_lines.o `test -f 'print_lines.c' || echo '$(srcdir)/'`print_lines.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_lines.Tpo $(DEPDIR)/dwarfdump-print_lines.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_lines.c' object='dwarfdump-print_lines.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_lines.o `test -f 'print_lines.c' || echo '$(srcdir)/'`print_lines.c dwarfdump-print_lines.obj: print_lines.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_lines.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_lines.Tpo -c -o dwarfdump-print_lines.obj `if test -f 'print_lines.c'; then $(CYGPATH_W) 'print_lines.c'; else $(CYGPATH_W) '$(srcdir)/print_lines.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_lines.Tpo $(DEPDIR)/dwarfdump-print_lines.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_lines.c' object='dwarfdump-print_lines.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_lines.obj `if test -f 'print_lines.c'; then $(CYGPATH_W) 'print_lines.c'; else $(CYGPATH_W) '$(srcdir)/print_lines.c'; fi` dwarfdump-print_locs.o: print_locs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_locs.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_locs.Tpo -c -o dwarfdump-print_locs.o `test -f 'print_locs.c' || echo '$(srcdir)/'`print_locs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_locs.Tpo $(DEPDIR)/dwarfdump-print_locs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_locs.c' object='dwarfdump-print_locs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_locs.o `test -f 'print_locs.c' || echo '$(srcdir)/'`print_locs.c dwarfdump-print_locs.obj: print_locs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_locs.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_locs.Tpo -c -o dwarfdump-print_locs.obj `if test -f 'print_locs.c'; then $(CYGPATH_W) 'print_locs.c'; else $(CYGPATH_W) '$(srcdir)/print_locs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_locs.Tpo $(DEPDIR)/dwarfdump-print_locs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_locs.c' object='dwarfdump-print_locs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_locs.obj `if test -f 'print_locs.c'; then $(CYGPATH_W) 'print_locs.c'; else $(CYGPATH_W) '$(srcdir)/print_locs.c'; fi` dwarfdump-print_macro.o: print_macro.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macro.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_macro.Tpo -c -o dwarfdump-print_macro.o `test -f 'print_macro.c' || echo '$(srcdir)/'`print_macro.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macro.Tpo $(DEPDIR)/dwarfdump-print_macro.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macro.c' object='dwarfdump-print_macro.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macro.o `test -f 'print_macro.c' || echo '$(srcdir)/'`print_macro.c dwarfdump-print_macro.obj: print_macro.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macro.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_macro.Tpo -c -o dwarfdump-print_macro.obj `if test -f 'print_macro.c'; then $(CYGPATH_W) 'print_macro.c'; else $(CYGPATH_W) '$(srcdir)/print_macro.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macro.Tpo $(DEPDIR)/dwarfdump-print_macro.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macro.c' object='dwarfdump-print_macro.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macro.obj `if test -f 'print_macro.c'; then $(CYGPATH_W) 'print_macro.c'; else $(CYGPATH_W) '$(srcdir)/print_macro.c'; fi` dwarfdump-print_macros.o: print_macros.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macros.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_macros.Tpo -c -o dwarfdump-print_macros.o `test -f 'print_macros.c' || echo '$(srcdir)/'`print_macros.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macros.Tpo $(DEPDIR)/dwarfdump-print_macros.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macros.c' object='dwarfdump-print_macros.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macros.o `test -f 'print_macros.c' || echo '$(srcdir)/'`print_macros.c dwarfdump-print_macros.obj: print_macros.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_macros.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_macros.Tpo -c -o dwarfdump-print_macros.obj `if test -f 'print_macros.c'; then $(CYGPATH_W) 'print_macros.c'; else $(CYGPATH_W) '$(srcdir)/print_macros.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_macros.Tpo $(DEPDIR)/dwarfdump-print_macros.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_macros.c' object='dwarfdump-print_macros.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_macros.obj `if test -f 'print_macros.c'; then $(CYGPATH_W) 'print_macros.c'; else $(CYGPATH_W) '$(srcdir)/print_macros.c'; fi` dwarfdump-print_pubnames.o: print_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_pubnames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_pubnames.Tpo -c -o dwarfdump-print_pubnames.o `test -f 'print_pubnames.c' || echo '$(srcdir)/'`print_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_pubnames.Tpo $(DEPDIR)/dwarfdump-print_pubnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_pubnames.c' object='dwarfdump-print_pubnames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_pubnames.o `test -f 'print_pubnames.c' || echo '$(srcdir)/'`print_pubnames.c dwarfdump-print_pubnames.obj: print_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_pubnames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_pubnames.Tpo -c -o dwarfdump-print_pubnames.obj `if test -f 'print_pubnames.c'; then $(CYGPATH_W) 'print_pubnames.c'; else $(CYGPATH_W) '$(srcdir)/print_pubnames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_pubnames.Tpo $(DEPDIR)/dwarfdump-print_pubnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_pubnames.c' object='dwarfdump-print_pubnames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_pubnames.obj `if test -f 'print_pubnames.c'; then $(CYGPATH_W) 'print_pubnames.c'; else $(CYGPATH_W) '$(srcdir)/print_pubnames.c'; fi` dwarfdump-print_ranges.o: print_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_ranges.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_ranges.Tpo -c -o dwarfdump-print_ranges.o `test -f 'print_ranges.c' || echo '$(srcdir)/'`print_ranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_ranges.Tpo $(DEPDIR)/dwarfdump-print_ranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_ranges.c' object='dwarfdump-print_ranges.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_ranges.o `test -f 'print_ranges.c' || echo '$(srcdir)/'`print_ranges.c dwarfdump-print_ranges.obj: print_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_ranges.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_ranges.Tpo -c -o dwarfdump-print_ranges.obj `if test -f 'print_ranges.c'; then $(CYGPATH_W) 'print_ranges.c'; else $(CYGPATH_W) '$(srcdir)/print_ranges.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_ranges.Tpo $(DEPDIR)/dwarfdump-print_ranges.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_ranges.c' object='dwarfdump-print_ranges.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_ranges.obj `if test -f 'print_ranges.c'; then $(CYGPATH_W) 'print_ranges.c'; else $(CYGPATH_W) '$(srcdir)/print_ranges.c'; fi` dwarfdump-print_reloc.o: print_reloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_reloc.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_reloc.Tpo -c -o dwarfdump-print_reloc.o `test -f 'print_reloc.c' || echo '$(srcdir)/'`print_reloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_reloc.Tpo $(DEPDIR)/dwarfdump-print_reloc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_reloc.c' object='dwarfdump-print_reloc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_reloc.o `test -f 'print_reloc.c' || echo '$(srcdir)/'`print_reloc.c dwarfdump-print_reloc.obj: print_reloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_reloc.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_reloc.Tpo -c -o dwarfdump-print_reloc.obj `if test -f 'print_reloc.c'; then $(CYGPATH_W) 'print_reloc.c'; else $(CYGPATH_W) '$(srcdir)/print_reloc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_reloc.Tpo $(DEPDIR)/dwarfdump-print_reloc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_reloc.c' object='dwarfdump-print_reloc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_reloc.obj `if test -f 'print_reloc.c'; then $(CYGPATH_W) 'print_reloc.c'; else $(CYGPATH_W) '$(srcdir)/print_reloc.c'; fi` dwarfdump-print_section_groups.o: print_section_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_section_groups.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_section_groups.Tpo -c -o dwarfdump-print_section_groups.o `test -f 'print_section_groups.c' || echo '$(srcdir)/'`print_section_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_section_groups.Tpo $(DEPDIR)/dwarfdump-print_section_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_section_groups.c' object='dwarfdump-print_section_groups.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_section_groups.o `test -f 'print_section_groups.c' || echo '$(srcdir)/'`print_section_groups.c dwarfdump-print_section_groups.obj: print_section_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_section_groups.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_section_groups.Tpo -c -o dwarfdump-print_section_groups.obj `if test -f 'print_section_groups.c'; then $(CYGPATH_W) 'print_section_groups.c'; else $(CYGPATH_W) '$(srcdir)/print_section_groups.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_section_groups.Tpo $(DEPDIR)/dwarfdump-print_section_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_section_groups.c' object='dwarfdump-print_section_groups.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_section_groups.obj `if test -f 'print_section_groups.c'; then $(CYGPATH_W) 'print_section_groups.c'; else $(CYGPATH_W) '$(srcdir)/print_section_groups.c'; fi` dwarfdump-print_sections.o: print_sections.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_sections.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_sections.Tpo -c -o dwarfdump-print_sections.o `test -f 'print_sections.c' || echo '$(srcdir)/'`print_sections.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_sections.Tpo $(DEPDIR)/dwarfdump-print_sections.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_sections.c' object='dwarfdump-print_sections.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_sections.o `test -f 'print_sections.c' || echo '$(srcdir)/'`print_sections.c dwarfdump-print_sections.obj: print_sections.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_sections.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_sections.Tpo -c -o dwarfdump-print_sections.obj `if test -f 'print_sections.c'; then $(CYGPATH_W) 'print_sections.c'; else $(CYGPATH_W) '$(srcdir)/print_sections.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_sections.Tpo $(DEPDIR)/dwarfdump-print_sections.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_sections.c' object='dwarfdump-print_sections.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_sections.obj `if test -f 'print_sections.c'; then $(CYGPATH_W) 'print_sections.c'; else $(CYGPATH_W) '$(srcdir)/print_sections.c'; fi` dwarfdump-print_static_funcs.o: print_static_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_funcs.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_funcs.Tpo -c -o dwarfdump-print_static_funcs.o `test -f 'print_static_funcs.c' || echo '$(srcdir)/'`print_static_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_funcs.Tpo $(DEPDIR)/dwarfdump-print_static_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_funcs.c' object='dwarfdump-print_static_funcs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_funcs.o `test -f 'print_static_funcs.c' || echo '$(srcdir)/'`print_static_funcs.c dwarfdump-print_static_funcs.obj: print_static_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_funcs.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_funcs.Tpo -c -o dwarfdump-print_static_funcs.obj `if test -f 'print_static_funcs.c'; then $(CYGPATH_W) 'print_static_funcs.c'; else $(CYGPATH_W) '$(srcdir)/print_static_funcs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_funcs.Tpo $(DEPDIR)/dwarfdump-print_static_funcs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_funcs.c' object='dwarfdump-print_static_funcs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_funcs.obj `if test -f 'print_static_funcs.c'; then $(CYGPATH_W) 'print_static_funcs.c'; else $(CYGPATH_W) '$(srcdir)/print_static_funcs.c'; fi` dwarfdump-print_static_vars.o: print_static_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_vars.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_vars.Tpo -c -o dwarfdump-print_static_vars.o `test -f 'print_static_vars.c' || echo '$(srcdir)/'`print_static_vars.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_vars.Tpo $(DEPDIR)/dwarfdump-print_static_vars.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_vars.c' object='dwarfdump-print_static_vars.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_vars.o `test -f 'print_static_vars.c' || echo '$(srcdir)/'`print_static_vars.c dwarfdump-print_static_vars.obj: print_static_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_static_vars.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_static_vars.Tpo -c -o dwarfdump-print_static_vars.obj `if test -f 'print_static_vars.c'; then $(CYGPATH_W) 'print_static_vars.c'; else $(CYGPATH_W) '$(srcdir)/print_static_vars.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_static_vars.Tpo $(DEPDIR)/dwarfdump-print_static_vars.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_static_vars.c' object='dwarfdump-print_static_vars.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_static_vars.obj `if test -f 'print_static_vars.c'; then $(CYGPATH_W) 'print_static_vars.c'; else $(CYGPATH_W) '$(srcdir)/print_static_vars.c'; fi` dwarfdump-print_str_offsets.o: print_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_str_offsets.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_str_offsets.Tpo -c -o dwarfdump-print_str_offsets.o `test -f 'print_str_offsets.c' || echo '$(srcdir)/'`print_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_str_offsets.Tpo $(DEPDIR)/dwarfdump-print_str_offsets.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_str_offsets.c' object='dwarfdump-print_str_offsets.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_str_offsets.o `test -f 'print_str_offsets.c' || echo '$(srcdir)/'`print_str_offsets.c dwarfdump-print_str_offsets.obj: print_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_str_offsets.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_str_offsets.Tpo -c -o dwarfdump-print_str_offsets.obj `if test -f 'print_str_offsets.c'; then $(CYGPATH_W) 'print_str_offsets.c'; else $(CYGPATH_W) '$(srcdir)/print_str_offsets.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_str_offsets.Tpo $(DEPDIR)/dwarfdump-print_str_offsets.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_str_offsets.c' object='dwarfdump-print_str_offsets.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_str_offsets.obj `if test -f 'print_str_offsets.c'; then $(CYGPATH_W) 'print_str_offsets.c'; else $(CYGPATH_W) '$(srcdir)/print_str_offsets.c'; fi` dwarfdump-print_strings.o: print_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_strings.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_strings.Tpo -c -o dwarfdump-print_strings.o `test -f 'print_strings.c' || echo '$(srcdir)/'`print_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_strings.Tpo $(DEPDIR)/dwarfdump-print_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_strings.c' object='dwarfdump-print_strings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_strings.o `test -f 'print_strings.c' || echo '$(srcdir)/'`print_strings.c dwarfdump-print_strings.obj: print_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_strings.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_strings.Tpo -c -o dwarfdump-print_strings.obj `if test -f 'print_strings.c'; then $(CYGPATH_W) 'print_strings.c'; else $(CYGPATH_W) '$(srcdir)/print_strings.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_strings.Tpo $(DEPDIR)/dwarfdump-print_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_strings.c' object='dwarfdump-print_strings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_strings.obj `if test -f 'print_strings.c'; then $(CYGPATH_W) 'print_strings.c'; else $(CYGPATH_W) '$(srcdir)/print_strings.c'; fi` dwarfdump-print_types.o: print_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_types.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_types.Tpo -c -o dwarfdump-print_types.o `test -f 'print_types.c' || echo '$(srcdir)/'`print_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_types.Tpo $(DEPDIR)/dwarfdump-print_types.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_types.c' object='dwarfdump-print_types.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_types.o `test -f 'print_types.c' || echo '$(srcdir)/'`print_types.c dwarfdump-print_types.obj: print_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_types.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_types.Tpo -c -o dwarfdump-print_types.obj `if test -f 'print_types.c'; then $(CYGPATH_W) 'print_types.c'; else $(CYGPATH_W) '$(srcdir)/print_types.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_types.Tpo $(DEPDIR)/dwarfdump-print_types.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_types.c' object='dwarfdump-print_types.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_types.obj `if test -f 'print_types.c'; then $(CYGPATH_W) 'print_types.c'; else $(CYGPATH_W) '$(srcdir)/print_types.c'; fi` dwarfdump-print_weaknames.o: print_weaknames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_weaknames.o -MD -MP -MF $(DEPDIR)/dwarfdump-print_weaknames.Tpo -c -o dwarfdump-print_weaknames.o `test -f 'print_weaknames.c' || echo '$(srcdir)/'`print_weaknames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_weaknames.Tpo $(DEPDIR)/dwarfdump-print_weaknames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_weaknames.c' object='dwarfdump-print_weaknames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_weaknames.o `test -f 'print_weaknames.c' || echo '$(srcdir)/'`print_weaknames.c dwarfdump-print_weaknames.obj: print_weaknames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-print_weaknames.obj -MD -MP -MF $(DEPDIR)/dwarfdump-print_weaknames.Tpo -c -o dwarfdump-print_weaknames.obj `if test -f 'print_weaknames.c'; then $(CYGPATH_W) 'print_weaknames.c'; else $(CYGPATH_W) '$(srcdir)/print_weaknames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-print_weaknames.Tpo $(DEPDIR)/dwarfdump-print_weaknames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print_weaknames.c' object='dwarfdump-print_weaknames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-print_weaknames.obj `if test -f 'print_weaknames.c'; then $(CYGPATH_W) 'print_weaknames.c'; else $(CYGPATH_W) '$(srcdir)/print_weaknames.c'; fi` dwarfdump-sanitized.o: sanitized.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-sanitized.o -MD -MP -MF $(DEPDIR)/dwarfdump-sanitized.Tpo -c -o dwarfdump-sanitized.o `test -f 'sanitized.c' || echo '$(srcdir)/'`sanitized.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-sanitized.Tpo $(DEPDIR)/dwarfdump-sanitized.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sanitized.c' object='dwarfdump-sanitized.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-sanitized.o `test -f 'sanitized.c' || echo '$(srcdir)/'`sanitized.c dwarfdump-sanitized.obj: sanitized.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-sanitized.obj -MD -MP -MF $(DEPDIR)/dwarfdump-sanitized.Tpo -c -o dwarfdump-sanitized.obj `if test -f 'sanitized.c'; then $(CYGPATH_W) 'sanitized.c'; else $(CYGPATH_W) '$(srcdir)/sanitized.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-sanitized.Tpo $(DEPDIR)/dwarfdump-sanitized.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sanitized.c' object='dwarfdump-sanitized.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-sanitized.obj `if test -f 'sanitized.c'; then $(CYGPATH_W) 'sanitized.c'; else $(CYGPATH_W) '$(srcdir)/sanitized.c'; fi` dwarfdump-section_bitmaps.o: section_bitmaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-section_bitmaps.o -MD -MP -MF $(DEPDIR)/dwarfdump-section_bitmaps.Tpo -c -o dwarfdump-section_bitmaps.o `test -f 'section_bitmaps.c' || echo '$(srcdir)/'`section_bitmaps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-section_bitmaps.Tpo $(DEPDIR)/dwarfdump-section_bitmaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='section_bitmaps.c' object='dwarfdump-section_bitmaps.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-section_bitmaps.o `test -f 'section_bitmaps.c' || echo '$(srcdir)/'`section_bitmaps.c dwarfdump-section_bitmaps.obj: section_bitmaps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-section_bitmaps.obj -MD -MP -MF $(DEPDIR)/dwarfdump-section_bitmaps.Tpo -c -o dwarfdump-section_bitmaps.obj `if test -f 'section_bitmaps.c'; then $(CYGPATH_W) 'section_bitmaps.c'; else $(CYGPATH_W) '$(srcdir)/section_bitmaps.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-section_bitmaps.Tpo $(DEPDIR)/dwarfdump-section_bitmaps.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='section_bitmaps.c' object='dwarfdump-section_bitmaps.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-section_bitmaps.obj `if test -f 'section_bitmaps.c'; then $(CYGPATH_W) 'section_bitmaps.c'; else $(CYGPATH_W) '$(srcdir)/section_bitmaps.c'; fi` dwarfdump-strstrnocase.o: strstrnocase.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-strstrnocase.o -MD -MP -MF $(DEPDIR)/dwarfdump-strstrnocase.Tpo -c -o dwarfdump-strstrnocase.o `test -f 'strstrnocase.c' || echo '$(srcdir)/'`strstrnocase.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-strstrnocase.Tpo $(DEPDIR)/dwarfdump-strstrnocase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strstrnocase.c' object='dwarfdump-strstrnocase.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-strstrnocase.o `test -f 'strstrnocase.c' || echo '$(srcdir)/'`strstrnocase.c dwarfdump-strstrnocase.obj: strstrnocase.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-strstrnocase.obj -MD -MP -MF $(DEPDIR)/dwarfdump-strstrnocase.Tpo -c -o dwarfdump-strstrnocase.obj `if test -f 'strstrnocase.c'; then $(CYGPATH_W) 'strstrnocase.c'; else $(CYGPATH_W) '$(srcdir)/strstrnocase.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-strstrnocase.Tpo $(DEPDIR)/dwarfdump-strstrnocase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='strstrnocase.c' object='dwarfdump-strstrnocase.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-strstrnocase.obj `if test -f 'strstrnocase.c'; then $(CYGPATH_W) 'strstrnocase.c'; else $(CYGPATH_W) '$(srcdir)/strstrnocase.c'; fi` dwarfdump-true_section_name.o: true_section_name.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-true_section_name.o -MD -MP -MF $(DEPDIR)/dwarfdump-true_section_name.Tpo -c -o dwarfdump-true_section_name.o `test -f 'true_section_name.c' || echo '$(srcdir)/'`true_section_name.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-true_section_name.Tpo $(DEPDIR)/dwarfdump-true_section_name.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='true_section_name.c' object='dwarfdump-true_section_name.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-true_section_name.o `test -f 'true_section_name.c' || echo '$(srcdir)/'`true_section_name.c dwarfdump-true_section_name.obj: true_section_name.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-true_section_name.obj -MD -MP -MF $(DEPDIR)/dwarfdump-true_section_name.Tpo -c -o dwarfdump-true_section_name.obj `if test -f 'true_section_name.c'; then $(CYGPATH_W) 'true_section_name.c'; else $(CYGPATH_W) '$(srcdir)/true_section_name.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-true_section_name.Tpo $(DEPDIR)/dwarfdump-true_section_name.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='true_section_name.c' object='dwarfdump-true_section_name.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-true_section_name.obj `if test -f 'true_section_name.c'; then $(CYGPATH_W) 'true_section_name.c'; else $(CYGPATH_W) '$(srcdir)/true_section_name.c'; fi` dwarfdump-uri.o: uri.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-uri.o -MD -MP -MF $(DEPDIR)/dwarfdump-uri.Tpo -c -o dwarfdump-uri.o `test -f 'uri.c' || echo '$(srcdir)/'`uri.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-uri.Tpo $(DEPDIR)/dwarfdump-uri.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uri.c' object='dwarfdump-uri.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-uri.o `test -f 'uri.c' || echo '$(srcdir)/'`uri.c dwarfdump-uri.obj: uri.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -MT dwarfdump-uri.obj -MD -MP -MF $(DEPDIR)/dwarfdump-uri.Tpo -c -o dwarfdump-uri.obj `if test -f 'uri.c'; then $(CYGPATH_W) 'uri.c'; else $(CYGPATH_W) '$(srcdir)/uri.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfdump-uri.Tpo $(DEPDIR)/dwarfdump-uri.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='uri.c' object='dwarfdump-uri.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfdump_CPPFLAGS) $(CPPFLAGS) $(dwarfdump_CFLAGS) $(CFLAGS) -c -o dwarfdump-uri.obj `if test -f 'uri.c'; then $(CYGPATH_W) 'uri.c'; else $(CYGPATH_W) '$(srcdir)/uri.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-dwarfdumpdevDATA: $(dwarfdumpdev_DATA) @$(NORMAL_INSTALL) @list='$(dwarfdumpdev_DATA)'; test -n "$(dwarfdumpdevdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(dwarfdumpdevdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dwarfdumpdevdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dwarfdumpdevdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dwarfdumpdevdir)" || exit $$?; \ done uninstall-dwarfdumpdevDATA: @$(NORMAL_UNINSTALL) @list='$(dwarfdumpdev_DATA)'; test -n "$(dwarfdumpdevdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(dwarfdumpdevdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? runtests.sh.log: runtests.sh @p='runtests.sh'; \ b='runtests.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(dwarfdumpdevdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dwarfdumpdevDATA install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-dwarfdumpdevDATA \ uninstall-man uninstall-man: uninstall-man1 .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-dwarfdumpdevDATA install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-dwarfdumpdevDATA uninstall-man uninstall-man1 .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dwarfutils-20200114/dwarfdump/NEWS000066400000000000000000000272611361531463500166400ustar00rootroot00000000000000December 24, 2018 Any - or -- option on the dwarfdump command line turns off the default set of things to print. So, for example, instead of 'dwarfdump -v a.out' or 'dwarfdump -x abi=mips a.out' (which do nothing) do 'dwarfdump -v -a a.out' or 'dwarfdump -f -x abi=mips a.out'. Or maybe 'dwarfdump a.out' suffices for you. Or use other print or check options depending on your needs. June 14, 2018 A small simplification of build options simplifies building across different environments. If your environment needs to use the non-standard elf_open() call instead of plain open() then at configure time do --enable-elf-open. May 17, 2017 Now dwarfdump understands both split-dwarf and COMDAT sections (it calls the section-groups 'Groups') so it is possible to properly print all such. A traditional DWARF2,3,4,5 consumer can ignore section groups. To print in more complicate situations the -x groupnumber=3 (3 as an example) lets you choose a specific group/comdat to print. Dwarfdump prints out a section-groupnumber table when appropriate a making it easy to know what groups are present. March 24, 2017 dwarfdump: Now argv[0] is checked before setting the program_name global variable. If it contains '/dwarfdump.O' that part of the string is shortened to '/dwarfdump'. Doing this removes a need for the regressiontests to use sed and shortens the regressiontests runtime on one machine from 77 minutes to 23 minutes. September 20, 2016 dwarfdump now frees all memory it used when it terminates normally. No malloc space left behind. It gets a clean report from valgrind --leak-check=full --show-leak-kinds=all May 5, 2016 By default dwarfdump sanitizes strings, so if a corrupted DWARF file has non-printable bytes in a string they are each turned into %xx (% followed by two hex digits for a single string character). This is safe for terminals to print and shows the actual value. The '-x nosanitizestrings' option turns off this feature so bytes are shown as printf and your system show them. The same format as uri style, but only using % on characters that may have bad effects if printed to a terminal (not, for example, space or tab characters). Nor are normal '%' in a string altered (in uri such would be turned to %25 or to %%). February 25, 2015 Copied dwgetopt.c dwgetopt.h from libdwarf so dwarfdump can use dwgetopt() and still build without necessarily having the libdwarfsource easily available. Some environments do not have a getopt() so copying dwgetopt.h,.h here ensures we have this functionality for everyone. January 08, 2015 dwarfdump does new checking. See options -kD -kG -ku -kuf. In addition, dwarfdump output can be written to a file without using redirection by using the new -O file= option. January 29, 2014 Now using dwarf_tsearch() so tsearch is available on every platform. November 17, 2012 Added new checking options. To get good relocation-handling dwarfdump now expects to read headers from libdwarf with the relocation numbers. That means building dwarfdump separate from the libdwarf source is no longer as useful as it was. It is best to build libdwarf and dwarfdump together for decent handling of relocatable objects. December 13, 2011 Now prints missing line table column number as 0 (now matching the DWARF spec), the previous practice of printing -1 was always wrong. And prints the DWARF3/4 new line table fields (when present). October 29, 2011 Added support for printing .debug_types (type unit) data. October 26, 2011 Added new features to Makefile.in and documented in README how to build dwarfdump with headers or libraries in non-standard places. October 23, 2011 By default the various places with string option values and file paths all use URI transformation on input and if the transformation does anything at all dwarfdump reports the input and transformed strings. This makes it easy to deal with strings and expressions and file paths that are difficult to express in a shell (or that getopt mangles). Options -q and -U give you control over this process. October 07, 2011 The -x abi=mips frame register abi in dwarfdump.conf is now usable with modern MIPS objects as well as old IRIX objects. There are other mips-* frame register setups described in dwarfdump.conf for anyone testing that nothing new has been added that conflicts with old IRIX/MIPS frame generation. June 04, 2011 Error checking is now distinct from section printing, making error checking (the -k options) much easier to work with on large objects. So compiler-created errors can be found, the error reporting now prints context information. March 29, 2011 Added many new correctness tests. Changed the format of various items (line data prints in a more compact form, numbers are more uniformly hexadecimal fixed length where that makes sense). All the source files are uniformly indented to a multiple of 4 characters and all intent-tabs in the source have been removed. Major logic changes involved changing error-reporting to be more detailed and adding new tests for incorrect DWARF. Now reports error summary by the compiler name, not just overall. January 26, 2010 Changed the default frame-data register names from MIPS to a generic set of registers. Try '-x abi=mips' to get the traditional old MIPS register naming. June 22, 2009 Added the -S option to dwarfdump. June 10, 2009 Moved the gennames.c code to libdwarf. May 4, 2009 Replaced awk source-generation of certain functions with new gennames.c code. Now we can print an object with an address_size that varies by compilation unit. April 4, 2009 Corrected aspects of the frame-printing by ensuring we pass all the information libdwarf needs for fully consistent behavior. Three newly defined libdwarf calls calls made to ensure that better behavior (specifically having dwarfdump consistently recognize when registers are the cfa, undefined-value or same-value pseudo registers). Updated dwarfdump.conf to set these same things consistently. Mar 22, 2009 The -f and -F flags no longer also imply -i (it just did not make sense to tie them (cannot recall why it might have been tied before). Mar 20, 2009 Moved print_* functions from print_sections.c to individual source files. Hopefully making the code a bit easier to read. Feb 16, 2009 Added the -C option. It is a sort of 'pedantic' option as it turns on warnings about certain commonly used non-standard tag->tag and tag->attr relationships. Added the tag_attr_ext.list tag_tree_ext.list files which define the 'common use' extensions. Feb 14, 2009 Added configure option --enable-nonstandardprintf which makes it easy to get printf of Dwarf_Unsigned (etc) types correct even for non-standard compilers. December 30, 2008 Now we print the .debug_ranges section (with -N) and the data for DW_AT_ranges (with -i). December 8, 2008 The -M option now causes printing of FORM details. And -v adds details about abbreviation 'indexes' into an abbreviation table (.debug_abbrev) providing more detail for folks debugging or improving their understanding of DWARF data. April 9, 2008 Added -H to limit the number of compilation-units/FDEs dwarfdump prints in one run. Added -n to eliminate function-name printing in .debug_frame output (with a large-enough debug_info section function-name printing is too slow). The function name printing will be fixed in another release. December 8, 2007 Had to add an ugly configure conditional as libelf has unconditional use of off64_t in recent libelf.h July 3, 2007 Now with -v dwarf expression blocks in frame operations are printed expanded out. July 2, 2007 Added a new abi -x abi=general usable for any cpu with up to 1000 registers. May 7, 2007 Sun Microsystems contributes new dwarf.h extensions and a new -G option to dwarfdump -i (so one can see the 'global' offset to DIEs). Thanks to Chris Quenelle of Sun. April 17, 2006 New -x name= -x abi= and configuration file enable sensible printing of a wide range of .debug_frame eh_frame correctly without recompiling dwarfdump or touching libdwarf.h or dwarf.h. March 29, 2005 Now handles DWARF3. For non-MIPS objects, the list of register names in print_sections.c is not appropriate, #define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES to turn off the MIPS names. December 1, 2005 Added new DWARF3 TAGs and ATtributes to the -k lists, clarified the -k reporting, and made the build more robust in the face of errors in the *.list relationship-spec-files. August 1, 2005 Now print_die.c deals with long loclists without a coredump. Added esb.h esb.c (and testesb.c for testing) to encapsulate getting space for possibly-long strings. Now print_die.c uses snprintf() not sprintf (hopefully this will not inconvenience anyone, snprintf() has been available on most systems for years now). Altered print of location lists a little bit - for better appearance. July 15, 2005 Now completely frees all allocated memory. Various routines were not calling dealloc() code and new libdwarf dealloc routines are now used where those are needed. Now prints DWARF3 .debug_pubtypes section (with -a or -y). The .debug_pubtypes section and SGI-specific .debug_typenames are equivalent so they are treated alike. Mar 21, 2005 The -f flag now prints only .debug_frame data. The .eh_frame section (GNU exceptions data) now prints with -F (not -a). Printing gcc 3.3 or 3.4 .eh_frame with zR augmentation does not work at this time, so do not use -F to print such an object. The line section print now prints a CU-DIE offset for each such DIEs line information. This makes it much easier to correctly associate -l (or -v -l) output with -v -v -l when debugging a faulty linetable in an executable. With -v -v -l (two -v) the output of line info continues to be a completely different format than zero or one -v, the two-v form showing the detailed line table opcodes. With g++ 3.3.3 one sees bad line addresses at times as the DW_LNE_set_address address for header files do not always get their relocations applied. I am told this is fixed in 3.4.x. Mar 18, 2005 In correcting printing of macro information the format of the macro (-m) output has changed substantially. Much more complete now. Still could use enhancement. Oct 28, 2004 Updated contact address in copyright: SGI moved 1/4 mile to a new address: 1500 Crittenden Lane. Oct 02, 2003 Now fully supports .debug_loc section. June 14, 2001 Now calling a new function dwarf_get_arange_cu_header_offset() in libdwarf and printing the returned cu header offset for aranges entries. Making it easier to track down internal errors in the dwarf2 data. Also added small other consistency checks, printing a message and exit()ing on error. April 14, 2000 The libdwarf copyright has changed to version 2.1 of the GNU Lesser General Public License. Anyone holding a version of libdwarf that was published before this new copyright is allowed to use the copyright published in that earlier libdwarf source on the earlier source or to use this new copyright on the earlier source, at their option. July 21, 1999 Added gnu extensions to the frame information printer and handling for egcs eh_frame printing. libdwarf changes mean this now can print little-endian object dwarf on a big-endian system and vice-versa. December, 1998 added dwarfdump to the dwarf public source distribution. June, 1994 libdwarf consumer interface changed completely so updated to match. May, 1993 Initial version of dwarfdump for dwarf version 2 written at sgi. dwarfutils-20200114/dwarfdump/README000066400000000000000000000061431361531463500170150ustar00rootroot00000000000000I would prefer you try using ../dwarfdump2, not this source. If you must use this for some reason, could you let me know why? Thanks. To build dwarfdump, first build libdwarf in the neighboring directory then type ./configure make Installation is a bit primitive. sudo make install may or may not work. Some or all of the following might be required on Unix or Linux or MacOS: sudo mkdir -p /usr/local/share/man/man1/ sudo mkdir -p /usr/local/lib sudo mkdir -p /usr/local/bin Then retry the 'sudo make install' and (if necessary) try sudo chmod a+x /usr/local/bin/dwarfdump sudo chmod a+r /usr/local/share/man/man1/dwarfdump.1 sudo chmod a+r /usr/local/lib/dwarfdump.conf You don't really need the dwarfdump.1 man page, but you might as well have it. If the man page is not visible with 'man dwarfdump' try 'man manpath' for hints. If you don't need others using dwarfdump on your computer, just cp dwarfdump $HOME/bin/dwarfdump (by convention many people put personal executables in $HOME/bin and fix up $PATH to refer there) which suffices as 'installation'. Also cp dwarfdump.conf $HOME To use dwarf or libdwarf, you may want to install dwarf.h and libdwarf.h somewhere convenient. You can just copy those two headers to /usr/local/include by hand (or anywhere, really, that you have permission to copy to) (you may need to use -I/usr/local/include on compile lines to reference them there, but see below on configure and make). Notice that dwarf_names.c and dwarf_names.h are supplied by the release though the Makefile can and may rebuild them. Some users find it difficult to get a reliable awk(1) program, so for them these prebuilt versions may be useful. If your headers or libelf/libdwarf are not in the expected places, use the make command line to add flags and include directories. For example ./configure PREINCS="-I /usr/local/include" POSTINCS="-I /home/x/include" make PREINCS content is inserted before CFLAGS as make(1) is running. POSTINCS content is added after the CFLAGS value. To set LDFLAGS, do so at configure time, for example: ./configure LDFLAGS="-L /some/dir" And/or use PRELIBS and/or POSTLIBS at 'make' time similar to the use of PREINCS and POSTINCS. If the libdwarf directory has both libdwarf.so and libdwarf.a, the libdwarf.so will be picked up and "./tag_tree_build: error while loading shared libraries: libdwarf.so: cannot open shared object file: No such file or directory" will probably result. Either: remove libdwarf.so and rebuild or set the environment variable LD_LIBRARY_PATH to the directory containing the .so or use LDFLAGS to set rpath (see just below). It is perhaps simpler to ensure that the libdwarf directory only has an archive, not a shared-library. But sometimes one wants a shared library. In that case one can set ld's -rpath on the gcc command line like this: LDFLAGS="-Wl,-rpath=/some/path/libdir" so the shared library can be found at run time automatically. The same problem may arise with libelf, and the same approach will solve the problem. David Anderson. davea42 at earthlink dot net. dwarfutils-20200114/dwarfdump/README.testcases000066400000000000000000000024001361531463500210020ustar00rootroot00000000000000The following binary test cases are included in the dwarfdump distribution to provide an unchanging means of verifying that dwarfdump basically works. November 5, 2019. Each .base is the inital 500 lines produced by dwarfdump as a baseline to check against the latest compiled dwarfdump output. testobjLE32PE.test.c was compiled to an executable on a Windows 8.1 system with MinGW using a gcc compiler (called just test.c at the time of the compilation). testobjLE32PE.test.c testobjLE32PE.base testobjLE32PE.exe testuriLE64ELf is a compilation of dwarfdump/uri.c and is a plain .o, a relocatable (renamed .obj to avoid a reader confusing this with build-time .o objects). testuriLE64ELf.base testuriLE64ELf.obj test-mach-o-32 is a little-endian compilation to an executable of dwarfexample/simplereader.c on a 32bit Apple system using Apple compilers. The DWARF is in the .dSYM as is normal for Apple and the executable is not present here: There is no executable code here. Notice the __TEXT and __DATA and __PAGEZERO sections are empty (zero length). test-mach-o-32.base test-mach-o-32.dSYM The readelfobj project on sourceforge.net can build executables for all three object formats: readelfobj readobjpe readobjmacho which will show the object file headers. dwarfutils-20200114/dwarfdump/addrmap.c000066400000000000000000000070101361531463500177030ustar00rootroot00000000000000/* Copyright 2010-2012 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* If memory full we do not exit, we just keep going as if all were well. */ #include "globals.h" #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "addrmap.h" #include "dwarf_tsearch.h" static struct Addr_Map_Entry * addr_map_create_entry(Dwarf_Unsigned k,char *name) { struct Addr_Map_Entry *mp = (struct Addr_Map_Entry *)malloc(sizeof(struct Addr_Map_Entry)); if (!mp) { return 0; } mp->mp_key = k; if (name) { mp->mp_name = (char *)strdup(name); } else { mp->mp_name = 0; } return mp; } static void addr_map_free_func(void *mx) { struct Addr_Map_Entry *m = mx; if (!m) { return; } free(m->mp_name); m->mp_name = 0; free(m); return; } static int addr_map_compare_func(const void *l, const void *r) { const struct Addr_Map_Entry *ml = l; const struct Addr_Map_Entry *mr = r; if (ml->mp_key < mr->mp_key) { return -1; } if (ml->mp_key > mr->mp_key) { return 1; } return 0; } struct Addr_Map_Entry * addr_map_insert( Dwarf_Unsigned addr,char *name,void **tree1) { void *retval = 0; struct Addr_Map_Entry *re = 0; struct Addr_Map_Entry *e; e = addr_map_create_entry(addr,name); /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,tree1, addr_map_compare_func); if (retval) { re = *(struct Addr_Map_Entry **)retval; if (re != e) { /* We returned an existing record, e not needed. */ addr_map_free_func(e); } else { /* Record e got added to tree1, do not free record e. */ } } return re; } struct Addr_Map_Entry * addr_map_find(Dwarf_Unsigned addr,void **tree1) { void *retval = 0; struct Addr_Map_Entry *re = 0; struct Addr_Map_Entry *e = 0; e = addr_map_create_entry(addr,NULL); retval = dwarf_tfind(e,tree1, addr_map_compare_func); if (retval) { re = *(struct Addr_Map_Entry **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ addr_map_free_func(e); return re; } void addr_map_destroy(void *map) { /* tdestroy is not part of Posix, it is a GNU libc function. */ dwarf_tdestroy(map,addr_map_free_func); } dwarfutils-20200114/dwarfdump/addrmap.h000066400000000000000000000027171361531463500177210ustar00rootroot00000000000000/* Copyright 2010 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef ADDRMAP_H #define ADDRMAP_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct Addr_Map_Entry { Dwarf_Unsigned mp_key; char * mp_name; }; struct Addr_Map_Entry * addr_map_insert(Dwarf_Unsigned addr, char *name, void **map); struct Addr_Map_Entry * addr_map_find(Dwarf_Unsigned addr, void **map); void addr_map_destroy(void *map); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ADDRMAP_H */ dwarfutils-20200114/dwarfdump/checkutil.c000066400000000000000000000434731361531463500202630ustar00rootroot00000000000000/* Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2011-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* These simple list-processing functions are in support of checking DWARF for compiler-errors of various sorts. */ #include "globals.h" /* It includes config.h */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "esb.h" /* Private function */ static void DumpFullBucketGroup(Bucket_Group *pBucketGroup); static int FindDataIndexInBucket(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData); static void PrintBucketData(Bucket_Group *pBucketGroup, Bucket_Data *pBucketData); static void ProcessBucketGroup(Bucket_Group *pBucketGroup, void (*pFunction)(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData)); Bucket_Group * AllocateBucketGroup(int kind) { Bucket_Group *pBucketGroup = (Bucket_Group *)calloc(1,sizeof(Bucket_Group)); pBucketGroup->kind = kind; return pBucketGroup; } void ReleaseBucketGroup(Bucket_Group *pBucketGroup) { Bucket *pBucket = 0; Bucket *pNext = 0; assert(pBucketGroup); for (pBucket = pBucketGroup->pHead; pBucket; /*pBucket = pBucket->pNext*/) { pNext = pBucket->pNext; free(pBucket); pBucket = pNext; } pBucketGroup->pHead = NULL; pBucketGroup->pTail = NULL; free(pBucketGroup); } void ResetBucketGroup(Bucket_Group *pBucketGroup) { Bucket *pBucket = 0; assert(pBucketGroup); for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) { pBucket->nEntries = 0; } ResetSentinelBucketGroup(pBucketGroup); } /* Reset sentinels in a Bucket Group. */ void ResetSentinelBucketGroup(Bucket_Group *pBucketGroup) { /* Sanity checks */ assert(pBucketGroup); pBucketGroup->pFirst = NULL; pBucketGroup->pLast = NULL; } void PrintBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Bool bFull) { if (pBucketGroup) { if (bFull) { DumpFullBucketGroup(pBucketGroup); } else { if (pBucketGroup->pFirst && pBucketGroup->pLast) { printf("\nBegin Traversing, First = 0x%08" DW_PR_DUx ", Last = 0x%08" DW_PR_DUx "\n", pBucketGroup->pFirst->key,pBucketGroup->pLast->key); ProcessBucketGroup(pBucketGroup,PrintBucketData); } } } } static void PrintBucketData(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData) { int nCount = 0; assert(pBucketGroup); assert(pBucketData); nCount = FindDataIndexInBucket(pBucketGroup,pBucketData); printf("[%06d] Key = 0x%08" DW_PR_DUx ", Base = 0x%08" DW_PR_DUx ", Low = 0x%08" DW_PR_DUx ", High = 0x%08" DW_PR_DUx ", Flag = %d, Name = '%s'\n", ++nCount, pBucketData->key, pBucketData->base, pBucketData->low, pBucketData->high, pBucketData->bFlag, pBucketData->name); } static void DumpFullBucketGroup(Bucket_Group *pBucketGroup) { int nBucketNo = 1; int nIndex = 0; int nCount = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); printf("\nBucket Group at 0x%" DW_PR_DUx " [lower 0x%" DW_PR_DUx " upper 0x%" DW_PR_DUx "]\n", (Dwarf_Unsigned)(uintptr_t)pBucketGroup, (Dwarf_Unsigned)pBucketGroup->lower, (Dwarf_Unsigned)pBucketGroup->upper); for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { printf("LowPC & HighPC records for bucket %d, at 0x%08" DW_PR_DUx "\n", nBucketNo++, (Dwarf_Unsigned)(uintptr_t)pBucket); for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; printf("[%06d] Key = 0x%08" DW_PR_DUx ", Base = 0x%08" DW_PR_DUx ", Low = 0x%08" DW_PR_DUx ", High = 0x%08" DW_PR_DUx ", Flag = %d, Name = '%s'\n", ++nCount, pBucketData->key, pBucketData->base, pBucketData->low, pBucketData->high, pBucketData->bFlag, pBucketData->name); } } } /* Insert entry into Bucket Group. We make no check for duplicate information. */ void AddEntryIntoBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key,Dwarf_Addr base, Dwarf_Addr low,Dwarf_Addr high, const char *name, Dwarf_Bool bFlag) { Bucket *pBucket = 0; Bucket_Data data; data.bFlag = bFlag; data.name = name; data.key = key; data.base = base; data.low = low; data.high = high; assert(pBucketGroup); if (!pBucketGroup->pHead) { /* Allocate first bucket */ pBucket = (Bucket *)calloc(1,sizeof(Bucket)); pBucketGroup->pHead = pBucket; pBucketGroup->pTail = pBucket; pBucket->nEntries = 1; pBucket->Entries[0] = data; return; } pBucket = pBucketGroup->pTail; /* Check if we have a previous allocated set of buckets (have been cleared */ if (pBucket->nEntries) { if (pBucket->nEntries < BUCKET_SIZE) { pBucket->Entries[pBucket->nEntries++] = data; } else { /* Allocate new bucket */ pBucket = (Bucket *)calloc(1,sizeof(Bucket)); pBucketGroup->pTail->pNext = pBucket; pBucketGroup->pTail = pBucket; pBucket->nEntries = 1; pBucket->Entries[0] = data; } } else { /* We have an allocated bucket with zero entries; search for the first available bucket to be used as the current insertion point */ for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) { if (pBucket->nEntries < BUCKET_SIZE) { pBucket->Entries[pBucket->nEntries++] = data; break; } } } } /* For Groups where entries are individually deleted, this does that work. */ Dwarf_Bool DeleteKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; /* Sanity checks */ assert(pBucketGroup); /* For now do a linear search */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (pBucketData->key == key) { Bucket_Data data = {FALSE,NULL,0,0,0,0}; int nStart; for (nStart = nIndex + 1; nStart < pBucket->nEntries; ++nStart) { pBucket->Entries[nIndex] = pBucket->Entries[nStart]; ++nIndex; } pBucket->Entries[nIndex] = data; --pBucket->nEntries; return TRUE; } } } return FALSE; } /* Search to see if the address is in the range between low and high addresses in some Bucked Data record. This matches == if high is exact match (which usually means one-past-true-high). */ Dwarf_Bool FindAddressInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); /* For now do a linear search */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (address >= pBucketData->low && address <= pBucketData->high) { return TRUE; } } } return FALSE; } /* Search an entry (Bucket Data) in the Bucket Set */ Bucket_Data *FindDataInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key) { int mid = 0; int low = 0; int high = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); for (pBucket = pBucketGroup->pHead; pBucket; pBucket = pBucket->pNext) { /* Get lower and upper references */ if (pBucket->nEntries) { low = 0; high = pBucket->nEntries; while (low < high) { mid = low + (high - low) / 2; if (pBucket->Entries[mid].key < key) { low = mid + 1; } else { high = mid; } } if ((low < pBucket->nEntries) && (pBucket->Entries[low].key == key)) { pBucketData = &pBucket->Entries[low]; /* Update sentinels to allow traversing the table */ if (!pBucketGroup->pFirst) { pBucketGroup->pFirst = pBucketData; } pBucketGroup->pLast = pBucketData; return pBucketData; } } } return (Bucket_Data *)NULL; } /* Find the Bucket that contains a given Bucket Data and return its local index. Else return -1. */ static int FindDataIndexInBucket(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData) { Bucket *pBucket = 0; Bucket_Data *pLower = 0; Bucket_Data *pUpper = 0; /* Sanity checks */ assert(pBucketGroup); assert(pBucketData); /* Use sentinels if any. */ if (pBucketGroup->pFirst && pBucketGroup->pLast && pBucketData >= pBucketGroup->pFirst && pBucketData <= pBucketGroup->pLast) { /* Find bucket that contains the first sentinel */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { pLower = &pBucket->Entries[0]; pUpper = &pBucket->Entries[pBucket->nEntries - 1]; /* Check if the first sentinel is in this bucket. */ if (pBucketGroup->pFirst >= pLower && pBucketGroup->pFirst <= pUpper) { /* We have found the bucket, return the index. */ return pBucketData - pBucketGroup->pFirst; } } } else { /* Find bucket that contains the entry */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { pLower = &pBucket->Entries[0]; pUpper = &pBucket->Entries[pBucket->nEntries - 1]; /* Check if the first sentinel is in this bucket */ if (pBucketData >= pLower && pBucketData <= pUpper) { /* We have found the bucket, return the index */ return pBucketData - pLower; } } } /* Invalid data; just return index indicating not-found */ return -1; } /* Search an entry (Bucket Data) in the Bucket Group. The key is an offset, a DIE offset within Visited info. */ Bucket_Data *FindKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; /* Sanity checks */ assert(pBucketGroup); /* For now do a linear search */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (pBucketData->key == key) { return pBucketData; } } } return (Bucket_Data *)NULL; } /* Search an entry (Bucket Data) in the Bucket Set by name. Used to find link-once section names. */ Bucket_Data * FindNameInBucketGroup(Bucket_Group *pBucketGroup,char *name) { int nIndex = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; assert(pBucketGroup); /* For now do a linear search. */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (!strcmp(pBucketData->name,name)) { return pBucketData; } } } return (Bucket_Data *)NULL; } /* Check if an address valid or not. That is, check if it is in the lower -> upper range of a bucket. It checks <= and >= so the lower end and one-past on the upper end matches. */ Dwarf_Bool IsValidInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address) { Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; int nIndex = 0; assert(pBucketGroup); /* Check the address is within the allowed limits */ if (address >= pBucketGroup->lower && address <= pBucketGroup->upper) { for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = 0; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (address >= pBucketData->low && address <= pBucketData->high) { return TRUE; } } } } return FALSE; } /* Reset limits for values in the Bucket Set */ void ResetLimitsBucketSet(Bucket_Group *pBucketGroup) { assert(pBucketGroup); pBucketGroup->lower = 0; pBucketGroup->upper = 0; } /* Limits are set only for ranges, so only in pRangesInfo. */ void SetLimitsBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr lower,Dwarf_Addr upper) { assert(pBucketGroup); if (lower < upper) { pBucketGroup->lower = lower; pBucketGroup->upper = upper; } } /* Traverse Bucket Set and execute a supplied function */ static void ProcessBucketGroup(Bucket_Group *pBucketGroup, void (*pFunction)(Bucket_Group *pBucketGroup,Bucket_Data *pBucketData)) { int nIndex = 0; int nStart = 0; Bucket *pBucket = 0; Bucket_Data *pBucketData = 0; Bucket_Data *pLower = 0; Bucket_Data *pUpper = 0; Dwarf_Bool bFound = FALSE; /* Sanity checks */ assert(pBucketGroup); /* No sentinels present; do nothing */ if (!pBucketGroup->pFirst || !pBucketGroup->pLast) { return; } /* Find bucket that contains the first sentinel */ for (pBucket = pBucketGroup->pHead; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { pLower = &pBucket->Entries[0]; pUpper = &pBucket->Entries[pBucket->nEntries - 1]; /* Check if the first sentinel is in this bucket */ if (pBucketGroup->pFirst >= pLower && pBucketGroup->pFirst <= pUpper) { /* Low sentinel is in this bucket */ bFound = TRUE; break; } } /* Invalid sentinel; do nothing */ if (!bFound) { return; } /* Calculate index for first sentinel */ nStart = pBucketGroup->pFirst - pLower; /* Start traversing from found bucket */ for (; pBucket && pBucket->nEntries; pBucket = pBucket->pNext) { for (nIndex = nStart; nIndex < pBucket->nEntries; ++nIndex) { pBucketData = &pBucket->Entries[nIndex]; if (pBucketData > pBucketGroup->pLast) { return; } /* Call the user supplied function */ if (pFunction) { pFunction(pBucketGroup,pBucketData); } } /* For next bucket start with first entry */ nStart = 0; } } /* Check if a given (lopc,hipc) are valid for a linkonce. We pass in the linkonce (instead of referencing the global pLinkonceInfo) as that means searches for pLinkonceInfo find all the uses, making understanding of the code a tiny bit easier. The section name created is supposed to be the appropriate linkonce section name. */ Dwarf_Bool IsValidInLinkonce(Bucket_Group *pLo, const char *name,Dwarf_Addr lopc,Dwarf_Addr hipc) { #define SECTION_NAME_LEN 2048 /* Guessing a sensible length */ static char section_name[SECTION_NAME_LEN]; Bucket_Data *pBucketData = 0; /* Since text is quite uniformly just this name, no need to get it from elsewhere, though it will not work for non-elf. */ const char *lo_text = ".text."; /* Build the name that represents the linkonce section (.text). This is not defined in DWARF so not correct for all compilers. */ #ifdef ORIGINAL_SPRINTF snprintf(section_name,sizeof(section_name),"%s%s",lo_text,name); pBucketData = FindNameInBucketGroup(pLo,section_name); #else struct esb_s sn; esb_constructor_fixed(&sn,section_name,sizeof(section_name)); esb_append(&sn,lo_text); esb_append(&sn,name); pBucketData = FindNameInBucketGroup(pLo,esb_get_string(&sn)); esb_destructor(&sn); #endif if (pBucketData) { if (lopc >= pBucketData->low && lopc <= pBucketData->high) { if (hipc >= pBucketData->low && hipc <= pBucketData->high) { return TRUE; } } } return FALSE; } dwarfutils-20200114/dwarfdump/checkutil.h000066400000000000000000000074221361531463500202620ustar00rootroot00000000000000/* Copyright (C) 2011 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef CHECKUTIL_H #define CHECKUTIL_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Map information. Depending on the specific functions used various fields here are either used or ignored. */ typedef struct { Dwarf_Bool bFlag; /* General flag */ const char *name; /* Generic name */ Dwarf_Addr key; /* Used for binary search, the key is either a pc address or a DIE offset depending on which bucket table is in use. */ Dwarf_Addr base; /* Used for base address */ Dwarf_Addr low; /* Used for Low PC */ Dwarf_Addr high; /* Used for High PC */ } Bucket_Data; /* This groups Bucket_Data records into a 'bucket' so that a single malloc creates BUCKET_SIZE entries. The intent is to reduce overhead (as compared to having next/previous pointers in each Bucket_Data and mallocing each Bucket_Data individually. */ #define BUCKET_SIZE 2040 typedef struct bucket { int nEntries; Bucket_Data Entries[BUCKET_SIZE]; struct bucket *pNext; } Bucket; /* This Forms the head record of a list of Buckets. */ typedef struct { int kind; /* Kind of bucket */ Dwarf_Addr lower; /* Lower value for data */ Dwarf_Addr upper; /* Upper value for data */ Bucket_Data *pFirst; /* First sentinel */ Bucket_Data *pLast; /* Last sentinel */ Bucket *pHead; /* First bucket in set */ Bucket *pTail; /* Last bucket in set */ } Bucket_Group; Bucket_Group *AllocateBucketGroup(int kind); void ReleaseBucketGroup(Bucket_Group *pBucketGroup); void ResetBucketGroup(Bucket_Group *pBucketGroup); void ResetSentinelBucketGroup(Bucket_Group *pBucketGroup); void PrintBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Bool bFull); void AddEntryIntoBucketGroup(Bucket_Group *pBucketGroup, Dwarf_Addr key,Dwarf_Addr base,Dwarf_Addr low,Dwarf_Addr high, const char *name, Dwarf_Bool bFlag); Dwarf_Bool DeleteKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key); Dwarf_Bool FindAddressInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr address); Bucket_Data *FindDataInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key); Bucket_Data *FindKeyInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr key); Bucket_Data *FindNameInBucketGroup(Bucket_Group *pBucketGroup,char *name); Dwarf_Bool IsValidInBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr pc); void ResetLimitsBucketSet(Bucket_Group *pBucketGroup); void SetLimitsBucketGroup(Bucket_Group *pBucketGroup,Dwarf_Addr lower,Dwarf_Addr upper); Dwarf_Bool IsValidInLinkonce(Bucket_Group *pLo, const char *name,Dwarf_Addr lopc,Dwarf_Addr hipc); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* CHECKUTIL_H */ dwarfutils-20200114/dwarfdump/command_options.c000066400000000000000000002541401361531463500214740ustar00rootroot00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "dwconf.h" #include "dwgetopt.h" #include "common.h" #include "makename.h" #include "uri.h" #include "esb.h" /* For flexible string buffer. */ #include "sanitized.h" #include "tag_common.h" #include "section_bitmaps.h" #include "command_options.h" #include "compiler_info.h" static const char *remove_quotes_pair(const char *text); static char *special_program_name(char *n); static void suppress_check_dwarf(void); extern char *dwoptarg; /* These configure items are for the frame data. We're flexible in the path to dwarfdump.conf . The HOME strings here are transformed in dwconf.c to reference the environment variable $HOME . As of August 2018 CONFPREFIX is always set as it comes from autoconf --prefix, aka $prefix which defaults to /usr/local The install puts the .conf file in CONFPREFIX/dwarfdump/ */ static char *config_file_defaults[] = { "dwarfdump.conf", "./dwarfdump.conf", "HOME/.dwarfdump.conf", "HOME/dwarfdump.conf", #ifdef CONFPREFIX /* See Makefile.am dwarfdump_CFLAGS. This prefix is the --prefix option (defaults to /usr/local and Makefile.am adds /share/dwarfdump ) */ /* We need 2 levels of macro to get the name turned into the string we want. */ #define STR2(s) # s #define STR(s) STR2(s) STR(CONFPREFIX) "/dwarfdump.conf", #else /* This no longer used as of August 2018. */ "/usr/lib/dwarfdump.conf", #endif 0 }; static const char *config_file_abi = 0; /* Do printing of most sections. Do not do detailed checking. */ static void do_all(void) { glflags.gf_frame_flag = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; /* .debug_types */ glflags.gf_line_flag = TRUE; glflags.gf_pubnames_flag = TRUE; glflags.gf_macinfo_flag = TRUE; glflags.gf_macro_flag = TRUE; glflags.gf_aranges_flag = TRUE; /* Do not do glflags.gf_loc_flag = TRUE glflags.gf_abbrev_flag = TRUE; glflags.gf_ranges_flag = TRUE; because nothing in the DWARF spec guarantees the sections are free of random bytes in areas not referenced by .debug_info */ glflags.gf_string_flag = TRUE; /* Do not do glflags.gf_reloc_flag = TRUE; as print_relocs makes no sense for non-elf dwarfdump users. */ glflags.gf_static_func_flag = TRUE; /* SGI only*/ glflags.gf_static_var_flag = TRUE; /* SGI only*/ glflags.gf_pubtypes_flag = TRUE; /* both SGI typenames and dwarf_pubtypes. */ glflags.gf_weakname_flag = TRUE; /* SGI only*/ glflags.gf_gnu_debuglink_flag = FALSE; #if 0 glflags.gf_header_flag = TRUE; /* Setting this flag without saying what sections to print means no section headers print. So the above gf_header_flag setting here has long been a no-op. */ #endif glflags.gf_debug_names_flag = TRUE; } static int get_number_value(char *v_in,long int *v_out) { long int v= 0; size_t len = strlen(v_in); char *endptr = 0; if (len < 1) { return DW_DLV_ERROR; } v = strtol(v_in,&endptr,10); if (endptr == v_in) { return DW_DLV_NO_ENTRY; } if (*endptr != '\0') { return DW_DLV_ERROR; } *v_out = v; return DW_DLV_OK; } static void suppress_print_dwarf(void) { glflags.gf_do_print_dwarf = FALSE; glflags.gf_do_check_dwarf = TRUE; } /* Remove matching leading/trailing quotes. Does not alter the passed in string. If quotes removed does a makename on a modified string. */ static const char * remove_quotes_pair(const char *text) { static char single_quote = '\''; static char double_quote = '\"'; char quote = 0; const char *p = text; int len = strlen(text); if (len < 2) { return p; } /* Compare first character with ' or " */ if (p[0] == single_quote) { quote = single_quote; } else { if (p[0] == double_quote) { quote = double_quote; } else { return p; } } { if (p[len - 1] == quote) { char *altered = calloc(1,len+1); const char *str2 = 0; strcpy(altered,p+1); altered[len - 2] = '\0'; str2 = makename(altered); free(altered); return str2; } } return p; } /* By trimming a /dwarfdump.O down to /dwarfdump (keeping any prefix or suffix) we can avoid a sed command in regressiontests/DWARFTEST.sh and save 12 minutes run time of a regression test. The effect is, when nothing has changed in the normal output, that the program_name matches too. Because we don't want a different name of dwarfdump to cause a mismatch. */ static char * special_program_name(char *n) { char * mp = "/dwarfdump.O"; char * revstr = "/dwarfdump"; char *cp = n; size_t mslen = strlen(mp); for( ; *cp; ++cp ) { if (*cp == *mp) { if(!strncmp(cp,mp,mslen)){ esb_append(glflags.newprogname,revstr); cp += mslen-1; } else { esb_appendn(glflags.newprogname,cp,1); } } else { esb_appendn(glflags.newprogname,cp,1); } } return esb_get_string(glflags.newprogname); } static void suppress_check_dwarf(void) { glflags.gf_do_print_dwarf = TRUE; if (glflags.gf_do_check_dwarf) { printf("Warning: check flag turned off, " "checking and printing are separate.\n"); } glflags.gf_do_check_dwarf = FALSE; set_checks_off(); } /* The strings whose pointers are returned here from makename are never destructed, but that is ok since there are only about 10 created at most. */ const char * do_uri_translation(const char *s,const char *context) { struct esb_s str; char *finalstr = 0; if (!glflags.gf_uri_options_translation) { return makename(s); } esb_constructor(&str); translate_from_uri(s,&str); if (glflags.gf_do_print_uri_in_input) { if (strcmp(s,esb_get_string(&str))) { printf("Uri Translation on option %s\n",context); printf(" \'%s\'\n",s); printf(" \'%s\'\n",esb_get_string(&str)); } } finalstr = makename(esb_get_string(&str)); esb_destructor(&str); return finalstr; } /* Support for short (-option) and long (--option) names options. These functions implement the individual options. They are called from short names and long names options. Implementation code is shared for both types of formats. */ /* Handlers for the short/long names options. */ static void arg_check_abbrev(void); static void arg_check_all(void); static void arg_check_aranges(void); static void arg_check_attr_dup(void); static void arg_check_attr_encodings(void); static void arg_check_attr_names(void); static void arg_check_constants(void); static void arg_check_files_lines(void); static void arg_check_forward_refs(void); static void arg_check_frame_basic(void); static void arg_check_frame_extended(void); static void arg_check_frame_info(void); static void arg_check_gaps(void); static void arg_check_loc(void); static void arg_check_macros(void); static void arg_check_pubnames(void); static void arg_check_ranges(void); static void arg_check_self_refs(void); static void arg_check_show(void); static void arg_check_silent(void); static void arg_check_summary(void); static void arg_check_tag_attr(void); static void arg_check_tag_tag(void); static void arg_check_type(void); static void arg_check_unique(void); #ifdef HAVE_USAGE_TAG_ATTR static void arg_check_usage(void); static void arg_check_usage_extended(void); #endif /* HAVE_USAGE_TAG_ATTR */ static void arg_elf(void); static void arg_elf_abbrev(void); static void arg_elf_aranges(void); static void arg_elf_default(void); static void arg_elf_fission(void); static void arg_elf_frames(void); static void arg_elf_header(void); static void arg_elf_info(void); static void arg_elf_line(void); static void arg_elf_loc(void); static void arg_elf_macinfo(void); static void arg_elf_pubnames(void); static void arg_elf_pubtypes(void); static void arg_elf_ranges(void); static void arg_elf_strings(void); static void arg_elf_text(void); static void arg_file_abi(void); static void arg_file_line5(void); static void arg_file_name(void); static void arg_file_output(void); static void arg_file_tied(void); static void arg_file_use_no_libelf(void); static void arg_format_attr_name(void); static void arg_format_dense(void); static void arg_format_ellipsis(void); static void arg_format_extensions(void); static void arg_format_global_offsets(void); static void arg_format_loc(void); static void arg_format_registers(void); static void arg_format_suppress_data(void); static void arg_format_suppress_group(void); static void arg_format_suppress_lookup(void); static void arg_format_suppress_offsets(void); static void arg_format_suppress_sanitize(void); static void arg_format_suppress_uri(void); static void arg_format_suppress_uri_msg(void); static void arg_format_file(void); static void arg_format_gcc(void); static void arg_format_groupnumber(void); static void arg_format_limit(void); static void arg_format_producer(void); static void arg_format_snc(void); static void arg_print_all(void); static void arg_print_abbrev(void); static void arg_print_aranges(void); static void arg_print_debug_frame(void); static void arg_print_debug_names(void); static void arg_print_gnu_debuglink(void); static void arg_print_fission(void); static void arg_print_gnu_frame(void); static void arg_print_info(void); static void arg_print_lines(void); static void arg_print_lines_short(void); static void arg_print_loc(void); static void arg_print_macinfo(void); static void arg_print_pubnames(void); static void arg_print_producers(void); static void arg_print_ranges(void); static void arg_print_static(void); static void arg_print_static_func(void); static void arg_print_static_var(void); static void arg_print_str_offsets(void); static void arg_print_strings(void); static void arg_print_types(void); static void arg_print_weaknames(void); static void arg_reloc(void); static void arg_reloc_abbrev(void); static void arg_reloc_aranges(void); static void arg_reloc_frames(void); static void arg_reloc_info(void); static void arg_reloc_line(void); static void arg_reloc_loc(void); static void arg_reloc_pubnames(void); static void arg_reloc_ranges(void); static void arg_search_any(void); static void arg_search_any_count(void); static void arg_search_match(void); static void arg_search_match_count(void); #ifdef HAVE_REGEX static void arg_search_regex(void); static void arg_search_regex_count(void); #endif /* HAVE_REGEX */ static void arg_search_count(void); static void arg_search_invalid(void); static void arg_search_print_children(void); static void arg_search_print_parent(void); static void arg_search_print_tree(void); static void arg_help(void); static void arg_trace(void); static void arg_verbose(void); static void arg_version(void); static void arg_c_multiple_selection(void); static void arg_E_multiple_selection(void); static void arg_h_multiple_selection(void); static void arg_l_multiple_selection(void); static void arg_k_multiple_selection(void); static void arg_kx_multiple_selection(void); #ifdef HAVE_USAGE_TAG_ATTR static void arg_ku_multiple_selection(void); #endif /* HAVE_USAGE_TAG_ATTR */ static void arg_o_multiple_selection(void); static void arg_O_multiple_selection(void); static void arg_S_multiple_selection(void); static void arg_t_multiple_selection(void); static void arg_W_multiple_selection(void); static void arg_x_multiple_selection(void); static void arg_not_supported(void); static void arg_x_invalid(void); /* Extracted from 'process_args', as they are used by option handlers. */ static boolean arg_usage_error = FALSE; static int arg_option = 0; static const char *usage_debug_text[] = { "Usage: DwarfDump ", "options:\t-0\tprint this information", "\t\t-1\tDump RangesInfo Table", "\t\t-2\tDump Location (.debug_loc) Info", "\t\t-3\tDump Ranges (.debug_ranges) Info", "\t\t-4\tDump Linkonce Table", "\t\t-5\tDump Visited Info", "" }; static const char *usage_long_text[] = { "Usage: DwarfDump ", " ", "----------------------------------------------------------------------", "Print Debug Sections", "----------------------------------------------------------------------", "-b --print-abbrev Print abbrev section", "-a --print-all Print all debug_* sections", "-r --print-aranges Print aranges section", "-F --print-eh-frame Print gnu .eh_frame section", "-I --print-fission Print fission sections:", " .gdb_index, .debug_cu_index, .debug_tu_index,", " .debug_tu_index, .gdb_index, .debug_cu_index,", " .debug_tu_index, .debug_tu_index, .gdb_index,", " .debug_cu_index, .debug_tu_index", "-f --print-frame Print dwarf frame section", " --print-gnu-debuglink Print .gnu_debuglink section", "-i --print-info Print info section", "-l --print-lines Print line section", "-ls --print-lines-short Print line section, but do not", " print address", "-c --print-loc Print loc section", "-m --print-macinfo Print macinfo section", "-P --print-producers Print list of compile units per producer", "-p --print-pubnames Print pubnames section", "-N --print-ranges Print ranges section", "-ta --print-static Print both static sections", "-tf --print-static-func Print static func section", "-tv --print-static-var Print static var section", "-s --print-strings Print string section", " --print-str-offsets Print the .debug_str_offsets section", "-y --print-type Print pubtypes section", "-w --print-weakname Print weakname section", " ", "----------------------------------------------------------------------", "Print Relocations Info", "----------------------------------------------------------------------", #ifdef DWARF_WITH_LIBELF "-o --reloc Print relocation info [afiloprR]", "-oa --reloc-abbrev Print relocation .debug_abbrev section", "-or --reloc-aranges Print relocation .debug_aranges section", "-of --reloc-frames Print relocation .debug_frame section", "-oi --reloc-info Print relocation .debug_info section", "-ol --reloc-line Print relocation .debug_line section", "-oo --reloc-loc Print relocation .debug_loc section", "-op --reloc-pubnames Print relocation .debug_pubnames section", "-oR --reloc-ranges Print relocation .debug_ranges section", #else " libelf not present, use GNU readelf or readelfobj", " to see relocations", #endif /* DWARF_WITH_LIBELF */ " ", "----------------------------------------------------------------------", "Print ELF sections header", "----------------------------------------------------------------------", #ifdef DWARF_WITH_LIBELF "-E --elf Print object Header and/or section information", " Same as -E[adfhiIlmoprRstx]", "-Ea --elf-abbrev Print .debug_abbrev header", "-Er --elf-aranges Print .debug_aranges header", "-Ed --elf-default Same as -E and {liaprfoRstx}", "-EI --elf-fission Print fission headers,", " .gdb_index, .debug_cu_index, .debug_tu_index", "-Ef --elf-frames Print .debug_frame header", "-Eh --elf-header Print ELF header", "-Ei --elf-info Print .debug_info header", "-El --elf-line Print .debug_line header", "-Eo --elf-loc Print .debug_loc header", "-Em --elf-macinfo Print old macinfo and dwarf5 macro header", "-Ep --elf-pubnames Print .debug_pubnames header", "-Et --elf-pubtypes Print .debug_types header", "-ER --elf-ranges Print .debug_ranges header", "-Es --elf-strings Print .debug_string header", "-Ex --elf-text Print .text header", #else " libelf not present, use GNU readelf or readelfobj", " to see elf file details", #endif /* DWARF_WITH_LIBELF */ " ", "----------------------------------------------------------------------", "Check DWARF Integrity", "----------------------------------------------------------------------", "-kb --check-abbrev Check abbreviations", "-ka --check-all Do all checks", "-kM --check-aranges Check ranges list (.debug_aranges)", "-kD --check-attr-dup Check duplicated attributes", "-kE --check-attr-encodings Examine attributes encodings", "-kn --check-attr-names Examine names in attributes", "-kc --check-constants Examine DWARF constants", "-kF --check-files-lines Examine integrity of files-lines", " attributes", "-kR --check-forward-refs Check forward references to DIEs", " (declarations)", "-kx --check-frame-basic Basic frames check (.eh_frame,", " .debug_frame)", "-kxe --check-frame-extended Extensive frames check (.eh_frame,", " .debug_frame)", "-kf --check-frame-info Examine frame information (use with", " -f or -F)", "-kg --check-gaps Check debug info gaps", "-kl --check-loc Check location list (.debug_loc)", "-kw --check-macros Check macros", "-ke --check-pubnames Examine attributes of pubnames", "-km --check-ranges Check ranges list (.debug_ranges)", "-kS --check-self-refs Check self references to DIEs", "-kd --check-show Show check results", "-ks --check-silent Perform checks in silent mode", "-ki --check-summary Display summary for all compilers", "-kr --check-tag-attr Examine tag-attr relation", "-kt --check-tag-tag Examine tag-tag relations", " Unless -C option given certain common", " tag-attr and tag-tag extensions are", " assumed to be ok (not reported).", "-ky --check-type Eexamine type info", "-kG --check-unique Print only unique errors", #ifdef HAVE_USAGE_TAG_ATTR "-ku --check-usage Print tag-tree & tag-attr usage", " (basic format)", "-kuf --check-usage-extended Print tag-tree & tag-attr usage", " (full format)", #endif /* HAVE_USAGE_TAG_ATTR */ " ", "----------------------------------------------------------------------", "Print Output Qualifiers", "----------------------------------------------------------------------", "-M --format-attr-name Print the form name for each attribute", "-d --format-dense One line per entry (info section only)", "-e --format-ellipsis Short names for tags, attrs etc.", "-G --format-global-offsets Show global die offsets", "-g --format-loc (incomplete loclist support. Do not use.)", "-R --format-registers Print frame register names as r33 etc", " and allow up to 1200 registers.", " Print using a 'generic' register set.", "-Q --format-suppress-data Suppress printing section data", "-x noprintsectiongroups", " --format-suppress-group do not print section groups", "-n --format-suppress-lookup Suppress frame information function name", " lookup(when printing frame information", " from multi-gigabyte object files this", " option may save significant time).", "-D --format-suppress-offsets do not show offsets", #if 0 "-x nosanitizestrings", " --format-suppress-sanitize Bogus string characters come thru printf", #endif "-U --format-suppress-uri Suppress uri-translate", "-q --format-suppress-uri-msg Suppress uri-did-translate notification", "-C --format-extensions Activate printing (with -i) of warnings", " about certain common DWARF extensions.", " ", "----------------------------------------------------------------------", "Print Output Limiters", "----------------------------------------------------------------------", "-u --format-file= Print only specified file (CU name)", "-cg --format-gcc Check only GCC compiler objects", "-x groupnumber= --format-group= Groupnumber to print", "-H --format-limit= Limit output to the first ", " major units.", " Stop after compilation units", "-c --format-producer= Check only specific compiler objects", " is described by 'DW_AT_producer'", " -c'350.1' check only compiler objects", " with 350.1 in the CU name", "-cs --format-snc Check only SNC compiler objects", " ", "----------------------------------------------------------------------", "File Specifications", "----------------------------------------------------------------------", "-x abi= --file-abi= Name abi in dwarfdump.conf", "-x name= --file-name= Name dwarfdump.conf", "-x line5= --file-line5= Table DWARF5 new interfaces", " where is:", " std, s2l, orig or orig2l", "-O file= --file-output= Name the output file", "-x tied= --file-tied= Name an associated object file", " (Split DWARF)", " --file-use-no-libelf Use non-libelf to read objects", " (as much as possible)", " ", "----------------------------------------------------------------------", "Search text in attributes", "----------------------------------------------------------------------", "-S any= --search-any= Search any ", "-Svany= --search-any-count= print number of occurrences", "-S match= --search-match= Search matching ", "-Svmatch= --search-match-count print number of occurrences", #ifdef HAVE_REGEX "-S regex= --search-regex= Use regular expression", " matching", "-Svregex= --search-regex-count print number of", " occurrences", #endif /* HAVE_REGEX */ " only one -S option allowed, any= and", " regex= only usable if the functions", " required are found at configure time", " ", "-Wc --search-print-children Print children tree (wide format) with -S", "-Wp --search-print-parent Print parent tree (wide format) with -S", "-W --search-print-tree Print parent/children tree ", " (wide format) with -S", " ", "----------------------------------------------------------------------", "Help & Version", "----------------------------------------------------------------------", "-h --help Print this dwarfdump help message.", "-v --verbose Show more information.", "-vv --verbose-more Show even more information.", "-V --version Print version information.", "", }; enum longopts_vals { OPT_BEGIN = 999, /* Check DWARF Integrity */ OPT_CHECK_ABBREV, /* -kb --check-abbrev */ OPT_CHECK_ALL, /* -ka --check-all */ OPT_CHECK_ARANGES, /* -kM --check-aranges */ OPT_CHECK_ATTR_DUP, /* -kD --check-attr-dup */ OPT_CHECK_ATTR_ENCODINGS, /* -kE --check-attr-encodings */ OPT_CHECK_ATTR_NAMES, /* -kn --check-attr-names */ OPT_CHECK_CONSTANTS, /* -kc --check-constants */ OPT_CHECK_FILES_LINES, /* -kF --check-files-lines */ OPT_CHECK_FORWARD_REFS, /* -kR --check-forward-refs */ OPT_CHECK_FRAME_BASIC, /* -kx --check-frame-basic */ OPT_CHECK_FRAME_EXTENDED, /* -kxe --check-frame-extended */ OPT_CHECK_FRAME_INFO, /* -kf --check-frame-info */ OPT_CHECK_GAPS, /* -kg --check-gaps */ OPT_CHECK_LOC, /* -kl --check-loc */ OPT_CHECK_MACROS, /* -kw --check-macros */ OPT_CHECK_PUBNAMES, /* -ke --check-pubnames */ OPT_CHECK_RANGES, /* -km --check-ranges */ OPT_CHECK_SELF_REFS, /* -kS --check-self-refs */ OPT_CHECK_SHOW, /* -kd --check-show */ OPT_CHECK_SILENT, /* -ks --check-silent */ OPT_CHECK_SUMMARY, /* -ki --check-summary */ OPT_CHECK_TAG_ATTR, /* -kr --check-tag-attr */ OPT_CHECK_TAG_TAG, /* -kt --check-tag-tag */ OPT_CHECK_TYPE, /* -ky --check-type */ OPT_CHECK_UNIQUE, /* -kG --check-unique */ #ifdef HAVE_USAGE_TAG_ATTR OPT_CHECK_USAGE, /* -ku --check-usage */ OPT_CHECK_USAGE_EXTENDED, /* -kuf --check-usage-extended */ #endif /* HAVE_USAGE_TAG_ATTR */ /* Print ELF sections header */ OPT_ELF, /* -E --elf */ OPT_ELF_ABBREV, /* -Ea --elf-abbrev */ OPT_ELF_ARANGES, /* -Er --elf-aranges */ OPT_ELF_DEFAULT, /* -Ed --elf-default */ OPT_ELF_FISSION, /* -EI --elf-fission */ OPT_ELF_FRAMES, /* -Ef --elf-frames */ OPT_ELF_HEADER, /* -Eh --elf-header */ OPT_ELF_INFO, /* -Ei --elf-info */ OPT_ELF_LINE, /* -El --elf-line */ OPT_ELF_LOC, /* -Eo --elf-loc */ OPT_ELF_MACINFO, /* -Em --elf-macinfo */ OPT_ELF_PUBNAMES, /* -Ep --elf-pubnames */ OPT_ELF_PUBTYPES, /* -Et --elf-pubtypes */ OPT_ELF_RANGES, /* -ER --elf-ranges */ OPT_ELF_STRINGS, /* -Es --elf-strings */ OPT_ELF_TEXT, /* -Ex --elf-text */ /* File Specifications */ OPT_FILE_ABI, /* -x abi= --file-abi= */ OPT_FILE_LINE5, /* -x line5= --file-line5= */ OPT_FILE_NAME, /* -x name= --file-name= */ OPT_FILE_OUTPUT, /* -O file= --file-output= */ OPT_FILE_TIED, /* -x tied= --file-tied= */ OPT_FILE_USE_NO_LIBELF, /* --file-use-no-libelf= */ /* Print Output Qualifiers */ OPT_FORMAT_ATTR_NAME, /* -M --format-attr-name */ OPT_FORMAT_DENSE, /* -d --format-dense */ OPT_FORMAT_ELLIPSIS, /* -e --format-ellipsis */ OPT_FORMAT_EXTENSIONS, /* -C --format-extensions */ OPT_FORMAT_GLOBAL_OFFSETS, /* -G --format-global-offsets */ OPT_FORMAT_LOC, /* -g --format-loc */ OPT_FORMAT_REGISTERS, /* -R --format-registers */ OPT_FORMAT_SUPPRESS_DATA, /* -Q --format-suppress-data */ OPT_FORMAT_SUPPRESS_GROUP , /* -x --format-suppress-group */ OPT_FORMAT_SUPPRESS_LOOKUP, /* -n --format-suppress-lookup */ OPT_FORMAT_SUPPRESS_OFFSETS, /* -D --format-suppress-offsets */ OPT_FORMAT_SUPPRESS_SANITIZE, /* -x?? --format-suppress-sanitize */ OPT_FORMAT_SUPPRESS_URI, /* -U --format-suppress-uri */ OPT_FORMAT_SUPPRESS_URI_MSG, /* -q --format-suppress-uri-msg */ /* Print Output Limiters */ OPT_FORMAT_FILE, /* -u --format-file= */ OPT_FORMAT_GCC, /* -cg --format-gcc */ OPT_FORMAT_GROUP_NUMBER, /* -x --format-group-number= */ OPT_FORMAT_LIMIT, /* -H --format-limit= */ OPT_FORMAT_PRODUCER, /* -c --format-producer= */ OPT_FORMAT_SNC, /* -cs --format-snc */ /* Print Debug Sections */ OPT_PRINT_ABBREV, /* -b --print-abbrev */ OPT_PRINT_ALL, /* -a --print-all */ OPT_PRINT_ARANGES, /* -r --print-aranges */ OPT_PRINT_DEBUG_NAMES, /* --print-debug-name */ OPT_PRINT_GNU_DEBUGLINK, /* --print-gnu-debuglink */ OPT_PRINT_EH_FRAME, /* -F --print-eh-frame */ OPT_PRINT_FISSION, /* -I --print-fission */ OPT_PRINT_FRAME, /* -f --print-frame */ OPT_PRINT_INFO, /* -i --print-info */ OPT_PRINT_LINES, /* -l --print-lines */ OPT_PRINT_LINES_SHORT, /* -ls --print-lines-short */ OPT_PRINT_LOC, /* -c --print-loc */ OPT_PRINT_MACINFO, /* -m --print-macinfo */ OPT_PRINT_PRODUCERS, /* -P --print-producers */ OPT_PRINT_PUBNAMES, /* -p --print-pubnames */ OPT_PRINT_RANGES, /* -N --print-ranges */ OPT_PRINT_STATIC, /* -ta --print-static */ OPT_PRINT_STATIC_FUNC, /* -tf --print-static-func */ OPT_PRINT_STATIC_VAR, /* -tv --print-static-var */ OPT_PRINT_STRINGS, /* -s --print-strings */ OPT_PRINT_STR_OFFSETS, /* --print-str-offsets */ OPT_PRINT_TYPE, /* -y --print-type */ OPT_PRINT_WEAKNAME, /* -w --print-weakname */ /* Print Relocations Info */ OPT_RELOC, /* -o --reloc */ OPT_RELOC_ABBREV, /* -oa --reloc-abbrev */ OPT_RELOC_ARANGES, /* -or --reloc-aranges */ OPT_RELOC_FRAMES, /* -of --reloc-frames */ OPT_RELOC_INFO, /* -oi --reloc-info */ OPT_RELOC_LINE, /* -ol --reloc-line */ OPT_RELOC_LOC, /* -oo --reloc-loc */ OPT_RELOC_PUBNAMES, /* -op --reloc-pubnames */ OPT_RELOC_RANGES, /* -oR --reloc-ranges */ /* Search text in attributes */ OPT_SEARCH_ANY, /* -S any= --search-any= */ OPT_SEARCH_ANY_COUNT, /* -Svany= --search-any-count= */ OPT_SEARCH_MATCH, /* -S match= --search-match= */ OPT_SEARCH_MATCH_COUNT, /* -Svmatch= --search-match-count*/ OPT_SEARCH_PRINT_CHILDREN, /* -Wc --search-print-children */ OPT_SEARCH_PRINT_PARENT, /* -Wp --search-print-parent */ OPT_SEARCH_PRINT_TREE, /* -W --search-print-tree */ #ifdef HAVE_REGEX OPT_SEARCH_REGEX, /* -S regex= --search-regex= */ OPT_SEARCH_REGEX_COUNT, /* -Svregex= --search-regex-count*/ #endif /* HAVE_REGEX */ /* Help & Version */ OPT_HELP, /* -h --help */ OPT_VERBOSE, /* -v --verbose */ OPT_VERBOSE_MORE, /* -vv --verbose-more */ OPT_VERSION, /* -V --version */ /* Trace */ OPT_TRACE, /* -# --trace= */ OPT_END }; static struct dwoption longopts[] = { /* Check DWARF Integrity. */ {"check-abbrev", dwno_argument, 0, OPT_CHECK_ABBREV }, {"check-all", dwno_argument, 0, OPT_CHECK_ALL }, {"check-aranges", dwno_argument, 0, OPT_CHECK_ARANGES }, {"check-attr-dup", dwno_argument, 0, OPT_CHECK_ATTR_DUP }, {"check-attr-encodings", dwno_argument, 0, OPT_CHECK_ATTR_ENCODINGS}, {"check-attr-names", dwno_argument, 0, OPT_CHECK_ATTR_NAMES }, {"check-constants", dwno_argument, 0, OPT_CHECK_CONSTANTS }, {"check-files-lines", dwno_argument, 0, OPT_CHECK_FILES_LINES }, {"check-forward-refs", dwno_argument, 0, OPT_CHECK_FORWARD_REFS }, {"check-frame-basic", dwno_argument, 0, OPT_CHECK_FRAME_BASIC }, {"check-frame-extended", dwno_argument, 0, OPT_CHECK_FRAME_EXTENDED}, {"check-frame-info", dwno_argument, 0, OPT_CHECK_FRAME_INFO }, {"check-gaps", dwno_argument, 0, OPT_CHECK_GAPS }, {"check-loc", dwno_argument, 0, OPT_CHECK_LOC }, {"check-macros", dwno_argument, 0, OPT_CHECK_MACROS }, {"check-pubnames", dwno_argument, 0, OPT_CHECK_PUBNAMES }, {"check-ranges", dwno_argument, 0, OPT_CHECK_RANGES }, {"check-self-refs", dwno_argument, 0, OPT_CHECK_SELF_REFS }, {"check-show", dwno_argument, 0, OPT_CHECK_SHOW }, {"check-silent", dwno_argument, 0, OPT_CHECK_SILENT }, {"check-summary", dwno_argument, 0, OPT_CHECK_SUMMARY }, {"check-tag-attr", dwno_argument, 0, OPT_CHECK_TAG_ATTR }, {"check-tag-tag", dwno_argument, 0, OPT_CHECK_TAG_TAG }, {"check-type", dwno_argument, 0, OPT_CHECK_TYPE }, {"check-unique", dwno_argument, 0, OPT_CHECK_UNIQUE }, #ifdef HAVE_USAGE_TAG_ATTR {"check-usage", dwno_argument, 0, OPT_CHECK_USAGE }, {"check-usage-extended", dwno_argument, 0, OPT_CHECK_USAGE_EXTENDED}, #endif /* HAVE_USAGE_TAG_ATTR */ /* Print ELF sections header. */ {"elf", dwno_argument, 0, OPT_ELF }, {"elf-abbrev", dwno_argument, 0, OPT_ELF_ABBREV }, {"elf-aranges", dwno_argument, 0, OPT_ELF_ARANGES }, {"elf-default", dwno_argument, 0, OPT_ELF_DEFAULT }, {"elf-fission", dwno_argument, 0, OPT_ELF_FISSION }, {"elf-frames", dwno_argument, 0, OPT_ELF_FRAMES }, {"elf-header", dwno_argument, 0, OPT_ELF_HEADER }, {"elf-info", dwno_argument, 0, OPT_ELF_INFO }, {"elf-line", dwno_argument, 0, OPT_ELF_LINE }, {"elf-loc", dwno_argument, 0, OPT_ELF_LOC }, {"elf-macinfo", dwno_argument, 0, OPT_ELF_MACINFO }, {"elf-pubnames", dwno_argument, 0, OPT_ELF_PUBNAMES}, {"elf-pubtypes", dwno_argument, 0, OPT_ELF_PUBTYPES}, {"elf-ranges", dwno_argument, 0, OPT_ELF_RANGES }, {"elf-strings", dwno_argument, 0, OPT_ELF_STRINGS }, {"elf-text", dwno_argument, 0, OPT_ELF_TEXT }, /* File Specifications. */ {"file-abi", dwrequired_argument, 0, OPT_FILE_ABI }, {"file-line5", dwrequired_argument, 0, OPT_FILE_LINE5 }, {"file-name", dwrequired_argument, 0, OPT_FILE_NAME }, {"file-output", dwrequired_argument, 0, OPT_FILE_OUTPUT}, {"file-tied", dwrequired_argument, 0, OPT_FILE_TIED }, {"file-use-no-libelf", dwno_argument, 0, OPT_FILE_USE_NO_LIBELF }, /* Print Output Qualifiers. */ {"format-attr-name", dwno_argument, 0, OPT_FORMAT_ATTR_NAME }, {"format-dense", dwno_argument, 0, OPT_FORMAT_DENSE }, {"format-ellipsis", dwno_argument, 0, OPT_FORMAT_ELLIPSIS }, {"format-extensions", dwno_argument, 0, OPT_FORMAT_EXTENSIONS }, {"format-global-offsets", dwno_argument, 0, OPT_FORMAT_GLOBAL_OFFSETS }, {"format-loc", dwno_argument, 0, OPT_FORMAT_LOC }, {"format-registers", dwno_argument, 0, OPT_FORMAT_REGISTERS }, {"format-suppress-data", dwno_argument, 0, OPT_FORMAT_SUPPRESS_DATA }, {"format-suppress-group", dwno_argument, 0, OPT_FORMAT_SUPPRESS_GROUP }, {"format-suppress-lookup", dwno_argument, 0, OPT_FORMAT_SUPPRESS_LOOKUP }, {"format-suppress-offsets", dwno_argument, 0, OPT_FORMAT_SUPPRESS_OFFSETS }, {"format-suppress-sanitize", dwno_argument, 0, OPT_FORMAT_SUPPRESS_SANITIZE}, {"format-suppress-uri", dwno_argument, 0, OPT_FORMAT_SUPPRESS_URI }, {"format-suppress-uri-msg", dwno_argument, 0, OPT_FORMAT_SUPPRESS_URI_MSG }, /* Print Output Limiters. */ {"format-file", dwrequired_argument, 0, OPT_FORMAT_FILE }, {"format-gcc", dwno_argument, 0, OPT_FORMAT_GCC }, {"format-group-number", dwrequired_argument, 0, OPT_FORMAT_GROUP_NUMBER}, {"format-limit", dwrequired_argument, 0, OPT_FORMAT_LIMIT }, {"format-producer", dwrequired_argument, 0, OPT_FORMAT_PRODUCER }, {"format-snc", dwno_argument, 0, OPT_FORMAT_SNC }, /* Print Debug Sections. */ {"print-abbrev", dwno_argument, 0, OPT_PRINT_ABBREV }, {"print-all", dwno_argument, 0, OPT_PRINT_ALL }, {"print-aranges", dwno_argument, 0, OPT_PRINT_ARANGES }, {"print-debug-names", dwno_argument, 0, OPT_PRINT_DEBUG_NAMES}, {"print-gnu-debuglink", dwno_argument, 0, OPT_PRINT_GNU_DEBUGLINK}, {"print-eh-frame", dwno_argument, 0, OPT_PRINT_EH_FRAME }, {"print-fission", dwno_argument, 0, OPT_PRINT_FISSION }, {"print-frame", dwno_argument, 0, OPT_PRINT_FRAME }, {"print-info", dwno_argument, 0, OPT_PRINT_INFO }, {"print-lines", dwno_argument, 0, OPT_PRINT_LINES }, {"print-lines-short", dwno_argument, 0, OPT_PRINT_LINES_SHORT}, {"print-loc", dwno_argument, 0, OPT_PRINT_LOC }, {"print-macinfo", dwno_argument, 0, OPT_PRINT_MACINFO }, {"print-producers", dwno_argument, 0, OPT_PRINT_PRODUCERS }, {"print-pubnames", dwno_argument, 0, OPT_PRINT_PUBNAMES }, {"print-ranges", dwno_argument, 0, OPT_PRINT_RANGES }, {"print-static", dwno_argument, 0, OPT_PRINT_STATIC }, {"print-static-func", dwno_argument, 0, OPT_PRINT_STATIC_FUNC}, {"print-static-var", dwno_argument, 0, OPT_PRINT_STATIC_VAR }, {"print-strings", dwno_argument, 0, OPT_PRINT_STRINGS }, {"print-str-offsets", dwno_argument, 0, OPT_PRINT_STR_OFFSETS}, {"print-type", dwno_argument, 0, OPT_PRINT_TYPE }, {"print-weakname", dwno_argument, 0, OPT_PRINT_WEAKNAME }, /* Print Relocations Info. */ {"reloc", dwno_argument, 0, OPT_RELOC }, {"reloc-abbrev", dwno_argument, 0, OPT_RELOC_ABBREV }, {"reloc-aranges", dwno_argument, 0, OPT_RELOC_ARANGES }, {"reloc-frames", dwno_argument, 0, OPT_RELOC_FRAMES }, {"reloc-info", dwno_argument, 0, OPT_RELOC_INFO }, {"reloc-line", dwno_argument, 0, OPT_RELOC_LINE }, {"reloc-loc", dwno_argument, 0, OPT_RELOC_LOC }, {"reloc-pubnames", dwno_argument, 0, OPT_RELOC_PUBNAMES}, {"reloc-ranges", dwno_argument, 0, OPT_RELOC_RANGES }, /* Search text in attributes. */ {"search-any", dwrequired_argument, 0, OPT_SEARCH_ANY }, {"search-any-count", dwrequired_argument, 0, OPT_SEARCH_ANY_COUNT }, {"search-match", dwrequired_argument, 0, OPT_SEARCH_MATCH }, {"search-match-count", dwrequired_argument, 0, OPT_SEARCH_MATCH_COUNT }, {"search-print-children", dwno_argument, 0, OPT_SEARCH_PRINT_CHILDREN}, {"search-print-parent", dwno_argument, 0, OPT_SEARCH_PRINT_PARENT }, {"search-print-tree", dwno_argument, 0, OPT_SEARCH_PRINT_TREE }, #ifdef HAVE_REGEX {"search-regex", dwrequired_argument, 0, OPT_SEARCH_REGEX }, {"search-regex-count", dwrequired_argument, 0, OPT_SEARCH_REGEX_COUNT }, #endif /* HAVE_REGEX */ /* Help & Version. */ {"help", dwno_argument, 0, OPT_HELP }, {"verbose", dwno_argument, 0, OPT_VERBOSE }, {"verbose-more", dwno_argument, 0, OPT_VERBOSE_MORE }, {"version", dwno_argument, 0, OPT_VERSION }, /* Trace. */ {"trace", dwrequired_argument, 0, OPT_TRACE}, {0,0,0,0} }; /* Handlers for the command line options. */ /* Option 'print_debug_names' */ void arg_print_debug_names(void) { glflags.gf_debug_names_flag = TRUE; } /* Option 'print_gnu_debuglink' */ void arg_print_gnu_debuglink(void) { glflags.gf_gnu_debuglink_flag = TRUE; } /* Option '--print_str_offsets' */ void arg_print_str_offsets(void) { glflags.gf_print_str_offsets = TRUE; } /* Option '-#' */ void arg_trace(void) { int nTraceLevel = atoi(dwoptarg); if (nTraceLevel >= 0 && nTraceLevel <= MAX_TRACE_LEVEL) { glflags.nTrace[nTraceLevel] = 1; } /* Display dwarfdump debug options. */ if (dump_options) { print_usage_message(glflags.program_name,usage_debug_text); exit(OKAY); } } /* Option '-a' */ void arg_print_all(void) { suppress_check_dwarf(); do_all(); } /* Option '-b' */ void arg_print_abbrev(void) { glflags.gf_abbrev_flag = TRUE; suppress_check_dwarf(); } /* Option '-c[...]' */ void arg_c_multiple_selection(void) { /* Specify compiler name. */ if (dwoptarg) { switch (dwoptarg[0]) { case 's': arg_format_snc(); break; case 'g': arg_format_gcc(); break; default: arg_format_producer(); break; } } else { arg_print_loc(); } } /* Option '-c' */ void arg_print_loc(void) { glflags.gf_loc_flag = TRUE; suppress_check_dwarf(); } /* Option '-cs' */ void arg_format_snc(void) { /* -cs : Check SNC compiler */ glflags.gf_check_snc_compiler = TRUE; glflags.gf_check_all_compilers = FALSE; } /* Option '-cg' */ void arg_format_gcc(void) { /* -cg : Check GCC compiler */ glflags.gf_check_gcc_compiler = TRUE; glflags.gf_check_all_compilers = FALSE; } /* Option '-c' */ void arg_format_producer(void) { /* Assume a compiler version to check, most likely a substring of a compiler name. */ if (!record_producer(dwoptarg)) { fprintf(stderr, "Compiler table max %d exceeded, " "limiting the tracked compilers to %d\n", COMPILER_TABLE_MAX,COMPILER_TABLE_MAX); } } /* Option '-C' */ void arg_format_extensions(void) { glflags.gf_suppress_check_extensions_tables = TRUE; } /* Option '-d' */ void arg_format_dense(void) { glflags.gf_do_print_dwarf = TRUE; /* This is sort of useless unless printing, but harmless, so we do not insist we are printing with suppress_check_dwarf(). */ glflags.dense = TRUE; } /* Option '-D' */ void arg_format_suppress_offsets(void) { /* Do not emit offset in output */ glflags.gf_display_offsets = FALSE; } /* Option '-e' */ void arg_format_ellipsis(void) { suppress_check_dwarf(); glflags.ellipsis = TRUE; } /* Option '-E[...]' */ void arg_E_multiple_selection(void) { /* Object Header information (but maybe really print) */ /* Selected printing of section info */ if (dwoptarg) { switch (dwoptarg[0]) { case 'a': arg_elf_abbrev(); break; case 'd': arg_elf_default(); break; case 'f': arg_elf_frames(); break; case 'h': arg_elf_header(); break; case 'i': arg_elf_info(); break; case 'I': arg_elf_fission(); break; case 'l': arg_elf_line(); break; case 'm': arg_elf_macinfo(); break; case 'o': arg_elf_loc(); break; case 'p': arg_elf_pubnames(); break; case 'r': arg_elf_aranges(); break; case 'R': arg_elf_ranges(); break; case 's': arg_elf_strings(); break; case 't': arg_elf_pubtypes(); break; case 'x': arg_elf_text(); break; default: arg_usage_error = TRUE; break; } } else { arg_elf(); } } /* Option '-E' */ void arg_elf(void) { /* Display header and all sections info */ glflags.gf_header_flag = TRUE; set_all_sections_on(); } /* Option '-Ea' */ void arg_elf_abbrev(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_ABBREV); } /* Option '-Ed' */ void arg_elf_default(void) { /* case 'd', use the default section set */ glflags.gf_header_flag = TRUE; set_all_section_defaults(); } /* Option '-Ef' */ void arg_elf_frames(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_FRAME); } /* Option '-Eh' */ void arg_elf_header(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_HEADER); } /* Option '-Ei' */ void arg_elf_info(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_INFO); enable_section_map_entry(DW_HDR_DEBUG_TYPES); } /* Option '-EI' */ void arg_elf_fission(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_GDB_INDEX); enable_section_map_entry(DW_HDR_DEBUG_CU_INDEX); enable_section_map_entry(DW_HDR_DEBUG_TU_INDEX); enable_section_map_entry(DW_HDR_DEBUG_NAMES); } /* Option '-El' */ void arg_elf_line(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_LINE); } /* Option '-Em' */ void arg_elf_macinfo(void) { /* For both old macinfo and dwarf5 macro */ glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_MACINFO); } /* Option '-Eo' */ void arg_elf_loc(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_LOC); } /* Option '-Ep' */ void arg_elf_pubnames(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_PUBNAMES); } /* Option '-Er' */ void arg_elf_aranges(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_ARANGES); } /* Option '-ER' */ void arg_elf_ranges(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_RANGES); enable_section_map_entry(DW_HDR_DEBUG_RNGLISTS); } /* Option '-Es' */ void arg_elf_strings(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_STR); } /* Option '-Et' */ void arg_elf_pubtypes(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_DEBUG_PUBTYPES); } /* Option '-Ex' */ void arg_elf_text(void) { glflags.gf_header_flag = TRUE; enable_section_map_entry(DW_HDR_TEXT); } /* Option '-f' */ void arg_print_debug_frame(void) { glflags.gf_frame_flag = TRUE; suppress_check_dwarf(); } /* Option '-F' */ void arg_print_gnu_frame(void) { glflags.gf_eh_frame_flag = TRUE; suppress_check_dwarf(); } /* Option '-g' */ void arg_format_loc(void) { /*info_flag = TRUE; removed from -g. Nov 2015 */ glflags.gf_use_old_dwarf_loclist = TRUE; suppress_check_dwarf(); } /* Option '-G' */ void arg_format_global_offsets(void) { glflags.gf_show_global_offsets = TRUE; } /* Option '-h' */ void arg_h_multiple_selection(void) { if (dwoptarg) { arg_usage_error = TRUE; } else { arg_help(); } } /* Option '-h' */ void arg_help(void) { print_usage_message(glflags.program_name,usage_long_text); exit(OKAY); } /* Option '-H' */ void arg_format_limit(void) { int break_val = atoi(dwoptarg); if (break_val > 0) { glflags.break_after_n_units = break_val; } } /* Option '-i' */ void arg_print_info(void) { glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; suppress_check_dwarf(); } /* Option '-I' */ void arg_print_fission(void) { glflags.gf_gdbindex_flag = TRUE; glflags.gf_gnu_debuglink_flag = TRUE; suppress_check_dwarf(); } /* Option '-k[...]' */ void arg_k_multiple_selection(void) { switch (dwoptarg[0]) { case 'a': arg_check_all(); break; case 'b': arg_check_abbrev(); break; case 'c': arg_check_constants(); break; case 'd': arg_check_show(); break; case 'D': arg_check_attr_dup(); break; case 'e': arg_check_pubnames(); break; case 'E': arg_check_attr_encodings(); break; case 'f': arg_check_frame_info(); break; case 'F': arg_check_files_lines(); break; case 'g': arg_check_gaps(); break; case 'G': arg_check_unique(); break; case 'i': arg_check_summary(); break; case 'l': arg_check_loc(); break; case 'm': arg_check_ranges(); break; case 'M': arg_check_aranges(); break; case 'n': arg_check_attr_names(); break; case 'r': arg_check_tag_attr(); break; case 'R': arg_check_forward_refs(); break; case 's': arg_check_silent(); break; case 'S': arg_check_self_refs(); break; case 't': arg_check_tag_tag(); break; #ifdef HAVE_USAGE_TAG_ATTR case 'u': arg_ku_multiple_selection(); break; #endif /* HAVE_USAGE_TAG_ATTR */ case 'w': arg_check_macros(); break; case 'x': arg_kx_multiple_selection(); break; case 'y': arg_check_type(); break; default: arg_usage_error = TRUE; break; } } /* Option '-ka' */ void arg_check_all(void) { suppress_print_dwarf(); glflags.gf_check_pubname_attr = TRUE; glflags.gf_check_attr_tag = TRUE; glflags.gf_check_tag_tree = TRUE; glflags.gf_check_type_offset = TRUE; glflags.gf_gnu_debuglink_flag = FALSE; glflags.gf_check_names = TRUE; glflags.gf_pubnames_flag = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; glflags.gf_gdbindex_flag = TRUE; glflags.gf_check_decl_file = TRUE; glflags.gf_check_macros = TRUE; glflags.gf_check_frames = TRUE; glflags.gf_check_frames_extended = FALSE; glflags.gf_check_locations = TRUE; glflags.gf_frame_flag = TRUE; glflags.gf_eh_frame_flag = TRUE; glflags.gf_check_ranges = TRUE; glflags.gf_check_lines = TRUE; glflags.gf_check_fdes = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_check_aranges = TRUE; glflags.gf_aranges_flag = TRUE; /* Aranges section */ glflags.gf_check_abbreviations = TRUE; glflags.gf_check_dwarf_constants = TRUE; glflags.gf_check_di_gaps = TRUE; glflags.gf_check_forward_decl = TRUE; glflags.gf_check_self_references = TRUE; glflags.gf_check_attr_encoding = TRUE; glflags.gf_print_usage_tag_attr = TRUE; glflags.gf_check_duplicated_attributes = TRUE; } /* Option '-kb' */ void arg_check_abbrev(void) { /* Abbreviations */ suppress_print_dwarf(); glflags.gf_check_abbreviations = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; /* For some checks is worth trying the plain .debug_abbrev section on its own. */ glflags.gf_abbrev_flag = TRUE; } /* Option '-kc' */ void arg_check_constants(void) { /* DWARF constants */ suppress_print_dwarf(); glflags.gf_check_dwarf_constants = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kd' */ void arg_check_show(void) { /* Display check results */ suppress_print_dwarf(); glflags.gf_check_show_results = TRUE; } /* Option '-kD' */ void arg_check_attr_dup(void) { /* Check duplicated attributes */ suppress_print_dwarf(); glflags.gf_check_duplicated_attributes = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; /* For some checks is worth trying the plain .debug_abbrev section on its own. */ glflags.gf_abbrev_flag = TRUE; } /* Option '-ke' */ void arg_check_pubnames(void) { suppress_print_dwarf(); glflags.gf_check_pubname_attr = TRUE; glflags.gf_pubnames_flag = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_check_fdes = TRUE; } /* Option '-kE' */ void arg_check_attr_encodings(void) { /* Attributes encoding usage */ suppress_print_dwarf(); glflags.gf_check_attr_encoding = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kf' */ void arg_check_frame_info(void) { suppress_print_dwarf(); glflags.gf_check_harmless = TRUE; glflags.gf_check_fdes = TRUE; } /* Option '-kF' */ void arg_check_files_lines(void) { /* files-lines */ suppress_print_dwarf(); glflags.gf_check_decl_file = TRUE; glflags.gf_check_lines = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kg' */ void arg_check_gaps(void) { /* Check debug info gaps */ suppress_print_dwarf(); glflags.gf_check_di_gaps = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kG' */ void arg_check_unique(void) { /* Print just global (unique) errors */ suppress_print_dwarf(); glflags.gf_print_unique_errors = TRUE; } /* Option '-ki' */ void arg_check_summary(void) { /* Summary for each compiler */ suppress_print_dwarf(); glflags.gf_print_summary_all = TRUE; } /* Option '-kl' */ void arg_check_loc(void) { /* Locations list */ suppress_print_dwarf(); glflags.gf_check_locations = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; glflags.gf_loc_flag = TRUE; } /* Option '-km' */ void arg_check_ranges(void) { /* Ranges */ suppress_print_dwarf(); glflags.gf_check_ranges = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kM' */ void arg_check_aranges(void) { /* Aranges */ suppress_print_dwarf(); glflags.gf_check_aranges = TRUE; glflags.gf_aranges_flag = TRUE; } /* Option '-kn' */ void arg_check_attr_names(void) { /* invalid names */ suppress_print_dwarf(); glflags.gf_check_names = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kr' */ void arg_check_tag_attr(void) { suppress_print_dwarf(); glflags.gf_check_attr_tag = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; glflags.gf_check_harmless = TRUE; } /* Option '-kR' */ void arg_check_forward_refs(void) { /* forward declarations in DW_AT_specification */ suppress_print_dwarf(); glflags.gf_check_forward_decl = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-ks' */ void arg_check_silent(void) { /* Check verbose mode */ suppress_print_dwarf(); glflags.gf_check_verbose_mode = FALSE; } /* Option '-kS' */ void arg_check_self_refs(void) { /* self references in: DW_AT_specification, DW_AT_type, DW_AT_abstract_origin */ suppress_print_dwarf(); glflags.gf_check_self_references = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kt' */ void arg_check_tag_tag(void) { suppress_print_dwarf(); glflags.gf_check_tag_tree = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } #ifdef HAVE_USAGE_TAG_ATTR /* Option '-ku[...]' */ void arg_ku_multiple_selection(void) { /* Tag-Tree and Tag-Attr usage */ if (dwoptarg[1]) { switch (dwoptarg[1]) { case 'f': arg_check_usage_extended(); break; default: arg_usage_error = TRUE; break; } } else { arg_check_usage(); } } /* Option '-ku' */ void arg_check_usage(void) { suppress_print_dwarf(); glflags.gf_print_usage_tag_attr = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } /* Option '-kuf' */ void arg_check_usage_extended(void) { arg_check_usage(); /* -kuf : Full report */ glflags.gf_print_usage_tag_attr_full = TRUE; } #endif /* HAVE_USAGE_TAG_ATTR */ /* Option '-kw' */ void arg_check_macros(void) { suppress_print_dwarf(); glflags.gf_check_macros = TRUE; glflags.gf_macro_flag = TRUE; glflags.gf_macinfo_flag = TRUE; } /* Option '-kx[...]' */ void arg_kx_multiple_selection(void) { /* Frames check */ if (dwoptarg[1]) { switch (dwoptarg[1]) { case 'e': arg_check_frame_extended(); break; default: arg_usage_error = TRUE; break; } } else { arg_check_frame_basic(); } } /* Option '-kx' */ void arg_check_frame_basic(void) { suppress_print_dwarf(); glflags.gf_check_frames = TRUE; glflags.gf_frame_flag = TRUE; glflags.gf_eh_frame_flag = TRUE; } /* Option '-kxe' */ void arg_check_frame_extended(void) { arg_check_frame_basic(); /* -xe : Extended frames check */ glflags.gf_check_frames = FALSE; glflags.gf_check_frames_extended = TRUE; } /* Option '-ky' */ void arg_check_type(void) { suppress_print_dwarf(); glflags.gf_check_type_offset = TRUE; glflags.gf_check_harmless = TRUE; glflags.gf_check_decl_file = TRUE; glflags.gf_info_flag = TRUE; glflags.gf_pubtypes_flag = TRUE; glflags.gf_check_ranges = TRUE; glflags.gf_check_aranges = TRUE; } /* Option '-l[...]' */ void arg_l_multiple_selection(void) { if (dwoptarg) { switch (dwoptarg[0]) { case 's': arg_print_lines_short(); break; default: arg_usage_error = TRUE; break; } } else { arg_print_lines(); } } /* Option '-l' */ void arg_print_lines(void) { /* Enable to suppress offsets printing */ glflags.gf_line_flag = TRUE; suppress_check_dwarf(); } /* Option '-ls' */ void arg_print_lines_short(void) { /* -ls : suppress addresses */ glflags.gf_line_print_pc = FALSE; arg_print_lines(); } /* Option '-m' */ void arg_print_macinfo(void) { glflags.gf_macinfo_flag = TRUE; /* DWARF2,3,4 */ glflags.gf_macro_flag = TRUE; /* DWARF5 */ suppress_check_dwarf(); } /* Option '-M' */ void arg_format_attr_name(void) { glflags.show_form_used = TRUE; } /* Option '-n' */ void arg_format_suppress_lookup(void) { glflags.gf_suppress_nested_name_search = TRUE; } /* Option '-N' */ void arg_print_ranges(void) { glflags.gf_ranges_flag = TRUE; suppress_check_dwarf(); } /* Option '-o[...]' */ void arg_o_multiple_selection(void) { if (dwoptarg) { switch (dwoptarg[0]) { case 'a': arg_reloc_abbrev(); break; case 'i': arg_reloc_info(); break; case 'l': arg_reloc_line(); break; case 'p': arg_reloc_pubnames(); break; case 'r': arg_reloc_aranges(); break; case 'f': arg_reloc_frames(); break; case 'o': arg_reloc_loc(); break; case 'R': arg_reloc_ranges(); break; default: arg_usage_error = TRUE; break; } } else { arg_reloc(); } } /* Option '-o' */ void arg_reloc(void) { glflags.gf_reloc_flag = TRUE; set_all_reloc_sections_on(); } /* Option '-oa' */ void arg_reloc_abbrev(void) { /* Case a has no effect, no relocations can point out of the abbrev section. */ glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_ABBREV); } /* Option '-of' */ void arg_reloc_frames(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_FRAME); } /* Option '-oi' */ void arg_reloc_info(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_INFO); enable_reloc_map_entry(DW_SECTION_REL_DEBUG_TYPES); } /* Option '-ol' */ void arg_reloc_line(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_LINE); } /* Option '-oo' */ void arg_reloc_loc(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_LOC); enable_reloc_map_entry(DW_SECTION_REL_DEBUG_LOCLISTS); } /* Option '-op' */ void arg_reloc_pubnames(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_PUBNAMES); } /* Option '-or' */ void arg_reloc_aranges(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_ARANGES); } /* Option '-oR' */ void arg_reloc_ranges(void) { glflags.gf_reloc_flag = TRUE; enable_reloc_map_entry(DW_SECTION_REL_DEBUG_RANGES); enable_reloc_map_entry(DW_SECTION_REL_DEBUG_RNGLISTS); } /* Option '-O' */ void arg_O_multiple_selection(void) { /* Output filename */ /* -O file= */ if (strncmp(dwoptarg,"file=",5) == 0) { dwoptarg = &dwoptarg[5]; arg_file_output(); } else { arg_usage_error = TRUE; } } /* Option '-O file=' */ void arg_file_output(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-output=" : "-O file="; const char *path = do_uri_translation(dwoptarg,ctx); if (strlen(path) > 0) { glflags.output_file = path; } else { arg_usage_error = TRUE; } } /* Option '-p' */ void arg_print_pubnames(void) { glflags.gf_pubnames_flag = TRUE; suppress_check_dwarf(); } /* Option '-P' */ void arg_print_producers(void) { /* List of CUs per compiler */ glflags.gf_producer_children_flag = TRUE; } /* Option '-q' */ void arg_format_suppress_uri_msg(void) { /* Suppress uri-did-translate notification */ glflags.gf_do_print_uri_in_input = FALSE; } /* Option '-Q' */ void arg_format_suppress_data(void) { /* Q suppresses section data printing. */ glflags.gf_do_print_dwarf = FALSE; } /* Option '-r' */ void arg_print_aranges(void) { glflags.gf_aranges_flag = TRUE; suppress_check_dwarf(); } /* Option '-R' */ void arg_format_registers(void) { glflags.gf_generic_1200_regs = TRUE; } /* Option '-s' */ void arg_print_strings(void) { glflags.gf_string_flag = TRUE; suppress_check_dwarf(); } /* Option '-S' */ void arg_S_multiple_selection(void) { /* 'v' option, to print number of occurrences */ /* -S[v]match|any|regex=text*/ if (dwoptarg[0] == 'v') { ++dwoptarg; arg_search_count(); } if (strncmp(dwoptarg,"match=",6) == 0) { dwoptarg = &dwoptarg[6]; arg_search_match(); } else if (strncmp(dwoptarg,"any=",4) == 0) { dwoptarg = &dwoptarg[4]; arg_search_any(); } #ifdef HAVE_REGEX else if (strncmp(dwoptarg,"regex=",6) == 0) { dwoptarg = &dwoptarg[6]; arg_search_regex(); } #endif /* HAVE_REGEX */ else { arg_search_invalid(); } } /* Option '-S any=' */ void arg_search_any(void) { const char *tempstr = 0; const char *ctx = arg_option > OPT_BEGIN ? "--search-any=" : "-S any="; /* -S any= */ glflags.gf_search_is_on = TRUE; glflags.search_any_text = makename(dwoptarg); tempstr = remove_quotes_pair(glflags.search_any_text); glflags.search_any_text = do_uri_translation(tempstr,ctx); if (strlen(glflags.search_any_text) <= 0) { arg_search_invalid(); } } /* Option '-Sv any=' */ void arg_search_any_count(void) { arg_search_count(); arg_search_any(); } /* Option '-S match=' */ void arg_search_match(void) { const char *tempstr = 0; const char *ctx = arg_option > OPT_BEGIN ? "--search-match=" : "-S match="; /* -S match= */ glflags.gf_search_is_on = TRUE; glflags.search_match_text = makename(dwoptarg); tempstr = remove_quotes_pair(glflags.search_match_text); glflags.search_match_text = do_uri_translation(tempstr,ctx); if (strlen(glflags.search_match_text) <= 0) { arg_search_invalid(); } } /* Option '-Sv match=' */ void arg_search_match_count(void) { arg_search_count(); arg_search_match(); } #ifdef HAVE_REGEX /* Option '-S regex=' */ void arg_search_regex(void) { const char *tempstr = 0; const char *ctx = arg_option > OPT_BEGIN ? "--search-regex=" : "-S regex="; /* -S regex= */ glflags.gf_search_is_on = TRUE; glflags.search_regex_text = makename(dwoptarg); tempstr = remove_quotes_pair(glflags.search_regex_text); glflags.search_regex_text = do_uri_translation(tempstr,ctx); if (strlen(glflags.search_regex_text) > 0) { if (regcomp(glflags.search_re, glflags.search_regex_text, REG_EXTENDED)) { fprintf(stderr, "regcomp: unable to compile %s\n", glflags.search_regex_text); } } else { arg_search_invalid(); } } /* Option '-Sv regex=' */ void arg_search_regex_count(void) { arg_search_count(); arg_search_regex(); } #endif /* HAVE_REGEX */ /* Option '-Sv' */ void arg_search_count(void) { glflags.gf_search_print_results = TRUE; } /* Option '-t' */ void arg_t_multiple_selection(void) { switch (dwoptarg[0]) { case 'a': arg_print_static(); break; case 'f': arg_print_static_func(); break; case 'v': arg_print_static_var(); break; default: arg_usage_error = TRUE; break; } } /* Option '-ta' */ void arg_print_static(void) { /* all */ glflags.gf_static_func_flag = TRUE; glflags.gf_static_var_flag = TRUE; suppress_check_dwarf(); } /* Option '-tf' */ void arg_print_static_func(void) { /* .debug_static_func */ glflags.gf_static_func_flag = TRUE; suppress_check_dwarf(); } /* Option '-tv' */ void arg_print_static_var(void) { /* .debug_static_var */ glflags.gf_static_var_flag = TRUE; suppress_check_dwarf(); } /* Option '-u' */ void arg_format_file(void) { const char *ctx = arg_option > OPT_BEGIN ? "--format-file=" : "-u"; /* compile unit */ const char *tstr = 0; glflags.gf_cu_name_flag = TRUE; tstr = do_uri_translation(dwoptarg,ctx); esb_append(glflags.cu_name,tstr); } /* Option '-U' */ void arg_format_suppress_uri(void) { glflags.gf_uri_options_translation = FALSE; } /* Option '-v' */ void arg_verbose(void) { glflags.verbose++; } /* Option '-V' */ void arg_version(void) { /* Display dwarfdump compilation date and time */ print_version_details(glflags.program_fullname,TRUE); exit(OKAY); } /* Option '-w' */ void arg_print_weaknames(void) { /* .debug_weaknames */ glflags.gf_weakname_flag = TRUE; suppress_check_dwarf(); } /* Option '-W[...]' */ void arg_W_multiple_selection(void) { if (dwoptarg) { switch (dwoptarg[0]) { case 'c': arg_search_print_children(); break; case 'p': arg_search_print_parent(); break; default: arg_usage_error = TRUE; break; } } else { arg_search_print_tree(); } } /* Option '-W' */ void arg_search_print_tree(void) { /* Search results in wide format */ glflags.gf_search_wide_format = TRUE; /* -W : Display parent and children tree */ glflags.gf_display_children_tree = TRUE; glflags.gf_display_parent_tree = TRUE; } /* Option '-Wc' */ void arg_search_print_children(void) { /* -Wc : Display children tree */ arg_search_print_tree(); glflags.gf_display_children_tree = TRUE; glflags.gf_display_parent_tree = FALSE; } /* Option '-Wp' */ void arg_search_print_parent(void) { /* -Wp : Display parent tree */ arg_search_print_tree(); glflags.gf_display_children_tree = FALSE; glflags.gf_display_parent_tree = TRUE; } /* Option '-x[...]' */ void arg_x_multiple_selection(void) { if (strncmp(dwoptarg,"name=",5) == 0) { dwoptarg = &dwoptarg[5]; arg_file_name(); } else if (strncmp(dwoptarg,"abi=",4) == 0) { dwoptarg = &dwoptarg[4]; arg_file_abi(); } else if (strncmp(dwoptarg,"groupnumber=",12) == 0) { dwoptarg = &dwoptarg[12]; arg_format_groupnumber(); } else if (strncmp(dwoptarg,"tied=",5) == 0) { dwoptarg = &dwoptarg[5]; arg_file_tied(); } else if (strncmp(dwoptarg,"line5=",6) == 0) { dwoptarg = &dwoptarg[6]; arg_file_line5(); } else if (strcmp(dwoptarg,"nosanitizestrings") == 0) { arg_format_suppress_sanitize(); } else if (strcmp(dwoptarg,"noprintsectiongroups") == 0) { arg_format_suppress_group(); } else { arg_x_invalid(); } } /* Option '-x abi=' */ static void arg_file_abi(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-abi=" : "-x abi="; /* -x abi= meaning select abi from dwarfdump.conf file. Must always select abi to use dwarfdump.conf */ const char *abi = do_uri_translation(dwoptarg,ctx); if (strlen(abi) > 0) { config_file_abi = abi; } else { arg_x_invalid(); } } /* Option '-x groupnumber=' */ static void arg_format_groupnumber(void) { /* By default prints the lowest groupnumber in the object. Default is -x groupnumber=0 For group 1 (standard base dwarfdata) -x groupnumber=1 For group 1 (DWARF5 .dwo sections and dwp data) -x groupnumber=2 */ long int gnum = 0; int res = get_number_value(dwoptarg,&gnum); if (res == DW_DLV_OK) { glflags.group_number = gnum; } else { arg_x_invalid(); } } /* Option '-x line5=' */ static void arg_file_line5(void) { if (!strcmp(dwoptarg,"std")) { glflags.gf_line_flag_selection = singledw5; } else if (!strcmp(dwoptarg,"s2l")) { glflags.gf_line_flag_selection= s2l; } else if (!strcmp(dwoptarg,"orig")) { glflags.gf_line_flag_selection= orig; } else if (!strcmp(dwoptarg,"orig2l")) { glflags.gf_line_flag_selection= orig2l; } else { arg_x_invalid(); } } /* Option '-x name=' */ static void arg_file_name(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-name=" : "-x name="; /* -x name= meaning name dwarfdump.conf file. */ const char *path = do_uri_translation(dwoptarg,ctx); if (strlen(path) > 0) { esb_empty_string(glflags.config_file_path); esb_append(glflags.config_file_path,path); } else { arg_x_invalid(); } } /* Option '-x noprintsectiongroups' */ static void arg_format_suppress_group(void) { glflags.gf_section_groups_flag = FALSE; } /* Option '-x nosanitizestrings' */ static void arg_format_suppress_sanitize(void) { no_sanitize_string_garbage = TRUE; } /* Option '-x tied=' */ static void arg_file_tied(void) { const char *ctx = arg_option > OPT_BEGIN ? "--file-tied=" : "-x tied="; const char *tiedpath = do_uri_translation(dwoptarg,ctx); if (strlen(tiedpath) > 0) { esb_empty_string(glflags.config_file_tiedpath); esb_append(glflags.config_file_tiedpath,tiedpath); } else { arg_x_invalid(); } } /* Option '--file-use-no-libelf' */ static void arg_file_use_no_libelf(void) { glflags.gf_file_use_no_libelf = TRUE; } /* -y */ static void arg_print_types(void) { /* .debug_pubtypes */ /* Also for SGI-only, and obsolete, .debug_typenames */ suppress_check_dwarf(); glflags.gf_pubtypes_flag = TRUE; } /* Option not supported */ static void arg_not_supported(void) { fprintf(stderr, "-%c is no longer supported:ignored\n",arg_option); } /* Error message for invalid '-S' option. */ static void arg_search_invalid(void) { fprintf(stderr, "-S any= or -S match= or" " -S regex=\n"); fprintf(stderr, "is allowed, not -S %s\n",dwoptarg); arg_usage_error = TRUE; } /* Error message for invalid '-x' option. */ static void arg_x_invalid(void) { fprintf(stderr, "-x name= \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x abi= \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x tied= \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x line5={std,s2l,orig,orig2l} \n"); fprintf(stderr, " and \n"); fprintf(stderr, "-x nosanitizestrings \n"); fprintf(stderr, "are legal, not -x %s\n", dwoptarg); arg_usage_error = TRUE; } /* Process the command line arguments and sets the appropiated options. All the options are within the global flags structure. */ static void set_command_options(int argc, char *argv[]) { int longindex = 0; /* j unused */ while ((arg_option = dwgetopt_long(argc, argv, "#:abc::CdDeE::fFgGhH:iIk:l::mMnNo::O:pPqQrRsS:t:u:UvVwW::x:yz", longopts,&longindex)) != EOF) { switch (arg_option) { case '#': arg_trace(); break; case 'a': arg_print_all(); break; case 'b': arg_print_abbrev(); break; case 'c': arg_c_multiple_selection(); break; case 'C': arg_format_extensions(); break; case 'd': arg_format_dense(); break; case 'D': arg_format_suppress_offsets(); break; case 'e': arg_format_ellipsis(); break; case 'E': arg_E_multiple_selection(); break; case 'f': arg_print_debug_frame(); break; case 'F': arg_print_gnu_frame(); break; case 'g': arg_format_loc(); break; case 'G': arg_format_global_offsets(); break; case 'h': arg_h_multiple_selection(); break; case 'H': arg_format_limit(); break; case 'i': arg_print_info(); break; case 'I': arg_print_fission(); break; case 'k': arg_k_multiple_selection(); break; case 'l': arg_l_multiple_selection(); break; case 'm': arg_print_macinfo(); break; case 'M': arg_format_attr_name(); break; case 'n': arg_format_suppress_lookup(); break; case 'N': arg_print_ranges(); break; case 'o': arg_o_multiple_selection(); break; case 'O': arg_O_multiple_selection(); break; case 'p': arg_print_pubnames(); break; case 'P': arg_print_producers(); break; case 'q': arg_format_suppress_uri_msg(); break; case 'Q': arg_format_suppress_data(); break; case 'r': arg_print_aranges(); break; case 'R': arg_format_registers(); break; case 's': arg_print_strings(); break; case 'S': arg_S_multiple_selection(); break; case 't': arg_t_multiple_selection(); break; case 'u': arg_format_file(); break; case 'U': arg_format_suppress_uri(); break; case 'v': arg_verbose(); break; case 'V': arg_version(); break; case 'w': arg_print_weaknames(); break; case 'W': arg_W_multiple_selection(); break; case 'x': arg_x_multiple_selection(); break; case 'y': arg_print_types(); break; case 'z': arg_not_supported(); break; /* Check DWARF Integrity. */ case OPT_CHECK_ABBREV: arg_check_abbrev(); break; case OPT_CHECK_ALL: arg_check_all(); break; case OPT_CHECK_ARANGES: arg_check_aranges(); break; case OPT_CHECK_ATTR_DUP: arg_check_attr_dup(); break; case OPT_CHECK_ATTR_ENCODINGS: arg_check_attr_encodings(); break; case OPT_CHECK_ATTR_NAMES: arg_check_attr_names(); break; case OPT_CHECK_CONSTANTS: arg_check_constants(); break; case OPT_CHECK_FILES_LINES: arg_check_files_lines(); break; case OPT_CHECK_FORWARD_REFS: arg_check_forward_refs(); break; case OPT_CHECK_FRAME_BASIC: arg_check_frame_basic(); break; case OPT_CHECK_FRAME_EXTENDED: arg_check_frame_extended(); break; case OPT_CHECK_FRAME_INFO: arg_check_frame_info(); break; case OPT_CHECK_GAPS: arg_check_gaps(); break; case OPT_CHECK_LOC: arg_check_loc(); break; case OPT_CHECK_MACROS: arg_check_macros(); break; case OPT_CHECK_PUBNAMES: arg_check_pubnames(); break; case OPT_CHECK_RANGES: arg_check_ranges(); break; case OPT_CHECK_SELF_REFS: arg_check_self_refs(); break; case OPT_CHECK_SHOW: arg_check_show(); break; case OPT_CHECK_SILENT: arg_check_silent(); break; case OPT_CHECK_SUMMARY: arg_check_summary(); break; case OPT_CHECK_TAG_ATTR: arg_check_tag_attr(); break; case OPT_CHECK_TAG_TAG: arg_check_tag_tag(); break; case OPT_CHECK_TYPE: arg_check_type(); break; case OPT_CHECK_UNIQUE: arg_check_unique(); break; #ifdef HAVE_USAGE_TAG_ATTR case OPT_CHECK_USAGE: arg_check_usage(); break; case OPT_CHECK_USAGE_EXTENDED: arg_check_usage_extended(); break; #endif /* HAVE_USAGE_TAG_ATTR */ /* Print ELF sections header. */ case OPT_ELF: arg_elf(); break; case OPT_ELF_ABBREV: arg_elf_abbrev(); break; case OPT_ELF_ARANGES: arg_elf_aranges(); break; case OPT_ELF_DEFAULT: arg_elf_default(); break; case OPT_ELF_FISSION: arg_elf_fission(); break; case OPT_ELF_FRAMES: arg_elf_frames(); break; case OPT_ELF_HEADER: arg_elf_header(); break; case OPT_ELF_INFO: arg_elf_info(); break; case OPT_ELF_LINE: arg_elf_line(); break; case OPT_ELF_LOC: arg_elf_loc(); break; case OPT_ELF_MACINFO: arg_elf_macinfo(); break; case OPT_ELF_PUBNAMES: arg_elf_pubnames(); break; case OPT_ELF_PUBTYPES: arg_elf_pubtypes(); break; case OPT_ELF_RANGES: arg_elf_ranges(); break; case OPT_ELF_STRINGS: arg_elf_strings(); break; case OPT_ELF_TEXT: arg_elf_text(); break; /* File Specifications. */ case OPT_FILE_ABI: arg_file_abi(); break; case OPT_FILE_LINE5: arg_file_line5(); break; case OPT_FILE_NAME: arg_file_name(); break; case OPT_FILE_OUTPUT: arg_file_output(); break; case OPT_FILE_TIED: arg_file_tied(); break; case OPT_FILE_USE_NO_LIBELF: arg_file_use_no_libelf(); break; /* Print Output Qualifiers. */ case OPT_FORMAT_ATTR_NAME: arg_format_attr_name(); break; case OPT_FORMAT_DENSE: arg_format_dense(); break; case OPT_FORMAT_ELLIPSIS: arg_format_ellipsis(); break; case OPT_FORMAT_EXTENSIONS: arg_format_extensions(); break; case OPT_FORMAT_GLOBAL_OFFSETS: arg_format_global_offsets(); break; case OPT_FORMAT_LOC: arg_format_loc(); break; case OPT_FORMAT_REGISTERS: arg_format_registers(); break; case OPT_FORMAT_SUPPRESS_DATA: arg_format_suppress_data(); break; case OPT_FORMAT_SUPPRESS_GROUP: arg_format_suppress_group(); break; case OPT_FORMAT_SUPPRESS_OFFSETS: arg_format_suppress_offsets(); break; case OPT_FORMAT_SUPPRESS_LOOKUP: arg_format_suppress_lookup(); break; case OPT_FORMAT_SUPPRESS_SANITIZE:arg_format_suppress_sanitize();break; case OPT_FORMAT_SUPPRESS_URI: arg_format_suppress_uri(); break; case OPT_FORMAT_SUPPRESS_URI_MSG: arg_format_suppress_uri_msg(); break; /* Print Output Limiters. */ case OPT_FORMAT_FILE: arg_format_file(); break; case OPT_FORMAT_GCC: arg_format_gcc(); break; case OPT_FORMAT_GROUP_NUMBER: arg_format_groupnumber(); break; case OPT_FORMAT_LIMIT: arg_format_limit(); break; case OPT_FORMAT_PRODUCER: arg_format_producer(); break; case OPT_FORMAT_SNC: arg_format_snc(); break; /* Print Debug Sections. */ case OPT_PRINT_ABBREV: arg_print_abbrev(); break; case OPT_PRINT_ALL: arg_print_all(); break; case OPT_PRINT_ARANGES: arg_print_aranges(); break; case OPT_PRINT_DEBUG_NAMES: arg_print_debug_names(); break; case OPT_PRINT_GNU_DEBUGLINK: arg_print_gnu_debuglink(); break; case OPT_PRINT_EH_FRAME: arg_print_gnu_frame(); break; case OPT_PRINT_FISSION: arg_print_fission(); break; case OPT_PRINT_FRAME: arg_print_debug_frame(); break; case OPT_PRINT_INFO: arg_print_info(); break; case OPT_PRINT_LINES: arg_print_lines(); break; case OPT_PRINT_LINES_SHORT: arg_print_lines_short(); break; case OPT_PRINT_LOC: arg_print_loc(); break; case OPT_PRINT_MACINFO: arg_print_macinfo(); break; case OPT_PRINT_PRODUCERS: arg_print_producers(); break; case OPT_PRINT_PUBNAMES: arg_print_pubnames(); break; case OPT_PRINT_RANGES: arg_print_ranges(); break; case OPT_PRINT_STATIC: arg_print_static(); break; case OPT_PRINT_STATIC_FUNC: arg_print_static_func(); break; case OPT_PRINT_STATIC_VAR: arg_print_static_var(); break; case OPT_PRINT_STRINGS: arg_print_strings(); break; case OPT_PRINT_STR_OFFSETS: arg_print_str_offsets(); break; case OPT_PRINT_TYPE: arg_print_types(); break; case OPT_PRINT_WEAKNAME: arg_print_weaknames(); break; /* Print Relocations Info. */ case OPT_RELOC: arg_reloc(); break; case OPT_RELOC_ABBREV: arg_reloc_abbrev(); break; case OPT_RELOC_ARANGES: arg_reloc_aranges(); break; case OPT_RELOC_FRAMES: arg_reloc_frames(); break; case OPT_RELOC_INFO: arg_reloc_info(); break; case OPT_RELOC_LINE: arg_reloc_line(); break; case OPT_RELOC_LOC: arg_reloc_loc(); break; case OPT_RELOC_PUBNAMES: arg_reloc_pubnames(); break; case OPT_RELOC_RANGES: arg_reloc_ranges(); break; /* Search text in attributes. */ case OPT_SEARCH_ANY: arg_search_any(); break; case OPT_SEARCH_ANY_COUNT: arg_search_any_count(); break; case OPT_SEARCH_MATCH: arg_search_match(); break; case OPT_SEARCH_MATCH_COUNT: arg_search_match_count(); break; case OPT_SEARCH_PRINT_CHILDREN: arg_search_print_children(); break; case OPT_SEARCH_PRINT_PARENT: arg_search_print_parent(); break; case OPT_SEARCH_PRINT_TREE: arg_search_print_tree(); break; #ifdef HAVE_REGEX case OPT_SEARCH_REGEX: arg_search_regex(); break; case OPT_SEARCH_REGEX_COUNT: arg_search_regex_count(); break; #endif /* HAVE_REGEX */ /* Help & Version. */ case OPT_HELP: arg_help(); break; case OPT_VERBOSE: arg_verbose(); break; case OPT_VERBOSE_MORE: arg_verbose(); break; case OPT_VERSION: arg_version(); break; /* Trace. */ case OPT_TRACE: arg_trace(); break; default: arg_usage_error = TRUE; break; } } } /* process arguments and return object filename */ const char * process_args(int argc, char *argv[]) { glflags.program_name = special_program_name(argv[0]); glflags.program_fullname = argv[0]; suppress_check_dwarf(); if (argv[1] != NULL && argv[1][0] != '-') { do_all(); } glflags.gf_section_groups_flag = TRUE; /* Process the arguments and sets the appropiated option */ set_command_options(argc, argv); init_conf_file_data(glflags.config_file_data); if (config_file_abi && glflags.gf_generic_1200_regs) { printf("Specifying both -R and -x abi= is not allowed. Use one " "or the other. -x abi= ignored.\n"); config_file_abi = FALSE; } if (glflags.gf_generic_1200_regs) { init_generic_config_1200_regs(glflags.config_file_data); } if (config_file_abi && (glflags.gf_frame_flag || glflags.gf_eh_frame_flag)) { int res = 0; res = find_conf_file_and_read_config( esb_get_string(glflags.config_file_path), config_file_abi, config_file_defaults, glflags.config_file_data); if (res > 0) { printf ("Frame not configured due to error(s). Giving up.\n"); glflags.gf_eh_frame_flag = FALSE; glflags.gf_frame_flag = FALSE; } } if (arg_usage_error ) { printf("%s option error.\n",glflags.program_name); printf("To see the options list: %s -h\n",glflags.program_name); exit(FAILED); } if (dwoptind != (argc - 1)) { printf("No object file name provided to %s\n",glflags.program_name); printf("To see the options list: %s -h\n",glflags.program_name); exit(FAILED); } /* FIXME: it seems silly to be printing section names where the section does not exist in the object file. However we continue the long-standard practice of printing such by default in most cases. For now. */ if (glflags.group_number == DW_GROUPNUMBER_DWO) { /* For split-dwarf/DWO some sections make no sense. This prevents printing of meaningless headers where no data can exist. */ glflags.gf_pubnames_flag = FALSE; glflags.gf_eh_frame_flag = FALSE; glflags.gf_frame_flag = FALSE; glflags.gf_macinfo_flag = FALSE; glflags.gf_aranges_flag = FALSE; glflags.gf_ranges_flag = FALSE; glflags.gf_static_func_flag = FALSE; glflags.gf_static_var_flag = FALSE; glflags.gf_weakname_flag = FALSE; } if (glflags.group_number > DW_GROUPNUMBER_BASE) { /* These no longer apply, no one uses. */ glflags.gf_static_func_flag = FALSE; glflags.gf_static_var_flag = FALSE; glflags.gf_weakname_flag = FALSE; glflags.gf_pubnames_flag = FALSE; } if (glflags.gf_do_check_dwarf) { /* Reduce verbosity when checking (checking means checking-only). */ glflags.verbose = 1; } return do_uri_translation(argv[dwoptind],"file-to-process"); } dwarfutils-20200114/dwarfdump/command_options.h000066400000000000000000000025211361531463500214730ustar00rootroot00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef COMMAND_OPTIONS_H #define COMMAND_OPTIONS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ const char *process_args(int argc, char *argv[]); const char *do_uri_translation(const char *s,const char *context); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* COMMAND_OPTIONS_H */ dwarfutils-20200114/dwarfdump/common.c000066400000000000000000000067301361531463500175730ustar00rootroot00000000000000/* Copyright (C) 2008-2010 SN Systems. All Rights Reserved. Portions Copyright (C) 2008-2017 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. . All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* These do little except on Windows */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "common.h" #include "defined_types.h" #include "sanitized.h" #include "warningcontrol.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ #include #ifndef BUILD_STANDARD_SOURCE /* Must match libdwarf.h.in declaration. */ const char * dwarf_package_version(void); #endif /* BUILD_STANDARD_SOURCE */ /*#define RELEASE_DATE "20180416" */ /* PACKAGE_VERSION is from config.h */ /* The Linux/Unix version does not want a version string to print unless -V is on the command line. */ void print_version_details(UNUSEDARG const char * name, #ifdef _WIN32 UNUSEDARG /* we don't use this arg with Windows */ #endif int alwaysprint) { #ifdef _WIN32 #ifdef _DEBUG char *acType = "Debug"; #else char *acType = "Release"; #endif /* _DEBUG */ #ifdef _WIN64 char *bits = "64"; #else char *bits = "32"; #endif /* _WIN64 */ #ifdef ORIGINAL_SPRINTF static char acVersion[64]; snprintf(acVersion,sizeof(acVersion), "[%s %s %s Win%s (%s)]",__DATE__,__TIME__,acType,bits, PACKAGE_VERSION); printf("%s %s\n", sanitized(name),acVersion); #else printf("%s [%s %s %s Win%s (%s)]\n", sanitized(name),__DATE__,__TIME__,acType,bits, PACKAGE_VERSION); #endif /* !ORIGINAL_SPRINTF */ #else /* !_WIN32 */ if (alwaysprint) { #ifdef BUILD_STANDARD_SOURCE /* Used by scripts/buildstandardsource.sh */ printf("%s\n",DW_VERSION_DATE_STR); #else const char *pv = dwarf_package_version(); printf("%s Package Version \"%s\"\n",DW_VERSION_DATE_STR, pv); #endif } #endif /* _WIN32 */ } void print_args(UNUSEDARG int argc, UNUSEDARG char *argv[]) { #ifdef _WIN32 int index = 1; printf("Arguments: "); for (index = 1; index < argc; ++index) { printf("%s ",sanitized(argv[index])); } printf("\n"); #endif /* _WIN32 */ } /* Going to stdout as of April 2018. dwarfdump only calls if requested by user. */ void print_usage_message( UNUSEDARG const char *program_name_in, const char **text) { unsigned i = 0; for (i = 0; *text[i]; ++i) { printf("%s\n", text[i]); } } dwarfutils-20200114/dwarfdump/common.h000066400000000000000000000025561361531463500176020ustar00rootroot00000000000000/* Copyright (C) 2009-2010 SN Systems. All Rights Reserved. Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef COMMON_INCLUDED_H #define COMMON_INCLUDED_H void print_args(int argc, char *argv[]); void print_version_details(const char *name, int alwaysprint); void print_usage_message(const char *program_name, const char **text); #endif /* COMMON_INCLUDED_H */ dwarfutils-20200114/dwarfdump/compiler_info.c000066400000000000000000000367721361531463500211410ustar00rootroot00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "makename.h" #include "command_options.h" #include "compiler_info.h" /* Record compilers whose CU names have been seen. Full CU names recorded here, though only a portion of the name may have been checked to cause the compiler data to be entered here. The +1 guarantees we do not overstep the array. */ static Compiler compilers_detected[COMPILER_TABLE_MAX]; static int compilers_detected_count = 0; /* compilers_targeted is a list of indications of compilers on which we wish error checking (and the counts of checks made and errors found). We do substring comparisons, so the compilers_targeted name might be simply a compiler version number or a short substring of a CU producer name. The +1 guarantees we do not overstep the array. */ static Compiler compilers_targeted[COMPILER_TABLE_MAX]; static int compilers_targeted_count = 0; static int current_compiler = -1; /* Indicates if the current CU is a target */ static boolean current_cu_is_checked_compiler = TRUE; static int hasprefix(const char *sample, const char *prefix) { unsigned prelen = strlen(prefix); if (strncmp(sample,prefix,prelen) == 0) { return TRUE; } return FALSE; } static void PRINT_CHECK_RESULT(char *str, Compiler *pCompiler, Dwarf_Check_Categories category) { Dwarf_Check_Result result = pCompiler->results[category]; printf("%-24s%10d %10d\n", str, result.checks, result.errors); } /* Print checks and errors for a specific compiler */ static void print_specific_checks_results(Compiler *pCompiler) { printf("\nDWARF CHECK RESULT\n"); printf(" \n"); if (glflags.gf_check_pubname_attr) { PRINT_CHECK_RESULT("pubname_attr", pCompiler, pubname_attr_result); } if (glflags.gf_check_attr_tag) { PRINT_CHECK_RESULT("attr_tag", pCompiler, attr_tag_result); } if (glflags.gf_check_tag_tree) { PRINT_CHECK_RESULT("tag_tree", pCompiler, tag_tree_result); } if (glflags.gf_check_type_offset) { PRINT_CHECK_RESULT("type_offset", pCompiler, type_offset_result); } if (glflags.gf_check_decl_file) { PRINT_CHECK_RESULT("decl_file", pCompiler, decl_file_result); } if (glflags.gf_check_ranges) { PRINT_CHECK_RESULT("ranges", pCompiler, ranges_result); } if (glflags.gf_check_lines) { PRINT_CHECK_RESULT("line_table", pCompiler, lines_result); } if (glflags.gf_check_fdes) { PRINT_CHECK_RESULT("fde_table", pCompiler, fde_duplication); } if (glflags.gf_check_aranges) { PRINT_CHECK_RESULT("aranges", pCompiler, aranges_result); } if (glflags.gf_check_names) { PRINT_CHECK_RESULT("names",pCompiler, names_result); } if (glflags.gf_check_frames) { PRINT_CHECK_RESULT("frames",pCompiler, frames_result); } if (glflags.gf_check_locations) { PRINT_CHECK_RESULT("locations",pCompiler, locations_result); } if (glflags.gf_check_harmless) { PRINT_CHECK_RESULT("harmless_errors", pCompiler, harmless_result); } if (glflags.gf_check_abbreviations) { PRINT_CHECK_RESULT("abbreviations", pCompiler, abbreviations_result); } if (glflags.gf_check_dwarf_constants) { PRINT_CHECK_RESULT("dwarf_constants", pCompiler, dwarf_constants_result); } if (glflags.gf_check_di_gaps) { PRINT_CHECK_RESULT("debug_info_gaps", pCompiler, di_gaps_result); } if (glflags.gf_check_forward_decl) { PRINT_CHECK_RESULT("forward_declarations", pCompiler, forward_decl_result); } if (glflags.gf_check_self_references) { PRINT_CHECK_RESULT("self_references", pCompiler, self_references_result); } /* Display attributes encoding results */ if (glflags.gf_check_attr_encoding) { PRINT_CHECK_RESULT("attr_encoding", pCompiler, attr_encoding_result); } /* Duplicated attributes */ if (glflags.gf_check_duplicated_attributes) { PRINT_CHECK_RESULT("duplicated_attributes", pCompiler, duplicated_attributes_result); } PRINT_CHECK_RESULT("** Summarize **",pCompiler, total_check_result); fflush(stdout); } /* Add a CU name to the current compiler entry, specified by the 'current_compiler'; the name is added to the 'compilers_detected' table and is printed if the '-P' option is specified in the command line. */ void add_cu_name_compiler_target(char *name) { a_name_chain *cu_last = 0; a_name_chain *nc = 0; Compiler *pCompiler = 0; if (current_compiler < 1) { fprintf(stderr,"Current compiler set to %d, cannot add " "Compilation unit name. Giving up.",current_compiler); exit(FAILED); } pCompiler = &compilers_detected[current_compiler]; cu_last = pCompiler->cu_last; /* Record current cu name */ nc = (a_name_chain *)malloc(sizeof(a_name_chain)); nc->item = makename(name); nc->next = NULL; if (cu_last) { cu_last->next = nc; } else { pCompiler->cu_list = nc; } pCompiler->cu_last = nc; } /* Reset a compiler entry, so all fields are properly set */ void reset_compiler_entry(Compiler *compiler) { memset(compiler,0,sizeof(Compiler)); } /* Record which compiler was used (or notice we saw it before) and set a couple variables as a side effect (which are used all over): current_cu_is_checked_compiler (used in checking_this_compiler() ) current_compiler The compiler name is from DW_AT_producer. */ void update_compiler_target(const char *producer_name) { boolean cFound = FALSE; int index = 0; safe_strcpy(glflags.CU_producer,sizeof(glflags.CU_producer),producer_name, strlen(producer_name)); current_cu_is_checked_compiler = FALSE; /* This list of compilers is just a start: GCC id : "GNU" SNC id : "SN Systems" */ /* Find a compiler version to check */ if (compilers_targeted_count) { for (index = 1; index <= compilers_targeted_count; ++index) { if (is_strstrnocase(glflags.CU_producer, compilers_targeted[index].name)) { compilers_targeted[index].verified = TRUE; current_cu_is_checked_compiler = TRUE; break; } } } else { /* Internally the strings do not include quotes */ boolean snc_compiler = hasprefix(glflags.CU_producer,"SN") ? TRUE : FALSE; boolean gcc_compiler = hasprefix(glflags.CU_producer,"GNU") ? TRUE : FALSE; current_cu_is_checked_compiler = glflags.gf_check_all_compilers || (snc_compiler && glflags.gf_check_snc_compiler) || (gcc_compiler && glflags.gf_check_gcc_compiler) ; } /* Check for already detected compiler */ for (index = 1; index <= compilers_detected_count; ++index) { if ( #if _WIN32 !stricmp(compilers_detected[index].name,glflags.CU_producer) #else !strcmp(compilers_detected[index].name,glflags.CU_producer) #endif /* _WIN32 */ ) { /* Set current compiler index */ current_compiler = index; cFound = TRUE; break; } } if (!cFound) { /* Record a new detected compiler name. */ if (compilers_detected_count + 1 < COMPILER_TABLE_MAX) { Compiler *pCompiler = 0; char *cmp = makename(glflags.CU_producer); /* Set current compiler index, first compiler at position [1] */ current_compiler = ++compilers_detected_count; pCompiler = &compilers_detected[current_compiler]; reset_compiler_entry(pCompiler); pCompiler->name = cmp; } } } void clean_up_compilers_detected(void) { memset(&compilers_detected[0],0, COMPILER_TABLE_MAX*sizeof(Compiler)); compilers_detected_count = 0; } /* Are we checking for errors from the compiler of the current compilation unit? */ boolean checking_this_compiler(void) { /* This flag has been update by 'update_compiler_target()' and indicates if the current CU is in a targeted compiler specified by the user. Default value is TRUE, which means test all compilers until a CU is detected. */ return current_cu_is_checked_compiler; } static int qsort_compare_compiler(const void *elem1,const void *elem2) { Compiler cmp1 = *(Compiler *)elem1; Compiler cmp2 = *(Compiler *)elem2; int cnt1 = cmp1.results[total_check_result].errors; int cnt2 = cmp2.results[total_check_result].errors; if (cnt1 < cnt2) { return 1; } else if (cnt1 > cnt2) { return -1; } /* When error counts match, sort on name. */ { int v = strcmp(cmp2.name, cmp1.name); return v; } } /* Print a summary of checks and errors */ void print_checks_results(void) { int index = 0; Compiler *pCompilers; Compiler *pCompiler; /* Sort based on errors detected; the first entry is reserved */ pCompilers = &compilers_detected[1]; qsort((void *)pCompilers,compilers_detected_count, sizeof(Compiler),qsort_compare_compiler); /* Print list of CUs for each compiler detected */ if (glflags.gf_producer_children_flag) { a_name_chain *nc = 0; a_name_chain *nc_next = 0; int count = 0; int total = 0; printf("\n*** CU NAMES PER COMPILER ***\n"); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; printf("\n%02d: %s",index,pCompiler->name); count = 0; for (nc = pCompiler->cu_list; nc; nc = nc_next) { printf("\n %02d: '%s'",++count,nc->item); nc_next = nc->next; free(nc); } total += count; printf("\n"); } printf("\nDetected %d CU names\n",total); } /* Print error report only if errors have been detected */ /* Print error report if the -kd option */ if ((glflags.gf_do_check_dwarf && glflags.check_error) || glflags.gf_check_show_results) { int count = 0; int compilers_not_detected = 0; int compilers_verified = 0; /* Find out how many compilers have been verified. */ for (index = 1; index <= compilers_detected_count; ++index) { if (compilers_detected[index].verified) { ++compilers_verified; } } /* Find out how many compilers have been not detected. */ for (index = 1; index <= compilers_targeted_count; ++index) { if (!compilers_targeted[index].verified) { ++compilers_not_detected; } } /* Print compilers detected list */ printf( "\n%d Compilers detected:\n",compilers_detected_count); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; printf("%02d: %s\n",index,pCompiler->name); } /* Print compiler list specified by the user with the '-c', that were not detected. */ if (compilers_not_detected) { count = 0; printf( "\n%d Compilers not detected:\n",compilers_not_detected); for (index = 1; index <= compilers_targeted_count; ++index) { if (!compilers_targeted[index].verified) { printf( "%02d: '%s'\n", ++count,compilers_targeted[index].name); } } } count = 0; printf("\n%d Compilers verified:\n",compilers_verified); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; if (pCompiler->verified) { printf("%02d: errors = %5d, %s\n", ++count, pCompiler->results[total_check_result].errors, pCompiler->name); } } /* Print summary if we have verified compilers or if the -kd option used. */ if (compilers_verified || glflags.gf_check_show_results) { /* Print compilers detected summary*/ if (glflags.gf_print_summary_all) { count = 0; printf("\n*** ERRORS PER COMPILER ***\n"); for (index = 1; index <= compilers_detected_count; ++index) { pCompiler = &compilers_detected[index]; if (pCompiler->verified) { printf("\n%02d: %s", ++count,pCompiler->name); print_specific_checks_results(pCompiler); } } } /* Print general summary (all compilers checked) */ printf("\n*** TOTAL ERRORS FOR ALL COMPILERS ***\n"); print_specific_checks_results(&compilers_detected[0]); } } fflush(stdout); } void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc) { compilers_detected[0].results[category].checks += inc; compilers_detected[0].results[total_check_result].checks += inc; if (current_compiler > 0 && current_compiler < COMPILER_TABLE_MAX) { compilers_detected[current_compiler].results[category].checks += inc; compilers_detected[current_compiler].results[total_check_result].checks += inc; compilers_detected[current_compiler].verified = TRUE; } } void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc) { compilers_detected[0].results[category].errors += inc; compilers_detected[0].results[total_check_result].errors += inc; if (current_compiler > 0 && current_compiler < COMPILER_TABLE_MAX) { compilers_detected[current_compiler].results[category].errors += inc; compilers_detected[current_compiler].results[total_check_result].errors += inc; } } boolean record_producer(char *name) { boolean recorded = FALSE; if ((compilers_targeted_count+1) < COMPILER_TABLE_MAX) { Compiler *pCompiler = 0; const char *cmp = 0; cmp = do_uri_translation(name,"-c"); /* First compiler at position [1] */ compilers_targeted_count++; pCompiler = &compilers_targeted[compilers_targeted_count]; reset_compiler_entry(pCompiler); pCompiler->name = cmp; glflags.gf_check_all_compilers = FALSE; recorded = TRUE; } return recorded; } dwarfutils-20200114/dwarfdump/compiler_info.h000066400000000000000000000043461361531463500211360ustar00rootroot00000000000000/* Copyright 2010-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef COMPILER_INFO_H #define COMPILER_INFO_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define COMPILER_TABLE_MAX 100 typedef struct anc { struct anc *next; char *item; } a_name_chain; typedef struct { int checks; int errors; } Dwarf_Check_Result; /* Records information about compilers (producers) found in the debug information, including the check results for several categories (see -k option). */ typedef struct { const char *name; boolean verified; a_name_chain *cu_list; a_name_chain *cu_last; Dwarf_Check_Result results[LAST_CATEGORY]; } Compiler; /* Compiler statistics. */ extern void update_compiler_target(const char *producer_name); extern void add_cu_name_compiler_target(char *name); extern void clean_up_compilers_detected(void); extern boolean checking_this_compiler(void); extern void reset_compiler_entry(Compiler *compiler); extern void print_checks_results(void); extern void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc); extern void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc); extern boolean record_producer(char *name); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* COMPILER_INFO_H */ dwarfutils-20200114/dwarfdump/defined_types.h000066400000000000000000000026021361531463500211240ustar00rootroot00000000000000/* Copyright 2011-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DEFINED_TYPES_H #define DEFINED_TYPES_H #ifndef BOOLEAN_TYPEDEFED #define BOOLEAN_TYPEDEFED typedef int boolean; #endif /* BOOLEAN_TYPEDEFED */ #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FAILED #define FAILED 1 #endif #define OKAY 0 #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DEFINED_TYPES_H */ dwarfutils-20200114/dwarfdump/dwarf_names.c000066400000000000000000003013701361531463500205670ustar00rootroot00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #include "dwarf.h" #include "libdwarf.h" /* ARGSUSED */ int dwarf_get_TAG_name (unsigned int val,const char ** s_out) { switch (val) { case DW_TAG_array_type: *s_out = "DW_TAG_array_type"; return DW_DLV_OK; case DW_TAG_class_type: *s_out = "DW_TAG_class_type"; return DW_DLV_OK; case DW_TAG_entry_point: *s_out = "DW_TAG_entry_point"; return DW_DLV_OK; case DW_TAG_enumeration_type: *s_out = "DW_TAG_enumeration_type"; return DW_DLV_OK; case DW_TAG_formal_parameter: *s_out = "DW_TAG_formal_parameter"; return DW_DLV_OK; case DW_TAG_imported_declaration: *s_out = "DW_TAG_imported_declaration"; return DW_DLV_OK; case DW_TAG_label: *s_out = "DW_TAG_label"; return DW_DLV_OK; case DW_TAG_lexical_block: *s_out = "DW_TAG_lexical_block"; return DW_DLV_OK; case DW_TAG_member: *s_out = "DW_TAG_member"; return DW_DLV_OK; case DW_TAG_pointer_type: *s_out = "DW_TAG_pointer_type"; return DW_DLV_OK; case DW_TAG_reference_type: *s_out = "DW_TAG_reference_type"; return DW_DLV_OK; case DW_TAG_compile_unit: *s_out = "DW_TAG_compile_unit"; return DW_DLV_OK; case DW_TAG_string_type: *s_out = "DW_TAG_string_type"; return DW_DLV_OK; case DW_TAG_structure_type: *s_out = "DW_TAG_structure_type"; return DW_DLV_OK; case DW_TAG_subroutine_type: *s_out = "DW_TAG_subroutine_type"; return DW_DLV_OK; case DW_TAG_typedef: *s_out = "DW_TAG_typedef"; return DW_DLV_OK; case DW_TAG_union_type: *s_out = "DW_TAG_union_type"; return DW_DLV_OK; case DW_TAG_unspecified_parameters: *s_out = "DW_TAG_unspecified_parameters"; return DW_DLV_OK; case DW_TAG_variant: *s_out = "DW_TAG_variant"; return DW_DLV_OK; case DW_TAG_common_block: *s_out = "DW_TAG_common_block"; return DW_DLV_OK; case DW_TAG_common_inclusion: *s_out = "DW_TAG_common_inclusion"; return DW_DLV_OK; case DW_TAG_inheritance: *s_out = "DW_TAG_inheritance"; return DW_DLV_OK; case DW_TAG_inlined_subroutine: *s_out = "DW_TAG_inlined_subroutine"; return DW_DLV_OK; case DW_TAG_module: *s_out = "DW_TAG_module"; return DW_DLV_OK; case DW_TAG_ptr_to_member_type: *s_out = "DW_TAG_ptr_to_member_type"; return DW_DLV_OK; case DW_TAG_set_type: *s_out = "DW_TAG_set_type"; return DW_DLV_OK; case DW_TAG_subrange_type: *s_out = "DW_TAG_subrange_type"; return DW_DLV_OK; case DW_TAG_with_stmt: *s_out = "DW_TAG_with_stmt"; return DW_DLV_OK; case DW_TAG_access_declaration: *s_out = "DW_TAG_access_declaration"; return DW_DLV_OK; case DW_TAG_base_type: *s_out = "DW_TAG_base_type"; return DW_DLV_OK; case DW_TAG_catch_block: *s_out = "DW_TAG_catch_block"; return DW_DLV_OK; case DW_TAG_const_type: *s_out = "DW_TAG_const_type"; return DW_DLV_OK; case DW_TAG_constant: *s_out = "DW_TAG_constant"; return DW_DLV_OK; case DW_TAG_enumerator: *s_out = "DW_TAG_enumerator"; return DW_DLV_OK; case DW_TAG_file_type: *s_out = "DW_TAG_file_type"; return DW_DLV_OK; case DW_TAG_friend: *s_out = "DW_TAG_friend"; return DW_DLV_OK; case DW_TAG_namelist: *s_out = "DW_TAG_namelist"; return DW_DLV_OK; case DW_TAG_namelist_item: *s_out = "DW_TAG_namelist_item"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2c. DW_TAG_namelist_items */ case DW_TAG_packed_type: *s_out = "DW_TAG_packed_type"; return DW_DLV_OK; case DW_TAG_subprogram: *s_out = "DW_TAG_subprogram"; return DW_DLV_OK; case DW_TAG_template_type_parameter: *s_out = "DW_TAG_template_type_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2f. DW_TAG_template_type_param */ case DW_TAG_template_value_parameter: *s_out = "DW_TAG_template_value_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x30. DW_TAG_template_value_param */ case DW_TAG_thrown_type: *s_out = "DW_TAG_thrown_type"; return DW_DLV_OK; case DW_TAG_try_block: *s_out = "DW_TAG_try_block"; return DW_DLV_OK; case DW_TAG_variant_part: *s_out = "DW_TAG_variant_part"; return DW_DLV_OK; case DW_TAG_variable: *s_out = "DW_TAG_variable"; return DW_DLV_OK; case DW_TAG_volatile_type: *s_out = "DW_TAG_volatile_type"; return DW_DLV_OK; case DW_TAG_dwarf_procedure: *s_out = "DW_TAG_dwarf_procedure"; return DW_DLV_OK; case DW_TAG_restrict_type: *s_out = "DW_TAG_restrict_type"; return DW_DLV_OK; case DW_TAG_interface_type: *s_out = "DW_TAG_interface_type"; return DW_DLV_OK; case DW_TAG_namespace: *s_out = "DW_TAG_namespace"; return DW_DLV_OK; case DW_TAG_imported_module: *s_out = "DW_TAG_imported_module"; return DW_DLV_OK; case DW_TAG_unspecified_type: *s_out = "DW_TAG_unspecified_type"; return DW_DLV_OK; case DW_TAG_partial_unit: *s_out = "DW_TAG_partial_unit"; return DW_DLV_OK; case DW_TAG_imported_unit: *s_out = "DW_TAG_imported_unit"; return DW_DLV_OK; case DW_TAG_mutable_type: *s_out = "DW_TAG_mutable_type"; return DW_DLV_OK; case DW_TAG_condition: *s_out = "DW_TAG_condition"; return DW_DLV_OK; case DW_TAG_shared_type: *s_out = "DW_TAG_shared_type"; return DW_DLV_OK; case DW_TAG_type_unit: *s_out = "DW_TAG_type_unit"; return DW_DLV_OK; case DW_TAG_rvalue_reference_type: *s_out = "DW_TAG_rvalue_reference_type"; return DW_DLV_OK; case DW_TAG_template_alias: *s_out = "DW_TAG_template_alias"; return DW_DLV_OK; case DW_TAG_coarray_type: *s_out = "DW_TAG_coarray_type"; return DW_DLV_OK; case DW_TAG_generic_subrange: *s_out = "DW_TAG_generic_subrange"; return DW_DLV_OK; case DW_TAG_dynamic_type: *s_out = "DW_TAG_dynamic_type"; return DW_DLV_OK; case DW_TAG_atomic_type: *s_out = "DW_TAG_atomic_type"; return DW_DLV_OK; case DW_TAG_call_site: *s_out = "DW_TAG_call_site"; return DW_DLV_OK; case DW_TAG_call_site_parameter: *s_out = "DW_TAG_call_site_parameter"; return DW_DLV_OK; case DW_TAG_skeleton_unit: *s_out = "DW_TAG_skeleton_unit"; return DW_DLV_OK; case DW_TAG_immutable_type: *s_out = "DW_TAG_immutable_type"; return DW_DLV_OK; case DW_TAG_lo_user: *s_out = "DW_TAG_lo_user"; return DW_DLV_OK; case DW_TAG_MIPS_loop: *s_out = "DW_TAG_MIPS_loop"; return DW_DLV_OK; case DW_TAG_HP_array_descriptor: *s_out = "DW_TAG_HP_array_descriptor"; return DW_DLV_OK; case DW_TAG_format_label: *s_out = "DW_TAG_format_label"; return DW_DLV_OK; case DW_TAG_function_template: *s_out = "DW_TAG_function_template"; return DW_DLV_OK; case DW_TAG_class_template: *s_out = "DW_TAG_class_template"; return DW_DLV_OK; case DW_TAG_GNU_BINCL: *s_out = "DW_TAG_GNU_BINCL"; return DW_DLV_OK; case DW_TAG_GNU_EINCL: *s_out = "DW_TAG_GNU_EINCL"; return DW_DLV_OK; case DW_TAG_GNU_template_template_parameter: *s_out = "DW_TAG_GNU_template_template_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x4106. DW_TAG_GNU_template_template_param */ case DW_TAG_GNU_template_parameter_pack: *s_out = "DW_TAG_GNU_template_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_formal_parameter_pack: *s_out = "DW_TAG_GNU_formal_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_call_site: *s_out = "DW_TAG_GNU_call_site"; return DW_DLV_OK; case DW_TAG_GNU_call_site_parameter: *s_out = "DW_TAG_GNU_call_site_parameter"; return DW_DLV_OK; case DW_TAG_SUN_function_template: *s_out = "DW_TAG_SUN_function_template"; return DW_DLV_OK; case DW_TAG_SUN_class_template: *s_out = "DW_TAG_SUN_class_template"; return DW_DLV_OK; case DW_TAG_SUN_struct_template: *s_out = "DW_TAG_SUN_struct_template"; return DW_DLV_OK; case DW_TAG_SUN_union_template: *s_out = "DW_TAG_SUN_union_template"; return DW_DLV_OK; case DW_TAG_SUN_indirect_inheritance: *s_out = "DW_TAG_SUN_indirect_inheritance"; return DW_DLV_OK; case DW_TAG_SUN_codeflags: *s_out = "DW_TAG_SUN_codeflags"; return DW_DLV_OK; case DW_TAG_SUN_memop_info: *s_out = "DW_TAG_SUN_memop_info"; return DW_DLV_OK; case DW_TAG_SUN_omp_child_func: *s_out = "DW_TAG_SUN_omp_child_func"; return DW_DLV_OK; case DW_TAG_SUN_rtti_descriptor: *s_out = "DW_TAG_SUN_rtti_descriptor"; return DW_DLV_OK; case DW_TAG_SUN_dtor_info: *s_out = "DW_TAG_SUN_dtor_info"; return DW_DLV_OK; case DW_TAG_SUN_dtor: *s_out = "DW_TAG_SUN_dtor"; return DW_DLV_OK; case DW_TAG_SUN_f90_interface: *s_out = "DW_TAG_SUN_f90_interface"; return DW_DLV_OK; case DW_TAG_SUN_fortran_vax_structure: *s_out = "DW_TAG_SUN_fortran_vax_structure"; return DW_DLV_OK; case DW_TAG_SUN_hi: *s_out = "DW_TAG_SUN_hi"; return DW_DLV_OK; case DW_TAG_ALTIUM_circ_type: *s_out = "DW_TAG_ALTIUM_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_mwa_circ_type: *s_out = "DW_TAG_ALTIUM_mwa_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rev_carry_type: *s_out = "DW_TAG_ALTIUM_rev_carry_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rom: *s_out = "DW_TAG_ALTIUM_rom"; return DW_DLV_OK; case DW_TAG_upc_shared_type: *s_out = "DW_TAG_upc_shared_type"; return DW_DLV_OK; case DW_TAG_upc_strict_type: *s_out = "DW_TAG_upc_strict_type"; return DW_DLV_OK; case DW_TAG_upc_relaxed_type: *s_out = "DW_TAG_upc_relaxed_type"; return DW_DLV_OK; case DW_TAG_PGI_kanji_type: *s_out = "DW_TAG_PGI_kanji_type"; return DW_DLV_OK; case DW_TAG_PGI_interface_block: *s_out = "DW_TAG_PGI_interface_block"; return DW_DLV_OK; case DW_TAG_hi_user: *s_out = "DW_TAG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_children_name (unsigned int val,const char ** s_out) { switch (val) { case DW_children_no: *s_out = "DW_children_no"; return DW_DLV_OK; case DW_children_yes: *s_out = "DW_children_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FORM_name (unsigned int val,const char ** s_out) { switch (val) { case DW_FORM_addr: *s_out = "DW_FORM_addr"; return DW_DLV_OK; case DW_FORM_block2: *s_out = "DW_FORM_block2"; return DW_DLV_OK; case DW_FORM_block4: *s_out = "DW_FORM_block4"; return DW_DLV_OK; case DW_FORM_data2: *s_out = "DW_FORM_data2"; return DW_DLV_OK; case DW_FORM_data4: *s_out = "DW_FORM_data4"; return DW_DLV_OK; case DW_FORM_data8: *s_out = "DW_FORM_data8"; return DW_DLV_OK; case DW_FORM_string: *s_out = "DW_FORM_string"; return DW_DLV_OK; case DW_FORM_block: *s_out = "DW_FORM_block"; return DW_DLV_OK; case DW_FORM_block1: *s_out = "DW_FORM_block1"; return DW_DLV_OK; case DW_FORM_data1: *s_out = "DW_FORM_data1"; return DW_DLV_OK; case DW_FORM_flag: *s_out = "DW_FORM_flag"; return DW_DLV_OK; case DW_FORM_sdata: *s_out = "DW_FORM_sdata"; return DW_DLV_OK; case DW_FORM_strp: *s_out = "DW_FORM_strp"; return DW_DLV_OK; case DW_FORM_udata: *s_out = "DW_FORM_udata"; return DW_DLV_OK; case DW_FORM_ref_addr: *s_out = "DW_FORM_ref_addr"; return DW_DLV_OK; case DW_FORM_ref1: *s_out = "DW_FORM_ref1"; return DW_DLV_OK; case DW_FORM_ref2: *s_out = "DW_FORM_ref2"; return DW_DLV_OK; case DW_FORM_ref4: *s_out = "DW_FORM_ref4"; return DW_DLV_OK; case DW_FORM_ref8: *s_out = "DW_FORM_ref8"; return DW_DLV_OK; case DW_FORM_ref_udata: *s_out = "DW_FORM_ref_udata"; return DW_DLV_OK; case DW_FORM_indirect: *s_out = "DW_FORM_indirect"; return DW_DLV_OK; case DW_FORM_sec_offset: *s_out = "DW_FORM_sec_offset"; return DW_DLV_OK; case DW_FORM_exprloc: *s_out = "DW_FORM_exprloc"; return DW_DLV_OK; case DW_FORM_flag_present: *s_out = "DW_FORM_flag_present"; return DW_DLV_OK; case DW_FORM_strx: *s_out = "DW_FORM_strx"; return DW_DLV_OK; case DW_FORM_addrx: *s_out = "DW_FORM_addrx"; return DW_DLV_OK; case DW_FORM_ref_sup4: *s_out = "DW_FORM_ref_sup4"; return DW_DLV_OK; case DW_FORM_strp_sup: *s_out = "DW_FORM_strp_sup"; return DW_DLV_OK; case DW_FORM_data16: *s_out = "DW_FORM_data16"; return DW_DLV_OK; case DW_FORM_line_strp: *s_out = "DW_FORM_line_strp"; return DW_DLV_OK; case DW_FORM_ref_sig8: *s_out = "DW_FORM_ref_sig8"; return DW_DLV_OK; case DW_FORM_implicit_const: *s_out = "DW_FORM_implicit_const"; return DW_DLV_OK; case DW_FORM_loclistx: *s_out = "DW_FORM_loclistx"; return DW_DLV_OK; case DW_FORM_rnglistx: *s_out = "DW_FORM_rnglistx"; return DW_DLV_OK; case DW_FORM_ref_sup8: *s_out = "DW_FORM_ref_sup8"; return DW_DLV_OK; case DW_FORM_strx1: *s_out = "DW_FORM_strx1"; return DW_DLV_OK; case DW_FORM_strx2: *s_out = "DW_FORM_strx2"; return DW_DLV_OK; case DW_FORM_strx3: *s_out = "DW_FORM_strx3"; return DW_DLV_OK; case DW_FORM_strx4: *s_out = "DW_FORM_strx4"; return DW_DLV_OK; case DW_FORM_addrx1: *s_out = "DW_FORM_addrx1"; return DW_DLV_OK; case DW_FORM_addrx2: *s_out = "DW_FORM_addrx2"; return DW_DLV_OK; case DW_FORM_addrx3: *s_out = "DW_FORM_addrx3"; return DW_DLV_OK; case DW_FORM_addrx4: *s_out = "DW_FORM_addrx4"; return DW_DLV_OK; case DW_FORM_GNU_addr_index: *s_out = "DW_FORM_GNU_addr_index"; return DW_DLV_OK; case DW_FORM_GNU_str_index: *s_out = "DW_FORM_GNU_str_index"; return DW_DLV_OK; case DW_FORM_GNU_ref_alt: *s_out = "DW_FORM_GNU_ref_alt"; return DW_DLV_OK; case DW_FORM_GNU_strp_alt: *s_out = "DW_FORM_GNU_strp_alt"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_AT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_AT_sibling: *s_out = "DW_AT_sibling"; return DW_DLV_OK; case DW_AT_location: *s_out = "DW_AT_location"; return DW_DLV_OK; case DW_AT_name: *s_out = "DW_AT_name"; return DW_DLV_OK; case DW_AT_ordering: *s_out = "DW_AT_ordering"; return DW_DLV_OK; case DW_AT_subscr_data: *s_out = "DW_AT_subscr_data"; return DW_DLV_OK; case DW_AT_byte_size: *s_out = "DW_AT_byte_size"; return DW_DLV_OK; case DW_AT_bit_offset: *s_out = "DW_AT_bit_offset"; return DW_DLV_OK; case DW_AT_bit_size: *s_out = "DW_AT_bit_size"; return DW_DLV_OK; case DW_AT_element_list: *s_out = "DW_AT_element_list"; return DW_DLV_OK; case DW_AT_stmt_list: *s_out = "DW_AT_stmt_list"; return DW_DLV_OK; case DW_AT_low_pc: *s_out = "DW_AT_low_pc"; return DW_DLV_OK; case DW_AT_high_pc: *s_out = "DW_AT_high_pc"; return DW_DLV_OK; case DW_AT_language: *s_out = "DW_AT_language"; return DW_DLV_OK; case DW_AT_member: *s_out = "DW_AT_member"; return DW_DLV_OK; case DW_AT_discr: *s_out = "DW_AT_discr"; return DW_DLV_OK; case DW_AT_discr_value: *s_out = "DW_AT_discr_value"; return DW_DLV_OK; case DW_AT_visibility: *s_out = "DW_AT_visibility"; return DW_DLV_OK; case DW_AT_import: *s_out = "DW_AT_import"; return DW_DLV_OK; case DW_AT_string_length: *s_out = "DW_AT_string_length"; return DW_DLV_OK; case DW_AT_common_reference: *s_out = "DW_AT_common_reference"; return DW_DLV_OK; case DW_AT_comp_dir: *s_out = "DW_AT_comp_dir"; return DW_DLV_OK; case DW_AT_const_value: *s_out = "DW_AT_const_value"; return DW_DLV_OK; case DW_AT_containing_type: *s_out = "DW_AT_containing_type"; return DW_DLV_OK; case DW_AT_default_value: *s_out = "DW_AT_default_value"; return DW_DLV_OK; case DW_AT_inline: *s_out = "DW_AT_inline"; return DW_DLV_OK; case DW_AT_is_optional: *s_out = "DW_AT_is_optional"; return DW_DLV_OK; case DW_AT_lower_bound: *s_out = "DW_AT_lower_bound"; return DW_DLV_OK; case DW_AT_producer: *s_out = "DW_AT_producer"; return DW_DLV_OK; case DW_AT_prototyped: *s_out = "DW_AT_prototyped"; return DW_DLV_OK; case DW_AT_return_addr: *s_out = "DW_AT_return_addr"; return DW_DLV_OK; case DW_AT_start_scope: *s_out = "DW_AT_start_scope"; return DW_DLV_OK; case DW_AT_bit_stride: *s_out = "DW_AT_bit_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2e. DW_AT_stride_size */ case DW_AT_upper_bound: *s_out = "DW_AT_upper_bound"; return DW_DLV_OK; case DW_AT_abstract_origin: *s_out = "DW_AT_abstract_origin"; return DW_DLV_OK; case DW_AT_accessibility: *s_out = "DW_AT_accessibility"; return DW_DLV_OK; case DW_AT_address_class: *s_out = "DW_AT_address_class"; return DW_DLV_OK; case DW_AT_artificial: *s_out = "DW_AT_artificial"; return DW_DLV_OK; case DW_AT_base_types: *s_out = "DW_AT_base_types"; return DW_DLV_OK; case DW_AT_calling_convention: *s_out = "DW_AT_calling_convention"; return DW_DLV_OK; case DW_AT_count: *s_out = "DW_AT_count"; return DW_DLV_OK; case DW_AT_data_member_location: *s_out = "DW_AT_data_member_location"; return DW_DLV_OK; case DW_AT_decl_column: *s_out = "DW_AT_decl_column"; return DW_DLV_OK; case DW_AT_decl_file: *s_out = "DW_AT_decl_file"; return DW_DLV_OK; case DW_AT_decl_line: *s_out = "DW_AT_decl_line"; return DW_DLV_OK; case DW_AT_declaration: *s_out = "DW_AT_declaration"; return DW_DLV_OK; case DW_AT_discr_list: *s_out = "DW_AT_discr_list"; return DW_DLV_OK; case DW_AT_encoding: *s_out = "DW_AT_encoding"; return DW_DLV_OK; case DW_AT_external: *s_out = "DW_AT_external"; return DW_DLV_OK; case DW_AT_frame_base: *s_out = "DW_AT_frame_base"; return DW_DLV_OK; case DW_AT_friend: *s_out = "DW_AT_friend"; return DW_DLV_OK; case DW_AT_identifier_case: *s_out = "DW_AT_identifier_case"; return DW_DLV_OK; case DW_AT_macro_info: *s_out = "DW_AT_macro_info"; return DW_DLV_OK; case DW_AT_namelist_item: *s_out = "DW_AT_namelist_item"; return DW_DLV_OK; case DW_AT_priority: *s_out = "DW_AT_priority"; return DW_DLV_OK; case DW_AT_segment: *s_out = "DW_AT_segment"; return DW_DLV_OK; case DW_AT_specification: *s_out = "DW_AT_specification"; return DW_DLV_OK; case DW_AT_static_link: *s_out = "DW_AT_static_link"; return DW_DLV_OK; case DW_AT_type: *s_out = "DW_AT_type"; return DW_DLV_OK; case DW_AT_use_location: *s_out = "DW_AT_use_location"; return DW_DLV_OK; case DW_AT_variable_parameter: *s_out = "DW_AT_variable_parameter"; return DW_DLV_OK; case DW_AT_virtuality: *s_out = "DW_AT_virtuality"; return DW_DLV_OK; case DW_AT_vtable_elem_location: *s_out = "DW_AT_vtable_elem_location"; return DW_DLV_OK; case DW_AT_allocated: *s_out = "DW_AT_allocated"; return DW_DLV_OK; case DW_AT_associated: *s_out = "DW_AT_associated"; return DW_DLV_OK; case DW_AT_data_location: *s_out = "DW_AT_data_location"; return DW_DLV_OK; case DW_AT_byte_stride: *s_out = "DW_AT_byte_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x51. DW_AT_stride */ case DW_AT_entry_pc: *s_out = "DW_AT_entry_pc"; return DW_DLV_OK; case DW_AT_use_UTF8: *s_out = "DW_AT_use_UTF8"; return DW_DLV_OK; case DW_AT_extension: *s_out = "DW_AT_extension"; return DW_DLV_OK; case DW_AT_ranges: *s_out = "DW_AT_ranges"; return DW_DLV_OK; case DW_AT_trampoline: *s_out = "DW_AT_trampoline"; return DW_DLV_OK; case DW_AT_call_column: *s_out = "DW_AT_call_column"; return DW_DLV_OK; case DW_AT_call_file: *s_out = "DW_AT_call_file"; return DW_DLV_OK; case DW_AT_call_line: *s_out = "DW_AT_call_line"; return DW_DLV_OK; case DW_AT_description: *s_out = "DW_AT_description"; return DW_DLV_OK; case DW_AT_binary_scale: *s_out = "DW_AT_binary_scale"; return DW_DLV_OK; case DW_AT_decimal_scale: *s_out = "DW_AT_decimal_scale"; return DW_DLV_OK; case DW_AT_small: *s_out = "DW_AT_small"; return DW_DLV_OK; case DW_AT_decimal_sign: *s_out = "DW_AT_decimal_sign"; return DW_DLV_OK; case DW_AT_digit_count: *s_out = "DW_AT_digit_count"; return DW_DLV_OK; case DW_AT_picture_string: *s_out = "DW_AT_picture_string"; return DW_DLV_OK; case DW_AT_mutable: *s_out = "DW_AT_mutable"; return DW_DLV_OK; case DW_AT_threads_scaled: *s_out = "DW_AT_threads_scaled"; return DW_DLV_OK; case DW_AT_explicit: *s_out = "DW_AT_explicit"; return DW_DLV_OK; case DW_AT_object_pointer: *s_out = "DW_AT_object_pointer"; return DW_DLV_OK; case DW_AT_endianity: *s_out = "DW_AT_endianity"; return DW_DLV_OK; case DW_AT_elemental: *s_out = "DW_AT_elemental"; return DW_DLV_OK; case DW_AT_pure: *s_out = "DW_AT_pure"; return DW_DLV_OK; case DW_AT_recursive: *s_out = "DW_AT_recursive"; return DW_DLV_OK; case DW_AT_signature: *s_out = "DW_AT_signature"; return DW_DLV_OK; case DW_AT_main_subprogram: *s_out = "DW_AT_main_subprogram"; return DW_DLV_OK; case DW_AT_data_bit_offset: *s_out = "DW_AT_data_bit_offset"; return DW_DLV_OK; case DW_AT_const_expr: *s_out = "DW_AT_const_expr"; return DW_DLV_OK; case DW_AT_enum_class: *s_out = "DW_AT_enum_class"; return DW_DLV_OK; case DW_AT_linkage_name: *s_out = "DW_AT_linkage_name"; return DW_DLV_OK; case DW_AT_string_length_bit_size: *s_out = "DW_AT_string_length_bit_size"; return DW_DLV_OK; case DW_AT_string_length_byte_size: *s_out = "DW_AT_string_length_byte_size"; return DW_DLV_OK; case DW_AT_rank: *s_out = "DW_AT_rank"; return DW_DLV_OK; case DW_AT_str_offsets_base: *s_out = "DW_AT_str_offsets_base"; return DW_DLV_OK; case DW_AT_addr_base: *s_out = "DW_AT_addr_base"; return DW_DLV_OK; case DW_AT_rnglists_base: *s_out = "DW_AT_rnglists_base"; return DW_DLV_OK; case DW_AT_dwo_id: *s_out = "DW_AT_dwo_id"; return DW_DLV_OK; case DW_AT_dwo_name: *s_out = "DW_AT_dwo_name"; return DW_DLV_OK; case DW_AT_reference: *s_out = "DW_AT_reference"; return DW_DLV_OK; case DW_AT_rvalue_reference: *s_out = "DW_AT_rvalue_reference"; return DW_DLV_OK; case DW_AT_macros: *s_out = "DW_AT_macros"; return DW_DLV_OK; case DW_AT_call_all_calls: *s_out = "DW_AT_call_all_calls"; return DW_DLV_OK; case DW_AT_call_all_source_calls: *s_out = "DW_AT_call_all_source_calls"; return DW_DLV_OK; case DW_AT_call_all_tail_calls: *s_out = "DW_AT_call_all_tail_calls"; return DW_DLV_OK; case DW_AT_call_return_pc: *s_out = "DW_AT_call_return_pc"; return DW_DLV_OK; case DW_AT_call_value: *s_out = "DW_AT_call_value"; return DW_DLV_OK; case DW_AT_call_origin: *s_out = "DW_AT_call_origin"; return DW_DLV_OK; case DW_AT_call_parameter: *s_out = "DW_AT_call_parameter"; return DW_DLV_OK; case DW_AT_call_pc: *s_out = "DW_AT_call_pc"; return DW_DLV_OK; case DW_AT_call_tail_call: *s_out = "DW_AT_call_tail_call"; return DW_DLV_OK; case DW_AT_call_target: *s_out = "DW_AT_call_target"; return DW_DLV_OK; case DW_AT_call_target_clobbered: *s_out = "DW_AT_call_target_clobbered"; return DW_DLV_OK; case DW_AT_call_data_location: *s_out = "DW_AT_call_data_location"; return DW_DLV_OK; case DW_AT_call_data_value: *s_out = "DW_AT_call_data_value"; return DW_DLV_OK; case DW_AT_noreturn: *s_out = "DW_AT_noreturn"; return DW_DLV_OK; case DW_AT_alignment: *s_out = "DW_AT_alignment"; return DW_DLV_OK; case DW_AT_export_symbols: *s_out = "DW_AT_export_symbols"; return DW_DLV_OK; case DW_AT_deleted: *s_out = "DW_AT_deleted"; return DW_DLV_OK; case DW_AT_defaulted: *s_out = "DW_AT_defaulted"; return DW_DLV_OK; case DW_AT_loclists_base: *s_out = "DW_AT_loclists_base"; return DW_DLV_OK; case DW_AT_HP_block_index: *s_out = "DW_AT_HP_block_index"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2000. DW_AT_lo_user */ case DW_AT_MIPS_fde: *s_out = "DW_AT_MIPS_fde"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2001. DW_AT_HP_unmodifiable */ /* Skipping alternate spelling of value 0x2001. DW_AT_CPQ_discontig_ranges */ case DW_AT_MIPS_loop_begin: *s_out = "DW_AT_MIPS_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2002. DW_AT_CPQ_semantic_events */ case DW_AT_MIPS_tail_loop_begin: *s_out = "DW_AT_MIPS_tail_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2003. DW_AT_CPQ_split_lifetimes_var */ case DW_AT_MIPS_epilog_begin: *s_out = "DW_AT_MIPS_epilog_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2004. DW_AT_CPQ_split_lifetimes_rtn */ case DW_AT_MIPS_loop_unroll_factor: *s_out = "DW_AT_MIPS_loop_unroll_factor"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2005. DW_AT_CPQ_prologue_length */ case DW_AT_MIPS_software_pipeline_depth: *s_out = "DW_AT_MIPS_software_pipeline_depth"; return DW_DLV_OK; case DW_AT_MIPS_linkage_name: *s_out = "DW_AT_MIPS_linkage_name"; return DW_DLV_OK; case DW_AT_MIPS_stride: *s_out = "DW_AT_MIPS_stride"; return DW_DLV_OK; case DW_AT_MIPS_abstract_name: *s_out = "DW_AT_MIPS_abstract_name"; return DW_DLV_OK; case DW_AT_MIPS_clone_origin: *s_out = "DW_AT_MIPS_clone_origin"; return DW_DLV_OK; case DW_AT_MIPS_has_inlines: *s_out = "DW_AT_MIPS_has_inlines"; return DW_DLV_OK; case DW_AT_MIPS_stride_byte: *s_out = "DW_AT_MIPS_stride_byte"; return DW_DLV_OK; case DW_AT_MIPS_stride_elem: *s_out = "DW_AT_MIPS_stride_elem"; return DW_DLV_OK; case DW_AT_MIPS_ptr_dopetype: *s_out = "DW_AT_MIPS_ptr_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_allocatable_dopetype: *s_out = "DW_AT_MIPS_allocatable_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_assumed_shape_dopetype: *s_out = "DW_AT_MIPS_assumed_shape_dopetype"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2010. DW_AT_HP_actuals_stmt_list */ case DW_AT_MIPS_assumed_size: *s_out = "DW_AT_MIPS_assumed_size"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2011. DW_AT_HP_proc_per_section */ case DW_AT_HP_raw_data_ptr: *s_out = "DW_AT_HP_raw_data_ptr"; return DW_DLV_OK; case DW_AT_HP_pass_by_reference: *s_out = "DW_AT_HP_pass_by_reference"; return DW_DLV_OK; case DW_AT_HP_opt_level: *s_out = "DW_AT_HP_opt_level"; return DW_DLV_OK; case DW_AT_HP_prof_version_id: *s_out = "DW_AT_HP_prof_version_id"; return DW_DLV_OK; case DW_AT_HP_opt_flags: *s_out = "DW_AT_HP_opt_flags"; return DW_DLV_OK; case DW_AT_HP_cold_region_low_pc: *s_out = "DW_AT_HP_cold_region_low_pc"; return DW_DLV_OK; case DW_AT_HP_cold_region_high_pc: *s_out = "DW_AT_HP_cold_region_high_pc"; return DW_DLV_OK; case DW_AT_HP_all_variables_modifiable: *s_out = "DW_AT_HP_all_variables_modifiable"; return DW_DLV_OK; case DW_AT_HP_linkage_name: *s_out = "DW_AT_HP_linkage_name"; return DW_DLV_OK; case DW_AT_HP_prof_flags: *s_out = "DW_AT_HP_prof_flags"; return DW_DLV_OK; case DW_AT_INTEL_other_endian: *s_out = "DW_AT_INTEL_other_endian"; return DW_DLV_OK; case DW_AT_sf_names: *s_out = "DW_AT_sf_names"; return DW_DLV_OK; case DW_AT_src_info: *s_out = "DW_AT_src_info"; return DW_DLV_OK; case DW_AT_mac_info: *s_out = "DW_AT_mac_info"; return DW_DLV_OK; case DW_AT_src_coords: *s_out = "DW_AT_src_coords"; return DW_DLV_OK; case DW_AT_body_begin: *s_out = "DW_AT_body_begin"; return DW_DLV_OK; case DW_AT_body_end: *s_out = "DW_AT_body_end"; return DW_DLV_OK; case DW_AT_GNU_vector: *s_out = "DW_AT_GNU_vector"; return DW_DLV_OK; case DW_AT_GNU_guarded_by: *s_out = "DW_AT_GNU_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded_by: *s_out = "DW_AT_GNU_pt_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_guarded: *s_out = "DW_AT_GNU_guarded"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded: *s_out = "DW_AT_GNU_pt_guarded"; return DW_DLV_OK; case DW_AT_GNU_locks_excluded: *s_out = "DW_AT_GNU_locks_excluded"; return DW_DLV_OK; case DW_AT_GNU_exclusive_locks_required: *s_out = "DW_AT_GNU_exclusive_locks_required"; return DW_DLV_OK; case DW_AT_GNU_shared_locks_required: *s_out = "DW_AT_GNU_shared_locks_required"; return DW_DLV_OK; case DW_AT_GNU_odr_signature: *s_out = "DW_AT_GNU_odr_signature"; return DW_DLV_OK; case DW_AT_GNU_template_name: *s_out = "DW_AT_GNU_template_name"; return DW_DLV_OK; case DW_AT_GNU_call_site_value: *s_out = "DW_AT_GNU_call_site_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_data_value: *s_out = "DW_AT_GNU_call_site_data_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_target: *s_out = "DW_AT_GNU_call_site_target"; return DW_DLV_OK; case DW_AT_GNU_call_site_target_clobbered: *s_out = "DW_AT_GNU_call_site_target_clobbered"; return DW_DLV_OK; case DW_AT_GNU_tail_call: *s_out = "DW_AT_GNU_tail_call"; return DW_DLV_OK; case DW_AT_GNU_all_tail_call_sites: *s_out = "DW_AT_GNU_all_tail_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_call_sites: *s_out = "DW_AT_GNU_all_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_source_call_sites: *s_out = "DW_AT_GNU_all_source_call_sites"; return DW_DLV_OK; case DW_AT_GNU_macros: *s_out = "DW_AT_GNU_macros"; return DW_DLV_OK; case DW_AT_GNU_dwo_name: *s_out = "DW_AT_GNU_dwo_name"; return DW_DLV_OK; case DW_AT_GNU_dwo_id: *s_out = "DW_AT_GNU_dwo_id"; return DW_DLV_OK; case DW_AT_GNU_ranges_base: *s_out = "DW_AT_GNU_ranges_base"; return DW_DLV_OK; case DW_AT_GNU_addr_base: *s_out = "DW_AT_GNU_addr_base"; return DW_DLV_OK; case DW_AT_GNU_pubnames: *s_out = "DW_AT_GNU_pubnames"; return DW_DLV_OK; case DW_AT_GNU_pubtypes: *s_out = "DW_AT_GNU_pubtypes"; return DW_DLV_OK; case DW_AT_GNU_discriminator: *s_out = "DW_AT_GNU_discriminator"; return DW_DLV_OK; case DW_AT_SUN_template: *s_out = "DW_AT_SUN_template"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2201. DW_AT_VMS_rtnbeg_pd_address */ case DW_AT_SUN_alignment: *s_out = "DW_AT_SUN_alignment"; return DW_DLV_OK; case DW_AT_SUN_vtable: *s_out = "DW_AT_SUN_vtable"; return DW_DLV_OK; case DW_AT_SUN_count_guarantee: *s_out = "DW_AT_SUN_count_guarantee"; return DW_DLV_OK; case DW_AT_SUN_command_line: *s_out = "DW_AT_SUN_command_line"; return DW_DLV_OK; case DW_AT_SUN_vbase: *s_out = "DW_AT_SUN_vbase"; return DW_DLV_OK; case DW_AT_SUN_compile_options: *s_out = "DW_AT_SUN_compile_options"; return DW_DLV_OK; case DW_AT_SUN_language: *s_out = "DW_AT_SUN_language"; return DW_DLV_OK; case DW_AT_SUN_browser_file: *s_out = "DW_AT_SUN_browser_file"; return DW_DLV_OK; case DW_AT_SUN_vtable_abi: *s_out = "DW_AT_SUN_vtable_abi"; return DW_DLV_OK; case DW_AT_SUN_func_offsets: *s_out = "DW_AT_SUN_func_offsets"; return DW_DLV_OK; case DW_AT_SUN_cf_kind: *s_out = "DW_AT_SUN_cf_kind"; return DW_DLV_OK; case DW_AT_SUN_vtable_index: *s_out = "DW_AT_SUN_vtable_index"; return DW_DLV_OK; case DW_AT_SUN_omp_tpriv_addr: *s_out = "DW_AT_SUN_omp_tpriv_addr"; return DW_DLV_OK; case DW_AT_SUN_omp_child_func: *s_out = "DW_AT_SUN_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_func_offset: *s_out = "DW_AT_SUN_func_offset"; return DW_DLV_OK; case DW_AT_SUN_memop_type_ref: *s_out = "DW_AT_SUN_memop_type_ref"; return DW_DLV_OK; case DW_AT_SUN_profile_id: *s_out = "DW_AT_SUN_profile_id"; return DW_DLV_OK; case DW_AT_SUN_memop_signature: *s_out = "DW_AT_SUN_memop_signature"; return DW_DLV_OK; case DW_AT_SUN_obj_dir: *s_out = "DW_AT_SUN_obj_dir"; return DW_DLV_OK; case DW_AT_SUN_obj_file: *s_out = "DW_AT_SUN_obj_file"; return DW_DLV_OK; case DW_AT_SUN_original_name: *s_out = "DW_AT_SUN_original_name"; return DW_DLV_OK; case DW_AT_SUN_hwcprof_signature: *s_out = "DW_AT_SUN_hwcprof_signature"; return DW_DLV_OK; case DW_AT_SUN_amd64_parmdump: *s_out = "DW_AT_SUN_amd64_parmdump"; return DW_DLV_OK; case DW_AT_SUN_part_link_name: *s_out = "DW_AT_SUN_part_link_name"; return DW_DLV_OK; case DW_AT_SUN_link_name: *s_out = "DW_AT_SUN_link_name"; return DW_DLV_OK; case DW_AT_SUN_pass_with_const: *s_out = "DW_AT_SUN_pass_with_const"; return DW_DLV_OK; case DW_AT_SUN_return_with_const: *s_out = "DW_AT_SUN_return_with_const"; return DW_DLV_OK; case DW_AT_SUN_import_by_name: *s_out = "DW_AT_SUN_import_by_name"; return DW_DLV_OK; case DW_AT_SUN_f90_pointer: *s_out = "DW_AT_SUN_f90_pointer"; return DW_DLV_OK; case DW_AT_SUN_pass_by_ref: *s_out = "DW_AT_SUN_pass_by_ref"; return DW_DLV_OK; case DW_AT_SUN_f90_allocatable: *s_out = "DW_AT_SUN_f90_allocatable"; return DW_DLV_OK; case DW_AT_SUN_f90_assumed_shape_array: *s_out = "DW_AT_SUN_f90_assumed_shape_array"; return DW_DLV_OK; case DW_AT_SUN_c_vla: *s_out = "DW_AT_SUN_c_vla"; return DW_DLV_OK; case DW_AT_SUN_return_value_ptr: *s_out = "DW_AT_SUN_return_value_ptr"; return DW_DLV_OK; case DW_AT_SUN_dtor_start: *s_out = "DW_AT_SUN_dtor_start"; return DW_DLV_OK; case DW_AT_SUN_dtor_length: *s_out = "DW_AT_SUN_dtor_length"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_initial: *s_out = "DW_AT_SUN_dtor_state_initial"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_final: *s_out = "DW_AT_SUN_dtor_state_final"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_deltas: *s_out = "DW_AT_SUN_dtor_state_deltas"; return DW_DLV_OK; case DW_AT_SUN_import_by_lname: *s_out = "DW_AT_SUN_import_by_lname"; return DW_DLV_OK; case DW_AT_SUN_f90_use_only: *s_out = "DW_AT_SUN_f90_use_only"; return DW_DLV_OK; case DW_AT_SUN_namelist_spec: *s_out = "DW_AT_SUN_namelist_spec"; return DW_DLV_OK; case DW_AT_SUN_is_omp_child_func: *s_out = "DW_AT_SUN_is_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_fortran_main_alias: *s_out = "DW_AT_SUN_fortran_main_alias"; return DW_DLV_OK; case DW_AT_SUN_fortran_based: *s_out = "DW_AT_SUN_fortran_based"; return DW_DLV_OK; case DW_AT_ALTIUM_loclist: *s_out = "DW_AT_ALTIUM_loclist"; return DW_DLV_OK; case DW_AT_use_GNAT_descriptive_type: *s_out = "DW_AT_use_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNAT_descriptive_type: *s_out = "DW_AT_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNU_numerator: *s_out = "DW_AT_GNU_numerator"; return DW_DLV_OK; case DW_AT_GNU_denominator: *s_out = "DW_AT_GNU_denominator"; return DW_DLV_OK; case DW_AT_GNU_bias: *s_out = "DW_AT_GNU_bias"; return DW_DLV_OK; case DW_AT_go_kind: *s_out = "DW_AT_go_kind"; return DW_DLV_OK; case DW_AT_go_key: *s_out = "DW_AT_go_key"; return DW_DLV_OK; case DW_AT_go_elem: *s_out = "DW_AT_go_elem"; return DW_DLV_OK; case DW_AT_go_embedded_field: *s_out = "DW_AT_go_embedded_field"; return DW_DLV_OK; case DW_AT_go_runtime_type: *s_out = "DW_AT_go_runtime_type"; return DW_DLV_OK; case DW_AT_upc_threads_scaled: *s_out = "DW_AT_upc_threads_scaled"; return DW_DLV_OK; case DW_AT_PGI_lbase: *s_out = "DW_AT_PGI_lbase"; return DW_DLV_OK; case DW_AT_PGI_soffset: *s_out = "DW_AT_PGI_soffset"; return DW_DLV_OK; case DW_AT_PGI_lstride: *s_out = "DW_AT_PGI_lstride"; return DW_DLV_OK; case DW_AT_APPLE_optimized: *s_out = "DW_AT_APPLE_optimized"; return DW_DLV_OK; case DW_AT_APPLE_flags: *s_out = "DW_AT_APPLE_flags"; return DW_DLV_OK; case DW_AT_APPLE_isa: *s_out = "DW_AT_APPLE_isa"; return DW_DLV_OK; case DW_AT_APPLE_block: *s_out = "DW_AT_APPLE_block"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3fe4. DW_AT_APPLE_closure */ case DW_AT_APPLE_major_runtime_vers: *s_out = "DW_AT_APPLE_major_runtime_vers"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3fe5. DW_AT_APPLE_major_runtime_vers */ case DW_AT_APPLE_runtime_class: *s_out = "DW_AT_APPLE_runtime_class"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3fe6. DW_AT_APPLE_runtime_class */ case DW_AT_APPLE_omit_frame_ptr: *s_out = "DW_AT_APPLE_omit_frame_ptr"; return DW_DLV_OK; case DW_AT_hi_user: *s_out = "DW_AT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_OP_name (unsigned int val,const char ** s_out) { switch (val) { case DW_OP_addr: *s_out = "DW_OP_addr"; return DW_DLV_OK; case DW_OP_deref: *s_out = "DW_OP_deref"; return DW_DLV_OK; case DW_OP_const1u: *s_out = "DW_OP_const1u"; return DW_DLV_OK; case DW_OP_const1s: *s_out = "DW_OP_const1s"; return DW_DLV_OK; case DW_OP_const2u: *s_out = "DW_OP_const2u"; return DW_DLV_OK; case DW_OP_const2s: *s_out = "DW_OP_const2s"; return DW_DLV_OK; case DW_OP_const4u: *s_out = "DW_OP_const4u"; return DW_DLV_OK; case DW_OP_const4s: *s_out = "DW_OP_const4s"; return DW_DLV_OK; case DW_OP_const8u: *s_out = "DW_OP_const8u"; return DW_DLV_OK; case DW_OP_const8s: *s_out = "DW_OP_const8s"; return DW_DLV_OK; case DW_OP_constu: *s_out = "DW_OP_constu"; return DW_DLV_OK; case DW_OP_consts: *s_out = "DW_OP_consts"; return DW_DLV_OK; case DW_OP_dup: *s_out = "DW_OP_dup"; return DW_DLV_OK; case DW_OP_drop: *s_out = "DW_OP_drop"; return DW_DLV_OK; case DW_OP_over: *s_out = "DW_OP_over"; return DW_DLV_OK; case DW_OP_pick: *s_out = "DW_OP_pick"; return DW_DLV_OK; case DW_OP_swap: *s_out = "DW_OP_swap"; return DW_DLV_OK; case DW_OP_rot: *s_out = "DW_OP_rot"; return DW_DLV_OK; case DW_OP_xderef: *s_out = "DW_OP_xderef"; return DW_DLV_OK; case DW_OP_abs: *s_out = "DW_OP_abs"; return DW_DLV_OK; case DW_OP_and: *s_out = "DW_OP_and"; return DW_DLV_OK; case DW_OP_div: *s_out = "DW_OP_div"; return DW_DLV_OK; case DW_OP_minus: *s_out = "DW_OP_minus"; return DW_DLV_OK; case DW_OP_mod: *s_out = "DW_OP_mod"; return DW_DLV_OK; case DW_OP_mul: *s_out = "DW_OP_mul"; return DW_DLV_OK; case DW_OP_neg: *s_out = "DW_OP_neg"; return DW_DLV_OK; case DW_OP_not: *s_out = "DW_OP_not"; return DW_DLV_OK; case DW_OP_or: *s_out = "DW_OP_or"; return DW_DLV_OK; case DW_OP_plus: *s_out = "DW_OP_plus"; return DW_DLV_OK; case DW_OP_plus_uconst: *s_out = "DW_OP_plus_uconst"; return DW_DLV_OK; case DW_OP_shl: *s_out = "DW_OP_shl"; return DW_DLV_OK; case DW_OP_shr: *s_out = "DW_OP_shr"; return DW_DLV_OK; case DW_OP_shra: *s_out = "DW_OP_shra"; return DW_DLV_OK; case DW_OP_xor: *s_out = "DW_OP_xor"; return DW_DLV_OK; case DW_OP_bra: *s_out = "DW_OP_bra"; return DW_DLV_OK; case DW_OP_eq: *s_out = "DW_OP_eq"; return DW_DLV_OK; case DW_OP_ge: *s_out = "DW_OP_ge"; return DW_DLV_OK; case DW_OP_gt: *s_out = "DW_OP_gt"; return DW_DLV_OK; case DW_OP_le: *s_out = "DW_OP_le"; return DW_DLV_OK; case DW_OP_lt: *s_out = "DW_OP_lt"; return DW_DLV_OK; case DW_OP_ne: *s_out = "DW_OP_ne"; return DW_DLV_OK; case DW_OP_skip: *s_out = "DW_OP_skip"; return DW_DLV_OK; case DW_OP_lit0: *s_out = "DW_OP_lit0"; return DW_DLV_OK; case DW_OP_lit1: *s_out = "DW_OP_lit1"; return DW_DLV_OK; case DW_OP_lit2: *s_out = "DW_OP_lit2"; return DW_DLV_OK; case DW_OP_lit3: *s_out = "DW_OP_lit3"; return DW_DLV_OK; case DW_OP_lit4: *s_out = "DW_OP_lit4"; return DW_DLV_OK; case DW_OP_lit5: *s_out = "DW_OP_lit5"; return DW_DLV_OK; case DW_OP_lit6: *s_out = "DW_OP_lit6"; return DW_DLV_OK; case DW_OP_lit7: *s_out = "DW_OP_lit7"; return DW_DLV_OK; case DW_OP_lit8: *s_out = "DW_OP_lit8"; return DW_DLV_OK; case DW_OP_lit9: *s_out = "DW_OP_lit9"; return DW_DLV_OK; case DW_OP_lit10: *s_out = "DW_OP_lit10"; return DW_DLV_OK; case DW_OP_lit11: *s_out = "DW_OP_lit11"; return DW_DLV_OK; case DW_OP_lit12: *s_out = "DW_OP_lit12"; return DW_DLV_OK; case DW_OP_lit13: *s_out = "DW_OP_lit13"; return DW_DLV_OK; case DW_OP_lit14: *s_out = "DW_OP_lit14"; return DW_DLV_OK; case DW_OP_lit15: *s_out = "DW_OP_lit15"; return DW_DLV_OK; case DW_OP_lit16: *s_out = "DW_OP_lit16"; return DW_DLV_OK; case DW_OP_lit17: *s_out = "DW_OP_lit17"; return DW_DLV_OK; case DW_OP_lit18: *s_out = "DW_OP_lit18"; return DW_DLV_OK; case DW_OP_lit19: *s_out = "DW_OP_lit19"; return DW_DLV_OK; case DW_OP_lit20: *s_out = "DW_OP_lit20"; return DW_DLV_OK; case DW_OP_lit21: *s_out = "DW_OP_lit21"; return DW_DLV_OK; case DW_OP_lit22: *s_out = "DW_OP_lit22"; return DW_DLV_OK; case DW_OP_lit23: *s_out = "DW_OP_lit23"; return DW_DLV_OK; case DW_OP_lit24: *s_out = "DW_OP_lit24"; return DW_DLV_OK; case DW_OP_lit25: *s_out = "DW_OP_lit25"; return DW_DLV_OK; case DW_OP_lit26: *s_out = "DW_OP_lit26"; return DW_DLV_OK; case DW_OP_lit27: *s_out = "DW_OP_lit27"; return DW_DLV_OK; case DW_OP_lit28: *s_out = "DW_OP_lit28"; return DW_DLV_OK; case DW_OP_lit29: *s_out = "DW_OP_lit29"; return DW_DLV_OK; case DW_OP_lit30: *s_out = "DW_OP_lit30"; return DW_DLV_OK; case DW_OP_lit31: *s_out = "DW_OP_lit31"; return DW_DLV_OK; case DW_OP_reg0: *s_out = "DW_OP_reg0"; return DW_DLV_OK; case DW_OP_reg1: *s_out = "DW_OP_reg1"; return DW_DLV_OK; case DW_OP_reg2: *s_out = "DW_OP_reg2"; return DW_DLV_OK; case DW_OP_reg3: *s_out = "DW_OP_reg3"; return DW_DLV_OK; case DW_OP_reg4: *s_out = "DW_OP_reg4"; return DW_DLV_OK; case DW_OP_reg5: *s_out = "DW_OP_reg5"; return DW_DLV_OK; case DW_OP_reg6: *s_out = "DW_OP_reg6"; return DW_DLV_OK; case DW_OP_reg7: *s_out = "DW_OP_reg7"; return DW_DLV_OK; case DW_OP_reg8: *s_out = "DW_OP_reg8"; return DW_DLV_OK; case DW_OP_reg9: *s_out = "DW_OP_reg9"; return DW_DLV_OK; case DW_OP_reg10: *s_out = "DW_OP_reg10"; return DW_DLV_OK; case DW_OP_reg11: *s_out = "DW_OP_reg11"; return DW_DLV_OK; case DW_OP_reg12: *s_out = "DW_OP_reg12"; return DW_DLV_OK; case DW_OP_reg13: *s_out = "DW_OP_reg13"; return DW_DLV_OK; case DW_OP_reg14: *s_out = "DW_OP_reg14"; return DW_DLV_OK; case DW_OP_reg15: *s_out = "DW_OP_reg15"; return DW_DLV_OK; case DW_OP_reg16: *s_out = "DW_OP_reg16"; return DW_DLV_OK; case DW_OP_reg17: *s_out = "DW_OP_reg17"; return DW_DLV_OK; case DW_OP_reg18: *s_out = "DW_OP_reg18"; return DW_DLV_OK; case DW_OP_reg19: *s_out = "DW_OP_reg19"; return DW_DLV_OK; case DW_OP_reg20: *s_out = "DW_OP_reg20"; return DW_DLV_OK; case DW_OP_reg21: *s_out = "DW_OP_reg21"; return DW_DLV_OK; case DW_OP_reg22: *s_out = "DW_OP_reg22"; return DW_DLV_OK; case DW_OP_reg23: *s_out = "DW_OP_reg23"; return DW_DLV_OK; case DW_OP_reg24: *s_out = "DW_OP_reg24"; return DW_DLV_OK; case DW_OP_reg25: *s_out = "DW_OP_reg25"; return DW_DLV_OK; case DW_OP_reg26: *s_out = "DW_OP_reg26"; return DW_DLV_OK; case DW_OP_reg27: *s_out = "DW_OP_reg27"; return DW_DLV_OK; case DW_OP_reg28: *s_out = "DW_OP_reg28"; return DW_DLV_OK; case DW_OP_reg29: *s_out = "DW_OP_reg29"; return DW_DLV_OK; case DW_OP_reg30: *s_out = "DW_OP_reg30"; return DW_DLV_OK; case DW_OP_reg31: *s_out = "DW_OP_reg31"; return DW_DLV_OK; case DW_OP_breg0: *s_out = "DW_OP_breg0"; return DW_DLV_OK; case DW_OP_breg1: *s_out = "DW_OP_breg1"; return DW_DLV_OK; case DW_OP_breg2: *s_out = "DW_OP_breg2"; return DW_DLV_OK; case DW_OP_breg3: *s_out = "DW_OP_breg3"; return DW_DLV_OK; case DW_OP_breg4: *s_out = "DW_OP_breg4"; return DW_DLV_OK; case DW_OP_breg5: *s_out = "DW_OP_breg5"; return DW_DLV_OK; case DW_OP_breg6: *s_out = "DW_OP_breg6"; return DW_DLV_OK; case DW_OP_breg7: *s_out = "DW_OP_breg7"; return DW_DLV_OK; case DW_OP_breg8: *s_out = "DW_OP_breg8"; return DW_DLV_OK; case DW_OP_breg9: *s_out = "DW_OP_breg9"; return DW_DLV_OK; case DW_OP_breg10: *s_out = "DW_OP_breg10"; return DW_DLV_OK; case DW_OP_breg11: *s_out = "DW_OP_breg11"; return DW_DLV_OK; case DW_OP_breg12: *s_out = "DW_OP_breg12"; return DW_DLV_OK; case DW_OP_breg13: *s_out = "DW_OP_breg13"; return DW_DLV_OK; case DW_OP_breg14: *s_out = "DW_OP_breg14"; return DW_DLV_OK; case DW_OP_breg15: *s_out = "DW_OP_breg15"; return DW_DLV_OK; case DW_OP_breg16: *s_out = "DW_OP_breg16"; return DW_DLV_OK; case DW_OP_breg17: *s_out = "DW_OP_breg17"; return DW_DLV_OK; case DW_OP_breg18: *s_out = "DW_OP_breg18"; return DW_DLV_OK; case DW_OP_breg19: *s_out = "DW_OP_breg19"; return DW_DLV_OK; case DW_OP_breg20: *s_out = "DW_OP_breg20"; return DW_DLV_OK; case DW_OP_breg21: *s_out = "DW_OP_breg21"; return DW_DLV_OK; case DW_OP_breg22: *s_out = "DW_OP_breg22"; return DW_DLV_OK; case DW_OP_breg23: *s_out = "DW_OP_breg23"; return DW_DLV_OK; case DW_OP_breg24: *s_out = "DW_OP_breg24"; return DW_DLV_OK; case DW_OP_breg25: *s_out = "DW_OP_breg25"; return DW_DLV_OK; case DW_OP_breg26: *s_out = "DW_OP_breg26"; return DW_DLV_OK; case DW_OP_breg27: *s_out = "DW_OP_breg27"; return DW_DLV_OK; case DW_OP_breg28: *s_out = "DW_OP_breg28"; return DW_DLV_OK; case DW_OP_breg29: *s_out = "DW_OP_breg29"; return DW_DLV_OK; case DW_OP_breg30: *s_out = "DW_OP_breg30"; return DW_DLV_OK; case DW_OP_breg31: *s_out = "DW_OP_breg31"; return DW_DLV_OK; case DW_OP_regx: *s_out = "DW_OP_regx"; return DW_DLV_OK; case DW_OP_fbreg: *s_out = "DW_OP_fbreg"; return DW_DLV_OK; case DW_OP_bregx: *s_out = "DW_OP_bregx"; return DW_DLV_OK; case DW_OP_piece: *s_out = "DW_OP_piece"; return DW_DLV_OK; case DW_OP_deref_size: *s_out = "DW_OP_deref_size"; return DW_DLV_OK; case DW_OP_xderef_size: *s_out = "DW_OP_xderef_size"; return DW_DLV_OK; case DW_OP_nop: *s_out = "DW_OP_nop"; return DW_DLV_OK; case DW_OP_push_object_address: *s_out = "DW_OP_push_object_address"; return DW_DLV_OK; case DW_OP_call2: *s_out = "DW_OP_call2"; return DW_DLV_OK; case DW_OP_call4: *s_out = "DW_OP_call4"; return DW_DLV_OK; case DW_OP_call_ref: *s_out = "DW_OP_call_ref"; return DW_DLV_OK; case DW_OP_form_tls_address: *s_out = "DW_OP_form_tls_address"; return DW_DLV_OK; case DW_OP_call_frame_cfa: *s_out = "DW_OP_call_frame_cfa"; return DW_DLV_OK; case DW_OP_bit_piece: *s_out = "DW_OP_bit_piece"; return DW_DLV_OK; case DW_OP_implicit_value: *s_out = "DW_OP_implicit_value"; return DW_DLV_OK; case DW_OP_stack_value: *s_out = "DW_OP_stack_value"; return DW_DLV_OK; case DW_OP_implicit_pointer: *s_out = "DW_OP_implicit_pointer"; return DW_DLV_OK; case DW_OP_addrx: *s_out = "DW_OP_addrx"; return DW_DLV_OK; case DW_OP_constx: *s_out = "DW_OP_constx"; return DW_DLV_OK; case DW_OP_entry_value: *s_out = "DW_OP_entry_value"; return DW_DLV_OK; case DW_OP_const_type: *s_out = "DW_OP_const_type"; return DW_DLV_OK; case DW_OP_regval_type: *s_out = "DW_OP_regval_type"; return DW_DLV_OK; case DW_OP_deref_type: *s_out = "DW_OP_deref_type"; return DW_DLV_OK; case DW_OP_xderef_type: *s_out = "DW_OP_xderef_type"; return DW_DLV_OK; case DW_OP_convert: *s_out = "DW_OP_convert"; return DW_DLV_OK; case DW_OP_reinterpret: *s_out = "DW_OP_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_push_tls_address: *s_out = "DW_OP_GNU_push_tls_address"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xe0. DW_OP_lo_user */ /* Skipping alternate spelling of value 0xe0. DW_OP_HP_unknown */ case DW_OP_HP_is_value: *s_out = "DW_OP_HP_is_value"; return DW_DLV_OK; case DW_OP_HP_fltconst4: *s_out = "DW_OP_HP_fltconst4"; return DW_DLV_OK; case DW_OP_HP_fltconst8: *s_out = "DW_OP_HP_fltconst8"; return DW_DLV_OK; case DW_OP_HP_mod_range: *s_out = "DW_OP_HP_mod_range"; return DW_DLV_OK; case DW_OP_HP_unmod_range: *s_out = "DW_OP_HP_unmod_range"; return DW_DLV_OK; case DW_OP_HP_tls: *s_out = "DW_OP_HP_tls"; return DW_DLV_OK; case DW_OP_INTEL_bit_piece: *s_out = "DW_OP_INTEL_bit_piece"; return DW_DLV_OK; case DW_OP_GNU_uninit: *s_out = "DW_OP_GNU_uninit"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xf0. DW_OP_APPLE_uninit */ case DW_OP_GNU_encoded_addr: *s_out = "DW_OP_GNU_encoded_addr"; return DW_DLV_OK; case DW_OP_GNU_implicit_pointer: *s_out = "DW_OP_GNU_implicit_pointer"; return DW_DLV_OK; case DW_OP_GNU_entry_value: *s_out = "DW_OP_GNU_entry_value"; return DW_DLV_OK; case DW_OP_GNU_const_type: *s_out = "DW_OP_GNU_const_type"; return DW_DLV_OK; case DW_OP_GNU_regval_type: *s_out = "DW_OP_GNU_regval_type"; return DW_DLV_OK; case DW_OP_GNU_deref_type: *s_out = "DW_OP_GNU_deref_type"; return DW_DLV_OK; case DW_OP_GNU_convert: *s_out = "DW_OP_GNU_convert"; return DW_DLV_OK; case DW_OP_PGI_omp_thread_num: *s_out = "DW_OP_PGI_omp_thread_num"; return DW_DLV_OK; case DW_OP_GNU_reinterpret: *s_out = "DW_OP_GNU_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_parameter_ref: *s_out = "DW_OP_GNU_parameter_ref"; return DW_DLV_OK; case DW_OP_GNU_addr_index: *s_out = "DW_OP_GNU_addr_index"; return DW_DLV_OK; case DW_OP_GNU_const_index: *s_out = "DW_OP_GNU_const_index"; return DW_DLV_OK; case DW_OP_hi_user: *s_out = "DW_OP_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ATE_address: *s_out = "DW_ATE_address"; return DW_DLV_OK; case DW_ATE_boolean: *s_out = "DW_ATE_boolean"; return DW_DLV_OK; case DW_ATE_complex_float: *s_out = "DW_ATE_complex_float"; return DW_DLV_OK; case DW_ATE_float: *s_out = "DW_ATE_float"; return DW_DLV_OK; case DW_ATE_signed: *s_out = "DW_ATE_signed"; return DW_DLV_OK; case DW_ATE_signed_char: *s_out = "DW_ATE_signed_char"; return DW_DLV_OK; case DW_ATE_unsigned: *s_out = "DW_ATE_unsigned"; return DW_DLV_OK; case DW_ATE_unsigned_char: *s_out = "DW_ATE_unsigned_char"; return DW_DLV_OK; case DW_ATE_imaginary_float: *s_out = "DW_ATE_imaginary_float"; return DW_DLV_OK; case DW_ATE_packed_decimal: *s_out = "DW_ATE_packed_decimal"; return DW_DLV_OK; case DW_ATE_numeric_string: *s_out = "DW_ATE_numeric_string"; return DW_DLV_OK; case DW_ATE_edited: *s_out = "DW_ATE_edited"; return DW_DLV_OK; case DW_ATE_signed_fixed: *s_out = "DW_ATE_signed_fixed"; return DW_DLV_OK; case DW_ATE_unsigned_fixed: *s_out = "DW_ATE_unsigned_fixed"; return DW_DLV_OK; case DW_ATE_decimal_float: *s_out = "DW_ATE_decimal_float"; return DW_DLV_OK; case DW_ATE_UTF: *s_out = "DW_ATE_UTF"; return DW_DLV_OK; case DW_ATE_UCS: *s_out = "DW_ATE_UCS"; return DW_DLV_OK; case DW_ATE_ASCII: *s_out = "DW_ATE_ASCII"; return DW_DLV_OK; case DW_ATE_ALTIUM_fract: *s_out = "DW_ATE_ALTIUM_fract"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_ATE_lo_user */ /* Skipping alternate spelling of value 0x80. DW_ATE_HP_float80 */ case DW_ATE_ALTIUM_accum: *s_out = "DW_ATE_ALTIUM_accum"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x81. DW_ATE_HP_complex_float80 */ case DW_ATE_HP_float128: *s_out = "DW_ATE_HP_float128"; return DW_DLV_OK; case DW_ATE_HP_complex_float128: *s_out = "DW_ATE_HP_complex_float128"; return DW_DLV_OK; case DW_ATE_HP_floathpintel: *s_out = "DW_ATE_HP_floathpintel"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float80: *s_out = "DW_ATE_HP_imaginary_float80"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float128: *s_out = "DW_ATE_HP_imaginary_float128"; return DW_DLV_OK; case DW_ATE_SUN_interval_float: *s_out = "DW_ATE_SUN_interval_float"; return DW_DLV_OK; case DW_ATE_SUN_imaginary_float: *s_out = "DW_ATE_SUN_imaginary_float"; return DW_DLV_OK; case DW_ATE_hi_user: *s_out = "DW_ATE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DEFAULTED_name (unsigned int val,const char ** s_out) { switch (val) { case DW_DEFAULTED_no: *s_out = "DW_DEFAULTED_no"; return DW_DLV_OK; case DW_DEFAULTED_in_class: *s_out = "DW_DEFAULTED_in_class"; return DW_DLV_OK; case DW_DEFAULTED_out_of_class: *s_out = "DW_DEFAULTED_out_of_class"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_IDX_name (unsigned int val,const char ** s_out) { switch (val) { case DW_IDX_compile_unit: *s_out = "DW_IDX_compile_unit"; return DW_DLV_OK; case DW_IDX_type_unit: *s_out = "DW_IDX_type_unit"; return DW_DLV_OK; case DW_IDX_die_offset: *s_out = "DW_IDX_die_offset"; return DW_DLV_OK; case DW_IDX_parent: *s_out = "DW_IDX_parent"; return DW_DLV_OK; case DW_IDX_type_hash: *s_out = "DW_IDX_type_hash"; return DW_DLV_OK; case DW_IDX_hi_user: *s_out = "DW_IDX_hi_user"; return DW_DLV_OK; case DW_IDX_lo_user: *s_out = "DW_IDX_lo_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLEX_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LLEX_end_of_list_entry: *s_out = "DW_LLEX_end_of_list_entry"; return DW_DLV_OK; case DW_LLEX_base_address_selection_entry: *s_out = "DW_LLEX_base_address_selection_entry"; return DW_DLV_OK; case DW_LLEX_start_end_entry: *s_out = "DW_LLEX_start_end_entry"; return DW_DLV_OK; case DW_LLEX_start_length_entry: *s_out = "DW_LLEX_start_length_entry"; return DW_DLV_OK; case DW_LLEX_offset_pair_entry: *s_out = "DW_LLEX_offset_pair_entry"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LLE_end_of_list: *s_out = "DW_LLE_end_of_list"; return DW_DLV_OK; case DW_LLE_base_addressx: *s_out = "DW_LLE_base_addressx"; return DW_DLV_OK; case DW_LLE_startx_endx: *s_out = "DW_LLE_startx_endx"; return DW_DLV_OK; case DW_LLE_startx_length: *s_out = "DW_LLE_startx_length"; return DW_DLV_OK; case DW_LLE_offset_pair: *s_out = "DW_LLE_offset_pair"; return DW_DLV_OK; case DW_LLE_default_location: *s_out = "DW_LLE_default_location"; return DW_DLV_OK; case DW_LLE_base_address: *s_out = "DW_LLE_base_address"; return DW_DLV_OK; case DW_LLE_start_end: *s_out = "DW_LLE_start_end"; return DW_DLV_OK; case DW_LLE_start_length: *s_out = "DW_LLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_RLE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_RLE_end_of_list: *s_out = "DW_RLE_end_of_list"; return DW_DLV_OK; case DW_RLE_base_addressx: *s_out = "DW_RLE_base_addressx"; return DW_DLV_OK; case DW_RLE_startx_endx: *s_out = "DW_RLE_startx_endx"; return DW_DLV_OK; case DW_RLE_startx_length: *s_out = "DW_RLE_startx_length"; return DW_DLV_OK; case DW_RLE_offset_pair: *s_out = "DW_RLE_offset_pair"; return DW_DLV_OK; case DW_RLE_base_address: *s_out = "DW_RLE_base_address"; return DW_DLV_OK; case DW_RLE_start_end: *s_out = "DW_RLE_start_end"; return DW_DLV_OK; case DW_RLE_start_length: *s_out = "DW_RLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_UT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_UT_compile: *s_out = "DW_UT_compile"; return DW_DLV_OK; case DW_UT_type: *s_out = "DW_UT_type"; return DW_DLV_OK; case DW_UT_partial: *s_out = "DW_UT_partial"; return DW_DLV_OK; case DW_UT_skeleton: *s_out = "DW_UT_skeleton"; return DW_DLV_OK; case DW_UT_split_compile: *s_out = "DW_UT_split_compile"; return DW_DLV_OK; case DW_UT_split_type: *s_out = "DW_UT_split_type"; return DW_DLV_OK; case DW_UT_lo_user: *s_out = "DW_UT_lo_user"; return DW_DLV_OK; case DW_UT_hi_user: *s_out = "DW_UT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_SECT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_SECT_INFO: *s_out = "DW_SECT_INFO"; return DW_DLV_OK; case DW_SECT_TYPES: *s_out = "DW_SECT_TYPES"; return DW_DLV_OK; case DW_SECT_ABBREV: *s_out = "DW_SECT_ABBREV"; return DW_DLV_OK; case DW_SECT_LINE: *s_out = "DW_SECT_LINE"; return DW_DLV_OK; case DW_SECT_LOCLISTS: *s_out = "DW_SECT_LOCLISTS"; return DW_DLV_OK; case DW_SECT_STR_OFFSETS: *s_out = "DW_SECT_STR_OFFSETS"; return DW_DLV_OK; case DW_SECT_MACRO: *s_out = "DW_SECT_MACRO"; return DW_DLV_OK; case DW_SECT_RNGLISTS: *s_out = "DW_SECT_RNGLISTS"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_DS_unsigned: *s_out = "DW_DS_unsigned"; return DW_DLV_OK; case DW_DS_leading_overpunch: *s_out = "DW_DS_leading_overpunch"; return DW_DLV_OK; case DW_DS_trailing_overpunch: *s_out = "DW_DS_trailing_overpunch"; return DW_DLV_OK; case DW_DS_leading_separate: *s_out = "DW_DS_leading_separate"; return DW_DLV_OK; case DW_DS_trailing_separate: *s_out = "DW_DS_trailing_separate"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_END_name (unsigned int val,const char ** s_out) { switch (val) { case DW_END_default: *s_out = "DW_END_default"; return DW_DLV_OK; case DW_END_big: *s_out = "DW_END_big"; return DW_DLV_OK; case DW_END_little: *s_out = "DW_END_little"; return DW_DLV_OK; case DW_END_lo_user: *s_out = "DW_END_lo_user"; return DW_DLV_OK; case DW_END_hi_user: *s_out = "DW_END_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATCF_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ATCF_lo_user: *s_out = "DW_ATCF_lo_user"; return DW_DLV_OK; case DW_ATCF_SUN_mop_bitfield: *s_out = "DW_ATCF_SUN_mop_bitfield"; return DW_DLV_OK; case DW_ATCF_SUN_mop_spill: *s_out = "DW_ATCF_SUN_mop_spill"; return DW_DLV_OK; case DW_ATCF_SUN_mop_scopy: *s_out = "DW_ATCF_SUN_mop_scopy"; return DW_DLV_OK; case DW_ATCF_SUN_func_start: *s_out = "DW_ATCF_SUN_func_start"; return DW_DLV_OK; case DW_ATCF_SUN_end_ctors: *s_out = "DW_ATCF_SUN_end_ctors"; return DW_DLV_OK; case DW_ATCF_SUN_branch_target: *s_out = "DW_ATCF_SUN_branch_target"; return DW_DLV_OK; case DW_ATCF_SUN_mop_stack_probe: *s_out = "DW_ATCF_SUN_mop_stack_probe"; return DW_DLV_OK; case DW_ATCF_SUN_func_epilog: *s_out = "DW_ATCF_SUN_func_epilog"; return DW_DLV_OK; case DW_ATCF_hi_user: *s_out = "DW_ATCF_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ACCESS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ACCESS_public: *s_out = "DW_ACCESS_public"; return DW_DLV_OK; case DW_ACCESS_protected: *s_out = "DW_ACCESS_protected"; return DW_DLV_OK; case DW_ACCESS_private: *s_out = "DW_ACCESS_private"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_VIS_local: *s_out = "DW_VIS_local"; return DW_DLV_OK; case DW_VIS_exported: *s_out = "DW_VIS_exported"; return DW_DLV_OK; case DW_VIS_qualified: *s_out = "DW_VIS_qualified"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIRTUALITY_name (unsigned int val,const char ** s_out) { switch (val) { case DW_VIRTUALITY_none: *s_out = "DW_VIRTUALITY_none"; return DW_DLV_OK; case DW_VIRTUALITY_virtual: *s_out = "DW_VIRTUALITY_virtual"; return DW_DLV_OK; case DW_VIRTUALITY_pure_virtual: *s_out = "DW_VIRTUALITY_pure_virtual"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LANG_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LANG_C89: *s_out = "DW_LANG_C89"; return DW_DLV_OK; case DW_LANG_C: *s_out = "DW_LANG_C"; return DW_DLV_OK; case DW_LANG_Ada83: *s_out = "DW_LANG_Ada83"; return DW_DLV_OK; case DW_LANG_C_plus_plus: *s_out = "DW_LANG_C_plus_plus"; return DW_DLV_OK; case DW_LANG_Cobol74: *s_out = "DW_LANG_Cobol74"; return DW_DLV_OK; case DW_LANG_Cobol85: *s_out = "DW_LANG_Cobol85"; return DW_DLV_OK; case DW_LANG_Fortran77: *s_out = "DW_LANG_Fortran77"; return DW_DLV_OK; case DW_LANG_Fortran90: *s_out = "DW_LANG_Fortran90"; return DW_DLV_OK; case DW_LANG_Pascal83: *s_out = "DW_LANG_Pascal83"; return DW_DLV_OK; case DW_LANG_Modula2: *s_out = "DW_LANG_Modula2"; return DW_DLV_OK; case DW_LANG_Java: *s_out = "DW_LANG_Java"; return DW_DLV_OK; case DW_LANG_C99: *s_out = "DW_LANG_C99"; return DW_DLV_OK; case DW_LANG_Ada95: *s_out = "DW_LANG_Ada95"; return DW_DLV_OK; case DW_LANG_Fortran95: *s_out = "DW_LANG_Fortran95"; return DW_DLV_OK; case DW_LANG_PLI: *s_out = "DW_LANG_PLI"; return DW_DLV_OK; case DW_LANG_ObjC: *s_out = "DW_LANG_ObjC"; return DW_DLV_OK; case DW_LANG_ObjC_plus_plus: *s_out = "DW_LANG_ObjC_plus_plus"; return DW_DLV_OK; case DW_LANG_UPC: *s_out = "DW_LANG_UPC"; return DW_DLV_OK; case DW_LANG_D: *s_out = "DW_LANG_D"; return DW_DLV_OK; case DW_LANG_Python: *s_out = "DW_LANG_Python"; return DW_DLV_OK; case DW_LANG_OpenCL: *s_out = "DW_LANG_OpenCL"; return DW_DLV_OK; case DW_LANG_Go: *s_out = "DW_LANG_Go"; return DW_DLV_OK; case DW_LANG_Modula3: *s_out = "DW_LANG_Modula3"; return DW_DLV_OK; case DW_LANG_Haskel: *s_out = "DW_LANG_Haskel"; return DW_DLV_OK; case DW_LANG_C_plus_plus_03: *s_out = "DW_LANG_C_plus_plus_03"; return DW_DLV_OK; case DW_LANG_C_plus_plus_11: *s_out = "DW_LANG_C_plus_plus_11"; return DW_DLV_OK; case DW_LANG_OCaml: *s_out = "DW_LANG_OCaml"; return DW_DLV_OK; case DW_LANG_Rust: *s_out = "DW_LANG_Rust"; return DW_DLV_OK; case DW_LANG_C11: *s_out = "DW_LANG_C11"; return DW_DLV_OK; case DW_LANG_Swift: *s_out = "DW_LANG_Swift"; return DW_DLV_OK; case DW_LANG_Julia: *s_out = "DW_LANG_Julia"; return DW_DLV_OK; case DW_LANG_Dylan: *s_out = "DW_LANG_Dylan"; return DW_DLV_OK; case DW_LANG_C_plus_plus_14: *s_out = "DW_LANG_C_plus_plus_14"; return DW_DLV_OK; case DW_LANG_Fortran03: *s_out = "DW_LANG_Fortran03"; return DW_DLV_OK; case DW_LANG_Fortran08: *s_out = "DW_LANG_Fortran08"; return DW_DLV_OK; case DW_LANG_RenderScript: *s_out = "DW_LANG_RenderScript"; return DW_DLV_OK; case DW_LANG_BLISS: *s_out = "DW_LANG_BLISS"; return DW_DLV_OK; case DW_LANG_lo_user: *s_out = "DW_LANG_lo_user"; return DW_DLV_OK; case DW_LANG_Mips_Assembler: *s_out = "DW_LANG_Mips_Assembler"; return DW_DLV_OK; case DW_LANG_Upc: *s_out = "DW_LANG_Upc"; return DW_DLV_OK; case DW_LANG_SUN_Assembler: *s_out = "DW_LANG_SUN_Assembler"; return DW_DLV_OK; case DW_LANG_ALTIUM_Assembler: *s_out = "DW_LANG_ALTIUM_Assembler"; return DW_DLV_OK; case DW_LANG_hi_user: *s_out = "DW_LANG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ID_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ID_case_sensitive: *s_out = "DW_ID_case_sensitive"; return DW_DLV_OK; case DW_ID_up_case: *s_out = "DW_ID_up_case"; return DW_DLV_OK; case DW_ID_down_case: *s_out = "DW_ID_down_case"; return DW_DLV_OK; case DW_ID_case_insensitive: *s_out = "DW_ID_case_insensitive"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CC_name (unsigned int val,const char ** s_out) { switch (val) { case DW_CC_normal: *s_out = "DW_CC_normal"; return DW_DLV_OK; case DW_CC_program: *s_out = "DW_CC_program"; return DW_DLV_OK; case DW_CC_nocall: *s_out = "DW_CC_nocall"; return DW_DLV_OK; case DW_CC_pass_by_reference: *s_out = "DW_CC_pass_by_reference"; return DW_DLV_OK; case DW_CC_pass_by_value: *s_out = "DW_CC_pass_by_value"; return DW_DLV_OK; case DW_CC_lo_user: *s_out = "DW_CC_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x40. DW_CC_GNU_renesas_sh */ case DW_CC_GNU_borland_fastcall_i386: *s_out = "DW_CC_GNU_borland_fastcall_i386"; return DW_DLV_OK; case DW_CC_ALTIUM_interrupt: *s_out = "DW_CC_ALTIUM_interrupt"; return DW_DLV_OK; case DW_CC_ALTIUM_near_system_stack: *s_out = "DW_CC_ALTIUM_near_system_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_near_user_stack: *s_out = "DW_CC_ALTIUM_near_user_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_huge_user_stack: *s_out = "DW_CC_ALTIUM_huge_user_stack"; return DW_DLV_OK; case DW_CC_hi_user: *s_out = "DW_CC_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_INL_name (unsigned int val,const char ** s_out) { switch (val) { case DW_INL_not_inlined: *s_out = "DW_INL_not_inlined"; return DW_DLV_OK; case DW_INL_inlined: *s_out = "DW_INL_inlined"; return DW_DLV_OK; case DW_INL_declared_not_inlined: *s_out = "DW_INL_declared_not_inlined"; return DW_DLV_OK; case DW_INL_declared_inlined: *s_out = "DW_INL_declared_inlined"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ORD_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ORD_row_major: *s_out = "DW_ORD_row_major"; return DW_DLV_OK; case DW_ORD_col_major: *s_out = "DW_ORD_col_major"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DSC_name (unsigned int val,const char ** s_out) { switch (val) { case DW_DSC_label: *s_out = "DW_DSC_label"; return DW_DLV_OK; case DW_DSC_range: *s_out = "DW_DSC_range"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNCT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LNCT_path: *s_out = "DW_LNCT_path"; return DW_DLV_OK; case DW_LNCT_directory_index: *s_out = "DW_LNCT_directory_index"; return DW_DLV_OK; case DW_LNCT_timestamp: *s_out = "DW_LNCT_timestamp"; return DW_DLV_OK; case DW_LNCT_size: *s_out = "DW_LNCT_size"; return DW_DLV_OK; case DW_LNCT_MD5: *s_out = "DW_LNCT_MD5"; return DW_DLV_OK; case DW_LNCT_GNU_subprogram_name: *s_out = "DW_LNCT_GNU_subprogram_name"; return DW_DLV_OK; case DW_LNCT_GNU_decl_file: *s_out = "DW_LNCT_GNU_decl_file"; return DW_DLV_OK; case DW_LNCT_GNU_decl_line: *s_out = "DW_LNCT_GNU_decl_line"; return DW_DLV_OK; case DW_LNCT_lo_user: *s_out = "DW_LNCT_lo_user"; return DW_DLV_OK; case DW_LNCT_hi_user: *s_out = "DW_LNCT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LNS_copy: *s_out = "DW_LNS_copy"; return DW_DLV_OK; case DW_LNS_advance_pc: *s_out = "DW_LNS_advance_pc"; return DW_DLV_OK; case DW_LNS_advance_line: *s_out = "DW_LNS_advance_line"; return DW_DLV_OK; case DW_LNS_set_file: *s_out = "DW_LNS_set_file"; return DW_DLV_OK; case DW_LNS_set_column: *s_out = "DW_LNS_set_column"; return DW_DLV_OK; case DW_LNS_negate_stmt: *s_out = "DW_LNS_negate_stmt"; return DW_DLV_OK; case DW_LNS_set_basic_block: *s_out = "DW_LNS_set_basic_block"; return DW_DLV_OK; case DW_LNS_const_add_pc: *s_out = "DW_LNS_const_add_pc"; return DW_DLV_OK; case DW_LNS_fixed_advance_pc: *s_out = "DW_LNS_fixed_advance_pc"; return DW_DLV_OK; case DW_LNS_set_prologue_end: *s_out = "DW_LNS_set_prologue_end"; return DW_DLV_OK; case DW_LNS_set_epilogue_begin: *s_out = "DW_LNS_set_epilogue_begin"; return DW_DLV_OK; case DW_LNS_set_isa: *s_out = "DW_LNS_set_isa"; return DW_DLV_OK; case DW_LNS_set_address_from_logical: *s_out = "DW_LNS_set_address_from_logical"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xd. DW_LNS_set_subprogram */ case DW_LNS_inlined_call: *s_out = "DW_LNS_inlined_call"; return DW_DLV_OK; case DW_LNS_pop_context: *s_out = "DW_LNS_pop_context"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LNE_end_sequence: *s_out = "DW_LNE_end_sequence"; return DW_DLV_OK; case DW_LNE_set_address: *s_out = "DW_LNE_set_address"; return DW_DLV_OK; case DW_LNE_define_file: *s_out = "DW_LNE_define_file"; return DW_DLV_OK; case DW_LNE_set_discriminator: *s_out = "DW_LNE_set_discriminator"; return DW_DLV_OK; case DW_LNE_HP_negate_is_UV_update: *s_out = "DW_LNE_HP_negate_is_UV_update"; return DW_DLV_OK; case DW_LNE_HP_push_context: *s_out = "DW_LNE_HP_push_context"; return DW_DLV_OK; case DW_LNE_HP_pop_context: *s_out = "DW_LNE_HP_pop_context"; return DW_DLV_OK; case DW_LNE_HP_set_file_line_column: *s_out = "DW_LNE_HP_set_file_line_column"; return DW_DLV_OK; case DW_LNE_HP_set_routine_name: *s_out = "DW_LNE_HP_set_routine_name"; return DW_DLV_OK; case DW_LNE_HP_set_sequence: *s_out = "DW_LNE_HP_set_sequence"; return DW_DLV_OK; case DW_LNE_HP_negate_post_semantics: *s_out = "DW_LNE_HP_negate_post_semantics"; return DW_DLV_OK; case DW_LNE_HP_negate_function_exit: *s_out = "DW_LNE_HP_negate_function_exit"; return DW_DLV_OK; case DW_LNE_HP_negate_front_end_logical: *s_out = "DW_LNE_HP_negate_front_end_logical"; return DW_DLV_OK; case DW_LNE_HP_define_proc: *s_out = "DW_LNE_HP_define_proc"; return DW_DLV_OK; case DW_LNE_HP_source_file_correlation: *s_out = "DW_LNE_HP_source_file_correlation"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_LNE_lo_user */ case DW_LNE_hi_user: *s_out = "DW_LNE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ISA_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ISA_UNKNOWN: *s_out = "DW_ISA_UNKNOWN"; return DW_DLV_OK; case DW_ISA_ARM_thumb: *s_out = "DW_ISA_ARM_thumb"; return DW_DLV_OK; case DW_ISA_ARM_arm: *s_out = "DW_ISA_ARM_arm"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACRO_name (unsigned int val,const char ** s_out) { switch (val) { case DW_MACRO_define: *s_out = "DW_MACRO_define"; return DW_DLV_OK; case DW_MACRO_undef: *s_out = "DW_MACRO_undef"; return DW_DLV_OK; case DW_MACRO_start_file: *s_out = "DW_MACRO_start_file"; return DW_DLV_OK; case DW_MACRO_end_file: *s_out = "DW_MACRO_end_file"; return DW_DLV_OK; case DW_MACRO_define_strp: *s_out = "DW_MACRO_define_strp"; return DW_DLV_OK; case DW_MACRO_undef_strp: *s_out = "DW_MACRO_undef_strp"; return DW_DLV_OK; case DW_MACRO_import: *s_out = "DW_MACRO_import"; return DW_DLV_OK; case DW_MACRO_define_sup: *s_out = "DW_MACRO_define_sup"; return DW_DLV_OK; case DW_MACRO_undef_sup: *s_out = "DW_MACRO_undef_sup"; return DW_DLV_OK; case DW_MACRO_import_sup: *s_out = "DW_MACRO_import_sup"; return DW_DLV_OK; case DW_MACRO_define_strx: *s_out = "DW_MACRO_define_strx"; return DW_DLV_OK; case DW_MACRO_undef_strx: *s_out = "DW_MACRO_undef_strx"; return DW_DLV_OK; case DW_MACRO_lo_user: *s_out = "DW_MACRO_lo_user"; return DW_DLV_OK; case DW_MACRO_hi_user: *s_out = "DW_MACRO_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACINFO_name (unsigned int val,const char ** s_out) { switch (val) { case DW_MACINFO_define: *s_out = "DW_MACINFO_define"; return DW_DLV_OK; case DW_MACINFO_undef: *s_out = "DW_MACINFO_undef"; return DW_DLV_OK; case DW_MACINFO_start_file: *s_out = "DW_MACINFO_start_file"; return DW_DLV_OK; case DW_MACINFO_end_file: *s_out = "DW_MACINFO_end_file"; return DW_DLV_OK; case DW_MACINFO_vendor_ext: *s_out = "DW_MACINFO_vendor_ext"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CFA_name (unsigned int val,const char ** s_out) { switch (val) { case DW_CFA_extended: *s_out = "DW_CFA_extended"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_CFA_nop */ case DW_CFA_set_loc: *s_out = "DW_CFA_set_loc"; return DW_DLV_OK; case DW_CFA_advance_loc1: *s_out = "DW_CFA_advance_loc1"; return DW_DLV_OK; case DW_CFA_advance_loc2: *s_out = "DW_CFA_advance_loc2"; return DW_DLV_OK; case DW_CFA_advance_loc4: *s_out = "DW_CFA_advance_loc4"; return DW_DLV_OK; case DW_CFA_offset_extended: *s_out = "DW_CFA_offset_extended"; return DW_DLV_OK; case DW_CFA_restore_extended: *s_out = "DW_CFA_restore_extended"; return DW_DLV_OK; case DW_CFA_undefined: *s_out = "DW_CFA_undefined"; return DW_DLV_OK; case DW_CFA_same_value: *s_out = "DW_CFA_same_value"; return DW_DLV_OK; case DW_CFA_register: *s_out = "DW_CFA_register"; return DW_DLV_OK; case DW_CFA_remember_state: *s_out = "DW_CFA_remember_state"; return DW_DLV_OK; case DW_CFA_restore_state: *s_out = "DW_CFA_restore_state"; return DW_DLV_OK; case DW_CFA_def_cfa: *s_out = "DW_CFA_def_cfa"; return DW_DLV_OK; case DW_CFA_def_cfa_register: *s_out = "DW_CFA_def_cfa_register"; return DW_DLV_OK; case DW_CFA_def_cfa_offset: *s_out = "DW_CFA_def_cfa_offset"; return DW_DLV_OK; case DW_CFA_def_cfa_expression: *s_out = "DW_CFA_def_cfa_expression"; return DW_DLV_OK; case DW_CFA_expression: *s_out = "DW_CFA_expression"; return DW_DLV_OK; case DW_CFA_offset_extended_sf: *s_out = "DW_CFA_offset_extended_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_sf: *s_out = "DW_CFA_def_cfa_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_offset_sf: *s_out = "DW_CFA_def_cfa_offset_sf"; return DW_DLV_OK; case DW_CFA_val_offset: *s_out = "DW_CFA_val_offset"; return DW_DLV_OK; case DW_CFA_val_offset_sf: *s_out = "DW_CFA_val_offset_sf"; return DW_DLV_OK; case DW_CFA_val_expression: *s_out = "DW_CFA_val_expression"; return DW_DLV_OK; case DW_CFA_lo_user: *s_out = "DW_CFA_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x1c. DW_CFA_low_user */ case DW_CFA_MIPS_advance_loc8: *s_out = "DW_CFA_MIPS_advance_loc8"; return DW_DLV_OK; case DW_CFA_GNU_window_save: *s_out = "DW_CFA_GNU_window_save"; return DW_DLV_OK; case DW_CFA_GNU_args_size: *s_out = "DW_CFA_GNU_args_size"; return DW_DLV_OK; case DW_CFA_GNU_negative_offset_extended: *s_out = "DW_CFA_GNU_negative_offset_extended"; return DW_DLV_OK; case DW_CFA_METAWARE_info: *s_out = "DW_CFA_METAWARE_info"; return DW_DLV_OK; case DW_CFA_high_user: *s_out = "DW_CFA_high_user"; return DW_DLV_OK; case DW_CFA_advance_loc: *s_out = "DW_CFA_advance_loc"; return DW_DLV_OK; case DW_CFA_offset: *s_out = "DW_CFA_offset"; return DW_DLV_OK; case DW_CFA_restore: *s_out = "DW_CFA_restore"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_EH_name (unsigned int val,const char ** s_out) { switch (val) { case DW_EH_PE_absptr: *s_out = "DW_EH_PE_absptr"; return DW_DLV_OK; case DW_EH_PE_uleb128: *s_out = "DW_EH_PE_uleb128"; return DW_DLV_OK; case DW_EH_PE_udata2: *s_out = "DW_EH_PE_udata2"; return DW_DLV_OK; case DW_EH_PE_udata4: *s_out = "DW_EH_PE_udata4"; return DW_DLV_OK; case DW_EH_PE_udata8: *s_out = "DW_EH_PE_udata8"; return DW_DLV_OK; case DW_EH_PE_sleb128: *s_out = "DW_EH_PE_sleb128"; return DW_DLV_OK; case DW_EH_PE_sdata2: *s_out = "DW_EH_PE_sdata2"; return DW_DLV_OK; case DW_EH_PE_sdata4: *s_out = "DW_EH_PE_sdata4"; return DW_DLV_OK; case DW_EH_PE_sdata8: *s_out = "DW_EH_PE_sdata8"; return DW_DLV_OK; case DW_EH_PE_pcrel: *s_out = "DW_EH_PE_pcrel"; return DW_DLV_OK; case DW_EH_PE_textrel: *s_out = "DW_EH_PE_textrel"; return DW_DLV_OK; case DW_EH_PE_datarel: *s_out = "DW_EH_PE_datarel"; return DW_DLV_OK; case DW_EH_PE_funcrel: *s_out = "DW_EH_PE_funcrel"; return DW_DLV_OK; case DW_EH_PE_aligned: *s_out = "DW_EH_PE_aligned"; return DW_DLV_OK; case DW_EH_PE_omit: *s_out = "DW_EH_PE_omit"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FRAME_name (unsigned int val,const char ** s_out) { switch (val) { case DW_FRAME_CFA_COL: *s_out = "DW_FRAME_CFA_COL"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_FRAME_LAST_REG_NUM */ /* Skipping alternate spelling of value 0x0. DW_FRAME_RA_COL */ /* Skipping alternate spelling of value 0x0. DW_FRAME_STATIC_LINK */ case DW_FRAME_REG1: *s_out = "DW_FRAME_REG1"; return DW_DLV_OK; case DW_FRAME_REG2: *s_out = "DW_FRAME_REG2"; return DW_DLV_OK; case DW_FRAME_REG3: *s_out = "DW_FRAME_REG3"; return DW_DLV_OK; case DW_FRAME_REG4: *s_out = "DW_FRAME_REG4"; return DW_DLV_OK; case DW_FRAME_REG5: *s_out = "DW_FRAME_REG5"; return DW_DLV_OK; case DW_FRAME_REG6: *s_out = "DW_FRAME_REG6"; return DW_DLV_OK; case DW_FRAME_REG7: *s_out = "DW_FRAME_REG7"; return DW_DLV_OK; case DW_FRAME_REG8: *s_out = "DW_FRAME_REG8"; return DW_DLV_OK; case DW_FRAME_REG9: *s_out = "DW_FRAME_REG9"; return DW_DLV_OK; case DW_FRAME_REG10: *s_out = "DW_FRAME_REG10"; return DW_DLV_OK; case DW_FRAME_REG11: *s_out = "DW_FRAME_REG11"; return DW_DLV_OK; case DW_FRAME_REG12: *s_out = "DW_FRAME_REG12"; return DW_DLV_OK; case DW_FRAME_REG13: *s_out = "DW_FRAME_REG13"; return DW_DLV_OK; case DW_FRAME_REG14: *s_out = "DW_FRAME_REG14"; return DW_DLV_OK; case DW_FRAME_REG15: *s_out = "DW_FRAME_REG15"; return DW_DLV_OK; case DW_FRAME_REG16: *s_out = "DW_FRAME_REG16"; return DW_DLV_OK; case DW_FRAME_REG17: *s_out = "DW_FRAME_REG17"; return DW_DLV_OK; case DW_FRAME_REG18: *s_out = "DW_FRAME_REG18"; return DW_DLV_OK; case DW_FRAME_REG19: *s_out = "DW_FRAME_REG19"; return DW_DLV_OK; case DW_FRAME_REG20: *s_out = "DW_FRAME_REG20"; return DW_DLV_OK; case DW_FRAME_REG21: *s_out = "DW_FRAME_REG21"; return DW_DLV_OK; case DW_FRAME_REG22: *s_out = "DW_FRAME_REG22"; return DW_DLV_OK; case DW_FRAME_REG23: *s_out = "DW_FRAME_REG23"; return DW_DLV_OK; case DW_FRAME_REG24: *s_out = "DW_FRAME_REG24"; return DW_DLV_OK; case DW_FRAME_REG25: *s_out = "DW_FRAME_REG25"; return DW_DLV_OK; case DW_FRAME_REG26: *s_out = "DW_FRAME_REG26"; return DW_DLV_OK; case DW_FRAME_REG27: *s_out = "DW_FRAME_REG27"; return DW_DLV_OK; case DW_FRAME_REG28: *s_out = "DW_FRAME_REG28"; return DW_DLV_OK; case DW_FRAME_REG29: *s_out = "DW_FRAME_REG29"; return DW_DLV_OK; case DW_FRAME_REG30: *s_out = "DW_FRAME_REG30"; return DW_DLV_OK; case DW_FRAME_REG31: *s_out = "DW_FRAME_REG31"; return DW_DLV_OK; case DW_FRAME_FREG0: *s_out = "DW_FRAME_FREG0"; return DW_DLV_OK; case DW_FRAME_FREG1: *s_out = "DW_FRAME_FREG1"; return DW_DLV_OK; case DW_FRAME_FREG2: *s_out = "DW_FRAME_FREG2"; return DW_DLV_OK; case DW_FRAME_FREG3: *s_out = "DW_FRAME_FREG3"; return DW_DLV_OK; case DW_FRAME_FREG4: *s_out = "DW_FRAME_FREG4"; return DW_DLV_OK; case DW_FRAME_FREG5: *s_out = "DW_FRAME_FREG5"; return DW_DLV_OK; case DW_FRAME_FREG6: *s_out = "DW_FRAME_FREG6"; return DW_DLV_OK; case DW_FRAME_FREG7: *s_out = "DW_FRAME_FREG7"; return DW_DLV_OK; case DW_FRAME_FREG8: *s_out = "DW_FRAME_FREG8"; return DW_DLV_OK; case DW_FRAME_FREG9: *s_out = "DW_FRAME_FREG9"; return DW_DLV_OK; case DW_FRAME_FREG10: *s_out = "DW_FRAME_FREG10"; return DW_DLV_OK; case DW_FRAME_FREG11: *s_out = "DW_FRAME_FREG11"; return DW_DLV_OK; case DW_FRAME_FREG12: *s_out = "DW_FRAME_FREG12"; return DW_DLV_OK; case DW_FRAME_FREG13: *s_out = "DW_FRAME_FREG13"; return DW_DLV_OK; case DW_FRAME_FREG14: *s_out = "DW_FRAME_FREG14"; return DW_DLV_OK; case DW_FRAME_FREG15: *s_out = "DW_FRAME_FREG15"; return DW_DLV_OK; case DW_FRAME_FREG16: *s_out = "DW_FRAME_FREG16"; return DW_DLV_OK; case DW_FRAME_FREG17: *s_out = "DW_FRAME_FREG17"; return DW_DLV_OK; case DW_FRAME_FREG18: *s_out = "DW_FRAME_FREG18"; return DW_DLV_OK; case DW_FRAME_FREG19: *s_out = "DW_FRAME_FREG19"; return DW_DLV_OK; case DW_FRAME_FREG20: *s_out = "DW_FRAME_FREG20"; return DW_DLV_OK; case DW_FRAME_FREG21: *s_out = "DW_FRAME_FREG21"; return DW_DLV_OK; case DW_FRAME_FREG22: *s_out = "DW_FRAME_FREG22"; return DW_DLV_OK; case DW_FRAME_FREG23: *s_out = "DW_FRAME_FREG23"; return DW_DLV_OK; case DW_FRAME_FREG24: *s_out = "DW_FRAME_FREG24"; return DW_DLV_OK; case DW_FRAME_FREG25: *s_out = "DW_FRAME_FREG25"; return DW_DLV_OK; case DW_FRAME_FREG26: *s_out = "DW_FRAME_FREG26"; return DW_DLV_OK; case DW_FRAME_FREG27: *s_out = "DW_FRAME_FREG27"; return DW_DLV_OK; case DW_FRAME_FREG28: *s_out = "DW_FRAME_FREG28"; return DW_DLV_OK; case DW_FRAME_FREG29: *s_out = "DW_FRAME_FREG29"; return DW_DLV_OK; case DW_FRAME_FREG30: *s_out = "DW_FRAME_FREG30"; return DW_DLV_OK; case DW_FRAME_FREG31: *s_out = "DW_FRAME_FREG31"; return DW_DLV_OK; case DW_FRAME_FREG32: *s_out = "DW_FRAME_FREG32"; return DW_DLV_OK; case DW_FRAME_FREG33: *s_out = "DW_FRAME_FREG33"; return DW_DLV_OK; case DW_FRAME_FREG34: *s_out = "DW_FRAME_FREG34"; return DW_DLV_OK; case DW_FRAME_FREG35: *s_out = "DW_FRAME_FREG35"; return DW_DLV_OK; case DW_FRAME_FREG36: *s_out = "DW_FRAME_FREG36"; return DW_DLV_OK; case DW_FRAME_FREG37: *s_out = "DW_FRAME_FREG37"; return DW_DLV_OK; case DW_FRAME_FREG38: *s_out = "DW_FRAME_FREG38"; return DW_DLV_OK; case DW_FRAME_FREG39: *s_out = "DW_FRAME_FREG39"; return DW_DLV_OK; case DW_FRAME_FREG40: *s_out = "DW_FRAME_FREG40"; return DW_DLV_OK; case DW_FRAME_FREG41: *s_out = "DW_FRAME_FREG41"; return DW_DLV_OK; case DW_FRAME_FREG42: *s_out = "DW_FRAME_FREG42"; return DW_DLV_OK; case DW_FRAME_FREG43: *s_out = "DW_FRAME_FREG43"; return DW_DLV_OK; case DW_FRAME_FREG44: *s_out = "DW_FRAME_FREG44"; return DW_DLV_OK; case DW_FRAME_FREG45: *s_out = "DW_FRAME_FREG45"; return DW_DLV_OK; case DW_FRAME_FREG46: *s_out = "DW_FRAME_FREG46"; return DW_DLV_OK; case DW_FRAME_FREG47: *s_out = "DW_FRAME_FREG47"; return DW_DLV_OK; case DW_FRAME_FREG48: *s_out = "DW_FRAME_FREG48"; return DW_DLV_OK; case DW_FRAME_FREG49: *s_out = "DW_FRAME_FREG49"; return DW_DLV_OK; case DW_FRAME_FREG50: *s_out = "DW_FRAME_FREG50"; return DW_DLV_OK; case DW_FRAME_FREG51: *s_out = "DW_FRAME_FREG51"; return DW_DLV_OK; case DW_FRAME_FREG52: *s_out = "DW_FRAME_FREG52"; return DW_DLV_OK; case DW_FRAME_FREG53: *s_out = "DW_FRAME_FREG53"; return DW_DLV_OK; case DW_FRAME_FREG54: *s_out = "DW_FRAME_FREG54"; return DW_DLV_OK; case DW_FRAME_FREG55: *s_out = "DW_FRAME_FREG55"; return DW_DLV_OK; case DW_FRAME_FREG56: *s_out = "DW_FRAME_FREG56"; return DW_DLV_OK; case DW_FRAME_FREG57: *s_out = "DW_FRAME_FREG57"; return DW_DLV_OK; case DW_FRAME_FREG58: *s_out = "DW_FRAME_FREG58"; return DW_DLV_OK; case DW_FRAME_FREG59: *s_out = "DW_FRAME_FREG59"; return DW_DLV_OK; case DW_FRAME_FREG60: *s_out = "DW_FRAME_FREG60"; return DW_DLV_OK; case DW_FRAME_FREG61: *s_out = "DW_FRAME_FREG61"; return DW_DLV_OK; case DW_FRAME_FREG62: *s_out = "DW_FRAME_FREG62"; return DW_DLV_OK; case DW_FRAME_FREG63: *s_out = "DW_FRAME_FREG63"; return DW_DLV_OK; case DW_FRAME_FREG64: *s_out = "DW_FRAME_FREG64"; return DW_DLV_OK; case DW_FRAME_FREG65: *s_out = "DW_FRAME_FREG65"; return DW_DLV_OK; case DW_FRAME_FREG66: *s_out = "DW_FRAME_FREG66"; return DW_DLV_OK; case DW_FRAME_FREG67: *s_out = "DW_FRAME_FREG67"; return DW_DLV_OK; case DW_FRAME_FREG68: *s_out = "DW_FRAME_FREG68"; return DW_DLV_OK; case DW_FRAME_FREG69: *s_out = "DW_FRAME_FREG69"; return DW_DLV_OK; case DW_FRAME_FREG70: *s_out = "DW_FRAME_FREG70"; return DW_DLV_OK; case DW_FRAME_FREG71: *s_out = "DW_FRAME_FREG71"; return DW_DLV_OK; case DW_FRAME_FREG72: *s_out = "DW_FRAME_FREG72"; return DW_DLV_OK; case DW_FRAME_FREG73: *s_out = "DW_FRAME_FREG73"; return DW_DLV_OK; case DW_FRAME_FREG74: *s_out = "DW_FRAME_FREG74"; return DW_DLV_OK; case DW_FRAME_FREG75: *s_out = "DW_FRAME_FREG75"; return DW_DLV_OK; case DW_FRAME_FREG76: *s_out = "DW_FRAME_FREG76"; return DW_DLV_OK; case DW_FRAME_HIGHEST_NORMAL_REGISTER: *s_out = "DW_FRAME_HIGHEST_NORMAL_REGISTER"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CHILDREN_name (unsigned int val,const char ** s_out) { switch (val) { case DW_CHILDREN_no: *s_out = "DW_CHILDREN_no"; return DW_DLV_OK; case DW_CHILDREN_yes: *s_out = "DW_CHILDREN_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ADDR_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ADDR_none: *s_out = "DW_ADDR_none"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* END FILE */ dwarfutils-20200114/dwarfdump/dwarf_names.h000066400000000000000000000063361361531463500206000ustar00rootroot00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #ifndef DWARF_NAMES_H #define DWARF_NAMES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_NAMES_H */ /* END FILE */ dwarfutils-20200114/dwarfdump/dwarf_tsearch.h000066400000000000000000000075361361531463500211310ustar00rootroot00000000000000#ifndef DWARF_TSEARCH_H #define DWARF_TSEARCH_H /* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The following interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source code of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. See https://www.prevanders.net/tsearch.html and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional interface here, but to avoid interfering with libc implementations or code using libc implementations, we change all the names. */ /* The hashfunc return is now easily changed with cc -Duintptr_t or something. */ #ifndef DW_TSHASHTYPE #define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through the callback function in dwarf_twalk(); */ typedef enum { dwarf_preorder, dwarf_postorder, dwarf_endorder, dwarf_leaf } DW_VISIT; /* void * return values are actually void **key so you must dereference these once to get a key you passed in. */ void *dwarf_tsearch(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void *dwarf_tfind(const void * /*key*/, void *const * /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* dwarf_tdelete() returns NULL if it cannot delete anything or if the tree is now empty (if empty, *rootp is set NULL by dwarf_tdelete()). If the delete succeeds and the tree is non-empty returns a pointer to the parent node of the deleted item, unless the deleted item was at the root, in which case the returned pointer relates to the new root. */ void *dwarf_tdelete(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void dwarf_twalk(const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); /* dwarf_tdestroy() cannot set the root pointer NULL, you must do so on return from dwarf_tdestroy(). */ void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, char *(* /*keyprint*/)(const void *), const char *msg); /* Returns NULL and does nothing unless the implemenation used uses a hash tree. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); #endif /* DWARF_TSEARCH_H */ dwarfutils-20200114/dwarfdump/dwarf_tsearchbal.c000066400000000000000000000700731361531463500215770ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2 And based on chapter 6.2.3 Balanced Trees (sometimes call AVL trees) Algorithm A and the sketch on deletion. The wikipedia page on AVL trees is also quite useful. A Key equation is: bal-factor-node-k = height-left-subtree - height-right-subtree We don't know the absolute height, but we do know the balance factor of the pointed-to subtrees (-1,0, or 1). And we always know if we are adding or deleting a node. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include /* for printf */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" #define IMPLEMENTD15 1 #ifdef DW_CHECK_CONSISTENCY struct ts_entry; void dwarf_check_balance(struct ts_entry *head,int finalprefix); #endif /* head is a special link. rlink points to root node. head-> llink is a tree depth value. Using a pointer. root = head->rlink. The keypointer and balance fields of the head node are not used. Might be sensible to use the head balance field as a tree depth instead of using llink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. We will request free, so const void * is not quite right. */ void *keyptr; int balance; /* Knuth 6.2.3 algorithm A */ struct ts_entry * llink; struct ts_entry * rlink; }; static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[40]; /* This is a safe sprintf. No need for esb here. */ len = sprintf(number,"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging, mainly. We print the tree with the head node unnumbered and the root node called level 0. In Knuth algorithms where we have p[k] when k is zero k refers to the head node. Handy as then the root node is not special at all. But here it just looks better as shown, perhaps. The ordering here is so that if you turned an output page with the left side at the top then the tree sort of just shows up nicely in what most think of as a normal way. */ static void tdump_inner(struct ts_entry *t, char *(keyprint)(const void *), const char *descr, int level) { const char * keyv = ""; if(!t) { return; } tdump_inner(t->rlink,keyprint,"right",level+1); printlevel(level); if(t->keyptr) { keyv = keyprint(t->keyptr); } printf("0x%08" DW_PR_DUx " " "<%s %s> " " " "%s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", keyv, t->balance, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); tdump_inner(t->llink,keyprint,"left ",level+1); } #ifdef DW_CHECK_CONSISTENCY /* Checking that a tree (or sub tree) is in balance. Only meaningful for balanced trees. Returns the depth. */ int dwarf_check_balance_inner(struct ts_entry *t,int level,int maxdepth, int *founderror,const char *prefix) { int l = 0; int r = 0; if(level > maxdepth) { printf("%s Likely internal erroneous link loop, got to depth %d.\n", prefix,level); exit(1); } if(!t) { return 0; } if(!t->llink && !t->rlink) { if (t->balance != 0) { printf("%s: Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return 1; } l = dwarf_check_balance_inner(t->llink,level+1,maxdepth, founderror,prefix); r = dwarf_check_balance_inner(t->rlink,level+1,maxdepth, founderror,prefix); if (l ==r && t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " d should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; return l+1; } if(l > r) { if( (l-r) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " l %d r %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, l,r); (*founderror)++; } if (t->balance != -1) { printf("%s Balance at 0x%" DW_PR_DUx " should be -1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return l+1; } if(r != l) { if( (r-l) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " r %d l %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, r,l); (*founderror)++; } if (t->balance != 1) { printf("%s Balance at 0x%" DW_PR_DUx " should be 1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } else { if (t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } return r+1; } void dwarf_check_balance(struct ts_entry *head,int finalprefix) { const char *prefix = 0; int maxdepth = 0; size_t headdepth = 0; int errcount = 0; int depth = 0; struct ts_entry*root = 0; if(finalprefix) { prefix = "BalanceError:"; } else { prefix = "BalanceWarn:"; } if(!head) { printf("%s check balance null tree ptr\n",prefix); return; } root = head->rlink; headdepth = head->llink - (struct ts_entry *)0; if(!root) { printf("%s check balance null tree ptr\n",prefix); return; } maxdepth = headdepth+10; /* Counting in levels, not level number of top level. */ headdepth++; depth = dwarf_check_balance_inner(root,depth,maxdepth,&errcount,prefix); if (depth != headdepth) { printf("%s Head node says depth %lu, it is really %d\n", prefix, (unsigned long)headdepth, depth); ++errcount; } if(errcount) { printf("%s error count %d\n",prefix,errcount); } return; } #endif /* Dumping the tree to stdout. */ void dwarf_tdump(const void*headp_in, char *(*keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)headp_in; struct ts_entry *root = 0; size_t headdepth = 0; if(!head) { printf("dumptree null tree ptr : %s\n",msg); return; } headdepth = head->llink - (struct ts_entry *)0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " tree-depth %d: %s\n", (Dwarf_Unsigned)(uintptr_t)head, (int)headdepth, msg); root = head->rlink; if(!root) { printf("Empty tree\n"); return; } tdump_inner(root,keyprint,"top",0); } static void setlink(struct ts_entry*t,int a,struct ts_entry *x) { if(a < 0) { t->llink = x; } else { t->rlink = x; } } static struct ts_entry* getlink(struct ts_entry*t,int a) { if(a < 0) { return(t->llink); } return(t->rlink); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } /* We will eventually ask it be freed, so being const void * in is not quite right. */ e->keyptr = (void *)key; e->balance = 0; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *q = allocate_ts_entry(key); if (!q) { /* out of memory */ return NULL; } setlink(p,kc,q); /* Non-NULL means inserted. */ return q; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if(q) { *inserted = 1; } return q; } /* Algorithm A of Knuth 6.2.3, balanced tree. key is pointer to a user data area containing the key and possibly more. We could recurse on this routine, but instead we iterate (like Knuth does, but using for(;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* head, int (*compar)(const void *, const void *), int*inserted, UNUSEDARG struct ts_entry **nullme, UNUSEDARG int * comparres) { /* t points to parent of p */ struct ts_entry *t = head; /* p moves down tree, p starts as root. */ struct ts_entry *p = head->rlink; /* s points where rebalancing may be needed. */ struct ts_entry *s = p; struct ts_entry *r = 0; struct ts_entry *q = 0; int a = 0; int kc = 0; for(;;) { /* A2. */ kc = compar(key,p->keyptr); if(kc) { /* A3 and A4 handled here. */ q = getlink(p,kc); if(!q) { /* Does step A5. */ q = tsearch_inner_do_insert(key,kc,inserted,p); if (!q) { /* Out of memory. */ return q; } break; /* to A5. */ } if(q->balance) { t = p; s = q; } p = q; continue; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* A5: work already done. */ /* A6: */ { /* Balance factors on nodes betwen S and Q need to be changed from zero to +-1 */ int kc2 = compar(key,s->keyptr); if (kc2 < 0) { a = -1; } else { a = 1; } r = p = getlink(s,a); while (p != q) { int kc3 = compar(key,p->keyptr); if(kc3 < 0) { p->balance = -1; p = p->llink; } else if (kc3 > 0) { p->balance = 1; p = p->rlink; } else { /* ASSERT: p == q */ break; } } } /* A7: */ { if(! s->balance) { /* Tree has grown higher. */ s->balance = a; /* Counting in pointers, not integers. Ugh. */ head->llink = head->llink + 1; return q; } if(s->balance == -a) { /* Tree is more balanced */ s->balance = 0; return q; } if (s->balance == a) { /* Rebalance. */ if(r->balance == a) { /* single rotation, step A8. */ p = r; setlink(s,a,getlink(r,-a)); setlink(r,-a,s); s->balance = 0; r->balance = 0; } else if (r->balance == -a) { /* double rotation, step A9. */ p = getlink(r,-a); setlink(r,-a,getlink(p,a)); setlink(p,a,r); setlink(s,a,getlink(p,-a)); setlink(p,-a,s); if(p->balance == a) { s->balance = -a; r->balance = 0; } else if (p->balance == 0) { s->balance = 0; r->balance = 0; } else if (p->balance == -a) { s->balance = 0; r->balance = a; } p->balance = 0; } else { fprintf(stderr,"Impossible balanced tree situation!\n"); /* Impossible. Cannot be here. */ exit(1); } } else { fprintf(stderr,"Impossible balanced tree situation!!\n"); /* Impossible. Cannot be here. */ exit(1); } } /* A10: */ if (s == t->rlink) { t->rlink = p; } else { t->llink = p; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry **headp = (struct ts_entry **)headin; struct ts_entry *head = 0; struct ts_entry *r = 0; int inserted = 0; /* kcomparv should be ignored */ int kcomparv = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!headp) { return NULL; } head = *headp; if (!head) { struct ts_entry *root = 0; head = allocate_ts_entry(0); if(!head) { return NULL; } root = allocate_ts_entry(key); if(!root) { free(head); return NULL; } head->rlink = root; /* head->llink is used for the depth, as a count */ /* head points to the special head node ... */ *headin = head; return (void *)(&(root->keyptr)); } r = tsearch_inner(key,head,compar,&inserted,&nullme,&kcomparv); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search without insert. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry * const *phead = (struct ts_entry * const*)rootp; struct ts_entry *head = 0; struct ts_entry *p = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } p = head->rlink; while(p) { int kc = compar(key,p->keyptr); if(!kc) { return (void *)(&(p->keyptr)); } p = getlink(p,kc); } return NULL; } /* Used for an array of records used in the deletion code. k == 0 for the special head node which is never matched by input. k == 1 etc. */ struct pkrecord { struct ts_entry *pk; int ak; /* Is -1 or +1 */ }; /* Here we rearrange the tree so the node p to be deleted is a node with a null left link. With that done we can fix pkarray and then we can use the pkarray to rebalance. It's a bit long, so we refactor out the code from where it is called. The rearrangement is Algorithm 6.2.2D in Knuth. PRECONDITION: p,p->rlink, pp non-null. RETURNS: new high index of pkarray. */ static unsigned rearrange_tree_so_p_llink_null( struct pkrecord * pkarray, unsigned k, UNUSEDARG struct ts_entry *head, struct ts_entry *r, struct ts_entry *p, UNUSEDARG int pak, UNUSEDARG struct ts_entry *pp, int ppak) { struct ts_entry *s = 0; unsigned k2 = 0; /* indexing pkarray */ int pbalance = p->balance; /* Step D3 */ /* Since we are going to modify the tree by movement of a node down the tree a ways, we need to build pkarray with the (not yet found) new next node, in pkarray[k], not p. The deletion will be of p, but by then p will be moved in the tree so it has a null left link. P's possibly-non-null right link */ k2 = k; k2++; r = p->rlink; pkarray[k2].pk = r; pkarray[k2].ak = -1; s = r->llink; /* Move down and left to get a null llink. */ while (s->llink) { k2++; r = s; s = r->llink; pkarray[k2].pk = r; pkarray[k2].ak = -1; } /* Now we move S up in place (in the tree) of the node P we will delete. and p replaces s. Finally winding up with a newly shaped balanced tree. */ { struct ts_entry *tmp = 0; int sbalance = s->balance; s->llink = p->llink; r->llink = p; p->llink = 0; tmp = p->rlink; p->rlink = s->rlink; s->rlink = tmp; setlink(pp,ppak,s); s->balance = pbalance; p->balance = sbalance; /* Now the tree is rearranged and still in balance. */ /* Replace the previous k position entry with S. We trace the right link off of the moved S node. */ pkarray[k].pk = s; pkarray[k].ak = 1; r->llink = p->rlink; /* Now p is out of the tree and we start the rebalance at r. pkarray Index k2. */ } /* Step D4 */ free(p); return k2; } /* Returns deleted node parent unless the head changed. Returns NULL if wanted node not found or the tree is now empty or the head node changed. Sets *did_delete if it found and deleted a node. Sets *tree_empty if there are no more user nodes present. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *head, int (*compar)(const void *, const void *), int *tree_empty, int *did_delete ) { struct ts_entry *p = 0; struct ts_entry *pp = 0; struct pkrecord * pkarray = 0; size_t depth = head->llink - (struct ts_entry *)0; unsigned k = 0; /* Allocate extra, head is on the stack we create here and the depth might increase. */ depth = depth + 4; pkarray = calloc(sizeof(struct pkrecord),depth); if(!pkarray) { /* Malloc fails, we could abort... */ return NULL; } k = 0; pkarray[k].pk=head; pkarray[k].ak=1; p = head->rlink; while(p) { int kc = 0; k++; kc = compar(key,p->keyptr); pkarray[k].pk = p; pkarray[k].ak = kc; if(!kc) { break; } p = getlink(p,kc); } if(!p) { /* Node to delete never found. */ free(pkarray); return NULL; } { struct ts_entry *t = 0; struct ts_entry *r = 0; int pak = 0; int ppak = 0; p = pkarray[k].pk; pak = pkarray[k].ak; pp = pkarray[k-1].pk; ppak = pkarray[k-1].ak; /* Found a match. p to be deleted. */ t = p; *did_delete = 1; if(!t->rlink) { if(k == 1 && !t->llink) { *tree_empty = 1; /* upper level will fix up head node. */ free(t); free(pkarray); return NULL; } /* t->llink might be NULL. */ setlink(pp,ppak,t->llink); /* ASSERT: t->llink NULL or t->llink has no children, balance zero and balance of t->llink not changing. */ k--; /* Step D4. */ free(t); goto balance; } #ifdef IMPLEMENTD15 /* Step D1.5 */ if(!t->llink) { setlink(pp,ppak,t->rlink); /* we change the left link off ak */ k--; /* Step D4. */ free(t); goto balance; } #endif /* IMPLEMENTD15 */ /* Step D2 */ r = t->rlink; if (!r->llink) { /* We decrease the height of the right tree. */ r->llink = t->llink; setlink(pp,ppak,r); pkarray[k].pk = r; pkarray[k].ak = 1; /* The following essential line not mentioned in Knuth AFAICT. */ r->balance = t->balance; /* Step D4. */ free(t); goto balance; } /* Step D3, we rearrange the tree and pkarray so the balance step can work. step D2 is insufficient so not done. */ k = rearrange_tree_so_p_llink_null(pkarray,k, head,r, p,pak,pp,ppak); goto balance; } /* Now use pkarray decide if rebalancing needed and, if needed, to rebalance. k here matches l-1 in Knuth. */ balance: { unsigned k2 = k; /* We do not want a test in the for() itself. */ for( ; 1 ; k2--) { struct ts_entry *pk = 0; int ak = 0; int bk = 0; if (k2 == 0) { /* decreased in height */ head->llink--; goto cleanup; } pk = pkarray[k2].pk; if (!pk) { /* Nothing here to work with. Move up. */ continue; } ak = pkarray[k2].ak; bk = pk->balance; if(bk == ak) { pk->balance = 0; continue; } if(bk == 0) { pk->balance = -ak; goto cleanup; } /* ASSERT: bk == -ak. We will use bk == adel here (just below). */ /* Rebalancing required. Here we use (1) and (2) in 6.2.3 to adjust the nodes */ { /* Rebalance. We use s for what is called A in Knuth Case 1, Case 2 page 461. r For what is called B. So the link movement logic looks similar to the tsearch insert case.*/ struct ts_entry *r = 0; struct ts_entry *s = 0; struct ts_entry *pa = 0; int pak = 0; int adel = -ak; s = pk; r = getlink(s,adel); pa = pkarray[k2-1].pk; pak = pkarray[k2-1].ak; if(r->balance == adel) { /* case 1. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,r); s->balance = 0; r->balance = 0; continue; } else if (r->balance == -adel) { /* case 2 */ /* x plays the role of p in step A9 */ struct ts_entry*x = getlink(r,-adel); setlink(r,-adel,getlink(x,adel)); setlink(x,adel,r); setlink(s,adel,getlink(x,-adel)); setlink(x,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,x); if(x->balance == adel) { s->balance = -adel; r->balance = 0; } else if (x->balance == 0) { s->balance = 0; r->balance = 0; } else if (x->balance == -adel) { s->balance = 0; r->balance = adel; } x->balance = 0; continue; } else { /* r->balance == 0 case 3 we do a single rotation and we are done. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); setlink(pa,pak,r); r->balance = -adel; /*s->balance = r->balance = 0; */ goto cleanup; } } } } cleanup: free(pkarray); #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return pp; } void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int tree_empty = 0; int did_delete = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } if (!head->rlink) { return NULL; } parentp = tdelete_inner(key,head,compar,&tree_empty,&did_delete); if(tree_empty) { head->rlink = 0; head->llink = 0; free(head); *phead = 0; return NULL; } /* ASSERT: head->rlink non-null. */ if(did_delete) { if (!parentp) { parentp = head->rlink; } return (void *)(&(parentp->keyptr)); } /* Not deleted */ return NULL; } static void dwarf_twalk_inner(struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if(p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if(p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(!root) { return; } /* Get to actual tree. */ dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if(p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if(p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(root) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } dwarfutils-20200114/dwarfdump/dwarfdump-ta-ext-table.h000066400000000000000000000055021361531463500225620ustar00rootroot00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ /* Common extensions */ #define ATTR_TREE_EXT_ROW_COUNT 15 #define ATTR_TREE_EXT_COLUMN_COUNT 10 static unsigned int tag_attr_combination_ext_table[ATTR_TREE_EXT_ROW_COUNT][ATTR_TREE_EXT_COLUMN_COUNT] = { /* 0x13 - DW_TAG_structure_type */ { 0x00000013,0x0000001d,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x11 - DW_TAG_compile_unit */ { 0x00000011,0x00003fe1,0x00002131,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0d - DW_TAG_member */ { 0x0000000d,0x00002108,0x00002109,0x0000210a,0x0000210b,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x01 - DW_TAG_array_type */ { 0x00000001,0x00002107,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x2e - DW_TAG_subprogram */ { 0x0000002e,0x00002007,0x00002001,0x0000210c,0x0000210d,0x0000210e,0x00003fe7,0x00003fe1,0x00002116,0x00002117,}, /* 0x34 - DW_TAG_variable */ { 0x00000034,0x00002007,0x00002108,0x00002109,0x0000210a,0x0000210b,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4106 - DW_TAG_GNU_template_template_parameter*/ { 0x00004106,0x00000039,0x0000003a,0x0000003b,0x00000003,0x00002110,0x00002108,0x00000000,0x00000000,0x00000000,}, /* 0x4107 - DW_TAG_GNU_template_parameter_pack */ { 0x00004107,0x00000039,0x0000003a,0x0000003b,0x00000003,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4108 - DW_TAG_GNU_formal_parameter_pack */ { 0x00004108,0x00000039,0x0000003a,0x0000003b,0x00000003,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x4109 - DW_TAG_GNU_call_site */ { 0x00004109,0x00000031,0x00000011,0x00000001,0x00002115,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x410a - DW_TAG_GNU_call_site_parameter */ { 0x0000410a,0x00002111,0x00000031,0x00000002,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x27 - DW_TAG_constant */ { 0x00000027,0x00002303,0x00002304,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x21 - DW_TAG_subrange_type */ { 0x00000021,0x00002305,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0x0000001d,0x00002136,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0b - DW_TAG_lexical_block */ { 0x0000000b,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, }; /* END FILE */ dwarfutils-20200114/dwarfdump/dwarfdump-ta-table.h000066400000000000000000001505021361531463500217650ustar00rootroot00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #ifndef HAVE_USAGE_TAG_ATTR #define HAVE_USAGE_TAG_ATTR 1 #endif /* HAVE_USAGE_TAG_ATTR */ #ifdef HAVE_USAGE_TAG_ATTR #include "dwarf.h" #include "libdwarf.h" typedef struct { unsigned int count; /* Attribute count */ Dwarf_Half attr; /* Attribute value */ } Usage_Tag_Attr; /* 0x23 - DW_TAG_access_declaration */ static Usage_Tag_Attr tag_attr_23[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x01 - DW_TAG_array_type */ static Usage_Tag_Attr tag_attr_01[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x09 */ 0, DW_AT_ordering}, {/* 0x71 */ 0, DW_AT_rank}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x47 - DW_TAG_atomic_type */ static Usage_Tag_Attr tag_attr_47[] = { {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x24 - DW_TAG_base_type */ static Usage_Tag_Attr tag_attr_24[] = { {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x5b */ 0, DW_AT_binary_scale}, {/* 0x0c */ 0, DW_AT_bit_offset}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x6b */ 0, DW_AT_data_bit_offset}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x5c */ 0, DW_AT_decimal_scale}, {/* 0x5e */ 0, DW_AT_decimal_sign}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x5f */ 0, DW_AT_digit_count}, {/* 0x3e */ 0, DW_AT_encoding}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x60 */ 0, DW_AT_picture_string}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x5d */ 0, DW_AT_small}, {/* */ 0, 0} }; /* 0x48 - DW_TAG_call_site */ static Usage_Tag_Attr tag_attr_48[] = { {/* 0x57 */ 0, DW_AT_call_column}, {/* 0x58 */ 0, DW_AT_call_file}, {/* 0x59 */ 0, DW_AT_call_line}, {/* 0x7f */ 0, DW_AT_call_origin}, {/* 0x81 */ 0, DW_AT_call_pc}, {/* 0x7d */ 0, DW_AT_call_return_pc}, {/* 0x82 */ 0, DW_AT_call_tail_call}, {/* 0x83 */ 0, DW_AT_call_target}, {/* 0x84 */ 0, DW_AT_call_target_clobbered}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x49 - DW_TAG_call_site_parameter */ static Usage_Tag_Attr tag_attr_49[] = { {/* 0x85 */ 0, DW_AT_call_data_location}, {/* 0x86 */ 0, DW_AT_call_data_value}, {/* 0x80 */ 0, DW_AT_call_parameter}, {/* 0x7e */ 0, DW_AT_call_value}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x25 - DW_TAG_catch_block */ static Usage_Tag_Attr tag_attr_25[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x02 - DW_TAG_class_type */ static Usage_Tag_Attr tag_attr_02[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x1d */ 0, DW_AT_containing_type}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x44 - DW_TAG_coarray_type */ static Usage_Tag_Attr tag_attr_44[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x1a - DW_TAG_common_block */ static Usage_Tag_Attr tag_attr_1a[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x1b - DW_TAG_common_inclusion */ static Usage_Tag_Attr tag_attr_1b[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1a */ 0, DW_AT_common_reference}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x11 - DW_TAG_compile_unit */ static Usage_Tag_Attr tag_attr_11[] = { {/* 0x73 */ 0, DW_AT_addr_base}, {/* 0x35 */ 0, DW_AT_base_types}, {/* 0x1b */ 0, DW_AT_comp_dir}, {/* 0x75 */ 0, DW_AT_dwo_id}, {/* 0x76 */ 0, DW_AT_dwo_name}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x42 */ 0, DW_AT_identifier_case}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x13 */ 0, DW_AT_language}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x43 */ 0, DW_AT_macro_info}, {/* 0x79 */ 0, DW_AT_macros}, {/* 0x6a */ 0, DW_AT_main_subprogram}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x25 */ 0, DW_AT_producer}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x74 */ 0, DW_AT_rnglists_base}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x3f - DW_TAG_condition */ static Usage_Tag_Attr tag_attr_3f[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x26 - DW_TAG_const_type */ static Usage_Tag_Attr tag_attr_26[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x27 - DW_TAG_constant */ static Usage_Tag_Attr tag_attr_27[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x36 - DW_TAG_dwarf_procedure */ static Usage_Tag_Attr tag_attr_36[] = { {/* 0x02 */ 0, DW_AT_location}, {/* */ 0, 0} }; /* 0x46 - DW_TAG_dynamic_type */ static Usage_Tag_Attr tag_attr_46[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x03 - DW_TAG_entry_point */ static Usage_Tag_Attr tag_attr_03[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x40 */ 0, DW_AT_frame_base}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x2a */ 0, DW_AT_return_addr}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x48 */ 0, DW_AT_static_link}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x04 - DW_TAG_enumeration_type */ static Usage_Tag_Attr tag_attr_04[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x51 */ 0, DW_AT_byte_stride}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x6d */ 0, DW_AT_enum_class}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x28 - DW_TAG_enumerator */ static Usage_Tag_Attr tag_attr_28[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x29 - DW_TAG_file_type */ static Usage_Tag_Attr tag_attr_29[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x05 - DW_TAG_formal_parameter */ static Usage_Tag_Attr tag_attr_05[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x1e */ 0, DW_AT_default_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x21 */ 0, DW_AT_is_optional}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x4b */ 0, DW_AT_variable_parameter}, {/* */ 0, 0} }; /* 0x2a - DW_TAG_friend */ static Usage_Tag_Attr tag_attr_2a[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x41 */ 0, DW_AT_friend}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x45 - DW_TAG_generic_subrange */ static Usage_Tag_Attr tag_attr_45[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x51 */ 0, DW_AT_byte_stride}, {/* 0x37 */ 0, DW_AT_count}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x22 */ 0, DW_AT_lower_bound}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x62 */ 0, DW_AT_threads_scaled}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x2f */ 0, DW_AT_upper_bound}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x08 - DW_TAG_imported_declaration */ static Usage_Tag_Attr tag_attr_08[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x18 */ 0, DW_AT_import}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x3a - DW_TAG_imported_module */ static Usage_Tag_Attr tag_attr_3a[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x18 */ 0, DW_AT_import}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x3d - DW_TAG_imported_unit */ static Usage_Tag_Attr tag_attr_3d[] = { {/* 0x18 */ 0, DW_AT_import}, {/* */ 0, 0} }; /* 0x1c - DW_TAG_inheritance */ static Usage_Tag_Attr tag_attr_1c[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x38 */ 0, DW_AT_data_member_location}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x4c */ 0, DW_AT_virtuality}, {/* */ 0, 0} }; /* 0x1d - DW_TAG_inlined_subroutine */ static Usage_Tag_Attr tag_attr_1d[] = { {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x57 */ 0, DW_AT_call_column}, {/* 0x58 */ 0, DW_AT_call_file}, {/* 0x59 */ 0, DW_AT_call_line}, {/* 0x6c */ 0, DW_AT_const_expr}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x2a */ 0, DW_AT_return_addr}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x56 */ 0, DW_AT_trampoline}, {/* */ 0, 0} }; /* 0x38 - DW_TAG_interface_type */ static Usage_Tag_Attr tag_attr_38[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x0a - DW_TAG_label */ static Usage_Tag_Attr tag_attr_0a[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x0b - DW_TAG_lexical_block */ static Usage_Tag_Attr tag_attr_0b[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x0d - DW_TAG_member */ static Usage_Tag_Attr tag_attr_0d[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x0c */ 0, DW_AT_bit_offset}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x6b */ 0, DW_AT_data_bit_offset}, {/* 0x38 */ 0, DW_AT_data_member_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x61 */ 0, DW_AT_mutable}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x1e - DW_TAG_module */ static Usage_Tag_Attr tag_attr_1e[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x45 */ 0, DW_AT_priority}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2b - DW_TAG_namelist */ static Usage_Tag_Attr tag_attr_2b[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2c - DW_TAG_namelist_item */ static Usage_Tag_Attr tag_attr_2c[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x44 */ 0, DW_AT_namelist_item}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x39 - DW_TAG_namespace */ static Usage_Tag_Attr tag_attr_39[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x54 */ 0, DW_AT_extension}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* */ 0, 0} }; /* 0x2d - DW_TAG_packed_type */ static Usage_Tag_Attr tag_attr_2d[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x3c - DW_TAG_partial_unit */ static Usage_Tag_Attr tag_attr_3c[] = { {/* 0x73 */ 0, DW_AT_addr_base}, {/* 0x35 */ 0, DW_AT_base_types}, {/* 0x1b */ 0, DW_AT_comp_dir}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x75 */ 0, DW_AT_dwo_id}, {/* 0x76 */ 0, DW_AT_dwo_name}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x42 */ 0, DW_AT_identifier_case}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x13 */ 0, DW_AT_language}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x43 */ 0, DW_AT_macro_info}, {/* 0x79 */ 0, DW_AT_macros}, {/* 0x6a */ 0, DW_AT_main_subprogram}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x25 */ 0, DW_AT_producer}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x74 */ 0, DW_AT_rnglists_base}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x0f - DW_TAG_pointer_type */ static Usage_Tag_Attr tag_attr_0f[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x1f - DW_TAG_ptr_to_member_type */ static Usage_Tag_Attr tag_attr_1f[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x1d */ 0, DW_AT_containing_type}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x4a */ 0, DW_AT_use_location}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x10 - DW_TAG_reference_type */ static Usage_Tag_Attr tag_attr_10[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x37 - DW_TAG_restrict_type */ static Usage_Tag_Attr tag_attr_37[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x42 - DW_TAG_rvalue_reference_type */ static Usage_Tag_Attr tag_attr_42[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x20 - DW_TAG_set_type */ static Usage_Tag_Attr tag_attr_20[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x40 - DW_TAG_shared_type */ static Usage_Tag_Attr tag_attr_40[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x37 */ 0, DW_AT_count}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x12 - DW_TAG_string_type */ static Usage_Tag_Attr tag_attr_12[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x19 */ 0, DW_AT_string_length}, {/* 0x6f */ 0, DW_AT_string_length_bit_size}, {/* 0x70 */ 0, DW_AT_string_length_byte_size}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x13 - DW_TAG_structure_type */ static Usage_Tag_Attr tag_attr_13[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2e - DW_TAG_subprogram */ static Usage_Tag_Attr tag_attr_2e[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x36 */ 0, DW_AT_calling_convention}, {/* 0x1d */ 0, DW_AT_containing_type}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x66 */ 0, DW_AT_elemental}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x63 */ 0, DW_AT_explicit}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x40 */ 0, DW_AT_frame_base}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x20 */ 0, DW_AT_inline}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x6a */ 0, DW_AT_main_subprogram}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x64 */ 0, DW_AT_object_pointer}, {/* 0x27 */ 0, DW_AT_prototyped}, {/* 0x67 */ 0, DW_AT_pure}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x68 */ 0, DW_AT_recursive}, {/* 0x77 */ 0, DW_AT_reference}, {/* 0x2a */ 0, DW_AT_return_addr}, {/* 0x78 */ 0, DW_AT_rvalue_reference}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x48 */ 0, DW_AT_static_link}, {/* 0x56 */ 0, DW_AT_trampoline}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* 0x4c */ 0, DW_AT_virtuality}, {/* 0x4d */ 0, DW_AT_vtable_elem_location}, {/* */ 0, 0} }; /* 0x21 - DW_TAG_subrange_type */ static Usage_Tag_Attr tag_attr_21[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x2e */ 0, DW_AT_bit_stride}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x51 */ 0, DW_AT_byte_stride}, {/* 0x37 */ 0, DW_AT_count}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x22 */ 0, DW_AT_lower_bound}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x62 */ 0, DW_AT_threads_scaled}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x2f */ 0, DW_AT_upper_bound}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x15 - DW_TAG_subroutine_type */ static Usage_Tag_Attr tag_attr_15[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x27 */ 0, DW_AT_prototyped}, {/* 0x78 */ 0, DW_AT_rvalue_reference}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x43 - DW_TAG_template_alias */ static Usage_Tag_Attr tag_attr_43[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x2f - DW_TAG_template_type_parameter */ static Usage_Tag_Attr tag_attr_2f[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1e */ 0, DW_AT_default_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x30 - DW_TAG_template_value_parameter */ static Usage_Tag_Attr tag_attr_30[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x1e */ 0, DW_AT_default_value}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x31 - DW_TAG_thrown_type */ static Usage_Tag_Attr tag_attr_31[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x32 - DW_TAG_try_block */ static Usage_Tag_Attr tag_attr_32[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x16 - DW_TAG_typedef */ static Usage_Tag_Attr tag_attr_16[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x41 - DW_TAG_type_unit */ static Usage_Tag_Attr tag_attr_41[] = { {/* 0x13 */ 0, DW_AT_language}, {/* 0x10 */ 0, DW_AT_stmt_list}, {/* 0x72 */ 0, DW_AT_str_offsets_base}, {/* 0x53 */ 0, DW_AT_use_UTF8}, {/* */ 0, 0} }; /* 0x17 - DW_TAG_union_type */ static Usage_Tag_Attr tag_attr_17[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x4e */ 0, DW_AT_allocated}, {/* 0x4f */ 0, DW_AT_associated}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x50 */ 0, DW_AT_data_location}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x89 */ 0, DW_AT_export_symbols}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x69 */ 0, DW_AT_signature}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x18 - DW_TAG_unspecified_parameters */ static Usage_Tag_Attr tag_attr_18[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x3b - DW_TAG_unspecified_type */ static Usage_Tag_Attr tag_attr_3b[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x03 */ 0, DW_AT_name}, {/* */ 0, 0} }; /* 0x34 - DW_TAG_variable */ static Usage_Tag_Attr tag_attr_34[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x88 */ 0, DW_AT_alignment}, {/* 0x34 */ 0, DW_AT_artificial}, {/* 0x0b */ 0, DW_AT_byte_size}, {/* 0x0d */ 0, DW_AT_bit_size}, {/* 0x6c */ 0, DW_AT_const_expr}, {/* 0x1c */ 0, DW_AT_const_value}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x5a */ 0, DW_AT_description}, {/* 0x65 */ 0, DW_AT_endianity}, {/* 0x3f */ 0, DW_AT_external}, {/* 0x6e */ 0, DW_AT_linkage_name}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x47 */ 0, DW_AT_specification}, {/* 0x2c */ 0, DW_AT_start_scope}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; /* 0x19 - DW_TAG_variant */ static Usage_Tag_Attr tag_attr_19[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x3d */ 0, DW_AT_discr_list}, {/* 0x16 */ 0, DW_AT_discr_value}, {/* 0x01 */ 0, DW_AT_sibling}, {/* */ 0, 0} }; /* 0x33 - DW_TAG_variant_part */ static Usage_Tag_Attr tag_attr_33[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x31 */ 0, DW_AT_abstract_origin}, {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x15 */ 0, DW_AT_discr}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x35 - DW_TAG_volatile_type */ static Usage_Tag_Attr tag_attr_35[] = { {/* 0x39 */ 0, DW_AT_decl_column}, {/* 0x3a */ 0, DW_AT_decl_file}, {/* 0x3b */ 0, DW_AT_decl_line}, {/* 0x03 */ 0, DW_AT_name}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* */ 0, 0} }; /* 0x22 - DW_TAG_with_stmt */ static Usage_Tag_Attr tag_attr_22[] = { {/* 0x32 */ 0, DW_AT_accessibility}, {/* 0x33 */ 0, DW_AT_address_class}, {/* 0x3c */ 0, DW_AT_declaration}, {/* 0x52 */ 0, DW_AT_entry_pc}, {/* 0x12 */ 0, DW_AT_high_pc}, {/* 0x02 */ 0, DW_AT_location}, {/* 0x11 */ 0, DW_AT_low_pc}, {/* 0x55 */ 0, DW_AT_ranges}, {/* 0x46 */ 0, DW_AT_segment}, {/* 0x01 */ 0, DW_AT_sibling}, {/* 0x49 */ 0, DW_AT_type}, {/* 0x17 */ 0, DW_AT_visibility}, {/* */ 0, 0} }; static Usage_Tag_Attr *usage_tag_attr[] = { 0, tag_attr_01, /* 0x01 - DW_TAG_array_type */ tag_attr_02, /* 0x02 - DW_TAG_class_type */ tag_attr_03, /* 0x03 - DW_TAG_entry_point */ tag_attr_04, /* 0x04 - DW_TAG_enumeration_type */ tag_attr_05, /* 0x05 - DW_TAG_formal_parameter */ 0, 0, tag_attr_08, /* 0x08 - DW_TAG_imported_declaration */ 0, tag_attr_0a, /* 0x0a - DW_TAG_label */ tag_attr_0b, /* 0x0b - DW_TAG_lexical_block */ 0, tag_attr_0d, /* 0x0d - DW_TAG_member */ 0, tag_attr_0f, /* 0x0f - DW_TAG_pointer_type */ tag_attr_10, /* 0x10 - DW_TAG_reference_type */ tag_attr_11, /* 0x11 - DW_TAG_compile_unit */ tag_attr_12, /* 0x12 - DW_TAG_string_type */ tag_attr_13, /* 0x13 - DW_TAG_structure_type */ 0, tag_attr_15, /* 0x15 - DW_TAG_subroutine_type */ tag_attr_16, /* 0x16 - DW_TAG_typedef */ tag_attr_17, /* 0x17 - DW_TAG_union_type */ tag_attr_18, /* 0x18 - DW_TAG_unspecified_parameters */ tag_attr_19, /* 0x19 - DW_TAG_variant */ tag_attr_1a, /* 0x1a - DW_TAG_common_block */ tag_attr_1b, /* 0x1b - DW_TAG_common_inclusion */ tag_attr_1c, /* 0x1c - DW_TAG_inheritance */ tag_attr_1d, /* 0x1d - DW_TAG_inlined_subroutine */ tag_attr_1e, /* 0x1e - DW_TAG_module */ tag_attr_1f, /* 0x1f - DW_TAG_ptr_to_member_type */ tag_attr_20, /* 0x20 - DW_TAG_set_type */ tag_attr_21, /* 0x21 - DW_TAG_subrange_type */ tag_attr_22, /* 0x22 - DW_TAG_with_stmt */ tag_attr_23, /* 0x23 - DW_TAG_access_declaration */ tag_attr_24, /* 0x24 - DW_TAG_base_type */ tag_attr_25, /* 0x25 - DW_TAG_catch_block */ tag_attr_26, /* 0x26 - DW_TAG_const_type */ tag_attr_27, /* 0x27 - DW_TAG_constant */ tag_attr_28, /* 0x28 - DW_TAG_enumerator */ tag_attr_29, /* 0x29 - DW_TAG_file_type */ tag_attr_2a, /* 0x2a - DW_TAG_friend */ tag_attr_2b, /* 0x2b - DW_TAG_namelist */ tag_attr_2c, /* 0x2c - DW_TAG_namelist_item */ tag_attr_2d, /* 0x2d - DW_TAG_packed_type */ tag_attr_2e, /* 0x2e - DW_TAG_subprogram */ tag_attr_2f, /* 0x2f - DW_TAG_template_type_parameter */ tag_attr_30, /* 0x30 - DW_TAG_template_value_parameter */ tag_attr_31, /* 0x31 - DW_TAG_thrown_type */ tag_attr_32, /* 0x32 - DW_TAG_try_block */ tag_attr_33, /* 0x33 - DW_TAG_variant_part */ tag_attr_34, /* 0x34 - DW_TAG_variable */ tag_attr_35, /* 0x35 - DW_TAG_volatile_type */ tag_attr_36, /* 0x36 - DW_TAG_dwarf_procedure */ tag_attr_37, /* 0x37 - DW_TAG_restrict_type */ tag_attr_38, /* 0x38 - DW_TAG_interface_type */ tag_attr_39, /* 0x39 - DW_TAG_namespace */ tag_attr_3a, /* 0x3a - DW_TAG_imported_module */ tag_attr_3b, /* 0x3b - DW_TAG_unspecified_type */ tag_attr_3c, /* 0x3c - DW_TAG_partial_unit */ tag_attr_3d, /* 0x3d - DW_TAG_imported_unit */ 0, tag_attr_3f, /* 0x3f - DW_TAG_condition */ tag_attr_40, /* 0x40 - DW_TAG_shared_type */ tag_attr_41, /* 0x41 - DW_TAG_type_unit */ tag_attr_42, /* 0x42 - DW_TAG_rvalue_reference_type */ tag_attr_43, /* 0x43 - DW_TAG_template_alias */ tag_attr_44, /* 0x44 - DW_TAG_coarray_type */ tag_attr_45, /* 0x45 - DW_TAG_generic_subrange */ tag_attr_46, /* 0x46 - DW_TAG_dynamic_type */ tag_attr_47, /* 0x47 - DW_TAG_atomic_type */ tag_attr_48, /* 0x48 - DW_TAG_call_site */ tag_attr_49, /* 0x49 - DW_TAG_call_site_parameter */ 0 }; typedef struct { Dwarf_Small legal; /* Legal attributes */ Dwarf_Small found; /* Found attributes */ } Rate_Tag_Attr; static Rate_Tag_Attr rate_tag_attr[] = { {0, 0}, {22, 0, /* 0x01 - DW_TAG_array_type */}, {20, 0, /* 0x02 - DW_TAG_class_type */}, {14, 0, /* 0x03 - DW_TAG_entry_point */}, {23, 0, /* 0x04 - DW_TAG_enumeration_type */}, {16, 0, /* 0x05 - DW_TAG_formal_parameter */}, {0, 0}, {0, 0}, { 9, 0, /* 0x08 - DW_TAG_imported_declaration */}, {0, 0}, {10, 0, /* 0x0a - DW_TAG_label */}, {12, 0, /* 0x0b - DW_TAG_lexical_block */}, {0, 0}, {20, 0, /* 0x0d - DW_TAG_member */}, {0, 0}, {10, 0, /* 0x0f - DW_TAG_pointer_type */}, {10, 0, /* 0x10 - DW_TAG_reference_type */}, {21, 0, /* 0x11 - DW_TAG_compile_unit */}, {20, 0, /* 0x12 - DW_TAG_string_type */}, {21, 0, /* 0x13 - DW_TAG_structure_type */}, {0, 0}, {18, 0, /* 0x15 - DW_TAG_subroutine_type */}, {16, 0, /* 0x16 - DW_TAG_typedef */}, {20, 0, /* 0x17 - DW_TAG_union_type */}, { 6, 0, /* 0x18 - DW_TAG_unspecified_parameters */}, { 9, 0, /* 0x19 - DW_TAG_variant */}, {11, 0, /* 0x1a - DW_TAG_common_block */}, { 7, 0, /* 0x1b - DW_TAG_common_inclusion */}, { 8, 0, /* 0x1c - DW_TAG_inheritance */}, {14, 0, /* 0x1d - DW_TAG_inlined_subroutine */}, {16, 0, /* 0x1e - DW_TAG_module */}, {17, 0, /* 0x1f - DW_TAG_ptr_to_member_type */}, {18, 0, /* 0x20 - DW_TAG_set_type */}, {22, 0, /* 0x21 - DW_TAG_subrange_type */}, {12, 0, /* 0x22 - DW_TAG_with_stmt */}, { 7, 0, /* 0x23 - DW_TAG_access_declaration */}, {20, 0, /* 0x24 - DW_TAG_base_type */}, {10, 0, /* 0x25 - DW_TAG_catch_block */}, { 7, 0, /* 0x26 - DW_TAG_const_type */}, {15, 0, /* 0x27 - DW_TAG_constant */}, { 7, 0, /* 0x28 - DW_TAG_enumerator */}, {16, 0, /* 0x29 - DW_TAG_file_type */}, { 6, 0, /* 0x2a - DW_TAG_friend */}, { 9, 0, /* 0x2b - DW_TAG_namelist */}, { 5, 0, /* 0x2c - DW_TAG_namelist_item */}, { 7, 0, /* 0x2d - DW_TAG_packed_type */}, {40, 0, /* 0x2e - DW_TAG_subprogram */}, { 8, 0, /* 0x2f - DW_TAG_template_type_parameter */}, {10, 0, /* 0x30 - DW_TAG_template_value_parameter */}, { 9, 0, /* 0x31 - DW_TAG_thrown_type */}, {10, 0, /* 0x32 - DW_TAG_try_block */}, { 9, 0, /* 0x33 - DW_TAG_variant_part */}, {24, 0, /* 0x34 - DW_TAG_variable */}, { 6, 0, /* 0x35 - DW_TAG_volatile_type */}, { 1, 0, /* 0x36 - DW_TAG_dwarf_procedure */}, { 6, 0, /* 0x37 - DW_TAG_restrict_type */}, {10, 0, /* 0x38 - DW_TAG_interface_type */}, { 9, 0, /* 0x39 - DW_TAG_namespace */}, { 6, 0, /* 0x3a - DW_TAG_imported_module */}, { 5, 0, /* 0x3b - DW_TAG_unspecified_type */}, {22, 0, /* 0x3c - DW_TAG_partial_unit */}, { 1, 0, /* 0x3d - DW_TAG_imported_unit */}, {0, 0}, { 5, 0, /* 0x3f - DW_TAG_condition */}, {10, 0, /* 0x40 - DW_TAG_shared_type */}, { 4, 0, /* 0x41 - DW_TAG_type_unit */}, { 6, 0, /* 0x42 - DW_TAG_rvalue_reference_type */}, {16, 0, /* 0x43 - DW_TAG_template_alias */}, { 6, 0, /* 0x44 - DW_TAG_coarray_type */}, {21, 0, /* 0x45 - DW_TAG_generic_subrange */}, {12, 0, /* 0x46 - DW_TAG_dynamic_type */}, { 3, 0, /* 0x47 - DW_TAG_atomic_type */}, {10, 0, /* 0x48 - DW_TAG_call_site */}, { 8, 0, /* 0x49 - DW_TAG_call_site_parameter */}, {0, 0} }; #endif /* HAVE_USAGE_TAG_ATTR */ #define ATTR_TREE_ROW_COUNT 74 #define ATTR_TREE_COLUMN_COUNT 5 static unsigned int tag_attr_combination_table[ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = { /* 0x00 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x01 - DW_TAG_array_type */ { 0x00802a0a,0x1e065000,0x0401c280,0x00020000,0x00000100,}, /* 0x02 - DW_TAG_class_type */ { 0x2080280a,0x1e061000,0x0401c080,0x00000200,0x00000100,}, /* 0x03 - DW_TAG_entry_point */ { 0x0002000a,0x0e080400,0x04000341,0x00004000,0x00000000,}, /* 0x04 - DW_TAG_enumeration_type */ { 0x0080280a,0x1e065000,0x0403c280,0x00002200,0x00000100,}, /* 0x05 - DW_TAG_formal_parameter */ { 0x5000000e,0x0e120002,0x04000a40,0x00000020,0x00000000,}, /* 0x06 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x07 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x08 - DW_TAG_imported_declaration */ { 0x0100000a,0x0e041000,0x04000000,0x00000000,0x00000000,}, /* 0x09 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0a - DW_TAG_label */ { 0x0002000a,0x0e021000,0x04000040,0x00000000,0x00000000,}, /* 0x0b - DW_TAG_lexical_block */ { 0x0006000a,0x0e020000,0x04240040,0x00000000,0x00000000,}, /* 0x0c - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0d - DW_TAG_member */ { 0x1080380a,0x9f140000,0x04000200,0x00000802,0x00000000,}, /* 0x0e - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x0f - DW_TAG_pointer_type */ { 0x0000280a,0x0e080000,0x00000200,0x00000000,0x00000100,}, /* 0x10 - DW_TAG_reference_type */ { 0x0000280a,0x0e080000,0x00000200,0x00000000,0x00000100,}, /* 0x11 - DW_TAG_compile_unit */ { 0x080f0008,0x00200020,0x002c004c,0x027c0400,0x00000000,}, /* 0x12 - DW_TAG_string_type */ { 0x0280280a,0x1e061000,0x0401c040,0x00018000,0x00000000,}, /* 0x13 - DW_TAG_structure_type */ { 0x0080280a,0x1e061000,0x0401c080,0x00004200,0x00000300,}, /* 0x14 - */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x15 - DW_TAG_subroutine_type */ { 0x0080000a,0x1e0e1080,0x0401c200,0x01000000,0x00000000,}, /* 0x16 - DW_TAG_typedef */ { 0x0080000a,0x1e061000,0x0401c200,0x00000000,0x00000100,}, /* 0x17 - DW_TAG_union_type */ { 0x0080280a,0x1e061000,0x0401c080,0x00000200,0x00000300,}, /* 0x18 - DW_TAG_unspecified_parameters */ { 0x00000002,0x0e120000,0x00000000,0x00000000,0x00000000,}, /* 0x19 - DW_TAG_variant */ { 0x00400002,0x3e060000,0x00000000,0x00000000,0x00000000,}, /* 0x1a - DW_TAG_common_block */ { 0x0080000e,0x1e000000,0x04000040,0x00004000,0x00000000,}, /* 0x1b - DW_TAG_common_inclusion */ { 0x04800002,0x1e000000,0x00000000,0x00000000,0x00000000,}, /* 0x1c - DW_TAG_inheritance */ { 0x00000002,0x0f040000,0x00001200,0x00000000,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0x00060002,0x00021400,0x03e40040,0x00001000,0x00000000,}, /* 0x1e - DW_TAG_module */ { 0x0086000a,0x1e040000,0x042400e0,0x00000000,0x00000000,}, /* 0x1f - DW_TAG_ptr_to_member_type */ { 0x2080000a,0x1e0a0000,0x0401c600,0x00000000,0x00000100,}, /* 0x20 - DW_TAG_set_type */ { 0x0080280a,0x1e061000,0x0401c200,0x00000000,0x00000100,}, /* 0x21 - DW_TAG_subrange_type */ { 0x0080280a,0x1e86c004,0x0403c200,0x00000004,0x00000000,}, /* 0x22 - DW_TAG_with_stmt */ { 0x00860006,0x100c0000,0x00240240,0x00000000,0x00000000,}, /* 0x23 - DW_TAG_access_declaration */ { 0x0000000a,0x0e040000,0x04000000,0x00000000,0x00000000,}, /* 0x24 - DW_TAG_base_type */ { 0x0000380a,0x40000000,0xfc01c000,0x00000821,0x00000100,}, /* 0x25 - DW_TAG_catch_block */ { 0x00060002,0x0e020000,0x00240040,0x00000000,0x00000000,}, /* 0x26 - DW_TAG_const_type */ { 0x0000000a,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x27 - DW_TAG_constant */ { 0x1080000a,0x9e041000,0x04000200,0x00004020,0x00000000,}, /* 0x28 - DW_TAG_enumerator */ { 0x1000000a,0x0e000000,0x04000000,0x00000000,0x00000000,}, /* 0x29 - DW_TAG_file_type */ { 0x0080280a,0x0e021000,0x0401c200,0x00000000,0x00000100,}, /* 0x2a - DW_TAG_friend */ { 0x00000002,0x0e020000,0x00000002,0x00000000,0x00000000,}, /* 0x2b - DW_TAG_namelist */ { 0x0080000a,0x1e060000,0x00000000,0x00000000,0x00000000,}, /* 0x2c - DW_TAG_namelist_item */ { 0x00000002,0x0e000000,0x00000010,0x00000000,0x00000000,}, /* 0x2d - DW_TAG_packed_type */ { 0x0000000a,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x2e - DW_TAG_subprogram */ { 0x2086000a,0x9e5e1481,0x046433c1,0x018045d8,0x00000000,}, /* 0x2f - DW_TAG_template_type_parameter */ { 0x4000000a,0x0e000000,0x04000200,0x00000000,0x00000000,}, /* 0x30 - DW_TAG_template_value_parameter */ { 0x5000000e,0x0e000000,0x04000200,0x00000000,0x00000000,}, /* 0x31 - DW_TAG_thrown_type */ { 0x00000002,0x0e000000,0x0001c200,0x00000000,0x00000100,}, /* 0x32 - DW_TAG_try_block */ { 0x00060002,0x0e020000,0x00240040,0x00000000,0x00000000,}, /* 0x33 - DW_TAG_variant_part */ { 0x00200002,0x1e060000,0x00000200,0x00000000,0x00000000,}, /* 0x34 - DW_TAG_variable */ { 0x1080280e,0x9e161000,0x040002c0,0x00005020,0x00000100,}, /* 0x35 - DW_TAG_volatile_type */ { 0x0000000a,0x0e000000,0x00000200,0x00000000,0x00000000,}, /* 0x36 - DW_TAG_dwarf_procedure */ { 0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x37 - DW_TAG_restrict_type */ { 0x00000002,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x38 - DW_TAG_interface_type */ { 0x0000000a,0x0e041000,0x04000000,0x00000200,0x00000100,}, /* 0x39 - DW_TAG_namespace */ { 0x0000000a,0x0e001000,0x04100000,0x00000000,0x00000200,}, /* 0x3a - DW_TAG_imported_module */ { 0x01000002,0x0e001000,0x00000000,0x00000000,0x00000000,}, /* 0x3b - DW_TAG_unspecified_type */ { 0x00000008,0x0e000000,0x04000000,0x00000000,0x00000000,}, /* 0x3c - DW_TAG_partial_unit */ { 0x080f0008,0x00200020,0x042c004c,0x027c0400,0x00000000,}, /* 0x3d - DW_TAG_imported_unit */ { 0x01000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x3e - DW_TAG_mutable_type */ { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,}, /* 0x3f - DW_TAG_condition */ { 0x0000000a,0x0e000000,0x00000000,0x00000000,0x00000000,}, /* 0x40 - DW_TAG_shared_type */ { 0x0000000a,0x0e800000,0x0000c200,0x00000000,0x00000100,}, /* 0x41 - DW_TAG_type_unit */ { 0x00090000,0x00000000,0x00080000,0x00040000,0x00000000,}, /* 0x42 - DW_TAG_rvalue_reference_type */ { 0x00000008,0x0e080000,0x00000200,0x00000000,0x00000000,}, /* 0x43 - DW_TAG_template_alias */ { 0x0080000a,0x1e061000,0x0401c200,0x00000200,0x00000000,}, /* 0x44 - DW_TAG_coarray_type */ { 0x00000002,0x0e000000,0x00000200,0x00000000,0x00000100,}, /* 0x45 - DW_TAG_generic_subrange */ { 0x0080280a,0x1e82c004,0x0403c200,0x00000004,0x00000000,}, /* 0x46 - DW_TAG_dynamic_type */ { 0x0000000a,0x0e020000,0x0401c200,0x00000000,0x00000100,}, /* 0x47 - DW_TAG_atomic_type */ { 0x00000002,0x00000000,0x00000200,0x00000000,0x00000100,}, /* 0x48 - DW_TAG_call_site */ { 0x00000000,0x00000000,0x03800200,0xa0000000,0x0000001e,}, /* 0x49 - DW_TAG_call_site_parameter */ { 0x0000000e,0x00000000,0x00000200,0x40000000,0x00000061,}, }; /* END FILE */ dwarfutils-20200114/dwarfdump/dwarfdump-tt-ext-table.h000066400000000000000000000025221361531463500226040ustar00rootroot00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #define TAG_TREE_EXT_COLUMN_COUNT 5 #define TAG_TREE_EXT_ROW_COUNT 9 /* Common extensions */ static unsigned int tag_tree_combination_ext_table[TAG_TREE_EXT_ROW_COUNT][TAG_TREE_EXT_COLUMN_COUNT] = { /* 0x13 - DW_TAG_structure_type */ { 0x00000013,0x00000034,0x00004106,0x00004107,0x00004108,}, /* 0x02 - DW_TAG_class_type */ { 0x00000002,0x00000034,0x00004106,0x00004107,0x00004108,}, /* 0x0b - DW_TAG_lexical_block */ { 0x0000000b,0x00004109,0x00000000,0x00000000,0x00000000,}, /* 0x2e - DW_TAG_subprogram */ { 0x0000002e,0x00004109,0x00004106,0x00004107,0x00004108,}, /* 0x17 - DW_TAG_union_type */ { 0x00000017,0x00004106,0x00004107,0x00004108,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0x0000001d,0x00004109,0x00000000,0x00000000,0x00000000,}, /* 0x4109 - DW_TAG_GNU_call_site */ { 0x00004109,0x0000410a,0x00000000,0x00000000,0x00000000,}, /* 0x4107 - DW_TAG_GNU_template_parameter_pack */ { 0x00004107,0x0000002f,0x00000030,0x00004106,0x00000000,}, /* 0x4108 - DW_TAG_GNU_formal_parameter_pack */ { 0x00004108,0x00000005,0x00000000,0x00000000,0x00000000,}, }; /* END FILE */ dwarfutils-20200114/dwarfdump/dwarfdump-tt-table.h000066400000000000000000001061031361531463500220060ustar00rootroot00000000000000/* Generated code, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #ifndef HAVE_USAGE_TAG_ATTR #define HAVE_USAGE_TAG_ATTR 1 #endif /* HAVE_USAGE_TAG_ATTR */ #ifdef HAVE_USAGE_TAG_ATTR #include "dwarf.h" #include "libdwarf.h" typedef struct { unsigned int count; /* Tag count */ Dwarf_Half tag; /* Tag value */ } Usage_Tag_Tree; /* 0x23 - DW_TAG_access_declaration */ static Usage_Tag_Tree tag_tree_23[] = { {/* */ 0, 0} }; /* 0x01 - DW_TAG_array_type */ static Usage_Tag_Tree tag_tree_01[] = { {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* */ 0, 0} }; /* 0x24 - DW_TAG_base_type */ static Usage_Tag_Tree tag_tree_24[] = { {/* */ 0, 0} }; /* 0x48 - DW_TAG_call_site */ static Usage_Tag_Tree tag_tree_48[] = { {/* 0x49 */ 0, DW_TAG_call_site_parameter}, {/* */ 0, 0} }; /* 0x49 - DW_TAG_call_site_parameter */ static Usage_Tag_Tree tag_tree_49[] = { {/* */ 0, 0} }; /* 0x25 - DW_TAG_catch_block */ static Usage_Tag_Tree tag_tree_25[] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x02 - DW_TAG_class_type */ static Usage_Tag_Tree tag_tree_02[] = { {/* 0x0d */ 0, DW_TAG_member}, {/* 0x1c */ 0, DW_TAG_inheritance}, {/* 0x23 */ 0, DW_TAG_access_declaration}, {/* 0x2a */ 0, DW_TAG_friend}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* */ 0, 0} }; /* 0x44 - DW_TAG_coarray_type */ static Usage_Tag_Tree tag_tree_44[] = { {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* */ 0, 0} }; /* 0x1a - DW_TAG_common_block */ static Usage_Tag_Tree tag_tree_1a[] = { {/* 0x34 */ 0, DW_TAG_variable}, {/* */ 0, 0} }; /* 0x1b - DW_TAG_common_inclusion */ static Usage_Tag_Tree tag_tree_1b[] = { {/* */ 0, 0} }; /* 0x11 - DW_TAG_compile_unit */ static Usage_Tag_Tree tag_tree_11[] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x36 */ 0, DW_TAG_dwarf_procedure}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x39 */ 0, DW_TAG_namespace}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* 0x3b */ 0, DW_TAG_unspecified_type}, {/* */ 0, 0} }; /* 0x41 - DW_TAG_type_unit */ static Usage_Tag_Tree tag_tree_41[] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x39 */ 0, DW_TAG_namespace}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* */ 0, 0} }; /* 0x3f - DW_TAG_condition */ static Usage_Tag_Tree tag_tree_3f[] = { {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* */ 0, 0} }; /* 0x47 - DW_TAG_atomic_type */ static Usage_Tag_Tree tag_tree_47[] = { {/* */ 0, 0} }; /* 0x26 - DW_TAG_const_type */ static Usage_Tag_Tree tag_tree_26[] = { {/* */ 0, 0} }; /* 0x27 - DW_TAG_constant */ static Usage_Tag_Tree tag_tree_27[] = { {/* */ 0, 0} }; /* 0x36 - DW_TAG_dwarf_procedure */ static Usage_Tag_Tree tag_tree_36[] = { {/* */ 0, 0} }; /* 0x03 - DW_TAG_entry_point */ static Usage_Tag_Tree tag_tree_03[] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x1b */ 0, DW_TAG_common_inclusion}, {/* */ 0, 0} }; /* 0x04 - DW_TAG_enumeration_type */ static Usage_Tag_Tree tag_tree_04[] = { {/* 0x28 */ 0, DW_TAG_enumerator}, {/* */ 0, 0} }; /* 0x28 - DW_TAG_enumerator */ static Usage_Tag_Tree tag_tree_28[] = { {/* */ 0, 0} }; /* 0x29 - DW_TAG_file_type */ static Usage_Tag_Tree tag_tree_29[] = { {/* */ 0, 0} }; /* 0x05 - DW_TAG_formal_parameter */ static Usage_Tag_Tree tag_tree_05[] = { {/* */ 0, 0} }; /* 0x2a - DW_TAG_friend */ static Usage_Tag_Tree tag_tree_2a[] = { {/* */ 0, 0} }; /* 0x08 - DW_TAG_imported_declaration */ static Usage_Tag_Tree tag_tree_08[] = { {/* */ 0, 0} }; /* 0x3a - DW_TAG_imported_module */ static Usage_Tag_Tree tag_tree_3a[] = { {/* */ 0, 0} }; /* 0x3d - DW_TAG_imported_unit */ static Usage_Tag_Tree tag_tree_3d[] = { {/* */ 0, 0} }; /* 0x1c - DW_TAG_inheritance */ static Usage_Tag_Tree tag_tree_1c[] = { {/* */ 0, 0} }; /* 0x1d - DW_TAG_inlined_subroutine */ static Usage_Tag_Tree tag_tree_1d[] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x0b */ 0, DW_TAG_lexical_block}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x38 - DW_TAG_interface_type */ static Usage_Tag_Tree tag_tree_38[] = { {/* 0x0d */ 0, DW_TAG_member}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* */ 0, 0} }; /* 0x0a - DW_TAG_label */ static Usage_Tag_Tree tag_tree_0a[] = { {/* */ 0, 0} }; /* 0x0b - DW_TAG_lexical_block */ static Usage_Tag_Tree tag_tree_0b[] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x0a */ 0, DW_TAG_label}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x0b */ 0, DW_TAG_lexical_block}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* */ 0, 0} }; /* 0x0d - DW_TAG_member */ static Usage_Tag_Tree tag_tree_0d[] = { {/* */ 0, 0} }; /* 0x1e - DW_TAG_module */ static Usage_Tag_Tree tag_tree_1e[] = { {/* */ 0, 0} }; /* 0x2b - DW_TAG_namelist */ static Usage_Tag_Tree tag_tree_2b[] = { {/* 0x2c */ 0, DW_TAG_namelist_item}, {/* */ 0, 0} }; /* 0x2c - DW_TAG_namelist_item */ static Usage_Tag_Tree tag_tree_2c[] = { {/* */ 0, 0} }; /* 0x39 - DW_TAG_namespace */ static Usage_Tag_Tree tag_tree_39[] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x39 */ 0, DW_TAG_namespace}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* */ 0, 0} }; /* 0x2d - DW_TAG_packed_type */ static Usage_Tag_Tree tag_tree_2d[] = { {/* */ 0, 0} }; /* 0x3c - DW_TAG_partial_unit */ static Usage_Tag_Tree tag_tree_3c[] = { {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x46 */ 0, DW_TAG_dynamic_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1e */ 0, DW_TAG_module}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x0f - DW_TAG_pointer_type */ static Usage_Tag_Tree tag_tree_0f[] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x1f - DW_TAG_ptr_to_member_type */ static Usage_Tag_Tree tag_tree_1f[] = { {/* */ 0, 0} }; /* 0x10 - DW_TAG_reference_type */ static Usage_Tag_Tree tag_tree_10[] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x42 - DW_TAG_rvalue_reference_type */ static Usage_Tag_Tree tag_tree_42[] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x37 - DW_TAG_restrict_type */ static Usage_Tag_Tree tag_tree_37[] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x20 - DW_TAG_set_type */ static Usage_Tag_Tree tag_tree_20[] = { {/* */ 0, 0} }; /* 0x40 - DW_TAG_shared_type */ static Usage_Tag_Tree tag_tree_40[] = { {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x37 */ 0, DW_TAG_restrict_type}, {/* 0x42 */ 0, DW_TAG_rvalue_reference_type}, {/* 0x40 */ 0, DW_TAG_shared_type}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* */ 0, 0} }; /* 0x12 - DW_TAG_string_type */ static Usage_Tag_Tree tag_tree_12[] = { {/* */ 0, 0} }; /* 0x13 - DW_TAG_structure_type */ static Usage_Tag_Tree tag_tree_13[] = { {/* 0x0d */ 0, DW_TAG_member}, {/* 0x1c */ 0, DW_TAG_inheritance}, {/* 0x23 */ 0, DW_TAG_access_declaration}, {/* 0x2a */ 0, DW_TAG_friend}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x33 */ 0, DW_TAG_variant_part}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* 0x43 */ 0, DW_TAG_template_alias}, {/* */ 0, 0} }; /* 0x2e - DW_TAG_subprogram */ static Usage_Tag_Tree tag_tree_2e[] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* 0x31 */ 0, DW_TAG_thrown_type}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x1b */ 0, DW_TAG_common_inclusion}, {/* 0x1a */ 0, DW_TAG_common_block}, {/* 0x01 */ 0, DW_TAG_array_type}, {/* 0x44 */ 0, DW_TAG_coarray_type}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x0f */ 0, DW_TAG_pointer_type}, {/* 0x10 */ 0, DW_TAG_reference_type}, {/* 0x12 */ 0, DW_TAG_string_type}, {/* 0x0b */ 0, DW_TAG_lexical_block}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x15 */ 0, DW_TAG_subroutine_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* 0x1d */ 0, DW_TAG_inlined_subroutine}, {/* 0x1f */ 0, DW_TAG_ptr_to_member_type}, {/* 0x20 */ 0, DW_TAG_set_type}, {/* 0x21 */ 0, DW_TAG_subrange_type}, {/* 0x45 */ 0, DW_TAG_generic_subrange}, {/* 0x24 */ 0, DW_TAG_base_type}, {/* 0x26 */ 0, DW_TAG_const_type}, {/* 0x47 */ 0, DW_TAG_atomic_type}, {/* 0x27 */ 0, DW_TAG_constant}, {/* 0x29 */ 0, DW_TAG_file_type}, {/* 0x2b */ 0, DW_TAG_namelist}, {/* 0x2d */ 0, DW_TAG_packed_type}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x34 */ 0, DW_TAG_variable}, {/* 0x35 */ 0, DW_TAG_volatile_type}, {/* 0x0a */ 0, DW_TAG_label}, {/* 0x3a */ 0, DW_TAG_imported_module}, {/* 0x08 */ 0, DW_TAG_imported_declaration}, {/* */ 0, 0} }; /* 0x21 - DW_TAG_subrange_type */ static Usage_Tag_Tree tag_tree_21[] = { {/* */ 0, 0} }; /* 0x45 - DW_TAG_generic_subrange */ static Usage_Tag_Tree tag_tree_45[] = { {/* */ 0, 0} }; /* 0x15 - DW_TAG_subroutine_type */ static Usage_Tag_Tree tag_tree_15[] = { {/* 0x05 */ 0, DW_TAG_formal_parameter}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x18 */ 0, DW_TAG_unspecified_parameters}, {/* */ 0, 0} }; /* 0x2f - DW_TAG_template_type_parameter */ static Usage_Tag_Tree tag_tree_2f[] = { {/* */ 0, 0} }; /* 0x30 - DW_TAG_template_value_parameter */ static Usage_Tag_Tree tag_tree_30[] = { {/* */ 0, 0} }; /* 0x31 - DW_TAG_thrown_type */ static Usage_Tag_Tree tag_tree_31[] = { {/* */ 0, 0} }; /* 0x32 - DW_TAG_try_block */ static Usage_Tag_Tree tag_tree_32[] = { {/* */ 0, 0} }; /* 0x16 - DW_TAG_typedef */ static Usage_Tag_Tree tag_tree_16[] = { {/* */ 0, 0} }; /* 0x17 - DW_TAG_union_type */ static Usage_Tag_Tree tag_tree_17[] = { {/* 0x2a */ 0, DW_TAG_friend}, {/* 0x0d */ 0, DW_TAG_member}, {/* 0x02 */ 0, DW_TAG_class_type}, {/* 0x04 */ 0, DW_TAG_enumeration_type}, {/* 0x13 */ 0, DW_TAG_structure_type}, {/* 0x16 */ 0, DW_TAG_typedef}, {/* 0x2e */ 0, DW_TAG_subprogram}, {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* 0x17 */ 0, DW_TAG_union_type}, {/* */ 0, 0} }; /* 0x43 - DW_TAG_template_alias */ static Usage_Tag_Tree tag_tree_43[] = { {/* 0x2f */ 0, DW_TAG_template_type_parameter}, {/* 0x30 */ 0, DW_TAG_template_value_parameter}, {/* */ 0, 0} }; /* 0x18 - DW_TAG_unspecified_parameters */ static Usage_Tag_Tree tag_tree_18[] = { {/* */ 0, 0} }; /* 0x3b - DW_TAG_unspecified_type */ static Usage_Tag_Tree tag_tree_3b[] = { {/* */ 0, 0} }; /* 0x34 - DW_TAG_variable */ static Usage_Tag_Tree tag_tree_34[] = { {/* */ 0, 0} }; /* 0x19 - DW_TAG_variant */ static Usage_Tag_Tree tag_tree_19[] = { {/* 0x33 */ 0, DW_TAG_variant_part}, {/* */ 0, 0} }; /* 0x33 - DW_TAG_variant_part */ static Usage_Tag_Tree tag_tree_33[] = { {/* */ 0, 0} }; /* 0x35 - DW_TAG_volatile_type */ static Usage_Tag_Tree tag_tree_35[] = { {/* */ 0, 0} }; /* 0x22 - DW_TAG_with_stmt */ static Usage_Tag_Tree tag_tree_22[] = { {/* */ 0, 0} }; static Usage_Tag_Tree *usage_tag_tree[] = { 0, tag_tree_01, /* 0x01 - DW_TAG_array_type */ tag_tree_02, /* 0x02 - DW_TAG_class_type */ tag_tree_03, /* 0x03 - DW_TAG_entry_point */ tag_tree_04, /* 0x04 - DW_TAG_enumeration_type */ tag_tree_05, /* 0x05 - DW_TAG_formal_parameter */ 0, 0, tag_tree_08, /* 0x08 - DW_TAG_imported_declaration */ 0, tag_tree_0a, /* 0x0a - DW_TAG_label */ tag_tree_0b, /* 0x0b - DW_TAG_lexical_block */ 0, tag_tree_0d, /* 0x0d - DW_TAG_member */ 0, tag_tree_0f, /* 0x0f - DW_TAG_pointer_type */ tag_tree_10, /* 0x10 - DW_TAG_reference_type */ tag_tree_11, /* 0x11 - DW_TAG_compile_unit */ tag_tree_12, /* 0x12 - DW_TAG_string_type */ tag_tree_13, /* 0x13 - DW_TAG_structure_type */ 0, tag_tree_15, /* 0x15 - DW_TAG_subroutine_type */ tag_tree_16, /* 0x16 - DW_TAG_typedef */ tag_tree_17, /* 0x17 - DW_TAG_union_type */ tag_tree_18, /* 0x18 - DW_TAG_unspecified_parameters */ tag_tree_19, /* 0x19 - DW_TAG_variant */ tag_tree_1a, /* 0x1a - DW_TAG_common_block */ tag_tree_1b, /* 0x1b - DW_TAG_common_inclusion */ tag_tree_1c, /* 0x1c - DW_TAG_inheritance */ tag_tree_1d, /* 0x1d - DW_TAG_inlined_subroutine */ tag_tree_1e, /* 0x1e - DW_TAG_module */ tag_tree_1f, /* 0x1f - DW_TAG_ptr_to_member_type */ tag_tree_20, /* 0x20 - DW_TAG_set_type */ tag_tree_21, /* 0x21 - DW_TAG_subrange_type */ tag_tree_22, /* 0x22 - DW_TAG_with_stmt */ tag_tree_23, /* 0x23 - DW_TAG_access_declaration */ tag_tree_24, /* 0x24 - DW_TAG_base_type */ tag_tree_25, /* 0x25 - DW_TAG_catch_block */ tag_tree_26, /* 0x26 - DW_TAG_const_type */ tag_tree_27, /* 0x27 - DW_TAG_constant */ tag_tree_28, /* 0x28 - DW_TAG_enumerator */ tag_tree_29, /* 0x29 - DW_TAG_file_type */ tag_tree_2a, /* 0x2a - DW_TAG_friend */ tag_tree_2b, /* 0x2b - DW_TAG_namelist */ tag_tree_2c, /* 0x2c - DW_TAG_namelist_item */ tag_tree_2d, /* 0x2d - DW_TAG_packed_type */ tag_tree_2e, /* 0x2e - DW_TAG_subprogram */ tag_tree_2f, /* 0x2f - DW_TAG_template_type_parameter */ tag_tree_30, /* 0x30 - DW_TAG_template_value_parameter */ tag_tree_31, /* 0x31 - DW_TAG_thrown_type */ tag_tree_32, /* 0x32 - DW_TAG_try_block */ tag_tree_33, /* 0x33 - DW_TAG_variant_part */ tag_tree_34, /* 0x34 - DW_TAG_variable */ tag_tree_35, /* 0x35 - DW_TAG_volatile_type */ tag_tree_36, /* 0x36 - DW_TAG_dwarf_procedure */ tag_tree_37, /* 0x37 - DW_TAG_restrict_type */ tag_tree_38, /* 0x38 - DW_TAG_interface_type */ tag_tree_39, /* 0x39 - DW_TAG_namespace */ tag_tree_3a, /* 0x3a - DW_TAG_imported_module */ tag_tree_3b, /* 0x3b - DW_TAG_unspecified_type */ tag_tree_3c, /* 0x3c - DW_TAG_partial_unit */ tag_tree_3d, /* 0x3d - DW_TAG_imported_unit */ 0, tag_tree_3f, /* 0x3f - DW_TAG_condition */ tag_tree_40, /* 0x40 - DW_TAG_shared_type */ tag_tree_41, /* 0x41 - DW_TAG_type_unit */ tag_tree_42, /* 0x42 - DW_TAG_rvalue_reference_type */ tag_tree_43, /* 0x43 - DW_TAG_template_alias */ tag_tree_44, /* 0x44 - DW_TAG_coarray_type */ tag_tree_45, /* 0x45 - DW_TAG_generic_subrange */ 0, tag_tree_47, /* 0x47 - DW_TAG_atomic_type */ tag_tree_48, /* 0x48 - DW_TAG_call_site */ tag_tree_49, /* 0x49 - DW_TAG_call_site_parameter */ 0 }; typedef struct { Dwarf_Small legal; /* Legal tags */ Dwarf_Small found; /* Found tags */ } Rate_Tag_Tree; static Rate_Tag_Tree rate_tag_tree[] = { {0, 0}, { 4, 0 /* 0x01 - DW_TAG_array_type */}, {21, 0 /* 0x02 - DW_TAG_class_type */}, { 3, 0 /* 0x03 - DW_TAG_entry_point */}, { 1, 0 /* 0x04 - DW_TAG_enumeration_type */}, { 0, 0 /* 0x05 - DW_TAG_formal_parameter */}, {0, 0}, {0, 0}, { 0, 0 /* 0x08 - DW_TAG_imported_declaration */}, {0, 0}, { 0, 0 /* 0x0a - DW_TAG_label */}, {32, 0 /* 0x0b - DW_TAG_lexical_block */}, {0, 0}, { 0, 0 /* 0x0d - DW_TAG_member */}, {0, 0}, { 8, 0 /* 0x0f - DW_TAG_pointer_type */}, { 8, 0 /* 0x10 - DW_TAG_reference_type */}, {37, 0 /* 0x11 - DW_TAG_compile_unit */}, { 0, 0 /* 0x12 - DW_TAG_string_type */}, {21, 0 /* 0x13 - DW_TAG_structure_type */}, {0, 0}, { 3, 0 /* 0x15 - DW_TAG_subroutine_type */}, { 0, 0 /* 0x16 - DW_TAG_typedef */}, {10, 0 /* 0x17 - DW_TAG_union_type */}, { 0, 0 /* 0x18 - DW_TAG_unspecified_parameters */}, { 1, 0 /* 0x19 - DW_TAG_variant */}, { 1, 0 /* 0x1a - DW_TAG_common_block */}, { 0, 0 /* 0x1b - DW_TAG_common_inclusion */}, { 0, 0 /* 0x1c - DW_TAG_inheritance */}, {30, 0 /* 0x1d - DW_TAG_inlined_subroutine */}, { 0, 0 /* 0x1e - DW_TAG_module */}, { 0, 0 /* 0x1f - DW_TAG_ptr_to_member_type */}, { 0, 0 /* 0x20 - DW_TAG_set_type */}, { 0, 0 /* 0x21 - DW_TAG_subrange_type */}, { 0, 0 /* 0x22 - DW_TAG_with_stmt */}, { 0, 0 /* 0x23 - DW_TAG_access_declaration */}, { 0, 0 /* 0x24 - DW_TAG_base_type */}, {25, 0 /* 0x25 - DW_TAG_catch_block */}, { 0, 0 /* 0x26 - DW_TAG_const_type */}, { 0, 0 /* 0x27 - DW_TAG_constant */}, { 0, 0 /* 0x28 - DW_TAG_enumerator */}, { 0, 0 /* 0x29 - DW_TAG_file_type */}, { 0, 0 /* 0x2a - DW_TAG_friend */}, { 1, 0 /* 0x2b - DW_TAG_namelist */}, { 0, 0 /* 0x2c - DW_TAG_namelist_item */}, { 0, 0 /* 0x2d - DW_TAG_packed_type */}, {38, 0 /* 0x2e - DW_TAG_subprogram */}, { 0, 0 /* 0x2f - DW_TAG_template_type_parameter */}, { 0, 0 /* 0x30 - DW_TAG_template_value_parameter */}, { 0, 0 /* 0x31 - DW_TAG_thrown_type */}, { 0, 0 /* 0x32 - DW_TAG_try_block */}, { 0, 0 /* 0x33 - DW_TAG_variant_part */}, { 0, 0 /* 0x34 - DW_TAG_variable */}, { 0, 0 /* 0x35 - DW_TAG_volatile_type */}, { 0, 0 /* 0x36 - DW_TAG_dwarf_procedure */}, { 8, 0 /* 0x37 - DW_TAG_restrict_type */}, { 2, 0 /* 0x38 - DW_TAG_interface_type */}, {31, 0 /* 0x39 - DW_TAG_namespace */}, { 0, 0 /* 0x3a - DW_TAG_imported_module */}, { 0, 0 /* 0x3b - DW_TAG_unspecified_type */}, {30, 0 /* 0x3c - DW_TAG_partial_unit */}, { 0, 0 /* 0x3d - DW_TAG_imported_unit */}, {0, 0}, { 2, 0 /* 0x3f - DW_TAG_condition */}, { 9, 0 /* 0x40 - DW_TAG_shared_type */}, {33, 0 /* 0x41 - DW_TAG_type_unit */}, { 8, 0 /* 0x42 - DW_TAG_rvalue_reference_type */}, { 2, 0 /* 0x43 - DW_TAG_template_alias */}, { 5, 0 /* 0x44 - DW_TAG_coarray_type */}, { 0, 0 /* 0x45 - DW_TAG_generic_subrange */}, {0, 0}, { 0, 0 /* 0x47 - DW_TAG_atomic_type */}, { 1, 0 /* 0x48 - DW_TAG_call_site */}, { 0, 0 /* 0x49 - DW_TAG_call_site_parameter */}, {0, 0} }; #endif /* HAVE_USAGE_TAG_ATTR */ #define TAG_TREE_COLUMN_COUNT 3 #define TAG_TREE_ROW_COUNT 73 static unsigned int tag_tree_combination_table[TAG_TREE_ROW_COUNT][TAG_TREE_COLUMN_COUNT] = { /* 0x00 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x01 - DW_TAG_array_type */ { 0x00000010,0x00000002,0x00000060,}, /* 0x02 - DW_TAG_class_type */ { 0x90c8a114,0x0001c458,0x000000d8,}, /* 0x03 - DW_TAG_entry_point */ { 0x09000020,0x00000000,0x00000000,}, /* 0x04 - DW_TAG_enumeration_type */ { 0x00000000,0x00000100,0x00000000,}, /* 0x05 - DW_TAG_formal_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x06 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x07 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x08 - DW_TAG_imported_declaration */ { 0x00000000,0x00000000,0x00000000,}, /* 0x09 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0a - DW_TAG_label */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0b - DW_TAG_lexical_block */ { 0xe0ed8d36,0x043068d3,0x000000f0,}, /* 0x0c - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0d - DW_TAG_member */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0e - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x0f - DW_TAG_pointer_type */ { 0x00010000,0x00a02040,0x00000085,}, /* 0x10 - DW_TAG_reference_type */ { 0x00008000,0x00a02040,0x00000085,}, /* 0x11 - DW_TAG_compile_unit */ { 0xe4ed8116,0x0ef06ad3,0x000000fc,}, /* 0x12 - DW_TAG_string_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x13 - DW_TAG_structure_type */ { 0x90c8a114,0x0009c458,0x00000098,}, /* 0x14 - */ { 0x00000000,0x00000000,0x00000000,}, /* 0x15 - DW_TAG_subroutine_type */ { 0x01400020,0x00000000,0x00000000,}, /* 0x16 - DW_TAG_typedef */ { 0x00000000,0x00000000,0x00000000,}, /* 0x17 - DW_TAG_union_type */ { 0x00c82014,0x0001c400,0x00000000,}, /* 0x18 - DW_TAG_unspecified_parameters */ { 0x00000000,0x00000000,0x00000000,}, /* 0x19 - DW_TAG_variant */ { 0x00000000,0x00080000,0x00000000,}, /* 0x1a - DW_TAG_common_block */ { 0x00000000,0x00100000,0x00000000,}, /* 0x1b - DW_TAG_common_inclusion */ { 0x00000000,0x00000000,0x00000000,}, /* 0x1c - DW_TAG_inheritance */ { 0x00000000,0x00000000,0x00000000,}, /* 0x1d - DW_TAG_inlined_subroutine */ { 0xa1ed8836,0x00306ad3,0x000000f0,}, /* 0x1e - DW_TAG_module */ { 0x00000000,0x00000000,0x00000000,}, /* 0x1f - DW_TAG_ptr_to_member_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x20 - DW_TAG_set_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x21 - DW_TAG_subrange_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x22 - DW_TAG_with_stmt */ { 0x00000000,0x00000000,0x00000000,}, /* 0x23 - DW_TAG_access_declaration */ { 0x00000000,0x00000000,0x00000000,}, /* 0x24 - DW_TAG_base_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x25 - DW_TAG_catch_block */ { 0x81ed8036,0x003062d3,0x00000080,}, /* 0x26 - DW_TAG_const_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x27 - DW_TAG_constant */ { 0x00000000,0x00000000,0x00000000,}, /* 0x28 - DW_TAG_enumerator */ { 0x00000000,0x00000000,0x00000000,}, /* 0x29 - DW_TAG_file_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2a - DW_TAG_friend */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2b - DW_TAG_namelist */ { 0x00000000,0x00001000,0x00000000,}, /* 0x2c - DW_TAG_namelist_item */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2d - DW_TAG_packed_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x2e - DW_TAG_subprogram */ { 0xaded8d36,0x0433ead3,0x000000b0,}, /* 0x2f - DW_TAG_template_type_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x30 - DW_TAG_template_value_parameter */ { 0x00000000,0x00000000,0x00000000,}, /* 0x31 - DW_TAG_thrown_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x32 - DW_TAG_try_block */ { 0x00000000,0x00000000,0x00000000,}, /* 0x33 - DW_TAG_variant_part */ { 0x00000000,0x00000000,0x00000000,}, /* 0x34 - DW_TAG_variable */ { 0x00000000,0x00000000,0x00000000,}, /* 0x35 - DW_TAG_volatile_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x36 - DW_TAG_dwarf_procedure */ { 0x00000000,0x00000000,0x00000000,}, /* 0x37 - DW_TAG_restrict_type */ { 0x00018000,0x00202040,0x00000085,}, /* 0x38 - DW_TAG_interface_type */ { 0x00002000,0x00004000,0x00000000,}, /* 0x39 - DW_TAG_namespace */ { 0xe4ed8116,0x063068d3,0x000000f0,}, /* 0x3a - DW_TAG_imported_module */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3b - DW_TAG_unspecified_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3c - DW_TAG_partial_unit */ { 0xe4ed8116,0x00306ad3,0x000000f0,}, /* 0x3d - DW_TAG_imported_unit */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3e - DW_TAG_mutable_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x3f - DW_TAG_condition */ { 0x00000000,0x00000082,0x00000000,}, /* 0x40 - DW_TAG_shared_type */ { 0x00018000,0x00a02040,0x00000085,}, /* 0x41 - DW_TAG_type_unit */ { 0xe4ed8116,0x06306ad3,0x000000f8,}, /* 0x42 - DW_TAG_rvalue_reference_type */ { 0x00018000,0x00a02040,0x00000081,}, /* 0x43 - DW_TAG_template_alias */ { 0x00000000,0x00018000,0x00000000,}, /* 0x44 - DW_TAG_coarray_type */ { 0x00000002,0x00000012,0x00000060,}, /* 0x45 - DW_TAG_generic_subrange */ { 0x00000000,0x00000000,0x00000000,}, /* 0x46 - DW_TAG_dynamic_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x47 - DW_TAG_atomic_type */ { 0x00000000,0x00000000,0x00000000,}, /* 0x48 - DW_TAG_call_site */ { 0x00000000,0x00000000,0x00000200,}, }; /* END FILE */ dwarfutils-20200114/dwarfdump/dwarfdump.1000066400000000000000000000530331361531463500202100ustar00rootroot00000000000000.TH DWARFDUMP .SH NAME dwarfdump \- dumps DWARF debug information of an ELF object .SH SYNOPSIS .B dwarfdump [options] \f2objectfilename\fP .SH DESCRIPTION The .B dwarfdump command prints or checks DWARF sections as requested by specific options. With no options (but with the required \f2objectfilename\fP ) all sections print (but some sections cannot be printed independently safely, so those are only printed at offsets where the .debug_info section refers to those sections). .PP All options are available in the traditional (single-letter) form and in a long-options form with meaningful names. .PP With no options .B dwarfdump prints a basic set of DWARF section information. If any option is given on the command line the basic set is ignored and one must tell .B dwarfdump what to print or check (for example by adding the .B \-a option). .PP As of June 2011 the printing options and the checking options are mutually exclusive (if checking options are selected the section details are not printed). When errors are encountered dwarfdump does attempt to print sufficient context so that one can understand exactly where the error is in the DWARF. This change makes checking really large object files much easier. .PP The format is intended to be human readable. If a script is to parse the output, the .BR \--format-dense\ (\-d) option is useful. .PP Not all sections actually exist in any given object file. .PP The format may change from release to release, so it is unwise to depend too heavily on the format. .PP Frame information (.debug_frame and .eh_frame) is heavily dependent on the ABI/ISA of the object file. By default we use a generic set of register names handling up to 100 registers named r0-r99. The .BR \--format-registers\ (\-R) option uses a built-in generic register name set handling up to 1200 registers named r0-r1199. .PP The .BR \-file-abi=\ (\-x\ abi=) description below shows how to name an abi and use that to guide the .BR \--print-frame\ (\-f) or .BR \--print-eh-frame\ (\-F) processing. .PP Unless one of .BR \--print-frame\ (\-f) or .B \--print-eh-frame\ (\-F) or .BR \--print-all\ (\-a) is used any abi reference is ignored because no frame data will be printed. .PP Unless the cpu for the object file being dumped has many registers, do not use .B \--format-registers or .B \-file-abi= as those can be needlessly slow dumping frame sections. Instead, use the correct abi (if it exists in dwarfdump.conf) or a generic such as .B \--file-abi=abi=generic100 or .B \--file-abi=abi=generic500 . .PP The most useful abi choices are likely .B mips or .B x86 or .B x86_64 or .B ppc or .B arm . Without .BR \--format-registers\ (\-R) or .BR \-file-abi=\ (\-x\ abi=) dwarfdump ignores the dwarfdump.conf file and uses compiled-in generic set of register names. If no .BR \--file-name=\ (\-x\ name=) is given, dwarfdump looks for "./dwarfdump.conf", "$HOME/.dwarfdump.conf", "/lib/dwarfdump.conf" and takes the first it finds. If one or more .BR \--file-name=\ (\-x\ name=) is given the last of these is used and all other such files are ignored. .PP Some checking ( .BR \-k ) options (See "Check DWARF Integrity" in the help output) print so-called harmless errors. These are compiler errors that do not cause any known problem and are only detected inside libdwarf itself. These are difficult to properly report in dwarfdump and any error strings may not appear close to the time the error was encountered. .PP If zlib compression was used on the DWARF sections in the object file being read the real section names such as .zdebug_info etc will be reported by dwarfdump. When dwarfdump says something is at offset 55 of .zdebug_info (or the like) keep in mind that the offset applies to the uncompressed section (in memory), not the .zdebug_ compressed section in \f2objectfilename\fP. .SH URI STYLE INPUT STRINGS .PP The and all the options taking name strings look for URIs and translate the URI strings to characters by default. So any single % character is treated as if the following two characters are hex digits representing the underlying true character. Various characters are meaningful to shells (such as bash or sh) and to getopt (such as the space character) If the URI translation does anything it prints the before and after of the URI translation on standard output, so inspection of the first lines of output will show if URI did anything. The actual options themselves are assumed to be non-URI. So in the option .BR \--format-producer=S&T\ (\-cS&T) the & character might cause input issues so .B \--format-producer=S%26T should be used instead. To actually input a single % character (in a name, for example), double it to %% on the command line (or simply use %25). .PP Options .BR \--format-suppress-uri\ (\-U) (turning off URI interpretation) and .BR \--format-suppress-uri-msg\ (\-q) (making finding URI sequences silent) give finer control of URI interpretation. PP As an example, to get a string'a b' make the string 'a%20b' (here the quote (') is for exposition not part of the string, though quote is certainly problematic in a name). Instead of escaping " quotes in the string, type %25, as in 'a "b' should be typed 'a%20%25b' Any characters can be typed in URI style, not just characters which are problematic to the shell or getopt. We strongly suggest you not type URI-style characters where such are not needed or use the % character itself in command line strings unless you must. .SH PRINTING OPTIONS .TP .BR \--print-all\ (\-a) Print each section as independently as possible. Sections that can safely be printed independently (like .debug_abbrev) have relevant info printed in the report (sometimes dependent on -v). .TP .BR \--print-abbrev\ (\-b) Print the .debug_abbrev section. Because the DWARF specifications do not rule out garbage data areas in .debug_abbrev (if they are not referenced from .debug_info) any garbage bytes can result in this print failing. .TP .BR \--print-loc\ (\-c) Print locations lists. .TP .BR \--elf\ (\-E) prints, for Elf objects, object file details. See the "Print ELF sections header" section of the help file for additional choices on elf printing. If libdwarf or dwarfdump is built without libelf this option is unavailable. .TP .BR \--print-frame\ (\-f) Print the .debug_frame section. .TP .BR \--print-eh-frame\ (\-F) Print the GNU .eh_frame section. .TP .BR \--print-info\ (\-i) Print the .debug_info section. .TP .BR \--print-fission\ (\-I) Print any .gdb_index, .debug_cu_index, and .debug_tu_index sections that exist in the object. .TP .BR \--print-gnu-debuglink\ If the .gnu_debuglink section is present its content is printed. If the .note.gnu.build-id section is present its content is printed. If a DWARF containing file named by the content of the .gnu_debuglink section exists the name will be printed. .TP .BR \--print-lines\ (\-l) Print the .debug_info section and the associated line section data. .TP .BR \--print-lines-short\ (\-ls) Print the .debug_info section and the associated line section data, but omit the address. Useful when a comparison of line sections from objects with slight differences is required. .TP .BR \--print-macinfo\ (\-m) Print the .debug_macinfo (DWARF 2,3,4) and .debug_macro (DWARF5) sections. .TP .BR \--print-ranges\ (\-N) Print .debug_ranges section. Because the DWARF specifications do not rule out garbage data areas in .debug_ranges (if they are not referenced from .debug_info) any garbage bytes can result in this print failing. .TP .BR \--print-pubnames\ (\-p) Print the .debug_pubnames section. .TP .B \--print-str-offsets Print the .debug_str_offsets section. .TP .BR \--print-aranges\ (\-r) Print the .debug_aranges section. .TP .BR \--print-strings\ (\-s) Print .debug_string section. .TP .BR \--print-static\ (\-ta) Print the IRIX only sections .debug_static_funcs and .debug_static_vars. .TP .BR \--print-type\ (\-y) Print the .debug_pubtypes section (and .debug_typenames, an SGI IRIX-only section). .PP Having dwarfdump print relocations may help establish whether dwarfdump understands any relocations that might exist. Other tools may be more useful than dwarfdump for printing object-file details. See "Print Relocations Info" in the help output for additional relocation printing choices. .TP .BR \--reloc\ (\-o) Print all relocation records as well as we can manage. If libdwarf or dwarfdump were built without libelf this option is unavailable. .TP .BR \--version\ (\-V) Print a dwarfdump date/version string and stop. .SH CHECKING OPTIONS .TP .BR \--check-all\ (\-ka) Turns on all checking options except .BR \--check-frame-extended\ (\-kxe) (which might be slow enough one might not want to use it routinely.) .TP .BR \--check-abbrev\ (\-kb) Checks for certain abbreviations section errors when reading DIEs. .TP .BR \--check-constants\ (\-kc) Checks for errors in constants in debug_info. .TP .BR \-check-show\ (\-kd) Turns on full reporting of error totals per producer. (the default shows less detail). .TP .BR \--check-silent \-ks Turns off some verbose checking detection. .TP .BR \--check-attr-dup\ (\-kD) Turns on reporting of duplicated attributes. Duplicated attributes on a single DW_TAG are improper DWARF, but at least one compiler emitted such. .TP .BR \--check-pubnames\ (\-ke) Turns on reading pubnames and checking for fde errors. .TP .BR \--check-attr-encodings\ (\-kE) Checks the integer encoding representation in debug_info, computing whether these integer values could fit in fewer bytes if represented in LEB128. .TP .BR \--check-frame-info\ (\-kf) Turns on checking for FDE errors (.debug_frame and .eh_frame). .TP .BR \--check-files-lines\ (\-kF) Turns on checking for line table errors. .TP .BR \--check-gaps\ (\-kg) Turns on checking for unused gaps in .debug_info (these gaps are not an error, just a waste of space). .TP .BR \--check-unique\ (\-kG) Print only unique errors. Error lines are simpified (hex numbers removed, for example) and when a given message string would otherwise appear again it is suppressed. .TP .BR \--check-summary\ (\-ki) Causes a summary of checking results per compiler (producer) to be printed at the end. .TP .B \--check-loc\ (\-kl) Turns on locations list checking. .TP .B \--check-ranges\ (\-km) Turns on checking of ranges. .TP .BR \--check-aranges\ (\-kM) Turns on checking of aranges. .TP .BR \--check-tag-attr\ (\-kr) Turns on DIE tag-attr combinations checking, looking for surprising attributes for DIE tags. .TP .BR \--check-forward-refs\ (\-kR) Turns on reading DIEs and checking for forward declarations from DW_AT_specification attributes. (which are not an error but can be a source of inefficiency for debuggers). .TP .BR \--check-self-refs\ (\-kS) Turns on checking DIE references for circular references. .TP .BR \--check-tag-tag\ (\-kt) Turns on tag-tag combinations checking, looking for surprising parent-child DIE relationships. .TP .BR \--check-usage\ (\-ku) Print tag-tree and tag-attribute usage (basic format). .TP .BR \--check-usage-extended\ (\-kuf) Print tag-tree and tag-attribute usage (full format). For standard TAGs and ATtributes this presents an overview of how they were used. .TP .BR \--check-frame-basic\ (\-kx) Turns on basic frames checking for .debug_frame and .eh_frame). .TP .BR \--check-frame-extended\ (\-kxe) Turns off basic check_frames and turns on extended frame checking for .debug_frame and .eh_frame. This option can be slow. .TP .BR \--check-type\ (\-ky) Turns on type_offset checking (ensuring local attribute offsets refer to what they should) and that DW_AT_decl_file and some other offsets refer to appropriate locations. .SH OPTION MODIFIERS .TP .BR \--format-extensions\ (\-C) Normally when checking for tag-tag or tag-attribute combinations both the standard combinations and some common extensions are allowed. With -C the extensions are taken out of the allowed class of combinations. .TP .BR \--format-dense\ (\-d) When printing DIEs, put all the attributes for each DIE on the same (long) line as the TAG. This makes searching for DIE information (as with grep) much simpler as the entire DIE is on one line. .TP .BR \--format-supress-offsets\ (\-D) Turns off the display of section offsets and attribute values in printed output. So the .debug_info output is just TAGs and Attributes. For pubnames (and the like) it removes offsets from the output. For locations lists it removes offsets from the output, but that is useless since the attribute values don't show so neither does the location data. .TP .BR \--format-ellipsis\ (\-e) Turns on truncation of attribute and tag names. For example DW_TAG_foo becomes foo. Not compatible with checking, only useful for printing DIEs. .TP .BR \--format-global-offsets\ (\-G) When printing, add global offsets to the offsets printed. .TP .BR \--format-limit=\ (\-H\ number) When printing or checking .debug_info, this terminates the search after 'number' compilation units. When printing frame information this terminates the FDE reporting after 'number' FDEs and the CIE reporting (which occurs if one adds -v) after 'number' CIEs. Example '--format-limit=1' .TP .BR \--format-attr-name\ (\-M) When printing, show the FORM for each attribute. If a -v is added (or more than one) then details of any form indirection are also shown. .TP .BR \--format-suppress-lookup\ (\-n) When printing frames, this turns off the search for function names. In a really large object the search can take more time than one wants to wait, so this avoids the search. .TP .BR \--file-output=\ (\-O file=) The will be used as the file name for output instead of writing to stdout (stdout is the default). .TP .BR \-format-suppress-data\ (\-Q) Suppresses section data printing (set automatically with a checking option). .TP .BR \--format-registers\ (\-R) When printing frames for ABIs with lots of registers, this allows up to 1200 registers to be named (like R999) without choosing an ABI with, for example '-x abi=ppc' .TP .BR \--version\ (\-v) Increases the detail shown when printing. In some sections, using more -v options will increase the detail (one to three are useful) or may change the report to show, for example, the actual line-data-commands instead of the resultant line-table. .SH SELECTIVE ENTRY PRINTING .PP These --search (-S) options stand alone and basic print information about the compilation unit and DIE where the string(s) appear. At most one of each of the following is effective (so for example one can only have one 'match', but one can have a 'match', an 'any', and a 'regex'). Any --search (-S) causes the .debug_info section to be inspected. No checking options or printing options should be supplied with --search(-S) options. The strings should use URI-style to avoid any conflicts with the command-line parser applicable (bash, sh, ...) or getopt(). These are particularly useful when the amount of DWARF information is really large. If v is added to the -S option, the number of occurrences is printed. (see below for an example). .TP .BR \--search-match=\ (\-S match=string) .TP .BR \--search-match-count=\ (\-S vmatch=string) When printing DIEs for each tag value or attribute name that matches 'string' exactly print the compilation unit information and its section offset. Any CU with no match is not printed. The 'string' is read as a URI string. The count (Sv) form reports the count of occurrences. .TP .BR \--search-any=\ (\-S any=string) .TP .BR \--search-any-count=\ (\-Svany=string) When printing DIEs for each tag value or attribute name that contains 'string' somewhere in the tag or attribute (case insensitive) print the compilation unit information and its section offset. Any CU with no match is not printed. The 'string' is read as a URI string. The count (Sv) form reports the count of occurrences. .TP .BR \--search-regex=string\ (\-S regex=string) .TP .BR \--search-regex-count=string\ (\-Svregex=string) When printing DIEs for each tag value or attribute name where the 'string' reqular expression matches print the compilation unit information and its section offset. Any CU with no match is not printed. The 'string' is read as a URI string. The count (Sv) form reports the count of occurrences. .PP The string cannot have spaces or other characters which are meaningful to getopt(3) and the shell will strip off quotes and other characters. So the string is assumed to be in URI style and is translated. In other words, to match 'a b' make the -S string 'a%20b' Instead of escaping " quotes in the string, type %25, as in 'a "b' should be typed 'a%20%25b' (the ' are for exposition here, not part of the strings). Any characters can be typed in URI style, not just characters which are problematic to the shell or getopt. .PP The .BR \--search-any\ (\-S any) and .BR \--regex-any\ (\-S regex) options are only usable if regular-expression library functions required are found at configure time. .PP The .BR \--search-print\ (\-W) option is a modifier to the -S option, and increases the amount of output -S prints. An example v modifier to the -S option is shown below. And we show the -W in context with a -S option. .TP .BR \--search-match-count=string1\ (\-S\ vmatch=string1) Prints information about the DIEs that -S matches and prints the count of occurrences. .TP .BR \-S\ match=string1\ \-W .TP .BR \--search-match=string1\ \--search-print-tree Prints the parent tree and the children tree for the DIEs that -S matches. .TP .BR \-S\ match=string2\ \-Wp .TP .BR \--search-match=string2\ \--search-print-parent Prints the parent tree for the DIEs that -S matches. .TP .BR \-S\ match=string3\ \-Wc .TP .BR \--search-match=string3\ \--search-print-children Prints the children tree for the DIEs that -S matches. .TP .BR \--format-gcc\ (\-cg) Restricts printing/checking to compilers whose producer string starts with 'GNU' and turns off -cs. .TP .BR \--format-snc\ (\-cs) Restricts printing/checking to compilers whose producer string starts with 'SN' and turns off -cg. .TP .BR \--format-producer=\ (\-c) Restricts printing/checking to compilers whose producer string contains 'name' (not case sensitive). The 'name' is read as a URI string. .SH OTHER OPTIONS .TP .BR \-x\ name= .TP .BR \--file-name=/p/a/t/h.conf\ (\-x name=/p/a/t/h.conf) The file path given is the name of a file assumed to be a dwarfdump.conf-like file. The file path is read as a URI string. .TP .BR \-x\ abi=ppc .TP .BR \--file-abi=ppc Selects the abi (from a dwarfdump.conf file) to be used in printing frame information (here using ppc as an example). The abi is read as a URI string. .TP .BR \--format-group=\ (\-x\ groupnumber=) For an object file with both DWARF5 split dwarf (.debug_info.dwo for example) and ordinary DWARF sections (.debug_info for example) in the single object file one must use .BR \--format-group=2 to print the dwo sections. Adding .BR \--file-tied= naming the same object file ties in the non-dwo sections. .TP .BR \-x\ tied=/t/i/depath .TP .BR \--file-tied=/t/i/depath Used when opening a main object that is a .dwo or .dwp file. The tied file path names the executable which has the .debug_addr section that may be referred to from the main object. See Split Objects (aka Debug Fission). .TP .BR \-x\ line5=s2l .TP .BR \--file-line5=s2l Normally used only to test libdwarf interfaces. There are 4 different interface function sets and to ensure they all work this option lets us choose which to use. The options are 's2l' (default, Allows standard and two-level line tables using the latest interface functions), 'std' (Allows standard single level line tables using the latest interface functions), 'orig' (allows DWARF2,3,4 original line tables using an older interface function set), 'orig2l' (allows original line tables and some two-level line tables using an older interface set). .TP .B \--print-producers .B \-P When checking this adds the list of compilation-unit names seen for each producer-compiler to the printed checking results. .TP .B \-q .TP .B \--format-suppress-uri-msg When a URI is found and translated while reading the command line, be quiet about the URI translation. That is, don't print the original and translated option strings. .TP .B \-u cuname .TP .B \--format-file= Turns on selective printing of DIEs (printing like -i). Only the DIEs for a compilation unit that match the name provided are printed. If the compilation unit is ./a/b/c.c the 'cuname' you provide should be c.c as the characters through the final path-separating / are ignored. If 'cuname' begins with a / then the entire name string of a compilation unit must match 'cuname'. The 'file' is read as a URI string. .TP .B \-U .TP .B \--format-suppress-uri Turn off the URI interpretation of the command line strings entirely. Must be be on the command line before any URI strings encountered to be fully effective. Likely something no one needs to do. .TP .B \-h .TP .B \--help Show this man page. .SH FILES dwarfdump ./dwarfdump.conf $(HOME)/.dwarfdump.conf $(HOME)/dwarfdump.conf /lib/dwarfdump.conf .SH NOTES In some cases compilers use DW_FORM_data1 (for example) and in such cases the signedness of the value must be taken from context. Rather than attempt to determine the context, dwarfdump prints the value with both signednesses whenever there is ambiguity about the correct interpretation. For example, "DW_AT_const_value 176(as signed = -80)". For normal DWARF consumers that correctly and fully evaluate all attributes there is no ambiguity of signedness: the ambiguity for dwarfdump is due to dwarfdump evaluating DIEs in a simple order and not keeping track of much context. .SH BUGS Support for DWARF5 is being completed but may not be complete. dwarfutils-20200114/dwarfdump/dwarfdump.c000066400000000000000000001641011361531463500202710ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" /* for 'open' */ #include #include #include #include #ifdef HAVE_UNISTD_H #include /* for dup2() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #include "makename.h" #include "macrocheck.h" #include "dwconf.h" #include "dwconf_using_functions.h" #include "common.h" #include "helpertree.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "tag_common.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ #include "command_options.h" #include "compiler_info.h" #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ #ifdef HAVE_ELF_OPEN extern int elf_open(const char *name,int mode); #endif /* HAVE_ELF_OPEN */ #ifdef HAVE_CUSTOM_LIBELF extern int elf_is_custom_format(void *header, size_t headerlen, size_t *size, unsigned *endian, unsigned *offsetsize, int *errcode); #endif /* HAVE_CUSTOM_LIBELF */ #define BYTES_PER_INSTRUCTION 4 /* The type of Bucket. */ #define KIND_RANGES_INFO 1 #define KIND_SECTIONS_INFO 2 #define KIND_VISITED_INFO 3 /* Build section information */ void build_linkonce_info(Dwarf_Debug dbg); struct glflags_s glflags; /* Functions used to manage the unique errors table */ static void allocate_unique_errors_table(void); static void release_unique_errors_table(void); #ifdef TESTING static void dump_unique_errors_table(void); #endif static boolean add_to_unique_errors_table(char * error_text); static struct esb_s esb_short_cu_name; static struct esb_s esb_long_cu_name; static struct esb_s dwarf_error_line; static int process_one_file(int fd, int tiedfd, Elf *efp, Elf * tiedfp, const char * file_name, const char * tied_file_name, #ifdef DWARF_WITH_LIBELF int archive, #endif struct dwconf_s *conf); static void print_gnu_debuglink(Dwarf_Debug dbg); static int open_a_file(const char * name) { /* Set to a file number that cannot be legal. */ int fd = -1; #if HAVE_ELF_OPEN /* It is not possible to share file handles between applications or DLLs. Each application has its own file-handle table. For two applications to use the same file using a DLL, they must both open the file individually. Let the 'libelf' dll open and close the file. */ fd = elf_open(name, O_RDONLY | O_BINARY); #else fd = open(name, O_RDONLY | O_BINARY); #endif return fd; } static void close_a_file(int f) { if (f != -1) { close(f); } } #ifdef DWARF_WITH_LIBELF static int is_it_known_elf_header(Elf *elf) { Elf32_Ehdr *eh32; eh32 = elf32_getehdr(elf); if (eh32) { return 1; } #ifdef HAVE_ELF64_GETEHDR { Elf64_Ehdr *eh64; /* not a 32-bit obj */ eh64 = elf64_getehdr(elf); if (eh64) { return 1; } } #endif /* HAVE_ELF64_GETEHDR */ /* Not something we can handle. */ return 0; } #endif /* DWARF_WITH_LIBELF */ static void check_for_major_errors(void) { if (glflags.gf_count_major_errors) { #if 0 causes hundreds of test mismatches, so not reporting this. printf("There were %ld DWARF errors reported: " "see ERROR above\n", glflags.gf_count_major_errors); #endif /* 0 */ exit(FAILED); } return; } static void flag_data_pre_allocation(void) { memset(glflags.section_high_offsets_global,0, sizeof(*glflags.section_high_offsets_global)); /* If we are checking .debug_line, .debug_ranges, .debug_aranges, or .debug_loc build the tables containing the pairs LowPC and HighPC. It is safer (and not expensive) to build all of these at once so mistakes in options do not lead to coredumps (like -ka -p did once). */ if (glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations || glflags.gf_do_check_dwarf || glflags.gf_check_self_references) { glflags.pRangesInfo = AllocateBucketGroup(KIND_RANGES_INFO); glflags.pLinkonceInfo = AllocateBucketGroup(KIND_SECTIONS_INFO); glflags.pVisitedInfo = AllocateBucketGroup(KIND_VISITED_INFO); } /* Create the unique error table */ if (glflags.gf_print_unique_errors) { allocate_unique_errors_table(); } /* Allocate range array to be used by all CUs */ if (glflags.gf_check_ranges) { allocate_range_array_info(); } } static void flag_data_post_cleanup(void) { #ifdef DWARF_WITH_LIBELF clean_up_syms_malloc_data(); #endif /* DWARF_WITH_LIBELF */ if (glflags.pRangesInfo) { ReleaseBucketGroup(glflags.pRangesInfo); glflags.pRangesInfo = 0; } if (glflags.pLinkonceInfo) { ReleaseBucketGroup(glflags.pLinkonceInfo); glflags.pLinkonceInfo = 0; } if (glflags.pVisitedInfo) { ReleaseBucketGroup(glflags.pVisitedInfo); glflags.pVisitedInfo = 0; } /* Release range array to be used by all CUs */ if (glflags.gf_check_ranges) { release_range_array_info(); } /* Delete the unique error set */ if (glflags.gf_print_unique_errors) { release_unique_errors_table(); } clean_up_compilers_detected(); destruct_abbrev_array(); } #ifdef DWARF_WITH_LIBELF static int process_using_libelf(int fd, int tiedfd, const char *file_name, char *out_path_buf, const char *tied_file_name, int archive) { Elf_Cmd cmd = 0; Elf *arf = 0; Elf *elf = 0; Elf *elftied = 0; int archmemnum = 0; (void) elf_version(EV_NONE); if (elf_version(EV_CURRENT) == EV_NONE) { (void) fprintf(stderr, "dwarfdump: libelf.a out of date.\n"); exit(FAILED); } /* We will use libelf to process an archive so long as is convienient. we don't intend to ever write our own archive reader. Archive support was never tested and may disappear. */ cmd = ELF_C_READ; arf = elf_begin(fd, cmd, (Elf *) 0); if (!arf) { fprintf(stderr, "%s ERROR: " "Unable to obtain ELF descriptor for %s\n", glflags.program_name, file_name); free(out_path_buf); return (FAILED); } if (esb_string_len(glflags.config_file_tiedpath) > 0) { int isknown = 0; if (tiedfd == -1) { fprintf(stderr, "%s ERROR: " "can't open tied file %s\n", glflags.program_name, tied_file_name); free(out_path_buf); return (FAILED); } elftied = elf_begin(tiedfd, cmd, (Elf *) 0); if (elf_kind(elftied) == ELF_K_AR) { fprintf(stderr, "%s ERROR: tied file %s is " "an archive. Not allowed. Giving up.\n", glflags.program_name, tied_file_name); free(out_path_buf); return (FAILED); } isknown = is_it_known_elf_header(elftied); if (!isknown) { fprintf(stderr, "Cannot process tied file %s: unknown format\n", tied_file_name); free(out_path_buf); return FAILED; } } while ((elf = elf_begin(fd, cmd, arf)) != 0) { int isknown = is_it_known_elf_header(elf); if (!isknown) { /* not a 64-bit obj either! */ /* dwarfdump is almost-quiet when not an object */ if (archive) { Elf_Arhdr *mem_header = elf_getarhdr(elf); const char *memname = (mem_header && mem_header->ar_name)? mem_header->ar_name:""; /* / and // archive entries are not archive objects, but are not errors. For the ATT/USL type of archive. */ if (strcmp(memname,"/") && strcmp(memname,"//")) { fprintf(stderr, "Can't process archive member " "%d %s of %s: unknown format\n", archmemnum, sanitized(memname), file_name); } } else { fprintf(stderr, "Can't process %s: unknown format\n", file_name); } glflags.check_error = 1; cmd = elf_next(elf); elf_end(elf); continue; } flag_data_pre_allocation(); process_one_file(fd,tiedfd, elf,elftied, file_name, tied_file_name, archive, glflags.config_file_data); flag_data_post_cleanup(); cmd = elf_next(elf); elf_end(elf); archmemnum += 1; } elf_end(arf); if (elftied) { elf_end(elftied); elftied = 0; } return 0; /* normal return. */ } #endif /* DWARF_WITH_LIBELF */ /* Iterate through dwarf and print all info. */ int main(int argc, char *argv[]) { const char * file_name = 0; const char * tied_file_name = 0; int fd = -1; int tiedfd = -1; unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; int errcode = 0; char *out_path_buf = 0; unsigned out_path_buf_len = 0; int res = 0; #ifdef _WIN32 /* Open the null device used during formatting printing */ if (!esb_open_null_device()) { fprintf(stderr,"dwarfdump: Unable to open null device.\n"); exit(FAILED); } #endif /* _WIN32 */ /* Global flags initialization and esb-buffers construction. */ init_global_flags(); set_checks_off(); esb_constructor(&esb_short_cu_name); esb_constructor(&esb_long_cu_name); esb_constructor(&dwarf_error_line); #ifdef _WIN32 /* Often we redirect the output to a file, but we have found issues due to the buffering associated with stdout. Some issues were fixed just by the use of 'fflush', but the main issued remained. The stdout stream is buffered, so will only display what's in the buffer after it reaches a newline (or when it's told to). We have a few options to print immediately: - Print to stderr instead using fprintf. - Print to stdout and flush stdout whenever we need it to using fflush. - We can also disable buffering on stdout by using setbuf: setbuf(stdout,NULL); Make stdout unbuffered; this seems to work for all cases. The problem is no longer present. September 2018. */ /* Calling setbuf() with NULL argument, it turns off all buffering for the specified stream. Then writing to and/or reading from the stream will be exactly as directed by the program. But if dwarfdump is used over a network drive, it shows a dramatic slowdown when sending the output to a file. An operation that takes couple of seconds, it was taking few hours. */ /* setbuf(stdout,NULL); */ /* Redirect stderr to stdout. */ dup2(fileno(stdout),fileno(stderr)); #endif /* _WIN32 */ print_version_details(argv[0],FALSE); file_name = process_args(argc, argv); print_args(argc,argv); /* Redirect stdout and stderr to an specific file */ if (glflags.output_file) { if (NULL == freopen(glflags.output_file,"w",stdout)) { fprintf(stderr, "dwarfdump: Unable to redirect output to '%s'\n", glflags.output_file); exit(FAILED); } dup2(fileno(stdout),fileno(stderr)); /* Record version and arguments in the output file */ print_version_details(argv[0],FALSE); print_args(argc,argv); } /* Because LibDwarf now generates some new warnings, allow the user to hide them by using command line options */ { Dwarf_Cmdline_Options wcmd; /* The struct has just one field!. */ wcmd.check_verbose_mode = glflags.gf_check_verbose_mode; dwarf_record_cmdline_options(wcmd); } /* The 100+2 etc is more than suffices for the expansion that a MacOS dsym might need. */ out_path_buf_len = strlen(file_name)*2 + 100 + 2; out_path_buf = malloc(out_path_buf_len); if(!out_path_buf) { fprintf(stderr, "%s ERROR: Unable to malloc %lu bytes " "for possible path string %s.\n", glflags.program_name,(unsigned long)out_path_buf_len, file_name); return (FAILED); } res = dwarf_object_detector_path(file_name, out_path_buf,out_path_buf_len, &ftype,&endian,&offsetsize,&filesize,&errcode); if ( res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { char *errmsg = dwarf_errmsg_by_number(errcode); fprintf(stderr, "%s ERROR: can't open %s:" " %s\n", glflags.program_name, file_name, errmsg); } else { fprintf(stderr, "%s ERROR: Can't open %s\n", glflags.program_name, file_name); } free(out_path_buf); return (FAILED); } if (strcmp(file_name,out_path_buf)) { /* We have a MacOS dsym, file_name altered */ file_name = makename(out_path_buf); } fd = open_a_file(file_name); if (fd == -1) { fprintf(stderr, "%s ERROR: can't open %s\n", glflags.program_name, file_name); free(out_path_buf); return (FAILED); } if (esb_string_len(glflags.config_file_tiedpath) > 0) { unsigned tftype = 0; unsigned tendian = 0; unsigned toffsetsize = 0; Dwarf_Unsigned tfilesize = 0; tied_file_name = esb_get_string(glflags.config_file_tiedpath); res = dwarf_object_detector_path(file_name, out_path_buf,out_path_buf_len, &tftype,&tendian,&toffsetsize,&tfilesize,&errcode); if ( res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { char *errmsg = dwarf_errmsg_by_number(errcode); fprintf(stderr, "%s ERROR: can't open tied file %s:" " %s\n", glflags.program_name, tied_file_name, errmsg); } else { fprintf(stderr, "%s ERROR: tied file not an object file '%s'.\n", glflags.program_name, tied_file_name); } free(out_path_buf); return (FAILED); } if (ftype != tftype || endian != tendian || offsetsize != toffsetsize) { fprintf(stderr, "%s ERROR: tied file \'%s\' and " "main file \'%s\' not " "the same kind of object!\n", glflags.program_name, tied_file_name,out_path_buf); free(out_path_buf); return (FAILED); } if (strcmp(file_name,out_path_buf)) { /* We have a MacOS dsym, file_name altered. Can this really happen with a tied file? */ esb_empty_string(glflags.config_file_tiedpath); esb_append(glflags.config_file_tiedpath,out_path_buf); tied_file_name = out_path_buf; } tiedfd = open_a_file(tied_file_name); if (tiedfd == -1) { fprintf(stderr, "%s ERROR: can't open tied file %s\n", glflags.program_name, tied_file_name); free(out_path_buf); return (FAILED); } } if ( (ftype == DW_FTYPE_ELF && (glflags.gf_reloc_flag || glflags.gf_header_flag)) || #ifdef HAVE_CUSTOM_LIBELF ftype == DW_FTYPE_CUSTOM_ELF || #endif /* HAVE_CUSTOM_LIBELF */ ftype == DW_FTYPE_ARCHIVE) { #ifdef DWARF_WITH_LIBELF int excode = 0; excode = process_using_libelf(fd,tiedfd,file_name, out_path_buf, tied_file_name, (ftype == DW_FTYPE_ARCHIVE)? TRUE:FALSE); if (excode) { free(out_path_buf); exit(excode); } #else /* !DWARF_WITH_LIBELF */ fprintf(stderr, "Can't process %s: archives and " "printing elf headers not supported in this dwarfdump " "--disable-libelf build.\n", file_name); #endif /* DWARF_WITH_LIBELF */ } else if (ftype == DW_FTYPE_ELF) { flag_data_pre_allocation(); process_one_file(fd,tiedfd, 0,0, file_name, tied_file_name, #ifdef DWARF_WITH_LIBELF 0 /* elf_archive */, #endif glflags.config_file_data); flag_data_post_cleanup(); } else if (ftype == DW_FTYPE_MACH_O) { flag_data_pre_allocation(); process_one_file(fd,tiedfd, 0,0, file_name, tied_file_name, #ifdef DWARF_WITH_LIBELF 0 /* mach_o_archive */, #endif glflags.config_file_data); flag_data_post_cleanup(); } else if (ftype == DW_FTYPE_PE) { flag_data_pre_allocation(); process_one_file(fd,tiedfd, 0,0, file_name, tied_file_name, #ifdef DWARF_WITH_LIBELF 0/* pe_archive */, #endif glflags.config_file_data); flag_data_post_cleanup(); } else { fprintf(stderr, "Can't process %s: unhandled format\n", file_name); } free(out_path_buf); out_path_buf = 0; /* These cleanups only necessary once all objects processed. */ #ifdef HAVE_REGEX if (glflags.search_regex_text) { regfree(glflags.search_re); } #endif makename_destructor(); esb_destructor(&esb_long_cu_name); esb_destructor(&esb_short_cu_name); esb_destructor(&dwarf_error_line); sanitized_string_destructor(); ranges_esb_string_destructor(); /* Global flags initialization and esb-buffers destruction. */ reset_global_flags(); close_a_file(fd); close_a_file(tiedfd); #ifdef _WIN32 /* Close the null device used during formatting printing */ esb_close_null_device(); #endif /* _WIN32 */ check_for_major_errors(); if (glflags.gf_count_major_errors) { printf("There were %ld DWARF errors reported: " "see ERROR above\n", glflags.gf_count_major_errors); exit(FAILED); } /* As the tool have reached this point, it means there are no internal errors and we should return an OKAY condition, regardless if the file being processed has minor errors. */ return OKAY; } void print_any_harmless_errors(Dwarf_Debug dbg) { #define LOCAL_PTR_ARY_COUNT 50 /* We do not need to initialize the local array, libdwarf does it. */ const char *buf[LOCAL_PTR_ARY_COUNT]; unsigned totalcount = 0; unsigned i = 0; unsigned printcount = 0; int res = dwarf_get_harmless_error_list(dbg,LOCAL_PTR_ARY_COUNT,buf, &totalcount); if (res == DW_DLV_NO_ENTRY) { return; } if (totalcount > 0) { printf("\n*** HARMLESS ERROR COUNT: %u ***\n",totalcount); } for (i = 0 ; buf[i]; ++i) { ++printcount; DWARF_CHECK_COUNT(harmless_result,1); DWARF_CHECK_ERROR(harmless_result,buf[i]); } if (totalcount > printcount) { /*harmless_result.checks += (totalcount - printcount); */ DWARF_CHECK_COUNT(harmless_result,(totalcount - printcount)); /*harmless_result.errors += (totalcount - printcount); */ DWARF_ERROR_COUNT(harmless_result,(totalcount - printcount)); } } /* Print a summary of search results */ static void print_search_results(void) { const char *search_type = 0; const char *search_text = 0; if (glflags.search_any_text) { search_type = "any"; search_text = glflags.search_any_text; } else { if (glflags.search_match_text) { search_type = "match"; search_text = glflags.search_match_text; } else { search_type = "regex"; search_text = glflags.search_regex_text; } } fflush(stdout); fflush(stderr); printf("\nSearch type : '%s'\n",search_type); printf("Pattern searched : '%s'\n",search_text); printf("Occurrences Found: %d\n",glflags.search_occurrences); fflush(stdout); } /* This is for dwarf_print_lines() */ static void printf_callback_for_libdwarf(UNUSEDARG void *userdata, const char *data) { printf("%s",data); } /* Does not return on error. */ void get_address_size_and_max(Dwarf_Debug dbg, Dwarf_Half * size, Dwarf_Addr * max, Dwarf_Error *aerr) { int dres = 0; Dwarf_Half lsize = 4; /* Get address size and largest representable address */ dres = dwarf_get_address_size(dbg,&lsize,aerr); if (dres != DW_DLV_OK) { print_error(dbg, "get_address_size()", dres, *aerr); } if(max) { *max = (lsize == 8 ) ? 0xffffffffffffffffULL : 0xffffffff; } if(size) { *size = lsize; } } /* dbg is often null when dbgtied was passed in. */ static void dbgsetup(Dwarf_Debug dbg,struct dwconf_s *setup_config_file_data) { if (!dbg) { return; } dwarf_set_frame_rule_initial_value(dbg, setup_config_file_data->cf_initial_rule_value); dwarf_set_frame_rule_table_size(dbg, setup_config_file_data->cf_table_entry_count); dwarf_set_frame_cfa_value(dbg, setup_config_file_data->cf_cfa_reg); dwarf_set_frame_same_value(dbg, setup_config_file_data->cf_same_val); dwarf_set_frame_undefined_value(dbg, setup_config_file_data->cf_undefined_val); if (setup_config_file_data->cf_address_size) { dwarf_set_default_address_size(dbg, setup_config_file_data->cf_address_size); } dwarf_set_harmless_error_list_size(dbg,50); } /* Callable at any time, Sets section sizes with the sizes known as of the call. Repeat whenever about to reference a size that might not have been set as of the last call. */ static void set_global_section_sizes(Dwarf_Debug dbg) { dwarf_get_section_max_offsets_c(dbg, &glflags.section_high_offsets_global->debug_info_size, &glflags.section_high_offsets_global->debug_abbrev_size, &glflags.section_high_offsets_global->debug_line_size, &glflags.section_high_offsets_global->debug_loc_size, &glflags.section_high_offsets_global->debug_aranges_size, &glflags.section_high_offsets_global->debug_macinfo_size, &glflags.section_high_offsets_global->debug_pubnames_size, &glflags.section_high_offsets_global->debug_str_size, &glflags.section_high_offsets_global->debug_frame_size, &glflags.section_high_offsets_global->debug_ranges_size, &glflags.section_high_offsets_global->debug_pubtypes_size, &glflags.section_high_offsets_global->debug_types_size, &glflags.section_high_offsets_global->debug_macro_size, &glflags.section_high_offsets_global->debug_str_offsets_size, &glflags.section_high_offsets_global->debug_sup_size, &glflags.section_high_offsets_global->debug_cu_index_size, &glflags.section_high_offsets_global->debug_tu_index_size); } /* Given a file which we know is an elf file, process the dwarf data. */ static int process_one_file(int fd, int tiedfd, Elf *elf, Elf *tiedelf, const char * file_name, const char * tied_file_name, #ifdef DWARF_WITH_LIBELF int archive, #endif struct dwconf_s *l_config_file_data) { Dwarf_Debug dbg = 0; Dwarf_Debug dbgtied = 0; int dres = 0; struct Dwarf_Printf_Callback_Info_s printfcallbackdata; Dwarf_Half elf_address_size = 0; /* Target pointer size */ Dwarf_Error onef_err = 0; const char *title = 0; /* If using a tied file group number should be 2 DW_GROUPNUMBER_DWO but in a dwp or separate-split-dwarf object then 0 will find the .dwo data automatically. */ if (elf) { title = "dwarf_elf_init_b"; dres = dwarf_elf_init_b(elf, DW_DLC_READ,glflags.group_number, NULL, NULL, &dbg, &onef_err); } else { title = "dwarf_init_b"; dres = dwarf_init_b(fd, DW_DLC_READ,glflags.group_number, NULL, NULL, &dbg, &onef_err); } if (dres == DW_DLV_NO_ENTRY) { if (glflags.group_number > 0) { printf("No DWARF information present in %s " "for section group %d \n", file_name,glflags.group_number); } else { printf("No DWARF information present in %s\n",file_name); } return 0; } if (dres != DW_DLV_OK) { print_error(dbg, title, dres, onef_err); } dres = dwarf_add_file_path(dbg,file_name,&onef_err); if (dres != DW_DLV_OK) { print_error(dbg,"Unable to add file path to object file data", dres, onef_err); } if (tiedelf || tiedfd >= 0) { if (tiedelf) { dres = dwarf_elf_init_b(tiedelf, DW_DLC_READ, DW_GROUPNUMBER_BASE, NULL, NULL, &dbgtied, &onef_err); } else { /* The tied file we define as group 1, BASE. */ dres = dwarf_init_b(tiedfd, DW_DLC_READ, DW_GROUPNUMBER_BASE, NULL, NULL, &dbgtied, &onef_err); } if (dres == DW_DLV_NO_ENTRY) { printf("No DWARF information present in tied file: %s\n", tied_file_name); return 0; } if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_elf_init on tied_file", dres, onef_err); } dres = dwarf_add_file_path(dbgtied,tied_file_name,&onef_err); if (dres != DW_DLV_OK) { print_error(dbg, "Unable to add tied file name to tied file", dres, onef_err); } } memset(&printfcallbackdata,0,sizeof(printfcallbackdata)); printfcallbackdata.dp_fptr = printf_callback_for_libdwarf; dwarf_register_printf_callback(dbg,&printfcallbackdata); if (dbgtied) { dwarf_register_printf_callback(dbgtied,&printfcallbackdata); } memset(&printfcallbackdata,0,sizeof(printfcallbackdata)); dbgsetup(dbg,l_config_file_data); dbgsetup(dbgtied,l_config_file_data); get_address_size_and_max(dbg,&elf_address_size,0,&onef_err); #ifdef DWARF_WITH_LIBELF if (archive) { Elf_Arhdr *mem_header = elf_getarhdr(elf); const char *memname = (mem_header && mem_header->ar_name)? mem_header->ar_name:""; printf("\narchive member \t%s\n",sanitized(memname)); } #endif /* DWARF_WITH_LIBELF */ /* Ok for dbgtied to be NULL. */ dres = dwarf_set_tied_dbg(dbg,dbgtied,&onef_err); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_set_tied_dbg() failed", dres, onef_err); } /* Get .text and .debug_ranges info if in check mode */ if (glflags.gf_do_check_dwarf) { Dwarf_Addr lower = 0; Dwarf_Addr upper = 0; Dwarf_Unsigned size = 0; int res = 0; res = dwarf_get_section_info_by_name(dbg,".text",&lower,&size,&onef_err); if (DW_DLV_OK == res) { upper = lower + size; } /* Set limits for Ranges Information */ if (glflags.pRangesInfo) { SetLimitsBucketGroup(glflags.pRangesInfo,lower,upper); } /* Build section information */ build_linkonce_info(dbg); } if (glflags.gf_header_flag && elf) { #ifdef DWARF_WITH_LIBELF print_object_header(dbg); #endif /* DWARF_WITH_LIBELF */ } if (glflags.gf_section_groups_flag) { print_section_groups_data(dbg); /* If groupnum > 2 this turns off some of the gf_flags here so we don't print section names of things we do not want to print. */ update_section_flags_per_groups(dbg); } reset_overall_CU_error_data(); if (glflags.gf_info_flag || glflags.gf_line_flag || glflags.gf_types_flag || glflags.gf_check_macros || glflags.gf_macinfo_flag || glflags.gf_macro_flag || glflags.gf_cu_name_flag || glflags.gf_search_is_on || glflags.gf_producer_children_flag) { print_infos(dbg,TRUE); reset_overall_CU_error_data(); print_infos(dbg,FALSE); if (glflags.gf_check_macros) { set_global_section_sizes(dbg); if(macro_check_tree) { /* Fake item representing end of section. */ /* Length of the fake item is zero. */ print_macro_statistics("DWARF5 .debug_macro", ¯o_check_tree, glflags.section_high_offsets_global->debug_macro_size); } if(macinfo_check_tree) { /* Fake item representing end of section. */ /* Length of the fake item is zero. */ print_macro_statistics("DWARF2 .debug_macinfo", &macinfo_check_tree, glflags.section_high_offsets_global->debug_macinfo_size); } } clear_macro_statistics(¯o_check_tree); clear_macro_statistics(&macinfo_check_tree); } if (glflags.gf_gdbindex_flag) { reset_overall_CU_error_data(); /* By definition if gdb_index is present then "cu" and "tu" will not be. And vice versa. */ print_gdb_index(dbg); print_debugfission_index(dbg,"cu"); print_debugfission_index(dbg,"tu"); } if (glflags.gf_pubnames_flag) { reset_overall_CU_error_data(); print_pubnames(dbg); } if (glflags.gf_loc_flag) { reset_overall_CU_error_data(); print_locs(dbg); } if (glflags.gf_abbrev_flag) { reset_overall_CU_error_data(); print_abbrevs(dbg); } if (glflags.gf_string_flag) { reset_overall_CU_error_data(); print_strings(dbg); } if (glflags.gf_aranges_flag) { reset_overall_CU_error_data(); print_aranges(dbg); } if (glflags.gf_ranges_flag) { reset_overall_CU_error_data(); print_ranges(dbg); } if (glflags.gf_frame_flag || glflags.gf_eh_frame_flag) { reset_overall_CU_error_data(); current_cu_die_for_print_frames = 0; print_frames(dbg, glflags.gf_frame_flag, glflags.gf_eh_frame_flag, l_config_file_data); } if (glflags.gf_static_func_flag) { reset_overall_CU_error_data(); print_static_funcs(dbg); } if (glflags.gf_static_var_flag) { reset_overall_CU_error_data(); print_static_vars(dbg); } /* DWARF_PUBTYPES is the standard typenames dwarf section. SGI_TYPENAME is the same concept but is SGI specific ( it was defined 10 years before dwarf pubtypes). */ if (glflags.gf_pubtypes_flag) { reset_overall_CU_error_data(); print_types(dbg, DWARF_PUBTYPES); reset_overall_CU_error_data(); print_types(dbg, SGI_TYPENAME); } if (glflags.gf_weakname_flag) { reset_overall_CU_error_data(); print_weaknames(dbg); } if (glflags.gf_reloc_flag && elf) { reset_overall_CU_error_data(); #ifdef DWARF_WITH_LIBELF print_relocinfo(dbg); #endif /* DWARF_WITH_LIBELF */ } if (glflags.gf_debug_names_flag) { reset_overall_CU_error_data(); print_debug_names(dbg); } /* Print search results */ if (glflags.gf_search_print_results && glflags.gf_search_is_on) { print_search_results(); } /* The right time to do this is unclear. But we need to do it. */ if (glflags.gf_check_harmless) { print_any_harmless_errors(dbg); } /* Print error report only if errors have been detected */ /* Print error report if the -kd option */ print_checks_results(); /* Print the detailed attribute usage space and free the attributes_encoding data allocated. */ if (glflags.gf_check_attr_encoding) { print_attributes_encoding(dbg); } /* Print the tags and attribute usage */ if (glflags.gf_print_usage_tag_attr) { print_tag_attributes_usage(dbg); } if (glflags.gf_print_str_offsets) { /* print the .debug_str_offsets section, if any. */ print_str_offsets_section(dbg); } /* prints nothing unless section .gnu_debuglink is present. Lets print for a few critical sections. */ if( glflags.gf_gnu_debuglink_flag) { print_gnu_debuglink(dbg); } /* Could finish dbg first. Either order ok. */ if (dbgtied) { dres = dwarf_finish(dbgtied,&onef_err); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_finish on dbgtied", dres, onef_err); } dbgtied = 0; } groups_restore_subsidiary_flags(); dres = dwarf_finish(dbg, &onef_err); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_finish", dres, onef_err); dbg = 0; } printf("\n"); #ifdef DWARF_WITH_LIBELF clean_up_syms_malloc_data(); #endif /* DWARF_WITH_LIBELF */ destruct_abbrev_array(); esb_close_null_device(); helpertree_clear_statistics(&helpertree_offsets_base_info); helpertree_clear_statistics(&helpertree_offsets_base_types); return 0; } /* Generic constants for debugging */ #define DUMP_RANGES_INFO 1 /* Dump RangesInfo Table. */ #define DUMP_LOCATION_SECTION_INFO 2 /* Dump Location (.debug_loc) Info. */ #define DUMP_RANGES_SECTION_INFO 3 /* Dump Ranges (.debug_ranges) Info. */ #define DUMP_LINKONCE_INFO 4 /* Dump Linkonce Table. */ #define DUMP_VISITED_INFO 5 /* Dump Visited Info. */ /* ARGSUSED */ static void print_error_maybe_continue(UNUSEDARG Dwarf_Debug dbg, const char * msg, int dwarf_code, Dwarf_Error lerr, Dwarf_Bool do_continue) { unsigned long realmajorerr = glflags.gf_count_major_errors; printf("\n"); if (dwarf_code == DW_DLV_ERROR) { char * errmsg = dwarf_errmsg(lerr); /* We now (April 2016) guarantee the error number is in the error string so we do not need to print the dwarf_errno() value to show the number. */ if (do_continue) { printf( "%s ERROR: %s: %s. Attempting to continue.\n", glflags.program_name, msg, errmsg); } else { printf( "%s ERROR: %s: %s\n", glflags.program_name, msg, errmsg); } } else if (dwarf_code == DW_DLV_NO_ENTRY) { printf("%s NO ENTRY: %s: \n", glflags.program_name, msg); } else if (dwarf_code == DW_DLV_OK) { printf("%s: %s \n", glflags.program_name, msg); } else { printf("%s InternalError: %s: code %d\n", glflags.program_name, msg, dwarf_code); } /* Display compile unit name */ PRINT_CU_INFO(); glflags.gf_count_major_errors = realmajorerr; } void print_error(Dwarf_Debug dbg, const char * msg, int dwarf_code, Dwarf_Error lerr) { print_error_maybe_continue(dbg,msg,dwarf_code,lerr,FALSE); if (dbg) { Dwarf_Error ignored_err = 0; /* If dbg was never initialized dwarf_finish can do nothing useful. There is no global-state for libdwarf to clean up. */ if (dwarf_code == DW_DLV_ERROR) { dwarf_dealloc(dbg,lerr,DW_DLA_ERROR); } dwarf_finish(dbg, &ignored_err); check_for_major_errors(); } exit(FAILED); } /* ARGSUSED */ void print_error_and_continue(Dwarf_Debug dbg, const char * msg, int dwarf_code, Dwarf_Error lerr) { glflags.gf_count_major_errors++; print_error_maybe_continue(dbg, msg,dwarf_code,lerr,TRUE); } /* Predicate function. Returns 'true' if the CU should be skipped as the DW_AT_name of the CU does not match the command-line-supplied cu name. Else returns false.*/ boolean should_skip_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die) { Dwarf_Half tag = 0; Dwarf_Attribute attrib = 0; Dwarf_Half theform = 0; int dares = 0; int tres = 0; int fres = 0; Dwarf_Error lerr = 0; tres = dwarf_tag(cu_die, &tag, &lerr); if (tres != DW_DLV_OK) { print_error(dbg, "dwarf_tag in aranges", tres, lerr); } dares = dwarf_attr(cu_die, DW_AT_name, &attrib, &lerr); if (dares != DW_DLV_OK) { print_error(dbg, "dwarf_attr arange" " derived die has no name", dares, lerr); } fres = dwarf_whatform(attrib, &theform, &lerr); if (fres == DW_DLV_OK) { if (theform == DW_FORM_string || theform == DW_FORM_strp) { char * temps = 0; int sres = dwarf_formstring(attrib, &temps, &lerr); if (sres == DW_DLV_OK) { char *lcun = esb_get_string(glflags.cu_name); char *p = temps; if (lcun[0] != '/') { p = strrchr(temps, '/'); if (p == NULL) { p = temps; } else { p++; } } /* Ignore case if Windows */ #if _WIN32 if (stricmp(lcun, p)) { /* skip this cu. */ return TRUE; } #else if (strcmp(lcun, p)) { /* skip this cu. */ return TRUE; } #endif /* _WIN32 */ } else { print_error(dbg, "arange: string missing", sres, lerr); } } } else { print_error(dbg, "dwarf_whatform unexpected value.", fres, lerr); } dwarf_dealloc(dbg, attrib, DW_DLA_ATTR); return FALSE; } /* Returns the cu of the CU. In case of error, give up, do not return. */ int get_cu_name(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, char * *short_name, char * *long_name) { Dwarf_Attribute name_attr = 0; Dwarf_Error lerr = 0; int ares; ares = dwarf_attr(cu_die, DW_AT_name, &name_attr, &lerr); if (ares == DW_DLV_ERROR) { print_error(dbg, "hassattr on DW_AT_name", ares, lerr); } else { if (ares == DW_DLV_NO_ENTRY) { *short_name = ""; *long_name = ""; } else { /* DW_DLV_OK */ /* The string return is valid until the next call to this function; so if the caller needs to keep the returned string, the string must be copied (makename()). */ char *filename = 0; esb_empty_string(&esb_long_cu_name); get_attr_value(dbg, DW_TAG_compile_unit, cu_die, dieprint_cu_offset, name_attr, NULL, 0, &esb_long_cu_name, 0 /*show_form_used*/,0 /* verbose */); *long_name = esb_get_string(&esb_long_cu_name); /* Generate the short name (filename) */ filename = strrchr(*long_name,'/'); if (!filename) { filename = strrchr(*long_name,'\\'); } if (filename) { ++filename; } else { filename = *long_name; } esb_empty_string(&esb_short_cu_name); esb_append(&esb_short_cu_name,filename); *short_name = esb_get_string(&esb_short_cu_name); } } dwarf_dealloc(dbg, name_attr, DW_DLA_ATTR); return ares; } /* Returns the producer of the CU Caller must ensure producernameout is a valid, constructed, empty esb_s instance before calling. Never returns DW_DLV_ERROR. */ int get_producer_name(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, struct esb_s *producernameout) { Dwarf_Attribute producer_attr = 0; Dwarf_Error pnerr = 0; int ares = dwarf_attr(cu_die, DW_AT_producer, &producer_attr, &pnerr); if (ares == DW_DLV_ERROR) { print_error(dbg, "hassattr on DW_AT_producer", ares, pnerr); } if (ares == DW_DLV_NO_ENTRY) { /* We add extra quotes so it looks more like the names for real producers that get_attr_value produces. */ esb_append(producernameout,"\"\""); } else { /* DW_DLV_OK */ /* The string return is valid until the next call to this function; so if the caller needs to keep the returned string, the string must be copied (makename()). */ get_attr_value(dbg, DW_TAG_compile_unit, cu_die, dieprint_cu_offset, producer_attr, NULL, 0, producernameout, 0 /*show_form_used*/,0 /* verbose */); } /* If ares is error or missing case, producer_attr will be left NULL by the call, which is safe when calling dealloc(). */ dwarf_dealloc(dbg, producer_attr, DW_DLA_ATTR); return ares; } void print_secname(Dwarf_Debug dbg,const char *secname) { if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,secname, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } } /* We'll check for errors when checking. print only if printing (as opposed to checking). */ static void print_gnu_debuglink(Dwarf_Debug dbg) { int res = 0; char * name = 0; unsigned char *crcbytes = 0; char * link_path = 0; unsigned link_path_len = 0; unsigned buildidtype = 0; char *buildidowner = 0; unsigned char *buildidbyteptr = 0; unsigned buildidlength = 0; char **paths_array = 0; unsigned paths_array_length = 0; Dwarf_Error linkerror = 0; res = dwarf_gnu_debuglink(dbg, &name, &crcbytes, &link_path, /* free this */ &link_path_len, &buildidtype, &buildidowner, &buildidbyteptr, &buildidlength, &paths_array, /* free this */ &paths_array_length, &linkerror); if (res == DW_DLV_NO_ENTRY) { return; } else if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "Error accessing debuglink or note section", res,linkerror); } if (crcbytes) { print_secname(dbg,".gnu_debuglink"); /* Done with error checking, so print if we are printing. */ if (glflags.gf_do_print_dwarf) { printf(" Debuglink name : %s",sanitized(name)); { unsigned char *crc = 0; unsigned char *end = 0; crc = crcbytes; end = crcbytes +4; printf(" crc 0X: "); for (; crc < end; crc++) { printf("%02x ", *crc); } } printf("\n"); if (link_path_len) { printf(" Debuglink target: %s\n",sanitized(link_path)); } } } if (buildidlength) { print_secname(dbg,".note.gnu.build-id"); if (glflags.gf_do_print_dwarf) { printf(" Build-id type : %u\n", buildidtype); printf(" Build-id ownername: %s\n", sanitized(buildidowner)); printf(" Build-id length : %u\n",buildidlength); printf(" Build-id : "); { const unsigned char *cur = 0; const unsigned char *end = 0; cur = buildidbyteptr; end = cur + buildidlength; for (; cur < end; cur++) { printf("%02x", (unsigned char)*cur); } } printf("\n"); } } if (paths_array_length) { unsigned i = 0; printf(" Possible " ".gnu_debuglink/.note.gnu.build-id pathnames for\n"); printf(" an alternate object file with more detailed DWARF\n"); for( ; i < paths_array_length; ++i) { char *path = paths_array[i]; printf(" [%u] %s\n",i,sanitized(path)); } printf("\n"); } free(link_path); free(paths_array); } /* GCC linkonce names */ char *lo_text = ".text."; /*".gnu.linkonce.t.";*/ char *lo_debug_abbr = ".gnu.linkonce.wa."; char *lo_debug_aranges = ".gnu.linkonce.wr."; char *lo_debug_frame_1 = ".gnu.linkonce.wf."; char *lo_debug_frame_2 = ".gnu.linkonce.wF."; char *lo_debug_info = ".gnu.linkonce.wi."; char *lo_debug_line = ".gnu.linkonce.wl."; char *lo_debug_macinfo = ".gnu.linkonce.wm."; char *lo_debug_loc = ".gnu.linkonce.wo."; char *lo_debug_pubnames = ".gnu.linkonce.wp."; char *lo_debug_ranges = ".gnu.linkonce.wR."; char *lo_debug_str = ".gnu.linkonce.ws."; /* SNC compiler/linker linkonce names */ char *nlo_text = ".text."; char *nlo_debug_abbr = ".debug.wa."; char *nlo_debug_aranges = ".debug.wr."; char *nlo_debug_frame_1 = ".debug.wf."; char *nlo_debug_frame_2 = ".debug.wF."; char *nlo_debug_info = ".debug.wi."; char *nlo_debug_line = ".debug.wl."; char *nlo_debug_macinfo = ".debug.wm."; char *nlo_debug_loc = ".debug.wo."; char *nlo_debug_pubnames = ".debug.wp."; char *nlo_debug_ranges = ".debug.wR."; char *nlo_debug_str = ".debug.ws."; /* Build linkonce section information */ void build_linkonce_info(Dwarf_Debug dbg) { int nCount = 0; int section_index = 0; int res = 0; static char **linkonce_names[] = { &lo_text, /* .text */ &nlo_text, /* .text */ &lo_debug_abbr, /* .debug_abbr */ &nlo_debug_abbr, /* .debug_abbr */ &lo_debug_aranges, /* .debug_aranges */ &nlo_debug_aranges, /* .debug_aranges */ &lo_debug_frame_1, /* .debug_frame */ &nlo_debug_frame_1, /* .debug_frame */ &lo_debug_frame_2, /* .debug_frame */ &nlo_debug_frame_2, /* .debug_frame */ &lo_debug_info, /* .debug_info */ &nlo_debug_info, /* .debug_info */ &lo_debug_line, /* .debug_line */ &nlo_debug_line, /* .debug_line */ &lo_debug_macinfo, /* .debug_macinfo */ &nlo_debug_macinfo, /* .debug_macinfo */ &lo_debug_loc, /* .debug_loc */ &nlo_debug_loc, /* .debug_loc */ &lo_debug_pubnames, /* .debug_pubnames */ &nlo_debug_pubnames, /* .debug_pubnames */ &lo_debug_ranges, /* .debug_ranges */ &nlo_debug_ranges, /* .debug_ranges */ &lo_debug_str, /* .debug_str */ &nlo_debug_str, /* .debug_str */ NULL }; const char *section_name = NULL; Dwarf_Addr section_addr = 0; Dwarf_Unsigned section_size = 0; Dwarf_Error error = 0; int nIndex = 0; nCount = dwarf_get_section_count(dbg); /* Ignore section with index=0 */ for (section_index = 1; section_index < nCount; ++section_index) { res = dwarf_get_section_info_by_index(dbg,section_index, §ion_name, §ion_addr, §ion_size, &error); if (res == DW_DLV_OK) { for (nIndex = 0; linkonce_names[nIndex]; ++nIndex) { if (section_name == strstr(section_name, *linkonce_names[nIndex])) { /* Insert only linkonce sections */ AddEntryIntoBucketGroup(glflags.pLinkonceInfo, section_index, section_addr,section_addr, section_addr + section_size, section_name, TRUE); break; } } } } if (dump_linkonce_info) { PrintBucketGroup(glflags.pLinkonceInfo,TRUE); } } /* Check for specific TAGs and initialize some information used by '-k' options */ void tag_specific_checks_setup(Dwarf_Half val,int die_indent_level) { switch (val) { case DW_TAG_compile_unit: /* To help getting the compile unit name */ glflags.seen_CU = TRUE; /* If we are checking line information, build the table containing the pairs LowPC and HighPC */ if (glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations) { ResetBucketGroup(glflags.pRangesInfo); } /* The following flag indicate that only low_pc and high_pc values found in DW_TAG_subprograms are going to be considered when building the address table used to check ranges, lines, etc */ glflags.need_PU_valid_code = TRUE; break; case DW_TAG_subprogram: /* Keep track of a PU */ if (die_indent_level == 1) { /* A DW_TAG_subprogram can be nested, when is used to declare a member function for a local class; process the DIE only if we are at level zero in the DIEs tree */ glflags.seen_PU = TRUE; glflags.seen_PU_base_address = FALSE; glflags.seen_PU_high_address = FALSE; glflags.PU_name[0] = 0; glflags.need_PU_valid_code = TRUE; } break; } } /* Print CU basic information but use the local DIE for the offsets. */ void PRINT_CU_INFO(void) { Dwarf_Unsigned loff = glflags.DIE_offset; Dwarf_Unsigned goff = glflags.DIE_overall_offset; char lbuf[50]; char hbuf[50]; if (glflags.current_section_id == DEBUG_LINE || glflags.current_section_id == DEBUG_FRAME || glflags.current_section_id == DEBUG_FRAME_EH_GNU || glflags.current_section_id == DEBUG_ARANGES || glflags.current_section_id == DEBUG_MACRO || glflags.current_section_id == DEBUG_MACINFO ) { /* These sections involve the CU die, so use the CU offsets. The DEBUG_MAC* cases are logical but not yet useful (Dec 2015). In other cases the local DIE offset makes more sense. */ loff = glflags.DIE_CU_offset; goff = glflags.DIE_CU_overall_offset; } if (!cu_data_is_set()) { return; } printf("\n"); printf("CU Name = %s\n",sanitized(glflags.CU_name)); printf("CU Producer = %s\n",sanitized(glflags.CU_producer)); printf("DIE OFF = 0x%" DW_PR_XZEROS DW_PR_DUx " GOFF = 0x%" DW_PR_XZEROS DW_PR_DUx, loff,goff); /* We used to print leftover and incorrect values at times. */ if (glflags.need_CU_high_address) { safe_strcpy(hbuf,sizeof(hbuf),"unknown ",10); } else { /* safe, hbuf is large enough. */ sprintf(hbuf, "0x%" DW_PR_XZEROS DW_PR_DUx,glflags.CU_high_address); } if (glflags.need_CU_base_address) { safe_strcpy(lbuf,sizeof(lbuf),"unknown ",10); } else { /* safe, lbuf is large enough. */ sprintf(lbuf, "0x%" DW_PR_XZEROS DW_PR_DUx,glflags.CU_low_address); } #if 0 /* Old format print */ printf(", Low PC = 0x%08" DW_PR_DUx ", High PC = 0x%08" DW_PR_DUx , CU_low_address,CU_high_address); #endif printf(", Low PC = %s, High PC = %s", lbuf,hbuf); printf("\n"); } void DWARF_CHECK_ERROR_PRINT_CU() { if (glflags.gf_check_verbose_mode) { if (glflags.gf_print_unique_errors) { if (!glflags.gf_found_error_message) { PRINT_CU_INFO(); } } else { PRINT_CU_INFO(); } } glflags.check_error++; glflags.gf_record_dwarf_error = TRUE; } /* Sometimes is useful, just to know the kind of errors in an object file; not much interest in the number of errors; the specific case is just to have a general idea about the DWARF quality in the file */ char ** set_unique_errors = NULL; unsigned int set_unique_errors_entries = 0; unsigned int set_unique_errors_size = 0; #define SET_UNIQUE_ERRORS_DELTA 64 /* Create the space to store the unique error messages */ void allocate_unique_errors_table(void) { if (!set_unique_errors) { set_unique_errors = (char **) malloc(SET_UNIQUE_ERRORS_DELTA * sizeof(char*)); set_unique_errors_size = SET_UNIQUE_ERRORS_DELTA; set_unique_errors_entries = 0; } } #ifdef TESTING /* Just for debugging purposes, dump the unique errors table */ void dump_unique_errors_table(void) { unsigned int index; printf("*** Unique Errors Table ***\n"); printf("Delta : %d\n",SET_UNIQUE_ERRORS_DELTA); printf("Size : %d\n",set_unique_errors_size); printf("Entries: %d\n",set_unique_errors_entries); for (index = 0; index < set_unique_errors_entries; ++index) { printf("%3d: '%s'\n",index,set_unique_errors[index]); } } #endif /* Release the space used to store the unique error messages */ void release_unique_errors_table(void) { unsigned int index; for (index = 0; index < set_unique_errors_entries; ++index) { free(set_unique_errors[index]); } free(set_unique_errors); set_unique_errors = 0; set_unique_errors_entries = 0; set_unique_errors_size = 0; } /* Returns TRUE if the text is already in the set; otherwise FALSE */ boolean add_to_unique_errors_table(char * error_text) { unsigned int index; size_t len; char * stored_text; char * filtered_text; char * start = NULL; char * end = NULL; char * pattern = "0x"; char * white = " "; char * question = "?"; /* Create a copy of the incoming text */ filtered_text = makename(error_text); len = strlen(filtered_text); /* Remove from the error_text, any hexadecimal numbers (start with 0x), because for some errors, an additional information is given in the form of addresses; we are interested just in the general error. */ start = strstr(filtered_text,pattern); while (start) { /* We have found the start of the pattern; look for a space */ end = strstr(start,white); if (!end) { /* Preserve any line terminator */ end = filtered_text + len -1; } memset(start,*question,end - start); start = strstr(filtered_text,pattern); } /* Check if the error text is already in the table */ for (index = 0; index < set_unique_errors_entries; ++index) { stored_text = set_unique_errors[index]; if (!strcmp(stored_text,filtered_text)) { return TRUE; } } /* Store the new text; check if we have space to store the error text */ if (set_unique_errors_entries + 1 == set_unique_errors_size) { set_unique_errors_size += SET_UNIQUE_ERRORS_DELTA; set_unique_errors = (char **)realloc(set_unique_errors, set_unique_errors_size * sizeof(char*)); } set_unique_errors[set_unique_errors_entries] = filtered_text; ++set_unique_errors_entries; return FALSE; } /* Print a DWARF error message and if in "reduced" output only print one error of each kind; this feature is useful, when we are interested only in the kind of errors and not on the number of errors. PRECONDITION: if s3 non-null so are s1,s2. If s2 is non-null so is s1. s1 is always non-null. */ static void print_dwarf_check_error(const char *s1,const char *s2, const char *s3) { static boolean do_init = TRUE; boolean found = FALSE; char * error_text = NULL; static char *leader = "\n*** DWARF CHECK: "; static char *trailer = " ***\n"; if (do_init) { esb_constructor(&dwarf_error_line); do_init = FALSE; } esb_empty_string(&dwarf_error_line); esb_append(&dwarf_error_line,leader); /* print_dwarf_check_error("\n*** DWARF CHECK: %s ***\n", str); print_dwarf_check_error("\n*** DWARF CHECK: %s: %s ***\n", print_dwarf_check_error("\n*** DWARF CHECK: %s -> %s: %s ***\n", */ if (s3) { esb_append(&dwarf_error_line,s1); esb_append(&dwarf_error_line," -> "); esb_append(&dwarf_error_line,s2); esb_append(&dwarf_error_line,": "); esb_append(&dwarf_error_line,s3); } else if (s2) { esb_append(&dwarf_error_line,s1); esb_append(&dwarf_error_line,": "); esb_append(&dwarf_error_line,s2); } else { esb_append(&dwarf_error_line,s1); } esb_append(&dwarf_error_line,trailer); error_text = esb_get_string(&dwarf_error_line); if (glflags.gf_print_unique_errors) { found = add_to_unique_errors_table(error_text); if (!found) { printf("%s",error_text); } } else { printf("%s",error_text); } /* To indicate if the current error message have been found or not */ glflags.gf_found_error_message = found; } void DWARF_CHECK_ERROR3(Dwarf_Check_Categories category, const char *str1, const char *str2, const char *strexpl) { if (checking_this_compiler()) { DWARF_ERROR_COUNT(category,1); if (glflags.gf_check_verbose_mode) { print_dwarf_check_error(str1, str2,strexpl); } DWARF_CHECK_ERROR_PRINT_CU(); } } dwarfutils-20200114/dwarfdump/dwarfdump.conf000066400000000000000000000357701361531463500210050ustar00rootroot00000000000000# MIPS/IRIX ISA/ABI # Used to configure dwarfdump printing of .debug_frame and # .eh_frame. # Any number of abi's can be described. Only one can be selected # in a given dwarfdump run (see dwarfdump options) # Available commands are # beginabi: # reg: # frame_interface: # cfa_reg: # initial_reg_value: # same_val_reg: 1035 # undefined_val_reg: 1034 # reg_table_size: # address_size: <4 or 8, Rarely needed, see example below. > # includeabi: # endabi: # # Symbolic names do not work here, use literal numbers # where applicable (in C standard decimal, octal (leading 0) or # hexadecimal ). # # Whitespace is required to separate command: from operands and # operands from each other on a line. # # There is no ordering required within a beginabi/endabi pair. # As many ABIs as required may be listed. # dwarfdump will choose exactly one abi to dump frame information. # # MIPS abi,the old IRIX form, not to be used on modern objects. # Begin with abi name (use here and on dwarfdump command line). beginabi: mips-irix # Instructs dwarfdump to default to the older frame interface. # Use value 3 to use the newer interface. # The '2' interface is supported but deprecated (deprecated # because it cannot work with all popular ABIs: mixing # the cfa-rule into the table column set was not a good idea # but it is part of the MIPS/IRIX standard usage). frame_interface: 2 # If (and only if) using frame_interface: 2 tell dwarfdump # what table colum that DW_FRAME_CFA_COL is. # If using frame_interface: 3 cfa_reg: should be # DW_FRAME_CFA_COL3 (1436) cfa_reg: 0 # For MIPS, the same as DW_FRAME_SAME_VAL (1035). # For other ISA/ABIs 1034 (DW_FRAME_UNDEFINED_VAL) might be better. # Depends on the ABI convention, if set wrong way too many # regs will be listed in the frame output. # This instructs dwarfdump to set libdwarf to this value, # overriding the libdwarf default. # If initial_reg_value not set the libdwarf default is used # (see libdwarf.h DW_FRAME_REG_INITIAL_VALUE). initial_reg_value: 1035 # DW_FRAME_SAME_VAL same_val_reg: 1035 undefined_val_reg: 1034 # Built in to frame_interface: 2 as 66. reg_table_size: 66 # Only name registers for wich a r4 (for example) is not what you # want to see # No particular order of the reg: lines required. reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface reg: r1/at 1 reg: r2/v0 2 reg: r3/v1 3 reg: r4/a0 4 reg: r5/a1 5 reg: r6/a2 6 reg: r7/a3 7 reg: r8/t0 8 reg: r9/t1 9 reg: r10/t2 10 reg: r11/t3 11 reg: r12/t4 12 reg: r13/t5 13 reg: r14/t6 14 reg: r15/t7 15 reg: r16/s0 16 reg: r17/s1 17 reg: r18/s2 18 reg: r19/s3 19 reg: r20/s4 20 reg: r21/s5 21 reg: r22/s6 22 reg: r23/s7 23 reg: r24/t8 24 reg: r25/t9 25 reg: r26/k0 26 reg: r27/k1 27 reg: r28/gp 28 reg: r29/sp 29 reg: r30/s8 30 reg: r31 31 reg: $f0 32 reg: $f1 33 reg: $f2 34 reg: $f3 35 reg: $f4 36 reg: $f5 37 reg: $f6 38 reg: $f7 39 reg: $f8 40 reg: $f9 41 reg: $f10 42 reg: $f11 43 reg: $f12 44 reg: $f13 45 reg: $f14 46 reg: $f15 47 reg: $f16 48 reg: $f17 49 reg: $f18 50 reg: $f19 51 reg: $f20 52 reg: $f21 53 reg: $f22 54 reg: $f23 55 reg: $f24 56 reg: $f25 57 reg: $f26 58 reg: $f27 59 reg: $f28 60 reg: $f29 61 reg: $f30 62 reg: $f31 63 reg: ra 64 reg: slk 65 # End of abi definition. endabi: mips-irix # Make 'mips' abi be a modern MIPS, not an old IRIX version. beginabi: mips includeabi: mips-simple3 endabi: mips # MIPS/IRIX ISA/ABI for testing libdwarf. beginabi: mips-irix2 frame_interface: 2 reg_table_size: 66 cfa_reg: 0 same_val_reg: 1035 undefined_val_reg: 1034 initial_reg_value: 1035 reg: cfa 0 # Used with MIPS/IRIX original DWARF2 interface reg: ra 64 reg: slk 65 # End of abi definition. endabi: mips-irix2 # MIPS/IRIX ISA/ABI for testing the new frame interface # with libdwarf. beginabi: mips-simple3 frame_interface: 3 # When using frame_interface: 3 the size of the register table # is not fixed. It can be as large as needed. reg_table_size: 66 cfa_reg: 1436 # DW_FRAME_CFA_COL3 initial_reg_value: 1035 same_val_reg: 1035 undefined_val_reg: 1034 # No cfa as a 'normal' register. # Rule 0 is just register 0, which is not used # in frame descriptions. # (so cfa does not have a number here, and dwarfdump gives # it the name 'cfa' automatically). reg: ra 64 reg: slk 65 # End of abi definition. endabi: mips-simple3 beginabi: ia64 frame_interface: 3 initial_reg_value: 1034 # DW_FRAME_UNDEFINED_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 695 same_val_reg: 1035 undefined_val_reg: 1034 # The following register names are not necessarily correct... # Register indexes r32-r127 not used. reg: f0 128 # ... reg: f127 255 reg: b0 321 reg: b1 322 reg: b2 323 reg: b3 324 reg: b4 325 reg: b5 326 reg: b6 327 reg: b7 328 reg: vfp 329 reg: vrap 330 reg: pr 331 reg: ip 332 reg: psr 333 reg: cfm 334 reg: k0 335 reg: k1 336 reg: k2 337 reg: k3 338 reg: k4 339 reg: k5 340 reg: k6 341 reg: k7 342 reg: rsc 350 reg: bsp 351 reg: bspstore 352 reg: rnat 353 reg: fcr 355 reg: eflag 358 reg: csd 359 reg: ssd 360 reg: cflg 361 reg: fsr 362 reg: fir 363 reg: fdr 364 reg: pfs 398 reg: lc 399 reg: ec 400 endabi: ia64 beginabi: x86 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL reg_table_size: 66 # more than large enough, hopefully. cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1035 undefined_val_reg: 1034 # The following register names are not necessarily correct... reg: eax 0 reg: ecx 1 reg: edx 2 reg: ebx 3 reg: esp 4 reg: ebp 5 reg: esi 6 reg: edi 7 reg: eip 8 reg: eflags 9 reg: trapno 10 reg: st0 11 reg: st1 12 reg: st2 13 reg: st3 14 reg: st4 15 reg: st5 16 reg: st6 17 reg: st7 18 # 19 is ? 20 is ? reg: xmm0 21 reg: xmm1 22 reg: xmm2 23 reg: xmm3 24 reg: xmm4 25 reg: xmm5 26 reg: xmm6 27 reg: xmm7 28 reg: mm0 29 reg: mm1 30 reg: mm2 31 reg: mm3 32 reg: mm4 33 reg: mm5 34 reg: mm6 35 reg: mm7 36 reg: fcw 37 reg: fsw 38 reg: mxcsr 39 reg: es 40 reg: cs 41 reg: ss 42 reg: ds 43 reg: fs 44 reg: gs 45 # 46 47 are ? reg: tr 48 reg: ldtr 49 endabi: x86 beginabi: x86_64 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL reg_table_size: 66 # more than large enough, hopefully. cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1035 undefined_val_reg: 1034 # The following register names are not necessarily correct... reg: rax 0 reg: rdx 1 reg: rcx 2 reg: rbx 3 reg: rsi 4 reg: rdi 5 reg: rbp 6 reg: rsp 7 reg: r8 8 reg: r9 9 reg: r10 10 reg: r11 11 reg: r12 12 reg: r13 13 reg: r14 14 reg: r15 15 reg: rip 16 reg: xmm0 17 reg: xmm1 18 reg: xmm2 19 reg: xmm3 20 reg: xmm4 21 reg: xmm5 22 reg: xmm6 23 reg: xmm7 24 reg: xmm8 25 reg: xmm9 26 reg: xmm10 27 reg: xmm11 28 reg: xmm12 29 reg: xmm13 30 reg: xmm14 31 reg: xmm15 32 reg: st0 33 reg: st1 34 reg: st2 35 reg: st3 36 reg: st4 37 reg: st5 38 reg: st6 39 reg: st7 40 reg: mm0 41 reg: mm1 42 reg: mm2 43 reg: mm3 44 reg: mm4 45 reg: mm5 46 reg: mm6 47 reg: mm7 48 reg: rflags 49 reg: es 50 reg: cs 51 reg: ss 52 reg: ds 53 reg: fs 54 reg: gs 55 # 56, 57 are ? reg: fs.base 58 reg: gs.base 59 # 60 61 are ? reg: tr 62 reg: ldtr 63 endabi: x86_64 beginabi: m68k frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL reg_table_size: 66 # more than large enough, hopefully. cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1035 undefined_val_reg: 1034 reg: d0 0 reg: d1 1 reg: d2 2 reg: d3 3 reg: d4 4 reg: d5 5 reg: d6 6 reg: d7 7 reg: a0 8 reg: a1 9 reg: a2 10 reg: a3 11 reg: a4 12 reg: a5 13 reg: a6 14 reg: sp 15 reg: fp0 16 reg: fp1 17 reg: fp2 18 reg: fp3 19 reg: fp4 20 reg: fp5 21 reg: fp6 22 reg: pc 23 endabi: m68k # Demonstrates use of address_size and includeabi keywords. # address_size is useful when an Elf64 object has DWARF2 # 32bit (4 byte) address-size frame data (which has no address_size field) # and no .debug_info section to provide the 32bit address size. beginabi: ppc32bitaddress address_size: 4 includeabi: ppc endabi: ppc32bitaddress beginabi: ppc # This abi defined Oct 2008 based on: # http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html frame_interface: 3 # abi dwarf table uses up thru 1155. # As of Oct 2008, the only ABI requiring a higher # DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3. initial_reg_value: 1235 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 same_val_reg: 1235 undefined_val_reg: 1234 reg_table_size: 1200 reg: r0 0 reg: f0 32 reg: f1 33 reg: f2 34 reg: f3 35 reg: f4 36 reg: f5 37 reg: f6 38 reg: f7 39 reg: f8 40 reg: f9 41 reg: f10 42 reg: f11 43 reg: f12 44 reg: f13 45 reg: f14 46 reg: f16 47 reg: f17 48 reg: f18 49 reg: f19 50 reg: f20 51 reg: f21 52 reg: f22 53 reg: f23 54 reg: f24 55 reg: f25 56 reg: f26 57 reg: f27 58 reg: f28 59 reg: f29 60 reg: f30 62 reg: f31 63 reg: cr 64 reg: fpcsr 65 # spr0 is also called MQ reg: spr0 100 # spr1 is also called XER reg: spr1 101 # spr4 also called rtcu reg: spr4 104 # spr5 also called rtcl reg: spr5 105 #spr8 also called LR reg: spr8 108 # spr9 also called ctr reg: spr9 109 reg: msr 66 reg: sr0 70 reg: sr1 71 reg: sr2 72 reg: sr3 73 reg: sr4 74 reg: sr5 75 reg: sr6 76 reg: sr7 77 reg: sr8 78 reg: sr9 79 #dsisr also called spr18 reg: spr18 118 # dar also called spr19 reg: spr19 119 #dec also called spr22 reg: spr22 122 #sdr1 also called spr25 reg: spr25 125 #srr0 also called spr26 reg: spr26 126 #srr1 also called spr27 reg: spr27 127 #vrsave also called spr256 reg: spr256 356 #sprg0 also called spr272 reg: spr272 372 #sprg1 also called spr273 reg: spr273 373 #sprg2 also called spr274 reg: spr274 374 #sprg3 also called spr275 reg: spr275 375 #asr also called spr280 reg: spr280 380 #ear also called spr282 reg: spr282 382 #tb also called spr284 reg: spr284 384 #tbu also called spr285 reg: spr285 385 #pvr also called spr287 reg: spr287 387 #ibat0u also called spr528 reg: spr528 628 #ibat0l also called spr529 reg: spr529 629 #ibat1u also called spr530 reg: spr530 630 #ibat1l also called spr531 reg: spr531 631 #ibat2u also called spr532 reg: spr532 632 #ibat2l also called spr533 reg: spr533 633 #ibat3u also called spr534 reg: spr534 634 #ibat3l also called spr535 reg: spr535 635 #dbat0u also called spr536 reg: spr536 636 #dbat0l also called spr537 reg: spr537 637 #dbat1u also called spr538 reg: spr538 638 #dbat1l also called spr539 reg: spr539 639 #dbat2u also called spr540 reg: spr540 640 #dbat2l also called spr541 reg: spr541 641 #dbat3u also called spr542 reg: spr542 642 #dbat3l also called spr543 reg: spr543 643 #hid0 also called spr1008 reg: spr1008 1108 #hid1 also called spr1009 reg: spr1009 1109 #hid2 also called iabr or spr1010 reg: spr1010 1110 #hid5 also called dabr or spr1013 reg: spr1013 1113 #hid15 also called pir or spr1023 reg: spr1023 1123 # vector registers 0-31 reg: vr0 1124 reg: vr1 1125 reg: vr2 1126 reg: vr3 1127 reg: vr4 1128 reg: vr5 1129 reg: vr6 1130 reg: vr7 1131 reg: vr8 1132 reg: vr9 1133 reg: vr10 1134 reg: vr11 1135 reg: vr12 1136 reg: vr13 1137 reg: vr14 1138 reg: vr15 1130 reg: vr16 1140 reg: vr17 1141 reg: vr18 1142 reg: vr19 1143 reg: vr20 1144 reg: vr21 1145 reg: vr22 1146 reg: vr23 1147 reg: vr24 1148 reg: vr25 1149 reg: vr26 1150 reg: vr27 1151 reg: vr28 1152 reg: vr29 1153 reg: vr30 1154 reg: vr31 1155 endabi: ppc # 'Generic 1000 register abi'. # This is useful as a 'general' ABI settings for # cpus using up to 1000 registers. The register names # show as a number, like 'r991'. beginabi: generic frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 1000 same_val_reg: 1035 undefined_val_reg: 1034 reg: r0 0 endabi: generic # 'Generic 500 register abi'. # This is useful as a 'general' ABI settings for # cpus using up to 500 registers. The register names # show as a number, like 'r91'. beginabi: generic500 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 500 same_val_reg: 1035 undefined_val_reg: 1034 reg: r0 0 endabi: generic500 # 'Generic 100 register abi'. # This is useful as a 'general' ABI settings for # cpus using up to 100 registers. The register names # show as a number, like 'r91'. beginabi: generic100 frame_interface: 3 initial_reg_value: 1035 # DW_FRAME_SAME_VAL cfa_reg: 1436 # DW_FRAME_CFA_COL3 reg_table_size: 100 same_val_reg: 1035 undefined_val_reg: 1034 reg: r0 0 endabi: generic100 beginabi: arm frame_interface: 3 # When using frame_interface: 3 the size of the register # table is not fixed. It can be as large as needed. reg_table_size: 288 cfa_reg: 1436 # DW_FRAME_CFA_COL3 initial_reg_value: 1034 same_val_reg: 1035 undefined_val_reg: 1034 # If the vendor co-processor registers are allowed # or other numbers above 287 used then # the reg_table_size must be increased and (possibly) # the cfa, same_value, undefined_value reg values changed # here. # r0-r15 are 0 through 15. # Numbers 16 through 63 had meaning # in some ARM DWARF register mappings. reg: s0 64 reg: s1 65 reg: s2 66 reg: s3 67 reg: s4 68 reg: s5 69 reg: s6 70 reg: s7 71 reg: s8 72 reg: s9 73 reg: s10 74 reg: s11 75 reg: s12 76 reg: s13 77 reg: s14 78 reg: s15 79 reg: s16 80 reg: s17 81 reg: s18 82 reg: s19 83 reg: s20 84 reg: s21 85 reg: s22 86 reg: s23 87 reg: s24 88 reg: s25 89 reg: s26 90 reg: s27 91 reg: s28 92 reg: s29 93 reg: s30 94 reg: s31 95 reg: f0 96 reg: f1 97 reg: f2 98 reg: f3 99 reg: f4 100 reg: f5 101 reg: f6 102 reg: f7 103 reg: wcgr0 104 reg: wcgr0 105 reg: wcgr0 106 reg: wcgr0 107 reg: wcgr0 108 reg: wcgr0 109 reg: wcgr0 110 reg: wcgr0 111 reg: wr0 112 reg: wr1 113 reg: wr2 114 reg: wr3 115 reg: wr4 116 reg: wr5 117 reg: wr6 118 reg: wr7 119 reg: wr8 120 reg: wr9 121 reg: wr10 122 reg: wr11 123 reg: wr12 124 reg: wr13 125 reg: wr14 126 reg: wr15 127 reg: spsr 128 reg: spsr_fiq 129 reg: spsr_irq 130 reg: spsr_abt 131 reg: spsr_und 132 reg: spsr_svc 133 reg: r8_usr 144 reg: r9_usr 145 reg: r10_usr 146 reg: r11_usr 147 reg: r12_usr 148 reg: r13_usr 149 reg: r14_usr 150 reg: r8_fiq 151 reg: r9_fiq 152 reg: r10_fiq 153 reg: r11_fiq 154 reg: r12_fiq 155 reg: r13_fiq 156 reg: r14_fiq 157 reg: r13_riq 158 reg: r14_riq 159 reg: r14_abt 160 reg: r13_abt 161 reg: r14_und 162 reg: r13_und 163 reg: r14_svc 164 reg: r13_svc 165 reg: wc0 192 reg: wc1 193 reg: wc2 192 reg: wc3 192 reg: wc4 192 reg: wc5 197 reg: wc6 198 reg: wc7 199 reg: d0 256 reg: d1 257 reg: d2 258 reg: d3 259 reg: d4 260 reg: d5 261 reg: d6 262 reg: d7 263 reg: d8 264 reg: d9 265 reg: d10 266 reg: d11 267 reg: d12 268 reg: d13 269 reg: d14 270 reg: d15 271 reg: d16 272 reg: d17 273 reg: d18 274 reg: d19 275 reg: d20 266 reg: d21 277 reg: d22 278 reg: d23 279 reg: d24 280 reg: d25 281 reg: d26 282 reg: d27 283 reg: d28 284 reg: d29 285 reg: d30 286 reg: d31 287 # End of abi definition. endabi: arm dwarfutils-20200114/dwarfdump/dwconf.c000066400000000000000000001224051361531463500175610ustar00rootroot00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Windows specific */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if defined(_WIN32) && defined(HAVE_WINDOWS_H) #include #define BOOLEAN_TYPEDEFED 1 #endif /* HAVE_WINDOWS_H */ #include "globals.h" #include "dwarf.h" #include "libdwarf.h" #include #include "dwconf.h" #include "makename.h" /* The nesting level is arbitrary, 2 should suffice. But at least this prevents an infinite loop. */ #define MAX_NEST_LEVEL 3 struct token_s { unsigned tk_len; char *tk_data; }; enum linetype_e { LT_ERROR, LT_COMMENT, LT_BLANK, LT_BEGINABI, LT_REG, LT_FRAME_INTERFACE, LT_CFA_REG, LT_INITIAL_REG_VALUE, LT_SAME_VAL_REG, LT_UNDEFINED_VAL_REG, LT_REG_TABLE_SIZE, LT_ADDRESS_SIZE, LT_INCLUDEABI, LT_ENDABI }; struct comtable_s { enum linetype_e type; char *name; size_t namelen; }; static int errcount = 0; /* Count errors found in this scan of the configuration file. */ static char name_begin_abi[] = "beginabi:"; static char name_reg[] = "reg:"; static char name_frame_interface[] = "frame_interface:"; static char name_cfa_reg[] = "cfa_reg:"; static char name_initial_reg_value[] = "initial_reg_value:"; static char name_same_val_reg[] = "same_val_reg:"; static char name_undefined_val_reg[] = "undefined_val_reg:"; static char name_reg_table_size[] = "reg_table_size:"; static char name_address_size[] = "address_size:"; static char name_includeabi[] = "includeabi:"; static char name_endabi[] = "endabi:"; /* The namelen field is filled in at runtime with the correct value. Filling in a fake '1' avoids a compiler warning. */ static struct comtable_s comtable[] = { {LT_BEGINABI, name_begin_abi,1}, {LT_REG, name_reg,1}, {LT_FRAME_INTERFACE, name_frame_interface,1}, {LT_CFA_REG, name_cfa_reg,1}, {LT_INITIAL_REG_VALUE, name_initial_reg_value,1}, {LT_SAME_VAL_REG, name_same_val_reg,1}, {LT_UNDEFINED_VAL_REG, name_undefined_val_reg,1}, {LT_REG_TABLE_SIZE, name_reg_table_size,1}, {LT_ADDRESS_SIZE, name_address_size,1}, {LT_INCLUDEABI, name_includeabi,1}, {LT_ENDABI, name_endabi,1}, }; struct conf_internal_s { unsigned long beginabi_lineno; unsigned long frame_interface_lineno; unsigned long initial_reg_value_lineno; unsigned long reg_table_size_lineno; unsigned long address_size_lineno; unsigned long same_val_reg_lineno; unsigned long undefined_val_reg_lineno; unsigned long cfa_reg_lineno; unsigned long regcount; struct dwconf_s * conf_out; const char * conf_name_used; char ** conf_defaults; }; static void init_conf_internal(struct conf_internal_s *s, struct dwconf_s * conf_out) { s->beginabi_lineno = 0; s->frame_interface_lineno = 0; s->initial_reg_value_lineno = 0; s->reg_table_size_lineno = 0; s->address_size_lineno = 0; s->same_val_reg_lineno = 0; s->undefined_val_reg_lineno = 0; s->cfa_reg_lineno = 0; s->cfa_reg_lineno = 0; s->conf_name_used = 0; s->conf_defaults = 0; s->regcount = 0; s->conf_out = conf_out; } static unsigned size_of_comtable = sizeof(comtable) / sizeof(comtable[0]); static FILE *find_a_file(const char *named_file, char **defaults, const char** name_used); static int find_abi_start(FILE * stream, const char *abi_name, long *offset, unsigned long *lineno_out); static int parse_abi(FILE * stream, const char *fname, const char *abiname, struct conf_internal_s *out, unsigned long lineno, unsigned nest_level); static char *get_token(char *cp, struct token_s *outtok); /* This finds a dwarfdump.conf file and then parses it. It updates conf_out as appropriate. This finds the first file (looking in a set of places) with that name. It then looks for the right ABI entry. If the first file it finds does not have that ABI entry it gives up. It would also be reasonable to search every 'dwarfdump.conf' it finds for the abi. But we stop at the first dwarfdump.conf we find. This is the internal call to get the conf data to implement a crude 'includeabi' feature. Returns 0 if no errors found, else returns > 0. */ static int find_conf_file_and_read_config_inner(const char *named_file, const char *named_abi, struct conf_internal_s *conf_internal, unsigned nest_level) { FILE *conf_stream = 0; const char *name_used = 0; long offset = 0; int res = FALSE; unsigned long lineno = 0; errcount = 0; conf_stream = find_a_file(named_file, conf_internal->conf_defaults, &name_used); if (!conf_stream) { ++errcount; printf("dwarfdump found no file %s!\n", named_file ? named_file : "readable for configuration. " "(add options -v -v to see what file names tried)\n"); return errcount; } if (glflags.verbose > 1) { printf("dwarfdump using configuration file %s\n", name_used); } conf_internal->conf_name_used = name_used; res = find_abi_start(conf_stream, named_abi, &offset, &lineno); if (errcount > 0 || res == FALSE) { ++errcount; fclose(conf_stream); printf("dwarfdump found no ABI %s in file %s.\n", named_abi, name_used); return errcount; } res = fseek(conf_stream, offset, SEEK_SET); if (res != 0) { ++errcount; fclose(conf_stream); printf("dwarfdump seek to %ld offset in %s failed!\n", offset, name_used); return errcount; } parse_abi(conf_stream, name_used, named_abi, conf_internal, lineno, nest_level); fclose(conf_stream); return errcount; } /* This is the external-facing call to get the conf data. */ int find_conf_file_and_read_config(const char *named_file, const char *named_abi, char **defaults, struct dwconf_s *conf_out) { int res = 0; struct conf_internal_s conf_internal; init_conf_file_data(conf_out); init_conf_internal(&conf_internal,conf_out); conf_internal.conf_defaults = defaults; res = find_conf_file_and_read_config_inner(named_file, named_abi, &conf_internal,0); return res; } /* Given path strings, attempt to make a canonical file name: that is, avoid superfluous '/' so that no '//' (or worse) is created in the output. The path components are to be separated so at least one '/' is to appear between the two 'input strings' when creating the output. */ #if defined(BUILD_FOR_TEST) || !defined(_WIN32) static char * canonical_append(char *target, unsigned int target_size, const char *first_string, const char *second_string) { size_t firstlen = strlen(first_string); /* +1 +1: Leave room for added "/" and final NUL, though that is overkill, as we drop a NUL byte too. */ if ((firstlen + strlen(second_string) + 1 + 1) >= target_size) { /* Not enough space. */ return NULL; } for (; *second_string == '/'; ++second_string) { } for (; firstlen > 0 && first_string[firstlen - 1] == '/'; --firstlen) { } target[0] = 0; if (firstlen > 0) { strncpy(target, first_string, firstlen); target[firstlen + 1] = 0; } target[firstlen] = '/'; firstlen++; target[firstlen] = 0; strcat(target, second_string); return target; } #endif /* defined(BUILD_FOR_TEST) || !defined(_WIN32) */ #ifdef BUILD_FOR_TEST #define CANBUF 25 struct canap_s { char *res_exp; char *first; char *second; } canap[] = { { "ab/c", "ab", "c"}, { "ab/c", "ab/", "c"}, { "ab/c", "ab", "/c"}, { "ab/c", "ab////", "/////c"}, { "ab/", "ab", ""}, { "ab/", "ab////", ""}, { "ab/", "ab////", ""}, { "/a", "", "a"}, { 0, "/abcdefgbijkl", "pqrstuvwxyzabcd"}, { 0, 0, 0} }; static void test_canonical_append(void) { /* Make buf big, this is test code, so be safe. */ char lbuf[1000]; unsigned i; unsigned failcount = 0; printf("Entry test_canonical_append\n"); for (i = 0;; ++i) { char *res = 0; if (canap[i].first == 0 && canap[i].second == 0) break; res = canonical_append(lbuf, CANBUF, canap[i].first, canap[i].second); if (res == 0) { if (canap[i].res_exp == 0) { /* GOOD */ printf("PASS %u\n", i); } else { ++failcount; printf("FAIL: entry %u wrong, expected %s, got NULL\n", i, canap[i].res_exp); } } else { if (canap[i].res_exp == 0) { ++failcount; printf("FAIL: entry %u wrong, got %s expected NULL\n", i, res); } else { if (strcmp(res, canap[i].res_exp) == 0) { printf("PASS %u\n", i); /* GOOD */ } else { ++failcount; printf("FAIL: entry %u wrong, expected %s got %s\n", i, canap[i].res_exp, res); } } } } printf("FAIL count %u\n", failcount); } #endif /* BUILD_FOR_TEST */ /* Try to find a file as named and open for read. We treat each name as a full name, we are not combining separate name and path components. This is an arbitrary choice... The defaults are listed in command_options.c in the array config_file_defaults[]. Since named_file comes from an esb_get_string, lname may be non-null but pointing to empty string to mean no-name. */ static FILE * find_a_file(const char *named_file, char **defaults, const char ** name_used) { FILE *fin = 0; const char *lname = named_file; const char *type = "r"; int i = 0; #ifdef BUILD_FOR_TEST test_canonical_append(); #endif /* BUILD_FOR_TEST */ if (lname && (strlen(lname) > 0)) { /* Name given, just assume it is fully correct, try no other. */ if (glflags.verbose > 1) { printf("dwarfdump looking for configuration as %s\n", lname); } fin = fopen(lname, type); if (fin) { *name_used = lname; return fin; } return 0; } /* No name given, find a default, if we can. */ for (i = 0; defaults[i]; ++i) { lname = defaults[i]; #ifdef _WIN32 /* Open the configuration file, located in the directory where the tool is loaded from */ { static char szPath[MAX_PATH]; if (GetModuleFileName(NULL,szPath,MAX_PATH)) { char *pDir = strrchr(szPath,'/'); size_t len = 0; if (!pDir) { pDir = strrchr(szPath,'\\'); if (!pDir) { /* No file was found */ return 0; } } /* Add the configuration name to the pathname */ ++pDir; len = pDir - szPath; safe_strcpy(pDir,sizeof(szPath)-len,"dwarfdump.conf",14); lname = szPath; } } #else /* non-Win */ if (strncmp(lname, "HOME/", 5) == 0) { /* arbitrary size */ char buf[2000]; char *homedir = getenv("HOME"); if (homedir) { char *cp = canonical_append(buf, sizeof(buf), homedir, lname + 5); if (!cp) { /* OOps, ignore this one. */ continue; } lname = makename(buf); } } #endif /* _WIN32 */ if (glflags.verbose > 1) { printf("dwarfdump looking for configuration as %s\n", lname); } fin = fopen(lname, type); if (fin) { *name_used = lname; return fin; } } return 0; } /* Start at a token begin, see how long it is, return length. */ static unsigned find_token_len(char *cp) { unsigned len = 0; for (; *cp; ++cp) { if (isspace(*cp)) { return len; } if (*cp == '#') { return len; /* begins comment */ } ++len; } return len; } /* Skip past all whitespace: the only code that even knows what whitespace is. */ static char * skipwhite(char *cp) { for (; *cp; ++cp) { if (!isspace(*cp)) { return cp; } } return cp; } /* Return TRUE if ok. FALSE if find more tokens. Emit error message if error. */ static int ensure_has_no_more_tokens(char *cp, const char *fname, unsigned long lineno) { struct token_s tok; get_token(cp, &tok); if (tok.tk_len > 0) { printf("dwarfdump.conf error: " "extra characters after command operands, found " "\"%s\" in %s line %lu\n", tok.tk_data, fname, lineno); ++errcount; return FALSE; } return TRUE; } /* There may be many beginabi: lines in a dwarfdump.conf file, find the one we want and return its file offset. */ static int find_abi_start(FILE * stream, const char *abi_name, long *offset, unsigned long *lineno_out) { char buf[100]; unsigned long lineno = 0; for (; !feof(stream);) { struct token_s tok; char *line = 0; long loffset = ftell(stream); line = fgets(buf, sizeof(buf), stream); ++lineno; if (!line) { ++errcount; return FALSE; } line = get_token(buf, &tok); if (strcmp(tok.tk_data, name_begin_abi) != 0) { continue; } get_token(line, &tok); if (strcmp(tok.tk_data, abi_name) != 0) { continue; } *offset = loffset; *lineno_out = lineno; return TRUE; } ++errcount; return FALSE; } static char *tempstr = 0; static unsigned tempstr_len = 0; /* Use a global buffer (tempstr) to turn a non-delimited input char array into a NUL-terminated C string (with the help of makename() to get a permanent address for the result ing string). */ static char * build_string(unsigned tlen, char *cp) { if (tlen >= tempstr_len) { free(tempstr); tempstr = malloc(tlen + 100); } strncpy(tempstr, cp, tlen); tempstr[tlen] = 0; return makename(tempstr); } /* The tokenizer for our simple parser. */ static char * get_token(char *cp, struct token_s *outtok) { char *lcp = skipwhite(cp); unsigned tlen = find_token_len(lcp); outtok->tk_len = tlen; if (tlen > 0) { outtok->tk_data = build_string(tlen, lcp); } else { outtok->tk_data = ""; } return lcp + tlen; } /* We can't get all the field set up statically very easily, so we get the command string length set here. */ static void finish_comtable_setup(void) { unsigned i; for (i = 0; i < size_of_comtable; ++i) { comtable[i].namelen = strlen(comtable[i].name); } } /* Given a line of the table, determine if it is a command or not, and if a command, which one is it. Return LT_ERROR if it's not recognized. */ static enum linetype_e which_command(char *cp, struct comtable_s **tableentry) { unsigned i = 0; struct token_s tok; if (*cp == '#') return LT_COMMENT; if (!*cp) return LT_BLANK; get_token(cp, &tok); for (i = 0; i < size_of_comtable; ++i) { if (tok.tk_len == comtable[i].namelen && strcmp(comtable[i].name, tok.tk_data) == 0) { *tableentry = &comtable[i]; return comtable[i].type; } } return LT_ERROR; } /* We are promised it's an abiname: command find the name on the line. */ static int parsebeginabi(char *cp, const char *fname, const char *abiname, unsigned long lineno, struct comtable_s *comtab) { size_t clen = comtab->namelen; size_t abinamelen = strlen(abiname); struct token_s tok; cp = cp + clen + 1; cp = skipwhite(cp); get_token(cp, &tok); if (tok.tk_len != abinamelen || strncmp(cp, abiname, abinamelen) != 0) { printf("dwarfdump internal error: " "mismatch %s with %s %s line %lu\n", cp, tok.tk_data, fname, lineno); ++errcount; return FALSE; } ensure_has_no_more_tokens(cp + tok.tk_len, fname, lineno); return TRUE; } /* This expands register names as required, but does not ensure no names duplicated. */ #define CONF_TABLE_OVERSIZE 100 static void add_to_reg_table(struct dwconf_s *conf, char *rname, unsigned long rval, const char *fname, unsigned long lineno) { if (conf->cf_regs_malloced == 0) { conf->cf_regs = 0; conf->cf_named_regs_table_size = 0; } if (rval >= conf->cf_named_regs_table_size) { char **newregs = 0; unsigned long newtablen = rval + CONF_TABLE_OVERSIZE; unsigned long newtabsize = newtablen * sizeof(char *); unsigned long oldtabsize = conf->cf_named_regs_table_size * sizeof(char *); newregs = realloc(conf->cf_regs, newtabsize); if (!newregs) { printf("dwarfdump: unable to malloc table %lu bytes. " " %s line %lu\n", newtabsize, fname, lineno); exit(1); } /* Zero out the new entries. */ memset((char *) newregs + (oldtabsize), 0, (newtabsize - oldtabsize)); conf->cf_named_regs_table_size = (unsigned long) newtablen; conf->cf_regs = newregs; conf->cf_regs_malloced = 1; } conf->cf_regs[rval] = rname; return; } /* Our input is supposed to be a number. Determine the value (and return it) or generate an error message. */ static int make_a_number(char *cmd, const char *filename, unsigned long lineno, struct token_s *tok, unsigned long *val_out) { char *endnum = 0; unsigned long val = 0; val = strtoul(tok->tk_data, &endnum, 0); if (val == 0 && endnum == (tok->tk_data)) { printf("dwarfdump.conf error: " "%s missing register number (\"%s\" not valid) %s line %lu\n", cmd, tok->tk_data, filename, lineno); ++errcount; return FALSE; } if (endnum != (tok->tk_data + tok->tk_len)) { printf("dwarfdump.conf error: " "%s Missing register number (\"%s\" not valid) %s line %lu\n", cmd, tok->tk_data, filename, lineno); ++errcount; return FALSE; } *val_out = val; return TRUE; } /* We are guaranteed it's a reg: command, so parse that command and record the interesting data. */ static int parsereg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s regnum; struct token_s tokreg; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tokreg); cp = get_token(cp, ®num); if (tokreg.tk_len == 0) { printf("dwarfdump.conf error: " "reg: missing register name %s line %lu", fname, lineno); ++errcount; return FALSE; } if (regnum.tk_len == 0) { printf("dwarfdump.conf error: " "reg: missing register number %s line %lu", fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, ®num, &val); if (!ok) { ++errcount; return FALSE; } add_to_reg_table(conf->conf_out, tokreg.tk_data, val, fname, lineno); res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's an frame_interface: command. Parse it and record the value data. */ static int parseframe_interface(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing interface number %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } if (val != 2 && val != 3) { printf("dwarfdump.conf error: " "%s only interface numbers 2 or 3 are allowed, " " not %lu. %s line %lu", comtab->name, val, fname, lineno); ++errcount; return FALSE; } conf->conf_out->cf_interface_number = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's a cfa_reg: command. Parse it and record the important data. */ static int parsecfa_reg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing cfa_reg number %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_cfa_reg = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's an initial_reg_value: command, parse it and put the reg value where it will be remembered. */ static int parseinitial_reg_value(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing initial reg value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_initial_rule_value = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } static int parsesame_val_reg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing same_reg value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_same_val = val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } static int parseundefined_val_reg(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing undefined_reg value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_undefined_val = (int) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's a table size command, parse it and record the table size. */ static int parsereg_table_size(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing reg table size value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_table_entry_count = (unsigned long) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's a table size command, parse it and record the table size. */ static int parseaddress_size(char *cp, const char *fname, unsigned long lineno, struct conf_internal_s *conf, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; unsigned long val = 0; int ok = FALSE; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); if (tok.tk_len == 0) { printf("dwarfdump.conf error: " "%s missing address size value %s line %lu", comtab->name, fname, lineno); ++errcount; return FALSE; } ok = make_a_number(comtab->name, fname, lineno, &tok, &val); if (!ok) { ++errcount; return FALSE; } conf->conf_out->cf_address_size = (unsigned long) val; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* We are guaranteed it's an endabi: command, parse it and check we have the right abi. */ static int parseendabi(char *cp, const char *fname, const char *abiname, unsigned long lineno, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; int res = 0; cp = cp + clen + 1; cp = get_token(cp, &tok); if (strcmp(abiname, tok.tk_data) != 0) { printf("%s error: " "mismatch abi name %s (here) vs. %s (beginabi:) %s line %lu\n", comtab->name, tok.tk_data, abiname, fname, lineno); ++errcount; return FALSE; } res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } static int parseincludeabi(char *cp, const char *fname, unsigned long lineno, char **abiname_out, struct comtable_s *comtab) { size_t clen = comtab->namelen; struct token_s tok; char *name = 0; int res = FALSE; cp = cp + clen + 1; cp = get_token(cp, &tok); name = makename(tok.tk_data); *abiname_out = name; res = ensure_has_no_more_tokens(cp, fname, lineno); return res; } /* Return TRUE if we succeeded and filed in *out. Return FALSE if we failed (and fill in nothing). beginabi: reg: frame_interface: cfa_reg: initial_reg_value: reg_table_size: endabi: We are positioned at the start of a beginabi: line when called. */ static int parse_abi(FILE * stream, const char *fname, const char *abiname, struct conf_internal_s *conf_internal, unsigned long lineno, unsigned int nest_level) { struct dwconf_s *localconf = conf_internal->conf_out; char buf[1000]; int comtype = 0; static int first_time_done = 0; struct comtable_s *comtabp = 0; if (nest_level > MAX_NEST_LEVEL) { ++errcount; printf("dwarfdump.conf: includeabi nest too deep in %s at line %lu\n", fname, lineno); return FALSE; } if (first_time_done == 0) { finish_comtable_setup(); first_time_done = 1; } for (; !feof(stream);) { char *line = 0; /* long loffset = ftell(stream); */ line = fgets(buf, sizeof(buf), stream); if (!line) { ++errcount; printf ("dwarfdump: end of file or error before endabi: in %s, line %lu\n", fname, lineno); return FALSE; } ++lineno; line = skipwhite(line); comtype = which_command(line, &comtabp); switch (comtype) { case LT_ERROR: ++errcount; printf ("dwarfdump: Unknown text in %s is \"%s\" at line %lu\n", fname, line, lineno); break; case LT_COMMENT: break; case LT_BLANK: break; case LT_BEGINABI: if (conf_internal->beginabi_lineno > 0) { ++errcount; printf ("dwarfdump: Encountered beginabi: when not expected. " "%s line %lu previous beginabi line %lu\n", fname, lineno, conf_internal->beginabi_lineno); } conf_internal->beginabi_lineno = lineno; parsebeginabi(line, fname, abiname, lineno, comtabp); break; case LT_REG: parsereg(line, fname, lineno, conf_internal, comtabp); conf_internal->regcount++; break; case LT_FRAME_INTERFACE: if (conf_internal->frame_interface_lineno > 0) { ++errcount; printf ("dwarfdump: Encountered duplicate frame_interface: " "%s line %lu previous frame_interface: line %lu\n", fname, lineno, conf_internal->frame_interface_lineno); } conf_internal->frame_interface_lineno = lineno; parseframe_interface(line, fname, lineno, conf_internal, comtabp); break; case LT_CFA_REG: if (conf_internal->cfa_reg_lineno > 0) { printf("dwarfdump: Encountered duplicate cfa_reg: " "%s line %lu previous cfa_reg line %lu\n", fname, lineno, conf_internal->cfa_reg_lineno); ++errcount; } conf_internal->cfa_reg_lineno = lineno; parsecfa_reg(line, fname, lineno, conf_internal, comtabp); break; case LT_INITIAL_REG_VALUE: if (conf_internal->initial_reg_value_lineno > 0) { printf ("dwarfdump: Encountered duplicate initial_reg_value: " "%s line %lu previous initial_reg_value: line %lu\n", fname, lineno, conf_internal->initial_reg_value_lineno); ++errcount; } conf_internal->initial_reg_value_lineno = lineno; parseinitial_reg_value(line, fname, lineno, conf_internal, comtabp); break; case LT_SAME_VAL_REG: if (conf_internal->same_val_reg_lineno > 0) { ++errcount; printf ("dwarfdump: Encountered duplicate same_val_reg: " "%s line %lu previous initial_reg_value: line %lu\n", fname, lineno, conf_internal->initial_reg_value_lineno); } conf_internal->same_val_reg_lineno = lineno; parsesame_val_reg(line, fname, lineno, conf_internal, comtabp); break; case LT_UNDEFINED_VAL_REG: if (conf_internal->undefined_val_reg_lineno > 0) { ++errcount; printf ("dwarfdump: Encountered duplicate undefined_val_reg: " "%s line %lu previous initial_reg_value: line %lu\n", fname, lineno, conf_internal->initial_reg_value_lineno); } conf_internal->undefined_val_reg_lineno = lineno; parseundefined_val_reg(line, fname, lineno, conf_internal, comtabp); break; case LT_REG_TABLE_SIZE: if (conf_internal->reg_table_size_lineno > 0) { printf("dwarfdump: duplicate reg_table_size: " "%s line %lu previous reg_table_size: line %lu\n", fname, lineno, conf_internal->reg_table_size_lineno); ++errcount; } conf_internal->reg_table_size_lineno = lineno; parsereg_table_size(line, fname, lineno, conf_internal, comtabp); break; case LT_ENDABI: parseendabi(line, fname, abiname, lineno, comtabp); if (conf_internal->regcount > localconf->cf_table_entry_count) { printf("dwarfdump: more registers named than " " in %s ( %lu named vs %s %lu) %s line %lu\n", abiname, (unsigned long) conf_internal->regcount, name_reg_table_size, (unsigned long) localconf->cf_table_entry_count, fname, (unsigned long) lineno); ++errcount; } return TRUE; case LT_ADDRESS_SIZE: if (conf_internal->address_size_lineno > 0) { printf("dwarfdump: duplicate address_size: " "%s line %lu previous address_size: line %lu\n", fname, lineno, conf_internal->address_size_lineno); ++errcount; } conf_internal->address_size_lineno = lineno; parseaddress_size(line, fname, lineno, conf_internal, comtabp); break; case LT_INCLUDEABI: { char *abiname_inner = 0; unsigned long abilno = conf_internal->beginabi_lineno; int ires = 0; ires = parseincludeabi(line,fname,lineno, &abiname_inner,comtabp); if (ires == FALSE) { return FALSE; } /* For the nested abi read, the abi line number must be set as if not-yet-read, and then restored. */ conf_internal->beginabi_lineno = 0; find_conf_file_and_read_config_inner( conf_internal->conf_name_used, abiname_inner, conf_internal,nest_level+1); conf_internal->beginabi_lineno = abilno; } break; default: printf ("dwarfdump internal error, impossible line type %d %s %lu \n", (int) comtype, fname, lineno); exit(1); } } ++errcount; printf("End of file, no endabi: found. %s, line %lu\n", fname, lineno); return FALSE; } /* MIPS/IRIX frame register names. For alternate name sets, use dwarfdump.conf or revise dwarf.h and libdwarf.h and this table. */ static char *regnames[] = { "cfa", "r1/at", "r2/v0", "r3/v1", "r4/a0", "r5/a1", "r6/a2", "r7/a3", "r8/t0", "r9/t1", "r10/t2", "r11/t3", "r12/t4", "r13/t5", "r14/t6", "r15/t7", "r16/s0", "r17/s1", "r18/s2", "r19/s3", "r20/s4", "r21/s5", "r22/s6", "r23/s7", "r24/t8", "r25/t9", "r26/k0", "r27/k1", "r28/gp", "r29/sp", "r30/s8", "r31", "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", "ra", "slk", }; /* Naming a few registers makes printing these just a little bit faster. */ static char *genericregnames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20" }; /* This is a simple generic set of registers. The table entry count is pretty arbitrary. */ void init_conf_file_data(struct dwconf_s *config_file_data) { unsigned generic_table_count; config_file_data->cf_abi_name = ""; config_file_data->cf_config_file_path = ""; config_file_data->cf_interface_number = 3; config_file_data->cf_table_entry_count = 100; config_file_data->cf_initial_rule_value = DW_FRAME_UNDEFINED_VAL; config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL3; config_file_data->cf_address_size = 0; config_file_data->cf_same_val = DW_FRAME_SAME_VAL; config_file_data->cf_undefined_val = DW_FRAME_UNDEFINED_VAL; config_file_data->cf_regs = genericregnames; generic_table_count = sizeof(genericregnames) / sizeof(genericregnames[0]); config_file_data->cf_named_regs_table_size = generic_table_count; config_file_data->cf_regs_malloced = 0; } /* These defaults match MIPS/IRIX ABI defaults, but this function is not actually used. For a 'generic' ABI, see -R or init_conf_file_data(). To really get the old MIPS, use '-x abi=mips'. For other ABIs, see -x abi= to configure dwarfdump (and libdwarf) frame data reporting at runtime. */ void init_mips_conf_file_data(struct dwconf_s *config_file_data) { unsigned long base_table_count = sizeof(regnames) / sizeof(regnames[0]); memset(config_file_data, 0, sizeof(*config_file_data)); /* Interface 2 is deprecated, but for testing purposes is acceptable. */ config_file_data->cf_interface_number = 2; config_file_data->cf_table_entry_count = DW_REG_TABLE_SIZE; config_file_data->cf_initial_rule_value = DW_FRAME_REG_INITIAL_VALUE; config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL; config_file_data->cf_address_size = 0; config_file_data->cf_same_val = DW_FRAME_SAME_VAL; config_file_data->cf_undefined_val = DW_FRAME_UNDEFINED_VAL; config_file_data->cf_regs = regnames; config_file_data->cf_named_regs_table_size = base_table_count; config_file_data->cf_regs_malloced = 0; if (config_file_data->cf_table_entry_count != base_table_count) { printf("dwarfdump: improper base table initization, " "header files wrong: " "DW_REG_TABLE_SIZE %u != string table size %lu\n", (unsigned) DW_REG_TABLE_SIZE, (unsigned long) base_table_count); exit(1); } return; } /* A 'generic' ABI. For up to 1200 registers. Perhaps cf_initial_rule_value should be d UNDEFINED VALUE (1034) instead, but for the purposes of getting the dwarfdump output correct either will work. */ void init_generic_config_1200_regs(struct dwconf_s *config_file_data) { unsigned long generic_table_count = sizeof(genericregnames) / sizeof(genericregnames[0]); config_file_data->cf_interface_number = 3; config_file_data->cf_table_entry_count = 1200; /* There is no defined name for cf_initial_rule_value, cf_same_val, or cf_undefined_val in libdwarf.h, these must just be high enough to be higher than any real register number. DW_FRAME_CFA_COL3 must also be higher than any real register number. */ config_file_data->cf_initial_rule_value = 1235; /* SAME VALUE */ config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL3; config_file_data->cf_address_size = 0; config_file_data->cf_same_val = 1235; config_file_data->cf_undefined_val = 1234; config_file_data->cf_regs = genericregnames; config_file_data->cf_named_regs_table_size = generic_table_count; config_file_data->cf_regs_malloced = 0; } /* Print the 'right' string for the register we are given. Deal sensibly with the special regs as well as numbers we know and those we have not been told about. We are not allowing negative register numbers. */ void print_reg_from_config_data(Dwarf_Unsigned reg, struct dwconf_s *config_data) { char *name = 0; if (reg == config_data->cf_cfa_reg) { fputs("cfa",stdout); return; } if (reg == config_data->cf_undefined_val) { fputs("u",stdout); return; } if (reg == config_data->cf_same_val) { fputs("s",stdout); return; } if (config_data->cf_regs == 0 || reg >= config_data->cf_named_regs_table_size) { printf("r%" DW_PR_DUu "",reg); return; } name = config_data->cf_regs[reg]; if (!name) { /* Can happen, the reg names table can be sparse. */ printf("r%" DW_PR_DUu "", reg); return; } fputs(name,stdout); return; } dwarfutils-20200114/dwarfdump/dwconf.h000066400000000000000000000105411361531463500175630ustar00rootroot00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWCONFIG_H #define DWCONFIG_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Declarations helping configure the frame reader. We are not allowing negative register numbers. Which could be allowed if necessary with a little work. */ struct dwconf_s { char *cf_config_file_path; char *cf_abi_name; /* 2 for old, 3 for frame interface 3. 2 means use the old mips-abi-oriented frame interface. 3 means use the new DWARF3-capable and configureable-abi interface. Now, anyone who revises dwarf.h and libdwarf.h to match their abi-of-interest will still be able to use cf_interface_number 2 as before. But most folks don't update those header files and instead of making *them* configurable we make dwarfdump (and libdwarf) configurable sufficiently to print frame information sensibly. */ int cf_interface_number; /* The number of table rules , aka columns. For MIPS/IRIX is 66. */ unsigned long cf_table_entry_count; /* Array of cf_table_entry_count reg names. Names not filled in from dwarfdump.conf have NULL (0) pointer value. cf_named_regs_table_size must match size of cf_regs array. Set cf_regs_malloced 1 if table was malloced. Set 0 if static. */ char **cf_regs; unsigned long cf_named_regs_table_size; unsigned cf_regs_malloced; /* The 'default initial value' when intializing a table. for MIPS is DW_FRAME_SAME_VAL(1035). For other ISA/ABIs may be DW_FRAME_UNDEFINED_VAL(1034). */ unsigned cf_initial_rule_value; unsigned cf_same_val; unsigned cf_undefined_val; /* The number of the cfa 'register'. For cf_interface_number 2 of MIPS this is 0. For other architectures (and anytime using cf_interface_number 3) this should be outside the table, a special value such as 1436, not a table column at all). */ unsigned cf_cfa_reg; /* If non-zero it is the number of bytes in an address for the frame data. Normally it will be zero because there are usually other sources for the correct address size. However, with DWARF2 frame data there is no explicit address size in the frame data and the object file might not have other .debug_ sections to work with. If zero, no address size was supplied, and that is normal and the already-set (or defaulted) address size is to be used. Only an exceptional frame configure will specify address size here. This won't work at all if the object needing this setting has different address size in different CUs. */ unsigned cf_address_size; }; /* Returns DW_DLV_OK if works. DW_DLV_ERROR if cannot do what is asked. */ int find_conf_file_and_read_config(const char *named_file, const char *named_abi, char **defaults, struct dwconf_s *conf_out); void init_conf_file_data(struct dwconf_s *config_file_data); void init_mips_conf_file_data(struct dwconf_s *config_file_data); void print_reg_from_config_data(Dwarf_Unsigned reg, struct dwconf_s *config_data); void init_generic_config_1200_regs(struct dwconf_s *conf); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWCONFIG_H */ dwarfutils-20200114/dwarfdump/dwconf_using_functions.h000066400000000000000000000030171361531463500230600ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012-2018 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWCONF_USING_FUNCTIONS_H #define DWCONF_USING_FUNCTIONS_H #ifdef __cplusplus extern "C" { #endif void print_frames (Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame,struct dwconf_s *); void printreg(Dwarf_Unsigned reg,struct dwconf_s *config_data); #ifdef __cplusplus } #endif #endif /* DWCONF_USING_FUNCTIONS_H */ dwarfutils-20200114/dwarfdump/dwgetopt.c000066400000000000000000000262201361531463500201340ustar00rootroot00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). renamed to make it clear this is a private version. Oct 17 2017: Created dwgetopt_long(). See dwgetopt.h */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* This does not presently handle the option string leading + or leading - features. Such are not used by by libdwarfdump. Nor does it understand the GNU Env var POSIXLY_CORRECT . It does know of the leading ":" in the option string. See BADCH below. */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include "dwgetopt.h" #define STRIP_OFF_CONSTNESS(a) ((void *)(size_t)(const void *)(a)) int dwopterr = 1, /* if error message should be printed */ dwoptind = 1, /* index into parent argv vector */ dwoptopt, /* character checked for validity */ dwoptreset; /* reset getopt */ char *dwoptarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" #define TRUE 1 #define FALSE 0 #if 0 /* FOR DEBUGGING ONLY */ /* Use for testing dwgetopt only. Not a standard function. */ void dwgetoptresetfortestingonly(void) { dwopterr = 1; dwoptind = 1; dwoptopt = 0; dwoptreset = 0; dwoptarg = 0; } #endif /* FOR DEBUGGING ONLY */ static const char *place = EMSG;/* option letter processing */ /* Post Condition: if return FALSE then *argerr is set false. */ static int dwoptnamematches( const struct dwoption *dwlopt, const char *iplace, const char **argloc, int *argerr) { const char *eq = 0; unsigned namelen = 0; unsigned arglen = 0; int d = 0; for(eq = iplace; *eq; ++eq) { if (*eq != '=') { continue; } /* Found =, arg should follow */ namelen = (eq - iplace); if (namelen != (unsigned)strlen(dwlopt->name)) { return FALSE; } eq++; arglen = strlen(eq); break; } if (namelen) { d = strncmp(iplace,dwlopt->name,namelen); if (d) { return FALSE; } if (dwlopt->has_arg == 0) { *argerr = TRUE; return TRUE; } if (arglen) { /* Discarding const, avoiding warning. Data is in user space, so this is ok. */ dwoptarg = (char *)eq; *argloc = (const char *)eq; } else { /* Has arg = but arg is empty. */ dwoptarg = 0; } return TRUE; } else { d = strcmp(iplace,dwlopt->name); if (d) { return FALSE; } if (dwlopt->has_arg == 1) { *argerr = TRUE; return TRUE; } dwoptarg = 0; return TRUE; } } /* dwgetopt_long A reimplemenation of a portion of the getopt(3) GNU/Linux getopt_long(). See dwgetopt.h for more details. */ int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex) { char *lplace = 0; if (dwoptreset) { /* Not really supported. */ place = EMSG; return (-1); } if (*place) { int v = dwgetopt(nargc,nargv,ostr); return v; } /* Use local lplace in case we need to call getopt() just below. */ lplace = nargv[dwoptind]; if (dwoptind >= nargc || *lplace++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } if (*lplace != '-') { /* Notice place not disturbed. */ int v = dwgetopt(nargc,nargv,ostr); return v; } /* Starts with two dashes. Now we set the global place */ place = lplace+1; if (!*place) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } /* We think this is a longopt. */ { int lo_num = 0; for(;;lo_num++) { const struct dwoption *dwlopt = longopts +lo_num; const char * argloc = 0; int argerr = 0; int resmatch = 0; if (!dwlopt->name) { dwoptind++; (void)fprintf(stderr, "%s: invalid long option '--%s'\n", nargv[0]?nargv[0]:"", place); /* Leave longindex unchanged. */ place = EMSG; return (BADCH); } resmatch= dwoptnamematches(dwlopt,place, &argloc,&argerr); if (resmatch) { dwoptarg = 0; if (argloc) { /* Must drop const here. Ugh. */ dwoptarg = (char *)argloc; } } if (argerr) { /* resmatch == TRUE arg option missing if required, present but not allowed. GNU Behavior not well documented. Had to experiment. if argument-not-allowed, and we have one, do ??? If argument-required, then here GNU would take the next argv as the argument. we are not currently doing that. */ /**longindex = lo_num; */ if (dwlopt->has_arg) { /* Missing required arg, this does not match GNU getopt_long behavior of taking next argv as the arg value. and thus making getopt_long succeed. */ (void)fprintf(stderr, "%s: missing required long option argument '--%s'\n", nargv[0]?nargv[0]:"", place); } else { /* has arg but should not */ (void)fprintf(stderr, "%s: option '--%s' does not allow an argument\n", nargv[0]?nargv[0]:"", dwlopt->name); } dwoptind++; place = EMSG; return (BADCH); } if (resmatch) { *longindex = lo_num; place = EMSG; dwoptind++; return dwlopt->val; } } /* Can never get here */ place = EMSG; dwoptind++; return (-1); } } /* * getopt -- * Parse argc/argv argument vector. * a: means * -afoo * -a foo * and 'foo' is returned in dwoptarg * b:: means * -b * and dwoptarg is null * -bother * and dwoptarg is 'other' */ int dwgetopt(int nargc, char * const nargv[], const char *ostr) { char *oli; /* option letter list index */ if (dwoptreset || *place == 0) { /* update scanning pointer */ dwoptreset = 0; place = nargv[dwoptind]; if (dwoptind >= nargc || *place++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } dwoptopt = *place++; if (dwoptopt == '-' && *place == 0) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } if (dwoptopt == 0) { /* Solitary '-', treat as a '-' option if the program (eg su) is looking for it. */ place = EMSG; if (strchr(ostr, '-') == NULL) { return -1; } dwoptopt = '-'; } } else { dwoptopt = *place++; } /* See if option letter is one the caller wanted... */ if (dwoptopt == ':' || (oli = strchr(ostr, dwoptopt)) == NULL) { if (*place == 0) { ++dwoptind; } if (dwopterr && *ostr != ':') { (void)fprintf(stderr, "%s: invalid option -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } /* Does this option need an argument? */ if (oli[1] != ':') { /* don't need argument */ dwoptarg = NULL; if (*place == 0) { ++dwoptind; } } else { int reqnextarg = 1; if (oli[1] && (oli[2] == ':')) { /* Pair of :: means special treatment of dwoptarg */ reqnextarg = 0; } /* Option-argument is either the rest of this argument or the entire next argument. */ if (*place ) { /* Whether : or :: */ dwoptarg = STRIP_OFF_CONSTNESS(place); } else if (reqnextarg) { /* ! *place */ if (nargc > (++dwoptind)) { dwoptarg = nargv[dwoptind]; } else { place=EMSG; /* Next arg required, but is missing */ if (*ostr == ':') { /* Leading : in ostr calls for BADARG return. */ return (BADARG); } if (dwopterr) { (void)fprintf(stderr, "%s: option requires an argument. -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } } else { /* ! *place */ /* The key part of :: treatment. */ dwoptarg = NULL; } place = EMSG; ++dwoptind; } return (dwoptopt); /* return option letter */ } dwarfutils-20200114/dwarfdump/dwgetopt.h000066400000000000000000000062671361531463500201520ustar00rootroot00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwopterr; extern int dwoptind; extern int dwoptopt; extern int dwoptreset; extern char *dwoptarg; int dwgetopt(int nargc, char * const nargv[], const char *ostr); /* As of October 2017 it seems adviseable to allow long option names. So based on a reading of 'man 3 getopt' we reimplement a portion of GNU getopt_long(). It's a wonderfully sensible design and all the credit should go to the original designers. We are not implementing all the features of GNU/Linux getopt_long(), just the features we wish to use. Specifically, we require val be 0 and flag be NULL and ignore those fields. We do not implement GNU digit_optind at all. Within these restrictions the interface behaves the same as GNU getopt_long() (or so it appears from the getopt documentation: release 4.04 of the Linux man-pages project, GETOPT(3), http://www.kernel.org/doc/man-pages/). */ struct dwoption { const char *name; int has_arg; int *flag; int val; }; #define dwno_argument 0 #define dwrequired_argument 1 #define dwoptional_argument 2 int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex); #ifdef __cplusplus } #endif /* __cplusplus */ dwarfutils-20200114/dwarfdump/esb.c000066400000000000000000000612351361531463500170550ustar00rootroot00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2013-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* esb.c extensible string buffer. A simple means (vaguely like a C++ class) that enables safely saving strings of arbitrary length built up in small pieces. We really do allow only C strings here. NUL bytes in a string result in adding only up to the NUL (and in the case of certain interfaces here a warning to stderr). The functions assume that pointer arguments of all kinds are not NULL. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #include "esb.h" #define TRUE 1 /* INITIAL_ALLOC value takes no account of space for a trailing NUL, the NUL is accounted for in init_esb_string and in later tests against esb_allocated_size. */ #ifdef SELFTEST #define INITIAL_ALLOC 1 /* SELFTEST */ #define MALLOC_COUNT 1 #else /* There is nothing magic about this size. It is just big enough to avoid most resizing. */ #define INITIAL_ALLOC 100 #endif /* Allow for final NUL */ static size_t alloc_size = INITIAL_ALLOC; /* NULL device used when printing formatted strings */ static FILE *null_device_handle = 0; #ifdef _WIN32 #define NULL_DEVICE_NAME "NUL" #else #define NULL_DEVICE_NAME "/dev/null" #endif /* _WIN32 */ #ifdef MALLOC_COUNT long malloc_count = 0; long malloc_size = 0; #endif /* m must be a string, like "ESBERR..." for this to work */ #define ESBERR(m) esb_appendn_internal(data,m,sizeof(m)-1) FILE *esb_open_null_device(void) { if (!null_device_handle) { null_device_handle = fopen(NULL_DEVICE_NAME,"w"); } return null_device_handle; } /* Close the null device used during formatting printing */ void esb_close_null_device(void) { if (null_device_handle) { fclose(null_device_handle); null_device_handle = 0; } } /* min_len is overall space wanted for initial alloc. ASSERT: esb_allocated_size == 0 */ static void init_esb_string(struct esb_s *data, size_t min_len) { char* d; if (data->esb_allocated_size > 0) { return; } /* Only esb_constructor applied so far. Now Allow for string space. */ if (min_len < alloc_size) { min_len = alloc_size; } else { min_len++ ; /* Allow for NUL at end */ } d = malloc(min_len); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += min_len; #endif if (!d) { fprintf(stderr, "dwarfdump is out of memory allocating %lu bytes\n", (unsigned long) min_len); exit(5); } data->esb_string = d; data->esb_allocated_size = min_len; data->esb_string[0] = 0; data->esb_used_bytes = 0; } /* Make more room. Leaving contents unchanged, effectively. The NUL byte at end has room and this preserves that room. */ static void esb_allocate_more(struct esb_s *data, size_t len) { size_t new_size = 0; char* newd = 0; if (data->esb_rigid) { return; } if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } new_size = data->esb_allocated_size + len; if (new_size < alloc_size) { new_size = alloc_size; } if (data->esb_fixed) { newd = malloc(new_size); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += len; #endif if (newd) { memcpy(newd,data->esb_string,data->esb_used_bytes+1); } } else { newd = realloc(data->esb_string, new_size); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += len; #endif } if (!newd) { fprintf(stderr, "dwarfdump is out of memory allocating " "%lu bytes\n", (unsigned long) new_size); exit(5); } /* If the area was reallocated by realloc() the earlier space was free()d by realloc(). */ data->esb_string = newd; data->esb_allocated_size = new_size; data->esb_fixed = 0; } /* Ensure that the total buffer length is large enough that at least minlen bytes are available, unused, in the allocation. */ void esb_force_allocation(struct esb_s *data, size_t minlen) { size_t target_len = 0; if (data->esb_rigid) { return; } if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } target_len = data->esb_used_bytes + minlen; if (data->esb_allocated_size < target_len) { size_t needed = target_len - data->esb_allocated_size; esb_allocate_more(data,needed); } } /* The 'len' is believed. Do not pass in strings < len bytes long. For strlen(in_string) > len bytes we take the initial len bytes. len does not include the trailing NUL. */ static void esb_appendn_internal(struct esb_s *data, const char * in_string, size_t len) { size_t remaining = 0; size_t needed = len; if (data->esb_allocated_size == 0) { size_t maxlen = (len >= alloc_size)? len:alloc_size; init_esb_string(data, maxlen); } /* ASSERT: data->esb_allocated_size > data->esb_used_bytes */ remaining = data->esb_allocated_size - data->esb_used_bytes - 1; if (remaining <= needed) { if (data->esb_rigid && len > remaining) { len = remaining; } else { size_t alloc_amt = needed - remaining; esb_allocate_more(data,alloc_amt); } } if (len == 0) { /* No room for anything more, or no more requested. */ return; } /* Might be that len < string len, so do not assume len+1 byte is a NUL byte. */ memcpy(&data->esb_string[data->esb_used_bytes],in_string,len); data->esb_used_bytes += len; /* Insist on explicit NUL terminator */ data->esb_string[data->esb_used_bytes] = 0; } /* len >= strlen(in_string) */ void esb_appendn(struct esb_s *data, const char * in_string, size_t len) { size_t full_len = strlen(in_string); if (full_len < len) { ESBERR("ESBERR_appendn bad call"); return; } esb_appendn_internal(data, in_string, len); } /* The length is gotten from the in_string itself, this is the usual way to add string data.. */ void esb_append(struct esb_s *data, const char * in_string) { size_t len = 0; if(in_string) { len = strlen(in_string); if (len) { esb_appendn_internal(data, in_string, len); } } } /* Always returns an empty string or a non-empty string. Never 0. */ char* esb_get_string(struct esb_s *data) { if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } return data->esb_string; } /* Sets esb_used_bytes to zero. The string is not freed and esb_allocated_size is unchanged. */ void esb_empty_string(struct esb_s *data) { if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } data->esb_used_bytes = 0; data->esb_string[0] = 0; } /* Return esb_used_bytes. */ size_t esb_string_len(struct esb_s *data) { return data->esb_used_bytes; } /* *data is presumed to contain garbage, not values, and is properly initialized here. */ void esb_constructor(struct esb_s *data) { memset(data, 0, sizeof(*data)); } #if 0 void esb_constructor_rigid(struct esb_s *data,char *buf,size_t buflen) { memset(data, 0, sizeof(*data)); data->esb_string = buf; data->esb_string[0] = 0; data->esb_allocated_size = buflen; data->esb_used_bytes = 0; data->esb_rigid = 1; data->esb_fixed = 1; } #endif /* ASSERT: buflen > 0 */ void esb_constructor_fixed(struct esb_s *data,char *buf,size_t buflen) { memset(data, 0, sizeof(*data)); if (buflen < 1) { return; } data->esb_string = buf; data->esb_string[0] = 0; data->esb_allocated_size = buflen; data->esb_used_bytes = 0; data->esb_rigid = 0; data->esb_fixed = 1; } /* The string is freed, contents of *data set to zeros. */ void esb_destructor(struct esb_s *data) { if(data->esb_fixed) { data->esb_allocated_size = 0; data->esb_used_bytes = 0; data->esb_string = 0; data->esb_rigid = 0; data->esb_fixed = 0; return; } if (data->esb_string) { free(data->esb_string); data->esb_string = 0; } esb_constructor(data); } /* To get all paths in the code tested, this sets the initial allocation/reallocation file-static which can be quite small but must not be zero The alloc_size variable is used for initializations. */ void esb_alloc_size(size_t size) { if (size < 1) { size = 1; } alloc_size = size; } size_t esb_get_allocated_size(struct esb_s *data) { return data->esb_allocated_size; } static void esb_appendn_internal_spaces(struct esb_s *data,size_t l) { static char spacebuf[] = {" "}; size_t charct = sizeof(spacebuf)-1; while (l > charct) { esb_appendn_internal(data,spacebuf,charct); l -= charct; } /* ASSERT: l > 0 */ esb_appendn_internal(data,spacebuf,l); } static void esb_appendn_internal_zeros(struct esb_s *data,size_t l) { static char zeros[] = {"0000000000000000000000000000000000000000"}; size_t charct = sizeof(zeros)-1; while (l > charct) { esb_appendn_internal(data,zeros,charct); l -= charct; } /* ASSERT: l > 0 */ esb_appendn_internal(data,zeros,l); } void esb_append_printf_s(struct esb_s *data,const char *format,const char *s) { size_t stringlen = strlen(s); size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; /* was %[-]fixedlen. Zero means no len provided. */ size_t fixedlen = 0; /* was %-, nonzero means left-justify */ long leftjustify = 0; size_t prefixlen = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } if (prefixlen) { esb_appendn_internal(data,format,prefixlen); } next++; if (format[next] == '-') { leftjustify++; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); if (format[next] != 's') { ESBERR("ESBERR_pct_s_missing_in_s"); return; } next++; if (leftjustify) { if (fixedlen && fixedlen <= stringlen) { /* This lets us have fixedlen < stringlen */ esb_appendn_internal(data,s,fixedlen); } else { esb_appendn_internal(data,s,stringlen); if(fixedlen) { size_t trailingspaces = fixedlen - stringlen; esb_appendn_internal_spaces(data,trailingspaces); } } } else { if (fixedlen && fixedlen <= stringlen) { /* This lets us have fixedlen < stringlen */ esb_appendn_internal(data,s,fixedlen); } else { if(fixedlen) { size_t leadingspaces = fixedlen - stringlen; size_t k = 0; for ( ; k < leadingspaces; ++k) { esb_appendn_internal(data," ",1); } } esb_appendn_internal(data,s,stringlen); } } if (!format[next]) { return; } { const char * startpt = format+next; size_t suffixlen = strlen(startpt); esb_appendn_internal(data,startpt,suffixlen); } return; } static char dtable[10] = { '0','1','2','3','4','5','6','7','8','9' }; static char xtable[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; static char Xtable[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; /* With gcc version 5.4.0 20160609 a version using const char *formatp instead of format[next] and deleting the 'next' variable is a few hundredths of a second slower, repeatably. We deal with formats like: %u %5u %05u (and ld and lld too). %x %5x %05x (and ld and lld too). */ void esb_append_printf_u(struct esb_s *data,const char *format,esb_unsigned v) { size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = 0; size_t divisor = 0; size_t prefixlen = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } esb_appendn_internal(data,format,prefixlen); if (format[next] != '%') { /* No % operator found */ ESBERR("ESBERR..esb_append_printf_u has no % operator"); return; } next++; if (format[next] == '-') { ESBERR("ESBERR_printf_u - format not supported"); next++; } if (format[next] == '0') { leadingzero = 1; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { ESBERR("ESBERR_pct_scount_in_u"); return; } if ( (Xcount +xcount+dcount+ucount) > 1) { ESBERR("ESBERR_pct_xcount_etc_u"); /* error */ return; } if (lcount > 2) { ESBERR("ESBERR_pct_lcount_error_u"); /* error */ return; } if (dcount > 0) { ESBERR("ESBERR_pct_dcount_error_u"); /* error */ return; } if (ucount) { divisor = 10; ctable = dtable; } else { divisor = 16; if (xcount) { ctable = xtable; } else { ctable = Xtable; } } { char digbuf[36]; char *digptr = 0; size_t digcharlen = 0; esb_unsigned remaining = v; if (divisor == 16) { digptr = digbuf+sizeof(digbuf) -1; for ( ;; ) { esb_unsigned dig; dig = remaining & 0xf; remaining = remaining >> 4; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } else { digptr = digbuf+sizeof(digbuf) -1; *digptr = 0; --digptr; for ( ;; ) { esb_unsigned dig; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } if (fixedlen <= digcharlen) { esb_appendn_internal(data,digptr,digcharlen); } else { if (!leadingzero) { size_t justcount = fixedlen - digcharlen; esb_appendn_internal_spaces(data,justcount); esb_appendn_internal(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; esb_appendn_internal_zeros(data,prefixcount); esb_appendn_internal(data,digptr,digcharlen); } } } if (format[next]) { size_t trailinglen = strlen(format+next); esb_appendn_internal(data,format+next,trailinglen); } } static char v32m[] = {"-2147483648"}; static char v64m[] = {"-9223372036854775808"}; /* We deal with formats like: %d %5d %05d %+d %+5d (and ld and lld too). */ void esb_append_printf_i(struct esb_s *data,const char *format,esb_int v) { size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int pluscount = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = dtable; size_t prefixlen = 0; int done = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } esb_appendn_internal(data,format,prefixlen); if (format[next] != '%') { /* No % operator found */ ESBERR("ESBERR..esb_append_printf_i has no % operator"); return; } next++; if (format[next] == '-') { ESBERR("ESBERR_printf_i - format not supported"); next++; } if (format[next] == '+') { pluscount++; next++; } if (format[next] == '0') { leadingzero = 1; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { ESBERR("ESBERR_pct_scount_in_i"); return; } if (!dcount || (lcount >2) || (Xcount +xcount+dcount+ucount) > 1) { /* error */ ESBERR("ESBERR_xcount_etc_i"); return; } { char digbuf[36]; char *digptr = digbuf+sizeof(digbuf) -1; size_t digcharlen = 0; esb_int remaining = v; int vissigned = 0; esb_int divisor = 10; *digptr = 0; --digptr; if (v < 0) { vissigned = 1; /* This test is for twos-complement machines and would be better done via configure with a compile-time check so we do not need a size test at runtime. */ if (sizeof(v) == 8) { esb_unsigned vm = 0x7fffffffffffffffULL; if (vm == (esb_unsigned)~v) { memcpy(digbuf,v64m,sizeof(v64m)); digcharlen = sizeof(v64m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } } else if (sizeof(v) == 4) { esb_unsigned vm = 0x7fffffffL; if (vm == (esb_unsigned)~v) { memcpy(digbuf,v32m,sizeof(v32m)); digcharlen = sizeof(v32m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } }else { ESBERR("ESBERR_sizeof_v_i"); /* error */ return; } } if(!done) { for ( ;; ) { esb_unsigned dig = 0; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; digcharlen++; if (!remaining) { break; } --digptr; } if (vissigned) { --digptr; digcharlen++; *digptr = '-'; } else if (pluscount) { --digptr; digcharlen++; *digptr = '+'; } } if (fixedlen > 0) { if (fixedlen <= digcharlen) { esb_appendn_internal(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; if (!leadingzero) { esb_appendn_internal_spaces(data,prefixcount); esb_appendn_internal(data,digptr,digcharlen); } else { if (*digptr == '-') { esb_appendn_internal(data,"-",1); esb_appendn_internal_zeros(data,prefixcount); digptr++; esb_appendn_internal(data,digptr,digcharlen-1); } else if (*digptr == '+') { esb_appendn_internal(data,"+",1); esb_appendn_internal_zeros(data,prefixcount); digptr++; esb_appendn_internal(data,digptr,digcharlen-1); } else { esb_appendn_internal_zeros(data,prefixcount); esb_appendn_internal(data,digptr,digcharlen); } } } } else { esb_appendn_internal(data,digptr,digcharlen); } } if (format[next]) { size_t trailinglen = strlen(format+next); esb_appendn_internal(data,format+next,trailinglen); } } /* Append a formatted string */ void esb_append_printf(struct esb_s *data,const char *in_string, ...) { va_list ap; size_t len = 0; size_t len2 = 0; size_t remaining = 0; if (!null_device_handle) { if(!esb_open_null_device()) { esb_append(data," Unable to open null printf device on:"); esb_append(data,in_string); return; } } va_start(ap,in_string); len = vfprintf(null_device_handle,in_string,ap); va_end(ap); if (data->esb_allocated_size == 0) { init_esb_string(data, alloc_size); } remaining = data->esb_allocated_size - data->esb_used_bytes - 1; if (remaining < len) { if (data->esb_rigid) { /* No room, give up. */ return; } else { esb_allocate_more(data, len); } } va_start(ap,in_string); #ifdef HAVE_VSNPRINTF len2 = vsnprintf(&data->esb_string[data->esb_used_bytes], data->esb_allocated_size, in_string,ap); #else len2 = vsprintf(&data->esb_string[data->esb_used_bytes], in_string,ap); #endif va_end(ap); data->esb_used_bytes += len2; if (len2 > len) { /* We are in big trouble, this should be impossible. We have trashed something in memory. */ fprintf(stderr, "dwarfdump esb internal error, vsprintf botch " " %lu < %lu \n", (unsigned long) len2, (unsigned long) len); exit(5); } return; } /* Get a copy of the internal data buffer. It is up to the code calling this to free() the string using the pointer returned here. */ char* esb_get_copy(struct esb_s *data) { char* copy = NULL; /* is ok as is if esb_allocated_size is 0 */ size_t len = data->esb_used_bytes+1; if (len) { copy = (char*)malloc(len); #ifdef MALLOC_COUNT ++malloc_count; malloc_size += len+1; #endif memcpy(copy,data->esb_string,len); } return copy; } dwarfutils-20200114/dwarfdump/esb.h000066400000000000000000000121421361531463500170530ustar00rootroot00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* esb.h Extensible string buffer. A simple vaguely object oriented extensible string buffer. The struct could be opaque here, but it seems ok to expose the contents: simplifies debugging. */ #ifndef ESB_H #define ESB_H #include "config.h" #include #include /* For va_start va_arg va_list */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* If esb_allocated_size > 0 then esb_string points to esb_allocated_size bytes and esb_used bytes <= (esb_allocated_size -1) All operations that insert or return strings ensure, first, that esb_allocated_size is non-zero and the requirements here are met. In esb_constructor esb_allocated_size and esb_used_bytes and esb_string are set 0. No malloc done. Default init alloc sets esb_allocated_size=alloc_size and mallocs alloc_size bytes. and esb_used_bytes = 0 and esb_string[0] = NUL. */ struct esb_s { char * esb_string; /* pointer to the data itself, or NULL. */ size_t esb_allocated_size; /* Size of allocated data or 0 The allocated size must include the trailing NUL as we do insert a NUL. */ size_t esb_used_bytes; /* Amount of space used or 0, which does not include the trailing NUL. Matches what strlen(esb_string) would return. */ /* rigid means never do malloc. fixed means the size is a user buffer but if we run out of room feel free to malloc space (and then unset esb_fixed). An esb can be (fixed and rigid), (fixed and not rigid), or (not fixed and not rigid). */ char esb_fixed; char esb_rigid; }; /* Mirroring the broken code in libdwarf.h.in */ typedef long long esb_int; typedef unsigned long long esb_unsigned; /* Open/close the null device used during formatting printing */ FILE *esb_open_null_device(void); void esb_close_null_device(void); /* string length taken from string itself. */ void esb_append(struct esb_s *data, const char * in_string); /* The 'len' is believed. Do not pass in strings < len bytes long. */ void esb_appendn(struct esb_s *data, const char * in_string, size_t len); /* Always returns an empty string or a non-empty string. Never 0. */ char * esb_get_string(struct esb_s *data); /* Sets esb_used_bytes to zero. The string is not freed and esb_allocated_size is unchanged. */ void esb_empty_string(struct esb_s *data); /* Return esb_used_bytes. */ size_t esb_string_len(struct esb_s *data); /* The following are for testing esb, not use by dwarfdump. */ /* *data is presumed to contain garbage, not values, and is properly initialized. */ void esb_constructor(struct esb_s *data); void esb_constructor_rigid(struct esb_s *data,char *buf,size_t buflen); void esb_constructor_fixed(struct esb_s *data,char *buf,size_t buflen); void esb_force_allocation(struct esb_s *data, size_t minlen); /* The string is freed, contents of *data set to zeroes. */ void esb_destructor(struct esb_s *data); /* To get all paths in the code tested, this sets the allocation/reallocation to the given value, which can be quite small but must not be zero. */ void esb_alloc_size(size_t size); size_t esb_get_allocated_size(struct esb_s *data); /* Append a formatted string */ void esb_append_printf(struct esb_s *data,const char *format, ...); void esb_append_printf_s(struct esb_s *data,const char *format,const char *s); void esb_append_printf_i(struct esb_s *data,const char *format,esb_int); void esb_append_printf_u(struct esb_s *data,const char *format,esb_unsigned); /* Get a copy of the internal data buffer */ char * esb_get_copy(struct esb_s *data); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ESB_H */ dwarfutils-20200114/dwarfdump/esb_using_functions.h000066400000000000000000000047001361531463500223510ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012-2018 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef ESB_USING_FUNCTIONS_H #define ESB_USING_FUNCTIONS_H #ifdef __cplusplus extern "C" { #endif void print_ranges_list_to_extra(Dwarf_Debug dbg, Dwarf_Unsigned off, Dwarf_Ranges *rangeset, Dwarf_Signed rangecount, Dwarf_Unsigned bytecount, struct esb_s *stringbuf); int get_producer_name(Dwarf_Debug dbg,Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, struct esb_s *producername); void get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Die die, Dwarf_Off die_cu_offset, Dwarf_Attribute attrib, char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp, int show_form,int local_verbose); void format_sig8_string(Dwarf_Sig8 *data,struct esb_s *out); void dwarfdump_print_one_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc * llbuf, /* 2014 interface */ Dwarf_Locdesc_c locs, /* 2015 interface */ Dwarf_Unsigned llent, /* Which locdesc is this */ Dwarf_Unsigned entrycount, /* count of DW_OP operators */ Dwarf_Addr baseaddr, struct esb_s *string_out); void format_sig8_string(Dwarf_Sig8*data, struct esb_s *out); void get_true_section_name(Dwarf_Debug dbg, const char *standard_name, struct esb_s *name_out, Dwarf_Bool add_compr); #ifdef __cplusplus } #endif #endif /* ESB_USING_FUNCTIONS_H */ dwarfutils-20200114/dwarfdump/getopttest.c000066400000000000000000000500611361531463500205010ustar00rootroot00000000000000/* This is for testing the local getopt. */ #ifdef GETOPT_FROM_SYSTEM #define dwgetopt getopt #define dwgetopt_long getopt_long #define dwopterr opterr #define dwoptind optind #define dwoptopt optopt #define dwopterr opterr #define dwoptarg optarg /* Leave dw_noargument etc to be defined as 0,1,2 as that matches system getopt.h */ #endif #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include "dwgetopt.h" /* for dwgetopt */ char *argv1[20]; /* Use for testing dwgetopt only. Not a standard function. */ static void dwgetoptresetfortestingonly(void) { dwopterr = 1; dwoptind = 1; dwoptopt = 0; dwoptreset = 0; dwoptarg = 0; } static int turnprintable(int c) { if ( c >= 0x20 && c <= 0x7f) { return c; } return '.'; } static void printcheckargs( int ct, int rchar,int xchar, char *roptarg,char *xoptarg, int roptind,int xoptind, const char *testid, int testline) { printf("chkval entry ct %d test %s line %d\n",ct,testid,testline); printf(" rchar 0x%x('%c') xchar 0x%x('%c') roptarg %s xoptarg %s\n", rchar,turnprintable(rchar), xchar,turnprintable(xchar), roptarg?roptarg:"",xoptarg?xoptarg:""); printf(" roptind %d xoptind %d\n",roptind,xoptind); } /* for rchar read the real int/char returned. for xchar read the expected int/char. for roptarg, read dwoptarg (the real optarg val), for xoptarg read expected-optarg for roptind read dwoptind, for xoptind read expected-optind */ static void chkval( int ct, int rchar,int xchar, char *roptarg,char *xoptarg, int roptind,int xoptind, const char *testid, int testline) { int err = 0; if (rchar != xchar) { int pr = turnprintable(rchar); int px = turnprintable(xchar); err++; printf("Mismatch %d %s line %d: got char %c %d 0x%x; exp char %c %d 0x%x\n", ct,testid,testline,pr,rchar,rchar,px,xchar,xchar); } if (roptarg != xoptarg) { /* pointers non-match */ if (roptarg && xoptarg && (!strcmp(roptarg,xoptarg))) { /* strings match. */ } else { err++; printf("Mismatch %d %s line %d: got dwoptarg %s 0x%lx exp optarg %s 0x%lx\n", ct,testid,testline, roptarg?roptarg:"", (unsigned long)roptarg, xoptarg?xoptarg:"", (unsigned long)xoptarg); } } if (roptind != xoptind) { err++; printf("Mismatch %d %s line %d: got dwoptind %d 0x%x exp optind %d 0x%x\n", ct,testid,testline, roptind,roptind,xoptind,xoptind); } if (err > 0) { printcheckargs(ct,rchar,xchar,roptarg,xoptarg,roptind,xoptind,testid,testline); printf("FAIL getopttest %s line %d\n",testid,testline); exit(1); } } static void chkval_long( int ct, int rchar,int xchar, char *roptarg,char *xoptarg, int roptind,int xoptind, int rlongindex, int xlongindex, const char *testid,int testline) { int err = 0; chkval(ct,rchar,xchar,roptarg,xoptarg,roptind,xoptind,testid,testline); if (rlongindex != xlongindex) { printf("chkval_long entry ct %d test %s line %d\n",ct,testid,testline); printf(" rlongindex %d xlongindex %d\n", rlongindex,xlongindex); ++err; printf("Mismatch %d %s line %d: on longopt longindex got %d expected %d\n", ct,testid,testline, rlongindex,xlongindex); } if (err > 0) { printf("FAIL getopttest %s line %d\n",testid,testline); exit(1); } } static int test3(void) { int ct = 1; int c = 0; int argct = 8; argv1[0]="a.out"; argv1[1]="-a"; argv1[2]="-#bx"; argv1[3]="-b"; argv1[4]="-c"; argv1[5]="-cfoo"; argv1[6]="-d"; argv1[7]="progtoread"; argv1[8]=0; for ( ;(c = dwgetopt(argct, argv1, "#:abc::d")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,2,"test31",__LINE__); break; case 2: chkval(ct,c,'#',dwoptarg,"bx",dwoptind,3,"test32",__LINE__); break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,4,"test33",__LINE__); break; case 4: chkval(ct,c,'c',dwoptarg,0,dwoptind,5,"test34",__LINE__); break; case 5: chkval(ct,c,'c',dwoptarg,"foo",dwoptind,6,"test35",__LINE__); break; case 6: chkval(ct,c,'d',dwoptarg,0,dwoptind,7,"test36",__LINE__); break; case 7: case 8: case 9: case 10: case 11: default: printf("FAIL test3 unexpected ct %d\n",ct); } } #if 0 printf(" final check: ct %d dwoptind %d\n",ct,optind); #endif if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL test3 on non-dash dwoptind %d arg got %s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt test 3\n"); return 0; } static int test2(void) { int ct = 1; int c = 0; int argct = 5; argv1[0]="a.out"; argv1[1]="-a"; argv1[2]="-#pound"; argv1[3]="-b"; argv1[4]="-cfilename"; argv1[5]=0; for ( ;(c = dwgetopt(argct, argv1, "#:abc::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,2,"test21",__LINE__); break; case 2: chkval(ct,c,'#',dwoptarg,"pound",dwoptind,3,"test22",__LINE__); break; break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,4,"test23",__LINE__); break; case 4: chkval(ct,c,'c',dwoptarg,"filename",dwoptind,5,"test24",__LINE__); break; default: printf("FAIL test2 unexpected ct %d\n",ct); exit(1); } } #if 0 printf(" final check: ct %d dwoptind %d\n",ct,optind); #endif if (argv1[dwoptind]) { printf("FAIL test2 on non-dash arg dwoptind %d got 0x%lx exp NULL\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test 2\n"); return 0; } static int ltest1(void) { int ct = 1; int c = 0; int argct = 13; static struct dwoption longopts[] = { {"simplelong", dwno_argument, 0,1000}, {"optarglong", dwoptional_argument,0,1001}, {"requireoptarglong",dwrequired_argument,0,1002}, {0,0,0,0} }; int longindex = 0; argv1[0]="a.out"; argv1[1]="-ab"; argv1[2] = "--simplelong"; argv1[3] = "--optarglong"; argv1[4] = "--requireoptarglong=val"; argv1[5] = "-cd"; argv1[6]="progtoread"; argv1[7]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1,"ltest1.1",__LINE__); break; case 2: chkval(ct,c,'b',dwoptarg,0,dwoptind,2,"ltest1.2",__LINE__); break; case 3: chkval_long(ct,c,1000,dwoptarg,0,dwoptind,3,longindex,0, "ltest1.3",__LINE__); break; case 4: chkval_long(ct,c,1001,dwoptarg,0,dwoptind,4,longindex,1, "ltest1.4",__LINE__); break; case 5: chkval_long(ct,c,1002,dwoptarg,"val",dwoptind,5,longindex,2, "ltest1.5",__LINE__); break; case 6: chkval(ct,c,'c',dwoptarg,0,dwoptind,5,"ltest1.6",__LINE__); break; case 7: chkval(ct,c,'d',dwoptarg,0,dwoptind,6,"ltest1.7",__LINE__); break; default: printf("FAIL ltest1 unexpected ct %d in ltest1\n",ct); exit(1); } } #if 0 printf(" final check: ct %d dwoptind %d\n",ct,optind); #endif if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL ltest1 on non-dash arg dwoptind %d got %s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt ltest1\n"); return 0; } static int ltest2(void) { int ct = 1; int c = 0; int argct = 13; static struct dwoption longopts[] = { {"optarglong", dwoptional_argument,0,6}, {0,0,0,0} }; int longindex = 0; argv1[0]="a.out"; argv1[1]="-ab"; argv1[2] = "--optarglong"; argv1[3] = "--optarglong="; argv1[4] = "--optarglong=val"; argv1[5] = "-cd"; argv1[6]="progtoread"; argv1[7]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1,"ltest21",__LINE__); break; case 2: chkval(ct,c,'b',dwoptarg,0,dwoptind,2,"ltest22",__LINE__); break; case 3: chkval_long(ct,c,6,dwoptarg,0,dwoptind,3,longindex,0, "ltest23",__LINE__); break; case 4: chkval_long(ct,c,6,dwoptarg,0,dwoptind,4,longindex,0, "ltest24",__LINE__); break; case 5: chkval_long(ct,c,6,dwoptarg,"val",dwoptind,5,longindex,0, "ltest25",__LINE__); break; case 6: chkval(ct,c,'c',dwoptarg,0,dwoptind,5,"ltest26",__LINE__); break; case 7: chkval(ct,c,'d',dwoptarg,0,dwoptind,6,"ltest27",__LINE__); break; default: printf("FAIL ltest1 unexpected ct %d in ltest2\n",ct); exit(1); } } #if 0 printf(" final check: ct %d dwoptind %d\n",ct,optind); #endif if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL ltest2 on non-dash arg dwoptind %d got %s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt ltest2\n"); return 0; } static int test1(void) { int ct = 1; int c = 0; int argct = 13; argv1[0]="a.out"; argv1[1]="-a"; argv1[2]="-#"; argv1[3]="6"; argv1[4]="-H1"; argv1[5]="-H"; argv1[6]="2"; argv1[7]="-ka"; argv1[8]="-l"; argv1[9]="-lv"; argv1[10]="-x"; argv1[11]="path=./foo"; argv1[12]="progtoread"; argv1[13]=0; for ( ;(c = dwgetopt(argct, argv1, "#:abc::CdDeE::fFgGhH:iIk:l::mMnNo::O:pPqQrRsS:t:u:UvVwW::x:yz")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,2,"test11",__LINE__); break; case 2: chkval(ct,c,'#',dwoptarg,"6",dwoptind,4,"test12",__LINE__); break; case 3: chkval(ct,c,'H',dwoptarg,"1",dwoptind,5,"test13",__LINE__); break; case 4: chkval(ct,c,'H',dwoptarg,"2",dwoptind,7,"test14",__LINE__); break; case 5: chkval(ct,c,'k',dwoptarg,"a",dwoptind,8,"test15",__LINE__); break; case 6: chkval(ct,c,'l',dwoptarg,0,dwoptind,9,"test16",__LINE__); break; case 7: chkval(ct,c,'l',dwoptarg,"v",dwoptind,10,"test17",__LINE__); break; case 8: chkval(ct,c,'x',dwoptarg,"path=./foo",dwoptind,12,"test18",__LINE__); break; default: printf("FAIL test1 unexpected ct %d in test1\n",ct); exit(1); } } #if 0 printf(" final check: ct %d dwoptind %d\n",ct,optind); #endif if (strcmp(argv1[dwoptind],"progtoread")) { printf("FAIL test1 on non-dash arg dwoptind %d got %s exp %s\n", dwoptind,argv1[dwoptind],"progtoread"); exit(1); } printf("PASS getopt test1\n"); return 0; } static int test5(void) { int ct = 1; int c = 0; int argct = 8; argv1[0]="a.out"; argv1[1]="-ab"; argv1[2]="-a"; argv1[3]="-cx"; argv1[4]="-c"; argv1[5]="y"; argv1[6]="-d"; argv1[7]="-da"; argv1[8]=0; for ( ;(c = dwgetopt(argct, argv1, "abc:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1,"test51",__LINE__); break; case 2: chkval(ct,c,'b',dwoptarg,0,dwoptind,2,"test52",__LINE__); break; case 3: chkval(ct,c,'a',dwoptarg,0,dwoptind,3,"test53",__LINE__); break; case 4: chkval(ct,c,'c',dwoptarg,"x",dwoptind,4,"test54",__LINE__); break; case 5: chkval(ct,c,'c',dwoptarg,"y",dwoptind,6,"test55",__LINE__); break; case 6: chkval(ct,c,'d',dwoptarg,0,dwoptind,7,"test56",__LINE__); break; case 7: chkval(ct,c,'d',dwoptarg,"a",dwoptind,8,"test17",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char 0x%x %c\n",ct,c,c); exit(1); } } #if 0 printf(" final check: ct %d dwoptind %d\n",ct,optind); #endif if (argv1[dwoptind]) { printf("FAIL test5 there is a non-dash arg dwoptind %d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test5\n"); return 0; } static int test6(void) { int ct = 1; int c = 0; int argct = 2; argv1[0]="a.out"; argv1[1]="-H"; argv1[2]=0; for ( ;(c = dwgetopt(argct, argv1, "abH:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'?',dwoptarg,0,dwoptind,2,"test61",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char 0x%x %c\n",ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test6 there is a non-dash arg dwoptind %d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test6\n"); return 0; } /* Leading : in opt string */ static int test7(void) { int ct = 1; int c = 0; int argct = 2; argv1[0]="a.out"; argv1[1]="-H"; argv1[2]=0; for ( ;(c = dwgetopt(argct, argv1, ":abH:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,':',dwoptarg,0,dwoptind,2,"test7.1",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char 0x%x %c\n",ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test7 there is a non-dash arg dwoptind %d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test7\n"); return 0; } static int test8(void) { int ct = 1; int c = 0; int argct = 2; argv1[0]="a.out"; argv1[1]="-x"; argv1[2]=0; /* We expect a ? because the arg list is improper. */ for ( ;(c = dwgetopt(argct, argv1, "abH:d::")) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'?',dwoptarg,0,dwoptind,2,"test8.1",__LINE__); break; default: printf("FAIL test5 unexpected ct %d in test1 char 0x%x %c\n",ct,c,c); exit(1); } } if (argv1[dwoptind]) { printf("FAIL test8 there is a non-dash arg dwoptind %d got 0x%lx\n", dwoptind,(unsigned long)argv1[dwoptind]); exit(1); } printf("PASS getopt test8\n"); return 0; } static int test9(void) { int ct = 1; int c = 0; int argct = 13; /* If an argument is required and there is no = in the input, the next argv is taken as the optarg. This was found by experiment. */ static struct dwoption longopts[] = { {"simplelong", dwno_argument, 0,1}, {"optarglong", dwoptional_argument,0,2}, {"requireoptarglong",dwrequired_argument,0,3}, {0,0,0,0} }; int longindex = 0; int stop = 0; argv1[0]="a.out"; argv1[1]="-acb"; argv1[2] = "--bogusarg"; argv1[3] = "-cd"; argv1[4]="progtoread"; argv1[5]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1, "ltest9.1",__LINE__); break; case 2: chkval(ct,c,'c',dwoptarg,0,dwoptind,1, "ltest9.2",__LINE__); break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,2, "ltest9.2",__LINE__); break; case 4: /* invalid long option */ chkval_long(ct,c,'?',dwoptarg,0,dwoptind,3, longindex,0, "ltest9.4",__LINE__); stop = 1; break; default: break; } if (stop) { break; } } printf("PASS getopt test9\n"); return 0; } static int test10(void) { int ct = 1; int c = 0; int argct = 13; /* If an argument is required and there is no = in the input, the next argv is taken as the optarg. This was found by experiment. */ static struct dwoption longopts[] = { {"simplelong", dwno_argument, 0,1}, {"optarglong", dwoptional_argument,0,2}, {"requireoptarglong",dwrequired_argument,0,3}, {0,0,0,0} }; int longindex = 0; int done=0; argv1[0]="a.out"; argv1[1]="-acb"; argv1[2] = "--optarglong"; argv1[3] = "--simplelong=oops"; argv1[4] = "-cd"; argv1[5]="progtoread"; argv1[6]=0; for ( ;(c = dwgetopt_long(argct, argv1, "abcd", longopts,&longindex)) != EOF; ct++) { switch(ct) { case 1: chkval(ct,c,'a',dwoptarg,0,dwoptind,1, "ltest10.1",__LINE__); break; case 2: chkval(ct,c,'c',dwoptarg,0,dwoptind,1, "ltest10.2",__LINE__); break; case 3: chkval(ct,c,'b',dwoptarg,0,dwoptind,2, "ltest10.3",__LINE__); break; case 4: chkval_long(ct,c,2,dwoptarg,0,dwoptind,3, longindex,1, "ltest10.4",__LINE__); break; case 5: /* This one has error . =arg when none allowed */ chkval_long(ct,c,'?',dwoptarg,0, dwoptind,4, longindex,1, "ltest10.5",__LINE__); done=1; break; default: break; } if (done) { break; } } printf("PASS getopt test10\n"); return 0; } int main(int argc, const char **argv) { int ct = 0; int failct = 0; printf("argc: %d\n",argc); for( ct = 0; ct < argc ; ++ct) { printf("argv[%d] = %s\n",ct,argv[ct]); } if ( argc == 3) { int num = 0; if (strcmp(argv[1],"-c")) { printf("FAIL: invalid arg list\n"); exit(1); } num = atoi(argv[2]); printf("Run one test, number %d\n",num); switch(num) { case 1: failct = test1(); break; case 2: failct = test2(); break; case 3: failct = test3(); break; case 5: failct = test5(); break; case 6: failct = test6(); break; case 7: failct = test7(); break; case 8: failct = test8(); break; case 9: failct = test9(); break; case 10: failct = test10(); break; default: printf("FAIL: invalid test number %d\n",num); exit(1); } if ( failct) { printf("FAIL getopttest\n"); exit(1); } printf("PASS getopttest\n"); exit(0); } else if (argc != 1) { printf("FAIL: invalid arg list\n"); exit(1); } failct += ltest1(); dwgetoptresetfortestingonly(); failct += ltest2(); dwgetoptresetfortestingonly(); failct += test5(); dwgetoptresetfortestingonly(); failct += test1(); dwgetoptresetfortestingonly(); failct += test2(); dwgetoptresetfortestingonly(); failct += test3(); dwgetoptresetfortestingonly(); failct += test6(); dwgetoptresetfortestingonly(); failct += test7(); dwgetoptresetfortestingonly(); failct += test8(); dwgetoptresetfortestingonly(); failct += test9(); dwgetoptresetfortestingonly(); failct += test10(); if ( failct) { printf("FAIL getopttest\n"); exit(1); } printf("PASS getopttest\n"); return 0; } dwarfutils-20200114/dwarfdump/glflags.c000066400000000000000000000310731361531463500177200ustar00rootroot00000000000000/* Copyright (C) 2017-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* All the dwarfdump flags are gathered into a single global struct as it has been hard to know how many there were or what they were all for. */ #include "globals.h" #include #include "esb.h" /* For flexible string buffer. */ #include "dwconf.h" #ifdef HAVE_REGEX regex_t _search_re; #endif static struct section_high_offsets_s _section_high_offsets_global; static struct dwconf_s _config_file_data; /* used in special_program_name() only */ static struct esb_s _newprogname; static struct esb_s _cu_name; static struct esb_s _config_file_path; static struct esb_s _config_file_tiedpath; void init_global_flags(void) { glflags.gf_debug_names_flag = FALSE; glflags.gf_info_flag = FALSE; glflags.gf_use_old_dwarf_loclist = FALSE; /* This so both dwarf_loclist_n() and dwarf_get_loclist_c() and the dwarf_loclist_from_expr variations can be tested. Defaults to new dwarf_get_loclist_c(). See -g option. The original IRIX dwarf_loclist() no longer tested as of October 2015. */ glflags.gf_line_flag_selection = s2l; glflags.gf_line_flag = FALSE; /* Setting this FALSE tells dwarfdump to use the old line-table interfaces. using: -x line5=no The new interfaces allow for both two-level line tables and access to line table headers in case we have a DWARF5 skeleton line table (a line table header with no lines). */ glflags.gf_line_skeleton_flag = TRUE; glflags.gf_line_print_pc = TRUE; /* Print addresses. */ glflags.gf_abbrev_flag = FALSE; glflags.gf_frame_flag = FALSE; /* .debug_frame section. */ glflags.gf_eh_frame_flag = FALSE; /* GNU .eh_frame section. */ glflags.gf_pubnames_flag = FALSE; glflags.gf_macinfo_flag = FALSE; /* DWARF2,3,4. Old macro section*/ glflags.gf_macro_flag = FALSE; /* DWARF5(and DWARF4 extension) new macro section */ glflags.gf_loc_flag = FALSE; glflags.gf_aranges_flag = FALSE; /* .debug_aranges section. */ glflags.gf_ranges_flag = FALSE; /* .debug_ranges section. */ glflags.gf_string_flag = FALSE; glflags.gf_reloc_flag = FALSE; glflags.gf_static_func_flag = FALSE; glflags.gf_static_var_flag = FALSE; glflags.gf_types_flag = FALSE; glflags.gf_weakname_flag = FALSE; glflags.gf_header_flag = FALSE; /* Control printing of Elf header. */ glflags.gf_gdbindex_flag = FALSE; glflags.gf_producer_children_flag = FALSE; /* List of CUs per compiler */ glflags.gf_check_abbrev_code = FALSE; glflags.gf_check_pubname_attr = FALSE; glflags.gf_check_reloc_offset = FALSE; glflags.gf_check_attr_tag = FALSE; glflags.gf_check_tag_tree = FALSE; glflags.gf_check_type_offset = FALSE; glflags.gf_check_decl_file = FALSE; glflags.gf_check_macros = FALSE; glflags.gf_check_lines = FALSE; glflags.gf_check_fdes = FALSE; glflags.gf_check_ranges = FALSE; glflags.gf_check_aranges = FALSE; glflags.gf_check_harmless = FALSE; glflags.gf_check_abbreviations = FALSE; glflags.gf_check_dwarf_constants = FALSE; glflags.gf_check_di_gaps = FALSE; glflags.gf_check_forward_decl = FALSE; glflags.gf_check_self_references = FALSE; glflags.gf_check_attr_encoding = FALSE; /* Attributes encoding */ glflags.gf_generic_1200_regs = FALSE; glflags.gf_suppress_check_extensions_tables = FALSE; glflags.gf_check_duplicated_attributes = FALSE; /* lots of checks make no sense on a dwp debugfission object. */ glflags.gf_suppress_checking_on_dwp = FALSE; glflags.gf_file_use_no_libelf = FALSE; /* suppress_nested_name_search is a band-aid. A workaround. A real fix for N**2 behavior is needed. */ glflags.gf_suppress_nested_name_search = FALSE; glflags.gf_uri_options_translation = TRUE; glflags.gf_do_print_uri_in_input = TRUE; glflags.gf_print_unique_errors = FALSE; glflags.gf_found_error_message = FALSE; glflags.gf_check_names = FALSE; /* During '-k' mode, display errors */ glflags.gf_check_verbose_mode = TRUE; glflags.gf_check_frames = FALSE; /* Extensive frames check */ glflags.gf_check_frames_extended = FALSE; glflags.gf_check_locations = FALSE; glflags.gf_print_usage_tag_attr = FALSE; glflags.gf_print_usage_tag_attr_full = FALSE; glflags.gf_check_all_compilers = TRUE; glflags.gf_check_snc_compiler = FALSE; glflags.gf_check_gcc_compiler = FALSE; glflags.gf_print_summary_all = FALSE; /* The check and print flags here make it easy to allow check-only or print-only. We no longer support check-and-print in a single run. */ glflags.gf_do_check_dwarf = FALSE; glflags.gf_do_print_dwarf = FALSE; glflags.gf_check_show_results = FALSE; glflags.gf_record_dwarf_error = FALSE; /* A test has failed, this is normally set FALSE shortly after being set TRUE, it is a short-range hint we should print something we might not otherwise print (under the circumstances). */ glflags.gf_check_debug_names = FALSE; /* Display parent/children when in wide format? */ glflags.gf_display_parent_tree = FALSE; glflags.gf_display_children_tree = FALSE; glflags.gf_stop_indent_level = 0; /* Print search results in wide format? */ glflags.gf_search_wide_format = FALSE; /* -S option: strings for 'any' and 'match' */ glflags.gf_search_is_on = FALSE; glflags.gf_search_print_results = FALSE; glflags.gf_cu_name_flag = FALSE; glflags.gf_show_global_offsets = FALSE; glflags.gf_display_offsets = TRUE; /* Base address has a special meaning in DWARF4 relative to address ranges. */ glflags.seen_PU = FALSE; /* Detected a PU */ glflags.seen_CU = FALSE; /* Detected a CU */ glflags.need_CU_name = TRUE; /* Need CU name */ glflags.need_CU_base_address = TRUE; /* Need CU Base address */ glflags.need_CU_high_address = TRUE; /* Need CU High address */ glflags.need_PU_valid_code = TRUE; /* Need PU valid code */ glflags.seen_PU_base_address = FALSE; /* Detected a Base address for PU */ glflags.seen_PU_high_address = FALSE; /* Detected a High address for PU */ glflags.PU_base_address = 0; /* PU Base address */ glflags.PU_high_address = 0; /* PU High address */ glflags.DIE_offset = 0; /* DIE offset in compile unit */ glflags.DIE_overall_offset = 0; /* DIE offset in .debug_info */ /* These globals enable better error reporting. */ glflags.DIE_CU_offset = 0; /* CU DIE offset in compile unit */ glflags.DIE_CU_overall_offset = 0; /* CU DIE offset in .debug_info */ glflags.current_section_id = 0; /* Section being process */ /* Base Address is needed for range lists and must come from a CU. Low address is for information and can come from a function or something in the CU. */ glflags.CU_base_address = 0; /* CU Base address */ glflags.CU_low_address = 0; /* CU low address */ glflags.CU_high_address = 0; /* CU High address */ glflags.fde_offset_for_cu_low = DW_DLV_BADOFFSET; glflags.fde_offset_for_cu_high = DW_DLV_BADOFFSET; glflags.program_name = NULL; glflags.program_fullname = NULL; /* Able to generate report on search */ glflags.search_any_text = 0; glflags.search_match_text = 0; glflags.search_regex_text = 0; glflags.search_occurrences = 0; #ifdef HAVE_REGEX glflags.search_re = &_search_re; #endif /* Start verbose at zero. verbose can be incremented with -v but not decremented. */ glflags.verbose = 0; glflags.dense = FALSE; glflags.ellipsis = FALSE; glflags.show_form_used = FALSE; /* break_after_n_units is mainly for testing. It enables easy limiting of output size/running time when one wants the output limited. For example, -H 2 limits the -i output to 2 compilation units and the -f or -F output to 2 FDEs and 2 CIEs. */ glflags.break_after_n_units = INT_MAX; glflags.section_high_offsets_global = &_section_high_offsets_global; glflags.pRangesInfo = NULL; glflags.pLinkonceInfo = NULL; glflags.pVisitedInfo = NULL; /* These names make diagnostic messages more complete, the fixed length is safe, though ultra long names will get truncated. */ glflags.PU_name[0] = 0; glflags.CU_name[0] = 0; glflags.CU_producer[0] = 0; /* Options to enable debug tracing. */ { int i = 0; for ( ; i <= MAX_TRACE_LEVEL; ++i) { glflags.nTrace[i] = 0; } } /* Output filename */ glflags.output_file = 0; glflags.group_number = 0; /* Global esb-buffers. */ glflags.newprogname = &_newprogname; esb_constructor(glflags.newprogname); glflags.cu_name = &_cu_name; esb_constructor(glflags.cu_name); glflags.config_file_path = &_config_file_path; esb_constructor(glflags.config_file_path); glflags.config_file_tiedpath = &_config_file_tiedpath; esb_constructor(glflags.config_file_tiedpath); glflags.config_file_data = &_config_file_data; /* Check errors. */ glflags.check_error = 0; } void reset_global_flags(void) { esb_destructor(glflags.newprogname); esb_destructor(glflags.cu_name); esb_destructor(glflags.config_file_path); esb_destructor(glflags.config_file_tiedpath); } /* When we add a 'print' option after an option requests one or more checks we turn off all checking, putting it back to default checking state. */ void set_checks_off(void) { glflags.gf_check_abbrev_code = FALSE; glflags.gf_check_pubname_attr = FALSE; glflags.gf_check_reloc_offset = FALSE; glflags.gf_check_attr_tag = FALSE; glflags.gf_check_tag_tree = FALSE; glflags.gf_check_type_offset = FALSE; glflags.gf_check_decl_file = FALSE; glflags.gf_check_lines = FALSE; glflags.gf_check_fdes = FALSE; glflags.gf_check_ranges = FALSE; glflags.gf_check_aranges = FALSE; glflags.gf_check_harmless = FALSE; glflags.gf_check_abbreviations = FALSE; glflags.gf_check_dwarf_constants = FALSE; glflags.gf_check_di_gaps = FALSE; glflags.gf_check_forward_decl = FALSE; glflags.gf_check_self_references = FALSE; glflags.gf_check_attr_encoding = FALSE; glflags.gf_check_duplicated_attributes = FALSE; glflags.gf_check_debug_names = FALSE; } /* Making this a named string makes it simpler to change what the reset,or 'I do not know' value is for CU name or producer name for PRINT_CU_INFO. */ static const char * default_cu_producer = ""; void reset_overall_CU_error_data(void) { safe_strcpy(glflags.CU_name,sizeof(glflags.CU_name), default_cu_producer,strlen(default_cu_producer)); safe_strcpy(glflags.CU_producer,sizeof(glflags.CU_producer), default_cu_producer,strlen(default_cu_producer)); glflags.DIE_offset = 0; glflags.DIE_overall_offset = 0; glflags.DIE_CU_offset = 0; glflags.DIE_CU_overall_offset = 0; glflags.CU_base_address = 0; glflags.CU_high_address = 0; glflags.CU_low_address = 0; } boolean cu_data_is_set(void) { if (strcmp(glflags.CU_name,default_cu_producer) || strcmp(glflags.CU_producer,default_cu_producer)) { return 1; } if (glflags.DIE_offset || glflags.DIE_overall_offset) { return 1; } if (glflags.CU_base_address || glflags.CU_low_address || glflags.CU_high_address) { return 1; } return 0; } dwarfutils-20200114/dwarfdump/glflags.h000066400000000000000000000337641361531463500177360ustar00rootroot00000000000000/* Copyright (C) 2017-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* All the dwarfdump flags are gathered into a single global struct as it has been hard to know how many there were or what they were all for. */ struct esb_s; struct dwconf_s; enum line_flag_type_e { singledw5, /* Meaning choose single table DWARF5 new interfaces. */ s2l, /* Meaning choose two-level DWARF5 new interfaces. */ orig, /* Meaning choose DWARF2,3,4 single level interface. */ orig2l /* Meaning choose DWARF 2,3,4 two-level interface. */ }; /* Check categories corresponding to the -k option */ typedef enum /* Dwarf_Check_Categories */ { abbrev_code_result, pubname_attr_result, reloc_offset_result, attr_tag_result, tag_tree_result, type_offset_result, decl_file_result, ranges_result, lines_result, aranges_result, /* Harmless errors are errors detected inside libdwarf but not reported via DW_DLE_ERROR returns because the errors won't really affect client code. The 'harmless' errors are reported and otherwise ignored. It is difficult to report the error when the error is noticed by libdwarf, the error is reported at a later time. The other errors dwarfdump reports are also generally harmless but are detected by dwarfdump so it's possble to report the error as soon as the error is discovered. */ harmless_result, fde_duplication, frames_result, locations_result, names_result, abbreviations_result, dwarf_constants_result, di_gaps_result, forward_decl_result, self_references_result, attr_encoding_result, duplicated_attributes_result, total_check_result, LAST_CATEGORY /* Must be last */ } Dwarf_Check_Categories; struct section_high_offsets_s { Dwarf_Unsigned debug_info_size; Dwarf_Unsigned debug_abbrev_size; Dwarf_Unsigned debug_line_size; Dwarf_Unsigned debug_loc_size; Dwarf_Unsigned debug_aranges_size; Dwarf_Unsigned debug_macinfo_size; Dwarf_Unsigned debug_pubnames_size; Dwarf_Unsigned debug_str_size; Dwarf_Unsigned debug_frame_size; Dwarf_Unsigned debug_ranges_size; Dwarf_Unsigned debug_pubtypes_size; Dwarf_Unsigned debug_types_size; Dwarf_Unsigned debug_macro_size; Dwarf_Unsigned debug_str_offsets_size; Dwarf_Unsigned debug_sup_size; Dwarf_Unsigned debug_cu_index_size; Dwarf_Unsigned debug_tu_index_size; }; /* Options to enable debug tracing. */ #define MAX_TRACE_LEVEL 10 struct glflags_s { /* This so both dwarf_loclist_n() and dwarf_get_loclist_c() and the dwarf_loclist_from_expr variations can be tested. Defaults to new dwarf_get_loclist_c(). See -g option. original IRIX dwarf_loclist() no longer tested as of October 2015. */ boolean gf_use_old_dwarf_loclist; enum line_flag_type_e gf_line_flag_selection; boolean gf_abbrev_flag; boolean gf_aranges_flag; /* .debug_aranges section. */ boolean gf_debug_names_flag; boolean gf_eh_frame_flag; /* GNU .eh_frame section. */ boolean gf_frame_flag; /* .debug_frame section. */ boolean gf_gdbindex_flag; /* .gdbindex section. */ boolean gf_gnu_debuglink_flag; /* .gnu_debuglink section. */ boolean gf_info_flag; /* .debug_info */ boolean gf_line_flag; boolean gf_line_print_pc; boolean gf_line_skeleton_flag; boolean gf_loc_flag; boolean gf_macinfo_flag; /* DWARF2,3,4. Old macro section*/ boolean gf_macro_flag; /* DWARF5 */ boolean gf_pubnames_flag; boolean gf_ranges_flag; /* .debug_ranges section. */ boolean gf_reloc_flag; /* Elf relocations, not DWARF. */ boolean gf_static_func_flag;/* SGI only */ boolean gf_static_var_flag; /* SGI only */ boolean gf_string_flag; boolean gf_pubtypes_flag; /* SGI only */ boolean gf_types_flag; /* .debug_types, not all CU types */ boolean gf_weakname_flag; /* SGI only */ boolean gf_header_flag; /* Control printing of Elf header. */ boolean gf_section_groups_flag; boolean gf_producer_children_flag; /* List of CUs per compiler */ boolean gf_check_abbrev_code; boolean gf_check_pubname_attr; boolean gf_check_reloc_offset; boolean gf_check_attr_tag; boolean gf_check_tag_tree; boolean gf_check_type_offset; boolean gf_check_decl_file; boolean gf_check_macros; boolean gf_check_lines; boolean gf_check_fdes; boolean gf_check_ranges; boolean gf_check_aranges; boolean gf_check_harmless; boolean gf_check_abbreviations; boolean gf_check_dwarf_constants; boolean gf_check_di_gaps; boolean gf_check_forward_decl; boolean gf_check_self_references; boolean gf_check_attr_encoding; /* Attributes encoding */ boolean gf_generic_1200_regs; boolean gf_suppress_check_extensions_tables; boolean gf_check_duplicated_attributes; /* lots of checks make no sense on a dwp debugfission object. */ boolean gf_suppress_checking_on_dwp; /* suppress_nested_name_search is a band-aid. A workaround. A real fix for N**2 behavior is needed. */ boolean gf_suppress_nested_name_search; boolean gf_uri_options_translation; boolean gf_do_print_uri_in_input; /* Print global (unique) error messages */ boolean gf_print_unique_errors; boolean gf_found_error_message; boolean gf_check_names; boolean gf_check_verbose_mode; /* During '-k' mode, display errors */ boolean gf_check_frames; boolean gf_check_frames_extended; /* Extensive frames check */ boolean gf_check_locations; /* Location list check */ boolean gf_print_usage_tag_attr; /* Print basic usage */ boolean gf_print_usage_tag_attr_full; /* Print full usage */ boolean gf_check_all_compilers; boolean gf_check_snc_compiler; /* Check SNC compiler */ boolean gf_check_gcc_compiler; boolean gf_print_summary_all; boolean gf_file_use_no_libelf; /* The check and print flags here make it easy to allow check-only or print-only. We no longer support check-and-print in a single run. */ boolean gf_do_check_dwarf; boolean gf_do_print_dwarf; boolean gf_check_show_results; /* Display checks results. */ boolean gf_record_dwarf_error; /* A test has failed, this is normally set FALSE shortly after being set TRUE, it is a short-range hint we should print something we might not otherwise print (under the circumstances). */ boolean gf_check_debug_names; /* Display parent/children when in wide format? */ boolean gf_display_parent_tree; boolean gf_display_children_tree; int gf_stop_indent_level; /* Print search results in wide format? */ boolean gf_search_wide_format; /* -S option: strings for 'any' and 'match' */ boolean gf_search_is_on; boolean gf_search_print_results; boolean gf_cu_name_flag; boolean gf_show_global_offsets; boolean gf_display_offsets; boolean gf_print_str_offsets; unsigned long gf_count_major_errors; /* Base address has a special meaning in DWARF4 relative to address ranges. */ boolean seen_PU; /* Detected a PU */ boolean seen_CU; /* Detected a CU */ boolean need_CU_name; /* Need CU name */ boolean need_CU_base_address; /* Need CU Base address */ boolean need_CU_high_address; /* Need CU High address */ boolean need_PU_valid_code; /* Need PU valid code */ boolean seen_PU_base_address; /* Detected a Base address for PU */ boolean seen_PU_high_address; /* Detected a High address for PU */ Dwarf_Addr PU_base_address; /* PU Base address */ Dwarf_Addr PU_high_address; /* PU High address */ Dwarf_Off DIE_offset; /* DIE offset in compile unit */ Dwarf_Off DIE_overall_offset; /* DIE offset in .debug_info */ /* These globals enable better error reporting. */ Dwarf_Off DIE_CU_offset; /* CU DIE offset in compile unit */ Dwarf_Off DIE_CU_overall_offset; /* CU DIE offset in .debug_info */ int current_section_id; /* Section being process */ /* Base Address is needed for range lists and must come from a CU. Low address is for information and can come from a function or something in the CU. */ Dwarf_Addr CU_base_address; /* CU Base address */ Dwarf_Addr CU_low_address; /* CU low address */ Dwarf_Addr CU_high_address; /* CU High address */ Dwarf_Off fde_offset_for_cu_low; Dwarf_Off fde_offset_for_cu_high; const char *program_name; const char *program_fullname; const char *search_any_text; const char *search_match_text; const char *search_regex_text; int search_occurrences; /* -S option: the compiled_regex */ #ifdef HAVE_REGEX regex_t *search_re; #endif /* Start verbose at zero. verbose can be incremented with -v but not decremented. */ int verbose; boolean dense; boolean ellipsis; boolean show_form_used; /* break_after_n_units is mainly for testing. It enables easy limiting of output size/running time when one wants the output limited. For example, -H 2 limits the -i output to 2 compilation units and the -f or -F output to 2 FDEs and 2 CIEs. */ int break_after_n_units; struct section_high_offsets_s *section_high_offsets_global; /* pRangesInfo records the DW_AT_high_pc and DW_AT_low_pc and is used to check that line range info falls inside the known valid ranges. The data is per CU, and is reset per CU in tag_specific_checks_setup(). */ Bucket_Group *pRangesInfo; /* pLinkonceInfo records data about the link once sections. If a line range is not valid in the current CU it might be valid in a linkonce section, this data records the linkonce sections. So it is filled in when an object file is read and remains unchanged for an entire object file. */ Bucket_Group *pLinkonceInfo; /* pVisitedInfo records a recursive traversal of DIE attributes DW_AT_specification DW_AT_abstract_origin DW_AT_type that let DWARF refer (as in a general graph) to arbitrary other DIEs. These traversals use pVisitedInfo to detect any compiler errors that introduce circular references. Printing of the traversals is also done on request. Entries are added and deleted as they are visited in a depth-first traversal. */ Bucket_Group *pVisitedInfo; /* Compilation Unit information for improved error messages. If the strings are too short we just truncate so fixed length here is fine. */ #define COMPILE_UNIT_NAME_LEN 512 char PU_name[COMPILE_UNIT_NAME_LEN]; /* PU Name */ char CU_name[COMPILE_UNIT_NAME_LEN]; /* CU Name */ char CU_producer[COMPILE_UNIT_NAME_LEN]; /* CU Producer Name */ /* Options to enable debug tracing. */ int nTrace[MAX_TRACE_LEVEL + 1]; /* Output filename */ const char *output_file; int group_number; /* Global esb-buffers. */ struct esb_s *newprogname; struct esb_s *cu_name; struct esb_s *config_file_path; struct esb_s *config_file_tiedpath; struct dwconf_s *config_file_data; /* Check errors. */ int check_error; }; extern struct glflags_s glflags; void init_global_flags(void); void reset_global_flags(void); void set_checks_off(void); void reset_overall_CU_error_data(void); boolean cu_data_is_set(void); /* Shortcuts for additional trace options */ #define DUMP_OPTIONS 0 /* Dump options. */ #define DUMP_RANGES_INFO 1 /* Dump RangesInfo Table. */ #define DUMP_LOCATION_SECTION_INFO 2 /* Dump Location (.debug_loc) Info. */ #define DUMP_RANGES_SECTION_INFO 3 /* Dump Ranges (.debug_ranges) Info. */ #define DUMP_LINKONCE_INFO 4 /* Dump Linkonce Table. */ #define DUMP_VISITED_INFO 5 /* Dump Visited Info. */ #define dump_options glflags.nTrace[DUMP_OPTIONS] #define dump_ranges_info glflags.nTrace[DUMP_RANGES_INFO] #define dump_location_section_info glflags.nTrace[DUMP_LOCATION_SECTION_INFO] #define dump_ranges_section_info glflags.nTrace[DUMP_RANGES_SECTION_INFO] #define dump_linkonce_info glflags.nTrace[DUMP_LINKONCE_INFO] #define dump_visited_info glflags.nTrace[DUMP_VISITED_INFO] /* Section IDs */ #define DEBUG_ABBREV 1 #define DEBUG_ARANGES 2 #define DEBUG_FRAME 3 #define DEBUG_INFO 4 #define DEBUG_LINE 5 #define DEBUG_LOC 6 #define DEBUG_MACINFO 7 #define DEBUG_PUBNAMES 8 #define DEBUG_RANGES 9 #define DEBUG_STATIC_VARS 10 #define DEBUG_STATIC_FUNC 11 #define DEBUG_STR 12 #define DEBUG_WEAKNAMES 13 #define DEBUG_TYPES 14 #define DEBUG_GDB_INDEX 15 #define DEBUG_FRAME_EH_GNU 16 #define DEBUG_MACRO 17 #define DEBUG_NAMES 18 /* Print the information only if unique errors is set and it is first time */ #define PRINTING_UNIQUE (!glflags.gf_found_error_message) dwarfutils-20200114/dwarfdump/globals.h000066400000000000000000000206241361531463500177310ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012-2018 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef globals_INCLUDED #define globals_INCLUDED #ifdef __cplusplus extern "C" { #endif #include "config.h" #ifdef DWARF_WITH_LIBELF /* Without libelf no need for _GNU_SOURCE */ #if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) /* At a certain point libelf.h requires _GNU_SOURCE. here we assume the criteria in configure determined that usefully. */ #define _GNU_SOURCE 1 #endif #endif /* DWARF_WITH_LIBELF */ #include "warningcontrol.h" #define DWARF_SECNAME_BUFFER_SIZE 50 #include #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef DWARF_WITH_LIBELF #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ #ifdef HAVE_LIBELF_H # include #else /* !HAVE_LIBELF_H */ # ifdef HAVE_LIBELF_LIBELF_H # include # endif /* HAVE_LIBELF_LIBELF_H */ #endif /* HAVE_LIB_ELF */ #endif /* DWARF_WITH_LIBELF */ #include "dwarf.h" #include "libdwarf.h" #ifdef HAVE_REGEX #include #endif #include "checkutil.h" #include "defined_types.h" #include "glflags.h" /* Used to try to avoid leakage when we hide errors. */ #define DROP_ERROR_INSTANCE(d,r,e) \ if (r == DW_DLV_ERROR) { \ dwarf_dealloc(d,e,DW_DLA_ERROR); \ e = 0; \ } /* Calculate wasted space */ extern void calculate_attributes_usage(Dwarf_Half attr,Dwarf_Half theform, Dwarf_Unsigned value); extern boolean is_strstrnocase(const char *data, const char *pattern); /* tsearch tree used in macro checking. */ extern void * macro_check_tree; /* DWARF5 macros. */ extern void * macinfo_check_tree; /* DWARF2,3,4 macros */ /* Process TAGs for checking mode and reset pRangesInfo table if appropriate. */ extern void tag_specific_checks_setup(Dwarf_Half val,int die_indent_level); extern void print_error_and_continue (Dwarf_Debug dbg, const char * msg,int res, Dwarf_Error err); extern void print_error (Dwarf_Debug dbg, const char * msg,int res, Dwarf_Error err); extern void print_line_numbers_this_cu (Dwarf_Debug dbg, Dwarf_Die in_die); extern void print_frames (Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame,struct dwconf_s *); extern void printreg(Dwarf_Unsigned reg,struct dwconf_s *config_data); extern void print_ranges (Dwarf_Debug dbg); extern void print_pubnames (Dwarf_Debug dbg); extern void print_macinfo (Dwarf_Debug dbg); extern void print_infos (Dwarf_Debug dbg,Dwarf_Bool is_info); extern void print_locs (Dwarf_Debug dbg); extern void print_abbrevs (Dwarf_Debug dbg); extern void print_strings (Dwarf_Debug dbg); extern void print_aranges (Dwarf_Debug dbg); extern void print_static_funcs(Dwarf_Debug dbg); extern void print_static_vars(Dwarf_Debug dbg); enum type_type_e {SGI_TYPENAME, DWARF_PUBTYPES} ; extern void print_types(Dwarf_Debug dbg,enum type_type_e type_type); extern void print_weaknames(Dwarf_Debug dbg); extern void print_exception_tables(Dwarf_Debug dbg); extern void print_debug_names(Dwarf_Debug dbg); int print_all_pubnames_style_records(Dwarf_Debug dbg, const char * linetitle, const char * section_true_name, Dwarf_Global *globbuf, Dwarf_Signed count, Dwarf_Error *err); /* These three ELF only */ extern void print_object_header(Dwarf_Debug dbg); extern void print_relocinfo (Dwarf_Debug dbg); void clean_up_syms_malloc_data(void); /* Space used to record range information */ extern void allocate_range_array_info(void); extern void release_range_array_info(void); extern void record_range_array_info_entry(Dwarf_Off die_off, Dwarf_Off range_off); extern void check_range_array_info(Dwarf_Debug dbg); boolean should_skip_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die); void get_address_size_and_max(Dwarf_Debug dbg, Dwarf_Half * size, Dwarf_Addr * max, Dwarf_Error *err); /* Returns the producer of the CU */ int get_cu_name(Dwarf_Debug dbg,Dwarf_Die cu_die, Dwarf_Off dieprint_cu_offset, char **short_name,char **long_name); /* Get number of abbreviations for a CU */ extern void get_abbrev_array_info(Dwarf_Debug dbg,Dwarf_Unsigned offset); /* Validate an abbreviation */ extern void validate_abbrev_code(Dwarf_Debug dbg,Dwarf_Unsigned abbrev_code); extern void print_die_and_children( Dwarf_Debug dbg, Dwarf_Die in_die, Dwarf_Off dieprint_cu_offset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt); extern boolean print_one_die( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_offset, boolean print_information, int die_indent_level, char **srcfiles, Dwarf_Signed cnt, boolean ignore_die_stack); /* Check for specific compiler */ extern boolean checking_this_compiler(void); extern void update_compiler_target(const char *producer_name); extern void add_cu_name_compiler_target(char *name); /* General error reporting routines. These were macros for a short time and when changed into functions they kept (for now) their capitalization. The capitalization will likely change. */ extern void PRINT_CU_INFO(void); extern void DWARF_CHECK_COUNT(Dwarf_Check_Categories category, int inc); extern void DWARF_ERROR_COUNT(Dwarf_Check_Categories category, int inc); extern void DWARF_CHECK_ERROR_PRINT_CU(void); #define DWARF_CHECK_ERROR(c,d) DWARF_CHECK_ERROR3(c,d,0,0) #define DWARF_CHECK_ERROR2(c,d,e) DWARF_CHECK_ERROR3(c,d,e,0) extern void DWARF_CHECK_ERROR3(Dwarf_Check_Categories category, const char *str1, const char *str2, const char *strexpl); extern void print_macinfo_by_offset(Dwarf_Debug dbg,Dwarf_Unsigned offset); void ranges_esb_string_destructor(void); void destruct_abbrev_array(void); extern Dwarf_Die current_cu_die_for_print_frames; /* This is an awful hack, making current_cu_die_for_print_frames public. But it enables cleaning up (doing all dealloc needed). */ /* defined in print_sections.c, die for the current compile unit, used in get_fde_proc_name() */ int get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, char *proc_name_buf, int proc_name_buf_len, void **pcMap); extern void dump_block(char *prefix, char *data, Dwarf_Signed len); extern void print_gdb_index(Dwarf_Debug dbg); extern void print_debugfission_index(Dwarf_Debug dbg,const char *type); void clean_up_die_esb(void); void safe_strcpy(char *out, long outlen, const char *in, long inlen); void print_macros_5style_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Bool in_import_list, Dwarf_Unsigned offset); /* Detailed attributes encoding space */ void print_attributes_encoding(Dwarf_Debug dbg); /* Detailed tag and attributes usage */ void print_tag_attributes_usage(Dwarf_Debug dbg); void print_section_groups_data(Dwarf_Debug dbg); void update_section_flags_per_groups(Dwarf_Debug dbg); void groups_restore_subsidiary_flags(void); void print_str_offsets_section(Dwarf_Debug dbg); void print_any_harmless_errors(Dwarf_Debug dbg); void print_secname(Dwarf_Debug dbg,const char *secname); #ifdef __cplusplus } #endif #endif /* globals_INCLUDED */ dwarfutils-20200114/dwarfdump/helpertree.c000066400000000000000000000105611361531463500204370ustar00rootroot00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "helpertree.h" #define TRUE 1 #define FALSE 0 /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ /* For .debug_info (not for tied file) */ struct Helpertree_Base_s helpertree_offsets_base_info; /* For .debug_types (not for tied file) */ struct Helpertree_Base_s helpertree_offsets_base_types; static struct Helpertree_Map_Entry_s * helpertree_map_create_entry(Dwarf_Unsigned offset, int val) { struct Helpertree_Map_Entry_s *mp = (struct Helpertree_Map_Entry_s *) calloc(1,sizeof(struct Helpertree_Map_Entry_s)); if (!mp) { return 0; } mp->hm_key = offset; mp->hm_val = val; return mp; } static void helpertree_map_free_func(void *mx) { struct Helpertree_Map_Entry_s *m = mx; free(m); } static int helpertree_map_compare_func(const void *l, const void *r) { const struct Helpertree_Map_Entry_s *ml = l; const struct Helpertree_Map_Entry_s *mr = r; if (ml->hm_key < mr->hm_key) { return -1; } if (ml->hm_key > mr->hm_key) { return 1; } return 0; } static void helpertree_map_destroy(void *map) { /* tdestroy is not part of Posix. */ dwarf_tdestroy(map,helpertree_map_free_func); } /* Globally-visible functions follow this line. */ struct Helpertree_Map_Entry_s * helpertree_add_entry(Dwarf_Unsigned offset, int val,struct Helpertree_Base_s *base) { void *retval = 0; struct Helpertree_Map_Entry_s *re = 0; struct Helpertree_Map_Entry_s *e; void **tree1 = 0; tree1 = &base->hb_base; e = helpertree_map_create_entry(offset,val); /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,tree1, helpertree_map_compare_func); if (retval) { re = *(struct Helpertree_Map_Entry_s **)retval; if (re != e) { /* We returned an existing record, e not needed. Set val. */ re->hm_val = val; helpertree_map_free_func(e); } else { /* Record e got added to tree1, do not free record e. */ } return retval; } return NULL; } struct Helpertree_Map_Entry_s * helpertree_find(Dwarf_Unsigned offset,struct Helpertree_Base_s *base) { void *retval = 0; struct Helpertree_Map_Entry_s *re = 0; struct Helpertree_Map_Entry_s *e = 0; e = helpertree_map_create_entry(offset,0); retval = dwarf_tfind(e,&base->hb_base, helpertree_map_compare_func); if (retval) { re = *(struct Helpertree_Map_Entry_s **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ helpertree_map_free_func(e); return re; } void helpertree_clear_statistics(struct Helpertree_Base_s *base) { if(!base) { return; } if (!base->hb_base) { return; } helpertree_map_destroy(base->hb_base); base->hb_base = 0; } dwarfutils-20200114/dwarfdump/helpertree.h000066400000000000000000000046761361531463500204560ustar00rootroot00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef HELPERTREE_H #define HELPERTREE_H /* This is a tsearch tree interface we may use in various ways where each different sort of use is a different Helpertree_Base_s instance. */ /* We create Helpertree_Base_s so we can use type-checked calls, not showing the tsearch void* outside of helpertree.c. */ struct Helpertree_Base_s { void * hb_base; }; /* For .debug_info */ extern struct Helpertree_Base_s helpertree_offsets_base_info; /* For .debug_types. */ extern struct Helpertree_Base_s helpertree_offsets_base_types; struct Helpertree_Map_Entry_s { /* Key is offset. It will be a section-global offset so applicable across an entire executable/object section. */ Dwarf_Unsigned hm_key; /* val is something defined differently in different uses. for integer type it is 0 means unknown -1 known signed 1 known unsigned. */ int hm_val; /* Add fields here as needed. */ }; /* Add entry or set to known-signed or known-unsigned. */ struct Helpertree_Map_Entry_s * helpertree_add_entry( Dwarf_Unsigned offset, int val, struct Helpertree_Base_s *helper); /* Look for entry. Use hm_val (if non-null return) to determine signedness. */ struct Helpertree_Map_Entry_s * helpertree_find(Dwarf_Unsigned offset,struct Helpertree_Base_s *helper); void helpertree_clear_statistics(struct Helpertree_Base_s *helper); #endif /* HELPERTREE_H */ dwarfutils-20200114/dwarfdump/helpertree_test.c000066400000000000000000000046021361531463500214750ustar00rootroot00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "helpertree.h" #define TRUE 1 #define FALSE 0 /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ struct Helpertree_Base_s testbase; int main() { struct Helpertree_Map_Entry_s *re = 0; int failcount = 0; /* Test 1 */ re = helpertree_add_entry(0x1000,0,&testbase); if (!re) { printf("FAIL test1\n"); failcount++; } re = helpertree_add_entry(0x2000,0,&testbase); if (!re) { printf("FAIL test2\n"); failcount++; } re = helpertree_find(0x1000,&testbase); if (!re) { printf("FAIL test3\n"); failcount++; } re = helpertree_find(0x2000,&testbase); if (!re) { printf("FAIL test4\n"); failcount++; } re = helpertree_find(0x2004,&testbase); if (re) { printf("FAIL test5\n"); failcount++; } helpertree_clear_statistics(&testbase); if (failcount) { return 1; } printf("PASS helpertree\n"); return 0; } dwarfutils-20200114/dwarfdump/macrocheck.c000066400000000000000000000371551361531463500204070ustar00rootroot00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "macrocheck.h" #define TRUE 1 #define FALSE 0 /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ void * macro_check_tree; /* DWARF5 macros */ void * macinfo_check_tree; /* DWARF 2,3,4 macros */ static struct Macrocheck_Map_Entry_s * macrocheck_map_insert( Dwarf_Unsigned off, unsigned prim,unsigned sec, void **map); static struct Macrocheck_Map_Entry_s * macrocheck_map_find( Dwarf_Unsigned offset, void **map); static void macrocheck_map_destroy(void *map); static Dwarf_Unsigned macro_count_recs(void **base); #ifdef SELFTEST int failcount = 0; #endif /* SELFTEST */ static struct Macrocheck_Map_Entry_s * macrocheck_map_create_entry(Dwarf_Unsigned offset, unsigned add_primary, unsigned add_secondary) { struct Macrocheck_Map_Entry_s *mp = (struct Macrocheck_Map_Entry_s *) calloc(1,sizeof(struct Macrocheck_Map_Entry_s)); if (!mp) { return 0; } mp->mp_key = offset; mp->mp_len = 0; mp->mp_printed = 0; mp->mp_refcount_primary = add_primary; mp->mp_refcount_secondary = add_secondary; return mp; } static void macrocheck_map_free_func(void *mx) { struct Macrocheck_Map_Entry_s *m = mx; free(m); } static int macrocheck_map_compare_func(const void *l, const void *r) { const struct Macrocheck_Map_Entry_s *ml = l; const struct Macrocheck_Map_Entry_s *mr = r; if (ml->mp_key < mr->mp_key) { return -1; } if (ml->mp_key > mr->mp_key) { return 1; } return 0; } static struct Macrocheck_Map_Entry_s * macrocheck_map_insert(Dwarf_Unsigned offset, unsigned add_prim,unsigned add_sec,void **tree1) { void *retval = 0; struct Macrocheck_Map_Entry_s *re = 0; struct Macrocheck_Map_Entry_s *e; e = macrocheck_map_create_entry(offset,add_prim,add_sec); /* tsearch records e's contents unless e is already present . We must not free it till destroy time if it got added to tree1. */ retval = dwarf_tsearch(e,tree1, macrocheck_map_compare_func); if (retval) { re = *(struct Macrocheck_Map_Entry_s **)retval; if (re != e) { /* We returned an existing record, e not needed. Increment refcounts. */ re->mp_refcount_primary += add_prim; re->mp_refcount_secondary += add_sec; macrocheck_map_free_func(e); } else { /* Record e got added to tree1, do not free record e. */ } } return NULL; } static struct Macrocheck_Map_Entry_s * macrocheck_map_find(Dwarf_Unsigned offset,void **tree1) { void *retval = 0; struct Macrocheck_Map_Entry_s *re = 0; struct Macrocheck_Map_Entry_s *e = 0; e = macrocheck_map_create_entry(offset,0,0); retval = dwarf_tfind(e,tree1, macrocheck_map_compare_func); if (retval) { re = *(struct Macrocheck_Map_Entry_s **)retval; } /* The one we created here must be deleted, it is dead. We look at the returned one instead. */ macrocheck_map_free_func(e); return re; } static void macrocheck_map_destroy(void *map) { /* tdestroy is not part of Posix. */ dwarf_tdestroy(map,macrocheck_map_free_func); } void add_macro_import(void **base,Dwarf_Bool is_primary,Dwarf_Unsigned offset) { Dwarf_Unsigned prim_count = 0; Dwarf_Unsigned sec_count = 0; if(is_primary) { prim_count = 1; } else { sec_count = 1; } macrocheck_map_insert(offset,prim_count,sec_count,base); } void add_macro_import_sup(UNUSEDARG void **base, UNUSEDARG Dwarf_Unsigned offset) { /* FIXME */ return; } void add_macro_area_len(void **base, Dwarf_Unsigned offset, Dwarf_Unsigned len) { struct Macrocheck_Map_Entry_s *re = 0; re = macrocheck_map_find(offset,base); if (re) { re->mp_len = len; } } static Dwarf_Unsigned reccount = 0; static void macro_walk_count_recs(UNUSEDARG const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { if (which == dwarf_postorder || which == dwarf_endorder) { return; } reccount += 1; } static Dwarf_Unsigned macro_count_recs(void **base) { reccount = 0; dwarf_twalk(*base,macro_walk_count_recs); return reccount; } static Dwarf_Unsigned lowestoff = 0; static Dwarf_Bool lowestfound = FALSE; static void macro_walk_find_lowest(const void *nodep,const DW_VISIT which, UNUSEDARG const int depth) { struct Macrocheck_Map_Entry_s * re = *(struct Macrocheck_Map_Entry_s**)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } if (!re->mp_printed) { if (lowestfound) { if (lowestoff > re->mp_key) { lowestoff = re->mp_key; } } else { lowestfound = TRUE; lowestoff = re->mp_key; } } } int get_next_unprinted_macro_offset(void **tree, Dwarf_Unsigned * off) { lowestfound = FALSE; lowestoff = 0; /* This walks the tree to find one entry. Which could get slow if the tree has lots of entries. */ dwarf_twalk(*tree,macro_walk_find_lowest); if (!lowestfound) { return DW_DLV_NO_ENTRY; } *off = lowestoff; return DW_DLV_OK; } void mark_macro_offset_printed(void **base, Dwarf_Unsigned offset) { struct Macrocheck_Map_Entry_s *re = 0; re = macrocheck_map_find(offset,base); if (re) { re->mp_printed = TRUE; } } static struct Macrocheck_Map_Entry_s **mac_as_array = 0; static unsigned mac_as_array_next = 0; static void macro_walk_to_array(const void *nodep,const DW_VISIT which, UNUSEDARG const int depth) { struct Macrocheck_Map_Entry_s * re = *(struct Macrocheck_Map_Entry_s**)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } mac_as_array[mac_as_array_next] = re; mac_as_array_next++; } static int qsort_compare(const void *lin, const void *rin) { const struct Macrocheck_Map_Entry_s *l = *(const struct Macrocheck_Map_Entry_s **)lin; const struct Macrocheck_Map_Entry_s *r = *(const struct Macrocheck_Map_Entry_s **)rin; if (l->mp_key < r->mp_key) { return -1; } if (l->mp_key > r->mp_key) { return 1; } if (l->mp_len < r->mp_len) { return -1; } if (l->mp_len > r->mp_len) { return 1; } return 0; } void print_macro_statistics(const char *name,void **tsbase, Dwarf_Unsigned section_size) { Dwarf_Unsigned count = 0; Dwarf_Unsigned lowest = -1ll; Dwarf_Unsigned highest = 0; Dwarf_Unsigned lastend = 0; Dwarf_Unsigned laststart = 0; Dwarf_Unsigned internalgap = 0; Dwarf_Unsigned wholegap = 0; Dwarf_Unsigned i = 0; if(! *tsbase) { return; } count = macro_count_recs(tsbase); if (count < 1) { return; } free(mac_as_array); mac_as_array = 0; mac_as_array_next = 0; mac_as_array = (struct Macrocheck_Map_Entry_s **)calloc(count, sizeof(struct Macrocheck_Map_Entry_s *)); if(!mac_as_array) { #ifdef SELFTEST ++failcount; #endif printf(" Macro checking ERROR %s: " "unable to allocate %" DW_PR_DUu "pointers\n", name, count); return; } dwarf_twalk(*tsbase,macro_walk_to_array); printf(" Macro unit count %s: %" DW_PR_DUu "\n",name,count); qsort(mac_as_array, count,sizeof(struct Macrocheck_Map_Entry_s *), qsort_compare); for (i = 0; i < count ; ++i) { Dwarf_Unsigned end = 0; struct Macrocheck_Map_Entry_s *r = mac_as_array[i]; #if 0 printf("debugging: i %u off 0x%x len 0x%x printed? %u " " ref prim: %u sec: %u\n", (unsigned)i, (unsigned)r->mp_key, (unsigned)r->mp_len, (unsigned)r->mp_printed, (unsigned)r->mp_refcount_primary, (unsigned)r->mp_refcount_secondary); #endif if (r->mp_key < lowest) { lowest = r->mp_key; } end = r->mp_key + r->mp_len; if (end > highest) { highest = end; } if (r->mp_refcount_primary > 1) { #ifdef SELFTEST ++failcount; #endif printf(" ERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is a primary count of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", r->mp_key, r->mp_key, r->mp_refcount_primary, r->mp_refcount_primary); } if (r->mp_refcount_primary && r->mp_refcount_secondary) { #ifdef SELFTEST ++failcount; #endif printf(" ERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is a nonzero primary count of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " with a secondary count of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", r->mp_key, r->mp_key, r->mp_refcount_primary, r->mp_refcount_primary, r->mp_refcount_secondary, r->mp_refcount_secondary); } } lastend = mac_as_array[0]->mp_key + mac_as_array[0]->mp_len; laststart = mac_as_array[0]->mp_key; printf(" Macro Offsets start at 0x%" DW_PR_XZEROS DW_PR_DUx " and end at 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lowest, highest); for (i = 1; i < count ; ++i) { struct Macrocheck_Map_Entry_s *r = mac_as_array[i]; #if 0 printf("debugging i %u off 0x%x len 0x%x\n", (unsigned)i, (unsigned)r->mp_key, (unsigned)r->mp_len); #endif if (r->mp_key > lastend) { internalgap += (r->mp_key - lastend); } else if (r->mp_key < lastend) { /* crazy overlap */ #ifdef SELFTEST ++failcount; #endif printf(" ERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is a crazy overlap with the previous end offset of " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " (previous start offset of 0x%" DW_PR_XZEROS DW_PR_DUx ")" " %" DW_PR_DUu "\n", r->mp_key, r->mp_key, lastend, lastend, laststart, laststart); } laststart = r->mp_key; lastend = laststart + r->mp_len; } /* wholegap is a) starting offset > 0 and b) space after used area before end of section. */ wholegap = mac_as_array[0]->mp_key + internalgap; if (lastend > section_size) { /* Something seriously wrong */ #ifdef SELFTEST ++failcount; #endif printf(" ERROR: For offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu " there is an overlap with the end of section " "0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n",laststart,laststart, lastend, lastend); } else { wholegap += (section_size - lastend); } if(wholegap) { printf(" Macro Offsets internal unused space: " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", internalgap); printf(" Macro Offsets total unused space: " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", wholegap); } free (mac_as_array); mac_as_array = 0; mac_as_array_next = 0; } void clear_macro_statistics(void **tsbase) { if(! *tsbase) { return; } macrocheck_map_destroy(*tsbase); *tsbase = 0; } #ifdef SELFTEST int main() { void * base = 0; Dwarf_Unsigned count = 0; int basefailcount = 0; /* Test 1 */ add_macro_import(&base,TRUE,200); count = macro_count_recs(&base); if (count != 1) { printf("FAIL: expect count 1, got %" DW_PR_DUu "\n",count); ++failcount; } print_macro_statistics("test1",&base,2000); /* Test two */ add_macro_area_len(&base,200,100); add_macro_import(&base,FALSE,350); add_macro_area_len(&base,350,100); count = macro_count_recs(&base); if (count != 2) { printf("FAIL: expect count 2, got %" DW_PR_DUu "\n",count); ++failcount; } print_macro_statistics("test 2",&base,2000); clear_macro_statistics(&base); /* Test three */ basefailcount = failcount; add_macro_import(&base,TRUE,0); add_macro_area_len(&base,0,1000); add_macro_import(&base,FALSE,2000); add_macro_area_len(&base,2000,100); mark_macro_offset_printed(&base,2000); add_macro_import(&base,FALSE,1000); add_macro_area_len(&base,1000,900); add_macro_import(&base,FALSE,1000); add_macro_area_len(&base,1000,900); count = macro_count_recs(&base); if (count != 3) { printf("FAIL: expect count 3, got %" DW_PR_DUu "\n",count); ++failcount; } printf("\n Expect an ERROR about overlap with " "the end of section\n"); print_macro_statistics("test 3",&base,2000); clear_macro_statistics(&base); if ((basefailcount+1) != failcount) { printf("FAIL: Found no error in test 3 checking!\n"); ++failcount; } else { failcount = basefailcount; } /* Test Four */ basefailcount = failcount; add_macro_import(&base,TRUE,50); add_macro_import(&base,TRUE,50); add_macro_area_len(&base,50,50); add_macro_import(&base,FALSE,200); add_macro_import(&base,FALSE,50); add_macro_import(&base,FALSE,60); add_macro_area_len(&base,60,10); printf( "\n Expect an ERROR about offset 50 having 2 primaries\n"); printf( " and Expect an ERROR about offset 50 having 2\n" " primaries" " and a secondary\n"); printf( " and Expect an ERROR about crazy overlap 60\n\n"); print_macro_statistics("test 4",&base,2000); clear_macro_statistics(&base); if ((basefailcount + 3) != failcount) { printf("FAIL: Found wrong errors in test 4 checking!\n"); } else { failcount = basefailcount; } if (failcount > 0) { printf("FAIL macrocheck selftest\n"); exit(1); } printf("PASS macrocheck selftest\n"); return 0; } #endif /* SELFTEST */ dwarfutils-20200114/dwarfdump/macrocheck.h000066400000000000000000000040171361531463500204030ustar00rootroot00000000000000/* Copyright 2015-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef MACROCHECK_H #define MACROCHECK_H struct Macrocheck_Map_Entry_s { Dwarf_Unsigned mp_key; /* Key is offset */ Dwarf_Unsigned mp_len; /* len in bytes off this macro set */ /* We count number of uses. More than 1 primary is an error. Both primary and secondary is ok or error? */ Dwarf_Unsigned mp_refcount_primary; Dwarf_Unsigned mp_refcount_secondary; /* So we go through each one just once. */ Dwarf_Bool mp_printed; }; void add_macro_import(void **base,Dwarf_Bool is_primary, Dwarf_Unsigned offset); void add_macro_import_sup(void **base,Dwarf_Unsigned offset); void add_macro_area_len(void **base, Dwarf_Unsigned offset, Dwarf_Unsigned len); int get_next_unprinted_macro_offset(void **base, Dwarf_Unsigned * off); void mark_macro_offset_printed(void **base, Dwarf_Unsigned offset); void print_macro_statistics(const char *name,void **basep, Dwarf_Unsigned section_size); void clear_macro_statistics(void **basep); #endif /* MACROCHECK_H */ dwarfutils-20200114/dwarfdump/makename.c000066400000000000000000000066071361531463500200640ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright(C) David Anderson 2016-2019. All Rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. makename.c $Revision: 1.4 $ $Date: 2005/11/08 21:48:42 $ This used to be elaborate stuff. Now it is trivial, as duplicating names is unimportant in dwarfdump (in general). And in fact, this is only called for attributes and tags etc whose true name is unknown. Not for any normal case. */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "makename.h" #include "globals.h" #if defined(__WIN32) && (!defined(__GNUC__) && !defined(__clang__)) #pragma warning(disable:4996) /* Warning when migrated to VS2010 */ #endif /* _WIN32 */ #define TRUE 1 #define FALSE 0 static void * makename_data; #define VALTYPE char * static int value_compare_func(const void *l, const void *r) { VALTYPE ml = (VALTYPE)l; VALTYPE mr = (VALTYPE)r; return strcmp(ml,mr); } /* Nothing to free for the 'value' example. */ static void value_node_free(void *valp) { VALTYPE v = (VALTYPE)valp; free(v); } void makename_destructor(void) { dwarf_tdestroy(makename_data,value_node_free); makename_data = 0; } /* WARNING: the tree walk functions will, if presented **tree when *tree is wanted, simply find nothing. No error, just bad results. So when a walk produces nothing suspect a code mistake here. The basic problem is void* is a terrible way to pass in a pointer. But it's how tsearch was defined long ago. */ char * makename(const char *s) { char *newstr = 0; VALTYPE re = 0; void *retval = 0; if (!s) { return ""; } newstr = (char *)strdup(s); retval = dwarf_tfind(newstr,&makename_data, value_compare_func); if (retval) { /* We found our string, it existed already. */ re = *(VALTYPE *)retval; free(newstr); return re; } retval = dwarf_tsearch(newstr,&makename_data, value_compare_func); if (!retval) { /* Out of memory, lets just use the string we dup'd and let it leak. Things will surely fail anyway. */ return newstr; } re = *(VALTYPE *)retval; return re; } dwarfutils-20200114/dwarfdump/makename.h000066400000000000000000000034431361531463500200640ustar00rootroot00000000000000#ifndef names_h #define names_h /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2016 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* makename.h $Revision: 1.3 $ $Date: 2004/10/28 22:26:58 $ This is for putting strings into stable storage. Effectively an strdup() wrapper. Rarely called. It leaks memory, (the memory is never freed) but that seems unimportant since use of this is very rare. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ char * makename(const char *); /* Makes a copy of the string in a malloc area. Can never return 0. */ /* Destroy all makename data. Do just before exit. */ void makename_destructor(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MAKENAME_H */ dwarfutils-20200114/dwarfdump/makename_test.c000066400000000000000000000052571361531463500211230ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright(C) David Anderson 2016. All Rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. makename.c $Revision: 1.4 $ $Date: 2005/11/08 21:48:42 $ This used to be elaborate stuff. Now it is trivial, as duplicating names is unimportant in dwarfdump (in general). And in fact, this is only called for attributes and tags etc whose true name is unknown. Not for any normal case. */ #include "config.h" #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "makename.h" #include "globals.h" #if defined(__WIN32) && (!defined(__GNUC__) && !defined(__clang__)) #pragma warning(disable:4996) /* Warning when migrated to VS2010 */ #endif /* _WIN32 */ #define TRUE 1 #define FALSE 0 #if 0 static void * makename_data; #endif #define VALTYPE char * #define DW_TSHASHTYPE uintptr_t char *samples[] = { "abcd", "efgh", "a", "abcd", 0 }; int main() { char *e1 = 0; char *e2= 0; char *e3= 0; char *e4= 0; int errct = 0; e1 = makename(samples[0]); e2 = makename(samples[1]); e3 = makename(samples[2]); e4 = makename(samples[3]); if (e1 != e4) { printf(" FAIL. mismatch pointers\n"); ++errct; } if (e1 == e2 ) { printf(" FAIL. match pointers\n"); ++errct; } if ( e1 == e3) { printf(" FAIL. match pointers\n"); ++errct; } if (errct) { exit(1); } printf("PASS makename test\n"); return 0; } dwarfutils-20200114/dwarfdump/naming.c000066400000000000000000000206251361531463500175530ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2012 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 and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ /* naming.c */ #include "globals.h" #include "dwarf.h" #include "libdwarf.h" #include "makename.h" #include "naming.h" #include "esb.h" #ifndef TRIVIAL_NAMING static const char * skipunder(const char *v) { const char *cp = v; int undercount = 0; for (; *cp ; ++cp) { if (*cp == '_') { ++undercount; if (undercount == 2) { return cp+1; } } } return ""; } #endif /* TRIVIAL_NAMING */ static const char * ellipname(int res, int val_in, const char *v,const char *ty,int printonerr) { #ifndef TRIVIAL_NAMING if (glflags.gf_check_dwarf_constants && checking_this_compiler()) { DWARF_CHECK_COUNT(dwarf_constants_result,1); } #endif if (res != DW_DLV_OK) { char buf[100]; char *n; #ifdef ORIGINAL_SPRINTF snprintf(buf,sizeof(buf),"",ty,val_in); #else struct esb_s eb; esb_constructor_fixed(&eb,buf,sizeof(buf)); esb_append_printf_s(&eb, "",val_in); #endif /* Capture any name error in DWARF constants */ #ifndef TRIVIAL_NAMING if (printonerr && glflags.gf_check_dwarf_constants && checking_this_compiler()) { if (glflags.gf_check_verbose_mode) { fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. " "Continuing. \n",ty,val_in,val_in ); } DWARF_ERROR_COUNT(dwarf_constants_result,1); DWARF_CHECK_ERROR_PRINT_CU(); } #else /* This is for the tree-generation, not dwarfdump itself. */ if (printonerr) { fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. " "Continuing. \n",ty,val_in,val_in ); } #endif #ifdef ORIGINAL_SPRINTF n = makename(buf); #else n = makename(esb_get_string(&eb)); esb_destructor(&eb); #endif return n; } #ifndef TRIVIAL_NAMING if (glflags.ellipsis) { return skipunder(v); } #endif return v; } const char * get_TAG_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_TAG_name(val_in,&v); return ellipname(res,val_in,v,"TAG",printonerr); } const char * get_children_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_children_name(val_in,&v); return ellipname(res,val_in,v,"children",printonerr); } const char * get_FORM_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_FORM_name(val_in,&v); return ellipname(res,val_in,v,"FORM",printonerr); } const char * get_AT_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_AT_name(val_in,&v); return ellipname(res,val_in,v,"AT",printonerr); } const char * get_OP_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_OP_name(val_in,&v); return ellipname(res,val_in,v,"OP",printonerr); } const char * get_ATE_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ATE_name(val_in,&v); return ellipname(res,val_in,v,"ATE",printonerr); } const char * get_DS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_DS_name(val_in,&v); return ellipname(res,val_in,v,"DS",printonerr); } const char * get_END_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_END_name(val_in,&v); return ellipname(res,val_in,v,"END",printonerr); } const char * get_ATCF_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ATCF_name(val_in,&v); return ellipname(res,val_in,v,"ATCF",printonerr); } const char * get_ACCESS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ACCESS_name(val_in,&v); return ellipname(res,val_in,v,"ACCESS",printonerr); } const char * get_VIS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_VIS_name(val_in,&v); return ellipname(res,val_in,v,"VIS",printonerr); } const char * get_VIRTUALITY_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_VIRTUALITY_name(val_in,&v); return ellipname(res,val_in,v,"VIRTUALITY",printonerr); } const char * get_LANG_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_LANG_name(val_in,&v); return ellipname(res,val_in,v,"LANG",printonerr); } const char * get_ID_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ID_name(val_in,&v); return ellipname(res,val_in,v,"ID",printonerr); } const char * get_CC_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_CC_name(val_in,&v); return ellipname(res,val_in,v,"CC",printonerr); } const char * get_INL_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_INL_name(val_in,&v); return ellipname(res,val_in,v,"INL",printonerr); } const char * get_ORD_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ORD_name(val_in,&v); return ellipname(res,val_in,v,"ORD",printonerr); } const char * get_DSC_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_DSC_name(val_in,&v); return ellipname(res,val_in,v,"DSC",printonerr); } const char * get_LNS_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_LNS_name(val_in,&v); return ellipname(res,val_in,v,"LNS",printonerr); } const char * get_LNE_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_LNE_name(val_in,&v); return ellipname(res,val_in,v,"LNE",printonerr); } const char * get_MACINFO_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_MACINFO_name(val_in,&v); return ellipname(res,val_in,v,"MACINFO",printonerr); } const char * get_MACRO_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_MACRO_name(val_in,&v); return ellipname(res,val_in,v,"MACRO",printonerr); } const char * get_CFA_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_CFA_name(val_in,&v); return ellipname(res,val_in,v,"CFA",printonerr); } const char * get_EH_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_EH_name(val_in,&v); return ellipname(res,val_in,v,"EH",printonerr); } const char * get_FRAME_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_FRAME_name(val_in,&v); return ellipname(res,val_in,v,"FRAME",printonerr); } const char * get_CHILDREN_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_CHILDREN_name(val_in,&v); return ellipname(res,val_in,v,"CHILDREN",printonerr); } const char * get_ADDR_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_ADDR_name(val_in,&v); return ellipname(res,val_in,v,"ADDR",printonerr); } dwarfutils-20200114/dwarfdump/naming.h000066400000000000000000000062721361531463500175620ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* naming.h */ #ifndef NAMING_H_INCLUDED #define NAMING_H_INCLUDED #ifdef __cplusplus extern "C" { #endif extern const char * get_TAG_name(unsigned int val_in,int printonerr); extern const char * get_children_name(unsigned int val_in,int printonerr); extern const char * get_FORM_name(unsigned int val_in,int printonerr); extern const char * get_AT_name(unsigned int val_in,int printonerr); extern const char * get_OP_name(unsigned int val_in,int printonerr); extern const char * get_ATE_name(unsigned int val_in,int printonerr); extern const char * get_DS_name(unsigned int val_in,int printonerr); extern const char * get_END_name(unsigned int val_in,int printonerr); extern const char * get_ATCF_name(unsigned int val_in,int printonerr); extern const char * get_ACCESS_name(unsigned int val_in,int printonerr); extern const char * get_VIS_name(unsigned int val_in,int printonerr); extern const char * get_VIRTUALITY_name(unsigned int val_in,int printonerr); extern const char * get_LANG_name(unsigned int val_in,int printonerr); extern const char * get_ID_name(unsigned int val_in,int printonerr); extern const char * get_CC_name(unsigned int val_in,int printonerr); extern const char * get_INL_name(unsigned int val_in,int printonerr); extern const char * get_ORD_name(unsigned int val_in,int printonerr); extern const char * get_DSC_name(unsigned int val_in,int printonerr); extern const char * get_LNS_name(unsigned int val_in,int printonerr); extern const char * get_LNE_name(unsigned int val_in,int printonerr); extern const char * get_MACINFO_name(unsigned int val_in,int printonerr); extern const char * get_MACRO_name(unsigned int val_in,int printonerr); extern const char * get_CFA_name(unsigned int val_in,int printonerr); extern const char * get_EH_name(unsigned int val_in,int printonerr); extern const char * get_FRAME_name(unsigned int val_in,int printonerr); extern const char * get_CHILDREN_name(unsigned int val_in,int printonerr); extern const char * get_ADDR_name(unsigned int val_in,int printonerr); #ifdef __cplusplus } #endif #endif /* NAMING_H_INCLUDED */ dwarfutils-20200114/dwarfdump/print_abbrevs.c000066400000000000000000000752531361531463500211510ustar00rootroot00000000000000 /* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #include "naming.h" #include "sanitized.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #define TRUE 1 #define FALSE 0 /* The following relevent for one specific Linker. */ #define SNLINKER_MAX_ATTRIB_COUNT 16 /* a warning limit which is arbitrary but leaves a bit more flexibility. */ #define GENERAL_MAX_ATTRIB_COUNT 32 /* Print data in .debug_abbrev This is inherently unsafe as it assumes there are no byte sequences in .debug_abbrev other than legal abbrev sequences. But the Dwarf spec does not promise that. The spec only promises that any bytes at an offset referred to from .debug_info are legal sequences. */ struct abbrev_entry_s { Dwarf_Unsigned ae_number; Dwarf_Unsigned ae_offset; Dwarf_Unsigned ae_attr; Dwarf_Unsigned ae_form; Dwarf_Unsigned ae_impl_const; unsigned ae_dupcount; }; static int ab_compare(const void *lin, const void *rin) { const struct abbrev_entry_s *l = (const struct abbrev_entry_s *)lin; const struct abbrev_entry_s *r = (const struct abbrev_entry_s *)rin; if (l->ae_attr < r->ae_attr) { return -1; } if (l->ae_attr > r->ae_attr) { return 1; } if (l->ae_form < r->ae_form) { return -1; } if (l->ae_form > r->ae_form) { return 1; } if (l->ae_number < r->ae_number) { return -1; } if (l->ae_number > r->ae_number) { return 1; } return 0; } static int attr_unknown(Dwarf_Unsigned attr) { const char *n = 0; int res = 0; if (!attr) { return TRUE; } if (attr <= DW_AT_loclists_base) { return FALSE; } if (attr > DW_AT_hi_user) { return TRUE; } res = dwarf_get_AT_name(attr,&n); if (res == DW_DLV_NO_ENTRY) { return TRUE; } return FALSE; } static int is_valid_form_we_know(Dwarf_Unsigned form) { int res = 0; const char *n = 0; res = dwarf_get_FORM_name(form,&n); if (res == DW_DLV_NO_ENTRY) { return FALSE; } return TRUE; } static void printdupab(struct abbrev_entry_s * lastaep) { struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "Attribute " "0x%" DW_PR_XZEROS DW_PR_DUx , lastaep->ae_attr); esb_append_printf_s(&msg, " (%s)", get_AT_name(lastaep->ae_attr, dwarf_names_print_on_error)); esb_append_printf_u(&msg, " %u times", lastaep->ae_dupcount); esb_append_printf_u(&msg, " near offset " "0x%" DW_PR_XZEROS DW_PR_DUx ".", lastaep->ae_offset); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&msg), "Duplicated attribute in abbrevs "); esb_destructor(&msg); } extern void print_abbrevs(Dwarf_Debug dbg) { Dwarf_Abbrev ab; Dwarf_Unsigned offset = 0; Dwarf_Off off = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned abbrev_num = 1; Dwarf_Signed child_flag = 0; int abres = 0; int tres = 0; int acres = 0; Dwarf_Error paerr = 0; unsigned loopct = 0; char const_integer_string[60]; glflags.current_section_id = DEBUG_ABBREV; for (loopct = 0; ; ++loopct) { const char *tagname = ""; struct abbrev_entry_s *entryarray =0; unsigned entryarray_size = 0; Dwarf_Unsigned abbrev_entry_count = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Half tag = 0; Dwarf_Unsigned length = 0; abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &abbrev_entry_count, &paerr); if (!loopct) { /* Do this here (not before the loop) so the section is loaded and uncompressed if necessary. We get information printed about the compression (if any) this way. */ print_secname(dbg,".debug_abbrev"); } if (abres == DW_DLV_ERROR) { print_error_and_continue(dbg, "Error reading abbreviations", abres, paerr); return; } if (abres == DW_DLV_NO_ENTRY) { return; } /* Here offset is the global offset in .debug_abbrev. The abbrev_num is a relatively worthless counter of all abbreviations. */ tres = dwarf_get_abbrev_tag(ab, &tag, &paerr); if (tres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "Error reading abbreviation Tag", tres, paerr); } tres = dwarf_get_abbrev_code(ab, &abbrev_code, &paerr); if (tres != DW_DLV_OK) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error_and_continue(dbg, "Error reading abbreviation code", tres, paerr); } if (!tag) { tagname = "Abbrev 0: null abbrev entry"; } else { tagname = get_TAG_name(tag,dwarf_names_print_on_error); } if ( glflags.gf_do_print_dwarf) { if (glflags.dense) { printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx ">", abbrev_num, offset,abbrev_code); if (glflags.verbose) { printf("", length); } printf(" %s", tagname); } else { printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx ">", abbrev_num, offset, abbrev_code); if (glflags.verbose) { printf("", length); } printf(" %-27s", tagname); } } /* Process specific TAGs specially. */ tag_specific_checks_setup(tag,0); ++abbrev_num; acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &paerr); if (acres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "Error reading abbreviation children flag", acres, paerr); return; } if (acres == DW_DLV_NO_ENTRY) { child_flag = 0; } /* If tag is zero, it is a null byte, not a real abbreviation, so there is no 'children' flag to print. */ if (tag && glflags.gf_do_print_dwarf) { const char * child_name = 0; child_name = get_children_name(child_flag, dwarf_names_print_on_error); printf(" %s", child_name); } if(!glflags.dense) { if ( glflags.gf_do_print_dwarf) { printf("\n"); } } if (abbrev_entry_count < 1) { if(tag) { printf(" This abbreviation code has no entries\n"); } if (length == 0 || length == 1 ) { if ( glflags.gf_do_print_dwarf && glflags.dense ) { printf("\n"); } if (!length) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); break; } } /* printed null abrev name above */ offset += length; dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); continue; } /* Abbrev contains the format of a die, which debug_info then points to with the real data. So here we just print the given format. */ entryarray_size = abbrev_entry_count; entryarray = calloc(entryarray_size, sizeof(struct abbrev_entry_s)); if (!entryarray) { printf( "%s ERROR: Malloc of %u abbrev_entry_s" " structs failed. Near section global offset 0x%" DW_PR_DUx " .\n", glflags.program_name,entryarray_size,offset); entryarray_size = 0; } for (i = 0; i < abbrev_entry_count ; i++) { int aeres = 0; Dwarf_Bool dofilter = FALSE; Dwarf_Unsigned form = 0; struct abbrev_entry_s *aep = entryarray+i; Dwarf_Unsigned attr = 0; Dwarf_Signed impl_const = 0; aeres = dwarf_get_abbrev_entry_b(ab, i, dofilter,&attr, &form,&impl_const, &off, &paerr); if (aeres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); free(entryarray); print_error(dbg, "Error reading abbreviation entry", aeres, paerr); } aep->ae_number = i; aep->ae_attr = attr; aep->ae_form = form; aep->ae_offset = off; aep->ae_impl_const = impl_const; if (glflags.gf_do_print_dwarf) { const_integer_string[0] = 0; if (form == DW_FORM_implicit_const) { sprintf(const_integer_string, " <%" DW_PR_DSd " (0x%" DW_PR_DUx ")>",impl_const,impl_const); } if (glflags.dense) { printf(" <%ld>%s<%s>%s", (unsigned long) off, get_AT_name(attr,dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error), const_integer_string); } else if (!const_integer_string[0]) { printf(" <0x%08lx> %-28s%s\n", (unsigned long) off, get_AT_name(attr, dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error)); } else { printf(" <0x%08lx> %-28s%-20s%s\n", (unsigned long) off, get_AT_name(attr, dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error), const_integer_string); } } } if (glflags.gf_check_abbreviations && entryarray_size > 0) { unsigned l = 0; struct abbrev_entry_s *lastaep = 0; DWARF_CHECK_COUNT(abbreviations_result,1); qsort((void *)entryarray,entryarray_size, sizeof(struct abbrev_entry_s),ab_compare); for(l = 0; l < entryarray_size ; ++l) { struct abbrev_entry_s *aep = entryarray+l; if (attr_unknown(aep->ae_attr) ) { struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "Attribute " "0x%" DW_PR_XZEROS DW_PR_DUx , aep->ae_attr); esb_append_printf_u(&msg, " near offset " "0x%" DW_PR_XZEROS DW_PR_DUx "." , aep->ae_offset); DWARF_CHECK_ERROR2(abbreviations_result, "Attr number unknown", esb_get_string(&msg)); esb_destructor(&msg); } if (!is_valid_form_we_know(aep->ae_form)){ struct esb_s msg; esb_constructor(&msg); esb_append_printf_u(&msg, "Form " "0x%" DW_PR_XZEROS DW_PR_DUx, aep->ae_form); esb_append_printf_u(&msg, " near offset " "0x%" DW_PR_XZEROS DW_PR_DUx ".", aep->ae_offset); DWARF_CHECK_ERROR2(abbreviations_result, "Form number unknown", esb_get_string(&msg)); esb_destructor(&msg); } if (l == 0) { lastaep = aep; } else if (lastaep->ae_attr == aep->ae_attr) { lastaep->ae_dupcount++; } else { if (lastaep->ae_dupcount) { printdupab(lastaep); } lastaep = aep; } } if (lastaep->ae_dupcount) { printdupab(lastaep); } } dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); free(entryarray); entryarray = 0; entryarray_size = 0; offset += length; if (glflags.gf_do_print_dwarf && glflags.dense) { printf("\n"); } } } /* Abbreviations array info for checking abbrev tags. The [zero] entry is not used. We never shrink the array, but it never grows beyond the largest abbreviation count of all the CUs. It is set up when we start a new CU and used to validate abbreviations on each DIE in the CU. See print_die.c */ static Dwarf_Unsigned *abbrev_array = NULL; /* Size of the array, the same as the abbrev tag count of the CU with the most of them. Be careful as abbrev_array[abbrev_array_size] is outside the high bound. */ static Dwarf_Unsigned abbrev_array_size = 0; #define ABBREV_ARRAY_INITIAL_SIZE 64 void destruct_abbrev_array(void) { free(abbrev_array); abbrev_array = 0; abbrev_array_size = 0; } /* Normally abbreviation numbers are allocated in sequence from 1 and increase by 1 but in case of a compiler bug or a damaged object file one can see strange things. This looks for surprises and reports them. Returns the abbrev_code unless the value looks very wrong, and then it returns zero as we do not want a gigantic abbrev code to cause trouble. */ static Dwarf_Unsigned check_abbrev_num_sequence(Dwarf_Unsigned abbrev_code, Dwarf_Unsigned last_abbrev_code, UNUSEDARG Dwarf_Unsigned l_abbrev_array_size, UNUSEDARG Dwarf_Unsigned abbrev_entry_count, UNUSEDARG Dwarf_Unsigned total_abbrevs_counted) { char buf[128]; DWARF_CHECK_COUNT(abbreviations_result,1); if (abbrev_code > last_abbrev_code) { if ((abbrev_code-last_abbrev_code) > 100 ) { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " skips up by %" DW_PR_DUu " from last abbrev code of %" DW_PR_DUu , abbrev_code, (abbrev_code-last_abbrev_code), last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Questionable abbreviation code! Not checking reuse."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, " skips up by %" DW_PR_DUu, (abbrev_code-last_abbrev_code)); esb_append_printf_u(&ar, " from last abbrev code of %" DW_PR_DUu , last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code! Not checking reuse."); esb_destructor(&ar); #endif return 0; } else if ((abbrev_code-last_abbrev_code) > 1 ) { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " skips up by %" DW_PR_DUu " from last abbrev code of %" DW_PR_DUu , abbrev_code, (abbrev_code-last_abbrev_code), last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Questionable abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " skips up by %" DW_PR_DUu, (abbrev_code-last_abbrev_code)); esb_append_printf_u(&ar, " from last abbrev code of %" DW_PR_DUu , last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); #endif } } else if (abbrev_code < last_abbrev_code) { #ifdef ORIGINAL_SPRINT snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " skips down by %" DW_PR_DUu " from last abbrev code of %" DW_PR_DUu , abbrev_code, (last_abbrev_code - abbrev_code), last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Questionable abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, " skips down by %" DW_PR_DUu, (last_abbrev_code - abbrev_code)); esb_append_printf_u(&ar, " from last abbrev code of %" DW_PR_DUu , last_abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " unchanged from last abbrev code!.", abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Questionable abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu " unchanged from last abbrev code!.", abbrev_code); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); #endif } return abbrev_code; } static void check_reused_code(Dwarf_Unsigned abbrev_code, Dwarf_Unsigned abbrev_entry_count) { char buf[128]; if (abbrev_code >= abbrev_array_size) { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " entry_count unchecked: %" DW_PR_DUu " ", abbrev_code,abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Questionable abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " entry_count unchecked: %" DW_PR_DUu " ", abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); #endif return; } if (abbrev_array[abbrev_code]) { DWARF_CHECK_COUNT(abbreviations_result,1); /* This abbrev code slot was used before. */ if (abbrev_array[abbrev_code] == abbrev_entry_count) { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " reused for same entry_count: %" DW_PR_DUu " ", abbrev_code,abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Questionable abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " reused for same entry_count: %" DW_PR_DUu " ", abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Questionable abbreviation code."); esb_destructor(&ar); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " reused for different entry_count. " " %" DW_PR_DUu " now %" DW_PR_DUu " ", abbrev_code, abbrev_array[abbrev_code], abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Invalid abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " reused for different entry_count. " " %" DW_PR_DUu , abbrev_array[abbrev_code]); esb_append_printf_u(&ar, " now %" DW_PR_DUu " ", abbrev_entry_count); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Invalid abbreviation code."); esb_destructor(&ar); #endif } } } /* Calculate the number of abbreviations for the current CU and set up basic abbreviations array info, storing the number of attributes per abbreviation */ void get_abbrev_array_info(Dwarf_Debug dbg, Dwarf_Unsigned offset_in) { Dwarf_Unsigned offset = offset_in; if (glflags.gf_check_abbreviations) { Dwarf_Abbrev ab = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned abbrev_entry_count = 0; Dwarf_Unsigned abbrev_code; int abres = DW_DLV_OK; Dwarf_Error aberr = 0; Dwarf_Unsigned last_abbrev_code = 0; Dwarf_Bool bMore = TRUE; Dwarf_Unsigned CU_abbrev_count = 0; if (abbrev_array == NULL) { /* Allocate initial abbreviation array info */ abbrev_array_size = ABBREV_ARRAY_INITIAL_SIZE; abbrev_array = (Dwarf_Unsigned *) calloc(abbrev_array_size,sizeof(Dwarf_Unsigned)); } else { /* Clear out values from previous CU */ memset((void *)abbrev_array,0, (abbrev_array_size) * sizeof(Dwarf_Unsigned)); } while (bMore && (abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &abbrev_entry_count, &aberr)) == DW_DLV_OK) { dwarf_get_abbrev_code(ab,&abbrev_code,&aberr); if (abbrev_code == 0) { /* End of abbreviation table for this CU */ ++offset; /* Skip abbreviation code */ bMore = FALSE; } else { /* Valid abbreviation code. We hope. */ if (abbrev_code > 0) { Dwarf_Unsigned abhigh = check_abbrev_num_sequence( abbrev_code, last_abbrev_code, abbrev_array_size,abbrev_entry_count, CU_abbrev_count); if (abhigh >= abbrev_array_size) { /* It is a new high, but is not outrageous. */ while (abbrev_code >= abbrev_array_size) { Dwarf_Unsigned old_size = abbrev_array_size; size_t addl_size_bytes = old_size * sizeof(Dwarf_Unsigned); /* Resize abbreviation array. Only a bogus abbreviation number will iterate more than once. The abhigh check. prevents a runaway. */ abbrev_array_size *= 2; abbrev_array = (Dwarf_Unsigned *) realloc(abbrev_array, abbrev_array_size * sizeof(Dwarf_Unsigned)); /* Zero out the new bytes. */ memset(abbrev_array + old_size,0, addl_size_bytes); } last_abbrev_code = abbrev_code; check_reused_code(abbrev_code, abbrev_entry_count); abbrev_array[abbrev_code] = abbrev_entry_count; } else { /* Zero is the case of 'too high' abbev_code. */ if (abhigh > 0) { /* More or less normal abbrev_code. */ last_abbrev_code = abbrev_code; check_reused_code(abbrev_code, abbrev_entry_count); abbrev_array[abbrev_code] = abbrev_entry_count; } } ++CU_abbrev_count; offset += length; } else { /* Invalid abbreviation code */ print_error(dbg, "get_abbrev_array_info", abres, aberr); last_abbrev_code = abbrev_code; } } dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); } } } /* Validate an abbreviation for the current CU. In case of bogus abbrev input the CU_abbrev_count might not be as large as abbrev_array_size says the array is. This should catch that case. */ void validate_abbrev_code(UNUSEDARG Dwarf_Debug dbg, Dwarf_Unsigned abbrev_code) { char buf[128]; DWARF_CHECK_COUNT(abbreviations_result,1); if (abbrev_code && abbrev_code >= abbrev_array_size) { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu " outside valid range of [0-%" DW_PR_DUu "]", abbrev_code,abbrev_array_size); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Invalid abbreviation code."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu, abbrev_code); esb_append_printf_u(&ar, " outside valid range of [0-%" DW_PR_DUu "]", abbrev_array_size); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Invalid abbreviation code."); esb_destructor(&ar); #endif } else { Dwarf_Unsigned abbrev_entry_count = abbrev_array[abbrev_code]; if (abbrev_entry_count > SNLINKER_MAX_ATTRIB_COUNT) { if (abbrev_entry_count > GENERAL_MAX_ATTRIB_COUNT) { #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu ", with %" DW_PR_DUu " attributes: " "outside a sanity-check maximum of %d.", abbrev_code, abbrev_entry_count, GENERAL_MAX_ATTRIB_COUNT); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Number of attributes exceeds sanity check"); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, ", with %" DW_PR_DUu " attributes: ", abbrev_entry_count); esb_append_printf_i(&ar, "outside a sanity-check maximum of %d.", GENERAL_MAX_ATTRIB_COUNT); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Number of attributes exceeds sanity check"); esb_destructor(&ar); #endif } else { /* These apply only to one compiliation environment, and are not generally applicable. */ #ifdef ORIGINAL_SPRINTF snprintf(buf, sizeof(buf), "Abbrev code %" DW_PR_DUu ", with %" DW_PR_DUu " attributes: " "outside an SN-LINKER expected-maximum of %d.", abbrev_code, abbrev_entry_count, SNLINKER_MAX_ATTRIB_COUNT); DWARF_CHECK_ERROR2(abbreviations_result,buf, "Number of attributes exceeds " "SN-LINKER-specific sanity check."); #else struct esb_s ar; esb_constructor_fixed(&ar,buf,sizeof(buf)); esb_append_printf_u(&ar, "Abbrev code %" DW_PR_DUu,abbrev_code); esb_append_printf_u(&ar, ", with %" DW_PR_DUu " attributes: ", abbrev_entry_count); esb_append_printf_i(&ar, "outside an SN-LINKER expected-maximum of %d.", SNLINKER_MAX_ATTRIB_COUNT); DWARF_CHECK_ERROR2(abbreviations_result, esb_get_string(&ar), "Number of attributes exceeds " "SN-LINKER-specific sanity check."); esb_destructor(&ar); #endif } } } } dwarfutils-20200114/dwarfdump/print_aranges.c000066400000000000000000000264771361531463500211510ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" static void do_checking(Dwarf_Debug dbg, Dwarf_Arange *arange_buf,Dwarf_Signed i, Dwarf_Off cu_die_offset,Dwarf_Bool first_cu, Dwarf_Off cu_die_offset_prev, Dwarf_Die cu_die ) { int dres = 0; Dwarf_Off cuhdroff = 0; Dwarf_Off cudieoff3 = 0; Dwarf_Error checking_err = 0; /* .debug_types has no address ranges, only .debug_info[.dwo] has them.*/ int is_info = 1; dres = dwarf_get_arange_cu_header_offset( arange_buf[i],&cuhdroff,&checking_err); if (dres == DW_DLV_OK) { Dwarf_Off cudieoff2 = 0; /* Get the CU offset for easy error reporting */ if (first_cu || cu_die_offset != cu_die_offset_prev) { dres = dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,&checking_err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_die_offsets", dres, checking_err); } } dres = dwarf_get_cu_die_offset_given_cu_header_offset_b( dbg,cuhdroff,is_info,&cudieoff2,&checking_err); if (dres == DW_DLV_OK) { /* Get the CU offset for easy error reporting */ dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,&checking_err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; DWARF_CHECK_COUNT(aranges_result,1); if (cu_die_offset != cudieoff2) { printf("Error, cu_die offsets mismatch, 0x%" DW_PR_DUx " != 0x%" DW_PR_DUx " from arange data", cu_die_offset,cudieoff2); DWARF_CHECK_ERROR(aranges_result, " dwarf_get_cu_die_offset_given_cu..." " gets wrong offset"); } } else { print_error(dbg, "dwarf_get_cu_die_offset_given...", dres, checking_err); } } else { print_error(dbg, "dwarf_get_arange_cu_header_offset", dres, checking_err); } dres = dwarf_get_cu_die_offset(arange_buf[i],&cudieoff3, &checking_err); if (dres == DW_DLV_OK) { DWARF_CHECK_COUNT(aranges_result,1); if (cudieoff3 != cu_die_offset) { printf( "Error, cu_die offsets (b) mismatch , 0x%" DW_PR_DUx " != 0x%" DW_PR_DUx " from arange data", cu_die_offset,cudieoff3); DWARF_CHECK_ERROR(aranges_result, " dwarf_get_cu_die_offset " " gets wrong offset"); } } else { print_error(dbg, "dwarf_get_cu_die_offset failed ", dres,checking_err); } } /* get all the data in .debug_aranges */ extern void print_aranges(Dwarf_Debug dbg) { Dwarf_Signed count = 0; Dwarf_Signed i = 0; Dwarf_Arange *arange_buf = NULL; int ares = 0; int aires = 0; Dwarf_Off prev_off = 0; /* Holds previous CU offset */ Dwarf_Bool first_cu = TRUE; Dwarf_Off cu_die_offset_prev = 0; Dwarf_Error pa_error = 0; /* Reset the global state, so we can traverse the debug_info */ glflags.seen_CU = FALSE; glflags.need_CU_name = TRUE; glflags.need_CU_base_address = TRUE; glflags.need_CU_high_address = TRUE; glflags.current_section_id = DEBUG_ARANGES; ares = dwarf_get_aranges(dbg, &arange_buf, &count, &pa_error); if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_aranges", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } if (ares == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_aranges", ares, pa_error); } else if (ares == DW_DLV_NO_ENTRY) { /* no arange is included */ } else { for (i = 0; i < count; i++) { Dwarf_Unsigned segment = 0; Dwarf_Unsigned segment_entry_size = 0; Dwarf_Addr start = 0; Dwarf_Unsigned length = 0; Dwarf_Off cu_die_offset = 0; Dwarf_Die cu_die = NULL; aires = dwarf_get_arange_info_b(arange_buf[i], &segment, &segment_entry_size, &start, &length, &cu_die_offset, &pa_error); if (aires != DW_DLV_OK) { print_error(dbg, "dwarf_get_arange_info", aires, pa_error); } else { int dres; struct esb_s producer_name; esb_constructor(&producer_name); /* Get basic locations for error reporting */ dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &pa_error); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_offdie", dres, pa_error); } if (glflags.gf_cu_name_flag) { if (should_skip_this_cu(dbg,cu_die)) { continue; } } /* Get producer name for this CU and update compiler list */ get_producer_name(dbg,cu_die,cu_die_offset,&producer_name); update_compiler_target(esb_get_string(&producer_name)); esb_destructor(&producer_name); if (!checking_this_compiler()) { continue; } if (glflags.gf_check_aranges) { do_checking(dbg,arange_buf,i, cu_die_offset,first_cu, cu_die_offset_prev,cu_die); } /* Get the offset of the cu header itself in the section, but not for end-entries. */ if (start || length) { Dwarf_Off off = 0; int cures3 = dwarf_get_arange_cu_header_offset( arange_buf[i], &off, &pa_error); if (cures3 != DW_DLV_OK) { print_error(dbg, "dwarf_get_cu_hdr_offset", cures3, pa_error); } /* Print the CU information if different. */ if (prev_off != off || first_cu) { first_cu = FALSE; prev_off = off; /* We are faking the indent level. We do not know what level it is, really. If do_check_dwarf we do not want to do the die print call as it will do check/print we may not have asked for. And if we did ask for debug_info checks this will do the checks a second time! So only call print_one_die if printing. */ if (glflags.gf_do_print_dwarf){ /* There is no die if its a set-end entry */ print_one_die(dbg, cu_die, cu_die_offset, /* print_information= */ (boolean) TRUE, /* indent_level = */0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); } /* Reset the state, so we can traverse the debug_info */ glflags.seen_CU = FALSE; glflags.need_CU_name = TRUE; if (glflags.gf_do_print_dwarf) { printf("\n"); } } if (glflags.gf_do_print_dwarf) { /* Print current aranges record */ if (segment_entry_size) { printf( "\narange starts at seg,off 0x%" DW_PR_XZEROS DW_PR_DUx ",0x%" DW_PR_XZEROS DW_PR_DUx ", ", segment, (Dwarf_Unsigned)start); } else { printf("\narange starts at 0x%" DW_PR_XZEROS DW_PR_DUx ", ", (Dwarf_Unsigned)start); } printf("length of 0x%" DW_PR_XZEROS DW_PR_DUx ", cu_die_offset = 0x%" DW_PR_XZEROS DW_PR_DUx, length, (Dwarf_Unsigned)cu_die_offset); } if (glflags.verbose && glflags.gf_do_print_dwarf) { printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned)off); } dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); cu_die = 0; } else { /* Must be a range end. We really do want to print this as there is a real record here, an 'arange end' record. */ if (glflags.gf_do_print_dwarf) { printf("\narange end\n"); } }/* end start||length test */ } /* end aires DW_DLV_OK test */ /* print associated die too? */ dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE); } dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST); } } dwarfutils-20200114/dwarfdump/print_debugfission.c000066400000000000000000000150421361531463500221740ustar00rootroot00000000000000/* Copyright 2014-2014 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" #define TRUE 1 #define FALSE 0 static int hashval_zero(Dwarf_Sig8 *val) { unsigned u = 0; for(u=0 ; u < sizeof(Dwarf_Sig8);++u) { if (val->signature[u]) { return FALSE; } } return TRUE; } extern void print_debugfission_index(Dwarf_Debug dbg,const char *type) { int res = 0; Dwarf_Xu_Index_Header xuhdr = 0; Dwarf_Unsigned version_number = 0; Dwarf_Unsigned offsets_count = 0; Dwarf_Unsigned units_count = 0; Dwarf_Unsigned hash_slots_count = 0; Dwarf_Error fierr = 0; const char * section_name = 0; const char * section_type2 = 0; const char * section_name2 = 0; int is_cu = !strcmp(type,"cu")?TRUE:FALSE; res = dwarf_get_xu_index_header(dbg, type, &xuhdr, &version_number, &offsets_count, &units_count, &hash_slots_count, §ion_name, &fierr); if (res == DW_DLV_NO_ENTRY) { /* This applies to most object files. */ return; } if (res == DW_DLV_ERROR) { /* Odd. FIXME */ return; } res = dwarf_get_xu_index_section_type(xuhdr, §ion_type2, §ion_name2, &fierr); if (res == DW_DLV_NO_ENTRY) { /* Impossible. */ print_error(dbg,"dwarf_get_xu_index_section_type", DW_DLE_XU_IMPOSSIBLE_ERROR,fierr); dwarf_xu_header_free(xuhdr); return; } if (res == DW_DLV_ERROR) { /* Impossible. FIXME */ print_error(dbg,"dwarf_get_xu_index_section_type", res,fierr); dwarf_xu_header_free(xuhdr); return; } if (strcmp(section_type2,type)) { print_error(dbg,"dwarf_get_xu_index_section_type", DW_DLE_XU_IMPOSSIBLE_ERROR,fierr); dwarf_xu_header_free(xuhdr); return; } if(!section_name || !*section_name) { section_name = (is_cu?".debug_cu_index":".debug_tu_index"); } { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,section_name, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } printf(" Version: %" DW_PR_DUu "\n", version_number); printf(" Number of columns: %" DW_PR_DUu "\n", offsets_count); printf(" number of entries: %" DW_PR_DUu "\n", units_count); printf(" Number of slots: %" DW_PR_DUu "\n", hash_slots_count); if (hash_slots_count > 0) { printf("\n"); printf(" hash index\n"); } { Dwarf_Unsigned h = 0; for( h = 0; h < hash_slots_count; h++) { Dwarf_Sig8 hashval; Dwarf_Unsigned index = 0; Dwarf_Unsigned col = 0; struct esb_s hashhexstring; esb_constructor(&hashhexstring); memset(&hashval,0,sizeof(hashval)); res = dwarf_get_xu_hash_entry(xuhdr,h, &hashval,&index,&fierr); if (res == DW_DLV_ERROR) { print_error(dbg,"dwarf_get_xu_hash_entry",res,fierr); dwarf_xu_header_free(xuhdr); esb_destructor(&hashhexstring); return; } else if (res == DW_DLV_NO_ENTRY) { /* Impossible */ printf(" [%4" DW_PR_DUu "] " "dwarf_get_xu_hash_entry impossible return code: " "No entry?\n", h); dwarf_xu_header_free(xuhdr); esb_destructor(&hashhexstring); return; } else if (hashval_zero(&hashval) && index == 0 ) { /* An unused hash slot, we do not print them */ continue; } format_sig8_string(&hashval,&hashhexstring); printf(" [%4" DW_PR_DUu "] %s" " %8" DW_PR_DUu "\n", h, esb_get_string(&hashhexstring), index); esb_destructor(&hashhexstring); printf(" col section " "offset size\n"); for (col = 0; col < offsets_count; col++) { Dwarf_Unsigned off = 0; Dwarf_Unsigned len = 0; const char * name = 0; Dwarf_Unsigned num = 0; res = dwarf_get_xu_section_names(xuhdr, col,&num,&name,&fierr); if (res != DW_DLV_OK) { print_error(dbg,"dwarf_get_xu_section_names",res,fierr); dwarf_xu_header_free(xuhdr); return; } res = dwarf_get_xu_section_offset(xuhdr, index,col,&off,&len,&fierr); if (res != DW_DLV_OK) { print_error(dbg,"dwarf_get_xu_section_offset",res,fierr); dwarf_xu_header_free(xuhdr); return; } printf(" [,%2" DW_PR_DUu "] %20s " "0x%" DW_PR_XZEROS DW_PR_DUx " (%8" DW_PR_DUu ") " "0x%" DW_PR_XZEROS DW_PR_DUx " (%8" DW_PR_DUu ")\n", col,name, off,off, len,len); } } } dwarf_xu_header_free(xuhdr); } dwarfutils-20200114/dwarfdump/print_die.c000066400000000000000000007012171361531463500202620ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2007-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "naming.h" #include "esb.h" /* For flexible string buffer. */ #include "esb_using_functions.h" #include "sanitized.h" #include "print_frames.h" /* for get_string_from_locs() . */ #include "macrocheck.h" #include "helpertree.h" #include "tag_common.h" /* Traverse a DIE and attributes to check self references */ static boolean traverse_one_die(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool Dwarf_Bool, char **srcfiles, Dwarf_Signed cnt, int die_indent_level); static boolean traverse_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, Dwarf_Half attr, Dwarf_Attribute attr_in, boolean print_information, char **srcfiles, Dwarf_Signed cnt, int die_indent_level); static void print_die_and_children_internal(Dwarf_Debug dbg, Dwarf_Die in_die_in, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt); static int print_one_die_section(Dwarf_Debug dbg,Dwarf_Bool is_info, Dwarf_Error *pod_err); /* Is this a PU has been invalidated by the SN Systems linker? */ #define IsInvalidCode(low,high) ((low == elf_max_address) || (low == 0 && high == 0)) #ifdef HAVE_USAGE_TAG_ATTR /* Record TAGs usage */ static unsigned int tag_usage[DW_TAG_last] = {0}; #endif /* HAVE_USAGE_TAG_ATTR */ static int get_form_values(Dwarf_Debug dbg,Dwarf_Attribute attrib, Dwarf_Half * theform, Dwarf_Half * directform); static void show_form_itself(int show_form,int verbose, int theform, int directform, struct esb_s * str_out); static void print_exprloc_content(Dwarf_Debug dbg,Dwarf_Die die, Dwarf_Attribute attrib, int showhextoo, struct esb_s *esbp); static boolean print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Half attr, Dwarf_Attribute actual_addr, boolean print_information, int die_indent_level, char **srcfiles, Dwarf_Signed cnt); static void get_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, struct esb_s *esbp); static int legal_tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr); static int legal_tag_tree_combination(Dwarf_Half parent_tag, Dwarf_Half child_tag); static int _dwarf_print_one_expr_op(Dwarf_Debug dbg, Dwarf_Loc* expr, Dwarf_Locdesc_c exprc, int index, Dwarf_Addr baseaddr,struct esb_s *string_out); static int formxdata_print_value(Dwarf_Debug dbg, Dwarf_Die die,Dwarf_Attribute attrib, Dwarf_Half theform, struct esb_s *esbp, Dwarf_Error * err, Dwarf_Bool hex_format); static void bracket_hex(const char *s1, Dwarf_Unsigned v, const char *s2, struct esb_s * esbp); static void formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp, Dwarf_Bool hex_format); static void formx_data16(Dwarf_Form_Data16 * u, struct esb_s *esbp, Dwarf_Bool hex_format); static void formx_signed(Dwarf_Signed s, struct esb_s *esbp); static int pd_dwarf_names_print_on_error = 1; static int die_stack_indent_level = 0; static boolean local_symbols_already_began = FALSE; typedef const char *(*encoding_type_func) (unsigned,int doprintingonerr); /* Indicators to record a pair [low,high], these are used in printing DIEs to accumulate the high and low pc across attributes and to record the pair as soon as both are known. Probably would be better to use variables as arguments to print_attribute(). */ static Dwarf_Addr lowAddr = 0; static Dwarf_Addr highAddr = 0; static Dwarf_Bool bSawLow = FALSE; static Dwarf_Bool bSawHigh = FALSE; /* The following too is related to high and low pc attributes of a function. It's misnamed, it really means 'yes, we have high and low pc' if it is TRUE. Defaulting to TRUE seems bogus. */ static Dwarf_Bool in_valid_code = TRUE; #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* 0 */ struct operation_descr_s { int op_code; int op_count; const char * op_1type; }; struct operation_descr_s opdesc[]= { {DW_OP_addr,1,"addr" }, {DW_OP_deref,0,"" }, {DW_OP_const1u,1,"1u" }, {DW_OP_const1s,1,"1s" }, {DW_OP_const2u,1,"2u" }, {DW_OP_const2s,1,"2s" }, {DW_OP_const4u,1,"4u" }, {DW_OP_const4s,1,"4s" }, {DW_OP_const8u,1,"8u" }, {DW_OP_const8s,1,"8s" }, {DW_OP_constu,1,"uleb" }, {DW_OP_consts,1,"sleb" }, {DW_OP_dup,0,""}, {DW_OP_drop,0,""}, {DW_OP_over,0,""}, {DW_OP_pick,1,"1u"}, {DW_OP_swap,0,""}, {DW_OP_rot,0,""}, {DW_OP_xderef,0,""}, {DW_OP_abs,0,""}, {DW_OP_and,0,""}, {DW_OP_div,0,""}, {DW_OP_minus,0,""}, {DW_OP_mod,0,""}, {DW_OP_mul,0,""}, {DW_OP_neg,0,""}, {DW_OP_not,0,""}, {DW_OP_or,0,""}, {DW_OP_plus,0,""}, {DW_OP_plus_uconst,1,"uleb"}, {DW_OP_shl,0,""}, {DW_OP_shr,0,""}, {DW_OP_shra,0,""}, {DW_OP_xor,0,""}, {DW_OP_skip,1,"2s"}, {DW_OP_bra,1,"2s"}, {DW_OP_eq,0,""}, {DW_OP_ge,0,""}, {DW_OP_gt,0,""}, {DW_OP_le,0,""}, {DW_OP_lt,0,""}, {DW_OP_ne,0,""}, /* lit0 thru reg31 handled specially, no operands */ /* breg0 thru breg31 handled specially, 1 operand */ {DW_OP_regx,1,"uleb"}, {DW_OP_fbreg,1,"sleb"}, {DW_OP_bregx,2,"uleb"}, {DW_OP_piece,1,"uleb"}, {DW_OP_deref_size,1,"1u"}, {DW_OP_xderef_size,1,"1u"}, {DW_OP_nop,0,""}, {DW_OP_push_object_address,0,""}, {DW_OP_call2,1,"2u"}, {DW_OP_call4,1,"4u"}, {DW_OP_call_ref,1,"off"}, {DW_OP_form_tls_address,0,""}, {DW_OP_call_frame_cfa,0,""}, {DW_OP_bit_piece,2,"uleb"}, {DW_OP_implicit_value,2,"u"}, {DW_OP_stack_value,0,""}, {DW_OP_GNU_uninit,0,""}, {DW_OP_GNU_encoded_addr,1,"addr"}, {DW_OP_implicit_pointer,2,"addr" }, /* DWARF5 */ {DW_OP_GNU_implicit_pointer,2,"addr" }, {DW_OP_entry_value,2,"val" }, /* DWARF5 */ {DW_OP_GNU_entry_value,2,"val" }, {DW_OP_const_type,3,"uleb" }, /* DWARF5 */ {DW_OP_GNU_const_type,3,"uleb" }, {DW_OP_regval_type,2,"uleb" }, /* DWARF5 */ {DW_OP_GNU_regval_type,2,"uleb" }, {DW_OP_deref_type,1,"val" }, /* DWARF5 */ {DW_OP_GNU_deref_type,1,"val" }, {DW_OP_convert,1,"uleb" }, /* DWARF5 */ {DW_OP_GNU_convert,1,"uleb" }, {DW_OP_reinterpret,1,"uleb" }, /* DWARF5 */ {DW_OP_GNU_reinterpret,1,"uleb" }, {DW_OP_GNU_parameter_ref,1,"val" }, {DW_OP_GNU_const_index,1,"val" }, {DW_OP_GNU_push_tls_address,0,"" }, {DW_OP_addrx,1,"uleb" }, /* DWARF5 */ {DW_OP_GNU_addr_index,1,"val" }, {DW_OP_constx,1,"u" }, /* DWARF5 */ {DW_OP_GNU_const_index,1,"u" }, {DW_OP_GNU_parameter_ref,1,"u" }, {DW_OP_xderef,0,"" }, /* DWARF5 */ {DW_OP_xderef_type,2,"1u" }, /* DWARF5 */ /* terminator */ {0,0,""} }; struct die_stack_data_s { Dwarf_Die die_; /* sibling_die_globaloffset_ is set while processing the DIE. We do not know the sibling global offset when we create the stack entry. If the sibling attribute absent we never know. */ Dwarf_Off sibling_die_globaloffset_; /* We may need is_info here too. */ Dwarf_Off cu_die_offset_; /* global offset. */ boolean already_printed_; }; struct die_stack_data_s empty_stack_entry; #define DIE_STACK_SIZE 800 static struct die_stack_data_s die_stack[DIE_STACK_SIZE]; #define SET_DIE_STACK_ENTRY(i,x,o) { die_stack[i].die_ = x; \ die_stack[i].cu_die_offset_ = o; \ die_stack[i].sibling_die_globaloffset_ = 0; \ die_stack[i].already_printed_ = FALSE; } #define EMPTY_DIE_STACK_ENTRY(i) { die_stack[i] = empty_stack_entry; } #define SET_DIE_STACK_SIBLING(x) { \ die_stack[die_stack_indent_level].sibling_die_globaloffset_ = x; } /* The first non-zero sibling offset we can find is what we want to return. The lowest sibling offset in the stack. Or 0 if we have none known. */ static Dwarf_Off get_die_stack_sibling() { int i = die_stack_indent_level; for( ; i >=0 ; --i) { Dwarf_Off v = die_stack[i].sibling_die_globaloffset_; if (v) { return v; } } return 0; } /* Higher stack level numbers must have a smaller sibling offset than lower or else the sibling offsets are wrong. Stack entries with sibling_die_globaloffset_ 0 must be ignored in this, it just means there was no sibling attribute at that level. */ static void validate_die_stack_siblings(Dwarf_Debug dbg) { int i = die_stack_indent_level; Dwarf_Off innersiboffset = 0; for( ; i >=0 ; --i) { Dwarf_Off v = die_stack[i].sibling_die_globaloffset_; if (v) { innersiboffset = v; break; } } if(!innersiboffset) { /* no sibling values to check. */ return; } for(--i ; i >= 0 ; --i) { /* outersiboffset is an outer sibling offset. */ Dwarf_Off outersiboffset = die_stack[i].sibling_die_globaloffset_; if (outersiboffset ) { if (outersiboffset < innersiboffset) { char small_buf[150]; Dwarf_Error ouerr = 0; /* safe: all values known length. */ #ifdef ORIGINAL_SPRINTF sprintf(small_buf, "Die stack sibling error, outer global offset " "0x%" DW_PR_XZEROS DW_PR_DUx " less than inner global offset " "0x%" DW_PR_XZEROS DW_PR_DUx ", the DIE tree is erroneous.", outersiboffset, innersiboffset); print_error(dbg,small_buf, DW_DLV_OK, ouerr); #else struct esb_s pm; esb_constructor_fixed(&pm,small_buf,sizeof(small_buf)); esb_append_printf_u(&pm, "Die stack sibling error, outer global offset " "0x%" DW_PR_XZEROS DW_PR_DUx,outersiboffset); esb_append_printf_u(&pm, " less than inner global offset " "0x%" DW_PR_XZEROS DW_PR_DUx ", the DIE tree is erroneous.", innersiboffset); print_error(dbg,esb_get_string(&pm), DW_DLV_OK,ouerr); esb_destructor(&pm); #endif } /* We only need check one level with an offset at each entry. */ break; } } return; } static int print_as_info_or_cu() { return (glflags.gf_info_flag || glflags.gf_types_flag || glflags.gf_cu_name_flag); } #if 0 /* Only used for debugging. */ static void dump_die_offsets(Dwarf_Debug dbg, Dwarf_Die die, const char *msg) { Dwarf_Error dderr = 0; Dwarf_Off goff = 0; Dwarf_Off loff = 0; Dwarf_Half tag = 0; int res = 0; res = dwarf_die_offsets(die,&goff, &loff,&dderr); DROP_ERROR_INSTANCE(dbg,res,dderr); res = dwarf_tag(die, &tag, &dderr); DROP_ERROR_INSTANCE(dbg,res,dderr); printf("debugonly: Die tag 0x%x GOFF 0x%llx Loff 0x%llx %s\n", tag,goff,loff,msg); } #endif static Dwarf_Bool form_refers_local_info(Dwarf_Half form) { if (form == DW_FORM_GNU_ref_alt || form == DW_FORM_GNU_strp_alt || form == DW_FORM_strp_sup || form == DW_FORM_line_strp ) { /* These do not refer to the current section and cannot be checked as if they did. */ return FALSE; } return TRUE; } /* process each compilation unit in .debug_info */ void print_infos(Dwarf_Debug dbg,Dwarf_Bool is_info) { int nres = 0; Dwarf_Error pi_err = 0; if (is_info) { nres = print_one_die_section(dbg,TRUE,&pi_err); if (nres == DW_DLV_ERROR) { char * errmsg = dwarf_errmsg(pi_err); Dwarf_Unsigned myerr = dwarf_errno(pi_err); fprintf(stderr, "%s ERROR: %s: %s (%lu)\n", glflags.program_name, "attempting to print .debug_info", errmsg, (unsigned long) myerr); fprintf(stderr, "attempting to continue.\n"); } return; } /* !is_info */ nres = print_one_die_section(dbg,FALSE,&pi_err); if (nres == DW_DLV_ERROR) { char * errmsg = dwarf_errmsg(pi_err); Dwarf_Unsigned myerr = dwarf_errno(pi_err); fprintf(stderr, "%s ERROR: %s: %s (%lu)\n", glflags.program_name, "attempting to print .debug_types", errmsg, (unsigned long) myerr); fprintf(stderr, "attempting to continue.\n"); } } static void print_debug_fission_header(struct Dwarf_Debug_Fission_Per_CU_s *fsd) { const char * fissionsec = ".debug_cu_index"; unsigned i = 0; struct esb_s hash_str; if (!fsd || !fsd->pcu_type) { /* No fission data. */ return; } esb_constructor(&hash_str); printf("\n"); if (!strcmp(fsd->pcu_type,"tu")) { fissionsec = ".debug_tu_index"; } printf(" %-19s = %s\n","Fission section",fissionsec); printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx "\n","Fission index ", fsd->pcu_index); format_sig8_string(&fsd->pcu_hash,&hash_str); printf(" %-19s = %s\n","Fission hash",esb_get_string(&hash_str)); /* 0 is always unused. Skip it. */ esb_destructor(&hash_str); printf(" %-19s = %s\n","Fission entries","offset size DW_SECTn"); for( i = 1; i < DW_FISSION_SECT_COUNT; ++i) { const char *nstring = 0; Dwarf_Unsigned off = 0; Dwarf_Unsigned size = fsd->pcu_size[i]; int res = 0; if (size == 0) { continue; } res = dwarf_get_SECT_name(i,&nstring); if (res != DW_DLV_OK) { nstring = "Unknown SECT"; } off = fsd->pcu_offset[i]; printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %2d\n", nstring, off,size,i); } } static void print_cu_hdr_cudie(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Die cudie, Dwarf_Unsigned overall_offset, Dwarf_Unsigned offset ) { struct Dwarf_Debug_Fission_Per_CU_s fission_data; if (glflags.dense) { printf("\n"); return; } memset(&fission_data,0,sizeof(fission_data)); printf("\nCOMPILE_UNIT
", (Dwarf_Unsigned)(overall_offset - offset)); #if 0 if (verbose) { int fission_data_result = 0; fission_data_result = dwarf_get_debugfission_for_die(cudie, &fission_data,&err); if (fission_data_result == DW_DLV_ERROR) { print_error(dbg,"Failure looking for Debug Fission data", fission_data_result, err); } print_debug_fission_header(&fission_data); } #endif printf(":\n"); } static void print_cu_hdr_std(Dwarf_Unsigned cu_header_length, Dwarf_Unsigned abbrev_offset, Dwarf_Half version_stamp, Dwarf_Half address_size, /* offset_size is often called length_size in libdwarf. */ Dwarf_Half offset_size, int debug_fission_res, Dwarf_Half cu_type, struct Dwarf_Debug_Fission_Per_CU_s * fsd) { int res = 0; const char *utname = 0; res = dwarf_get_UT_name(cu_type,&utname); if (res != DW_DLV_OK) { utname = "ERROR"; } if (glflags.dense) { printf("<%s>", "cu_header"); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "cu_header_length", cu_header_length); printf(" %s<0x%04x>", "version_stamp", version_stamp); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "abbrev_offset", abbrev_offset); printf(" %s<0x%02x>", "address_size", address_size); printf(" %s<0x%02x>", "offset_size", offset_size); printf(" %s<0x%02x %s>", "cu_type", cu_type,utname); if (debug_fission_res == DW_DLV_OK) { struct esb_s hash_str; unsigned i = 0; esb_constructor(&hash_str); format_sig8_string(&fsd->pcu_hash,&hash_str); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "fissionindex", fsd->pcu_index); printf(" %s<%s>", "fissionhash", esb_get_string(&hash_str)); esb_destructor(&hash_str); for( i = 1; i < DW_FISSION_SECT_COUNT; ++i) { const char *nstring = 0; Dwarf_Unsigned off = 0; Dwarf_Unsigned size = fsd->pcu_size[i]; int fires = 0; if (size == 0) { continue; } fires = dwarf_get_SECT_name(i,&nstring); if (fires != DW_DLV_OK) { nstring = "UnknownDW_SECT"; } off = fsd->pcu_offset[i]; printf(" %s< 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ">", nstring, off,size); } } } else { printf("\nCU_HEADER:\n"); printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", "cu_header_length", cu_header_length, cu_header_length); printf(" %-16s = 0x%04x %u\n", "version_stamp", version_stamp,version_stamp); printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", "abbrev_offset", abbrev_offset, abbrev_offset); printf(" %-16s = 0x%02x %u\n", "address_size", address_size,address_size); printf(" %-16s = 0x%02x %u\n", "offset_size", offset_size,offset_size); printf(" %-16s = 0x%02x %s\n", "cu_type", cu_type,utname); if (debug_fission_res == DW_DLV_OK) { print_debug_fission_header(fsd); } } } static void print_cu_hdr_signature(Dwarf_Sig8 *signature,Dwarf_Unsigned typeoffset) { if (glflags.dense) { struct esb_s sig8str; esb_constructor(&sig8str); format_sig8_string(signature,&sig8str); printf(" %s<%s>", "signature",esb_get_string(&sig8str)); printf(" %s<0x%" DW_PR_XZEROS DW_PR_DUx ">", "typeoffset", typeoffset); esb_destructor(&sig8str); } else { struct esb_s sig8str; esb_constructor(&sig8str); format_sig8_string(signature,&sig8str); printf(" %-16s = %s\n", "signature",esb_get_string(&sig8str)); printf(" %-16s = 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", "typeoffset", typeoffset,typeoffset); esb_destructor(&sig8str); } } static int get_macinfo_offset(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Unsigned *offset, Dwarf_Error *macerr) { Dwarf_Attribute attrib= 0; int vres = 0; int ares = 0; ares = dwarf_attr(cu_die, DW_AT_macro_info, &attrib, macerr); if (ares == DW_DLV_ERROR) { print_error(dbg, "dwarf_attr on DW_AT_macro_info", ares,*macerr); } else if (ares == DW_DLV_NO_ENTRY) { return ares; } vres = dwarf_global_formref(attrib,offset,macerr); if (vres == DW_DLV_ERROR) { dwarf_dealloc(dbg,attrib,DW_DLA_ATTR); print_error(dbg, "dwarf_global_formref on DW_AT_macro_info", vres, *macerr); } else if (vres == DW_DLV_NO_ENTRY) { } dwarf_dealloc(dbg,attrib,DW_DLA_ATTR); return vres; } static void print_die_secname(Dwarf_Debug dbg,int is_info) { if (print_as_info_or_cu() && glflags.gf_do_print_dwarf) { const char * section_name = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; if (is_info) { section_name = ".debug_info"; } else { section_name = ".debug_types"; } esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,section_name, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } } static Dwarf_Bool empty_signature(const Dwarf_Sig8 *sigp) { static const Dwarf_Sig8 zerosig; if (memcmp(sigp,&zerosig,sizeof(zerosig))) { return FALSE ; /* empty */ } return TRUE; } /* */ static int print_one_die_section(Dwarf_Debug dbg,Dwarf_Bool is_info, Dwarf_Error *pod_err) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Half extension_size = 0; Dwarf_Half length_size = 0; Dwarf_Sig8 signature; Dwarf_Unsigned typeoffset = 0; Dwarf_Unsigned next_cu_offset = 0; unsigned loop_count = 0; int nres = DW_DLV_OK; int cu_count = 0; char * cu_short_name = NULL; char * cu_long_name = NULL; int res = 0; Dwarf_Off dieprint_cu_goffset = 0; glflags.current_section_id = is_info?DEBUG_INFO:DEBUG_TYPES; { const char * test_section_name = 0; res = dwarf_get_die_section_name(dbg,is_info, &test_section_name,pod_err); if (res == DW_DLV_NO_ENTRY) { if(!is_info) { /* No .debug_types. Do not print .debug_types name */ return DW_DLV_NO_ENTRY; } } } /* Loop until it fails. */ for (;;++loop_count) { int sres = DW_DLV_OK; Dwarf_Die cu_die = 0; struct Dwarf_Debug_Fission_Per_CU_s fission_data; int fission_data_result = 0; Dwarf_Half cu_type = 0; /* glflags.DIE_overall_offset: in case dwarf_next_cu_header_d fails due to corrupt dwarf. */ glflags.DIE_overall_offset = dieprint_cu_goffset; memset(&fission_data,0,sizeof(fission_data)); nres = dwarf_next_cu_header_d(dbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &length_size,&extension_size, &signature, &typeoffset, &next_cu_offset, &cu_type, pod_err); if (!loop_count) { /* So compress flags show, we waited till section loaded. */ print_die_secname(dbg,is_info); } if (nres == DW_DLV_NO_ENTRY) { return nres; } if (nres == DW_DLV_ERROR) { /* With corrupt DWARF due to a bad CU die we won't know much. */ print_error_and_continue(dbg, "Failure reading CU header or DIE, corrupt DWARF", nres, *pod_err); return nres; } if (cu_count >= glflags.break_after_n_units) { printf("Break at %d\n",cu_count); break; } /* Regardless of any options used, get basic information about the current CU: producer, name */ sres = dwarf_siblingof_b(dbg, NULL,is_info, &cu_die, pod_err); if (sres != DW_DLV_OK) { print_error(dbg, "siblingof cu header", sres, *pod_err); } /* Get the CU offset for easy error reporting */ dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,pod_err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; dieprint_cu_goffset = glflags.DIE_overall_offset; if (glflags.gf_cu_name_flag) { if (should_skip_this_cu(dbg,cu_die)) { dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); cu_die = 0; ++cu_count; continue; } } { /* Get producer name for this CU and update compiler list */ struct esb_s producername; esb_constructor(&producername); get_producer_name(dbg,cu_die, dieprint_cu_goffset,&producername); update_compiler_target(esb_get_string(&producername)); esb_destructor(&producername); } /* Once the compiler table has been updated, see if we need to generate the list of CU compiled by all the producers contained in the elf file */ if (glflags.gf_producer_children_flag) { get_cu_name(dbg,cu_die, dieprint_cu_goffset,&cu_short_name,&cu_long_name); /* Add CU name to current compiler entry */ add_cu_name_compiler_target(cu_long_name); } /* If the current compiler is not requested by the user, then move to the next CU */ if (!checking_this_compiler()) { dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); ++cu_count; cu_die = 0; continue; } fission_data_result = dwarf_get_debugfission_for_die(cu_die, &fission_data,pod_err); if (fission_data_result == DW_DLV_ERROR) { print_error(dbg, "Failure looking for Debug Fission data", fission_data_result, *pod_err); } if(fission_data_result == DW_DLV_OK) { /* In a .dwp file some checks get all sorts of spurious errors. */ glflags.gf_suppress_checking_on_dwp = TRUE; glflags.gf_check_ranges = FALSE; glflags.gf_check_aranges = FALSE; glflags.gf_check_decl_file = FALSE; glflags.gf_check_lines = FALSE; glflags.gf_check_pubname_attr = FALSE; glflags.gf_check_fdes = FALSE; } /* We have not seen the compile unit yet, reset these error-reporting globals. */ glflags.seen_CU = FALSE; glflags.need_CU_name = TRUE; glflags.need_CU_base_address = TRUE; glflags.need_CU_high_address = TRUE; /* Some prerelease gcc versions used ranges but seemingly assumed the lack of a base address in the CU was defined to be a zero base. Assuming a base address (and low and high) is sensible. */ glflags.CU_base_address = 0; glflags.CU_high_address = 0; glflags.CU_low_address = 0; /* Release the 'cu_die' created by the call to 'dwarf_siblingof' at the top of the main loop. */ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); cu_die = 0; /* For debugging, stale die should be NULL. */ if ((glflags.gf_info_flag || glflags.gf_types_flag) && glflags.gf_do_print_dwarf) { if (glflags.verbose) { print_cu_hdr_std(cu_header_length,abbrev_offset, version_stamp,address_size,length_size, fission_data_result,cu_type,&fission_data); if (!empty_signature(&signature)) { print_cu_hdr_signature(&signature,typeoffset); } if (glflags.dense) { printf("\n"); } } else { if (!empty_signature(&signature)) { if (glflags.dense) { printf("<%s>", "cu_header"); } else { printf("\nCU_HEADER:\n"); } print_cu_hdr_signature(&signature,typeoffset); if (glflags.dense) { printf("\n"); } } } } /* Get abbreviation info for this CU */ get_abbrev_array_info(dbg,abbrev_offset); /* Process a single compilation unit in .debug_info or .debug_types. */ sres = dwarf_siblingof_b(dbg, NULL,is_info, &cu_die, pod_err); if (sres == DW_DLV_OK) { if (print_as_info_or_cu() || glflags.gf_search_is_on) { Dwarf_Signed cnt = 0; char **srcfiles = 0; Dwarf_Error srcerr = 0; int srcf = 0; srcf = dwarf_srcfiles(cu_die, &srcfiles, &cnt, &srcerr); if (srcf == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_srcfiles", srcf,srcerr); dwarf_dealloc(dbg,srcerr,DW_DLA_ERROR); srcerr = 0; srcfiles = 0; cnt = 0; } else if (srcf == DW_DLV_NO_ENTRY) { /*DW_DLV_NO_ENTRY generally means there there is no dW_AT_stmt_list attribute. and we do not want to print anything about statements in that case */ } /* Get the CU offset for easy error reporting */ dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,pod_err); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; dieprint_cu_goffset = glflags.DIE_overall_offset; print_die_and_children(dbg, cu_die, dieprint_cu_goffset,is_info, srcfiles, cnt); if (srcf == DW_DLV_OK) { int si = 0; for (si = 0; si < cnt; ++si) { dwarf_dealloc(dbg, srcfiles[si], DW_DLA_STRING); } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); } } /* Dump Ranges Information */ if (dump_ranges_info) { PrintBucketGroup(glflags.pRangesInfo,TRUE); } /* Check the range array if in checl mode */ if ( glflags.gf_check_ranges) { check_range_array_info(dbg); } /* Traverse the line section if in check mode or if line-printing requested */ if (glflags.gf_line_flag || glflags.gf_check_decl_file) { int oldsection = glflags.current_section_id; print_line_numbers_this_cu(dbg, cu_die); glflags.current_section_id = oldsection; } if (glflags.gf_macro_flag || glflags.gf_check_macros) { Dwarf_Bool in_import_list = FALSE; Dwarf_Unsigned import_offset = 0; int oldsection = glflags.current_section_id; print_macros_5style_this_cu(dbg, cu_die, in_import_list,import_offset); in_import_list = TRUE; while(get_next_unprinted_macro_offset(¯o_check_tree, &import_offset) == DW_DLV_OK) { print_macros_5style_this_cu(dbg, cu_die, in_import_list,import_offset); } glflags.current_section_id = oldsection; } if (glflags.gf_macinfo_flag || glflags.gf_check_macros) { int mres = 0; int oldsection = glflags.current_section_id; Dwarf_Unsigned offset = 0; mres = get_macinfo_offset(dbg,cu_die,&offset,pod_err); if (mres == DW_DLV_NO_ENTRY) { /* By far the most likely result. */ }else if (mres == DW_DLV_ERROR) { print_error(dbg, "get_macinfo_offset", mres,*pod_err); } else { print_macinfo_by_offset(dbg,offset); glflags.current_section_id = oldsection; } } dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); cu_die = 0; } else if (sres == DW_DLV_NO_ENTRY) { /* Do nothing I guess. */ } else { print_error(dbg, "Regetting cu_die", sres, *pod_err); } ++cu_count; } return nres; } static void print_a_die_stack(Dwarf_Debug dbg,char **srcfiles,Dwarf_Signed cnt,int lev) { boolean print_information = TRUE; boolean ignore_die_stack = FALSE; print_one_die(dbg, die_stack[lev].die_, die_stack[lev].cu_die_offset_, print_information,lev,srcfiles,cnt, ignore_die_stack); } extern void print_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die_in, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt) { print_die_and_children_internal(dbg, in_die_in, dieprint_cu_goffset, is_info,srcfiles,cnt); } static void print_die_stack(Dwarf_Debug dbg,char **srcfiles,Dwarf_Signed cnt) { int lev = 0; boolean print_information = TRUE; boolean ignore_die_stack = FALSE; for (lev = 0; lev <= die_stack_indent_level; ++lev) { print_one_die(dbg,die_stack[lev].die_, die_stack[lev].cu_die_offset_, print_information, lev,srcfiles,cnt, ignore_die_stack); } } /* recursively follow the die tree */ static void print_die_and_children_internal(Dwarf_Debug dbg, Dwarf_Die in_die_in, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt) { Dwarf_Die child = 0; Dwarf_Die sibling = 0; Dwarf_Error dacerr = 0; int tres = 0; int cdres = 0; Dwarf_Die in_die = in_die_in; for (;;) { /* Get the CU offset for easy error reporting */ dwarf_die_offsets(in_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,&dacerr); SET_DIE_STACK_ENTRY(die_stack_indent_level,in_die, dieprint_cu_goffset); if ( glflags.gf_check_tag_tree || glflags.gf_print_usage_tag_attr) { DWARF_CHECK_COUNT(tag_tree_result,1); if (die_stack_indent_level == 0) { Dwarf_Half tag = 0; tres = dwarf_tag(in_die, &tag, &dacerr); if (tres != DW_DLV_OK) { DWARF_CHECK_ERROR(tag_tree_result, "Tag-tree root tag unavailable: " "is not DW_TAG_compile_unit"); } else if (tag == DW_TAG_skeleton_unit) { /* OK */ } else if (tag == DW_TAG_compile_unit) { /* OK */ } else if (tag == DW_TAG_partial_unit) { /* OK */ } else if (tag == DW_TAG_type_unit) { /* OK */ } else { DWARF_CHECK_ERROR(tag_tree_result, "tag-tree root is not DW_TAG_compile_unit " "or DW_TAG_partial_unit or DW_TAG_type_unit"); } } else { Dwarf_Half tag_parent = 0; Dwarf_Half tag_child = 0; Dwarf_Error dacerr2 = 0; int pres = 0; int cres = 0; const char *ctagname = ""; const char *ptagname = ""; pres = dwarf_tag(die_stack[die_stack_indent_level - 1].die_, &tag_parent, &dacerr); cres = dwarf_tag(in_die, &tag_child, &dacerr2); if (pres != DW_DLV_OK) tag_parent = 0; if (cres != DW_DLV_OK) tag_child = 0; DROP_ERROR_INSTANCE(dbg,pres,dacerr); DROP_ERROR_INSTANCE(dbg,cres,dacerr2); /* Check for specific compiler */ if (checking_this_compiler()) { /* Process specific TAGs. */ tag_specific_checks_setup(tag_child,die_stack_indent_level); if (cres != DW_DLV_OK || pres != DW_DLV_OK) { if (cres == DW_DLV_OK) { ctagname = get_TAG_name(tag_child, pd_dwarf_names_print_on_error); } if (pres == DW_DLV_OK) { ptagname = get_TAG_name(tag_parent, pd_dwarf_names_print_on_error); } DWARF_CHECK_ERROR3(tag_tree_result,ptagname, ctagname, "Tag-tree relation is not standard.."); } else if (legal_tag_tree_combination(tag_parent, tag_child)) { /* OK */ } else { /* Report errors only if tag-tree check is on */ if (glflags.gf_check_tag_tree) { DWARF_CHECK_ERROR3(tag_tree_result, get_TAG_name(tag_parent, pd_dwarf_names_print_on_error), get_TAG_name(tag_child, pd_dwarf_names_print_on_error), "tag-tree relation is not standard."); } } } } } if (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode) { glflags.gf_record_dwarf_error = FALSE; } /* Here do pre-descent processing of the die. */ { boolean retry_print_on_match = FALSE; boolean ignore_die_stack = FALSE; retry_print_on_match = print_one_die(dbg, in_die, dieprint_cu_goffset, print_as_info_or_cu(), die_stack_indent_level, srcfiles, cnt,ignore_die_stack); validate_die_stack_siblings(dbg); if (!print_as_info_or_cu() && retry_print_on_match) { if (glflags.gf_display_parent_tree) { print_die_stack(dbg,srcfiles,cnt); } else { if (glflags.gf_display_children_tree) { print_a_die_stack(dbg,srcfiles,cnt,die_stack_indent_level); } } if (glflags.gf_display_children_tree) { glflags.gf_stop_indent_level = die_stack_indent_level; glflags.gf_info_flag = TRUE; glflags.gf_types_flag = TRUE; } } } cdres = dwarf_child(in_die, &child, &dacerr); /* Check for specific compiler */ if (glflags.gf_check_abbreviations && checking_this_compiler()) { Dwarf_Half ab_has_child; Dwarf_Bool bError = FALSE; Dwarf_Half tag = 0; tres = dwarf_die_abbrev_children_flag(in_die,&ab_has_child); if (tres == DW_DLV_OK) { DWARF_CHECK_COUNT(abbreviations_result,1); tres = dwarf_tag(in_die, &tag, &dacerr); if (tres == DW_DLV_OK) { switch (tag) { case DW_TAG_array_type: case DW_TAG_class_type: case DW_TAG_compile_unit: case DW_TAG_type_unit: case DW_TAG_partial_unit: case DW_TAG_enumeration_type: case DW_TAG_lexical_block: case DW_TAG_namespace: case DW_TAG_structure_type: case DW_TAG_subprogram: case DW_TAG_subroutine_type: case DW_TAG_union_type: case DW_TAG_entry_point: case DW_TAG_inlined_subroutine: break; default: bError = (cdres == DW_DLV_OK && !ab_has_child) || (cdres == DW_DLV_NO_ENTRY && ab_has_child); if (bError) { DWARF_CHECK_ERROR(abbreviations_result, "check 'dw_children' flag combination."); } break; } } } } /* child first: we are doing depth-first walk */ if (cdres == DW_DLV_OK) { /* If the global offset of the (first) child is <= the parent DW_AT_sibling global-offset-value then the compiler has made a mistake, and the DIE tree is corrupt. */ Dwarf_Off child_overall_offset = 0; int cores = dwarf_dieoffset(child, &child_overall_offset, &dacerr); if (cores == DW_DLV_OK) { Dwarf_Off parent_sib_val = get_die_stack_sibling(); if (parent_sib_val && (parent_sib_val <= child_overall_offset )) { char small_buf[180]; #ifdef ORIGINAL_SPRINTF /* safe: all values known length. */ sprintf(small_buf, "A parent DW_AT_sibling of " "0x%" DW_PR_XZEROS DW_PR_DUx " points %s the first child " "0x%" DW_PR_XZEROS DW_PR_DUx " so the die tree is corrupt " "(showing section, not CU, offsets). ", parent_sib_val, (parent_sib_val == child_overall_offset)? "at":"before", child_overall_offset); print_error(dbg,small_buf,DW_DLV_OK,dacerr); #else struct esb_s pm; esb_constructor_fixed(&pm,small_buf, sizeof(small_buf)); esb_append_printf_u(&pm, "A parent DW_AT_sibling of " "0x%" DW_PR_XZEROS DW_PR_DUx, parent_sib_val); esb_append_printf_s(&pm, " points %s the first child ", (parent_sib_val == child_overall_offset)? "at":"before"); esb_append_printf_u(&pm, "0x%" DW_PR_XZEROS DW_PR_DUx " so the die tree is corrupt " "(showing section, not CU, offsets). ", child_overall_offset); print_error(dbg,esb_get_string(&pm), DW_DLV_OK,dacerr); esb_destructor(&pm); #endif } } die_stack_indent_level++; SET_DIE_STACK_ENTRY(die_stack_indent_level,0,dieprint_cu_goffset); if (die_stack_indent_level >= DIE_STACK_SIZE ) { print_error(dbg, "ERROR: compiled in DIE_STACK_SIZE limit exceeded", DW_DLV_OK,dacerr); } print_die_and_children_internal(dbg, child, dieprint_cu_goffset, is_info, srcfiles, cnt); EMPTY_DIE_STACK_ENTRY(die_stack_indent_level); die_stack_indent_level--; if (die_stack_indent_level == 0) { local_symbols_already_began = FALSE; } dwarf_dealloc(dbg, child, DW_DLA_DIE); child = 0; } else if (cdres == DW_DLV_ERROR) { print_error(dbg, "dwarf_child", cdres, dacerr); } /* Stop the display of all children */ if (glflags.gf_display_children_tree && (glflags.gf_info_flag || glflags.gf_types_flag) && glflags.gf_stop_indent_level == die_stack_indent_level) { glflags.gf_info_flag = FALSE; glflags.gf_types_flag = FALSE; } cdres = dwarf_siblingof_b(dbg, in_die,is_info, &sibling, &dacerr); if (cdres == DW_DLV_OK) { /* print_die_and_children(dbg, sibling, srcfiles, cnt); We loop around to actually print this, rather than recursing. Recursing is horribly wasteful of stack space. */ } else if (cdres == DW_DLV_ERROR) { print_error(dbg, "dwarf_siblingof", cdres, dacerr); } /* If we have a sibling, verify that its offset is next to the last processed DIE; An incorrect sibling chain is a nasty bug. */ if (cdres == DW_DLV_OK && sibling && glflags.gf_check_di_gaps && checking_this_compiler()) { Dwarf_Off glb_off; DWARF_CHECK_COUNT(di_gaps_result,1); if (dwarf_validate_die_sibling(sibling,&glb_off) == DW_DLV_ERROR) { Dwarf_Off sib_off; struct esb_s msg; esb_constructor(&msg); dwarf_dieoffset(sibling,&sib_off,&dacerr); esb_append_printf(&msg, "GSIB = 0x%" DW_PR_XZEROS DW_PR_DUx " GOFF = 0x%" DW_PR_XZEROS DW_PR_DUx " Gap = %" DW_PR_DUu " bytes", sib_off,glb_off,sib_off-glb_off); DWARF_CHECK_ERROR2(di_gaps_result, "Incorrect sibling chain",esb_get_string(&msg)); esb_destructor(&msg); } } /* Here do any post-descent (ie post-dwarf_child) processing of the in_die. */ EMPTY_DIE_STACK_ENTRY(die_stack_indent_level); if (in_die != in_die_in) { /* Dealloc our in_die, but not the argument die, it belongs to our caller. Whether the siblingof call worked or not. */ dwarf_dealloc(dbg, in_die, DW_DLA_DIE); in_die = 0; } if (cdres == DW_DLV_OK) { /* Set to process the sibling, loop again. */ in_die = sibling; } else { /* We are done, no more siblings at this level. */ break; } } /* end for loop on siblings */ return; } /* Print one die on error and verbose or non check mode */ #define PRINTING_DIES (glflags.gf_do_print_dwarf || (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode)) /* If print_information is FALSE, check the TAG and if it is a CU die print the information anyway. */ boolean print_one_die(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, boolean print_information, int die_indent_level, char **srcfiles, Dwarf_Signed cnt, boolean ignore_die_stack) { Dwarf_Signed i = 0; Dwarf_Signed j = 0; Dwarf_Off offset = 0; Dwarf_Off overall_offset = 0; const char * tagname = 0; Dwarf_Half tag = 0; Dwarf_Signed atcnt = 0; Dwarf_Attribute *atlist = 0; int tres = 0; int ores = 0; int atres = 0; int abbrev_code = dwarf_die_abbrev_code(die); boolean attribute_matched = FALSE; Dwarf_Error podie_err = 0; /* Print using indentation < 1><0x000854ff GOFF=0x00546047> DW_TAG_pointer_type -> 34 < 1><0x000854ff> DW_TAG_pointer_type -> 18 DW_TAG_pointer_type -> 2 */ /* Attribute indent. */ int nColumn = glflags.gf_show_global_offsets ? 34 : 18; if (glflags.gf_check_abbreviations && checking_this_compiler()) { validate_abbrev_code(dbg,abbrev_code); } if (!ignore_die_stack && die_stack[die_indent_level].already_printed_) { /* FALSE seems like a safe return. */ return FALSE; } /* Reset indentation column if no offsets */ if (!glflags.gf_display_offsets) { nColumn = 2; } tres = dwarf_tag(die, &tag, &podie_err); if (tres != DW_DLV_OK) { print_error(dbg, "accessing tag of die!", tres, podie_err); } tagname = get_TAG_name(tag,pd_dwarf_names_print_on_error); #ifdef HAVE_USAGE_TAG_ATTR /* Record usage of TAGs */ if ( glflags.gf_print_usage_tag_attr && tag < DW_TAG_last) { ++tag_usage[tag]; } #endif /* HAVE_USAGE_TAG_ATTR */ tag_specific_checks_setup(tag,die_indent_level); ores = dwarf_dieoffset(die, &overall_offset, &podie_err); if (ores != DW_DLV_OK) { print_error(dbg, "dwarf_dieoffset", ores, podie_err); } ores = dwarf_die_CU_offset(die, &offset, &podie_err); if (ores != DW_DLV_OK) { print_error(dbg, "dwarf_die_CU_offset", ores, podie_err); } if (dump_visited_info && glflags.gf_check_self_references) { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ", die_indent_level, (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); printf("%*s%s\n",die_indent_level * 2 + 2," ",tagname); } /* Print the die */ if (PRINTING_DIES && print_information) { if (!ignore_die_stack) { die_stack[die_indent_level].already_printed_ = TRUE; } if (die_indent_level == 0) { print_cu_hdr_cudie(dbg,die, overall_offset, offset); } else if (local_symbols_already_began == FALSE && die_indent_level == 1 && !glflags.dense) { printf("\nLOCAL_SYMBOLS:\n"); local_symbols_already_began = TRUE; } /* Print just the Tags and Attributes */ if (!glflags.gf_display_offsets) { /* Print using indentation */ printf("%*s%s\n",die_stack_indent_level * 2 + 2," ",tagname); } else { if (glflags.dense) { if (glflags.gf_show_global_offsets) { if (die_indent_level == 0) { printf("<%d><0x%" DW_PR_DUx "+0x%" DW_PR_DUx " GOFF=0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)(overall_offset - offset), (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); } else { printf("<%d><0x%" DW_PR_DUx " GOFF=0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); } } else { if (die_indent_level == 0) { printf("<%d><0x%" DW_PR_DUx "+0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)(overall_offset - offset), (Dwarf_Unsigned)offset); } else { printf("<%d><0x%" DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset); } } printf("<%s>",tagname); if (glflags.verbose) { Dwarf_Off agoff = 0; Dwarf_Unsigned acount = 0; printf(" "); } } else { if (glflags.gf_show_global_offsets) { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset, (Dwarf_Unsigned)overall_offset); } else { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx ">", die_indent_level, (Dwarf_Unsigned)offset); } /* Print using indentation */ printf("%*s%s",die_indent_level * 2 + 2," ",tagname); if (glflags.verbose) { Dwarf_Off agoff = 0; Dwarf_Unsigned acount = 0; printf(" "); } fputs("\n",stdout); } } } atres = dwarf_attrlist(die, &atlist, &atcnt, &podie_err); if (atres == DW_DLV_ERROR) { print_error(dbg, "dwarf_attrlist", atres, podie_err); } else if (atres == DW_DLV_NO_ENTRY) { /* indicates there are no attrs. It is not an error. */ atcnt = 0; } /* Reset any loose references to low or high PC */ bSawLow = FALSE; bSawHigh = FALSE; /* Get the offset for easy error reporting: This is not the CU die. */ dwarf_die_offsets(die,&glflags.DIE_overall_offset, &glflags.DIE_offset,&podie_err); for (i = 0; i < atcnt; i++) { Dwarf_Half attr; int ares; ares = dwarf_whatattr(atlist[i], &attr, &podie_err); if (ares == DW_DLV_OK) { /* Check duplicated attributes; use brute force as the number of attributes is quite small; the problem was detected with the LLVM toolchain, generating more than 12 repeated attributes */ if (glflags.gf_check_duplicated_attributes) { Dwarf_Half attr_next; DWARF_CHECK_COUNT(duplicated_attributes_result,1); for (j = i + 1; j < atcnt; ++j) { ares = dwarf_whatattr(atlist[j], &attr_next, &podie_err); if (ares == DW_DLV_OK) { if (attr == attr_next) { DWARF_CHECK_ERROR2(duplicated_attributes_result, "Duplicated attribute ", get_AT_name(attr,pd_dwarf_names_print_on_error)); } } else { print_error(dbg, "dwarf_whatattr entry missing", ares, podie_err); } } } /* Print using indentation */ if (!glflags.dense && PRINTING_DIES && print_information) { printf("%*s",die_indent_level * 2 + 2 + nColumn," "); } { boolean attr_match = print_attribute(dbg, die, dieprint_cu_goffset, attr, atlist[i], print_information, die_indent_level, srcfiles, cnt); if (print_information == FALSE && attr_match) { attribute_matched = TRUE; } } if (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode) { glflags.gf_record_dwarf_error = FALSE; } } else { print_error(dbg, "dwarf_whatattr entry missing", ares, podie_err); } } for (i = 0; i < atcnt; i++) { dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); } if (atres == DW_DLV_OK) { dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } if (PRINTING_DIES && glflags.dense && print_information) { printf("\n"); } return attribute_matched; } /* Encodings have undefined signedness. Accept either signedness. The values are integer-like (they are defined in the DWARF specification), so the form the compiler uses (as long as it is a constant value) is a non-issue. The numbers need not be small (in spite of the function name), but the result should be an integer. If string_out is non-NULL, construct a string output, either an error message or the name of the encoding. The function pointer passed in is to code generated by a script at dwarfdump build time. The code for the val_as_string function is generated from dwarf.h. See /dwarf_names.c The known_signed bool is set true(nonzero) or false (zero) and *both* uval_out and sval_out are set to the value, though of course uval_out cannot represent a signed value properly and sval_out cannot represent all unsigned values properly. If string_out is non-NULL then attr_name and val_as_string must also be non-NULL. */ static int get_small_encoding_integer_and_name(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Unsigned * uval_out, const char *attr_name, struct esb_s* string_out, encoding_type_func val_as_string, Dwarf_Error * seierr, int show_form) { Dwarf_Unsigned uval = 0; int vres = dwarf_formudata(attrib, &uval, seierr); if (vres != DW_DLV_OK) { Dwarf_Signed sval = 0; if(vres == DW_DLV_ERROR) { dwarf_dealloc(dbg,*seierr, DW_DLV_ERROR); *seierr = 0; } vres = dwarf_formsdata(attrib, &sval, seierr); if (vres != DW_DLV_OK) { vres = dwarf_global_formref(attrib,&uval,seierr); if (vres != DW_DLV_OK) { if (string_out != 0) { esb_append_printf_s(string_out, "%s has a bad form.", attr_name); } return vres; } *uval_out = uval; } else { uval = (Dwarf_Unsigned) sval; *uval_out = uval; } } else { *uval_out = uval; } if (string_out) { Dwarf_Half theform = 0; Dwarf_Half directform = 0; struct esb_s fstring; esb_constructor(&fstring); get_form_values(dbg,attrib,&theform,&directform); esb_append(&fstring, val_as_string((Dwarf_Half) uval, pd_dwarf_names_print_on_error)); show_form_itself(show_form,glflags.verbose,theform, directform,&fstring); esb_append(string_out,esb_get_string(&fstring)); esb_destructor(&fstring); } return DW_DLV_OK; } /* Called for DW_AT_SUN_func_offsets We need a 32-bit signed number here. But we're getting rid of the __[u]int[n]_t dependence so lets use plain characters. */ static void get_FLAG_BLOCK_string(Dwarf_Debug dbg, Dwarf_Attribute attrib, struct esb_s*esbp) { int fres = 0; Dwarf_Block *tempb = 0; Dwarf_Unsigned array_len = 0; Dwarf_Signed *array = 0; Dwarf_Unsigned next = 0; Dwarf_Error fblkerr = 0; /* first get compressed block data */ fres = dwarf_formblock (attrib,&tempb, &fblkerr); if (fres != DW_DLV_OK) { print_error(dbg,"DW_FORM_blockn cannot get block\n", fres,fblkerr); return; } fres = dwarf_uncompress_integer_block_a(dbg, tempb->bl_len, (void *)tempb->bl_data, &array_len,&array,&fblkerr); /* uncompress block into 32bit signed int array. It's really a block of sleb numbers so the compression is minor unless the values are close to zero. */ if (fres != DW_DLV_OK) { print_error(dbg,"DW_AT_SUN_func_offsets cannot uncompress data\n",0,fblkerr); return; } if (array_len == 0) { print_error(dbg,"DW_AT_SUN_func_offsets has no data\n",0,fblkerr); return; } /* fill in string buffer */ next = 0; while (next < array_len) { unsigned i = 0; /* Print a full line */ esb_append(esbp,"\n "); for(i = 0 ; i < 2 && next < array_len; ++i,++next) { Dwarf_Signed vs = array[next]; Dwarf_Unsigned vu = (Dwarf_Unsigned)vs; if (i== 1) { esb_append(esbp," "); } esb_append_printf_i(esbp,"%6" DW_PR_DSd " ",vs); esb_append_printf_u(esbp, "(0x%" DW_PR_XZEROS DW_PR_DUx ")",vu); } } /* free array buffer */ dwarf_dealloc_uncompressed_block(dbg, array); } static const char * get_rangelist_type_descr(Dwarf_Ranges *r) { switch (r->dwr_type) { case DW_RANGES_ENTRY: return "range entry"; case DW_RANGES_ADDRESS_SELECTION: return "addr selection"; case DW_RANGES_END: return "range end"; } /* Impossible. */ return "Unknown"; } void print_ranges_list_to_extra(Dwarf_Debug dbg, Dwarf_Unsigned off, Dwarf_Ranges *rangeset, Dwarf_Signed rangecount, Dwarf_Unsigned bytecount, struct esb_s *stringbuf) { #ifdef ORIGINAL_SPRINTF char tmp[200]; #endif const char * sec_name = 0; Dwarf_Signed i = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); /* We don't want to set the compress data into the secname here. */ get_true_section_name(dbg,".debug_ranges", &truename,FALSE); sec_name = esb_get_string(&truename); if (glflags.dense) { #ifdef ORIGINAL_SPRINTF snprintf(tmp,sizeof(tmp), "< ranges: %" DW_PR_DSd " ranges at %s offset %" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ") " "(%" DW_PR_DUu " bytes)>", rangecount, sec_name, off, off, bytecount); esb_append(stringbuf,tmp); #else esb_append_printf_i(stringbuf,"< ranges: %" DW_PR_DSd,rangecount); esb_append_printf_s(stringbuf," ranges at %s" ,sec_name); esb_append_printf_u(stringbuf," offset %" DW_PR_DUu ,off); esb_append_printf_u(stringbuf," (0x%" DW_PR_XZEROS DW_PR_DUx,off); esb_append_printf_u(stringbuf,") " "(%" DW_PR_DUu " bytes)>",bytecount); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(tmp,sizeof(tmp), "\t\tranges: %" DW_PR_DSd " at %s offset %" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ") " "(%" DW_PR_DUu " bytes)\n", rangecount, sec_name, off, off, bytecount); esb_append(stringbuf,tmp); #else esb_append_printf_i(stringbuf,"\t\tranges: %" DW_PR_DSd,rangecount); esb_append_printf_s(stringbuf," at %s" ,sec_name); esb_append_printf_u(stringbuf," offset %" DW_PR_DUu ,off); esb_append_printf_u(stringbuf," (0x%" DW_PR_XZEROS DW_PR_DUx,off); esb_append_printf_u(stringbuf,") " "(%" DW_PR_DUu " bytes)\n",bytecount); #endif } for (i = 0; i < rangecount; ++i) { Dwarf_Ranges * r = rangeset +i; const char *type = get_rangelist_type_descr(r); if (glflags.dense) { #ifdef ORIGINAL_SPRINTF snprintf(tmp,sizeof(tmp), "<[%2" DW_PR_DSd "] %s 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx ">", (Dwarf_Signed)i, type, (Dwarf_Unsigned)r->dwr_addr1, (Dwarf_Unsigned)r->dwr_addr2); esb_append(stringbuf,tmp); #else esb_append_printf_i(stringbuf,"<[%2" DW_PR_DSd,i); esb_append_printf_s(stringbuf,"] %s",type); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx,r->dwr_addr1); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx ">",r->dwr_addr2); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(tmp,sizeof(tmp), "\t\t\t[%2" DW_PR_DSd "] %-14s 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Signed)i, type, (Dwarf_Unsigned)r->dwr_addr1, (Dwarf_Unsigned)r->dwr_addr2); esb_append(stringbuf,tmp); #else esb_append_printf_i(stringbuf,"\t\t\t[%2" DW_PR_DSd,i); esb_append_printf_s(stringbuf,"] %-14s",type); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx,r->dwr_addr1); esb_append_printf_u(stringbuf," 0x%" DW_PR_XZEROS DW_PR_DUx "\n",r->dwr_addr2); #endif } } esb_destructor(&truename); } static void do_dump_visited_info(int level, Dwarf_Off loff,Dwarf_Off goff, Dwarf_Off cu_die_goff, const char *atname, const char *valname) { printf("<%2d><0x%" DW_PR_XZEROS DW_PR_DUx " GOFF=0x%" DW_PR_XZEROS DW_PR_DUx " CU-GOFF=0x%" DW_PR_XZEROS DW_PR_DUx "> ", level, loff, goff,cu_die_goff); printf("%*s%s -> %s\n",level * 2 + 2, " ",atname,valname); } /* DW_FORM_data16 should not apply here. */ static boolean is_location_form(int form) { if (form == DW_FORM_block1 || form == DW_FORM_block2 || form == DW_FORM_block4 || form == DW_FORM_block || form == DW_FORM_data4 || form == DW_FORM_data8 || form == DW_FORM_sec_offset) { return TRUE; } return FALSE; } static void show_attr_form_error(Dwarf_Debug dbg,unsigned attr, unsigned form, struct esb_s *out) { const char *n = 0; int res = 0; Dwarf_Error formerr = 0; #ifdef ORIGINAL_SPRINTF char buf[30]; #endif esb_append(out,"ERROR: Attribute "); #ifdef ORIGINAL_SPRINTF snprintf(buf,sizeof(buf),"%u",attr); esb_append(out,buf); #else esb_append_printf_u(out,"%u",attr); #endif esb_append(out," ("); res = dwarf_get_AT_name(attr,&n); if (res != DW_DLV_OK) { n = "UknownAttribute"; } esb_append(out,n); esb_append(out,") "); esb_append(out," has form "); #ifdef ORIGINAL_SPRINTF snprintf(buf,sizeof(buf),"%u",form); esb_append(out,buf); #else esb_append_printf_u(out,"%u",form); #endif esb_append(out," ("); res = dwarf_get_FORM_name(form,&n); if (res != DW_DLV_OK) { n = "UknownForm"; } esb_append(out,n); esb_append(out,"), a form which is not appropriate"); print_error_and_continue(dbg,esb_get_string(out), DW_DLV_OK,formerr); } /* Traverse an attribute and following any reference in order to detect self references to DIES (loop). */ static boolean traverse_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, Dwarf_Half attr, Dwarf_Attribute attr_in, UNUSEDARG boolean print_information, char **srcfiles, Dwarf_Signed cnt, int die_indent_level) { Dwarf_Attribute attrib = 0; const char * atname = 0; int tres = 0; Dwarf_Half tag = 0; boolean circular_reference = FALSE; struct esb_s valname; Dwarf_Error err = 0; esb_constructor(&valname); is_info = dwarf_get_die_infotypes_flag(die); atname = get_AT_name(attr,pd_dwarf_names_print_on_error); /* The following gets the real attribute, even in the face of an incorrect doubling, or worse, of attributes. */ attrib = attr_in; /* Do not get attr via dwarf_attr: if there are (erroneously) multiple of an attr in a DIE, dwarf_attr will not get the second, erroneous one and dwarfdump will print the first one multiple times. Oops. */ tres = dwarf_tag(die, &tag, &err); if (tres == DW_DLV_ERROR) { tag = 0; } else if (tres == DW_DLV_NO_ENTRY) { tag = 0; } else { /* ok */ } switch (attr) { case DW_AT_specification: case DW_AT_abstract_origin: case DW_AT_type: { int res = 0; Dwarf_Off die_goff = 0; Dwarf_Off ref_goff = 0; Dwarf_Die ref_die = 0; struct esb_s specificationstr; Dwarf_Half theform = 0; Dwarf_Half directform = 0; char buf[100]; get_form_values(dbg,attrib,&theform,&directform); if (!form_refers_local_info(theform)) { break; } esb_constructor_fixed(&specificationstr,buf,sizeof(buf)); ++die_indent_level; get_attr_value(dbg, tag, die, dieprint_cu_goffset, attrib, srcfiles, cnt, &specificationstr,glflags.show_form_used,glflags.verbose); esb_append(&valname, esb_get_string(&specificationstr)); esb_destructor(&specificationstr); /* Get the global offset for reference */ res = dwarf_global_formref(attrib, &ref_goff, &err); if (res != DW_DLV_OK) { int dwerrno = dwarf_errno(err); if (dwerrno == DW_DLE_REF_SIG8_NOT_HANDLED ) { /* No need to stop, ref_sig8 refers out of the current section. */ break; } else { print_error(dbg, "dwarf_global_formref fails in traversal", res, err); } } /* Gives global offset in section. */ res = dwarf_dieoffset(die, &die_goff, &err); if (res != DW_DLV_OK) { int dwerrno = dwarf_errno(err); if (dwerrno == DW_DLE_REF_SIG8_NOT_HANDLED ) { /* No need to stop, ref_sig8 refers out of the current section. */ break; } else { print_error(dbg, "dwarf_dieoffset fails in traversal", res, err); } } /* Follow reference chain, looking for self references */ res = dwarf_offdie_b(dbg,ref_goff,is_info,&ref_die,&err); if (res == DW_DLV_OK) { Dwarf_Off target_die_cu_goff = 0; if (dump_visited_info) { Dwarf_Off die_loff = 0; res = dwarf_die_CU_offset(die, &die_loff, &err); DROP_ERROR_INSTANCE(dbg,res,err); do_dump_visited_info(die_indent_level,die_loff,die_goff, dieprint_cu_goffset, atname,esb_get_string(&valname)); } ++die_indent_level; res =dwarf_CU_dieoffset_given_die(ref_die, &target_die_cu_goff, &err); if (res != DW_DLV_OK) { print_error(dbg, "dwarf_dieoffset() accessing cu_goff die!", res, err); } circular_reference = traverse_one_die(dbg,attrib,ref_die, target_die_cu_goff, is_info, srcfiles,cnt,die_indent_level); DeleteKeyInBucketGroup(glflags.pVisitedInfo,ref_goff); dwarf_dealloc(dbg,ref_die,DW_DLA_DIE); --die_indent_level; ref_die = 0; } } break; } /* End switch. */ esb_destructor(&valname); return circular_reference; } /* Traverse one DIE in order to detect self references to DIES. This fails to deal with changing CUs via global references so srcfiles and cnt are sometimes bogus. FIXME */ static boolean traverse_one_die(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Bool is_info, char **srcfiles, Dwarf_Signed cnt, int die_indent_level) { Dwarf_Half tag = 0; Dwarf_Off overall_offset = 0; Dwarf_Signed atcnt = 0; int res = 0; boolean circular_reference = FALSE; boolean print_information = FALSE; Dwarf_Error err = 0; res = dwarf_tag(die, &tag, &err); if (res != DW_DLV_OK) { print_error(dbg, "accessing tag of die!", res, err); } res = dwarf_dieoffset(die, &overall_offset, &err); if (res != DW_DLV_OK) { print_error(dbg, "dwarf_dieoffset", res, err); } if (dump_visited_info) { Dwarf_Off offset = 0; const char * tagname = 0; res = dwarf_die_CU_offset(die, &offset, &err); if (res != DW_DLV_OK) { print_error(dbg, "dwarf_die_CU_offset", res, err); } tagname = get_TAG_name(tag,pd_dwarf_names_print_on_error); do_dump_visited_info(die_indent_level,offset,overall_offset, dieprint_cu_goffset, tagname,""); } DWARF_CHECK_COUNT(self_references_result,1); if (FindKeyInBucketGroup(glflags.pVisitedInfo,overall_offset)) { char * localvaln = NULL; Dwarf_Half attr = 0; struct esb_s bucketgroupstr; const char *atname = NULL; int wres = 0; esb_constructor(&bucketgroupstr); get_attr_value(dbg, tag, die, dieprint_cu_goffset, attrib, srcfiles, cnt, &bucketgroupstr, glflags.show_form_used, glflags.verbose); localvaln = esb_get_string(&bucketgroupstr); wres = dwarf_whatattr(attrib, &attr, &err); if (wres == DW_DLV_ERROR) { /* Lets not attempt to deal with the error, just lets not look for atname */ dwarf_dealloc(dbg,err,DW_DLA_ERROR); atname = " 2 && val[l-1] == '"') { esb_appendn(es,val+1,l-2); return; } } esb_append(es,val); } static int have_a_search_match(const char *valname,const char *atname) { /* valname may have had quotes inserted, but search_match_text will not. So we need to use a new copy, not valname here. */ struct esb_s esb_match; char *s2; esb_constructor(&esb_match); trim_quotes(valname,&esb_match); s2 = esb_get_string(&esb_match); if (glflags.search_match_text ) { if (!strcmp(s2,glflags.search_match_text) || !strcmp(atname,glflags.search_match_text)) { esb_destructor(&esb_match); return TRUE; } } if (glflags.search_any_text) { if (is_strstrnocase(s2,glflags.search_any_text) || is_strstrnocase(atname,glflags.search_any_text)) { esb_destructor(&esb_match); return TRUE; } } #ifdef HAVE_REGEX if (glflags.search_regex_text) { if (!regexec(glflags.search_re,s2,0,NULL,0) || !regexec(glflags.search_re,atname,0,NULL,0)) { esb_destructor(&esb_match); return TRUE; } } #endif esb_destructor(&esb_match); return FALSE; } /* Use our local die_stack to try to determine signedness of the DW_AT_discr_list LEB numbers. Returns -1 if we know it is signed. Returns 1 if we know it is unsigned. Returns 0 if we really do not know. */ static int determine_discr_signedness(Dwarf_Debug dbg) { Dwarf_Die parent = 0; Dwarf_Half tag = 0; int tres = 0; Dwarf_Error descrerr = 0; if (die_stack_indent_level < 1) { /* We have no idea. */ return 0; } parent = die_stack[die_stack_indent_level -1].die_; if (!parent) { /* We have no idea. */ return 0; } tres = dwarf_tag(parent, &tag, &descrerr); if (tres != DW_DLV_OK) { if(tres == DW_DLV_ERROR) { dwarf_dealloc(dbg, descrerr, DW_DLA_ERROR); descrerr =0; } return 0; } if (tag != DW_TAG_variant_part) { return 0; } /* Expect DW_AT_discr or DW_AT_type here, and if DW_AT_discr, that might have the DW_AT_type. */ /* FIXME: Initially lets just punt, say unsigned. */ return 1; } static void checksignv( struct esb_s *strout, const char *title, Dwarf_Signed sv, Dwarf_Unsigned uv) { #ifdef ORIGINAL_SPRINTF char tmpstrb[40]; #endif /* The test and output are not entirely meaningful, but it can be useful for readers of dwarfdump output. */ if (uv == (Dwarf_Unsigned)sv) { /* Nothing to do here. */ return; } esb_append(strout," <"); esb_append(strout,title); esb_append(strout," "); #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DSd,sv); esb_append(strout,tmpstrb); esb_append(strout,":"); #else esb_append_printf_i(strout,"%" DW_PR_DSd ":",sv); #endif #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DUu,uv); esb_append(strout,tmpstrb); esb_append(strout,">"); #else esb_append_printf_u(strout,"%" DW_PR_DUu ">",uv); #endif } static void append_discr_array_vals(Dwarf_Debug dbg, Dwarf_Dsc_Head h, Dwarf_Unsigned arraycount, int isunsigned, struct esb_s *strout, Dwarf_Error*paerr) { #ifdef ORIGINAL_SPRINTF char tmpstrb[200]; #endif Dwarf_Unsigned u = 0; if (isunsigned == 0) { esb_append(strout, ""); } #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "\n discr list array len: " "%" DW_PR_DUu "\n", arraycount); esb_append(strout,tmpstrb); #else esb_append_printf_u(strout, "\n discr list array len: " "%" DW_PR_DUu "\n",arraycount); #endif for(u = 0; u < arraycount; u++) { int u2res = 0; Dwarf_Half dtype = 0; Dwarf_Signed slow = 0; Dwarf_Signed shigh = 0; Dwarf_Unsigned ulow = 0; Dwarf_Unsigned uhigh = 0; const char *dsc_name = ""; #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DUu,u); #endif u2res = dwarf_discr_entry_u(h,u, &dtype,&ulow,&uhigh,paerr); if (u2res == DW_DLV_ERROR) { print_error(dbg, "DW_AT_discr_list entry access fail\n", u2res, *paerr); } u2res = dwarf_discr_entry_s(h,u, &dtype,&slow,&shigh,paerr); if (u2res == DW_DLV_ERROR) { print_error(dbg, "DW_AT_discr_list entry access fail\n", u2res, *paerr); } if (u2res == DW_DLV_NO_ENTRY) { #ifdef ORIGINAL_SPRINTF esb_append(strout,"\n " "discr index missing! "); esb_append(strout,tmpstrb); #else esb_append_printf_u(strout, "\n " "discr index missing! %" DW_PR_DUu,u); #endif break; } #ifdef ORIGINAL_SPRINTF esb_append(strout," "); esb_append(strout,tmpstrb); esb_append(strout,": "); #else esb_append_printf_u(strout, " " "%" DW_PR_DUu ": ",u); #endif dsc_name = get_DSC_name(dtype,pd_dwarf_names_print_on_error); esb_append(strout,sanitized(dsc_name)); esb_append(strout," "); if (!dtype) { if (isunsigned < 0) { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DSd,slow); esb_append(strout,tmpstrb); #else esb_append_printf_i(strout,"%" DW_PR_DSd,slow); #endif checksignv(strout,"as signed:unsigned",slow,ulow); } else { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DUu,ulow); esb_append(strout,tmpstrb); #else esb_append_printf_u(strout,"%" DW_PR_DUu,ulow); #endif checksignv(strout,"as signed:unsigned",slow,ulow); } } else { if (isunsigned < 0) { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DSd,slow); esb_append(strout,tmpstrb); #else esb_append_printf_i(strout,"%" DW_PR_DSd,slow); #endif checksignv(strout,"as signed:unsigned",slow,ulow); } else { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), "%" DW_PR_DUu,ulow); esb_append(strout,tmpstrb); #else esb_append_printf_u(strout,"%" DW_PR_DUu,ulow); #endif checksignv(strout,"as signed:unsigned",slow,ulow); } if (isunsigned < 0) { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), ", %" DW_PR_DSd,shigh); esb_append(strout,tmpstrb); #else esb_append_printf_i(strout,", %" DW_PR_DSd,shigh); #endif checksignv(strout,"as signed:unsigned",shigh,uhigh); } else { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb,sizeof(tmpstrb), ", %" DW_PR_DUu,uhigh); esb_append(strout,tmpstrb); #else esb_append_printf_u(strout,", %" DW_PR_DUu,uhigh); #endif checksignv(strout,"as signed:unsigned",shigh,uhigh); } } esb_append(strout,"\n"); } } /* Only two types of CU can have highpc or lowpc. */ static boolean tag_type_is_addressable_cu(int tag) { if (tag == DW_TAG_compile_unit) { return TRUE; } if (tag == DW_TAG_partial_unit) { return TRUE; } return FALSE; } static void handle_location_description(Dwarf_Debug dbg, Dwarf_Attribute attrib, Dwarf_Die die, Dwarf_Half attr, struct esb_s *valname) { /* The value is a location description or location list. */ struct esb_s framebasestr; Dwarf_Half theform = 0; Dwarf_Half directform = 0; esb_constructor(&framebasestr); get_form_values(dbg,attrib,&theform,&directform); if (is_location_form(theform)) { get_location_list(dbg, die, attrib, &framebasestr); show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform, &framebasestr); } else if (theform == DW_FORM_exprloc) { int showhextoo = 1; print_exprloc_content(dbg,die,attrib,showhextoo,&framebasestr); } else { show_attr_form_error(dbg,attr,theform,&framebasestr); } esb_empty_string(valname); esb_append(valname, esb_get_string(&framebasestr)); esb_destructor(&framebasestr); } static boolean print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Half attr, Dwarf_Attribute attr_in, boolean print_information, int die_indent_level, char **srcfiles, Dwarf_Signed cnt) { Dwarf_Attribute attrib = 0; Dwarf_Unsigned uval = 0; const char * atname = 0; struct esb_s valname; struct esb_s esb_extra; int tres = 0; Dwarf_Half tag = 0; int append_extra_string = 0; boolean found_search_attr = FALSE; boolean bTextFound = FALSE; Dwarf_Bool is_info = FALSE; Dwarf_Addr elf_max_address = 0; Dwarf_Error paerr = 0; char valbuf[500]; char xtrabuf[200]; #ifdef ORIGINAL_SPRINTF esb_constructor(&esb_extra); esb_constructor(&valname); #else esb_constructor_fixed(&esb_extra,valbuf,sizeof(valbuf)); esb_constructor_fixed(&valname,xtrabuf,sizeof(xtrabuf)); #endif is_info = dwarf_get_die_infotypes_flag(die); atname = get_AT_name(attr,pd_dwarf_names_print_on_error); get_address_size_and_max(dbg,0,&elf_max_address,&paerr); /* The following gets the real attribute, even in the face of an incorrect doubling, or worse, of attributes. */ attrib = attr_in; /* Do not get attr via dwarf_attr: if there are (erroneously) multiple of an attr in a DIE, dwarf_attr will not get the second, erroneous one and dwarfdump will print the first one multiple times. Oops. */ tres = dwarf_tag(die, &tag, &paerr); if (tres == DW_DLV_ERROR) { tag = 0; } else if (tres == DW_DLV_NO_ENTRY) { tag = 0; } else { /* ok */ } if ((glflags.gf_check_attr_tag || glflags.gf_print_usage_tag_attr)&& checking_this_compiler()) { const char *tagname = ""; DWARF_CHECK_COUNT(attr_tag_result,1); if (tres == DW_DLV_ERROR) { DWARF_CHECK_ERROR3(attr_tag_result,tagname, get_AT_name(attr,pd_dwarf_names_print_on_error), "check the tag-attr combination, dwarf_tag failed."); } else if (tres == DW_DLV_NO_ENTRY) { DWARF_CHECK_ERROR3(attr_tag_result,tagname, get_AT_name(attr,pd_dwarf_names_print_on_error), "check the tag-attr combination, dwarf_tag NO ENTRY?."); } else if (legal_tag_attr_combination(tag, attr)) { /* OK */ } else { /* Report errors only if tag-attr check is on */ if (glflags.gf_check_attr_tag) { tagname = get_TAG_name(tag,pd_dwarf_names_print_on_error); tag_specific_checks_setup(tag,die_stack_indent_level); DWARF_CHECK_ERROR3(attr_tag_result,tagname, get_AT_name(attr,pd_dwarf_names_print_on_error), "check the tag-attr combination"); } } } switch (attr) { case DW_AT_language: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_language", &valname, get_LANG_name, &paerr, glflags.show_form_used); break; case DW_AT_accessibility: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_accessibility", &valname, get_ACCESS_name, &paerr, glflags.show_form_used); break; case DW_AT_visibility: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_visibility", &valname, get_VIS_name, &paerr, glflags.show_form_used); break; case DW_AT_virtuality: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_virtuality", &valname, get_VIRTUALITY_name, &paerr, glflags.show_form_used); break; case DW_AT_identifier_case: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_identifier", &valname, get_ID_name, &paerr, glflags.show_form_used); break; case DW_AT_inline: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_inline", &valname, get_INL_name, &paerr, glflags.show_form_used); break; case DW_AT_encoding: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_encoding", &valname, get_ATE_name, &paerr, glflags.show_form_used); break; case DW_AT_ordering: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_ordering", &valname, get_ORD_name, &paerr, glflags.show_form_used); break; case DW_AT_calling_convention: get_small_encoding_integer_and_name(dbg, attrib, &uval, "DW_AT_calling_convention", &valname, get_CC_name, &paerr, glflags.show_form_used); break; case DW_AT_discr_list: { /* DWARF2 */ /* This has one of the block forms. It should be in a DW_TAG_variant. Up to September 2016 it was treated as integer or name here, which was quite wrong. */ enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN; Dwarf_Half theform = 0; Dwarf_Half directform = 0; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; int wres = 0; get_form_values(dbg,attrib,&theform,&directform); wres = dwarf_get_version_of_die(die,&version,&offset_size); if (wres != DW_DLV_OK) { print_error(dbg,"ERROR: Cannot get DIE context version number", DW_DLV_OK,paerr); break; } fc = dwarf_get_form_class(version,attr,offset_size,theform); if (fc == DW_FORM_CLASS_BLOCK) { int fres = 0; Dwarf_Block *tempb = 0; /* the block is a series of entries each of one of these formats: DW_DSC_label caselabel DW_DSC_range lowvalue highvalue The values are all LEB. Signed or unsigned depending on the DW_TAG_variant_part owning the DW_TAG_variant. The DW_TAG_variant_part will have a DW_AT_type or a DW_AT_discr and that attribute will reveal the signedness of all the leb values. As a practical matter DW_DSC_label/DW_DSC_range value (zero or one, so far) can safely be read as ULEB or SLEB and one gets a valid value whereas the caselabel, lowvalue,highvalue must be decoded with the proper sign. the high level (dwarfdump in this case) is the agent that should determine the proper signedness. */ fres = dwarf_formblock(attrib, &tempb, &paerr); if (fres == DW_DLV_OK) { struct esb_s bformstr; int isunsigned = 0; /* Meaning unknown */ Dwarf_Dsc_Head h = 0; Dwarf_Unsigned arraycount = 0; int sres = 0; #ifdef ORIGINAL_SPRINTF esb_constructor(&bformstr); #else char fbuf[256]; esb_constructor_fixed(&bformstr,fbuf,sizeof(fbuf)); #endif show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform,&bformstr); isunsigned = determine_discr_signedness(dbg); esb_empty_string(&valname); sres = dwarf_discr_list(dbg, (Dwarf_Small *)tempb->bl_data, tempb->bl_len, &h,&arraycount,&paerr); if (sres == DW_DLV_NO_ENTRY) { esb_append(&bformstr,""); break; } if (sres == DW_DLV_ERROR) { print_error(dbg, "DW_AT_discr_list access fail\n", sres, paerr); } append_discr_array_vals(dbg,h,arraycount, isunsigned,&bformstr,&paerr); if (glflags.verbose > 1) { unsigned u = 0; #ifdef ORIGINAL_SPRINTF char tmpstrb[100]; snprintf(tmpstrb,sizeof(tmpstrb), "\n block byte len:" "0x%" DW_PR_XZEROS DW_PR_DUx "\n ", tempb->bl_len); esb_append(&bformstr, tmpstrb); #else esb_append_printf_u(&bformstr, "\n block byte len:" "0x%" DW_PR_XZEROS DW_PR_DUx "\n ",tempb->bl_len); #endif for (u = 0; u < tempb->bl_len; u++) { #ifdef ORIGINAL_SPRINTF snprintf(tmpstrb, sizeof(tmpstrb), "%02x ", *(u + (unsigned char *)tempb->bl_data)); esb_append(&bformstr, tmpstrb); #else esb_append_printf_u(&bformstr, "%02x ", *(u + (unsigned char *)tempb->bl_data)); #endif } } esb_append(&valname, esb_get_string(&bformstr)); dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); esb_destructor(&bformstr); tempb = 0; } else { print_error(dbg, "DW_FORM_blockn cannot get block\n", fres, paerr); } } else { print_error(dbg, "DW_AT_discr_list is not form BLOCK\n", DW_DLV_OK, paerr); } } break; case DW_AT_data_member_location: { /* Value is a constant or a location description or location list. If a constant, it could be signed or unsigned. Telling whether a constant or a reference is nontrivial since DW_FORM_data{4,8} could be either in DWARF{2,3} */ enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN; Dwarf_Half theform = 0; Dwarf_Half directform = 0; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; int wres = 0; get_form_values(dbg,attrib,&theform,&directform); wres = dwarf_get_version_of_die(die,&version,&offset_size); if (wres != DW_DLV_OK) { print_error(dbg,"ERROR: Cannot get DIE context version number", DW_DLV_OK,paerr); break; } fc = dwarf_get_form_class(version,attr,offset_size,theform); if (fc == DW_FORM_CLASS_CONSTANT) { struct esb_s classconstantstr; esb_constructor(&classconstantstr); /* Makes no sense to look at type of our DIE to determine how to print the constant. */ wres = formxdata_print_value(dbg,NULL,attrib, theform, &classconstantstr, &paerr, FALSE); show_form_itself(glflags.show_form_used, glflags.verbose, theform, directform, &classconstantstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&classconstantstr)); esb_destructor(&classconstantstr); if (wres == DW_DLV_OK){ /* String appended already. */ break; } else if (wres == DW_DLV_NO_ENTRY) { print_error(dbg,"Cannot get DW_AT_data_member_location, how can it be NO_ENTRY? ",wres,paerr); break; } else { print_error(dbg,"Cannot get DW_AT_data_member_location ",wres,paerr); break; } } /* FALL THRU, this is a a location description, or a reference to one, or a mistake. */ } handle_location_description(dbg,attrib,die, attr,&valname); break; case DW_AT_location: case DW_AT_vtable_elem_location: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_use_location: case DW_AT_static_link: case DW_AT_frame_base: handle_location_description(dbg,attrib,die, attr,&valname); break; case DW_AT_SUN_func_offsets: { /* value is a location description or location list */ Dwarf_Half theform = 0; Dwarf_Half directform = 0; char buf[100]; struct esb_s funcformstr; esb_constructor_fixed(&funcformstr,buf,sizeof(buf)); get_form_values(dbg,attrib,&theform,&directform); get_FLAG_BLOCK_string(dbg, attrib,&funcformstr); show_form_itself(glflags.show_form_used,glflags.verbose, theform, directform,&funcformstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&funcformstr)); esb_destructor(&funcformstr); } break; case DW_AT_SUN_cf_kind: { Dwarf_Half kind = 0; Dwarf_Unsigned tempud = 0; Dwarf_Error cferr = 0; int wres = 0; Dwarf_Half theform = 0; Dwarf_Half directform = 0; struct esb_s cfkindstr; esb_constructor(&cfkindstr); get_form_values(dbg,attrib,&theform,&directform); wres = dwarf_formudata (attrib,&tempud, &cferr); if (wres == DW_DLV_OK) { kind = tempud; esb_append(&cfkindstr, get_ATCF_name(kind,pd_dwarf_names_print_on_error)); } else if (wres == DW_DLV_NO_ENTRY) { esb_append(&cfkindstr, "?"); } else { print_error(dbg,"Cannot get formudata....",wres,cferr); esb_append(&cfkindstr, "??"); } show_form_itself(glflags.show_form_used,glflags.verbose,theform, directform,&cfkindstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&cfkindstr)); esb_destructor(&cfkindstr); } break; case DW_AT_upper_bound: { Dwarf_Half theform; int rv; struct esb_s upperboundstr; esb_constructor(&upperboundstr); rv = dwarf_whatform(attrib,&theform,&paerr); /* depending on the form and the attribute, process the form */ if (rv == DW_DLV_ERROR) { print_error(dbg, "dwarf_whatform Cannot find attr form", rv, paerr); } else if (rv == DW_DLV_NO_ENTRY) { esb_destructor(&upperboundstr); break; } switch (theform) { case DW_FORM_block1: { Dwarf_Half btheform = 0; Dwarf_Half directform = 0; get_form_values(dbg,attrib,&btheform,&directform); get_location_list(dbg, die, attrib, &upperboundstr); show_form_itself(glflags.show_form_used,glflags.verbose, btheform, directform,&upperboundstr); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&upperboundstr)); } break; default: get_attr_value(dbg, tag, die, dieprint_cu_goffset, attrib, srcfiles, cnt, &upperboundstr, glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&upperboundstr)); break; } esb_destructor(&upperboundstr); break; } case DW_AT_low_pc: case DW_AT_high_pc: { Dwarf_Half theform; int rv; /* For DWARF4, the high_pc offset from the low_pc */ Dwarf_Unsigned highpcOff = 0; Dwarf_Bool offsetDetected = FALSE; struct esb_s highpcstr; esb_constructor(&highpcstr); rv = dwarf_whatform(attrib,&theform,&paerr); /* Depending on the form and the attribute, process the form. */ if (rv == DW_DLV_ERROR) { print_error(dbg, "dwarf_whatform cannot Find attr form", rv, paerr); } else if (rv == DW_DLV_NO_ENTRY) { break; } if (theform != DW_FORM_addr && theform != DW_FORM_GNU_addr_index && theform != DW_FORM_addrx) { /* New in DWARF4: other forms (of class constant) are not an address but are instead offset from pc. One could test for DWARF4 here before adding this string, but that seems unnecessary as this could not happen with DWARF3 or earlier. A normal consumer would have to add this value to DW_AT_low_pc to get a true pc. */ esb_append(&highpcstr,""); /* Update the high_pc value if we are checking the ranges */ if ( glflags.gf_check_ranges && attr == DW_AT_high_pc) { /* Get the offset value */ int show_form_here = 0; int res = get_small_encoding_integer_and_name(dbg, attrib, &highpcOff, /* attrname */ (const char *) NULL, /* err_string */ ( struct esb_s *) NULL, (encoding_type_func) 0, &paerr,show_form_here); if (res != DW_DLV_OK) { print_error(dbg, "get_small_encoding_integer_and_name", res, paerr); } offsetDetected = TRUE; } } get_attr_value(dbg, tag, die, dieprint_cu_goffset, attrib, srcfiles, cnt, &highpcstr,glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&highpcstr)); esb_destructor(&highpcstr); /* Update base and high addresses for CU */ if (glflags.seen_CU && (glflags.need_CU_base_address || glflags.need_CU_high_address)) { /* Update base address for CU */ if (attr == DW_AT_low_pc) { if (glflags.need_CU_base_address && tag_type_is_addressable_cu(tag)) { int res = dwarf_formaddr(attrib, &glflags.CU_base_address, &paerr); DROP_ERROR_INSTANCE(dbg,res,paerr); if (res == DW_DLV_OK) { glflags.need_CU_base_address = FALSE; glflags.CU_low_address = glflags.CU_base_address; } } else if (!glflags.CU_low_address) { /* We take the first non-zero address as meaningful. Even if no such in CU DIE. */ int res = dwarf_formaddr(attrib, &glflags.CU_low_address, &paerr); DROP_ERROR_INSTANCE(dbg,res,paerr); if (res == DW_DLV_OK) { /* Stop looking for base. Bogus, but there is none available, so stop. */ glflags.need_CU_base_address = FALSE; } } } /* Update high address for CU */ if (attr == DW_AT_high_pc) { if (glflags.need_CU_high_address ) { /* This is bogus in that it accepts the first high address in the CU, from any TAG */ int res = dwarf_formaddr(attrib, &glflags.CU_high_address, &paerr); DROP_ERROR_INSTANCE(dbg,res,paerr); if (res == DW_DLV_OK) { glflags.need_CU_high_address = FALSE; } } } } /* Record the low and high addresses as we have them */ /* For DWARF4 allow the high_pc value as an offset */ if ((glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations) && ((theform == DW_FORM_addr || theform == DW_FORM_GNU_addr_index || theform == DW_FORM_addrx) || offsetDetected)) { int res = 0; Dwarf_Addr addr = 0; /* Calculate the real high_pc value */ if (offsetDetected && glflags.seen_PU_base_address) { addr = lowAddr + highpcOff; res = DW_DLV_OK; } else { res = dwarf_formaddr(attrib, &addr, &paerr); DROP_ERROR_INSTANCE(dbg,res,paerr); } if(res == DW_DLV_OK) { if (attr == DW_AT_low_pc) { lowAddr = addr; bSawLow = TRUE; /* Record the base address of the last seen PU to be used when checking line information */ if (glflags.seen_PU && !glflags.seen_PU_base_address) { glflags.seen_PU_base_address = TRUE; glflags.PU_base_address = addr; } } else { /* DW_AT_high_pc */ highAddr = addr; bSawHigh = TRUE; /* Record the high address of the last seen PU to be used when checking line information */ if (glflags.seen_PU && !glflags.seen_PU_high_address) { glflags.seen_PU_high_address = TRUE; glflags.PU_high_address = addr; } } } /* We have now both low_pc and high_pc values */ if (bSawLow && bSawHigh) { /* We need to decide if this PU is valid, as the SN Linker marks a stripped function by setting lowpc to -1; also for discarded comdat, both lowpc and highpc are zero */ if (glflags.need_PU_valid_code) { glflags.need_PU_valid_code = FALSE; /* To ignore a PU as invalid code, only consider the lowpc and highpc values associated with the DW_TAG_subprogram; other instances of lowpc and highpc, must be ignore (lexical blocks) */ in_valid_code = TRUE; if (IsInvalidCode(lowAddr,highAddr) && tag == DW_TAG_subprogram) { in_valid_code = FALSE; } } /* We have a low_pc/high_pc pair; check if they are valid */ if (in_valid_code) { DWARF_CHECK_COUNT(ranges_result,1); if (lowAddr != elf_max_address && lowAddr > highAddr) { DWARF_CHECK_ERROR(ranges_result, ".debug_info: Incorrect values " "for low_pc/high_pc"); if (glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { printf("Low = 0x%" DW_PR_XZEROS DW_PR_DUx ", High = 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lowAddr,highAddr); } } if (glflags.gf_check_decl_file || glflags.gf_check_ranges || glflags.gf_check_locations) { AddEntryIntoBucketGroup(glflags.pRangesInfo,0, lowAddr, lowAddr,highAddr,NULL,FALSE); } } bSawLow = FALSE; bSawHigh = FALSE; } } } break; case DW_AT_ranges: { Dwarf_Half theform = 0; int rv; struct esb_s rangesstr; esb_constructor(&rangesstr); rv = dwarf_whatform(attrib,&theform,&paerr); if (rv == DW_DLV_ERROR) { print_error(dbg, "dwarf_whatform cannot find Attr Form", rv, paerr); } else if (rv == DW_DLV_NO_ENTRY) { esb_destructor(&rangesstr); break; } esb_empty_string(&rangesstr); get_attr_value(dbg, tag,die, dieprint_cu_goffset,attrib, srcfiles, cnt, &rangesstr, glflags.show_form_used,glflags.verbose); print_range_attribute(dbg, die, attr,attr_in, theform, pd_dwarf_names_print_on_error,print_information, &append_extra_string, &esb_extra); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&rangesstr)); esb_destructor(&rangesstr); } break; case DW_AT_MIPS_linkage_name: { struct esb_s linkagenamestr; esb_constructor(&linkagenamestr); get_attr_value(dbg, tag, die, dieprint_cu_goffset, attrib, srcfiles, cnt, &linkagenamestr, glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&linkagenamestr)); esb_destructor(&linkagenamestr); if ( glflags.gf_check_locations || glflags.gf_check_ranges) { int local_show_form = 0; int local_verbose = 0; const char *name = 0; struct esb_s lesb; esb_constructor(&lesb); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, local_show_form,local_verbose); /* Look for specific name forms, attempting to notice and report 'odd' identifiers. */ name = esb_get_string(&lesb); safe_strcpy(glflags.PU_name,sizeof(glflags.PU_name), name,strlen(name)); esb_destructor(&lesb); } } break; case DW_AT_name: case DW_AT_GNU_template_name: { struct esb_s templatenamestr; esb_constructor(&templatenamestr); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &templatenamestr, glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&templatenamestr)); esb_destructor(&templatenamestr); if ( glflags.gf_check_names && checking_this_compiler()) { int local_show_form = FALSE; int local_verbose = 0; struct esb_s lesb; const char *name = 0; esb_constructor(&lesb); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, local_show_form,local_verbose); /* Look for specific name forms, attempting to notice and report 'odd' identifiers. */ name = esb_get_string(&lesb); DWARF_CHECK_COUNT(names_result,1); if (!strcmp("\"(null)\"",name)) { DWARF_CHECK_ERROR(names_result, "string attribute is \"(null)\"."); } else { if (!dot_ok_in_identifier(tag,die,name) && !glflags.need_CU_name && strchr(name,'.')) { /* This is a suggestion there 'might' be a surprising name, not a guarantee of an error. */ DWARF_CHECK_ERROR(names_result, "string attribute is invalid."); } } esb_destructor(&lesb); } } /* If we are in checking mode and we do not have a PU name */ if (( glflags.gf_check_locations || glflags.gf_check_ranges) && glflags.seen_PU && !glflags.PU_name[0]) { int local_show_form = FALSE; int local_verbose = 0; const char *name = 0; struct esb_s lesb; esb_constructor(&lesb); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, local_show_form,local_verbose); name = esb_get_string(&lesb); safe_strcpy(glflags.PU_name,sizeof(glflags.PU_name),name, strlen(name)); esb_destructor(&lesb); } /* If we are processing the compile unit, record the name */ if (glflags.seen_CU && glflags.need_CU_name) { /* Lets not get the form name included. */ struct esb_s lesb; int local_show_form_used = FALSE; int local_verbose = 0; esb_constructor(&lesb); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, local_show_form_used,local_verbose); safe_strcpy(glflags.CU_name,sizeof(glflags.CU_name), esb_get_string(&lesb),esb_string_len(&lesb)); glflags.need_CU_name = FALSE; esb_destructor(&lesb); } break; case DW_AT_producer: { struct esb_s lesb; esb_constructor(&lesb); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&lesb)); esb_destructor(&lesb); /* If we are in checking mode, identify the compiler */ if ( glflags.gf_do_check_dwarf || glflags.gf_search_is_on) { /* Do not use show-form here! We just want the producer name, not the form name. */ int show_form_local = FALSE; int local_verbose = 0; struct esb_s local_e; esb_constructor(&local_e); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &local_e, show_form_local,local_verbose); /* Check if this compiler version is a target */ update_compiler_target(esb_get_string(&local_e)); esb_destructor(&local_e); } } break; /* When dealing with linkonce symbols, the low_pc and high_pc are associated with a specific symbol; SNC always generate a name with DW_AT_MIPS_linkage_name; GCC does not; instead gcc generates DW_AT_abstract_origin or DW_AT_specification; in that case we have to traverse this attribute in order to get the name for the linkonce */ case DW_AT_specification: case DW_AT_abstract_origin: case DW_AT_type: { struct esb_s lesb; esb_constructor(&lesb); get_attr_value(dbg, tag, die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&lesb)); esb_destructor(&lesb); if (glflags.gf_check_forward_decl || glflags.gf_check_self_references || glflags.gf_search_is_on) { Dwarf_Off die_goff = 0; Dwarf_Off ref_goff = 0; int res = 0; int suppress_check = 0; Dwarf_Half theform = 0; Dwarf_Half directform = 0; get_form_values(dbg,attrib,&theform,&directform); res = dwarf_global_formref(attrib, &ref_goff, &paerr); if (res == DW_DLV_ERROR) { int myerr = dwarf_errno(paerr); if (myerr == DW_DLE_REF_SIG8_NOT_HANDLED) { /* DW_DLE_REF_SIG8_NOT_HANDLED */ /* No offset available, it makes little sense to delve into this sort of reference unless we think a graph of self-refs *across* type-units is possible. Hmm. FIXME? */ suppress_check = 1 ; DWARF_CHECK_COUNT(self_references_result,1); DWARF_CHECK_ERROR(self_references_result, "DW_AT_ref_sig8 not handled so " "self references not fully checked"); dwarf_dealloc(dbg,paerr,DW_DLA_ERROR); paerr = 0; } else { print_error(dbg, "dwarf_die_CU_offsetD", res, paerr); } } else if (res == DW_DLV_NO_ENTRY) { print_error(dbg, "dwarf_die_CU_offsetD (NO ENTRY)", res, paerr); } res = dwarf_dieoffset(die, &die_goff, &paerr); if (res != DW_DLV_OK) { print_error(dbg, "ref formwith no ref?!", res, paerr); } if (!suppress_check && glflags.gf_check_self_references && form_refers_local_info(theform) ) { Dwarf_Die ref_die = 0; ResetBucketGroup(glflags.pVisitedInfo); AddEntryIntoBucketGroup(glflags.pVisitedInfo, die_goff,0,0,0, NULL,FALSE); /* Follow reference chain, looking for self references */ res = dwarf_offdie_b(dbg,ref_goff,is_info, &ref_die,&paerr); if (res == DW_DLV_OK) { Dwarf_Off ref_die_cu_goff = 0; Dwarf_Off die_loff = 0; /* CU-relative. */ if (dump_visited_info) { res = dwarf_die_CU_offset(die, &die_loff, &paerr); DROP_ERROR_INSTANCE(dbg,res,paerr); do_dump_visited_info(die_indent_level, die_loff,die_goff, dieprint_cu_goffset, atname,esb_get_string(&valname)); } ++die_indent_level; res =dwarf_CU_dieoffset_given_die(ref_die, &ref_die_cu_goff, &paerr); /* Check above call return status? FIXME */ if (res != DW_DLV_OK) { print_error(dbg,"dwarf_CU_die_dieoffset_given_die()" " accessing cu_goff die!", res, paerr); } traverse_one_die(dbg,attrib,ref_die, ref_die_cu_goff, is_info,srcfiles,cnt,die_indent_level); dwarf_dealloc(dbg,ref_die,DW_DLA_DIE); ref_die = 0; --die_indent_level; } DeleteKeyInBucketGroup(glflags.pVisitedInfo,die_goff); } if (!suppress_check && glflags.gf_check_forward_decl) { if (attr == DW_AT_specification) { /* Check the DW_AT_specification does not make forward references to DIEs. DWARF4 specifications, section 2.13.2, but really they are legal, this test is probably wrong. */ DWARF_CHECK_COUNT(forward_decl_result,1); if (ref_goff > die_goff) { DWARF_CHECK_ERROR2(forward_decl_result, "Invalid forward reference to DIE: ", esb_get_string(&valname)); } } } /* When doing search, if the attribute is DW_AT_specification or DW_AT_abstract_origin, get any name associated with the DIE referenced in the offset. The 2 more typical cases are: Member functions, where 2 DIES are generated: DIE for the declaration and DIE for the definition and connected via the DW_AT_specification. Inlined functions, where 2 DIES are generated: DIE for the concrete instance and DIE for the abstract instance and connected via the DW_AT_abstract_origin. */ if ( glflags.gf_search_is_on && (attr == DW_AT_specification || attr == DW_AT_abstract_origin)) { Dwarf_Die ref_die = 0; /* Follow reference chain, looking for the DIE name */ res = dwarf_offdie_b(dbg,ref_goff,is_info,&ref_die,&paerr); if (res == DW_DLV_OK) { /* Get the DIE name */ char *name = 0; res = dwarf_diename(ref_die,&name,&paerr); if (res == DW_DLV_OK) { esb_empty_string(&valname); esb_append(&valname,name); } /* Release the allocated DIE */ dwarf_dealloc(dbg,ref_die,DW_DLA_DIE); } } } /* If we are in checking mode and we do not have a PU name */ if (( glflags.gf_check_locations || glflags.gf_check_ranges) && glflags.seen_PU && !glflags.PU_name[0]) { if (tag == DW_TAG_subprogram) { /* This gets the DW_AT_name if this DIE has one. */ Dwarf_Addr low_pc = 0; static char proc_name[BUFSIZ]; proc_name[0] = 0; get_proc_name(dbg,die,low_pc,proc_name,BUFSIZ,/*pcMap=*/0); if (proc_name[0]) { safe_strcpy(glflags.PU_name,sizeof(glflags.PU_name), proc_name,strlen(proc_name)); } } } } break; default: { struct esb_s lesb; esb_constructor(&lesb); get_attr_value(dbg, tag,die, dieprint_cu_goffset,attrib, srcfiles, cnt, &lesb, glflags.show_form_used,glflags.verbose); esb_empty_string(&valname); esb_append(&valname, esb_get_string(&lesb)); esb_destructor(&lesb); } break; } if (!print_information) { if (have_a_search_match(esb_get_string(&valname),atname)) { /* Count occurrence of text */ ++glflags.search_occurrences; if ( glflags.gf_search_wide_format) { found_search_attr = TRUE; } else { PRINT_CU_INFO(); bTextFound = TRUE; } } } if ((PRINTING_UNIQUE && PRINTING_DIES && print_information) || bTextFound) { /* Print just the Tags and Attributes */ if (!glflags.gf_display_offsets) { printf("%-28s\n",atname); } else { if (glflags.dense) { printf(" %s<%s>", atname, esb_get_string(&valname)); if (append_extra_string) { char *v = esb_get_string(&esb_extra); printf("%s", v); } } else { printf("%-28s", atname); if (strlen(atname) >= 28) { printf(" "); } printf("%s\n", sanitized(esb_get_string(&valname))); if (append_extra_string) { char *v = esb_get_string(&esb_extra); printf("%s", sanitized(v)); } } } } esb_destructor(&valname); esb_destructor(&esb_extra); return found_search_attr; } void dwarfdump_print_one_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc * llbuf, /* Non-zero for old interface. */ Dwarf_Locdesc_c locdesc, /* Non-zero for 2015 interface. */ UNUSEDARG Dwarf_Unsigned llent, /* Which desc we have . */ Dwarf_Unsigned entrycount, /* How many location operators (DW_OP)? */ Dwarf_Addr baseaddr, struct esb_s *string_out) { Dwarf_Half no_of_ops = 0; unsigned i = 0; if(llbuf) { Dwarf_Locdesc *locd = 0; locd = llbuf; no_of_ops = llbuf->ld_cents; for (i = 0; i < no_of_ops; i++) { Dwarf_Loc * op = &locd->ld_s[i]; int res = _dwarf_print_one_expr_op(dbg,op,NULL,i, baseaddr,string_out); if (res == DW_DLV_ERROR) { return; } } return; } /* ASSERT: locs != NULL */ no_of_ops = entrycount; for (i = 0; i < no_of_ops; i++) { int res = 0; res = _dwarf_print_one_expr_op(dbg,NULL,locdesc,i, baseaddr,string_out); if (res == DW_DLV_ERROR) { return; } } } static int op_has_no_operands(int op) { unsigned i = 0; if (op >= DW_OP_lit0 && op <= DW_OP_reg31) { return TRUE; } for (; ; ++i) { struct operation_descr_s *odp = opdesc+i; if (odp->op_code == 0) { break; } if (odp->op_code != op) { continue; } if (odp->op_count == 0) { return TRUE; } return FALSE; } return FALSE; } static void show_contents(struct esb_s *string_out, unsigned int length,const unsigned char * bp) { unsigned int i = 0; #ifdef ORIGINAL_SPRINTF char small_buf[20]; #endif if(!length) { return; } esb_append(string_out," contents 0x"); for (; i < length; ++i,++bp) { /* Do not use DW_PR_DUx here, the value *bp is a const unsigned char. */ #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "%02x", *bp); esb_append(string_out,small_buf); #else esb_append_printf_u(string_out,"%02x", *bp); #endif } } int _dwarf_print_one_expr_op(Dwarf_Debug dbg, Dwarf_Loc* expr, Dwarf_Locdesc_c exprc, int index, UNUSEDARG Dwarf_Addr baseaddr, struct esb_s *string_out) { /* local_space_needed is intended to be 'more than big enough' for a short group of loclist entries. */ #ifdef ORIGINAL_SPRINTF char small_buf[100]; #endif Dwarf_Small op = 0; Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned offsetforbranch = 0; const char * op_name = 0; Dwarf_Error onexerr = 0; if (index > 0) { esb_append(string_out, " "); } if (expr) { /* DWARF 2,3,4 style */ op = expr->lr_atom; opd1 = expr->lr_number; opd2 = expr->lr_number2; } else { /* DWARF 2,3,4 and DWARF5 style */ int res = dwarf_get_location_op_value_c(exprc, index, &op,&opd1,&opd2,&opd3,&offsetforbranch, &onexerr); if (res != DW_DLV_OK) { print_error(dbg, "dwarf_get_location_op_value_c unexpected value!", DW_DLV_OK, onexerr); return DW_DLV_ERROR; } } op_name = get_OP_name(op,pd_dwarf_names_print_on_error); esb_append(string_out, op_name); if (op_has_no_operands(op)) { /* Nothing to add. */ } else if (op >= DW_OP_breg0 && op <= DW_OP_breg31) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "%+" DW_PR_DSd , (Dwarf_Signed) opd1); esb_append(string_out, small_buf); #else esb_append_printf_i(string_out, "%+" DW_PR_DSd , opd1); #endif } else { switch (op) { case DW_OP_addr: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_const1s: case DW_OP_const2s: case DW_OP_const4s: case DW_OP_const8s: case DW_OP_consts: case DW_OP_skip: case DW_OP_bra: case DW_OP_fbreg: esb_append(string_out," "); formx_signed(opd1,string_out); break; case DW_OP_GNU_addr_index: /* unsigned val */ case DW_OP_addrx: /* DWARF5: unsigned val */ case DW_OP_GNU_const_index: case DW_OP_constx: /* DWARF5: unsigned val */ case DW_OP_const1u: case DW_OP_const2u: case DW_OP_const4u: case DW_OP_const8u: case DW_OP_constu: case DW_OP_pick: case DW_OP_plus_uconst: case DW_OP_regx: case DW_OP_piece: case DW_OP_deref_size: case DW_OP_xderef_size: #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), " %" DW_PR_DUu , opd1); esb_append(string_out, small_buf); #else esb_append_printf_u(string_out, " %" DW_PR_DUu , opd1); #endif break; case DW_OP_bregx: bracket_hex(" ",opd1,"",string_out); esb_append(string_out,"+"); formx_signed(opd2,string_out); break; case DW_OP_call2: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_call4: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_call_ref: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_bit_piece: bracket_hex(" ",opd1,"",string_out); bracket_hex(" offset ",opd2,"",string_out); break; case DW_OP_implicit_value: { #define IMPLICIT_VALUE_PRINT_MAX 12 unsigned int print_len = 0; bracket_hex(" ",opd1,"",string_out); /* The other operand is a block of opd1 bytes. */ /* FIXME */ print_len = opd1; if (print_len > IMPLICIT_VALUE_PRINT_MAX) { print_len = IMPLICIT_VALUE_PRINT_MAX; } #undef IMPLICIT_VALUE_PRINT_MAX { const unsigned char *bp = 0; /* This is a really ugly cast, a way to implement DW_OP_implicit value in this libdwarf context. */ bp = (const unsigned char *)(uintptr_t) opd2; show_contents(string_out,print_len,bp); } } break; /* We do not know what the operands, if any, are. */ case DW_OP_HP_unknown: case DW_OP_HP_is_value: case DW_OP_HP_fltconst4: case DW_OP_HP_fltconst8: case DW_OP_HP_mod_range: case DW_OP_HP_unmod_range: case DW_OP_HP_tls: case DW_OP_INTEL_bit_piece: break; case DW_OP_stack_value: /* DWARF4 */ break; case DW_OP_GNU_uninit: /* DW_OP_APPLE_uninit */ /* No operands. */ break; case DW_OP_GNU_encoded_addr: bracket_hex(" ",opd1,"",string_out); break; case DW_OP_implicit_pointer: /* DWARF5 */ case DW_OP_GNU_implicit_pointer: bracket_hex(" ",opd1,"",string_out); esb_append(string_out, " "); formx_signed(opd2,string_out); break; case DW_OP_entry_value: /* DWARF5 */ case DW_OP_GNU_entry_value: { const unsigned char *bp = 0; unsigned int length = 0; length = opd1; bracket_hex(" ",opd1,"",string_out); bp = (Dwarf_Small *)(uintptr_t) opd2; if (!bp) { esb_append(string_out, "ERROR: Null databyte pointer DW_OP_entry_value "); } else { show_contents(string_out,length,bp); } } break; case DW_OP_const_type: /* DWARF5 */ case DW_OP_GNU_const_type: { const unsigned char *bp = 0; unsigned int length = 0; bracket_hex(" ",opd1,"",string_out); length = opd2; esb_append(string_out," const length: "); #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "%u" , length); esb_append(string_out, small_buf); #else esb_append_printf_u(string_out, "%u" , length); #endif /* Now point to the data bytes of the const. */ bp = (Dwarf_Small *)(uintptr_t)opd3; if (!bp) { esb_append(string_out, "ERROR: Null databyte pointer DW_OP_const_type "); } else { show_contents(string_out,length,bp); } } break; case DW_OP_regval_type: /* DWARF5 */ case DW_OP_GNU_regval_type: { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), " 0x%" DW_PR_DUx , opd1); esb_append(string_out, small_buf); #else esb_append_printf_u(string_out, " 0x%" DW_PR_DUx , opd1); #endif bracket_hex(" ",opd2,"",string_out); } break; case DW_OP_deref_type: /* DWARF5 */ case DW_OP_GNU_deref_type: { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), " 0x%02" DW_PR_DUx , opd1); esb_append(string_out, small_buf); #else esb_append_printf_u(string_out, " 0x%02" DW_PR_DUx , opd1); #endif bracket_hex(" ",opd2,"",string_out); } break; case DW_OP_convert: /* DWARF5 */ case DW_OP_GNU_convert: case DW_OP_reinterpret: /* DWARF5 */ case DW_OP_GNU_reinterpret: case DW_OP_GNU_parameter_ref: #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), " 0x%02" DW_PR_DUx , opd1); esb_append(string_out, small_buf); #else esb_append_printf_u(string_out, " 0x%02" DW_PR_DUx , opd1); #endif break; default: { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), " dwarf_op unknown 0x%x", (unsigned)op); esb_append(string_out,small_buf); #else esb_append_printf_u(string_out, " dwarf_op unknown 0x%x", (unsigned)op); #endif } break; } } return DW_DLV_OK; } static void loc_error_check(UNUSEDARG Dwarf_Debug dbg, Dwarf_Addr lopcfinal, Dwarf_Addr lopc, Dwarf_Addr hipcfinal, Dwarf_Addr hipc, Dwarf_Unsigned offset, Dwarf_Addr base_address, Dwarf_Bool *bError) { DWARF_CHECK_COUNT(locations_result,1); /* Check the low_pc and high_pc are within a valid range in the .text section */ if (IsValidInBucketGroup(glflags.pRangesInfo,lopcfinal) && IsValidInBucketGroup(glflags.pRangesInfo,hipcfinal)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol */ if (IsValidInLinkonce(glflags.pLinkonceInfo,glflags.PU_name, lopcfinal,hipcfinal)) { /* Valid values; do nothing */ } else { *bError = TRUE; DWARF_CHECK_ERROR(locations_result, ".debug_loc: Address outside a " "valid .text range"); if ( glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { printf( "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx ", " "Low = 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx "), High = 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", offset,base_address,lopcfinal, lopc, hipcfinal, hipc); } } } } static const char * adexplain(Dwarf_Unsigned liberr, const char * alterr) { if (liberr == DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION) { return "no-tied-debug-addr-available"; } return alterr; } /* Fill buffer with location lists Buffer esbp expands as needed. */ /*ARGSUSED*/ static void get_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, struct esb_s *esbp) { Dwarf_Locdesc *llbuf = 0; Dwarf_Locdesc **llbufarray = 0; /* Only for older interface. */ Dwarf_Unsigned no_of_elements; Dwarf_Loc_Head_c loclist_head = 0; /* 2015 loclist interface */ Dwarf_Error llerr = 0; Dwarf_Unsigned i = 0; int lres = 0; unsigned llent = 0; /* Base address used to update entries in .debug_loc. CU_base_address is a global. Terrible way to pass in this value. FIXME. See also CU_low_address as base address is special for address ranges */ Dwarf_Addr base_address = glflags.CU_base_address; Dwarf_Addr lopc = 0; Dwarf_Addr hipc = 0; Dwarf_Bool bError = FALSE; Dwarf_Small lle_value = 0; /* DWARF5 */ Dwarf_Small loclist_source = 0; /* This is the section offset of the expression, not the location description prefix. */ Dwarf_Unsigned section_offset = 0; Dwarf_Half elf_address_size = 0; Dwarf_Addr elf_max_address = 0; /* old and new interfaces differ on signedness. */ Dwarf_Signed locentry_count = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Bool checking = FALSE; if (!glflags.gf_use_old_dwarf_loclist) { lres = dwarf_get_loclist_c(attr,&loclist_head, &no_of_elements,&llerr); if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_loclist_c", lres, llerr); } else if (lres == DW_DLV_NO_ENTRY) { return; } } else { Dwarf_Signed sno = 0; lres = dwarf_loclist_n(attr, &llbufarray, &sno, &llerr); if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_loclist", lres, llerr); } else if (lres == DW_DLV_NO_ENTRY) { return; } no_of_elements = sno; } get_address_size_and_max(dbg,&elf_address_size,&elf_max_address,&llerr); for (llent = 0; llent < no_of_elements; ++llent) { #ifdef ORIGINAL_SPRINTF char small_buf[150]; #endif Dwarf_Unsigned locdesc_offset = 0; Dwarf_Locdesc_c locentry = 0; /* 2015 */ Dwarf_Addr lopcfinal = 0; Dwarf_Addr hipcfinal = 0; if (!glflags.gf_use_old_dwarf_loclist) { lres = dwarf_get_locdesc_entry_c(loclist_head, llent, &lle_value, &lopc, &hipc, &ulocentry_count, &locentry, &loclist_source, §ion_offset, &locdesc_offset, &llerr); if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_loclist_entry_c", lres, llerr); } else if (lres == DW_DLV_NO_ENTRY) { return; } locentry_count = ulocentry_count; } else { llbuf = llbufarray[llent]; lopc = llbuf->ld_lopc; hipc = llbuf->ld_hipc; loclist_source = llbuf->ld_from_loclist; section_offset = llbuf->ld_section_offset; locdesc_offset = section_offset - sizeof(Dwarf_Half) - 2 * elf_address_size; locentry_count = llbuf->ld_cents; ulocentry_count = locentry_count; if (lopc == elf_max_address) { lle_value = DW_LLEX_base_address_selection_entry; } else if (lopc== 0 && hipc == 0) { lle_value = DW_LLEX_end_of_list_entry; } else { lle_value = DW_LLEX_offset_pair_entry; } } if (!glflags.dense && loclist_source) { if (llent == 0) { if (loclist_source == 1) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "", locdesc_offset, (long) no_of_elements); esb_append(esbp, small_buf); #else esb_append_printf_u(esbp, "",no_of_elements); #endif } else { #ifdef ORIGINAL_SPRINTF /* ASSERT: loclist_source == 2 */ snprintf(small_buf, sizeof(small_buf), "", locdesc_offset, (long) no_of_elements); esb_append(esbp, small_buf); #else esb_append_printf_u(esbp, "",no_of_elements); #endif } } #ifdef ORIGINAL_SPRINTF esb_append(esbp, "\n\t\t\t"); snprintf(small_buf, sizeof(small_buf), "[%2d]", llent); esb_append(esbp, small_buf); #else esb_append_printf_i(esbp, "\n\t\t\t" "[%2d]",llent); #endif } /* If we have a location list refering to the .debug_loc Check for specific compiler we are validating. */ if ( glflags.gf_check_locations && in_valid_code && loclist_source && checking_this_compiler()) { checking = TRUE; } /* When dwarf_debug_addr_index_to_addr() fails it is probably DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 (because no TIED file supplied) but we don't distinguish that from other errors here. */ if(loclist_source || checking) { /* Simplifies to use the DWARF5 DW_LLE as the test.*/ if (lle_value == DW_LLEX_base_address_selection_entry) { /* (0xffffffff,addr), use specific address (current PU address) */ Dwarf_Addr realaddr = 0; if (loclist_source == 2) { /* hipc is index of a slot in .debug_addr section. which contains base_address. */ int res = dwarf_debug_addr_index_to_addr(die, hipc,&realaddr,&llerr); if(res == DW_DLV_OK) { base_address = realaddr; } else if(res == DW_DLV_ERROR) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",hipc, adexplain(dwarf_errno(llerr), "base-address-unavailable")); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "", adexplain(dwarf_errno(llerr), "base-address-unavailable")); #endif base_address = 0; } else { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",hipc); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "",hipc); #endif /* Cannot find .debug_addr */ base_address = 0; } #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "", hipc,base_address); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "", base_address); #endif } else { base_address = hipc; #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "", base_address); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "", base_address); #endif } } else if (lle_value == DW_LLEX_end_of_list_entry) { /* Nothing to do. */ esb_append(esbp,""); } else if (lle_value == DW_LLEX_start_length_entry) { int foundaddr = FALSE; if (loclist_source == 2) { Dwarf_Addr realaddr = 0; Dwarf_Addr slotindex = lopc; /* start (lopc) is index of a slot in .debug_addr section. */ int res = dwarf_debug_addr_index_to_addr(die, lopc,&realaddr,&llerr); if(res == DW_DLV_OK) { lopc = realaddr; foundaddr = TRUE; } else if(res == DW_DLV_ERROR) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",lopc, adexplain(dwarf_errno(llerr), "start-address-unavailable")); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "", adexplain(dwarf_errno(llerr), "start-address-unavailable")); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",lopc); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "",lopc); #endif /* Cannot find .debug_addr */ lopc = 0; } #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), " ", slotindex,realaddr,hipc); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, " ",hipc); #endif } else { esb_append(esbp,""); /* Impossible */ lopc = 0; } lopcfinal = lopc; hipcfinal = lopcfinal + hipc; if (checking && foundaddr) { loc_error_check(dbg,lopcfinal, lopc, hipcfinal, hipc, locdesc_offset, base_address, &bError); } } else if (lle_value == DW_LLEX_offset_pair_entry) { /* Same for both loclist_source. */ lopcfinal = lopc + base_address; hipcfinal = hipc + base_address; #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "< offset pair low-off : 0x%" DW_PR_XZEROS DW_PR_DUx " addr 0x%" DW_PR_XZEROS DW_PR_DUx " high-off 0x%" DW_PR_XZEROS DW_PR_DUx " addr 0x%" DW_PR_XZEROS DW_PR_DUx ">", lopc,lopcfinal,hipc,hipcfinal); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "< offset pair low-off : 0x%" DW_PR_XZEROS DW_PR_DUx,lopc); esb_append_printf_u(esbp, " addr 0x%" DW_PR_XZEROS DW_PR_DUx,lopcfinal); esb_append_printf_u(esbp, " high-off 0x%" DW_PR_XZEROS DW_PR_DUx,hipc); esb_append_printf_u(esbp, " addr 0x%" DW_PR_XZEROS DW_PR_DUx ">",hipcfinal); #endif if(checking) { loc_error_check(dbg,lopcfinal, lopc, hipcfinal, hipc, locdesc_offset, base_address, &bError); } } else if (lle_value == DW_LLEX_start_end_entry) { int foundaddr = FALSE; /* These are NOT relative to base_address */ if (loclist_source == 2) { /* indices in .debug_addr of start and end addresses. */ Dwarf_Addr reallo = 0; Dwarf_Addr realhi = 0; /* start is index of a slot in .debug_addr section. */ int res = dwarf_debug_addr_index_to_addr(die, lopc,&reallo,&llerr); if(res == DW_DLV_OK) { lopcfinal = reallo; foundaddr = TRUE; } else if(res == DW_DLV_ERROR) { #ifdef ORIGINAL_SPRINT snprintf(small_buf,sizeof(small_buf), "",lopc, adexplain(dwarf_errno(llerr), "start-address-unavailable")); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "", adexplain(dwarf_errno(llerr), "start-address-unavailable")); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",lopc); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "",lopc); #endif /* Cannot find .debug_addr */ lopcfinal = 0; } res = dwarf_debug_addr_index_to_addr(die, hipc,&realhi,&llerr); if(res == DW_DLV_OK) { hipcfinal = realhi; } else if(res == DW_DLV_ERROR) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",hipc, adexplain(dwarf_errno(llerr), "end-address-unavailable")); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "", adexplain(dwarf_errno(llerr), "end-address-unavailable")); #endif foundaddr = FALSE; } else { #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "",hipc); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "",hipc); #endif /* Cannot find .debug_addr */ hipcfinal = 0; foundaddr = FALSE; } #ifdef ORIGINAL_SPRINTF snprintf(small_buf,sizeof(small_buf), "< start-end low-index : 0x%" DW_PR_XZEROS DW_PR_DUx " addr 0x%" DW_PR_XZEROS DW_PR_DUx " high-index 0x%" DW_PR_XZEROS DW_PR_DUx " addr 0x%" DW_PR_XZEROS DW_PR_DUx ">", lopc,lopcfinal,hipc,hipcfinal); esb_append(esbp,small_buf); #else esb_append_printf_u(esbp, "< start-end low-index : 0x%" DW_PR_XZEROS DW_PR_DUx,lopc); esb_append_printf_u(esbp, " addr 0x%" DW_PR_XZEROS DW_PR_DUx,lopcfinal); esb_append_printf_u(esbp, " high-index 0x%" DW_PR_XZEROS DW_PR_DUx,hipc); esb_append_printf_u(esbp, " addr 0x%" DW_PR_XZEROS DW_PR_DUx ">",hipcfinal); #endif } else { esb_append(esbp,""); /* Impossible */ } if (checking && foundaddr) { loc_error_check(dbg,lopcfinal, lopc, hipcfinal, hipc, locdesc_offset, 0, &bError); } } else { char sbuf2[50]; sprintf(sbuf2, "Unexpected LLEX code 0x%x, ERROR",lle_value); print_error(dbg, sbuf2, DW_DLV_OK, llerr); } if (glflags.gf_display_offsets && glflags.verbose) { char *secname = ".debug_info"; if(loclist_source == 1) { secname = ".debug_loc"; } else if (loclist_source == 2) { secname = ".debug_loc.dwo"; } else if (loclist_source) { secname = ""; } #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "", secname, locdesc_offset); esb_append(esbp, small_buf); #else esb_append_printf_s(esbp,"", locdesc_offset); #endif } } dwarfdump_print_one_locdesc(dbg, /* Either llbuf or locentry non-zero. Not both. */ llbuf, locentry, llent, /* Which loc desc this is */ locentry_count, /* How many ops in this loc desc */ base_address, esbp); } if (bError && glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { printf("\n"); } if (!glflags.gf_use_old_dwarf_loclist) { dwarf_loc_head_c_dealloc(loclist_head); } else { for (i = 0; i < no_of_elements; ++i) { dwarf_dealloc(dbg, llbufarray[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbufarray[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbufarray, DW_DLA_LIST); } } /* New October 2017. The 'decimal' representation here is questionable. */ static void formx_data16(Dwarf_Form_Data16 * u, struct esb_s *esbp, Dwarf_Bool hex_format) { #ifdef ORIGINAL_SPRINTF char small_buf[20]; #endif unsigned i = 0; for( ; i < sizeof(Dwarf_Form_Data16); ++i){ esb_append(esbp, "0x"); if (hex_format) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf),"%02x ", u->fd_data[i]); esb_append(esbp, small_buf); #else esb_append_printf_u(esbp, "%02x ", u->fd_data[i]); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf),"%02d ", u->fd_data[i]); esb_append(esbp, small_buf); #else esb_append_printf_i(esbp, "%02d ", u->fd_data[i]); #endif } } } static void formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp, Dwarf_Bool hex_format) { #ifdef ORIGINAL_SPRINTF char small_buf[40]; #endif if (hex_format) { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "0x%" DW_PR_XZEROS DW_PR_DUx , u); esb_append(esbp, small_buf); #else esb_append_printf_u(esbp, "0x%" DW_PR_XZEROS DW_PR_DUx , u); #endif } else { #ifdef ORIGINAL_SPRINTF snprintf(small_buf, sizeof(small_buf), "%" DW_PR_DUu , u); esb_append(esbp, small_buf); #else esb_append_printf_u(esbp, "%" DW_PR_DUu , u); #endif } } static void formx_signed(Dwarf_Signed s, struct esb_s *esbp) { #ifdef ORIGINAL_SPRINTF char small_buf[40]; snprintf(small_buf, sizeof(small_buf), "%" DW_PR_DSd ,s); esb_append(esbp, small_buf); #else esb_append_printf_i(esbp, "%" DW_PR_DSd ,s); #endif } static void formx_unsigned_and_signed_if_neg(Dwarf_Unsigned tempud, Dwarf_Signed tempd, const char *leader,Dwarf_Bool hex_format,struct esb_s*esbp) { formx_unsigned(tempud,esbp,hex_format); if(tempd < 0) { esb_append(esbp,leader); formx_signed(tempd,esbp); esb_append(esbp,")"); } } /* If the DIE DW_AT_type exists and is directly known signed/unsigned return -1 for signed 1 for unsigned. Otherwise return 0 meaning 'no information'. So we only need to a messy lookup once per type-die offset */ static int check_for_type_unsigned(Dwarf_Debug dbg, Dwarf_Die die, UNUSEDARG struct esb_s *esbp) { Dwarf_Bool is_info = 0; struct Helpertree_Base_s * helperbase = 0; struct Helpertree_Map_Entry_s *e = 0; int res = 0; Dwarf_Attribute attr = 0; Dwarf_Attribute encodingattr = 0; Dwarf_Error error = 0; Dwarf_Unsigned diegoffset = 0; Dwarf_Unsigned typedieoffset = 0; Dwarf_Die typedie = 0; Dwarf_Unsigned tempud = 0; int show_form_here = FALSE; int retval = 0; if(!die) { return 0; } is_info = dwarf_get_die_infotypes_flag(die); if(is_info) { helperbase = &helpertree_offsets_base_info; } else { helperbase = &helpertree_offsets_base_types; } res = dwarf_dieoffset(die,&diegoffset,&error); if (res == DW_DLV_ERROR) { /* esb_append(esbp,""); */ return 0; } else if (res == DW_DLV_NO_ENTRY) { /* We don't know sign. */ /*esb_append(esbp,""); */ return 0; } /* This might be wrong. See the typedieoffset check below, which is correct... */ e = helpertree_find(diegoffset,helperbase); if(e) { /*bracket_hex("",esbp); bracket_hex("hm_val,">",esbp); */ return e->hm_val; } /* We look up the DW_AT_type die, if any, and use that offset to check for signedness. */ res = dwarf_attr(die, DW_AT_type, &attr,&error); if (res == DW_DLV_ERROR) { /*bracket_hex("",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /* We don't know sign. */ /*bracket_hex( "",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); return 0; } res = dwarf_global_formref(attr, &typedieoffset,&error); if (res == DW_DLV_ERROR) { /*bracket_hex( "",esbp); */ dwarf_dealloc(dbg,attr,DW_DLA_ATTR); helpertree_add_entry(diegoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /*esb_append(esbp,"helper NO ENTRY FAIL "); bracket_hex( "",esbp); */ dwarf_dealloc(dbg,attr,DW_DLA_ATTR); helpertree_add_entry(diegoffset, 0,helperbase); return 0; } dwarf_dealloc(dbg,attr,DW_DLA_ATTR); attr = 0; e = helpertree_find(typedieoffset,helperbase); if(e) { /*bracket_hex("",esbp); bracket_hex("hm_val,">",esbp); */ return e->hm_val; } res = dwarf_offdie_b(dbg,typedieoffset,is_info, &typedie,&error); if (res == DW_DLV_ERROR) { /*bracket_hex( "",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /*bracket_hex( "",esbp); */ helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } res = dwarf_attr(typedie, DW_AT_encoding, &encodingattr,&error); if (res == DW_DLV_ERROR) { /*bracket_hex( "",esbp); */ dwarf_dealloc(dbg,typedie,DW_DLA_DIE); helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } else if (res == DW_DLV_NO_ENTRY) { /*bracket_hex( "",esbp);*/ dwarf_dealloc(dbg,typedie,DW_DLA_DIE); helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } res = get_small_encoding_integer_and_name(dbg, encodingattr, &tempud, /* attrname */ (const char *) NULL, /* err_string */ ( struct esb_s *) NULL, (encoding_type_func) 0, &error,show_form_here); if (res != DW_DLV_OK) { /*bracket_hex( "",esbp);*/ dwarf_dealloc(dbg,typedie,DW_DLA_DIE); dwarf_dealloc(dbg,encodingattr,DW_DLA_ATTR); helpertree_add_entry(diegoffset, 0,helperbase); helpertree_add_entry(typedieoffset, 0,helperbase); return 0; } if (tempud == DW_ATE_signed || tempud == DW_ATE_signed_char) { /*esb_append(esbp,"helper small encoding SIGNED ");*/ retval = -1; } else { if (tempud == DW_ATE_unsigned || tempud == DW_ATE_unsigned_char) { /*esb_append(esbp,"helper small encoding UNSIGNED ");*/ retval = 1; } } /*bracket_hex( "",esbp); bracket_hex( "",esbp);*/ helpertree_add_entry(diegoffset,retval,helperbase); helpertree_add_entry(typedieoffset, retval,helperbase); dwarf_dealloc(dbg,typedie,DW_DLA_DIE); dwarf_dealloc(dbg,encodingattr,DW_DLA_ATTR); return retval; } /* We think this is an integer. Figure out how to print it. In case the signedness is ambiguous (such as on DW_FORM_data1 (ie, unknown signedness) print two ways. If we were to look at DW_AT_type in the base DIE we could follow it and determine if the type was unsigned or signed (usually easily) and use that information. */ static int formxdata_print_value(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attrib, Dwarf_Half theform, struct esb_s *esbp, Dwarf_Error * pverr, Dwarf_Bool hex_format) { Dwarf_Signed tempsd = 0; Dwarf_Unsigned tempud = 0; int sres = 0; int ures = 0; Dwarf_Error serr = 0; if (theform == DW_FORM_data16) { Dwarf_Form_Data16 v16; ures = dwarf_formdata16(attrib, &v16,pverr); if (ures == DW_DLV_OK) { formx_data16(&v16, esbp,hex_format); return DW_DLV_OK; } else if (ures == DW_DLV_NO_ENTRY) { /* impossible */ return ures; } else { return ures; } } ures = dwarf_formudata(attrib, &tempud, pverr); sres = dwarf_formsdata(attrib, &tempsd, &serr); if (ures == DW_DLV_OK) { if (sres == DW_DLV_OK) { if (tempud == (Dwarf_Unsigned)tempsd && tempsd >= 0) { /* Data is the same value and not negative, so makes no difference which we print. */ formx_unsigned(tempud,esbp,hex_format); } else { /* Here we don't know if signed or not and Assuming one or the other changes the interpretation of the bits. */ int helpertree_unsigned = 0; helpertree_unsigned = check_for_type_unsigned(dbg,die,esbp); if (!die || !helpertree_unsigned) { /* Signedness unclear. */ formx_unsigned_and_signed_if_neg(tempud,tempsd, " (",hex_format,esbp); } else if (helpertree_unsigned > 0) { formx_unsigned(tempud,esbp,hex_format); } else { /* Value signed. */ formx_signed(tempsd,esbp); } } } else if (sres == DW_DLV_NO_ENTRY) { formx_unsigned(tempud,esbp,hex_format); } else /* DW_DLV_ERROR */{ formx_unsigned(tempud,esbp,hex_format); } goto cleanup; } else { /* ures == DW_DLV_ERROR or DW_DLV_NO_ENTRY*/ if (sres == DW_DLV_OK) { formx_signed(tempsd,esbp); } else { /* Neither worked. */ } } /* Clean up any unused Dwarf_Error data. DW_DLV_NO_ENTRY cannot really happen, so a complete cleanup for that is not necessary. */ cleanup: if (sres == DW_DLV_OK || ures == DW_DLV_OK) { DROP_ERROR_INSTANCE(dbg,sres,serr); DROP_ERROR_INSTANCE(dbg,ures,*pverr); return DW_DLV_OK; } if (sres == DW_DLV_ERROR || ures == DW_DLV_ERROR) { if (sres == DW_DLV_ERROR && ures == DW_DLV_ERROR) { dwarf_dealloc(dbg,serr,DW_DLA_ERROR); serr = 0; return DW_DLV_ERROR; } if (sres == DW_DLV_ERROR) { *pverr = serr; serr = 0; } return DW_DLV_ERROR; } /* Both are DW_DLV_NO_ENTRY which is crazy, impossible. */ return DW_DLV_NO_ENTRY; } static void bracket_hex(const char *s1, Dwarf_Unsigned v, const char *s2, struct esb_s * esbp) { Dwarf_Bool hex_format = TRUE; esb_append(esbp,s1); formx_unsigned(v,esbp,hex_format); esb_append(esbp,s2); } #ifdef ORIGINAL_SPRINT static char * get_form_number_as_string(int form, char *buf, unsigned bufsize) { snprintf(buf,bufsize," %d",form); return buf; } #endif static void print_exprloc_content(Dwarf_Debug dbg,Dwarf_Die die, Dwarf_Attribute attrib, int showhextoo, struct esb_s *esbp) { Dwarf_Ptr x = 0; Dwarf_Unsigned tempud = 0; char small_buf[80]; Dwarf_Error ecerr = 0; int wres = 0; wres = dwarf_formexprloc(attrib,&tempud,&x,&ecerr); if (wres == DW_DLV_NO_ENTRY) { /* Show nothing? Impossible. */ } else if (wres == DW_DLV_ERROR) { print_error(dbg, "Cannot get a DW_FORM_exprloc....", wres, ecerr); } else { Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; Dwarf_Half version = 0; int ares = 0; unsigned u = 0; snprintf(small_buf, sizeof(small_buf), "len 0x%04" DW_PR_DUx ": ",tempud); esb_append(esbp, small_buf); if (showhextoo) { for (u = 0; u < tempud; u++) { snprintf(small_buf, sizeof(small_buf), "%02x", *(u + (unsigned char *) x)); esb_append(esbp, small_buf); } esb_append(esbp,": "); } ares = dwarf_get_version_of_die(die,&version,&offset_size); if (ares != DW_DLV_OK) { print_error(dbg,"ERROR: Cannot get version size for exprloc die", DW_DLV_ERROR,ecerr); } ares = dwarf_get_die_address_size(die,&address_size,&ecerr); if (wres == DW_DLV_NO_ENTRY) { print_error(dbg,"Cannot get die address size for exprloc", ares,ecerr); } else if (wres == DW_DLV_ERROR) { print_error(dbg,"Cannot Get die address size for exprloc", ares,ecerr); } else { get_string_from_locs(dbg,x,tempud,address_size, offset_size,version, esbp); } } } /* Borrow the definition from pro_encode_nm.h */ /* Bytes needed to encode a number. Not a tight bound, just a reasonable bound. */ #ifndef ENCODE_SPACE_NEEDED #define ENCODE_SPACE_NEEDED (2*sizeof(Dwarf_Unsigned)) #endif /* ENCODE_SPACE_NEEDED */ /* Table indexed by the attribute value; only standard attributes are included, ie. in the range [1..DW_AT_lo_user]; we waste a little bit of space, but accessing the table is fast. */ typedef struct attr_encoding { Dwarf_Unsigned entries; /* Attribute occurrences */ Dwarf_Unsigned formx; /* Space used by current encoding */ Dwarf_Unsigned leb128; /* Space used with LEB128 encoding */ } a_attr_encoding; /* The other DW_FORM_datan are lower form values than data16, so the following is safe for the unchanging static table. */ static int attributes_encoding_factor[DW_FORM_data16 + 1]; /* These must be reset for each object if we are processing an archive! see print_attributes_encoding(). */ static a_attr_encoding *attributes_encoding_table = NULL; static boolean attributes_encoding_do_init = TRUE; /* Check the potential amount of space wasted by attributes values that can be represented as an unsigned LEB128. Only attributes with forms: DW_FORM_data1, DW_FORM_data2, DW_FORM_data4 and DW_FORM_data are checked */ static void check_attributes_encoding(Dwarf_Half attr,Dwarf_Half theform, Dwarf_Unsigned value) { if (attributes_encoding_do_init) { /* Create table on first call */ attributes_encoding_table = (a_attr_encoding *)calloc(DW_AT_lo_user, sizeof(a_attr_encoding)); /* We use only 5 slots in the table, for quick access */ attributes_encoding_factor[DW_FORM_data1] = 1; /* index 0x0b */ attributes_encoding_factor[DW_FORM_data2] = 2; /* index 0x05 */ attributes_encoding_factor[DW_FORM_data4] = 4; /* index 0x06 */ attributes_encoding_factor[DW_FORM_data8] = 8; /* index 0x07 */ attributes_encoding_factor[DW_FORM_data16] = 16;/* index 0x1e */ attributes_encoding_do_init = FALSE; } /* Regardless of the encoding form, count the checks. */ DWARF_CHECK_COUNT(attr_encoding_result,1); /* For 'DW_AT_stmt_list', due to the way is generated, the value can be unknown at compile time and only the assembler can decide how to represent the offset; ignore this attribute. */ if (DW_AT_stmt_list == attr || DW_AT_macros == attr || DW_AT_GNU_macros == attr) { return; } /* Only checks those attributes that have DW_FORM_dataX: DW_FORM_data1, DW_FORM_data2, DW_FORM_data4 and DW_FORM_data8 DWARF5 adds DW_FORM_data16, but we ignore data16 here as it makes no sense as a uleb. */ if (theform == DW_FORM_data1 || theform == DW_FORM_data2 || theform == DW_FORM_data4 || theform == DW_FORM_data8 ) { int res = 0; /* Size of the byte stream buffer that needs to be memcpy-ed. */ int leb128_size = 0; /* To encode the attribute value */ char encode_buffer[ENCODE_SPACE_NEEDED]; char small_buf[64]; /* Just a small buffer */ res = dwarf_encode_leb128(value,&leb128_size, encode_buffer,sizeof(encode_buffer)); if (res == DW_DLV_OK) { if (attributes_encoding_factor[theform] > leb128_size) { int wasted_bytes = attributes_encoding_factor[theform] - leb128_size; snprintf(small_buf, sizeof(small_buf), "%d wasted byte(s)",wasted_bytes); DWARF_CHECK_ERROR2(attr_encoding_result, get_AT_name(attr,pd_dwarf_names_print_on_error), small_buf); /* Add the optimized size to the specific attribute, only if we are dealing with a standard attribute. */ if (attr < DW_AT_lo_user) { attributes_encoding_table[attr].entries += 1; attributes_encoding_table[attr].formx += attributes_encoding_factor[theform]; attributes_encoding_table[attr].leb128 += leb128_size; } } } } } /* Print a detailed encoding usage per attribute */ void print_attributes_encoding(Dwarf_Debug dbg) { if (attributes_encoding_table) { boolean print_header = TRUE; Dwarf_Unsigned total_entries = 0; Dwarf_Unsigned total_bytes_formx = 0; Dwarf_Unsigned total_bytes_leb128 = 0; Dwarf_Unsigned entries = 0; Dwarf_Unsigned bytes_formx = 0; Dwarf_Unsigned bytes_leb128 = 0; int index; int count = 0; float saved_rate = 0.0; Dwarf_Error attr_error = 0; for (index = 0; index < DW_AT_lo_user; ++index) { if (attributes_encoding_table[index].leb128) { if (print_header) { printf("\n*** SPACE USED BY ATTRIBUTE ENCODINGS ***\n"); printf("Nro Attribute Name " " Entries Data_x leb128 Rate\n"); print_header = FALSE; } entries = attributes_encoding_table[index].entries; bytes_formx = attributes_encoding_table[index].formx; bytes_leb128 = attributes_encoding_table[index].leb128; total_entries += entries; total_bytes_formx += bytes_formx; total_bytes_leb128 += bytes_leb128; saved_rate = bytes_leb128 * 100 / bytes_formx; printf("%3d %-25s " "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* Entries */ "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* FORMx */ "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* LEB128 */ "%3.0f%%" "\n", ++count, get_AT_name(index,pd_dwarf_names_print_on_error), entries, bytes_formx, bytes_leb128, saved_rate); } } if (!print_header) { /* At least we have an entry, print summary and percentage */ Dwarf_Addr lower = 0; Dwarf_Unsigned size = 0; int infoerr = 0; saved_rate = total_bytes_leb128 * 100 / total_bytes_formx; printf("** Summary ** " "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* Entries */ "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* FORMx */ "%10" /*DW_PR_XZEROS*/ DW_PR_DUu " " /* LEB128 */ "%3.0f%%" "\n", total_entries, total_bytes_formx, total_bytes_leb128, saved_rate); /* Get .debug_info size (Very unlikely to have an error here). */ infoerr = dwarf_get_section_info_by_name(dbg,".debug_info",&lower, &size,&attr_error); if (infoerr == DW_DLV_ERROR) { print_error(dbg, "get_section_info_by_name", infoerr,attr_error); } saved_rate = (total_bytes_formx - total_bytes_leb128) * 100 / size; if (saved_rate > 0) { printf("\n** .debug_info size can be reduced by %.0f%% **\n", saved_rate); } } free(attributes_encoding_table); attributes_encoding_table = 0; attributes_encoding_do_init = TRUE; } } /* Fill buffer with attribute value. We pass in tag so we can try to do the right thing with broken compiler DW_TAG_enumerator 'cnt' is signed for historical reasons (a mistake in an interface), but the value is never negative. We append to esbp's buffer. */ void get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Die die, Dwarf_Off dieprint_cu_goffset, Dwarf_Attribute attrib, char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp, int show_form, int local_verbose) { Dwarf_Half theform = 0; char * temps = 0; Dwarf_Block *tempb = 0; Dwarf_Signed tempsd = 0; Dwarf_Unsigned tempud = 0; Dwarf_Off off = 0; Dwarf_Die die_for_check = 0; Dwarf_Half tag_for_check = 0; Dwarf_Bool tempbool = 0; Dwarf_Addr addr = 0; int fres = 0; int bres = 0; int wres = 0; int dres = 0; Dwarf_Half direct_form = 0; char small_buf[COMPILE_UNIT_NAME_LEN]; /* Size to hold a filename */ Dwarf_Bool is_info = TRUE; Dwarf_Error err = 0; is_info = dwarf_get_die_infotypes_flag(die); /* Dwarf_whatform gets the real form, DW_FORM_indir is never returned: instead the real form following DW_FORM_indir is returned. */ fres = dwarf_whatform(attrib, &theform, &err); /* Depending on the form and the attribute, process the form. */ if (fres == DW_DLV_ERROR) { print_error(dbg, "dwarf_whatform cannot Find Attr Form", fres, err); } else if (fres == DW_DLV_NO_ENTRY) { return; } /* dwarf_whatform_direct gets the 'direct' form, so if the form is DW_FORM_indir that is what is returned. */ dwarf_whatform_direct(attrib, &direct_form, &err); /* Ignore errors in dwarf_whatform_direct() */ switch (theform) { case DW_FORM_GNU_addr_index: case DW_FORM_addrx: case DW_FORM_addrx1 : /* DWARF5 */ case DW_FORM_addrx2 : /* DWARF5 */ case DW_FORM_addrx3 : /* DWARF5 */ case DW_FORM_addrx4 : /* DWARF5 */ case DW_FORM_addr: bres = dwarf_formaddr(attrib, &addr, &err); if (bres == DW_DLV_OK) { if (theform == DW_FORM_GNU_addr_index || theform == DW_FORM_addrx) { Dwarf_Unsigned index = 0; int res = dwarf_get_debug_addr_index(attrib,&index,&err); if(res != DW_DLV_OK) { print_error(dbg, "addr missing index ?!", res, err); } bracket_hex("(addr_index: ",index, ")",esbp); } bracket_hex("",addr,"",esbp); } else if (bres == DW_DLV_ERROR) { if (DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION == dwarf_errno(err)) { Dwarf_Unsigned index = 0; int res = dwarf_get_debug_addr_index(attrib,&index,&err); if(res != DW_DLV_OK) { print_error(dbg, "addr missing index ?!", bres, err); } addr = 0; bracket_hex("(addr_index: ",index, ")",esbp); /* This is normal in a .dwo file. The .debug_addr is in a .o and in the final executable. */ } else { print_error(dbg, "addr form with no addr?!", bres, err); } } else { print_error(dbg, "addr is a DW_DLV_NO_ENTRY? Impossible.", bres, err); } break; case DW_FORM_ref_addr: { Dwarf_Half attr = 0; /* DW_FORM_ref_addr is not accessed thru formref: ** it is an address (global section offset) in ** the .debug_info section. */ bres = dwarf_global_formref(attrib, &off, &err); if (bres == DW_DLV_OK) { bracket_hex("",esbp); } else { print_error(dbg, "DW_FORM_ref_addr form with no reference?!", bres, err); } wres = dwarf_whatattr(attrib, &attr, &err); if (wres == DW_DLV_ERROR) { } else if (wres == DW_DLV_NO_ENTRY) { } else { if (attr == DW_AT_sibling) { /* The value had better be inside the current CU else there is a nasty error here, as a sibling has to be in the same CU, it seems. */ /* The target offset (off) had better be following the die's global offset else we have a serious botch. this FORM defines the value as a .debug_info global offset. */ Dwarf_Off cuoff = 0; Dwarf_Off culen = 0; Dwarf_Off die_overall_offset = 0; int res = 0; int ores = dwarf_dieoffset(die, &die_overall_offset, &err); if (ores != DW_DLV_OK) { print_error(dbg, "dwarf_dieoffset", ores, err); } SET_DIE_STACK_SIBLING(off); if (die_overall_offset >= off) { snprintf(small_buf,sizeof(small_buf), "ERROR: Sibling DW_FORM_ref_offset 0x%" DW_PR_XZEROS DW_PR_DUx " points %s die Global offset " "0x%" DW_PR_XZEROS DW_PR_DUx, off,(die_overall_offset == off)?"at":"before", die_overall_offset); print_error(dbg,small_buf,DW_DLV_OK,0); } res = dwarf_die_CU_offset_range(die,&cuoff, &culen,&err); DWARF_CHECK_COUNT(tag_tree_result,1); if (res != DW_DLV_OK) { } else { Dwarf_Off cuend = cuoff+culen; if (off < cuoff || off >= cuend) { DWARF_CHECK_ERROR(tag_tree_result, "DW_AT_sibling DW_FORM_ref_addr offset points " "outside of current CU"); } } } } } break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: { int refres = 0; Dwarf_Half attr = 0; Dwarf_Off goff = 0; /* Global offset */ Dwarf_Error referr = 0; /* CU-relative offset returned. */ refres = dwarf_formref(attrib, &off, &referr); if (refres != DW_DLV_OK) { /* Report incorrect offset */ snprintf(small_buf,sizeof(small_buf), "%s, offset=<0x%" DW_PR_XZEROS DW_PR_DUx ">","reference form with no valid local ref?!",off); print_error(dbg, small_buf, refres, referr); } refres = dwarf_whatattr(attrib, &attr, &referr); if (refres != DW_DLV_OK) { snprintf(small_buf,sizeof(small_buf), "Form %d, has no attribute value?!" ,theform); print_error(dbg, small_buf, refres, referr); } /* Convert the local offset 'off' into a global section offset 'goff'. */ refres = dwarf_convert_to_global_offset(attrib, off, &goff, &referr); if (refres != DW_DLV_OK) { /* Report incorrect offset */ snprintf(small_buf,sizeof(small_buf), "%s, GOFF=<0x%" DW_PR_XZEROS DW_PR_DUx ">","invalid offset",goff); print_error(dbg, small_buf, refres, referr); } if (attr == DW_AT_sibling) { /* The value had better be inside the current CU else there is a nasty error here, as a sibling has to be in the same CU, it seems. */ /* The target offset (off) had better be following the die's global offset else we have a serious botch. this FORM defines the value as a .debug_info global offset. */ Dwarf_Off die_overall_offset = 0; int ores = dwarf_dieoffset(die, &die_overall_offset, &referr); if (ores != DW_DLV_OK) { print_error(dbg, "dwarf_dieoffset", ores, referr); } SET_DIE_STACK_SIBLING(goff); if (die_overall_offset >= goff) { snprintf(small_buf,sizeof(small_buf), "ERROR: Sibling offset 0x%" DW_PR_XZEROS DW_PR_DUx " points %s its own die GOFF=" "0x%" DW_PR_XZEROS DW_PR_DUx, goff, (die_overall_offset == goff)?"at":"before", die_overall_offset); print_error(dbg,small_buf,DW_DLV_OK,0); } } /* Do references inside <> to distinguish them ** from constants. In dense form this results in <<>>. Ugly for dense form, but better than ambiguous. davea 9/94 */ if (glflags.gf_show_global_offsets) { bracket_hex("<",off,"",esbp); bracket_hex(" GOFF=",goff,">",esbp); } else { bracket_hex("<",off,">",esbp); } if (glflags.gf_check_type_offset) { if (attr == DW_AT_type && form_refers_local_info(theform)) { dres = dwarf_offdie_b(dbg, goff, is_info, &die_for_check, &referr); if (dres != DW_DLV_OK) { snprintf(small_buf,sizeof(small_buf), "DW_AT_type offset does not point to a DIE " "for global offset 0x%" DW_PR_XZEROS DW_PR_DUx " cu off 0x%" DW_PR_XZEROS DW_PR_DUx " local offset 0x%" DW_PR_XZEROS DW_PR_DUx " tag 0x%x", goff,dieprint_cu_goffset,off,tag); DWARF_CHECK_ERROR(type_offset_result,small_buf); } else { int tres2 = dwarf_tag(die_for_check, &tag_for_check, &err); if (tres2 == DW_DLV_OK) { switch (tag_for_check) { case DW_TAG_array_type: case DW_TAG_class_type: case DW_TAG_enumeration_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: case DW_TAG_restrict_type: case DW_TAG_string_type: case DW_TAG_structure_type: case DW_TAG_subroutine_type: case DW_TAG_typedef: case DW_TAG_union_type: case DW_TAG_ptr_to_member_type: case DW_TAG_set_type: case DW_TAG_subrange_type: case DW_TAG_base_type: case DW_TAG_const_type: case DW_TAG_file_type: case DW_TAG_packed_type: case DW_TAG_thrown_type: case DW_TAG_volatile_type: case DW_TAG_template_type_parameter: case DW_TAG_template_value_parameter: case DW_TAG_unspecified_type: /* Template alias */ case DW_TAG_template_alias: /* OK */ break; default: { snprintf(small_buf,sizeof(small_buf), "DW_AT_type offset " "0x%" DW_PR_XZEROS DW_PR_DUx " does not point to Type" " info we got tag 0x%x %s", (Dwarf_Unsigned)goff, tag_for_check, get_TAG_name(tag_for_check, pd_dwarf_names_print_on_error)); DWARF_CHECK_ERROR(type_offset_result,small_buf); } break; } dwarf_dealloc(dbg, die_for_check, DW_DLA_DIE); die_for_check = 0; } else { DWARF_CHECK_ERROR(type_offset_result, "DW_AT_type offset does not exist"); } } } } } break; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: fres = dwarf_formblock(attrib, &tempb, &err); if (fres == DW_DLV_OK) { unsigned u = 0; for (u = 0; u < tempb->bl_len; u++) { snprintf(small_buf, sizeof(small_buf), "%02x", *(u + (unsigned char *) tempb->bl_data)); esb_append(esbp, small_buf); } dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); tempb = 0; } else { print_error(dbg, "DW_FORM_blockn cannot get block\n", fres, err); } break; case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_data16: { Dwarf_Half attr = 0; fres = dwarf_whatattr(attrib, &attr, &err); if (fres == DW_DLV_ERROR) { print_error(dbg, "FORM_datan cannot get attr", fres, err); } else if (fres == DW_DLV_NO_ENTRY) { print_error(dbg, "FORM_datan cannot get attr", fres, err); } else { switch (attr) { case DW_AT_ordering: case DW_AT_byte_size: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_inline: case DW_AT_language: case DW_AT_visibility: case DW_AT_virtuality: case DW_AT_accessibility: case DW_AT_address_class: case DW_AT_calling_convention: case DW_AT_discr_list: /* DWARF2 */ case DW_AT_encoding: case DW_AT_identifier_case: case DW_AT_MIPS_loop_unroll_factor: case DW_AT_MIPS_software_pipeline_depth: case DW_AT_decl_column: case DW_AT_decl_file: case DW_AT_decl_line: case DW_AT_call_column: case DW_AT_call_file: case DW_AT_call_line: case DW_AT_start_scope: case DW_AT_byte_stride: case DW_AT_bit_stride: case DW_AT_count: case DW_AT_stmt_list: case DW_AT_MIPS_fde: { int show_form_here = 0; wres = get_small_encoding_integer_and_name(dbg, attrib, &tempud, /* attrname */ (const char *) NULL, /* err_string */ ( struct esb_s *) NULL, (encoding_type_func) 0, &err,show_form_here); if (wres == DW_DLV_OK) { Dwarf_Bool hex_format = TRUE; formx_unsigned(tempud,esbp,hex_format); /* Check attribute encoding */ if (glflags.gf_check_attr_encoding) { check_attributes_encoding(attr,theform,tempud); } if (attr == DW_AT_decl_file || attr == DW_AT_call_file) { if (srcfiles && tempud > 0 && /* ASSERT: cnt >= 0 */ tempud <= (Dwarf_Unsigned)cnt) { /* added by user request */ /* srcfiles is indexed starting at 0, but DW_AT_decl_file defines that 0 means no file, so tempud 1 means the 0th entry in srcfiles, thus tempud-1 is the correct index into srcfiles. */ char *fname = srcfiles[tempud - 1]; esb_append(esbp, " "); esb_append(esbp, fname); } /* Validate integrity of files referenced in .debug_line */ if (glflags.gf_check_decl_file) { DWARF_CHECK_COUNT(decl_file_result,1); /* Zero is always a legal index, it means no source name provided. */ if (tempud != 0 && tempud > ((Dwarf_Unsigned)cnt)) { if (!srcfiles) { snprintf(small_buf,sizeof(small_buf), "There is a file number=%" DW_PR_DUu " but no source files " " are known.",tempud); } else { snprintf(small_buf, sizeof(small_buf), "Does not point to valid file info " " filenum=%" DW_PR_DUu " filecount=%" DW_PR_DUu ".", tempud,cnt); } DWARF_CHECK_ERROR2(decl_file_result, get_AT_name(attr, pd_dwarf_names_print_on_error), small_buf); } } } } else { print_error(dbg, "Cannot get encoding attribute ..", wres, err); } } break; case DW_AT_const_value: /* Do not use hexadecimal format */ wres = formxdata_print_value(dbg,die,attrib, theform,esbp, &err, FALSE); if (wres == DW_DLV_OK){ /* String appended already. */ } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg,"Cannot get DW_AT_const_value ",wres,err); } break; case DW_AT_GNU_dwo_id: case DW_AT_GNU_odr_signature: case DW_AT_dwo_id: { Dwarf_Sig8 v; memset(&v,0,sizeof(v)); wres = dwarf_formsig8_const(attrib,&v,&err); if (wres == DW_DLV_OK){ struct esb_s t; esb_constructor(&t); format_sig8_string(&v,&t); esb_append(esbp,esb_get_string(&t)); esb_destructor(&t); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ esb_append(esbp,"Impossible: no entry for formsig8 dwo_id"); } else { print_error(dbg,"Cannot get DW_AT_const_value ",wres,err); } } break; case DW_AT_upper_bound: case DW_AT_lower_bound: default: { Dwarf_Bool chex = FALSE; Dwarf_Die tdie = die; if(DW_AT_ranges == attr) { /* In this case do not look for data type for unsigned/signed. and do use HEX. */ chex = TRUE; tdie = NULL; } /* Do not use hexadecimal format except for DW_AT_ranges. */ wres = formxdata_print_value(dbg, tdie,attrib, theform,esbp, &err, chex); if (wres == DW_DLV_OK) { /* String appended already. */ } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg, "Cannot get form data..", wres, err); } } break; } } if (glflags.gf_cu_name_flag) { if (attr == DW_AT_MIPS_fde) { if (glflags.fde_offset_for_cu_low == DW_DLV_BADOFFSET) { glflags.fde_offset_for_cu_low = glflags.fde_offset_for_cu_high = tempud; } else if (tempud < glflags.fde_offset_for_cu_low) { glflags.fde_offset_for_cu_low = tempud; } else if (tempud > glflags.fde_offset_for_cu_high) { glflags.fde_offset_for_cu_high = tempud; } } } } break; case DW_FORM_sdata: wres = dwarf_formsdata(attrib, &tempsd, &err); if (wres == DW_DLV_OK) { Dwarf_Bool hxform=TRUE; tempud = tempsd; formx_unsigned_and_signed_if_neg(tempud,tempsd, " (",hxform,esbp); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg, "Cannot get formsdata..", wres, err); } break; case DW_FORM_udata: wres = dwarf_formudata(attrib, &tempud, &err); if (wres == DW_DLV_OK) { Dwarf_Bool hex_format = TRUE; formx_unsigned(tempud,esbp,hex_format); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg, "Cannot get formudata....", wres, err); } break; /* various forms for strings. */ case DW_FORM_string: case DW_FORM_strp: case DW_FORM_strx: /* DWARF5 */ case DW_FORM_strx1: /* DWARF5 */ case DW_FORM_strx2: /* DWARF5 */ case DW_FORM_strx3: /* DWARF5 */ case DW_FORM_strx4: /* DWARF5 */ case DW_FORM_strp_sup: /* DWARF5 String in altrnt: tied file */ case DW_FORM_GNU_strp_alt: /* String in altrnt: tied file */ case DW_FORM_line_strp: /* DWARF5, offset to .debug_line_str */ /* unsigned offset in size of an offset */ case DW_FORM_GNU_str_index: { int sres = dwarf_formstring(attrib, &temps, &err); if (sres == DW_DLV_OK) { if (theform == DW_FORM_strx || theform == DW_FORM_strx1 || theform == DW_FORM_strx2 || theform == DW_FORM_strx3 || theform == DW_FORM_strx4 || theform == DW_FORM_GNU_str_index) { struct esb_s saver; Dwarf_Unsigned index = 0; esb_constructor(&saver); sres = dwarf_get_debug_str_index(attrib,&index,&err); esb_append(&saver,temps); if(sres == DW_DLV_OK) { bracket_hex("(indexed string: ",index,")",esbp); } else { esb_append(esbp,"(indexed string:no string provided?)"); } esb_append(esbp, esb_get_string(&saver)); esb_destructor(&saver); } else { esb_append(esbp,temps); } } else if (sres == DW_DLV_NO_ENTRY) { if (theform == DW_FORM_strx || theform == DW_FORM_GNU_str_index || theform == DW_FORM_strx1 || theform == DW_FORM_strx2 || theform == DW_FORM_strx3 || theform == DW_FORM_strx4 ) { esb_append(esbp, "(indexed string,no string provided?)"); } else { esb_append(esbp, ""); } } else { if (theform == DW_FORM_strx || theform == DW_FORM_GNU_str_index || theform == DW_FORM_strx1 || theform == DW_FORM_strx2 || theform == DW_FORM_strx3 || theform == DW_FORM_strx4 ) { print_error(dbg, "Cannot get an indexed string....", sres, err); } else { print_error(dbg, "Cannot get a formstr (or a formstrp)....", sres, err); } } } break; case DW_FORM_flag: wres = dwarf_formflag(attrib, &tempbool, &err); if (wres == DW_DLV_OK) { if (tempbool) { snprintf(small_buf, sizeof(small_buf), "yes(%d)", tempbool); esb_append(esbp, small_buf); } else { snprintf(small_buf, sizeof(small_buf), "no"); esb_append(esbp, small_buf); } } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg, "Cannot get formflag/p....", wres, err); } break; case DW_FORM_indirect: /* We should not ever get here, since the true form was determined and direct_form has the DW_FORM_indirect if it is used here in this attr. */ esb_append(esbp, get_FORM_name(theform, pd_dwarf_names_print_on_error)); break; case DW_FORM_exprloc: { /* DWARF4 */ int showhextoo = 1; print_exprloc_content(dbg,die,attrib,showhextoo,esbp); } break; case DW_FORM_sec_offset: { /* DWARF4 */ char* emptyattrname = 0; int show_form_here = 0; wres = get_small_encoding_integer_and_name(dbg, attrib, &tempud, emptyattrname, /* err_string */ NULL, (encoding_type_func) 0, &err,show_form_here); if (wres == DW_DLV_NO_ENTRY) { /* Show nothing? */ } else if (wres == DW_DLV_ERROR) { print_error(dbg, "Cannot get a DW_FORM_sec_offset....", wres, err); } else { bracket_hex("",tempud,"",esbp); } } break; case DW_FORM_flag_present: /* DWARF4 */ esb_append(esbp,"yes(1)"); break; case DW_FORM_ref_sig8: { /* DWARF4 */ Dwarf_Sig8 sig8data; wres = dwarf_formsig8(attrib,&sig8data,&err); if (wres != DW_DLV_OK) { /* Show nothing? */ print_error(dbg, "Cannot get a DW_FORM_ref_sig8 ....", wres, err); } else { struct esb_s sig8str; esb_constructor(&sig8str); format_sig8_string(&sig8data,&sig8str); esb_append(esbp,esb_get_string(&sig8str)); esb_destructor(&sig8str); if (!show_form) { esb_append(esbp," "); } } } break; case DW_FORM_implicit_const: { /* DWARF5, attr val is signed uleb */ wres = dwarf_formsdata(attrib, &tempsd, &err); if (wres == DW_DLV_OK) { Dwarf_Bool hxform=TRUE; tempud = tempsd; formx_unsigned_and_signed_if_neg(tempud,tempsd, " (",hxform,esbp); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg, "Cannot get formsdata, " "DW_FORM_implicit_const..", wres, err); } } break; case DW_FORM_loclistx: /* DWARF5, index into .debug_loclists */ case DW_FORM_rnglistx: { /* DWARF5, index into .debug_rnglists */ /* FIXME: print loclist or rnglist info */ wres = dwarf_formudata(attrib, &tempud, &err); if (wres == DW_DLV_OK) { Dwarf_Bool hex_format = TRUE; formx_unsigned(tempud,esbp,hex_format); } else if (wres == DW_DLV_NO_ENTRY) { /* nothing? */ } else { print_error(dbg, "Cannot get formudata" " on DW_FORM_loclistx....", wres, err); } } break; case DW_FORM_ref_sup4: /* DWARF5 */ case DW_FORM_ref_sup8: /* DWARF5 */ case DW_FORM_GNU_ref_alt: { bres = dwarf_global_formref(attrib, &off, &err); if (bres == DW_DLV_OK) { bracket_hex("",off,"",esbp); } else { print_error(dbg, "DW_FORM_GNU_ref_alt form with no reference?!", bres, err); } } break; default: print_error(dbg, "dwarf_whatform unexpected value", DW_DLV_OK, err); } show_form_itself(show_form,local_verbose,theform, direct_form,esbp); } void format_sig8_string(Dwarf_Sig8*data, struct esb_s *out) { unsigned i = 0; char small_buf[40]; esb_append(out,"0x"); for (; i < sizeof(data->signature); ++i) { #if 0 /* The signature is logically one glob of 8 bytes, not two, so show as one glob using 16 ascii hex digits */ if (i == 4) { esb_append(out," 0x"); } #endif snprintf(small_buf,sizeof(small_buf), "%02x", (unsigned char)(data->signature[i])); esb_append(out,small_buf); } } /* This leaks Dwarf_Error in case of error. FIXME */ static int get_form_values(Dwarf_Debug dbg,Dwarf_Attribute attrib, Dwarf_Half * theform, Dwarf_Half * directform) { Dwarf_Error verr = 0; int res = 0; res = dwarf_whatform(attrib, theform, &verr); DROP_ERROR_INSTANCE(dbg,res,verr); res = dwarf_whatform_direct(attrib, directform, &verr); DROP_ERROR_INSTANCE(dbg,res,verr); return res; } static void show_form_itself(int local_show_form, int local_verbose, int theform, int directform, struct esb_s *esbp) { #ifdef ORIGINAL_SPRINTF char small_buf[100]; #endif if (local_show_form && directform && directform == DW_FORM_indirect) { char *form_indir = " (used DW_FORM_indirect"; char *form_indir2 = ") "; esb_append(esbp, form_indir); if (local_verbose) { #ifdef ORIGINAL_SPRINT esb_append(esbp, get_form_number_as_string(DW_FORM_indirect, small_buf,sizeof(small_buf))); #else esb_append_printf_i(esbp," %d",DW_FORM_indirect); #endif } esb_append(esbp, form_indir2); } if (local_show_form) { esb_append(esbp,"
"); } } #include "dwarfdump-ta-table.h" #include "dwarfdump-ta-ext-table.h" static int legal_tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr) { if (tag <= 0) { return FALSE; } if (tag < ATTR_TREE_ROW_COUNT) { int index = attr / BITS_PER_WORD; if (index < ATTR_TREE_COLUMN_COUNT) { unsigned bitflag = ((unsigned)1) << (attr % BITS_PER_WORD); int known = ((tag_attr_combination_table[tag][index] & bitflag) > 0 ? TRUE : FALSE); if (known) { #ifdef HAVE_USAGE_TAG_ATTR /* Record usage of pair (tag,attr) */ if ( glflags.gf_print_usage_tag_attr) { Usage_Tag_Attr *usage_ptr = usage_tag_attr[tag]; while (usage_ptr->attr) { if (attr == usage_ptr->attr) { ++usage_ptr->count; break; } ++usage_ptr; } } #endif /* HAVE_USAGE_TAG_ATTR */ return TRUE; } } } /* DW_AT_MIPS_fde used to return TRUE as that was convenient for SGI/MIPS users. */ if (!glflags.gf_suppress_check_extensions_tables) { int r = 0; for (; r < ATTR_TREE_EXT_ROW_COUNT; ++r ) { int c = 1; if (tag != tag_attr_combination_ext_table[r][0]) { continue; } for (; c < ATTR_TREE_EXT_COLUMN_COUNT ; ++c) { if (tag_attr_combination_ext_table[r][c] == attr) { return TRUE; } } } } return (FALSE); } #include "dwarfdump-tt-table.h" #include "dwarfdump-tt-ext-table.h" /* Look only at valid table entries The check here must match the building-logic in tag_tree.c And must match the tags defined in dwarf.h The tag_tree_combination_table is a table of bit flags. */ static int legal_tag_tree_combination(Dwarf_Half tag_parent, Dwarf_Half tag_child) { if (tag_parent <= 0) { return FALSE; } if (tag_parent < TAG_TREE_ROW_COUNT) { int index = tag_child / BITS_PER_WORD; if (index < TAG_TREE_COLUMN_COUNT) { unsigned bitflag = ((unsigned)1) << (tag_child % BITS_PER_WORD); int known = ((tag_tree_combination_table[tag_parent] [index] & bitflag) > 0 ? TRUE : FALSE); if (known) { #ifdef HAVE_USAGE_TAG_ATTR /* Record usage of pair (tag_parent,tag_child) */ if ( glflags.gf_print_usage_tag_attr) { Usage_Tag_Tree *usage_ptr = usage_tag_tree[tag_parent]; while (usage_ptr->tag) { if (tag_child == usage_ptr->tag) { ++usage_ptr->count; break; } ++usage_ptr; } } #endif /* HAVE_USAGE_TAG_ATTR */ return TRUE; } } } if (!glflags.gf_suppress_check_extensions_tables) { int r = 0; for (; r < TAG_TREE_EXT_ROW_COUNT; ++r ) { int c = 1; if (tag_parent != tag_tree_combination_ext_table[r][0]) { continue; } for (; c < TAG_TREE_EXT_COLUMN_COUNT ; ++c) { if (tag_tree_combination_ext_table[r][c] == tag_child) { return TRUE; } } } } return (FALSE); } /* Print a detailed tag and attributes usage */ void print_tag_attributes_usage(UNUSEDARG Dwarf_Debug dbg) { #ifdef HAVE_USAGE_TAG_ATTR /* Traverse the tag-tree table to print its usage and then use the DW_TAG value as an index into the tag_attr table to print its associated usage all together. */ boolean print_header = TRUE; Rate_Tag_Tree *tag_rate; Rate_Tag_Attr *atr_rate; Usage_Tag_Tree *usage_tag_tree_ptr; Usage_Tag_Attr *usage_tag_attr_ptr; Dwarf_Unsigned total_tags = 0; Dwarf_Unsigned total_atrs = 0; Dwarf_Half total_found_tags = 0; Dwarf_Half total_found_atrs = 0; Dwarf_Half total_legal_tags = 0; Dwarf_Half total_legal_atrs = 0; float rate_1; float rate_2; int tag; printf("\n*** TAGS AND ATTRIBUTES USAGE ***\n"); for (tag = 1; tag < DW_TAG_last; ++tag) { /* Print usage of children TAGs */ if ( glflags.gf_print_usage_tag_attr_full || tag_usage[tag]) { usage_tag_tree_ptr = usage_tag_tree[tag]; if (usage_tag_tree_ptr && print_header) { total_tags += tag_usage[tag]; printf("%6d %s\n", tag_usage[tag], get_TAG_name(tag,pd_dwarf_names_print_on_error)); print_header = FALSE; } while (usage_tag_tree_ptr && usage_tag_tree_ptr->tag) { if ( glflags.gf_print_usage_tag_attr_full || usage_tag_tree_ptr->count) { total_tags += usage_tag_tree_ptr->count; printf("%6s %6d %s\n", " ", usage_tag_tree_ptr->count, get_TAG_name(usage_tag_tree_ptr->tag, pd_dwarf_names_print_on_error)); /* Record the tag as found */ if (usage_tag_tree_ptr->count) { ++rate_tag_tree[tag].found; } } ++usage_tag_tree_ptr; } } /* Print usage of attributes */ if ( glflags.gf_print_usage_tag_attr_full || tag_usage[tag]) { usage_tag_attr_ptr = usage_tag_attr[tag]; if (usage_tag_attr_ptr && print_header) { total_tags += tag_usage[tag]; printf("%6d %s\n", tag_usage[tag], get_TAG_name(tag,pd_dwarf_names_print_on_error)); } while (usage_tag_attr_ptr && usage_tag_attr_ptr->attr) { if ( glflags.gf_print_usage_tag_attr_full || usage_tag_attr_ptr->count) { total_atrs += usage_tag_attr_ptr->count; printf("%6s %6d %s\n", " ", usage_tag_attr_ptr->count, get_AT_name(usage_tag_attr_ptr->attr, pd_dwarf_names_print_on_error)); /* Record the attribute as found */ if (usage_tag_attr_ptr->count) { ++rate_tag_attr[tag].found; } } ++usage_tag_attr_ptr; } } print_header = TRUE; } printf("** Summary **\n" "Number of tags : %10" /*DW_PR_XZEROS*/ DW_PR_DUu "\n" /* TAGs */ "Number of attributes: %10" /*DW_PR_XZEROS*/ DW_PR_DUu "\n" /* ATRs */, total_tags, total_atrs); total_legal_tags = 0; total_found_tags = 0; total_legal_atrs = 0; total_found_atrs = 0; /* Print percentage of TAGs covered */ printf("\n*** TAGS AND ATTRIBUTES USAGE RATE ***\n"); printf("%-32s %-16s %-16s\n"," ","Tags","Attributes"); printf("%-32s legal found rate legal found rate\n","TAG name"); for (tag = 1; tag < DW_TAG_last; ++tag) { tag_rate = &rate_tag_tree[tag]; atr_rate = &rate_tag_attr[tag]; if ( glflags.gf_print_usage_tag_attr_full || tag_rate->found || atr_rate->found) { rate_1 = tag_rate->legal ? (float)((tag_rate->found * 100) / tag_rate->legal) : 0; rate_2 = atr_rate->legal ? (float)((atr_rate->found * 100) / atr_rate->legal) : 0; /* Skip not defined DW_TAG values (See dwarf.h) */ if (usage_tag_tree[tag]) { total_legal_tags += tag_rate->legal; total_found_tags += tag_rate->found; total_legal_atrs += atr_rate->legal; total_found_atrs += atr_rate->found; printf("%-32s %5d %5d %3.0f%% %5d %5d %3.0f%%\n", get_TAG_name(tag,pd_dwarf_names_print_on_error), tag_rate->legal,tag_rate->found,rate_1, atr_rate->legal,atr_rate->found,rate_2); } } } /* Print a whole summary */ rate_1 = total_legal_tags ? (float)((total_found_tags * 100) / total_legal_tags) : 0; rate_2 = total_legal_atrs ? (float)((total_found_atrs * 100) / total_legal_atrs) : 0; printf("%-32s %5d %5d %3.0f%% %5d %5d %3.0f%%\n", "** Summary **", total_legal_tags,total_found_tags,rate_1, total_legal_atrs,total_found_atrs,rate_2); #endif /* HAVE_USAGE_TAG_ATTR */ } dwarfutils-20200114/dwarfdump/print_dnames.c000066400000000000000000000052641361531463500207670ustar00rootroot00000000000000/* Copyright 2017-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "sanitized.h" #include "esb.h" #include "esb_using_functions.h" extern void print_debug_names(Dwarf_Debug dbg) { Dwarf_Dnames_Head dnhead = 0; Dwarf_Unsigned dn_count = 0; Dwarf_Unsigned dnindex = 0; Dwarf_Error error = 0; int res = 0; if(!dbg) { printf("Cannot print .debug_names, no Dwarf_Debug passed in"); printf("dwarfdump giving up. exit.\n"); exit(1); } glflags.current_section_id = DEBUG_NAMES; /* Only print anything if we know it has debug names present. And for now there is none. FIXME. */ res = dwarf_debugnames_header(dbg,&dnhead,&dn_count,&error); if (res == DW_DLV_NO_ENTRY) { return; } if (res == DW_DLV_ERROR) { const char *msg = "Section .debug_names is not openable"; print_error(dbg,msg, res, error); return; } /* Do nothing if not printing. */ if (glflags.gf_do_print_dwarf) { const char * section_name = ".debug_names"; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,section_name, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } if (glflags.gf_do_print_dwarf) { printf("names tables: %" DW_PR_DUu "\n",dn_count); } for ( ; dnindex < dn_count; ++dnindex) { if (glflags.gf_do_print_dwarf) { printf("names table %" DW_PR_DUu "\n",dnindex); } } dwarf_dealloc(dbg,dnhead,DW_DLA_DNAMES_HEAD); return; } dwarfutils-20200114/dwarfdump/print_frames.c000066400000000000000000002707021361531463500207760ustar00rootroot00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011-2018 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* From 199x through 2010 print_frames relied on the order of the fdes matching the order of the functions in the CUs when it came to printing a function name with an FDE. This sometimes worked for SGI/IRIX because of the way the compiler often emitted things. It always worked poorly for gcc and other compilers. As of 2010 the addrmap.h addrmap.h code provides help in doing a better job when the tsearch functions (part of POSIX) are available. */ #include "globals.h" #include "print_frames.h" #include "dwconf.h" #include "dwconf_using_functions.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "addrmap.h" #include "naming.h" #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ #define true 1 #define false 0 /* This attempts to provide some data for error messages. On failure just give up here and return. Other code will be reporting an error. */ static void load_CU_error_data(Dwarf_Debug dbg,Dwarf_Die die); static void print_one_frame_reg_col(Dwarf_Debug dbg, Dwarf_Unsigned rule_id, Dwarf_Small value_type, Dwarf_Unsigned reg_used, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct dwconf_s *config_data, Dwarf_Signed offset_relevant, Dwarf_Signed offset, Dwarf_Ptr block_ptr); static void print_frame_inst_bytes(Dwarf_Debug dbg, Dwarf_Ptr cie_init_inst, Dwarf_Signed len, Dwarf_Signed data_alignment_factor, int code_alignment_factor, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct dwconf_s *config_data); /* A strcpy which ensures NUL terminated string and never overruns the output. */ void safe_strcpy(char *out, long outlen, const char *in, long inlen) { if (inlen >= (outlen - 1)) { strncpy(out, in, outlen - 1); out[outlen - 1] = 0; } else { strcpy(out, in); } } #define MAXLEBLEN 10 #define BITSPERBYTE 8 /* decode ULEB */ static int local_dwarf_decode_u_leb128_chk(unsigned char *leb128, unsigned int *leb128_length, Dwarf_Unsigned *value_out, Dwarf_Small *data_end) { Dwarf_Unsigned byte = 0; Dwarf_Unsigned number = 0; unsigned int shift = 0; unsigned int byte_length = 1; byte = *leb128; if (leb128 >= data_end) { return DW_DLV_ERROR; } for (;;) { if (shift >= (sizeof(number)*BITSPERBYTE)) { return DW_DLV_ERROR; } number |= (byte & 0x7f) << shift; shift += 7; if ((byte & 0x80) == 0) { if (leb128_length != NULL) *leb128_length = byte_length; *value_out = number; return DW_DLV_OK; } byte_length++; if (byte_length > MAXLEBLEN) { return DW_DLV_ERROR; } ++leb128; if (leb128 >= data_end) { return DW_DLV_ERROR; } byte = *leb128; } return DW_DLV_ERROR; } #define BITSINBYTE 8 static int local_dwarf_decode_s_leb128_chk(unsigned char *leb128, unsigned int *leb128_length, Dwarf_Signed *value_out, Dwarf_Small *data_end) { Dwarf_Signed number = 0; Dwarf_Bool sign = 0; unsigned shift = 0; Dwarf_Unsigned byte = 0; unsigned byte_length = 1; /* byte_length being the number of bytes of data absorbed so far in turning the leb into a Dwarf_Signed. */ if (leb128 >= data_end) { return DW_DLV_ERROR; } byte = *leb128; for (;;) { sign = byte & 0x40; if (shift >= (sizeof(number)*BITSPERBYTE)) { return DW_DLV_ERROR; } number |= (byte & 0x7f) << shift; shift += 7; if ((byte & 0x80) == 0) { break; } ++leb128; if (leb128 >= data_end) { return DW_DLV_ERROR; } if (byte_length > MAXLEBLEN) { return DW_DLV_ERROR; } byte = *leb128; byte_length++; } if (sign) { /* The following avoids undefined behavior. */ unsigned shiftlim = sizeof(Dwarf_Signed) * BITSINBYTE -1; if (shift < shiftlim) { number |= -(Dwarf_Signed)(((Dwarf_Unsigned)1) << shift); } else if (shift == shiftlim) { number |= (((Dwarf_Unsigned)1) << shift); } } if (leb128_length != NULL) *leb128_length = byte_length; *value_out = number; return DW_DLV_OK; } /* For inlined functions, try to find name */ static int get_abstract_origin_funcname(Dwarf_Debug dbg,Dwarf_Attribute attr, char *name_out, unsigned maxlen) { Dwarf_Off off = 0; Dwarf_Die origin_die = 0; Dwarf_Attribute *atlist = NULL; Dwarf_Signed atcnt = 0; Dwarf_Signed i = 0; int dres = 0; int atres = 0; int name_found = 0; int res = 0; Dwarf_Error err = 0; res = dwarf_global_formref(attr,&off,&err); if (res != DW_DLV_OK) { return DW_DLV_NO_ENTRY; } dres = dwarf_offdie(dbg,off,&origin_die,&err); if (dres != DW_DLV_OK) { return DW_DLV_NO_ENTRY; } atres = dwarf_attrlist(origin_die, &atlist, &atcnt, &err); if (atres != DW_DLV_OK) { dwarf_dealloc(dbg,origin_die,DW_DLA_DIE); return DW_DLV_NO_ENTRY; } for (i = 0; i < atcnt; i++) { Dwarf_Half lattr = 0; int ares = 0; ares = dwarf_whatattr(atlist[i], &lattr, &err); if (ares == DW_DLV_ERROR) { break; } else if (ares == DW_DLV_OK) { if (lattr == DW_AT_name) { int sres = 0; char* tempsl = 0; sres = dwarf_formstring(atlist[i], &tempsl, &err); if (sres == DW_DLV_OK) { long len = (long) strlen(tempsl); safe_strcpy(name_out, maxlen, tempsl, len); name_found = 1; break; } } } } for (i = 0; i < atcnt; i++) { dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); dwarf_dealloc(dbg,origin_die,DW_DLA_DIE); if (!name_found) { return DW_DLV_NO_ENTRY; } return DW_DLV_OK; } /* Returns 1 if a proc with this low_pc found. Else returns 0. From print_die.c this has no pcMap passed in, we do not really have a sensible context, so this really just looks at the current attributes for a name. */ int get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, char *proc_name_buf, int proc_name_buf_len, void **pcMap) { Dwarf_Signed atcnt = 0; Dwarf_Signed i = 0; Dwarf_Attribute *atlist = NULL; Dwarf_Addr low_pc_die = 0; int atres = 0; int funcres = 1; int funcpcfound = 0; int funcnamefound = 0; Dwarf_Error proc_name_err = 0; proc_name_buf[0] = 0; /* always set to something */ if (pcMap) { struct Addr_Map_Entry *ame = 0; ame = addr_map_find(low_pc,pcMap); if (ame && ame->mp_name) { /* mp_name is NULL only if we ran out of heap space. */ safe_strcpy(proc_name_buf, proc_name_buf_len, ame->mp_name,(long) strlen(ame->mp_name)); return 1; } } atres = dwarf_attrlist(die, &atlist, &atcnt, &proc_name_err); if (atres == DW_DLV_ERROR) { print_error(dbg, "dwarf_attrlist", atres, proc_name_err); return 0; } if (atres == DW_DLV_NO_ENTRY) { return 0; } for (i = 0; i < atcnt; i++) { Dwarf_Half attr = 0; int ares = 0; char * temps = 0; int sres = 0; int dres = 0; if (funcnamefound == 1 && funcpcfound == 1) { /* stop as soon as both found */ break; } ares = dwarf_whatattr(atlist[i], &attr, &proc_name_err); if (ares == DW_DLV_ERROR) { load_CU_error_data(dbg,current_cu_die_for_print_frames); print_error(dbg, "get_proc_name whatattr error", ares, proc_name_err); } else if (ares == DW_DLV_OK) { switch (attr) { case DW_AT_specification: case DW_AT_abstract_origin: { if (!funcnamefound) { /* Only use this if we have not seen DW_AT_name yet .*/ int aores = get_abstract_origin_funcname(dbg, atlist[i], proc_name_buf,proc_name_buf_len); if (aores == DW_DLV_OK) { /* FOUND THE NAME */ funcnamefound = 1; } } } break; case DW_AT_name: /* Even if we saw DW_AT_abstract_origin, go ahead and take DW_AT_name. */ sres = dwarf_formstring(atlist[i], &temps, &proc_name_err); if (sres == DW_DLV_ERROR) { load_CU_error_data(dbg, current_cu_die_for_print_frames); print_error(dbg, "formstring in get_proc_name failed", sres, proc_name_err); /* 50 is safe wrong length since is bigger than the actual string */ safe_strcpy(proc_name_buf, proc_name_buf_len, "ERROR in dwarf_formstring!", 50); } else if (sres == DW_DLV_NO_ENTRY) { /* 50 is safe wrong length since is bigger than the actual string */ safe_strcpy(proc_name_buf, proc_name_buf_len, "NO ENTRY on dwarf_formstring?!", 50); } else { long len = (long) strlen(temps); safe_strcpy(proc_name_buf, proc_name_buf_len, temps, len); } funcnamefound = 1; /* FOUND THE NAME */ break; case DW_AT_low_pc: dres = dwarf_formaddr(atlist[i], &low_pc_die, &proc_name_err); if (dres == DW_DLV_ERROR) { load_CU_error_data(dbg, current_cu_die_for_print_frames); if (DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION == dwarf_errno(proc_name_err)) { print_error_and_continue(dbg, "The .debug_addr section is missing, " "low_pc unavailable", dres,proc_name_err); dwarf_dealloc(dbg,proc_name_err,DW_DLA_ERROR); proc_name_err= 0; } else { print_error(dbg, "formaddr in get_proc_name failed", dres, proc_name_err); } low_pc_die = ~low_pc; /* ensure no match */ } funcpcfound = 1; break; default: break; } } } for (i = 0; i < atcnt; i++) { dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); if (funcnamefound && funcpcfound && pcMap ) { /* Insert every name to map, not just the one we are looking for. This version does extra work in that early symbols in a CU will be inserted multiple times (the extra times have no effect), the dwarfdump2 version of this does less work. */ addr_map_insert(low_pc_die,proc_name_buf,pcMap); } if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_die) { funcres = 0; } return (funcres); } /* Modified Depth First Search looking for the procedure: a) only looks for children of subprogram. b) With subprogram looks at current die *before* looking for a child. Needed since some languages, including SGI MP Fortran, have nested functions. Return 0 on failure, 1 on success. */ static int load_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc, char *ret_name_buf, int ret_name_buf_len, void **pcMap) { char name_buf[BUFSIZ]; Dwarf_Die curdie = die; int die_locally_gotten = 0; Dwarf_Die prev_child = 0; Dwarf_Die newchild = 0; Dwarf_Die newsibling = 0; Dwarf_Half tag; Dwarf_Error nested_err = 0; int chres = DW_DLV_OK; ret_name_buf[0] = 0; name_buf[0] = 0; while (chres == DW_DLV_OK) { int tres; tres = dwarf_tag(curdie, &tag, &nested_err); newchild = 0; if (tres == DW_DLV_OK) { int lchres = 0; if (tag == DW_TAG_subprogram) { int proc_name_v = get_proc_name(dbg, curdie, low_pc, name_buf, BUFSIZ,pcMap); if (proc_name_v) { safe_strcpy(ret_name_buf, ret_name_buf_len, name_buf, (long) strlen(name_buf)); if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } return 1; } /* Check children of subprograms recursively should this really be check children of anything, or just children of subprograms? */ lchres = dwarf_child(curdie, &newchild, &nested_err); if (lchres == DW_DLV_OK) { /* look for inner subprogram */ int newprog = load_nested_proc_name(dbg, newchild, low_pc, name_buf, BUFSIZ, pcMap); dwarf_dealloc(dbg, newchild, DW_DLA_DIE); if (newprog) { /* Found it. We could just take this name or we could concatenate names together For now, just take name */ if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } safe_strcpy(ret_name_buf, ret_name_buf_len, name_buf, (long) strlen(name_buf)); return 1; } } else if (lchres == DW_DLV_NO_ENTRY) { /* nothing to do */ } else { load_CU_error_data(dbg, current_cu_die_for_print_frames); print_error(dbg, "load_nested_proc_name dwarf_child() failed ", lchres, nested_err); if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } return 0; } } /* end if TAG_subprogram */ } else { load_CU_error_data(dbg, current_cu_die_for_print_frames); print_error(dbg, "no tag on child read ", tres, nested_err); if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } return 0; } /* try next sibling */ prev_child = curdie; chres = dwarf_siblingof(dbg, curdie, &newsibling, &nested_err); if (chres == DW_DLV_ERROR) { load_CU_error_data(dbg, current_cu_die_for_print_frames); print_error(dbg, "dwarf_cu_header On Child read ", chres, nested_err); if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } return 0; } else if (chres == DW_DLV_NO_ENTRY) { if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, prev_child, DW_DLA_DIE); } return 0;/* proc name not at this level */ } else { /* DW_DLV_OK */ curdie = newsibling; if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, prev_child, DW_DLA_DIE); } prev_child = 0; die_locally_gotten = 1; } } if (die_locally_gotten) { /* If we got this die from the parent, we do not want to dealloc here! */ dwarf_dealloc(dbg, curdie, DW_DLA_DIE); } return 0; } /* For SGI MP Fortran and other languages, functions nest! As a result, we must dig thru all functions, not just the top level. This remembers the CU die and restarts each search at the start of the current cu. */ static char* get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc, const char *frame_section_name, void **pcMap, int *all_cus_seen) { static char proc_name[BUFSIZ]; Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_offset = 0; int cures = DW_DLV_OK; int dres = DW_DLV_OK; int chres = DW_DLV_OK; int looping = 0; Dwarf_Error pnerr = 0; proc_name[0] = 0; { struct Addr_Map_Entry *ame = 0; ame = addr_map_find(low_pc,pcMap); if (ame && ame->mp_name) { /* mp_name is only NULL here if we just ran out of heap memory! */ safe_strcpy(proc_name, sizeof(proc_name), ame->mp_name,(long) strlen(ame->mp_name)); return proc_name; } if (*all_cus_seen) { return ""; } } if (current_cu_die_for_print_frames == NULL) { /* Call depends on dbg->cu_context to know what to do. */ cures = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_offset, &pnerr); if (cures == DW_DLV_ERROR) { /* If there is a serious error in DIE information we just skip looking for a procedure name. Perhaps we should report something? */ return NULL; } else if (cures == DW_DLV_NO_ENTRY) { /* loop thru the list again */ current_cu_die_for_print_frames = 0; ++looping; } else { /* DW_DLV_OK */ dres = dwarf_siblingof(dbg, NULL, ¤t_cu_die_for_print_frames, &pnerr); if (dres == DW_DLV_ERROR) { /* If there is a serious error in DIE information we just skip looking for a procedure name. Perhaps we should report something? */ return NULL; } } } if (dres == DW_DLV_OK) { Dwarf_Die child = 0; if (current_cu_die_for_print_frames == 0) { /* no information. Possibly a stripped file */ return NULL; } chres = dwarf_child(current_cu_die_for_print_frames, &child, &pnerr); if (chres == DW_DLV_ERROR) { print_error(dbg, "dwarf_cu_header on child read ", chres, pnerr); } else if (chres == DW_DLV_NO_ENTRY) { } else { /* DW_DLV_OK */ int gotname = load_nested_proc_name(dbg, child, low_pc, proc_name, BUFSIZ,pcMap); dwarf_dealloc(dbg, child, DW_DLA_DIE); if (gotname) { return (proc_name); } child = 0; } } for (;;) { Dwarf_Die ldie = 0; cures = dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_offset, &pnerr); if (cures != DW_DLV_OK) { *all_cus_seen = 1; break; } dres = dwarf_siblingof(dbg, NULL, &ldie, &pnerr); if (current_cu_die_for_print_frames) { dwarf_dealloc(dbg, current_cu_die_for_print_frames, DW_DLA_DIE); } current_cu_die_for_print_frames = 0; if (dres == DW_DLV_ERROR) { struct esb_s msg; char local_buf[300]; esb_constructor_fixed(&msg,local_buf,sizeof(local_buf)); esb_append(&msg, "dwarf_cu_header Child Read finding proc name for %s"); esb_append(&msg,sanitized(frame_section_name)); print_error(dbg, esb_get_string(&msg), chres, pnerr); esb_destructor(&msg); continue; } else if (dres == DW_DLV_NO_ENTRY) { ++looping; if (looping > 1) { print_error(dbg, "looping on cu headers!", dres, pnerr); return NULL; } continue; } /* DW_DLV_OK In normal processing (ie, when doing print_info() we would call print_attribute for each die including cu_die and thus get CU_base_address, CU_high_address, PU_base_address, PU_high_address, CU_name for PRINT_CU_INFO() in case of error. */ current_cu_die_for_print_frames = ldie; { int chpfres = 0; Dwarf_Die child = 0; chpfres = dwarf_child(current_cu_die_for_print_frames, &child, &pnerr); if (chpfres == DW_DLV_ERROR) { load_CU_error_data(dbg,current_cu_die_for_print_frames); print_error(dbg, "dwarf Child Read ", chpfres, pnerr); } else if (chpfres == DW_DLV_NO_ENTRY) { ;/* do nothing, loop on cu */ } else { /* DW_DLV_OK) */ int gotname = load_nested_proc_name(dbg, child, low_pc, proc_name, BUFSIZ,pcMap); dwarf_dealloc(dbg, child, DW_DLA_DIE); if (gotname) { return (proc_name); } } } reset_overall_CU_error_data(); } return (NULL); } /* Attempting to take care of overflows so we only accept good as TRUE. */ static Dwarf_Bool valid_fde_content(Dwarf_Small * fde_start, Dwarf_Unsigned fde_length, Dwarf_Small * data_ptr, Dwarf_Unsigned data_ptr_length) { Dwarf_Small * fde_end = fde_start + fde_length; Dwarf_Small * data_end = 0; if (data_ptr < fde_start || data_ptr >= fde_end) { return FALSE; } data_end = data_ptr + data_ptr_length; if ( data_end < fde_start || data_end < data_ptr) { return FALSE; } if ( data_end >= fde_end) { return FALSE; } return TRUE; } /* Gather the fde print logic here so the control logic determining what FDE to print is clearer. */ static int print_one_fde(Dwarf_Debug dbg, const char *frame_section_name, Dwarf_Fde fde, Dwarf_Unsigned fde_index, Dwarf_Cie * cie_data, Dwarf_Signed cie_element_count, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Half version, int is_eh, struct dwconf_s *config_data, void ** pcMap, void ** lowpcSet, int * all_cus_seen) { Dwarf_Addr j = 0; Dwarf_Addr low_pc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Addr end_func_addr = 0; Dwarf_Ptr fde_bytes = NULL; Dwarf_Unsigned fde_bytes_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; Dwarf_Signed eh_table_offset = 0; int fres = 0; int offres = 0; struct esb_s temps; Dwarf_Error oneferr = 0; int printed_intro_addr = 0; char local_buf[100]; char temps_buf[200]; fres = dwarf_get_fde_range(fde, &low_pc, &func_length, &fde_bytes, &fde_bytes_length, &cie_offset, &cie_index, &fde_offset, &oneferr); if (fres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_fde_range", fres, oneferr); } if (fres == DW_DLV_NO_ENTRY) { return DW_DLV_NO_ENTRY; } if (glflags.gf_cu_name_flag && glflags.fde_offset_for_cu_low != DW_DLV_BADOFFSET && (fde_offset < glflags.fde_offset_for_cu_low || fde_offset > glflags.fde_offset_for_cu_high)) { return DW_DLV_NO_ENTRY; } /* eh_table_offset is IRIX ONLY. */ fres = dwarf_get_fde_exception_info(fde, &eh_table_offset, &oneferr); if (fres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_fde_exception_info", fres, oneferr); } esb_constructor_fixed(&temps,temps_buf,sizeof(temps_buf)); if (glflags.gf_suppress_nested_name_search) { /* do nothing. */ } else { struct Addr_Map_Entry *mp = 0; mp = addr_map_find(low_pc,lowpcSet); if (glflags.gf_check_frames || glflags.gf_check_frames_extended) { DWARF_CHECK_COUNT(fde_duplication,1); } { char *sptr = 0; sptr = get_fde_proc_name(dbg, low_pc, frame_section_name,pcMap,all_cus_seen); if (sptr) { esb_append(&temps,sanitized(sptr)); } } if (mp) { if (glflags.gf_check_frames || glflags.gf_check_frames_extended) { struct esb_s msg; esb_constructor_fixed(&msg, local_buf,sizeof(local_buf)); if (esb_string_len(&temps) > 0) { esb_append_printf(&msg, "An fde low pc of 0x%" DW_PR_DUx " is not the first fde with that pc. " "The first is named \"%s\"", (Dwarf_Unsigned)low_pc, esb_get_string(&temps)); } else { esb_append_printf(&msg, "An fde low pc of 0x%" DW_PR_DUx " is not the first fde with that pc. " "The first is not named.", (Dwarf_Unsigned)low_pc); } DWARF_CHECK_ERROR(fde_duplication,esb_get_string(&msg)); esb_destructor(&msg); } } else { addr_map_insert(low_pc,0,lowpcSet); } } /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { /* Printing the FDE header. */ printf("<%5" DW_PR_DSd ">" "<0x%" DW_PR_XZEROS DW_PR_DUx ":0x%" DW_PR_XZEROS DW_PR_DUx "><%s>" "" "", fde_index, (Dwarf_Unsigned)low_pc, (Dwarf_Unsigned)(low_pc + func_length), esb_get_string(&temps), (Dwarf_Unsigned)cie_offset, (Dwarf_Unsigned)cie_index, (Dwarf_Unsigned)fde_offset, fde_bytes_length); } esb_destructor(&temps); if (!is_eh) { /* IRIX uses eh_table_offset. No one else uses it. */ /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { if (eh_table_offset == DW_DLX_NO_EH_OFFSET) { printf("\n", "none"); } else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) { printf("\n", "unknown"); } else { printf("\n", eh_table_offset); } } } else { /* Printing the .eh_frame header augmentation string, if any. */ int ares = 0; Dwarf_Small *data = 0; Dwarf_Unsigned len = 0; ares = dwarf_get_fde_augmentation_data(fde, &data, &len, &oneferr); if (ares == DW_DLV_NO_ENTRY) { /* do nothing. */ } else if (ares == DW_DLV_OK) { if (glflags.gf_do_print_dwarf) { printf("\n "); } } else { print_error(dbg, "dwarf_get_fde_augmentation_data", ares, oneferr); } /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf("\n"); } } end_func_addr = low_pc + func_length; for (j = low_pc; j < end_func_addr; j++) { Dwarf_Half k = 0; Dwarf_Addr cur_pc_in_table = 0; cur_pc_in_table = j; if (config_data->cf_interface_number == 3) { Dwarf_Signed reg = 0; Dwarf_Signed offset_relevant = 0; Dwarf_Small value_type = 0; Dwarf_Signed offset_or_block_len = 0; Dwarf_Signed offset = 0; Dwarf_Ptr block_ptr = 0; Dwarf_Addr row_pc = 0; Dwarf_Bool has_more_rows = 0; Dwarf_Addr subsequent_pc = 0; int fires = dwarf_get_fde_info_for_cfa_reg3_b(fde, j, &value_type, &offset_relevant, ®, &offset_or_block_len, &block_ptr, &row_pc, &has_more_rows, &subsequent_pc, &oneferr); offset = offset_or_block_len; if (fires == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_fde_info_for_cfa_reg3", fires, oneferr); } if (fires == DW_DLV_NO_ENTRY) { continue; } if (!has_more_rows) { j = low_pc+func_length-1; } else { if (subsequent_pc > j) { /* Loop head will increment j to make up for -1 here. */ j = subsequent_pc -1; } } /* Do not print if in check mode */ if (!printed_intro_addr && glflags.gf_do_print_dwarf) { printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ": ", (Dwarf_Unsigned)cur_pc_in_table); printed_intro_addr = 1; } print_one_frame_reg_col(dbg, config_data->cf_cfa_reg, value_type, reg, address_size, offset_size,version, config_data, offset_relevant, offset, block_ptr); } for (k = 0; k < config_data->cf_table_entry_count; k++) { Dwarf_Signed reg = 0; Dwarf_Signed offset_relevant = 0; int fires = 0; Dwarf_Small value_type = 0; Dwarf_Ptr block_ptr = 0; Dwarf_Signed offset_or_block_len = 0; Dwarf_Signed offset = 0; Dwarf_Addr row_pc = 0; if (config_data->cf_interface_number == 3) { fires = dwarf_get_fde_info_for_reg3(fde, k, cur_pc_in_table, &value_type, &offset_relevant, ®, &offset_or_block_len, &block_ptr, &row_pc, &oneferr); offset = offset_or_block_len; } else { /* This interface is deprecated. Is the old MIPS/DWARF2 interface. */ /* ASSERT: config_data->cf_interface_number == 2 */ value_type = DW_EXPR_OFFSET; fires = dwarf_get_fde_info_for_reg(fde, k, cur_pc_in_table, &offset_relevant, ®, &offset, &row_pc, &oneferr); } if (fires == DW_DLV_ERROR) { printf("\n"); print_error(dbg, "dwarf_get_fde_info_for_reg (or reg3)", fires, oneferr); } if (fires == DW_DLV_NO_ENTRY) { continue; } if (row_pc != cur_pc_in_table) { /* row_pc < cur_pc_in_table means this pc has no new register value, the last one found still applies hence this is a duplicate row. row_pc > j cannot happen, the libdwarf function will not return such. */ continue; } /* Do not print if in check mode */ if (!printed_intro_addr && glflags.gf_do_print_dwarf) { printf(" 0x%" DW_PR_XZEROS DW_PR_DUx ": ", (Dwarf_Unsigned)j); printed_intro_addr = 1; } print_one_frame_reg_col(dbg,k, value_type, reg, address_size, offset_size,version, config_data, offset_relevant, offset, block_ptr); } if (printed_intro_addr) { printf("\n"); printed_intro_addr = 0; } } if (glflags.verbose > 1) { Dwarf_Off fde_off = 0; Dwarf_Off cie_off = 0; /* Get the fde instructions and print them in raw form, just like cie instructions */ Dwarf_Ptr instrs = 0; Dwarf_Unsigned ilen = 0; int res = 0; res = dwarf_get_fde_instr_bytes(fde, &instrs, &ilen, &oneferr); /* res will be checked below. */ offres = dwarf_fde_section_offset(dbg, fde, &fde_off, &cie_off, &oneferr); if (offres == DW_DLV_OK) { /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf(" fde section offset %" DW_PR_DUu " 0x%" DW_PR_XZEROS DW_PR_DUx " cie offset for fde: %" DW_PR_DUu " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned) fde_off, (Dwarf_Unsigned) fde_off, (Dwarf_Unsigned) cie_off, (Dwarf_Unsigned) cie_off); } } if (res == DW_DLV_OK) { int cires = 0; Dwarf_Unsigned cie_length = 0; Dwarf_Small cie_version = 0; char* augmenter = 0; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr initial_instructions = 0; Dwarf_Unsigned initial_instructions_length = 0; Dwarf_Half cie_offset_size = 0; if (cie_index >= cie_element_count) { printf("Bad cie index %" DW_PR_DSd " with fde index %" DW_PR_DUu "! " "(table entry max %" DW_PR_DSd ")\n", cie_index, fde_index, cie_element_count); exit(1); } cires = dwarf_get_offset_size(dbg,&cie_offset_size,&oneferr); if( cires != DW_DLV_OK) { return res; } cires = dwarf_get_cie_info_b(cie_data[cie_index], &cie_length, &cie_version, &augmenter, &code_alignment_factor, &data_alignment_factor, &return_address_register_rule, &initial_instructions, &initial_instructions_length, &cie_offset_size, &oneferr); if (cires == DW_DLV_ERROR) { printf ("Bad cie index %" DW_PR_DSd " with fde index %" DW_PR_DUu "!\n", cie_index, fde_index); print_error(dbg, "dwarf_get_cie_info", cires, oneferr); } if (cires == DW_DLV_NO_ENTRY) { ; /* ? */ } else { /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { print_frame_inst_bytes(dbg, instrs, (Dwarf_Signed) ilen, data_alignment_factor, (int) code_alignment_factor, address_size, cie_offset_size, cie_version, config_data); } } } else if (res == DW_DLV_NO_ENTRY) { printf("Impossible: no instr bytes for fde index %" DW_PR_DUu "?\n", fde_index); } else { /* DW_DLV_ERROR */ printf("Error: on gettinginstr bytes for fde index %" DW_PR_DUu "?\n", fde_index); print_error(dbg, "dwarf_get_fde_instr_bytes", res, oneferr); } } return DW_DLV_OK; } /* Print a cie. Gather the print logic here so the control logic deciding what to print is clearer. */ int print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie, Dwarf_Unsigned cie_index, Dwarf_Half address_size, struct dwconf_s *config_data) { int cires = 0; Dwarf_Unsigned cie_length = 0; Dwarf_Small version = 0; char* augmenter = ""; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr initial_instructions = 0; Dwarf_Unsigned initial_instructions_length = 0; Dwarf_Off cie_off = 0; Dwarf_Error onecie_err = 0; Dwarf_Half offset_size = 0; cires = dwarf_get_offset_size(dbg,&offset_size,&onecie_err); if( cires != DW_DLV_OK) { return cires; } cires = dwarf_get_cie_info(cie, &cie_length, &version, &augmenter, &code_alignment_factor, &data_alignment_factor, &return_address_register_rule, &initial_instructions, &initial_instructions_length, &onecie_err); if (cires == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_cie_info", cires, onecie_err); } if (cires == DW_DLV_NO_ENTRY) { printf("Impossible DW_DLV_NO_ENTRY on cie %" DW_PR_DUu "\n", cie_index); return DW_DLV_NO_ENTRY; } { if (glflags.gf_do_print_dwarf) { printf("<%5" DW_PR_DUu ">\tversion\t\t\t\t%d\n", cie_index, version); cires = dwarf_cie_section_offset(dbg, cie, &cie_off, &onecie_err); if (cires == DW_DLV_OK) { printf("\tcie section offset\t\t%" DW_PR_DUu " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned) cie_off, (Dwarf_Unsigned) cie_off); } /* This augmentation is from .debug_frame or eh_frame of a cie. . A string. */ printf("\taugmentation\t\t\t%s\n", sanitized(augmenter)); printf("\tcode_alignment_factor\t\t%" DW_PR_DUu "\n", code_alignment_factor); printf("\tdata_alignment_factor\t\t%" DW_PR_DSd "\n", data_alignment_factor); printf("\treturn_address_register\t\t%d\n", return_address_register_rule); } { int ares = 0; Dwarf_Small *data = 0; Dwarf_Unsigned len = 0; /* This call only returns DW_DLV_OK if the augmentation is cie aug from .eh_frame. The return is DW_DLV_OK only if there is eh_frame style augmentation bytes (its not a string). */ ares = dwarf_get_cie_augmentation_data(cie, &data, &len, &onecie_err); if (ares == DW_DLV_NO_ENTRY) { /* No Aug data (len zero) do nothing. */ } else if (ares == DW_DLV_OK) { /* We have the gnu eh_frame aug data bytes. */ if (glflags.gf_do_print_dwarf) { unsigned k2 = 0; printf("\teh aug data len 0x%" DW_PR_DUx , len); for (k2 = 0; data && k2 < len; ++k2) { if (k2 == 0) { printf(" bytes 0x"); } printf("%02x ", (unsigned char) data[k2]); } printf("\n"); } } /* else DW_DLV_ERROR or no data, do nothing */ } /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf("\tbytes of initial instructions\t%" DW_PR_DUu "\n", initial_instructions_length); printf("\tcie length\t\t\t%" DW_PR_DUu "\n", cie_length); /* For better layout */ printf("\tinitial instructions\n"); print_frame_inst_bytes(dbg, initial_instructions, (Dwarf_Signed) initial_instructions_length, data_alignment_factor, (int) code_alignment_factor, address_size, offset_size,version,config_data); } } return DW_DLV_OK; } void get_string_from_locs(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned block_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct esb_s *out_string) { Dwarf_Locdesc *locdescarray = 0; Dwarf_Signed listlen = 0; Dwarf_Unsigned ulistlen = 0; Dwarf_Error err2 =0; int res2 = 0; Dwarf_Addr baseaddr = 0; /* Really unknown */ if(!glflags.gf_use_old_dwarf_loclist) { Dwarf_Loc_Head_c head = 0; Dwarf_Locdesc_c locentry = 0; int lres = 0; Dwarf_Unsigned lopc = 0; Dwarf_Unsigned hipc = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Unsigned section_offset = 0; Dwarf_Unsigned locdesc_offset = 0; Dwarf_Small lle_value = 0; Dwarf_Small loclist_source = 0; res2 = dwarf_loclist_from_expr_c(dbg, bytes_in,block_len, addr_size, offset_size, version, &head, &ulistlen, &err2); if(res2 == DW_DLV_NO_ENTRY) { return; } if(res2 == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_loclist_from_expr_c", res2, err2); } lres = dwarf_get_locdesc_entry_c(head, 0, /* Data from 0th LocDesc */ &lle_value, &lopc, &hipc, &ulocentry_count, &locentry, &loclist_source, §ion_offset, &locdesc_offset, &err2); if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_locdesc_entry_c", lres, err2); } else if (lres == DW_DLV_NO_ENTRY) { return; } dwarfdump_print_one_locdesc(dbg, NULL, locentry, 0, /* index 0: locdesc 0 */ ulocentry_count, baseaddr, out_string); dwarf_loc_head_c_dealloc(head); return; } res2 =dwarf_loclist_from_expr_a(dbg, bytes_in,block_len, addr_size, &locdescarray, &listlen,&err2); if (res2 == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_loclist_from_expr_a", res2, err2); } if (res2==DW_DLV_NO_ENTRY) { return; } /* listlen is always 1 */ ulistlen = listlen; dwarfdump_print_one_locdesc(dbg, locdescarray, NULL, 0, ulistlen, baseaddr, out_string); dwarf_dealloc(dbg, locdescarray->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, locdescarray, DW_DLA_LOCDESC); return ; } /* DW_CFA_nop may be omitted for alignment, so we do not flag that one. */ static int lastop_pointless(int op) { if (op == DW_CFA_remember_state || op == DW_CFA_MIPS_advance_loc8 || op == DW_CFA_advance_loc || op == DW_CFA_advance_loc4 || op == DW_CFA_advance_loc2 || op == DW_CFA_advance_loc1 || op == DW_CFA_set_loc) { return true; } /* The last op is hopefully useful. */ return false; } /* iregion_start, iregion_end are the overall block of fde/cie instructions. idata, idata end are the area next to be read and they must lie within the iregion* range. The end address is one past the last byte. We are decoding here, libdwarf has not decoded these bytes, so it is up to us to check for corrupt data in the frame section. */ static int check_finstr_addrs(unsigned char *iregionstart, unsigned char *idata, unsigned char *idata_end, unsigned char *iregionend, const char *msg) { if ( idata > idata_end) { /* zero length allowed. But maybe overflow happened. */ printf("ERROR: frame instruction internal error reading %s\n", msg); return DW_DLV_ERROR; } if (idata < iregionstart) { printf("ERROR: frame instruction overflow(?) reading" " %s\n", msg); return DW_DLV_ERROR; } if (idata_end > iregionend) { Dwarf_Unsigned bytes_in = 0; bytes_in = idata - iregionstart; printf("ERROR: frame instruction reads off end" " %" DW_PR_DUu " bytes into instructions for %s\n", bytes_in,msg); return DW_DLV_ERROR; } return DW_DLV_OK; } /* Print the frame instructions in detail for a glob of instructions. The frame data has not been checked by libdwarf as libdwarf has not transformed it into simple structs. We are reading the raw data. */ /*ARGSUSED*/ static void print_frame_inst_bytes(Dwarf_Debug dbg, Dwarf_Ptr cie_init_inst, Dwarf_Signed len_in, Dwarf_Signed data_alignment_factor, int code_alignment_factor, Dwarf_Half addr_size, Dwarf_Half offset_size,Dwarf_Half version, struct dwconf_s *config_data) { unsigned char *instp = (unsigned char *) cie_init_inst; unsigned char *startpoint = instp; Dwarf_Unsigned uval = 0; Dwarf_Unsigned uval2 = 0; unsigned int uleblen = 0; unsigned int off = 0; unsigned int loff = 0; unsigned u16 = 0; unsigned int u32 = 0; Dwarf_Unsigned u64 = 0; int res = 0; Dwarf_Small *endpoint = 0; Dwarf_Signed len = 0; int lastop = 0; char exprstr_buf[200]; void (*copy_word) (void *, const void *, unsigned long) = 0; copy_word = dwarf_get_endian_copy_function(dbg); if (!copy_word) { printf("ERROR: Unable to print frame instruction bytes. " "Missing the word-copy function\n"); return; } if (len_in <= 0) { return; } len = len_in; endpoint = instp + len; for (; len > 0;) { unsigned char ibyte = 0; int top = 0; int bottom = 0; int delta = 0; int reg = 0; if (check_finstr_addrs(startpoint,instp,instp+1,endpoint, "start next instruction") != DW_DLV_OK) { return; } ibyte = *instp; top = ibyte & 0xc0; bottom = ibyte & 0x3f; lastop = top; switch (top) { case DW_CFA_advance_loc: delta = ibyte & 0x3f; printf("\t%2u DW_CFA_advance_loc %d", off, (int) (delta * code_alignment_factor)); if (glflags.verbose) { printf(" (%d * %d)", (int) delta, (int) code_alignment_factor); } printf("\n"); break; case DW_CFA_offset: loff = off; reg = ibyte & 0x3f; res = local_dwarf_decode_u_leb128_chk(instp + 1,&uleblen, &uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_offset\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_offset ", loff); printreg(reg, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) (((Dwarf_Signed) uval) * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DUu " * %" DW_PR_DSd ")", uval, data_alignment_factor); } printf("\n"); break; case DW_CFA_restore: reg = ibyte & 0x3f; printf("\t%2u DW_CFA_restore ", off); printreg(reg, config_data); printf("\n"); break; default: loff = off; lastop = top; switch (bottom) { case DW_CFA_set_loc: /* operand is address, so need address size */ /* which will be 4 or 8. */ if (check_finstr_addrs(startpoint, instp+1, instp+addr_size+1, endpoint, "DW_CFA_set_loc") != DW_DLV_OK) { return; } switch (addr_size) { case 4: { Dwarf_Unsigned v32 = 0; char b32[4]; memcpy(b32,instp+1,4); ASNAR(copy_word,v32, b32); uval = v32; } break; case 8: { Dwarf_Unsigned v64 = 0; char b64[8]; memcpy(b64,instp+1,8); ASNAR(copy_word,v64, b64); uval = v64; } break; default: printf ("Error: Unexpected address size %d in DW_CFA_set_loc!\n", addr_size); uval = 0; } instp += addr_size; len -= (Dwarf_Signed) addr_size; off += addr_size; printf("\t%2u DW_CFA_set_loc %" DW_PR_DUu "\n", loff, uval); break; case DW_CFA_advance_loc1: if (check_finstr_addrs(startpoint, instp+1, instp+2, endpoint, "DW_CFA_advance_loc1") != DW_DLV_OK) { return; } delta = (unsigned char) *(instp + 1); uval2 = delta; instp += 1; len -= 1; off += 1; printf("\t%2u DW_CFA_advance_loc1 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_advance_loc2: if (check_finstr_addrs(startpoint, instp+1, instp+3, endpoint, "DW_CFA_advance_loc2") != DW_DLV_OK) { return; } { char u2[2]; memcpy(u2,instp+1,2); ASNAR(copy_word,u16,u2); } uval2 = u16; instp += 2; len -= 2; off += 2; printf("\t%2u DW_CFA_advance_loc2 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_advance_loc4: if (check_finstr_addrs(startpoint, instp+1, instp+5, endpoint, "DW_CFA_advance_loc4") != DW_DLV_OK) { return; } { char u4[4]; memcpy(u4,instp+1,4); ASNAR(copy_word,u32,u4); } uval2 = u32; instp += 4; len -= 4; off += 4; printf("\t%2u DW_CFA_advance_loc4 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_MIPS_advance_loc8: if (check_finstr_addrs(startpoint, instp+1, instp+9, endpoint, "DW_CFA_MIPS_advance_loc8") != DW_DLV_OK) { return; } { char u8[8]; memcpy(u8,instp+1,8); ASNAR(copy_word,u64,u8); } uval2 = u64; instp += 8; len -= 8; off += 8; printf("\t%2u DW_CFA_MIPS_advance_loc8 %" DW_PR_DUu "\n", loff, uval2); break; case DW_CFA_offset_extended: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_offset_extended\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval2,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_offset_extended\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_offset_extended ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) (((Dwarf_Signed) uval2) * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DUu " * %d)", uval2, (int) data_alignment_factor); } printf("\n"); break; case DW_CFA_restore_extended: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_restore_extended\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_restore_extended ", loff); printreg(uval, config_data); printf("\n"); break; case DW_CFA_undefined: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_undefined\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_undefined ", loff); printreg( uval, config_data); printf("\n"); break; case DW_CFA_same_value: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_undefined\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_same_value ", loff); printreg(uval, config_data); printf("\n"); break; case DW_CFA_register: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_register\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval2,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_register\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_register ", loff); printreg(uval, config_data); printf(" = "); printreg(uval2, config_data); printf("\n"); break; case DW_CFA_remember_state: printf("\t%2u DW_CFA_remember_state\n", loff); break; case DW_CFA_restore_state: printf("\t%2u DW_CFA_restore_state\n", loff); break; case DW_CFA_def_cfa: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen, &uval2, endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_def_cfa ", loff); printreg( uval, config_data); printf(" %" DW_PR_DUu , uval2); printf("\n"); break; case DW_CFA_def_cfa_register: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa_register\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_def_cfa_register ", loff); printreg(uval, config_data); printf("\n"); break; case DW_CFA_def_cfa_offset: res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa_offset\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_def_cfa_offset %" DW_PR_DUu "\n", loff, uval); break; case DW_CFA_nop: printf("\t%2u DW_CFA_nop\n", loff); break; case DW_CFA_def_cfa_expression: /* DWARF3 */ { Dwarf_Unsigned block_len = 0; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&block_len,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa_expression\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf ("\t%2u DW_CFA_def_cfa_expression expr block len %" DW_PR_DUu "\n", loff, block_len); if (len < 0 || block_len > (Dwarf_Unsigned)len) { printf("ERROR expression length too long in DW_CFA_def_cfa_expression.\n"); return; } if (check_finstr_addrs(startpoint, instp+1, instp+block_len+1, endpoint, "DW_CFA_def_cfa_expression") != DW_DLV_OK) { return; } dump_block("\t\t", (char *) instp+1, (Dwarf_Signed) block_len); printf("\n"); if (glflags.verbose) { struct esb_s exprstring; esb_constructor_fixed(&exprstring,exprstr_buf, sizeof(exprstr_buf)); get_string_from_locs(dbg, instp+1,block_len,addr_size, offset_size,version,&exprstring); printf("\t\t%s\n",esb_get_string(&exprstring)); esb_destructor(&exprstring); } instp += block_len; len -= block_len; off += block_len; } break; case DW_CFA_expression: /* DWARF3 */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_expression\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; { /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ Dwarf_Unsigned block_len = 0; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&block_len,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_expression\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf ("\t%2u DW_CFA_expression %" DW_PR_DUu " expr block len %" DW_PR_DUu "\n", loff, uval, block_len); if (len < 0 || block_len > (Dwarf_Unsigned)len) { printf("ERROR expression length too long in DW_CFA_expression\n"); return; } if (check_finstr_addrs(startpoint, instp+1, instp+block_len+1, endpoint, "DW_CFA_expression") != DW_DLV_OK) { return; } dump_block("\t\t", (char *) instp+1, (Dwarf_Signed) block_len); printf("\n"); if (glflags.verbose) { struct esb_s exprstring; esb_constructor_fixed(&exprstring, exprstr_buf, sizeof(exprstr_buf)); get_string_from_locs(dbg, instp+1,block_len,addr_size, offset_size,version,&exprstring); printf("\t\t%s\n",esb_get_string(&exprstring)); esb_destructor(&exprstring); } instp += block_len; len -= block_len; off += block_len; } break; case DW_CFA_offset_extended_sf: /* DWARF3 */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_offset_extended_sf\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_offset_extended_sf\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_offset_extended_sf ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) ((sval2) * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DSd " * %d)", sval2, (int) data_alignment_factor); } } printf("\n"); break; case DW_CFA_def_cfa_sf: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa_sf\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa_sf\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_def_cfa_sf ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , sval2); printf(" (*data alignment factor=>%" DW_PR_DSd ")", (Dwarf_Signed)(sval2*data_alignment_factor)); } printf("\n"); break; case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ { /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ Dwarf_Signed sval = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_def_cfa_sf\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_def_cfa_offset_sf %" DW_PR_DSd " (*data alignment factor=> %" DW_PR_DSd ")\n", loff, sval, (Dwarf_Signed)(data_alignment_factor*sval)); } break; case DW_CFA_val_offset: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_val_offset\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_val_offset\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_val_offset ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd , (Dwarf_Signed) (sval2 * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DSd " * %d)", (Dwarf_Signed) sval2, (int) data_alignment_factor); } } printf("\n"); break; case DW_CFA_val_offset_sf: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_val_offset_sf\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; { Dwarf_Signed sval2 = 0; res = local_dwarf_decode_s_leb128_chk(instp + 1, &uleblen, &sval2,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_val_offset\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf("\t%2u DW_CFA_val_offset_sf ", loff); printreg(uval, config_data); printf(" %" DW_PR_DSd ,(Dwarf_Signed) (sval2 * data_alignment_factor)); if (glflags.verbose) { printf(" (%" DW_PR_DSd " * %d)", sval2, (int) data_alignment_factor); } } printf("\n"); break; case DW_CFA_val_expression: /* DWARF3 */ /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&uval,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_val_expression\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; { Dwarf_Unsigned block_len = 0; res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&block_len,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_val_expression\n"); return; } instp += uleblen; len -= uleblen; off += uleblen; printf ("\t%2u DW_CFA_val_expression %" DW_PR_DUu " expr block len %" DW_PR_DUu "\n", loff, uval, block_len); if (len < 0 || block_len > (Dwarf_Unsigned)len) { printf("ERROR expression length too long in DW_CFA_val_expression.\n"); return; } if (check_finstr_addrs(startpoint, instp+1, instp+block_len+1, endpoint, "DW_CFA_val_expression") != DW_DLV_OK) { return; } dump_block("\t\t", (char *) instp+1, (Dwarf_Signed) block_len); printf("\n"); if (glflags.verbose) { struct esb_s exprstring; esb_constructor_fixed(&exprstring, exprstr_buf, sizeof(exprstr_buf)); get_string_from_locs(dbg, instp+1,block_len,addr_size, offset_size,version,&exprstring); printf("\t\t%s\n",esb_get_string(&exprstring)); esb_destructor(&exprstring); } instp += block_len; len -= block_len; off += block_len; } break; /* Only in Metaware. Unknown meaning. */ case DW_CFA_METAWARE_info: { Dwarf_Unsigned val = 0; /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&val,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_METAWARE_info\n"); return; } printf("\t%2u DW_CFA_METAWARE_info value: %" DW_PR_DUu "\n", loff, val); instp += uleblen; len -= uleblen; off += uleblen; } break; #ifdef DW_CFA_GNU_window_save case DW_CFA_GNU_window_save:{ /* no information: this just tells unwinder to restore the window registers from the previous frame's window save area */ printf("\t%2u DW_CFA_GNU_window_save \n", loff); } break; #endif #ifdef DW_CFA_GNU_negative_offset_extended case DW_CFA_GNU_negative_offset_extended:{ printf("\t%2u DW_CFA_GNU_negative_offset_extended \n", loff); } break; #endif #ifdef DW_CFA_GNU_args_size /* single uleb128 is the current arg area size in bytes. no register exists yet to save this in */ case DW_CFA_GNU_args_size:{ Dwarf_Unsigned lreg = 0; /* instp is always 1 byte back, so we need +1 when we use it. See the final increment of this for loop. */ res = local_dwarf_decode_u_leb128_chk(instp + 1, &uleblen,&lreg,endpoint); if (res != DW_DLV_OK) { printf("ERROR reading leb in DW_CFA_GNU_args_size\n"); return; } printf("\t%2u DW_CFA_GNU_args_size arg size: %" DW_PR_DUu "\n", loff, lreg); instp += uleblen; len -= uleblen; off += uleblen; } break; #endif default: printf(" %u Unexpected op 0x%x: \n", loff, (unsigned int) bottom); len = 0; break; } } instp++; len--; off++; if ( len < 0) { printf("ERROR reading frame instructions, " "remaining length negative: %" DW_PR_DSd "\n",len); return; } } if (lastop_pointless(lastop)) { printf( " Warning: Final FDE operator is useless but not an error. %s\n", get_CFA_name(lastop,true)); } } /* Print our register names for the cases we have a name. Delegate to the configure code to actually do the print. */ void printreg(Dwarf_Unsigned reg, struct dwconf_s *config_data) { print_reg_from_config_data(reg, config_data); } /* Actually does the printing of a rule in the table. This may print something or may print nothing! */ static void print_one_frame_reg_col(Dwarf_Debug dbg, Dwarf_Unsigned rule_id, Dwarf_Small value_type, Dwarf_Unsigned reg_used, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct dwconf_s *config_data, Dwarf_Signed offset_relevant, Dwarf_Signed offset, Dwarf_Ptr block_ptr) { char *type_title = ""; int print_type_title = 1; if (reg_used == config_data->cf_initial_rule_value && (value_type == DW_EXPR_OFFSET || value_type == DW_EXPR_VAL_OFFSET) ) { /* This is really an empty column. Nothing to do. Would be great if we could tell the caller the *next* column used here or something. */ return; } if (!glflags.gf_do_print_dwarf) { return; } if (config_data->cf_interface_number == 2) print_type_title = 0; switch (value_type) { case DW_EXPR_OFFSET: type_title = "off"; goto preg2; case DW_EXPR_VAL_OFFSET: type_title = "valoff"; preg2: if (print_type_title) printf("<%s ", type_title); printreg(rule_id, config_data); printf("="); if (offset_relevant == 0) { printreg(reg_used, config_data); printf(" "); } else { printf("%02" DW_PR_DSd , offset); printf("("); printreg(reg_used, config_data); printf(") "); } if (print_type_title) printf("%s", "> "); break; case DW_EXPR_EXPRESSION: type_title = "expr"; goto pexp2; case DW_EXPR_VAL_EXPRESSION: type_title = "valexpr"; pexp2: if (print_type_title) printf("<%s ", type_title); printreg(rule_id, config_data); printf("="); printf("expr-block-len=%" DW_PR_DSd , offset); if (print_type_title) printf("%s", "> "); if (glflags.verbose) { char pref[40]; size_t len = 0; safe_strcpy(pref,sizeof(pref), "<",1); len = 1; safe_strcpy(pref+len,sizeof(pref)-len, type_title,strlen(type_title)); len = strlen(pref); safe_strcpy(pref+len,sizeof(pref)-len, "bytes:",6); /* The data being dumped comes direct from libdwarf so libdwarf validated it. */ dump_block(pref, block_ptr, offset); printf("%s", "> "); if (glflags.verbose) { struct esb_s exprstring; char local_buf[300]; esb_constructor_fixed(&exprstring,local_buf, sizeof(local_buf)); get_string_from_locs(dbg, block_ptr,offset,addr_size, offset_size,version,&exprstring); printf("",esb_get_string(&exprstring)); esb_destructor(&exprstring); } } break; default: printf("Internal error in libdwarf, value type %d\n", value_type); exit(1); } return; } /* get all the data in .debug_frame (or .eh_frame). The '3' versions mean print using the dwarf3 new interfaces. The non-3 mean use the old interfaces. All combinations of requests are possible. */ extern void print_frames(Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame, struct dwconf_s *config_data) { Dwarf_Signed i; int fres = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; Dwarf_Half version = 0; int framed = 0; void * map_lowpc_to_name = 0; Dwarf_Error err = 0; glflags.current_section_id = DEBUG_FRAME; /* The address size here will not be right for all frames. Only in DWARF4 is there a real address size known in the frame data itself. If any DIE is known then a real address size can be gotten from dwarf_get_die_address_size(). */ fres = dwarf_get_address_size(dbg, &address_size, &err); if (fres != DW_DLV_OK) { print_error(dbg, "dwarf_get_address_size", fres, err); } for (framed = 0; framed < 2; ++framed) { Dwarf_Cie *cie_data = NULL; Dwarf_Signed cie_element_count = 0; Dwarf_Fde *fde_data = NULL; Dwarf_Signed fde_element_count = 0; int frame_count = 0; int cie_count = 0; int all_cus_seen = 0; void * lowpcSet = 0; const char *frame_section_name = 0; int silent_if_missing = 0; int is_eh = 0; if (framed == 0) { glflags.current_section_id = DEBUG_FRAME; if (!print_debug_frame) { continue; } fres = dwarf_get_frame_section_name(dbg, &frame_section_name,&err); if (fres != DW_DLV_OK || !frame_section_name || !strlen(frame_section_name)) { frame_section_name = ".debug_frame"; } /* Big question here is how to print all the info? Can print the logical matrix, but that is huge, though could skip lines that don't change. Either that, or print the instruction statement program that describes the changes. */ fres = dwarf_get_fde_list(dbg, &cie_data, &cie_element_count, &fde_data, &fde_element_count, &err); if (glflags.gf_check_harmless) { print_any_harmless_errors(dbg); } } else { glflags.current_section_id = DEBUG_FRAME_EH_GNU; if (!print_eh_frame) { continue; } is_eh = 1; /* This is gnu g++ exceptions in a .eh_frame section. Which is just like .debug_frame except that the empty, or 'special' CIE_id is 0, not -1 (to distinguish fde from cie). And the augmentation is "eh". As of egcs-1.1.2 anyway. A non-zero cie_id is in a fde and is the difference between the fde address and the beginning of the cie it belongs to. This makes sense as this is intended to be referenced at run time, and is part of the running image. For more on augmentation strings, see libdwarf/dwarf_frame.c. */ /* Big question here is how to print all the info? Can print the logical matrix, but that is huge, though could skip lines that don't change. Either that, or print the instruction statement program that describes the changes. */ silent_if_missing = 1; fres = dwarf_get_frame_section_name_eh_gnu(dbg, &frame_section_name,&err); if (fres != DW_DLV_OK || !frame_section_name || !strlen(frame_section_name)) { frame_section_name = ".eh_frame"; } fres = dwarf_get_fde_list_eh(dbg, &cie_data, &cie_element_count, &fde_data, &fde_element_count, &err); if (glflags.gf_check_harmless) { print_any_harmless_errors(dbg); } } /* Do not print any frame info if in check mode */ if (glflags.gf_check_frames) { addr_map_destroy(lowpcSet); lowpcSet = 0; continue; } if (fres == DW_DLV_ERROR) { printf("\n%s\n", frame_section_name); print_error(dbg, "dwarf_get_fde_list", fres, err); } else if (fres == DW_DLV_NO_ENTRY) { if (!silent_if_missing) { printf("\n%s\n", frame_section_name); } /* no frame information */ } else { /* DW_DLV_OK */ /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; const char *stdsecname = 0; if (framed == 0) { stdsecname=".debug_frame"; } else { stdsecname=".eh_frame"; } esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,stdsecname, &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); printf("\nfde:\n"); } for (i = 0; i < fde_element_count; i++) { print_one_fde(dbg, frame_section_name, fde_data[i], i, cie_data, cie_element_count, address_size, offset_size, version, is_eh, config_data, &map_lowpc_to_name, &lowpcSet, &all_cus_seen); ++frame_count; if (frame_count >= glflags.break_after_n_units) { break; } } /* Print the cie set. */ /* Do not print if in check mode */ if (glflags.gf_do_print_dwarf) { printf("\ncie:\n"); } for (i = 0; i < cie_element_count; i++) { print_one_cie(dbg, cie_data[i], i, address_size, config_data); ++cie_count; if (cie_count >= glflags.break_after_n_units) { break; } } dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count, fde_data, fde_element_count); } addr_map_destroy(lowpcSet); lowpcSet = 0; } if (current_cu_die_for_print_frames) { dwarf_dealloc(dbg, current_cu_die_for_print_frames, DW_DLA_DIE); current_cu_die_for_print_frames = 0; } addr_map_destroy(map_lowpc_to_name); map_lowpc_to_name = 0; } /* This attempts to provide some data for error messages when reading frame/eh-frame data. On failure just give up here and return. Other code will be reporting an error, in this function we do not report such. Setting these globals as much as possible: CU_name CU_producer DIE_CU_offset DIE_CU_overall_offset CU_base_address CU_high_address Using DW_AT_low_pc, DW_AT_high_pc,DW_AT_name DW_AT_producer. */ static void load_CU_error_data(Dwarf_Debug dbg,Dwarf_Die cu_die) { Dwarf_Signed atcnt = 0; Dwarf_Attribute *atlist = 0; Dwarf_Half tag = 0; char **srcfiles = 0; Dwarf_Signed srccnt = 0; int local_show_form_used = 0; int local_verbose = 0; int atres = 0; Dwarf_Signed i = 0; Dwarf_Signed k = 0; Dwarf_Error loadcuerr = 0; Dwarf_Off cu_die_goff = 0; if(!cu_die) { return; } atres = dwarf_attrlist(cu_die, &atlist, &atcnt, &loadcuerr); if (atres != DW_DLV_OK) { /* Something is seriously wrong if it is DW_DLV_ERROR. */ DROP_ERROR_INSTANCE(dbg,atres,loadcuerr); return; } atres = dwarf_tag(cu_die, &tag, &loadcuerr); if (atres != DW_DLV_OK) { for (k = 0; k < atcnt; k++) { dwarf_dealloc(dbg, atlist[k], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); /* Something is seriously wrong if it is DW_DLV_ERROR. */ DROP_ERROR_INSTANCE(dbg,atres,loadcuerr); return; } /* The offsets will be zero if it fails. Let it pass. */ atres = dwarf_die_offsets(cu_die,&glflags.DIE_overall_offset, &glflags.DIE_offset,&loadcuerr); cu_die_goff = glflags.DIE_overall_offset; DROP_ERROR_INSTANCE(dbg,atres,loadcuerr); glflags.DIE_CU_overall_offset = glflags.DIE_overall_offset; glflags.DIE_CU_offset = glflags.DIE_offset; for (i = 0; i < atcnt; i++) { Dwarf_Half attr = 0; int ares = 0; Dwarf_Attribute attrib = atlist[i]; ares = dwarf_whatattr(attrib, &attr, &loadcuerr); if (ares != DW_DLV_OK) { for (k = 0; k < atcnt; k++) { dwarf_dealloc(dbg, atlist[k], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); return; } /* For now we will not fully deal with the complexity of DW_AT_high_pc being an offset of low pc. */ switch(attr) { case DW_AT_low_pc: { ares = dwarf_formaddr(attrib, &glflags.CU_base_address, &loadcuerr); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); glflags.CU_low_address = glflags.CU_base_address; } break; case DW_AT_high_pc: { /* This is wrong for DWARF4 instances where the attribute is really an offset. It's also useless for CU DIEs that do not have the DW_AT_high_pc high so CU_high_address will be zero*/ ares = dwarf_formaddr(attrib, &glflags.CU_high_address, &loadcuerr); DROP_ERROR_INSTANCE(dbg,ares,loadcuerr); } break; case DW_AT_name: case DW_AT_producer: { const char *name = 0; struct esb_s namestr; esb_constructor(&namestr); get_attr_value(dbg, tag, cu_die, cu_die_goff,attrib, srcfiles, srccnt, &namestr, local_show_form_used,local_verbose); name = esb_get_string(&namestr); if(attr == DW_AT_name) { safe_strcpy(glflags.CU_name,sizeof(glflags.CU_name),name, strlen(name)); } else { safe_strcpy(glflags.CU_producer,sizeof(glflags.CU_producer), name,strlen(name)); } esb_destructor(&namestr); } break; default: /* do nothing */ break; } } for (k = 0; k < atcnt; k++) { dwarf_dealloc(dbg, atlist[k], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } dwarfutils-20200114/dwarfdump/print_frames.h000066400000000000000000000032451361531463500207770ustar00rootroot00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRINT_FRAMES_H #define PRINT_FRAMES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie, Dwarf_Unsigned cie_index, Dwarf_Half address_size, struct dwconf_s * config_data); void get_string_from_locs(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned block_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version, struct esb_s *out_string); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PRINT_FRAMES_H */ dwarfutils-20200114/dwarfdump/print_gdbindex.c000066400000000000000000000340421361531463500213000ustar00rootroot00000000000000/* Copyright 2014-2014 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" static int print_culist_array(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Unsigned *cu_list_len, Dwarf_Error * culist_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_culist_array(gdbindex, &list_len,culist_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_culist_array failed",res,*culist_err); return res; } printf(" CU list. array length: %" DW_PR_DUu " format: [entry#] cuoffset culength\n", list_len); for( i = 0; i < list_len; i++) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned culength = 0; res = dwarf_gdbindex_culist_entry(gdbindex,i, &cuoffset,&culength,culist_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_culist_entry failed",res,*culist_err); return res; } printf(" [%4" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", i, cuoffset, culength); } printf("\n"); *cu_list_len = list_len; return DW_DLV_OK; } static int print_types_culist_array(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Error * cular_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_types_culist_array(gdbindex, &list_len,cular_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_types_culist_array failed",res,*cular_err); return res; } printf(" TU list. array length: %" DW_PR_DUu " format: [entry#] cuoffset culength signature\n", list_len); for( i = 0; i < list_len; i++) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned culength = 0; Dwarf_Unsigned signature = 0; res = dwarf_gdbindex_types_culist_entry(gdbindex,i, &cuoffset,&culength, &signature, cular_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_culist_entry failed",res,*cular_err); return res; } printf(" [%4" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", i, cuoffset, culength, signature); } printf("\n"); return DW_DLV_OK; } static int print_addressarea(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Error * addra_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_addressarea(gdbindex, &list_len,addra_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_addressarea failed",res,*addra_err); return res; } printf(" Address table array length: %" DW_PR_DUu " format: [entry#] lowpc highpc cu-index\n", list_len); for( i = 0; i < list_len; i++) { Dwarf_Unsigned lowpc = 0; Dwarf_Unsigned highpc = 0; Dwarf_Unsigned cu_index = 0; res = dwarf_gdbindex_addressarea_entry(gdbindex,i, &lowpc,&highpc, &cu_index, addra_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_addressarea_entry failed",res,*addra_err); return res; } printf(" [%4" DW_PR_DUu "] 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %4" DW_PR_DUu "\n", i, lowpc, highpc, cu_index); } printf("\n"); return DW_DLV_OK; } const char *kind_list[] = { "unknown(0) ", "type(1) ", "var-enum(2) ", "function(3) ", "other-sym(4)", "reserved(5) ", "function(6) ", "reserved(7) ", }; static void get_kind_string(struct esb_s *out,unsigned k) { if (k <= 7) { esb_append(out,sanitized(kind_list[k])); return; } esb_append(out, "kind-erroneous"); } /* NOTE: Returns pointer to static local string. Use the returned pointer immediately or things will not work properly. */ static void get_cu_index_string(struct esb_s *out, Dwarf_Unsigned index, Dwarf_Unsigned culist_len) { Dwarf_Unsigned type_index = 0; if (index < culist_len) { esb_append_printf(out,"%4" DW_PR_DUu,index); return; } type_index = index-culist_len; esb_append_printf(out, "%4" DW_PR_DUu "(T%4" DW_PR_DUu ")", index,type_index); return; } static int print_symtab_entry(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Unsigned index, Dwarf_Unsigned symnameoffset, Dwarf_Unsigned cuvecoffset, Dwarf_Unsigned culist_len, Dwarf_Error *sym_err) { int res = 0; const char *name = 0; Dwarf_Unsigned cuvec_len = 0; Dwarf_Unsigned ii = 0; if (symnameoffset == 0 && cuvecoffset == 0) { if (glflags.verbose > 1) { printf(" [%4" DW_PR_DUu "] \"empty-hash-entry\"\n", index); } return DW_DLV_OK; } res = dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset,&name,sym_err); if(res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_string_by_offset failed",res,*sym_err); *sym_err = 0; return res; } res = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset,&cuvec_len,sym_err); if( res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_cuvector_length failed",res,*sym_err); return res; } if (glflags.verbose > 1) { printf(" [%4" DW_PR_DUu "]" "stroff 0x%" DW_PR_XZEROS DW_PR_DUx " cuvecoff 0x%" DW_PR_XZEROS DW_PR_DUx " cuveclen 0x%" DW_PR_XZEROS DW_PR_DUx "\n", index,symnameoffset,cuvecoffset,cuvec_len); } for(ii = 0; ii < cuvec_len; ++ii ) { Dwarf_Unsigned attributes = 0; Dwarf_Unsigned cu_index = 0; Dwarf_Unsigned reserved1 = 0; Dwarf_Unsigned symbol_kind = 0; Dwarf_Unsigned is_static = 0; struct esb_s tmp_cuindx; struct esb_s tmp_kind; res = dwarf_gdbindex_cuvector_inner_attributes( gdbindex,cuvecoffset,ii, &attributes,sym_err); if( res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_cuvector_inner_attributes failed",res,*sym_err); return res; } res = dwarf_gdbindex_cuvector_instance_expand_value(gdbindex, attributes, &cu_index,&reserved1,&symbol_kind, &is_static, sym_err); if( res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_cuvector_instance_expand_value failed",res,*sym_err); return res; } /* if cu_index is > the cu-count, then it refers to a tu_index of 'cu_index - cu-count' */ esb_constructor(&tmp_cuindx); esb_constructor(&tmp_kind); get_kind_string(&tmp_kind,symbol_kind), get_cu_index_string(&tmp_cuindx,cu_index,culist_len); if (cuvec_len == 1) { printf(" [%4" DW_PR_DUu "]" "%s" " [%s %s] \"%s\"\n", index, esb_get_string(&tmp_cuindx), is_static? "static ": "global ", esb_get_string(&tmp_kind), sanitized(name)); } else if (ii == 0) { printf(" [%4" DW_PR_DUu "] \"%s\"\n" , index, sanitized(name)); printf(" %s [%s %s]\n", esb_get_string(&tmp_cuindx), is_static? "static ": "global ", esb_get_string(&tmp_kind)); }else{ printf(" %s [%s %s]\n", esb_get_string(&tmp_cuindx), is_static? "static ": "global ", esb_get_string(&tmp_kind)); } esb_destructor(&tmp_cuindx); esb_destructor(&tmp_kind); if (glflags.verbose > 1) { printf(" [%4" DW_PR_DUu "]" "attr 0x%" DW_PR_XZEROS DW_PR_DUx " cuindx 0x%" DW_PR_XZEROS DW_PR_DUx " kind 0x%" DW_PR_XZEROS DW_PR_DUx " static 0x%" DW_PR_XZEROS DW_PR_DUx "\n", ii,attributes,cu_index,symbol_kind,is_static); } } return DW_DLV_OK; } static int print_symboltable(Dwarf_Debug dbg, Dwarf_Gdbindex gdbindex, Dwarf_Unsigned culist_len, Dwarf_Error * symt_err) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i; int res = dwarf_gdbindex_symboltable_array(gdbindex, &list_len,symt_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_symboltable failed",res,*symt_err); return res; } printf("\n Symbol table: length %" DW_PR_DUu " format: [entry#] symindex cuindex [type] \"name\" or \n", list_len); printf(" " " format: [entry#] \"name\" , list of cuindex [type]\n"); for( i = 0; i < list_len; i++) { Dwarf_Unsigned symnameoffset = 0; Dwarf_Unsigned cuvecoffset = 0; res = dwarf_gdbindex_symboltable_entry(gdbindex,i, &symnameoffset,&cuvecoffset, symt_err); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_gdbindex_symboltable_entry failed",res,*symt_err); return res; } res = print_symtab_entry(dbg,gdbindex,i,symnameoffset,cuvecoffset, culist_len,symt_err); if (res != DW_DLV_OK) { return res; } } printf("\n"); return DW_DLV_OK; } extern void print_gdb_index(Dwarf_Debug dbg) { Dwarf_Gdbindex gdbindex = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned cu_list_offset = 0; Dwarf_Unsigned types_cu_list_offset = 0; Dwarf_Unsigned address_area_offset = 0; Dwarf_Unsigned symbol_table_offset = 0; Dwarf_Unsigned constant_pool_offset = 0; Dwarf_Unsigned section_size = 0; Dwarf_Unsigned unused = 0; const char *section_name = 0; /* unused */ Dwarf_Error error = 0; Dwarf_Unsigned culist_len = 0; int res = 0; glflags.current_section_id = DEBUG_GDB_INDEX; res = dwarf_gdbindex_header(dbg, &gdbindex, &version, &cu_list_offset, &types_cu_list_offset, &address_area_offset, &symbol_table_offset, &constant_pool_offset, §ion_size, &unused, §ion_name, &error); if (!glflags.gf_do_print_dwarf) { return; } if(res == DW_DLV_NO_ENTRY) { /* Silently! The section is rare so lets say nothing. */ return; } if(res == DW_DLV_ERROR) { printf("\n%s\n",".gdb_index not readable, error."); return; } { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".gdb_index", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } printf(" Version : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", version); printf(" CU list offset : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", cu_list_offset); printf(" Address area offset : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", types_cu_list_offset); printf(" Symbol table offset : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", address_area_offset); printf(" Constant pool offset: " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", constant_pool_offset); printf(" section size : " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", section_size); res = print_culist_array(dbg,gdbindex,&culist_len,&error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,error, DW_DLA_ERROR); error = 0; } return; } res = print_types_culist_array(dbg,gdbindex,&error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,error, DW_DLA_ERROR); error = 0; } return; } res = print_addressarea(dbg,gdbindex,&error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,error, DW_DLA_ERROR); error = 0; } return; } res = print_symboltable(dbg,gdbindex,culist_len,&error); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,error, DW_DLA_ERROR); error = 0; } return; } } dwarfutils-20200114/dwarfdump/print_lines.c000066400000000000000000001063201361531463500206250ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2015-2015 Google, Inc. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "uri.h" #include #include #include "print_sections.h" /* Print line number information: [line] [address] new basic-block filename */ #define DW_LINE_VERSION5 5 static void print_source_intro(Dwarf_Debug dbg,Dwarf_Die cu_die) { int ores = 0; Dwarf_Off off = 0; Dwarf_Error src_err = 0; ores = dwarf_dieoffset(cu_die, &off, &src_err); if (ores == DW_DLV_OK) { int lres = 0; const char *sec_name = 0; lres = dwarf_get_die_section_name_b(cu_die, &sec_name,&src_err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_info"; } printf("Source lines (from CU-DIE at %s offset 0x%" DW_PR_XZEROS DW_PR_DUx "):\n", sec_name, (Dwarf_Unsigned) off); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg,src_err, DW_DLA_ERROR); src_err = 0; } } else { if (ores == DW_DLV_ERROR) { dwarf_dealloc(dbg,src_err, DW_DLA_ERROR); src_err = 0; } printf("Source lines (for the CU-DIE at unknown location):\n"); } } static void record_line_error(const char *where, Dwarf_Error line_err) { if (glflags.gf_check_lines && checking_this_compiler()) { struct esb_s tmp_buff; char buftmp[140]; esb_constructor_fixed(&tmp_buff,buftmp,sizeof(buftmp)); esb_append_printf_s(&tmp_buff, "Error getting line details calling %s", where); esb_append_printf_s(&tmp_buff, " dwarf error is %s", dwarf_errmsg(line_err)); DWARF_CHECK_ERROR(lines_result,esb_get_string(&tmp_buff)); esb_destructor(&tmp_buff); } } static void process_line_table(Dwarf_Debug dbg, const char *sec_name, Dwarf_Line *linebuf, Dwarf_Signed linecount, Dwarf_Bool is_logicals_table, Dwarf_Bool is_actuals_table) { char *padding = 0; Dwarf_Signed i = 0; Dwarf_Addr pc = 0; Dwarf_Unsigned lineno = 0; Dwarf_Unsigned logicalno = 0; Dwarf_Unsigned column = 0; Dwarf_Unsigned call_context = 0; char* subprog_name = 0; char* subprog_filename = 0; Dwarf_Unsigned subprog_line = 0; Dwarf_Error lt_err = 0; Dwarf_Bool newstatement = 0; Dwarf_Bool lineendsequence = 0; Dwarf_Bool new_basic_block = 0; int sres = 0; int ares = 0; int lires = 0; int cores = 0; char lastsrc_tmp[500]; struct esb_s lastsrc; Dwarf_Addr elf_max_address = 0; Dwarf_Bool SkipRecord = FALSE; esb_constructor_fixed(&lastsrc,lastsrc_tmp,sizeof(lastsrc_tmp)); glflags.current_section_id = DEBUG_LINE; /* line_flag is TRUE */ get_address_size_and_max(dbg,0,&elf_max_address,<_err); /* Padding for a nice layout */ padding = glflags.gf_line_print_pc ? " " : ""; if (glflags.gf_do_print_dwarf) { /* Check if print of address is needed. */ printf("\n"); if (is_logicals_table) { printf("Logicals Table:\n"); printf("%sNS new statement, PE prologue end, " "EB epilogue begin\n",padding); printf("%sDI=val discriminator value\n", padding); printf("%sCC=val context, SB=val subprogram\n", padding); } else if (is_actuals_table) { printf("Actuals Table:\n"); printf("%sBB new basic block, ET end of text sequence\n" "%sIS=val ISA number\n",padding,padding); } else { /* Standard DWARF line table. */ printf("%sNS new statement, BB new basic block, " "ET end of text sequence\n",padding); printf("%sPE prologue end, EB epilogue begin\n",padding); printf("%sIS=val ISA number, DI=val discriminator value\n", padding); } if (is_logicals_table || is_actuals_table) { printf("[ row] "); } if (glflags.gf_line_print_pc) { printf(" "); } if (is_logicals_table) { printf("[lno,col] NS PE EB DI= CC= SB= uri: \"filepath\"\n"); } else if (is_actuals_table) { printf("[logical] BB ET IS=\n"); } else { printf("[lno,col] NS BB ET PE EB IS= DI= uri: \"filepath\"\n"); } } for (i = 0; i < linecount; i++) { Dwarf_Line line = linebuf[i]; char* filename = 0; int nsres = 0; Dwarf_Bool found_line_error = FALSE; Dwarf_Bool has_is_addr_set = FALSE; char *where = NULL; if (glflags.gf_check_decl_file && checking_this_compiler()) { /* A line record with addr=0 was detected */ if (SkipRecord) { /* Skip records that do not have s_addr_set' */ ares = dwarf_line_is_addr_set(line, &has_is_addr_set, <_err); if (ares == DW_DLV_OK && has_is_addr_set) { SkipRecord = FALSE; } else { /* Keep ignoring records until we have one with 'is_addr_set' */ continue; } } } if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); } filename = ""; if (!is_actuals_table) { sres = dwarf_linesrc(line, &filename, <_err); if (sres == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_linesrc()"; record_line_error(where,lt_err); found_line_error = TRUE; } } pc = 0; ares = dwarf_lineaddr(line, &pc, <_err); if (ares == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineaddr()"; record_line_error(where,lt_err); found_line_error = TRUE; pc = 0; } if (ares == DW_DLV_NO_ENTRY) { pc = 0; } if (is_actuals_table) { lires = dwarf_linelogical(line, &logicalno, <_err); if (lires == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_linelogical()"; record_line_error(where,lt_err); found_line_error = TRUE; } if (lires == DW_DLV_NO_ENTRY) { logicalno = 0; } column = 0; } else { lires = dwarf_lineno(line, &lineno, <_err); if (lires == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineno()"; record_line_error(where,lt_err); found_line_error = TRUE; } if (lires == DW_DLV_NO_ENTRY) { lineno = 0; } cores = dwarf_lineoff_b(line, &column, <_err); if (cores == DW_DLV_ERROR) { /* Do not terminate processing */ where = "dwarf_lineoff()"; record_line_error(where,lt_err); found_line_error = TRUE; } if (cores == DW_DLV_NO_ENTRY) { /* Zero was always the correct default, meaning the left edge. DWARF2/3/4 spec sec 6.2.2 */ column = 0; } } /* Process any possible error condition, though we won't be at the first such error. */ if (glflags.gf_check_decl_file && checking_this_compiler()) { DWARF_CHECK_COUNT(decl_file_result,1); if (found_line_error) { DWARF_CHECK_ERROR2(decl_file_result,where,dwarf_errmsg(lt_err)); } else if (glflags.gf_do_check_dwarf) { /* Check the address lies with a valid [lowPC:highPC] in the .text section*/ if (IsValidInBucketGroup(glflags.pRangesInfo,pc)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol. The problem we have here is we have consumed the deug_info section and we are dealing just with the records from the .debug_line, so no PU_name is available and no high_pc. Traverse the linkonce table if try to match the pc value with one of those ranges. */ if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); } if (FindAddressInBucketGroup(glflags.pLinkonceInfo,pc)){ /* Valid values; do nothing */ } else { /* The SN Systems Linker generates line records with addr=0, when dealing with linkonce symbols and no stripping */ if (pc) { if (glflags.gf_check_lines && checking_this_compiler()) { char abuf[40]; struct esb_s atm; esb_constructor_fixed(&atm, abuf,sizeof(abuf)); esb_append_printf_s(&atm, "%s: Address", sanitized(sec_name)); esb_append_printf_u(&atm, " 0x%" DW_PR_XZEROS DW_PR_DUx " outside a valid .text range", pc); DWARF_CHECK_ERROR(lines_result, esb_get_string(&atm)); esb_destructor(&atm); } } else { SkipRecord = TRUE; } } } /* Check the last record for the .debug_line, the one created by DW_LNE_end_sequence, is the same as the high_pc address for the last known user program unit (PU). There is no real reason */ if ((i + 1 == linecount) && glflags.seen_PU_high_address && !is_logicals_table) { /* Ignore those PU that have been stripped by the linker; their low_pc values are set to -1 (snc linker only) */ /* It is perfectly sensible for a compiler to leave a few bytes of NOP or other stuff after the last instruction in a subprogram, for cache-alignment or other purposes, so a mismatch here is not necessarily an error. */ if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); if ((pc != glflags.PU_high_address) && (glflags.PU_base_address != elf_max_address)) { char addr_tmp[140]; #ifdef ORIGINAL_SPRINTF snprintf(addr_tmp,sizeof(addr_tmp), "%s: Address" " 0x%" DW_PR_XZEROS DW_PR_DUx " DW_LNE_end_sequence address does not" " exactly match" " high function addr: " " 0x%" DW_PR_XZEROS DW_PR_DUx, sec_name,pc,glflags.PU_high_address); DWARF_CHECK_ERROR(lines_result, addr_tmp); #else struct esb_s cm; esb_constructor_fixed(&cm,addr_tmp, sizeof(addr_tmp)); esb_append_printf_s(&cm, "%s: Address",sanitized(sec_name)); esb_append_printf_u(&cm, " 0x%" DW_PR_XZEROS DW_PR_DUx " DW_LNE_end_sequence address does not" " exactly match",pc); esb_append_printf_u(&cm, " high function addr: " " 0x%" DW_PR_XZEROS DW_PR_DUx, glflags.PU_high_address); DWARF_CHECK_ERROR(lines_result, esb_get_string(&cm)); esb_destructor(&cm); #endif } } } } } /* Display the error information */ if (found_line_error || glflags.gf_record_dwarf_error) { if (glflags.gf_check_verbose_mode && PRINTING_UNIQUE) { /* Print the record number for better error description */ printf("Record = %" DW_PR_DUu " Addr = 0x%" DW_PR_XZEROS DW_PR_DUx " [%4" DW_PR_DUu ",%2" DW_PR_DUu "] '%s'\n", i, pc,lineno,column,sanitized(filename)); /* The compilation unit was already printed */ if (!glflags.gf_check_decl_file) { PRINT_CU_INFO(); } } glflags.gf_record_dwarf_error = FALSE; /* Due to a fatal error, skip current record */ if (found_line_error) { continue; } } if (glflags.gf_do_print_dwarf) { if (is_logicals_table || is_actuals_table) { printf("[%4" DW_PR_DUu "] ", i + 1); } /* Check if print of address is needed. */ if (glflags.gf_line_print_pc) { printf("0x%" DW_PR_XZEROS DW_PR_DUx " ", pc); } if (is_actuals_table) { printf("[%7" DW_PR_DUu "]", logicalno); } else { printf("[%4" DW_PR_DUu ",%2" DW_PR_DUu "]", lineno, column); } } if (!is_actuals_table) { nsres = dwarf_linebeginstatement(line, &newstatement, <_err); if (nsres == DW_DLV_OK) { if (newstatement && glflags.gf_do_print_dwarf) { printf(" %s","NS"); } } else if (nsres == DW_DLV_ERROR) { print_error(dbg, "linebeginstatment failed", nsres, lt_err); } } if (!is_logicals_table) { nsres = dwarf_lineblock(line, &new_basic_block, <_err); if (nsres == DW_DLV_OK) { if (new_basic_block && glflags.gf_do_print_dwarf) { printf(" %s","BB"); } } else if (nsres == DW_DLV_ERROR) { print_error(dbg, "lineblock failed", nsres, lt_err); } nsres = dwarf_lineendsequence(line, &lineendsequence, <_err); if (nsres == DW_DLV_OK) { if (lineendsequence && glflags.gf_do_print_dwarf) { printf(" %s", "ET"); } } else if (nsres == DW_DLV_ERROR) { print_error(dbg, "lineendsequence failed", nsres, lt_err); } } if (glflags.gf_do_print_dwarf) { Dwarf_Bool prologue_end = 0; Dwarf_Bool epilogue_begin = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; int disres = dwarf_prologue_end_etc(line, &prologue_end,&epilogue_begin, &isa,&discriminator,<_err); if (disres == DW_DLV_ERROR) { print_error(dbg, "dwarf_prologue_end_etc() failed", disres, lt_err); } if (prologue_end && !is_actuals_table) { printf(" PE"); } if (epilogue_begin && !is_actuals_table) { printf(" EB"); } if (isa && !is_logicals_table) { printf(" IS=0x%" DW_PR_DUx, isa); } if (discriminator && !is_actuals_table) { printf(" DI=0x%" DW_PR_DUx, discriminator); } if (is_logicals_table) { call_context = 0; disres = dwarf_linecontext(line, &call_context, <_err); if (disres == DW_DLV_ERROR) { print_error(dbg, "dwarf_linecontext() failed", disres, lt_err); } if (call_context) { printf(" CC=%" DW_PR_DUu, call_context); } subprog_name = 0; disres = dwarf_line_subprog(line, &subprog_name, &subprog_filename, &subprog_line, <_err); if (disres == DW_DLV_ERROR) { print_error(dbg, "dwarf_line_subprog() failed", disres, lt_err); } if (subprog_name && strlen(subprog_name)) { /* We do not print an empty name. Clutters things up. */ printf(" SB=\"%s\"", sanitized(subprog_name)); } } } if (!is_actuals_table) { if (i > 0 && glflags.verbose < 3 && strcmp(filename,esb_get_string(&lastsrc)) == 0) { /* Do not print name. */ } else { struct esb_s urs; char atmp2[200]; esb_constructor_fixed(&urs,atmp2,sizeof(atmp2)); esb_append(&urs, " uri: \""); translate_to_uri(filename,&urs); esb_append(&urs,"\""); if (glflags.gf_do_print_dwarf) { printf("%s",esb_get_string(&urs)); } esb_destructor(&urs); esb_empty_string(&lastsrc); esb_append(&lastsrc,filename); } if (sres == DW_DLV_OK) { dwarf_dealloc(dbg, filename, DW_DLA_STRING); } } if (glflags.gf_do_print_dwarf) { printf("\n"); } } esb_destructor(&lastsrc); } /* Here we test the interfaces into Dwarf_Line_Context. */ static void print_line_context_record(Dwarf_Debug dbg, Dwarf_Line_Context line_context) { int vres = 0; Dwarf_Unsigned lsecoff = 0; Dwarf_Unsigned version = 0; Dwarf_Signed dir_count = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; Dwarf_Signed i = 0; Dwarf_Signed subprog_count = 0; const char *name = 0; Dwarf_Small table_count = 0; Dwarf_Error err = 0; struct esb_s bufr; char bufr_tmp[100]; esb_constructor_fixed(&bufr,bufr_tmp,sizeof(bufr_tmp)); printf("Line Context data\n"); vres = dwarf_srclines_table_offset(line_context,&lsecoff,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" Line Section Offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n", lsecoff); vres = dwarf_srclines_version(line_context,&version, &table_count, &err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" version number 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", version,version); printf(" number of line tables %d.\n", table_count); vres = dwarf_srclines_comp_dir(line_context,&name,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } if (name) { printf(" Compilation directory: %s\n",name); } else { printf(" Compilation directory: \n"); } vres = dwarf_srclines_include_dir_count(line_context,&dir_count,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" include directory count 0x%" DW_PR_DUx " %" DW_PR_DSd "\n", (Dwarf_Unsigned)dir_count,dir_count); for(i = 1; i <= dir_count; ++i) { vres = dwarf_srclines_include_dir_data(line_context,i, &name,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" [%2" DW_PR_DSd "] \"%s\"\n",i,name); } vres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf( " files count 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", file_count,file_count); /* Set up so just one loop control needed for all versions of line tables. */ for(i = baseindex; i < endindex; ++i) { Dwarf_Unsigned dirindex = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindex, &modtime,&flength, &md5data,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } esb_empty_string(&bufr); if (name) { esb_empty_string(&bufr); esb_append(&bufr,"\""); esb_append(&bufr,name); esb_append(&bufr,"\""); } else { esb_append(&bufr,""); } printf(" [%2" DW_PR_DSd "] %-24s ,", i,esb_get_string(&bufr)); printf(" directory index %2" DW_PR_DUu ,dirindex); printf(", file length %2" DW_PR_DUu ,flength); if (md5data) { char *c = (char *)md5data; char *end = c+sizeof(*md5data); printf(", file md5 value 0x"); while(c < end) { printf("%02x",0xff&*c); ++c; } printf(" "); } if (modtime) { time_t tt3 = (time_t)modtime; /* ctime supplies newline */ printf( "file mod time 0x%x %s", (unsigned)tt3, ctime(&tt3)); } else { printf(" file mod time 0\n"); } } esb_destructor(&bufr); vres = dwarf_srclines_subprog_count(line_context,&subprog_count, &err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } if (subprog_count == 0) { return; } /* The following is for the experimental table which is only DWARF4 so far, so no need for a dwarf_srclines_subprog_indexes() function. Yet. */ printf(" subprograms count (experimental) 0x%" DW_PR_DUx " %" DW_PR_DUu "\n", subprog_count,subprog_count); for(i = 1; i <= subprog_count; ++i) { Dwarf_Unsigned decl_file = 0; Dwarf_Unsigned decl_line = 0; vres = dwarf_srclines_subprog_data(line_context,i, &name,&decl_file, &decl_line,&err); if (vres != DW_DLV_OK) { print_error(dbg,"Error accessing line context" "Something broken.", vres,err); return; } printf(" [%2" DW_PR_DSd "] \"%s\"" ", fileindex %2" DW_PR_DUu ", lineindex %2" DW_PR_DUu "\n", i,name,decl_file,decl_line); } } extern void print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die) { Dwarf_Unsigned lineversion = 0; Dwarf_Signed linecount = 0; Dwarf_Line *linebuf = NULL; Dwarf_Signed linecount_actuals = 0; Dwarf_Line *linebuf_actuals = NULL; Dwarf_Small table_count = 0; int lres = 0; int line_errs = 0; Dwarf_Line_Context line_context = 0; const char *sec_name = 0; Dwarf_Error err = 0; Dwarf_Off cudie_local_offset = 0; Dwarf_Off dieprint_cu_goffset = 0; int atres = 0; glflags.current_section_id = DEBUG_LINE; /* line_flag is TRUE */ lres = dwarf_get_line_section_name_from_die(cu_die, &sec_name,&err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_line"; } /* The offsets will be zero if it fails. Let it pass. */ atres = dwarf_die_offsets(cu_die,&dieprint_cu_goffset, &cudie_local_offset,&err); DROP_ERROR_INSTANCE(dbg,atres,err); if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_line", &truename,FALSE); /* Ignore the COMPRESSED flags */ printf("\n%s: line number info for a single cu\n", sanitized(esb_get_string(&truename))); esb_destructor(&truename); } else { /* We are checking, not printing. */ Dwarf_Half tag = 0; int tres = dwarf_tag(cu_die, &tag, &err); if (tres != DW_DLV_OK) { /* Something broken here. */ print_error(dbg,"Unable to see CU DIE tag " "though we could see it earlier. Something broken.", tres,err); return; } else if (tag == DW_TAG_type_unit) { /* Not checking since type units missing address or range in CU header. */ return; } } if (glflags.verbose > 1) { int errcount = 0; print_source_intro(dbg,cu_die); print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ 1, /* indent level */0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); DWARF_CHECK_COUNT(lines_result,1); lres = dwarf_print_lines(cu_die, &err,&errcount); if (errcount > 0) { DWARF_ERROR_COUNT(lines_result,errcount); DWARF_CHECK_COUNT(lines_result,(errcount-1)); } if (lres == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_srclines details", lres, err); } return; } if (glflags.gf_check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); dwarf_check_lineheader(cu_die,&line_errs); if (line_errs > 0) { DWARF_CHECK_ERROR_PRINT_CU(); DWARF_ERROR_COUNT(lines_result,line_errs); DWARF_CHECK_COUNT(lines_result,(line_errs-1)); } } /* The following is complicated by a desire to test various line table interface functions. Hence we test line_flag_selection. Normal code should pick an interface (for most the best choice is what we here call glflags.gf_line_flag_selection == singledw5) and use just that interface set. Sorry about the length of the code that results from having so many interfaces. */ if (glflags.gf_line_flag_selection == singledw5) { lres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context, &err); if(lres == DW_DLV_OK) { lres = dwarf_srclines_from_linecontext(line_context, &linebuf, &linecount,&err); } } else if (glflags.gf_line_flag_selection == orig) { /* DWARF2,3,4, ok for 5. */ /* Useless for experimental line tables */ lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err); if(lres == DW_DLV_OK && linecount ){ table_count++; } } else if (glflags.gf_line_flag_selection == orig2l) { lres = dwarf_srclines_two_level(cu_die, &lineversion, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, &err); if(lres == DW_DLV_OK && linecount){ table_count++; } if(lres == DW_DLV_OK && linecount_actuals){ table_count++; } } else if (glflags.gf_line_flag_selection == s2l) { lres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context, &err); if(lres == DW_DLV_OK) { lres = dwarf_srclines_two_level_from_linecontext(line_context, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, &err); } } if (lres == DW_DLV_ERROR) { /* Do not terminate processing */ if (glflags.gf_check_decl_file) { DWARF_CHECK_COUNT(decl_file_result,1); DWARF_CHECK_ERROR2(decl_file_result,"dwarf_srclines", dwarf_errmsg(err)); glflags.gf_record_dwarf_error = FALSE; /* Clear error condition */ } else { print_error_and_continue(dbg, "dwarf_srclines", lres, err); } } else if (lres == DW_DLV_NO_ENTRY) { /* no line information is included */ } else if (table_count > 0) { /* DW_DLV_OK */ if (glflags.gf_do_print_dwarf) { if(line_context && glflags.verbose) { print_line_context_record(dbg,line_context); } print_source_intro(dbg,cu_die); if (glflags.verbose) { print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ TRUE, /* indent_level= */ 0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); } } if(glflags.gf_line_flag_selection == singledw5 || glflags.gf_line_flag_selection == s2l) { if (table_count == 0 || table_count == 1) { /* ASSERT: is_single_table == true */ Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals,is_actuals); } else { Dwarf_Bool is_logicals = TRUE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); process_line_table(dbg,sec_name, linebuf_actuals, linecount_actuals, !is_logicals, !is_actuals); } dwarf_srclines_dealloc_b(line_context); } else if (glflags.gf_line_flag_selection == orig) { Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); dwarf_srclines_dealloc(dbg,linebuf,linecount); } else if (glflags.gf_line_flag_selection == orig2l) { if (table_count == 1 || table_count == 0) { Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); } else { Dwarf_Bool is_logicals = TRUE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); process_line_table(dbg,sec_name, linebuf_actuals, linecount_actuals, !is_logicals, !is_actuals); } dwarf_srclines_dealloc(dbg,linebuf,linecount); } /* end, table_count > 0 */ } else { /* DW_DLV_OK */ /* table_count == 0. no lines in table. Just a line table header. */ if (glflags.gf_do_print_dwarf) { int ores = 0; Dwarf_Unsigned off = 0; print_source_intro(dbg,cu_die); if (glflags.verbose) { print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ TRUE, /* indent_level= */ 0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); } if(line_context) { if (glflags.verbose > 2) { print_line_context_record(dbg,line_context); } ores = dwarf_srclines_table_offset(line_context, &off,&err); if (ores != DW_DLV_OK) { print_error(dbg,"dwarf_srclines_table_offset fail", ores,err); } else { printf(" Line table is present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no lines present\n", off); } } else { printf(" Line table is present but no lines present\n"); } } if(glflags.gf_line_flag_selection == singledw5 || glflags.gf_line_flag_selection == s2l) { dwarf_srclines_dealloc_b(line_context); } else { /* Original allocation. */ dwarf_srclines_dealloc(dbg,linebuf,linecount); } /* end, linecounttotal == 0 */ } } dwarfutils-20200114/dwarfdump/print_locs.c000066400000000000000000000122211361531463500204470ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2016 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* print data in .debug_loc There is no guarantee this will work because we are assuming that all bytes are valid loclist data, that there are no odd padding or garbage bytes. In normal use one gets into here via an offset from .debug_info, so it could be that bytes not referenced from .debug_info are garbage or even zero padding. So this can fail (error off) as such bytes can lead dwarf_get_loclist_entry() astray. It's also wrong because we don't know what CU or frame each loclist is from, so we don't know the address_size for sure. */ extern void print_locs(Dwarf_Debug dbg) { Dwarf_Unsigned offset = 0; Dwarf_Addr hipc_offset = 0; Dwarf_Addr lopc_offset = 0; Dwarf_Ptr data = 0; Dwarf_Unsigned entry_len = 0; Dwarf_Unsigned next_entry = 0; int index = 0; int lres = 0; int fres = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; Dwarf_Half version = 2; /* FAKE */ Dwarf_Error err = 0; struct esb_s exprstring; unsigned loopct = 0; esb_constructor(&exprstring); glflags.current_section_id = DEBUG_LOC; /* Do nothing if not printing. */ if (!glflags.gf_do_print_dwarf) { return; } if(!glflags.gf_use_old_dwarf_loclist) { printf("\n"); printf("Printing location lists with -c is no longer supported\n"); return; } fres = dwarf_get_address_size(dbg, &address_size, &err); if (fres != DW_DLV_OK) { print_error(dbg, "dwarf_get_address_size", fres, err); } fres = dwarf_get_offset_size(dbg, &offset_size, &err); if (fres != DW_DLV_OK) { print_error(dbg, "dwarf_get_address_size", fres, err); } #if 0 /* This print code not needed as cannot be safely used and uses old interface. */ { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_loc", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } #endif printf("Format : " "index section-offset begin-addr end-addr length-of-block-entry\n"); /* Pre=October 2015 version. */ for (loopct = 0; (lres = dwarf_get_loclist_entry(dbg, offset, &hipc_offset, &lopc_offset, &data, &entry_len, &next_entry, &err)) == DW_DLV_OK; ++loopct) { get_string_from_locs(dbg,data,entry_len,address_size, offset_size, version, &exprstring); /* Display offsets */ if (!loopct) { /* This print code not needed as cannot be safely used and uses old interface. */ print_secname(dbg,".debug_loc"); } if (glflags.gf_display_offsets) { ++index; printf(" [%8d] 0x%" DW_PR_XZEROS DW_PR_DUx, index, offset); if (glflags.verbose) { printf(" ", next_entry - entry_len); } } printf(" 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %8" DW_PR_DUu " %s\n", (Dwarf_Unsigned) lopc_offset, (Dwarf_Unsigned) hipc_offset, entry_len, esb_get_string(&exprstring)); esb_empty_string(&exprstring); offset = next_entry; } if (!loopct) { /* This print code not needed as cannot be safely used and uses old interface. */ print_secname(dbg,".debug_loc"); } esb_destructor(&exprstring); if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_loclist_entry", lres, err); } } dwarfutils-20200114/dwarfdump/print_macro.c000066400000000000000000000406051361531463500206170ustar00rootroot00000000000000/* Copyright 2015-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "uri.h" #include #include #include "print_sections.h" #include "macrocheck.h" #include "sanitized.h" static void print_source_intro(Dwarf_Die cu_die) { Dwarf_Off off = 0; int ores = 0; Dwarf_Error err = 0; ores = dwarf_dieoffset(cu_die, &off, &err); if (ores == DW_DLV_OK) { int lres = 0; const char *sec_name = 0; lres = dwarf_get_die_section_name_b(cu_die, &sec_name,&err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_info"; } printf("Macro data from CU-DIE at %s offset 0x%" DW_PR_XZEROS DW_PR_DUx ":\n", sec_name, (Dwarf_Unsigned) off); } else { printf("Macro data (for the CU-DIE at unknown location):\n"); } } static void print_macro_ops(Dwarf_Debug dbg, Dwarf_Macro_Context mcontext, Dwarf_Unsigned number_of_ops) { unsigned k = 0; for (k = 0; k < number_of_ops; ++k) { Dwarf_Unsigned section_offset = 0; Dwarf_Half macro_operator = 0; Dwarf_Half forms_count = 0; const Dwarf_Small *formcode_array = 0; Dwarf_Unsigned line_number = 0; Dwarf_Unsigned index = 0; Dwarf_Unsigned offset =0; const char * macro_string =0; int lres = 0; Dwarf_Error err = 0; lres = dwarf_get_macro_op(mcontext, k, §ion_offset,¯o_operator, &forms_count, &formcode_array,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_op()", lres,err); return; } if (glflags.gf_do_print_dwarf) { printf(" [%3d] 0x%02x %-20s", k,macro_operator, (macro_operator? get_MACRO_name(macro_operator,dwarf_names_print_on_error): "end-of-macros")); } if (glflags.gf_do_print_dwarf && glflags.show_form_used && forms_count > 0) { unsigned l = 0; printf("\n Forms count %2u:",forms_count); for(; l < forms_count;++l) { Dwarf_Small form = formcode_array[l]; printf(" 0x%02x %-18s ", form, get_FORM_name(form,dwarf_names_print_on_error)); } printf("\n "); } switch(macro_operator) { case 0: case DW_MACRO_end_file: if(glflags.gf_do_print_dwarf) { printf("\n"); } break; case DW_MACRO_define: case DW_MACRO_undef: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, &err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_defundef()", lres,err); } if (glflags.gf_do_print_dwarf) { printf(" line %" DW_PR_DUu " %s\n", line_number, macro_string?sanitized(macro_string):""); } break; } case DW_MACRO_define_strp: case DW_MACRO_undef_strp: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, &err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from strp dwarf_get_macro_defundef()", lres,err); } if (glflags.gf_do_print_dwarf) { printf(" line %" DW_PR_DUu " str offset 0x%" DW_PR_XZEROS DW_PR_DUx " %s\n", line_number,offset, macro_string?sanitized(macro_string):""); } break; } case DW_MACRO_define_strx: case DW_MACRO_undef_strx: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, &err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from strx dwarf_get_macro_defundef()", lres,err); } if (glflags.gf_do_print_dwarf) { printf(" line %" DW_PR_DUu " index 0x%" DW_PR_XZEROS DW_PR_DUx " str offset 0x%" DW_PR_XZEROS DW_PR_DUx " %s\n", line_number, index,offset, macro_string?macro_string:""); } break; } case DW_MACRO_define_sup: case DW_MACRO_undef_sup: { lres = dwarf_get_macro_defundef(mcontext, k, &line_number, &index, &offset, &forms_count, ¯o_string, &err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from sup dwarf_get_macro_defundef()", lres,err); } if (glflags.gf_do_print_dwarf) { printf(" line %" DW_PR_DUu " sup str offset 0x%" DW_PR_XZEROS DW_PR_DUx " %s\n", line_number,offset, macro_string?sanitized(macro_string):""); } break; } case DW_MACRO_start_file: { lres = dwarf_get_macro_startend_file(mcontext, k,&line_number, &index, ¯o_string,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_startend_file()", lres,err); } if (glflags.gf_do_print_dwarf) { printf(" line %" DW_PR_DUu " file number %" DW_PR_DUu " %s\n", line_number, index, macro_string?sanitized(macro_string):""); } break; } case DW_MACRO_import: { Dwarf_Bool is_primary = FALSE; lres = dwarf_get_macro_import(mcontext, k,&offset,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_import()", lres,err); } add_macro_import(¯o_check_tree, is_primary,offset); if (glflags.gf_do_print_dwarf) { printf(" offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n",offset); } break; } case DW_MACRO_import_sup: { lres = dwarf_get_macro_import(mcontext, k,&offset,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_import()(sup)", lres,err); } add_macro_import_sup(¯o_check_tree,offset); if (glflags.gf_do_print_dwarf) { printf(" sup_offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n",offset); } break; } } } } extern void print_macros_5style_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die, int by_offset, Dwarf_Unsigned offset) { int lres = 0; Dwarf_Unsigned version = 0; Dwarf_Macro_Context macro_context = 0; Dwarf_Unsigned macro_unit_offset = 0; Dwarf_Unsigned number_of_ops = 0; Dwarf_Unsigned ops_total_byte_len = 0; Dwarf_Bool is_primary = TRUE; Dwarf_Error err = 0; Dwarf_Off dieprint_cu_goffset = 0; Dwarf_Off cudie_local_offset = 0; int atres = 0; glflags.current_section_id = DEBUG_MACRO; if(!by_offset) { lres = dwarf_get_macro_context(cu_die, &version,¯o_context, ¯o_unit_offset, &number_of_ops, &ops_total_byte_len, &err); offset = macro_unit_offset; } else { lres = dwarf_get_macro_context_by_offset(cu_die, offset, &version,¯o_context, &number_of_ops, &ops_total_byte_len, &err); is_primary = FALSE; } if(lres == DW_DLV_NO_ENTRY) { return; } if(lres == DW_DLV_ERROR) { print_error(dbg,"Unable to dwarf_get_macro_context()", lres,err); return; } atres = dwarf_die_offsets(cu_die,&dieprint_cu_goffset, &cudie_local_offset,&err); DROP_ERROR_INSTANCE(dbg,atres,err); add_macro_import(¯o_check_tree,is_primary, offset); add_macro_area_len(¯o_check_tree,offset,ops_total_byte_len); if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_macro", &truename,TRUE); if(!by_offset) { printf("\n%s: Macro info for a single cu\n", sanitized(esb_get_string(&truename))); print_source_intro(cu_die); } else { printf("\n%s: Macro info for imported CU at offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", sanitized(esb_get_string(&truename)), offset); } esb_destructor(&truename); } else { /* We are checking, not printing. */ Dwarf_Half tag = 0; int tres = dwarf_tag(cu_die, &tag, &err); if (tres != DW_DLV_OK) { /* Something broken here. */ print_error(dbg,"Unable to see CU DIE tag " "though we could see it earlier. Something broken.", tres,err); return; } else if (tag == DW_TAG_type_unit) { /* Not checking since type units missing address or range in CU header. */ return; } } if (glflags.gf_do_print_dwarf && glflags.verbose > 1) { #if 0 int errcount = 0; #endif print_one_die(dbg, cu_die, dieprint_cu_goffset, /* print_information= */ 1, /* indent level */0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); #if 0 DWARF_CHECK_COUNT(lines_result,1); lres = dwarf_print_lines(cu_die, &err,&errcount); if (errcount > 0) { DWARF_ERROR_COUNT(lines_result,errcount); DWARF_CHECK_COUNT(lines_result,(errcount-1)); } if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_srclines details", lres, err); } #endif } { Dwarf_Half lversion =0; Dwarf_Unsigned mac_offset =0; Dwarf_Unsigned mac_len =0; Dwarf_Unsigned mac_header_len =0; Dwarf_Unsigned line_offset =0; unsigned mflags = 0; Dwarf_Bool has_line_offset = FALSE; Dwarf_Bool has_offset_size_64 = FALSE; Dwarf_Bool has_operands_table = FALSE; Dwarf_Half opcode_count = 0; Dwarf_Half offset_size = 4; lres = dwarf_macro_context_head(macro_context, &lversion, &mac_offset,&mac_len, &mac_header_len,&mflags,&has_line_offset, &line_offset, &has_offset_size_64,&has_operands_table, &opcode_count,&err); if(lres == DW_DLV_NO_ENTRY) { /* Impossible */ return; } if(lres == DW_DLV_ERROR) { print_error(dbg,"Call to dwarf_macro_context_head() failed", lres,err); return; } if (has_offset_size_64) { offset_size = 8; } if (glflags.gf_do_print_dwarf) { printf(" Macro version: %d\n",lversion); } if (glflags.verbose && glflags.gf_do_print_dwarf) { printf(" macro section offset 0x%" DW_PR_XZEROS DW_PR_DUx "\n", mac_offset); printf(" flags: 0x%x, line offset? %u offsetsize %u, " "operands_table? %u\n", mflags,has_line_offset,has_offset_size_64, has_operands_table); printf(" offset size 0x%x\n",offset_size); printf(" header length: 0x%" DW_PR_XZEROS DW_PR_DUx " total length: 0x%" DW_PR_XZEROS DW_PR_DUx "\n", mac_header_len,mac_len); if (has_line_offset) { printf(" debug_line_offset: 0x%" DW_PR_XZEROS DW_PR_DUx "\n", line_offset); } if (has_operands_table) { Dwarf_Half i = 0; for( i = 0; i < opcode_count; ++i) { Dwarf_Half opcode_num = 0; Dwarf_Half operand_count = 0; const Dwarf_Small *operand_array = 0; Dwarf_Half j = 0; lres = dwarf_macro_operands_table(macro_context, i, &opcode_num, &operand_count,&operand_array,&err); if (lres == DW_DLV_NO_ENTRY) { dwarf_dealloc_macro_context(macro_context); print_error(dbg, "NO ENTRY? dwarf_macro_operands_table()", lres,err); return; } if (lres == DW_DLV_ERROR) { dwarf_dealloc_macro_context(macro_context); print_error(dbg, "ERROR from dwarf_macro_operands_table()", lres,err); return; } printf(" [%3u] op: 0x%04x %20s operandcount: %u\n", i,opcode_num, get_MACRO_name(opcode_num, dwarf_names_print_on_error), operand_count); for (j = 0; j < operand_count; ++j) { Dwarf_Small opnd = operand_array[j]; printf(" [%3u] 0x%04x %20s\n", j,opnd, get_FORM_name(opnd, dwarf_names_print_on_error)); } } } } if (glflags.gf_do_print_dwarf) { printf(" MacroInformationEntries count: %" DW_PR_DUu ", bytes length: %" DW_PR_DUu "\n", number_of_ops,ops_total_byte_len); } print_macro_ops(dbg,macro_context,number_of_ops); } #if 0 if (check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); dwarf_check_lineheader(cu_die,&line_errs); if (line_errs > 0) { DWARF_CHECK_ERROR_PRINT_CU(); DWARF_ERROR_COUNT(lines_result,line_errs); DWARF_CHECK_COUNT(lines_result,(line_errs-1)); } } #endif dwarf_dealloc_macro_context(macro_context); macro_context = 0; mark_macro_offset_printed(¯o_check_tree,offset); } dwarfutils-20200114/dwarfdump/print_macros.c000066400000000000000000000154241361531463500210030ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "macrocheck.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" #include "print_frames.h" #define TRUE 1 #define FALSE 0 struct macro_counts_s { long mc_start_file; long mc_end_file; long mc_define; long mc_undef; long mc_extension; long mc_code_zero; long mc_unknown; }; static void print_one_macro_entry_detail(long i, char *type, struct Dwarf_Macro_Details_s *mdp) { /* "DW_MACINFO_*: section-offset file-index [line] string\n" */ if (glflags.gf_do_print_dwarf) { if (mdp->dmd_macro) { printf("%3ld %s: %6" DW_PR_DUu " %2" DW_PR_DSd " [%4" DW_PR_DSd "] \"%s\" \n", i, type, (Dwarf_Unsigned)mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno, sanitized(mdp->dmd_macro)); } else { printf("%3ld %s: %6" DW_PR_DUu " %2" DW_PR_DSd " [%4" DW_PR_DSd "] 0\n", i, type, (Dwarf_Unsigned)mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno); } } } static void print_one_macro_entry(long i, struct Dwarf_Macro_Details_s *mdp, struct macro_counts_s *counts) { switch (mdp->dmd_type) { case 0: counts->mc_code_zero++; print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp); break; case DW_MACINFO_start_file: counts->mc_start_file++; print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp); break; case DW_MACINFO_end_file: counts->mc_end_file++; print_one_macro_entry_detail(i, "DW_MACINFO_end_file ", mdp); break; case DW_MACINFO_vendor_ext: counts->mc_extension++; print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp); break; case DW_MACINFO_define: counts->mc_define++; print_one_macro_entry_detail(i, "DW_MACINFO_define ", mdp); break; case DW_MACINFO_undef: counts->mc_undef++; print_one_macro_entry_detail(i, "DW_MACINFO_undef ", mdp); break; default: { struct esb_s typeb; esb_constructor(&typeb); counts->mc_unknown++; esb_append_printf(&typeb, "DW_MACINFO_0x%x", mdp->dmd_type); print_one_macro_entry_detail(i, esb_get_string(&typeb), mdp); esb_destructor(&typeb); } break; } } /* print data in .debug_macinfo */ /*ARGSUSED*/ extern void print_macinfo_by_offset(Dwarf_Debug dbg,Dwarf_Unsigned offset) { Dwarf_Unsigned max = 0; Dwarf_Signed count = 0; Dwarf_Macro_Details *maclist = NULL; int lres = 0; long i = 0; struct macro_counts_s counts; Dwarf_Unsigned totallen = 0; Dwarf_Bool is_primary = TRUE; Dwarf_Error error = 0; glflags.current_section_id = DEBUG_MACINFO; /* No real need to get the real section name, this section not used much in modern compilers as this definition of macro data (V2-V4) is obsolete as it takes too much space to be much used. */ lres = dwarf_get_macro_details(dbg, offset, max, &count, &maclist, &error); if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_macro_details", lres, error); } else if (lres == DW_DLV_NO_ENTRY) { return; } memset(&counts, 0, sizeof(counts)); if (glflags.gf_do_print_dwarf) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_macinfo", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); printf("\n"); printf("compilation-unit .debug_macinfo offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n",offset); printf("num name section-offset file-index [line] \"string\"\n"); } for (i = 0; i < count; i++) { struct Dwarf_Macro_Details_s *mdp = &maclist[i]; print_one_macro_entry(i, mdp, &counts); } if (counts.mc_start_file == 0) { printf("DW_MACINFO file count of zero is invalid DWARF2/3/4\n"); } if (counts.mc_start_file != counts.mc_end_file) { printf("Counts of DW_MACINFO file (%ld) end_file (%ld) " "do not match!.\n", counts.mc_start_file, counts.mc_end_file); } if (counts.mc_code_zero < 1) { printf("Count of zeros in macro group should be non-zero " "(1 preferred), count is %ld\n", counts.mc_code_zero); } /* next byte is maclist[count - 1].dmd_offset + 1; */ totallen = (maclist[count - 1].dmd_offset + 1) - offset; add_macro_import(&macinfo_check_tree,is_primary, offset); add_macro_area_len(&macinfo_check_tree,offset,totallen); if (glflags.gf_do_print_dwarf) { printf("Macro counts: start file %ld, " "end file %ld, " "define %ld, " "undef %ld, " "ext %ld, " "code-zero %ld, " "unknown %ld\n", counts.mc_start_file, counts.mc_end_file, counts.mc_define, counts.mc_undef, counts.mc_extension, counts.mc_code_zero, counts.mc_unknown); } /* int type= maclist[count - 1].dmd_type; */ /* ASSERT: type is zero */ dwarf_dealloc(dbg, maclist, DW_DLA_STRING); return; } dwarfutils-20200114/dwarfdump/print_pubnames.c000066400000000000000000000416751361531463500213400ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "sanitized.h" /* This unifies the code for some error checks to avoid code duplication. */ static void check_info_offset_sanity( const char *sec, const char *field, char *global, Dwarf_Unsigned offset, Dwarf_Unsigned maxoff) { if (maxoff == 0) { /* Lets make a heuristic check. */ if (offset > 0xffffffff) { printf("Warning: section %s %s %s offset 0x%" DW_PR_XZEROS DW_PR_DUx " " "exceptionally large \n", sec, field, global, offset); } return; } if (offset >= maxoff) { printf("Warning: section %s %s %s offset 0x%" DW_PR_XZEROS DW_PR_DUx " " "larger than max of 0x%" DW_PR_DUx "\n", sec, field, global, offset, maxoff); } } static void deal_with_name_offset_err(Dwarf_Debug dbg, char *err_loc, const char *name, Dwarf_Unsigned die_off, int nres, Dwarf_Error aerr) { if (nres == DW_DLV_ERROR) { Dwarf_Unsigned myerr = dwarf_errno(aerr); struct esb_s fullmsg; if (myerr == DW_DLE_OFFSET_BAD) { printf("Error: bad offset %s %s: %" DW_PR_DUu " (0x%08" DW_PR_DUx ")\n", err_loc, name, die_off, die_off); } esb_constructor(&fullmsg); esb_append(&fullmsg,err_loc); esb_append(&fullmsg,name); print_error(dbg, esb_get_string(&fullmsg), nres, aerr); esb_destructor(&fullmsg); } } /* Unified pubnames style output. The error checking here against maxoff may be useless (in that libdwarf may return an error if the offset is bad and we will not get called here). But we leave it in nonetheless as it looks sensible. In at least one gigantic executable such offsets turned out wrong. */ static int print_pubname_style_entry(Dwarf_Debug dbg, const char *line_title, char *name, Dwarf_Unsigned die_off, Dwarf_Unsigned cu_die_off, Dwarf_Unsigned global_cu_offset, Dwarf_Unsigned maxoff) { Dwarf_Die die = NULL; Dwarf_Off die_CU_off = 0; int dres = 0; int ddres = 0; int cudres = 0; Dwarf_Error err = 0; /* get die at die_off */ dres = dwarf_offdie(dbg, die_off, &die, &err); /* Some llvm version puts the global die offset into pubnames with the result that we will get an error here but we just let that create an error, papering it over here by subtracting out the applicatble debug_info CU header offset is problematic. */ if (dres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," dwarf_offdie : " "die offset does not reference valid DIE. "); esb_append_printf(&details,"0x%" DW_PR_DUx, die_off); esb_append(&details,"."); print_error(dbg, esb_get_string(&details), dres, err); esb_destructor(&details); } /* get offset of die from its cu-header */ ddres = dwarf_die_CU_offset(die, &die_CU_off, &err); if (ddres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," cannot get CU die offset"); print_error(dbg, esb_get_string(&details), dres, err); esb_destructor(&details); die_CU_off = 0; } /* Get die at offset cu_die_off to check its existence. */ { Dwarf_Die cu_die = NULL; cudres = dwarf_offdie(dbg, cu_die_off, &cu_die, &err); if (cudres != DW_DLV_OK) { struct esb_s details; esb_constructor(&details); esb_append(&details,line_title); esb_append(&details," dwarf_offdie: " "cu die offset does not reference valid CU DIE. "); esb_append_printf(&details,"0x%" DW_PR_DUx, cu_die_off); esb_append(&details,"."); print_error(dbg, esb_get_string(&details), dres, err); esb_destructor(&details); } else { /* It exists, all is well. */ dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); } } /* Display offsets */ if (glflags.gf_display_offsets) { /* Print 'name'at the end for better layout */ printf("%s die-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ", cu-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx "," " die-in-cu 0x%" DW_PR_XZEROS DW_PR_DUx ", cu-header-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx , line_title, die_off, cu_die_off, (Dwarf_Unsigned) die_CU_off, /* Following is absolute offset of the beginning of the cu */ (Dwarf_Signed) (die_off - die_CU_off)); } if ((die_off - die_CU_off) != global_cu_offset) { printf(" error: real cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx, global_cu_offset); exit(1); } /* Display offsets */ if (glflags.gf_display_offsets && glflags.verbose) { printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx , global_cu_offset); } /* Print 'name'at the end for better layout */ printf(" '%s'\n",name); dwarf_dealloc(dbg, die, DW_DLA_DIE); check_info_offset_sanity(line_title, "die offset", name, die_off, maxoff); check_info_offset_sanity(line_title, "die cu offset", name, die_CU_off, maxoff); check_info_offset_sanity(line_title, "cu offset", name, (die_off - die_CU_off), maxoff); return DW_DLV_OK; } static void print_globals_header( Dwarf_Off pub_section_hdr_offset, Dwarf_Unsigned length_size, /* from pubnames header */ Dwarf_Unsigned length, /* from pubnames header */ Dwarf_Unsigned version, Dwarf_Off info_header_offset, Dwarf_Unsigned info_length) { printf("Pub section offset 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", pub_section_hdr_offset,pub_section_hdr_offset); printf(" offset size 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", length_size, length_size); printf(" length 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", length, length); printf(" version 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", version, version); printf(" info hdr offset 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", info_header_offset, info_header_offset); printf(" info hdr length 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", info_length, info_length); } /* Get all the data in .debug_pubnames */ void print_pubnames(Dwarf_Debug dbg) { Dwarf_Global *globbuf = NULL; Dwarf_Signed count = 0; /* Offset to previous CU */ Dwarf_Error err = 0; int res = 0; struct esb_s truename; Dwarf_Addr elf_max_address = 0; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s sanitname; glflags.current_section_id = DEBUG_PUBNAMES; get_address_size_and_max(dbg,0,&elf_max_address,&err); esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_pubnames", &truename,TRUE); if (glflags.verbose) { /* For best testing! */ res = dwarf_return_empty_pubnames(dbg,1,&err); if (res != DW_DLV_OK) { printf("FAIL: Erroneous libdwarf call " "of dwarf_return_empty_pubnames: Fix dwarfdump"); return; } } { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); esb_destructor(&truename); } res = dwarf_get_globals(dbg, &globbuf, &count, &err); if (glflags.gf_do_print_dwarf && count > 0) { printf("\n%s\n",esb_get_string(&sanitname)); } if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_get_globals", res, err); } else if (res == DW_DLV_NO_ENTRY) { esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); return; } else { print_all_pubnames_style_records(dbg, "global", esb_get_string(&sanitname), globbuf,count,&err); dwarf_globals_dealloc(dbg,globbuf,count); } esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); } int print_all_pubnames_style_records(Dwarf_Debug dbg, const char *linetitle, const char * section_true_name, Dwarf_Global *globbuf, Dwarf_Signed count, Dwarf_Error *err) { Dwarf_Unsigned maxoff = get_info_max_offset(dbg); Dwarf_Unsigned lastcudieoff = 0; Dwarf_Addr elf_max_address = 0; Dwarf_Signed i = 0; get_address_size_and_max(dbg,0,&elf_max_address,err); for (i = 0; i < count; i++) { int nres = 0; int cures3 = 0; Dwarf_Off die_off = 0; Dwarf_Off cu_die_off = 0; Dwarf_Off prev_cu_off = elf_max_address; Dwarf_Off global_cu_off = 0; char *name = 0; /* Turns the cu-local die_off in globbuf entry into a global die_off. The cu_off returned is the offset of the CU DIE, not the CU header. */ nres = dwarf_global_name_offsets(globbuf[i], &name, &die_off, &cu_die_off, err); deal_with_name_offset_err(dbg, "dwarf_global_name_offsets in ", section_true_name, die_off, nres, *err); if(glflags.verbose) { /* We know no die_off can be zero (except for the fake global created when the debug_pubnames for a CU has no actual entries) we do not need to check for i==0 to detect this is the initial global record and we want to print this pubnames section CU header. */ if (lastcudieoff != cu_die_off) { Dwarf_Off pub_section_hdr_offset = 0; Dwarf_Unsigned pub_offset_size = 0; Dwarf_Unsigned pub_length = 0; Dwarf_Unsigned pub_version = 0; Dwarf_Off info_header_offset = 0; Dwarf_Unsigned info_length = 0; nres = dwarf_get_globals_header(globbuf[i], &pub_section_hdr_offset, &pub_offset_size, &pub_length,&pub_version, &info_header_offset,&info_length,err); if (nres != DW_DLV_OK) { struct esb_s msge; esb_constructor(&msge); esb_append(&msge,"Access dwarf_get_globals_header in "); esb_append(&msge,section_true_name); esb_append(&msge,"fails. "); print_error_and_continue(dbg, esb_get_string(&msge), nres, *err); esb_destructor(&msge); return DW_DLV_ERROR; } if(glflags.gf_do_print_dwarf) { print_globals_header(pub_section_hdr_offset, pub_offset_size, pub_length, pub_version, info_header_offset, info_length); } } } lastcudieoff = cu_die_off; if (glflags.verbose) { /* If verbose we can see a zero die_off. */ if (!die_off && !strlen(name)) { /* A different and impossble cu die offset in case of an empty pubnames CU. */ continue; } } /* This gets the CU header offset, which is the offset that die_off needs to be added to to calculate the DIE offset. Note that dwarf_global_name_offsets already did that addition properly so this call is just so we can print the CU header offset. */ cures3 = dwarf_global_cu_offset(globbuf[i], &global_cu_off, err); if (cures3 != DW_DLV_OK) { print_error(dbg, "dwarf_global_cu_offset", cures3, *err); } if (glflags.gf_check_pubname_attr) { Dwarf_Bool has_attr = 0; int ares = 0; int dres = 0; Dwarf_Die die = 0; /* We are processing a new set of pubnames for a different CU; get the producer ID, at 'cu_off' to see if we need to skip these pubnames */ if (cu_die_off != prev_cu_off) { /* Record offset for previous CU */ prev_cu_off = cu_die_off; dres = dwarf_offdie(dbg, cu_die_off, &die, err); if (dres != DW_DLV_OK) { struct esb_s msgb; esb_constructor(&msgb); esb_append(&msgb,"Printing "); esb_append(&msgb,section_true_name); esb_append(&msgb," dwarf_offdie a "); print_error(dbg, esb_get_string(&msgb), dres,*err); esb_destructor(&msgb); } { /* Get producer name for this CU and update compiler list */ struct esb_s producername; esb_constructor(&producername); get_producer_name(dbg,die,cu_die_off,&producername); update_compiler_target(esb_get_string(&producername)); esb_destructor(&producername); } dwarf_dealloc(dbg, die, DW_DLA_DIE); } /* get die at die_off */ dres = dwarf_offdie(dbg, die_off, &die, err); if (dres != DW_DLV_OK) { struct esb_s msgc; esb_constructor(&msgc); esb_append(&msgc,"Printing "); esb_append(&msgc,section_true_name); esb_append(&msgc," dwarf_offdie b"); print_error(dbg, esb_get_string(&msgc), dres, *err); esb_destructor(&msgc); } ares = dwarf_hasattr(die, DW_AT_external, &has_attr, err); if (ares == DW_DLV_ERROR) { struct esb_s msgd; esb_constructor(&msgd); esb_append(&msgd,"hassattr on DW_AT_external from "); esb_append(&msgd,section_true_name); print_error(dbg, esb_get_string(&msgd), ares, *err); esb_destructor(&msgd); } /* Check for specific compiler */ if (checking_this_compiler()) { DWARF_CHECK_COUNT(pubname_attr_result,1); if (ares == DW_DLV_OK && has_attr) { /* Should the value of flag be examined? */ } else { DWARF_CHECK_ERROR2(pubname_attr_result,name, "pubname does not have DW_AT_external"); } } dwarf_dealloc(dbg, die, DW_DLA_DIE); } /* Now print name, after the test */ if (glflags.gf_do_print_dwarf || (glflags.gf_record_dwarf_error && glflags.gf_check_verbose_mode)) { int res = 0; res = print_pubname_style_entry(dbg, linetitle, name, die_off, cu_die_off, global_cu_off, maxoff); if (res != DW_DLV_OK) { return res; } glflags.gf_record_dwarf_error = FALSE; } } return DW_DLV_OK; } dwarfutils-20200114/dwarfdump/print_ranges.c000066400000000000000000000303511361531463500207720ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2018 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" static struct esb_s esb_string; void ranges_esb_string_destructor(void) { esb_destructor(&esb_string); } /* Because we do not know what DIE is involved, if the object being printed has different address sizes in different compilation units this will not work properly: anything could happen. */ extern void print_ranges(Dwarf_Debug dbg) { Dwarf_Unsigned off = 0; int group_number = 0; int wasdense = 0; Dwarf_Error pr_err = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; unsigned loopct = 0; glflags.current_section_id = DEBUG_RANGES; if (!glflags.gf_do_print_dwarf) { return; } #if 0 { esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_ranges", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); } #endif /* Turn off dense, we do not want print_ranges_list_to_extra to use dense form here. */ wasdense = glflags.dense; glflags.dense = 0; for (;;++loopct) { Dwarf_Ranges *rangeset = 0; Dwarf_Signed rangecount = 0; Dwarf_Unsigned bytecount = 0; /* We do not know what DIE is involved, we use the older call here. */ int rres = dwarf_get_ranges(dbg,off,&rangeset, &rangecount,&bytecount,&pr_err); if (!loopct) { esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_ranges", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); } if (rres == DW_DLV_OK) { char *val = 0; printf(" Ranges group %d:\n",group_number); esb_empty_string(&esb_string); print_ranges_list_to_extra(dbg,off, rangeset,rangecount,bytecount, &esb_string); dwarf_ranges_dealloc(dbg,rangeset,rangecount); val = esb_get_string(&esb_string); printf("%s",sanitized(val)); ++group_number; } else if (rres == DW_DLV_NO_ENTRY) { printf("End of %s.\n",sanitized(esb_get_string(&truename))); break; } else { /* ERROR, which does not quite mean a real error, as we might just be misaligned reading things without a DW_AT_ranges offset.*/ printf("End of %s..\n",sanitized(esb_get_string(&truename))); break; } off += bytecount; } glflags.dense = wasdense; esb_destructor(&truename); } /* Extracted this from print_range_attribute() to isolate the check of the range list. */ static void check_ranges_list(Dwarf_Debug dbg, UNUSEDARG Dwarf_Off die_off, Dwarf_Die cu_die, Dwarf_Unsigned original_off, Dwarf_Ranges *rangeset, Dwarf_Signed rangecount, Dwarf_Unsigned bytecount) { Dwarf_Unsigned off = original_off; Dwarf_Signed index = 0; Dwarf_Addr base_address = glflags.CU_base_address; Dwarf_Addr lopc = 0; Dwarf_Addr hipc = 0; Dwarf_Bool bError = FALSE; Dwarf_Half elf_address_size = 0; Dwarf_Addr elf_max_address = 0; Dwarf_Error rlerr = 0; static boolean do_print = TRUE; const char *sec_name = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_ranges", &truename,FALSE); sec_name = esb_get_string(&truename); get_address_size_and_max(dbg,&elf_address_size,&elf_max_address,&rlerr); /* Ignore last entry, is the end-of-list */ for (index = 0; index < rangecount - 1; index++) { Dwarf_Ranges *r = rangeset + index; if (r->dwr_addr1 == elf_max_address) { /* (0xffffffff,addr), use specific address (current PU address) */ base_address = r->dwr_addr2; } else { /* (offset,offset), update using CU address */ lopc = r->dwr_addr1 + base_address; hipc = r->dwr_addr2 + base_address; DWARF_CHECK_COUNT(ranges_result,1); /* Check the low_pc and high_pc are within a valid range in the .text section */ if (IsValidInBucketGroup(glflags.pRangesInfo,lopc) && IsValidInBucketGroup(glflags.pRangesInfo,hipc)) { /* Valid values; do nothing */ } else { /* At this point may be we are dealing with a linkonce symbol */ if (IsValidInLinkonce(glflags.pLinkonceInfo, glflags.PU_name,lopc,hipc)) { /* Valid values; do nothing */ } else { struct esb_s errbuf; bError = TRUE; esb_constructor(&errbuf); esb_append_printf(&errbuf, "%s: Address outside a " "valid .text range",sanitized(sec_name)); DWARF_CHECK_ERROR(ranges_result, esb_get_string(&errbuf)); esb_destructor(&errbuf); if (glflags.gf_check_verbose_mode && do_print) { /* Update DIEs offset just for printing */ int dioff_res = dwarf_die_offsets(cu_die, &glflags.DIE_overall_offset, &glflags.DIE_offset,&rlerr); if (dioff_res != DW_DLV_OK) { print_error(dbg, "dwarf_die_offsets",dioff_res, rlerr); } printf( "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx ", " "Low = 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx "), High = 0x%" DW_PR_XZEROS DW_PR_DUx " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", off,base_address,lopc, r->dwr_addr1,hipc, r->dwr_addr2); } } } } /* Each entry holds 2 addresses (offsets) */ off += elf_address_size * 2; } /* In the case of errors, we have to print the range records that caused the error. */ if (bError && glflags.gf_check_verbose_mode && do_print) { struct esb_s rangesstr; esb_constructor(&rangesstr); printf("\n"); print_ranges_list_to_extra(dbg,original_off, rangeset,rangecount,bytecount, &rangesstr); printf("%s\n", sanitized(esb_get_string(&rangesstr))); esb_destructor(&rangesstr); } /* In the case of printing unique errors, stop the printing of any subsequent errors, which have the same text. */ if (bError && glflags.gf_check_verbose_mode && glflags.gf_print_unique_errors) { do_print = FALSE; } esb_destructor(&truename); } /* Records information about compilers (producers) found in the debug information, including the check results for several categories (see -k option). */ typedef struct { Dwarf_Off die_off; Dwarf_Off range_off; } Range_Array_Entry; /* Array to record the DW_AT_range attribute DIE, to be used at the end of the CU, to check the range values; DWARF4 allows an offset relative to the low_pc as the high_pc value. Also, LLVM generates for the CU the pair (low_pc, at_ranges) instead of the traditional (low_pc, high_pc). */ static Range_Array_Entry *range_array = NULL; static Dwarf_Unsigned range_array_size = 0; static Dwarf_Unsigned range_array_count = 0; #define RANGE_ARRAY_INITIAL_SIZE 64 /* Allocate space to store information about the ranges; the values are extracted from the DW_AT_ranges attribute. The space is reused by all CUs. */ void allocate_range_array_info() { if (range_array == NULL) { /* Allocate initial range array info */ range_array = (Range_Array_Entry *) calloc(RANGE_ARRAY_INITIAL_SIZE,sizeof(Range_Array_Entry)); range_array_size = RANGE_ARRAY_INITIAL_SIZE; } } void release_range_array_info() { if (range_array) { free(range_array); range_array = 0; range_array_size = 0; range_array_count = 0; } } /* Clear out values from previous CU */ static void reset_range_array_info() { if (range_array) { memset((void *)range_array,0, (range_array_count) * sizeof(Range_Array_Entry)); range_array_count = 0; } } void record_range_array_info_entry(Dwarf_Off die_off,Dwarf_Off range_off) { /* Record a new detected range info. */ if (range_array_count == range_array_size) { /* Resize range array */ range_array_size *= 2; range_array = (Range_Array_Entry *) realloc(range_array, (range_array_size) * sizeof(Range_Array_Entry)); } /* The 'die_off' is the Global Die Offset */ range_array[range_array_count].die_off = die_off; range_array[range_array_count].range_off = range_off; ++range_array_count; } /* Now that we are at the end of the CU, check the range lists */ void check_range_array_info(Dwarf_Debug dbg) { if (range_array && range_array_count) { /* Traverse the range array and for each entry: Load the ranges Check for any outside conditions */ Dwarf_Off original_off = 0; Dwarf_Off die_off = 0; Dwarf_Unsigned index = 0; Dwarf_Die cu_die; int res; Dwarf_Error ra_err = 0; /* In case of errors, the correct DIE offset should be displayed. At this point we are at the end of the PU */ Dwarf_Off DIE_overall_offset_bak = glflags.DIE_overall_offset; for (index = 0; index < range_array_count; ++index) { Dwarf_Ranges *rangeset = 0; Dwarf_Signed rangecount = 0; Dwarf_Unsigned bytecount = 0; /* Get a range info record */ die_off = range_array[index].die_off; original_off = range_array[index].range_off; res = dwarf_offdie(dbg,die_off,&cu_die,&ra_err); if (res != DW_DLV_OK) { print_error(dbg,"dwarf_offdie",res,ra_err); } res = dwarf_get_ranges_a(dbg,original_off,cu_die, &rangeset,&rangecount,&bytecount,&ra_err); if (res == DW_DLV_OK) { check_ranges_list(dbg,die_off,cu_die,original_off, rangeset,rangecount,bytecount); } dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); }; reset_range_array_info(); /* Point back to the end of the PU */ glflags.DIE_overall_offset = DIE_overall_offset_bak; } } dwarfutils-20200114/dwarfdump/print_reloc.c000066400000000000000000000671571361531463500206350ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef DWARF_WITH_LIBELF #define DWARF_RELOC_MIPS #define DWARF_RELOC_PPC #define DWARF_RELOC_PPC64 #define DWARF_RELOC_ARM #define DWARF_RELOC_X86_64 #define DWARF_RELOC_386 #include "print_reloc.h" #include "print_reloc_decls.h" #include "section_bitmaps.h" #include "esb.h" #include "sanitized.h" static void print_reloc_information_64(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static void print_reloc_information_32(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link); static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link); static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size); static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf); static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf); /* Set the relocation names based on the machine type */ static void set_relocation_table_names(Dwarf_Small machine_type) { reloc_type_names = 0; number_of_reloc_type_names = 0; switch (machine_type) { case EM_MIPS: #ifdef DWARF_RELOC_MIPS reloc_type_names = reloc_type_names_MIPS; number_of_reloc_type_names = sizeof(reloc_type_names_MIPS) / sizeof(char *); #endif /* DWARF_RELOC_MIPS */ break; case EM_PPC: #ifdef DWARF_RELOC_PPC reloc_type_names = reloc_type_names_PPC; number_of_reloc_type_names = sizeof(reloc_type_names_PPC) / sizeof(char *); #endif /* DWARF_RELOC_PPC */ break; case EM_PPC64: #ifdef DWARF_RELOC_PPC64 reloc_type_names = reloc_type_names_PPC64; number_of_reloc_type_names = sizeof(reloc_type_names_PPC64) / sizeof(char *); #endif /* DWARF_RELOC_PPC64 */ break; case EM_ARM: #ifdef DWARF_RELOC_ARM reloc_type_names = reloc_type_names_ARM; number_of_reloc_type_names = sizeof(reloc_type_names_ARM) / sizeof(char *); #endif /* DWARF_RELOC_ARM */ break; case EM_386: #ifdef DWARF_RELOC_386 reloc_type_names = reloc_type_names_386; number_of_reloc_type_names = sizeof(reloc_type_names_386) / sizeof(char *); #endif /* DWARF_RELOC_386 */ break; case EM_X86_64: #ifdef DWARF_RELOC_X86_64 reloc_type_names = reloc_type_names_X86_64; number_of_reloc_type_names = sizeof(reloc_type_names_X86_64) / sizeof(char *); #endif /* DWARF_RELOC_X86_64 */ break; default: /* We don't have others covered. */ reloc_type_names = 0; number_of_reloc_type_names = 0; break; } } static void get_reloc_type_names(int index,struct esb_s* outbuf) { if (index < 0 || index >= number_of_reloc_type_names) { if (number_of_reloc_type_names == 0) { /* No table provided. */ esb_append_printf(outbuf, "reloc type %d", (int) index); } else { /* Table incomplete? */ esb_append_printf(outbuf, "reloc type %d unknown", (int) index); } return; } esb_append(outbuf, reloc_type_names[index]); } static void get_reloc_section(Dwarf_Debug dbg, Elf_Scn *scn, char *scn_name, Elf64_Word sh_type, struct sect_data_s * printable_sect, unsigned sectnum) { Elf_Data *data; int index; /* Check for reloc records we are interested in. */ for (index = 1; index < DW_SECTION_REL_ARRAY_SIZE; ++index) { const char *n = rel_info[index].name_rel; const char *na = rel_info[index].name_rela; Dwarf_Error err = 0; if (strcmp(scn_name, n) == 0) { SECT_DATA_SET(rel_info[index].index,sh_type,n, printable_sect,sectnum) return; } if (strcmp(scn_name, na) == 0) { SECT_DATA_SET(rel_info[index].index,sh_type,na, printable_sect,sectnum) return; } } return; } void print_relocinfo(Dwarf_Debug dbg) { Elf *elf = 0; char *endr_ident = 0; int is_64bit = 0; int res = 0; int i = 0; Dwarf_Error err = 0; for (i = 1; i < DW_SECTION_REL_ARRAY_SIZE; i++) { sect_data[i].display = reloc_map_enabled(i); sect_data[i].buf = 0; sect_data[i].size = 0; sect_data[i].type = SHT_NULL; } res = dwarf_get_elf(dbg, &elf, &err); if (res == DW_DLV_NO_ENTRY) { printf(" No Elf, so no elf relocations to print.\n"); return; } else if (res == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_elf error", res, err); } endr_ident = elf_getident(elf, NULL); if (!endr_ident) { print_error(dbg, "DW_ELF_GETIDENT_ERROR", res, err); } is_64bit = (endr_ident[EI_CLASS] == ELFCLASS64); if (is_64bit) { print_relocinfo_64(dbg, elf); } else { print_relocinfo_32(dbg, elf); } } static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf) { #ifdef HAVE_ELF64_GETEHDR Elf_Scn *scn = NULL; unsigned sect_number = 0; Elf64_Ehdr *ehdr64 = 0; Elf64_Shdr *shdr64 = 0; char *scn_name = 0; int i = 0; Elf64_Sym *sym_64 = 0; char **scn_names = 0; struct sect_data_s *printable_sects = 0; int scn_names_cnt = 0; Dwarf_Error err = 0; ehdr64 = elf64_getehdr(elf); if (ehdr64 == NULL) { print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err); } /* Make the section name array big enough that we don't need to check for overrun in the loop. */ scn_names_cnt = ehdr64->e_shnum + 1; scn_names = (char **)calloc(scn_names_cnt, sizeof(char *)); if (!scn_names) { print_error(dbg, "Out of malloc space in relocation print names", DW_DLV_OK, err); } printable_sects = (struct sect_data_s *)calloc(scn_names_cnt, sizeof(struct sect_data_s)); if (!printable_sects) { free(scn_names); print_error(dbg, "Out of malloc space in relocation print sects", DW_DLV_OK, err); } /* First nextscn returns section 1 */ while ((scn = elf_nextscn(elf, scn)) != NULL) { ++sect_number; shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { free(scn_names); free(printable_sects); print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err); } scn_name = elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name); if (scn_name == NULL) { print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err); } /* elf_nextscn() skips section with index '0' */ scn_names[sect_number] = scn_name; if (shdr64->sh_type == SHT_SYMTAB) { size_t sym_size = 0; size_t count = 0; sym_64 = (Elf64_Sym *) get_scndata(scn, &sym_size); if (sym_64 == NULL) { free(scn_names); free(printable_sects); print_error(dbg, "no Elf64 symbol table data", DW_DLV_OK, err); } count = sym_size / sizeof(Elf64_Sym); if(sym_size%sizeof(Elf64_Sym)) { print_error(dbg, "Elf64 problem reading .symtab data", DW_DLV_OK, err); } sym_64++; count--; free(sym_data_64); sym_data_64 = 0; sym_data_64 = read_64_syms(sym_64, count, elf, shdr64->sh_link); sym_data_64_entry_count = count; if (sym_data_64 == NULL) { free(scn_names); free(printable_sects); print_error(dbg, "problem reading Elf64 symbol table data", DW_DLV_OK, err); } } else { get_reloc_section(dbg,scn,scn_name,shdr64->sh_type, printable_sects,sect_number); } } /* Set the relocation names based on the machine type */ set_relocation_table_names(ehdr64->e_machine); for (i = 1; i < ehdr64->e_shnum + 1; i++) { if (printable_sects[i].display && printable_sects[i].buf != NULL && printable_sects[i].size > 0) { print_reloc_information_64(i, printable_sects[i].buf, printable_sects[i].size, printable_sects[i].type, scn_names,scn_names_cnt); } } free(printable_sects); free(scn_names); #endif } static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf) { Elf_Scn *scn = NULL; Elf32_Ehdr *ehdr32 = 0; Elf32_Shdr *shdr32 = 0; unsigned sect_number = 0; char *scn_name = 0; int i = 0; Elf32_Sym *sym = 0; char **scn_names = 0; int scn_names_cnt = 0; Dwarf_Error err = 0; struct sect_data_s *printable_sects = 0; ehdr32 = elf32_getehdr(elf); if (ehdr32 == NULL) { print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err); } /* Make the section name array big enough that we don't need to check for overrun in the loop. */ scn_names_cnt = ehdr32->e_shnum + 1; scn_names = (char **)calloc(scn_names_cnt, sizeof(char *)); if (!scn_names) { print_error(dbg, "Out of malloc space in relocation print names", DW_DLV_OK, err); } printable_sects = (struct sect_data_s *)calloc(scn_names_cnt, sizeof(struct sect_data_s)); if (!printable_sects) { free(scn_names); print_error(dbg, "Out of malloc space in relocation print sects", DW_DLV_OK, err); } while ((scn = elf_nextscn(elf, scn)) != NULL) { ++sect_number; shdr32 = elf32_getshdr(scn); if (shdr32 == NULL) { free(printable_sects); free(scn_names); print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err); } scn_name = elf_strptr(elf, ehdr32->e_shstrndx, shdr32->sh_name); if (scn_name == NULL) { free(printable_sects); free(scn_names); print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err); } scn_names[sect_number] = scn_name; if (shdr32->sh_type == SHT_SYMTAB) { size_t sym_size = 0; size_t count = 0; sym = (Elf32_Sym *) get_scndata(scn, &sym_size); if (sym == NULL) { free(printable_sects); free(scn_names); print_error(dbg, "No Elf32 symbol table data", DW_DLV_OK, err); } count = sym_size / sizeof(Elf32_Sym); if(sym_size%sizeof(Elf32_Sym)) { print_error(dbg, "Elf32 problem reading .symtab data", DW_DLV_OK, err); } sym++; count--; free(sym_data); sym_data = 0; sym_data = readsyms(sym, count, elf, shdr32->sh_link); sym_data_entry_count = count; if (sym_data == NULL) { free(printable_sects); free(scn_names); print_error(dbg, "problem reading Elf32 symbol table data", DW_DLV_OK, err); } } else { get_reloc_section(dbg,scn,scn_name,shdr32->sh_type, printable_sects,sect_number); } } /* End while. */ /* Set the relocation names based on the machine type */ set_relocation_table_names(ehdr32->e_machine); for (i = 1; i < ehdr32->e_shnum + 1; i++) { if (printable_sects[i].display && printable_sects[i].buf != NULL && printable_sects[i].size > 0) { print_reloc_information_32(i, printable_sects[i].buf, printable_sects[i].size, printable_sects[i].type, scn_names,scn_names_cnt); } } free(printable_sects); free(scn_names); } #if HAVE_ELF64_R_INFO #ifndef ELF64_R_TYPE #define ELF64_R_TYPE(x) 0 /* FIXME */ #endif #ifndef ELF64_R_SYM #define ELF64_R_SYM(x) 0 /* FIXME */ #endif #ifndef ELF64_ST_TYPE #define ELF64_ST_TYPE(x) 0 /* FIXME */ #endif #ifndef ELF64_ST_BIND #define ELF64_ST_BIND(x) 0 /* FIXME */ #endif #endif /* HAVE_ELF64_R_INFO */ static void print_reloc_information_64(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names,int scn_names_count) { /* Include support for Elf64_Rel and Elf64_Rela */ Dwarf_Unsigned add = 0; Dwarf_Half rel_size = SHT_RELA == type ? sizeof(Elf64_Rela) : sizeof(Elf64_Rel); Dwarf_Unsigned off = 0; struct esb_s tempesb; struct esb_s tempesc; printf("\n[%3d] %s:\n",section_no, sanitized(scn_names[section_no])); /* Print some headers and change the order for better reading */ printf("Offset Addend %-26s Index Symbol Name\n","Reloc Type"); #if HAVE_ELF64_GETEHDR for (off = 0; off < size; off += rel_size) { #if HAVE_ELF64_R_INFO /* This works for the Elf64_Rel in linux */ Elf64_Rel *p = (Elf64_Rel *) (buf + off); char *name = 0; if (sym_data_64) { size_t index = ELF64_R_SYM(p->r_info) - 1; if (index < sym_data_64_entry_count) { name = sym_data_64[index].name; if (!name || !name[0]){ SYM64 *sym_64 = &sym_data_64[index]; if (sym_64->type == STT_SECTION && sym_64->shndx < scn_names_count) { name = scn_names[sym_64->shndx]; } } } } if (!name || !name[0]) { name = ""; } if (SHT_RELA == type) { Elf64_Rela *pa = (Elf64_Rela *)p; add = pa->r_addend; } esb_constructor(&tempesb); esb_constructor(&tempesc); get_reloc_type_names(ELF64_R_TYPE(p->r_info),&tempesc); esb_append(&tempesb,sanitized(esb_get_string(&tempesc))); /* sanitized uses a static buffer, call just once here */ printf("0x%08lx 0x%08lx %-26s <%5ld> %s\n", (unsigned long int) (p->r_offset), (unsigned long int) (add), esb_get_string(&tempesb), (long)ELF64_R_SYM(p->r_info), sanitized(name)); esb_destructor(&tempesb); esb_destructor(&tempesc); #else /* ! R_INFO */ /* sgi/mips -64 does not have r_info in the 64bit relocations, but seperate fields, with 3 types, actually. Only one of which prints here, as only one really used with dwarf */ Elf64_Rel *p = (Elf64_Rel *) (buf + off); char *name = 0; /* We subtract 1 from sym indexes since we left symtab entry 0 out of the sym_data[_64] array */ if (sym_data_64) { size_t index = p->r_sym - 1; if (index < sym_data_64_entry_count) { name = sym_data_64[index].name; } } if (!name || !name[0]) { name = ""; } esb_constructor(&tempesb); esb_constructor(&tempesc); get_reloc_type_names(p->r_type,&tempesc)); esb_append(&tempesb,sanitized(esb_get_string(&tempesc))); printf("%5" DW_PR_DUu " %-26s <%3ld> %s\n", (Dwarf_Unsigned) (p->r_offset), esb_get_string(&tempesb), (long)p->r_sym, sanitized(name)); esb_destructor(&tempesb); esb_destructor(&tempesc); #endif } #endif /* HAVE_ELF64_GETEHDR */ } static void print_reloc_information_32(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count) { /* Include support for Elf32_Rel and Elf32_Rela */ Dwarf_Unsigned add = 0; Dwarf_Half rel_size = SHT_RELA == type ? sizeof(Elf32_Rela) : sizeof(Elf32_Rel); Dwarf_Unsigned off = 0; struct esb_s tempesb; struct esb_s tempesc; printf("\n[%3d] %s:\n",section_no, sanitized(scn_names[section_no])); /* Print some headers and change the order for better reading. */ printf("Offset Addend %-26s Index Symbol Name\n","Reloc Type"); for (off = 0; off < size; off += rel_size) { Elf32_Rel *p = (Elf32_Rel *) (buf + off); char *name = 0; /* We subtract 1 from sym indexes since we left symtab entry 0 out of the sym_data[_64] array */ if (sym_data) { size_t index = ELF32_R_SYM(p->r_info) - 1; if(index < sym_data_entry_count) { name = sym_data[index].name; if ((!name || !name[0]) && sym_data) { SYM *sym = &sym_data[index]; if (sym->type == STT_SECTION&& sym->shndx < scn_names_count) { name = scn_names[sym->shndx]; } } } } if (!name || !name[0]) { name = ""; } if (SHT_RELA == type) { Elf32_Rela *pa = (Elf32_Rela *)p; add = pa->r_addend; } esb_constructor(&tempesb); esb_constructor(&tempesc); get_reloc_type_names(ELF32_R_TYPE(p->r_info),&tempesc); esb_append(&tempesb,esb_get_string(&tempesc)); /* sanitized uses a static buffer, call just once here */ printf("0x%08lx 0x%08lx %-26s <%5ld> %s\n", (unsigned long int) (p->r_offset), (unsigned long int) (add), esb_get_string(&tempesb), (long)ELF32_R_SYM(p->r_info), sanitized(name)); esb_destructor(&tempesb); esb_destructor(&tempesc); } } /* We are only reading and saving syms 1...num-1. */ static SYM * readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link) { SYM *s = 0; SYM *buf = 0; indx_type i = 0; buf = (SYM *) calloc(num, sizeof(SYM)); if (buf == NULL) { return NULL; } s = buf; /* save pointer to head of array */ for (i = 0; i < num; i++, data++, buf++) { buf->indx = i; buf->name = (char *) elf_strptr(elf, link, data->st_name); buf->value = data->st_value; buf->size = data->st_size; buf->type = ELF32_ST_TYPE(data->st_info); buf->bind = ELF32_ST_BIND(data->st_info); buf->other = data->st_other; buf->shndx = data->st_shndx; } /* end for loop */ return (s); } /* We are only reading and saving syms 1...num-1. */ static SYM64 * read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link) { #ifdef HAVE_ELF64_GETEHDR SYM64 *s = 0; SYM64 *buf = 0; indx_type i = 0; buf = (SYM64 *) calloc(num, sizeof(SYM64)); if (buf == NULL) { return NULL; } s = buf; /* save pointer to head of array */ for (i = 0; i < num; i++, data++, buf++) { buf->indx = i; buf->name = (char *) elf_strptr(elf, link, data->st_name); buf->value = data->st_value; buf->size = data->st_size; buf->type = ELF64_ST_TYPE(data->st_info); buf->bind = ELF64_ST_BIND(data->st_info); buf->other = data->st_other; buf->shndx = data->st_shndx; } /* end for loop */ return (s); #else return 0; #endif /* HAVE_ELF64_GETEHDR */ } static void * get_scndata(Elf_Scn * fd_scn, size_t * scn_size) { Elf_Data *p_data; p_data = 0; if ((p_data = elf_getdata(fd_scn, p_data)) == 0 || p_data->d_size == 0) { return NULL; } *scn_size = p_data->d_size; return (p_data->d_buf); } /* Cleanup of malloc space (some of the pointers will be 0 here) so dwarfdump looks 'clean' to a malloc checker. */ void clean_up_syms_malloc_data() { free(sym_data); sym_data = 0; free(sym_data_64); sym_data_64 = 0; sym_data_64_entry_count = 0; sym_data_entry_count = 0; } void print_object_header(Dwarf_Debug dbg) { Elf *elf = 0; int res = 0; Dwarf_Error err = 0; /* Check if header information is required */ res = dwarf_get_elf(dbg, &elf, &err); if (res == DW_DLV_NO_ENTRY) { printf(" No Elf, so no elf headers to print.\n"); return; } else if (res == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_elf error", res, err); } if (section_map_enabled(DW_HDR_HEADER)) { #ifdef _WIN32 #ifdef HAVE_ELF32_GETEHDR /* Standard libelf has no function generating the names of the encodings, but this libelf apparently does. */ Elf_Ehdr_Literal eh_literals; Elf32_Ehdr *eh32 = 0; #ifdef HAVE_ELF64_GETEHDR Elf64_Ehdr *eh64 = 0; #endif /* HAVE_ELF64_GETEHDR */ eh32 = elf32_getehdr(elf); if (eh32) { /* Get literal strings for header fields */ elf32_gethdr_literals(eh32,&eh_literals); /* Print 32-bit obj header */ printf("\nObject Header:\ne_ident:\n"); printf(" File ID = %s\n",eh_literals.e_ident_file_id); printf(" File class = %02x (%s)\n", eh32->e_ident[EI_CLASS],eh_literals.e_ident_file_class); printf(" Data encoding = %02x (%s)\n", eh32->e_ident[EI_DATA],eh_literals.e_ident_data_encoding); printf(" File version = %02x (%s)\n", eh32->e_ident[EI_VERSION],eh_literals.e_ident_file_version); printf(" OS ABI = %02x (%s) (%s)\n",eh32->e_ident[EI_OSABI], eh_literals.e_ident_os_abi_s,eh_literals.e_ident_os_abi_l); printf(" ABI version = %02x (%s)\n", eh32->e_ident[EI_ABIVERSION], eh_literals.e_ident_abi_version); printf("e_type : 0x%x (%s)\n", eh32->e_type,eh_literals.e_type); printf("e_machine : 0x%x (%s) (%s)\n",eh32->e_machine, eh_literals.e_machine_s,eh_literals.e_machine_l); printf("e_version : 0x%x\n", eh32->e_version); printf("e_entry : 0x%08x\n",eh32->e_entry); printf("e_phoff : 0x%08x\n",eh32->e_phoff); printf("e_shoff : 0x%08x\n",eh32->e_shoff); printf("e_flags : 0x%x\n",eh32->e_flags); printf("e_ehsize : 0x%x\n",eh32->e_ehsize); printf("e_phentsize: 0x%x\n",eh32->e_phentsize); printf("e_phnum : 0x%x\n",eh32->e_phnum); printf("e_shentsize: 0x%x\n",eh32->e_shentsize); printf("e_shnum : 0x%x\n",eh32->e_shnum); printf("e_shstrndx : 0x%x\n",eh32->e_shstrndx); } else { #ifdef HAVE_ELF64_GETEHDR /* not a 32-bit obj */ eh64 = elf64_getehdr(elf); if (eh64) { /* Get literal strings for header fields */ elf64_gethdr_literals(eh64,&eh_literals); /* Print 64-bit obj header */ printf("\nObject Header:\ne_ident:\n"); printf(" File ID = %s\n",eh_literals.e_ident_file_id); printf(" File class = %02x (%s)\n", eh64->e_ident[EI_CLASS],eh_literals.e_ident_file_class); printf(" Data encoding = %02x (%s)\n", eh64->e_ident[EI_DATA],eh_literals.e_ident_data_encoding); printf(" File version = %02x (%s)\n", eh64->e_ident[EI_VERSION],eh_literals.e_ident_file_version); printf(" OS ABI = %02x (%s) (%s)\n",eh64->e_ident[EI_OSABI], eh_literals.e_ident_os_abi_s,eh_literals.e_ident_os_abi_l); printf(" ABI version = %02x (%s)\n", eh64->e_ident[EI_ABIVERSION], eh_literals.e_ident_abi_version); printf("e_type : 0x%x (%s)\n", eh64->e_type,eh_literals.e_type); printf("e_machine : 0x%x (%s) (%s)\n",eh64->e_machine, eh_literals.e_machine_s,eh_literals.e_machine_l); printf("e_version : 0x%x\n", eh64->e_version); printf("e_entry : 0x%" DW_PR_XZEROS DW_PR_DUx "\n",eh64->e_entry); printf("e_phoff : 0x%" DW_PR_XZEROS DW_PR_DUx "\n",eh64->e_phoff); printf("e_shoff : 0x%" DW_PR_XZEROS DW_PR_DUx "\n",eh64->e_shoff); printf("e_flags : 0x%x\n",eh64->e_flags); printf("e_ehsize : 0x%x\n",eh64->e_ehsize); printf("e_phentsize: 0x%x\n",eh64->e_phentsize); printf("e_phnum : 0x%x\n",eh64->e_phnum); printf("e_shentsize: 0x%x\n",eh64->e_shentsize); printf("e_shnum : 0x%x\n",eh64->e_shnum); printf("e_shstrndx : 0x%x\n",eh64->e_shstrndx); } #endif /* HAVE_ELF64_GETEHDR */ } #endif /* HAVE_ELF32_GETEHDR */ #endif /* _WIN32 */ } /* Print basic section information is required */ /* Mask only known sections (debug and text) bits */ if (any_section_header_to_print()) { int nCount = 0; int section_index = 0; const char *section_name = NULL; Dwarf_Addr section_addr = 0; Dwarf_Unsigned section_size = 0; Dwarf_Error error = 0; Dwarf_Unsigned total_bytes = 0; int printed_sections = 0; /* Print section information (name, size, address). */ nCount = dwarf_get_section_count(dbg); printf("\nInfo for %d sections:\n" " Nro Index Address Size(h) Size(d) Name\n", nCount); /* Ignore section with index=0 */ for (section_index = 1; section_index < nCount; ++section_index) { res = dwarf_get_section_info_by_index(dbg,section_index, §ion_name, §ion_addr, §ion_size, &error); if (res == DW_DLV_OK) { boolean print_it = FALSE; /* Use original mapping */ /* Check if the section name is a debug section */ print_it = section_name_is_debug_and_wanted( section_name); if (print_it) { ++printed_sections; printf(" %3d " /* nro */ "0x%03x " /* index */ "0x%" DW_PR_XZEROS DW_PR_DUx " " /* address */ "0x%" DW_PR_XZEROS DW_PR_DUx " " /* size (hex) */ "%" DW_PR_XZEROS DW_PR_DUu " " /* size (dec) */ "%s\n", /* name */ printed_sections, section_index, section_addr, section_size, section_size, section_name); total_bytes += section_size; } } } printf("*** Summary: %" DW_PR_DUu " bytes for %d section(s) ***\n", total_bytes, printed_sections); } } #endif /* DWARF_WITH_LIBELF */ dwarfutils-20200114/dwarfdump/print_reloc.h000066400000000000000000000027241361531463500206270ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRINT_RELOC_H_INCLUDED #define PRINT_RELOC_H_INCLUDED #include "dwarf_reloc_arm.h" #include "dwarf_reloc_mips.h" #include "dwarf_reloc_ppc.h" #include "dwarf_reloc_ppc64.h" #include "dwarf_reloc_x86_64.h" #include "dwarf_reloc_386.h" #endif /* PRINT_RELOC_H_INCLUDED */ dwarfutils-20200114/dwarfdump/print_reloc_decls.h000066400000000000000000000161301361531463500217750ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef DWARF_WITH_LIBELF #define DWARF_RELOC_MIPS #define DWARF_RELOC_PPC #define DWARF_RELOC_PPC64 #define DWARF_RELOC_ARM #define DWARF_RELOC_X86_64 #define DWARF_RELOC_386 #ifndef SELFTEST #include "print_reloc.h" #endif /* SELFTEST */ #include "section_bitmaps.h" #include "esb.h" #include "sanitized.h" #ifndef HAVE_ELF64_GETEHDR #define Elf64_Addr long #define Elf64_Word unsigned long #define Elf64_Xword unsigned long #define Elf64_Sym long #endif struct sect_data_s { Dwarf_Small *buf; Dwarf_Unsigned size; Dwarf_Bool display; /* Display reloc if TRUE */ const char *name; /* Section name */ Elf64_Xword type; /* To cover 32 and 64 records types */ }; #ifndef SELFTEST static struct sect_data_s sect_data[DW_SECTION_REL_ARRAY_SIZE]; #endif /* SELFTEST */ typedef size_t indx_type; typedef struct { indx_type indx; char *name; Elf32_Addr value; Elf32_Word size; int type; int bind; unsigned char other; Elf32_Half shndx; } SYM; typedef struct { indx_type indx; char *name; Elf64_Addr value; Elf64_Xword size; int type; int bind; unsigned char other; unsigned short shndx; } SYM64; #ifndef SELFTEST static void print_reloc_information_64(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static void print_reloc_information_32(int section_no, Dwarf_Small * buf, Dwarf_Unsigned size, Elf64_Xword type, char **scn_names, int scn_names_count); static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link); static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link); static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size); static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf); static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf); static SYM *sym_data; static SYM64 *sym_data_64; static unsigned long sym_data_entry_count; static unsigned long sym_data_64_entry_count; /* Include Section type, to be able to deal with all the Elf32_Rel, Elf32_Rela, Elf64_Rel, Elf64_Rela relocation types print_error does not return, so the following esb_destructor() call is unnecessary but reads well :-) */ #define SECT_DATA_SET(x,t,n,sout,r2) { \ data = elf_getdata(scn, 0); \ if (!data || !data->d_size) { \ struct esb_s data_disaster; \ esb_constructor(&data_disaster); \ esb_append(&data_disaster,(n)); \ esb_append(&data_disaster," null"); \ print_error(dbg,esb_get_string(&data_disaster),DW_DLV_OK, err); \ esb_destructor(&data_disaster); \ } \ sout[(r2)] = sect_data[(x)]; \ sout[(r2)].buf = data->d_buf; \ sout[(r2)].size = data->d_size; \ sout[(r2)].type = (t); \ sout[(r2)].name = (n); \ } /* Record the relocation table name information */ static const char **reloc_type_names = NULL; static int number_of_reloc_type_names = 0; #endif /* SELFTEST */ typedef struct { indx_type index; char *name_rel; /* .rel.debug_* names */ char *name_rela; /* .rela.debug_* names */ } REL_INFO; /* If the incoming scn_name is known, record the name in our reloc section names table. For a given (debug) section there can be a .rel or a .rela, not both. The name-to-index in this table is fixed, invariant. */ static REL_INFO rel_info[DW_SECTION_REL_ARRAY_SIZE] = { {0,0,0}, {/*1*/ DW_SECTION_REL_DEBUG_INFO, DW_SECTNAME_REL_DEBUG_INFO, DW_SECTNAME_RELA_DEBUG_INFO}, {/*2*/ DW_SECTION_REL_DEBUG_LINE, DW_SECTNAME_REL_DEBUG_LINE, DW_SECTNAME_RELA_DEBUG_LINE}, {/*3*/ DW_SECTION_REL_DEBUG_PUBNAMES, DW_SECTNAME_REL_DEBUG_PUBNAMES, DW_SECTNAME_RELA_DEBUG_PUBNAMES}, {/*4*/ DW_SECTION_REL_DEBUG_ABBREV, DW_SECTNAME_REL_DEBUG_ABBREV, DW_SECTNAME_RELA_DEBUG_ABBREV}, {/*5*/ DW_SECTION_REL_DEBUG_ARANGES, DW_SECTNAME_REL_DEBUG_ARANGES, DW_SECTNAME_RELA_DEBUG_ARANGES}, {/*6*/ DW_SECTION_REL_DEBUG_FRAME, DW_SECTNAME_REL_DEBUG_FRAME, DW_SECTNAME_RELA_DEBUG_FRAME}, {/*7*/ DW_SECTION_REL_DEBUG_LOC, DW_SECTNAME_REL_DEBUG_LOC, DW_SECTNAME_RELA_DEBUG_LOC}, {/*8*/ DW_SECTION_REL_DEBUG_LOCLISTS, DW_SECTNAME_REL_DEBUG_LOCLISTS, DW_SECTNAME_RELA_DEBUG_LOCLISTS}, {/*9*/ DW_SECTION_REL_DEBUG_RANGES, DW_SECTNAME_REL_DEBUG_RANGES, DW_SECTNAME_RELA_DEBUG_RANGES}, {/*10*/ DW_SECTION_REL_DEBUG_RNGLISTS, DW_SECTNAME_REL_DEBUG_RNGLISTS, DW_SECTNAME_RELA_DEBUG_RNGLISTS}, {/*11*/ DW_SECTION_REL_DEBUG_TYPES, DW_SECTNAME_REL_DEBUG_TYPES, DW_SECTNAME_RELA_DEBUG_TYPES}, {/*12*/ DW_SECTION_REL_DEBUG_STR_OFFSETS, DW_SECTNAME_REL_DEBUG_STR_OFFSETS, DW_SECTNAME_RELA_DEBUG_STR_OFFSETS}, {/*13*/ DW_SECTION_REL_DEBUG_PUBTYPES, DW_SECTNAME_REL_DEBUG_PUBTYPES, DW_SECTNAME_RELA_DEBUG_PUBTYPES}, {/*14*/ DW_SECTION_REL_GDB_INDEX, DW_SECTNAME_REL_GDB_INDEX, DW_SECTNAME_RELA_GDB_INDEX}, {/*15*/ DW_SECTION_REL_EH_FRAME, DW_SECTNAME_REL_EH_FRAME, DW_SECTNAME_RELA_EH_FRAME}, {/*16*/ DW_SECTION_REL_DEBUG_SUP, DW_SECTNAME_REL_DEBUG_SUP, DW_SECTNAME_RELA_DEBUG_SUP}, {/*17*/ DW_SECTION_REL_DEBUG_MACINFO, DW_SECTNAME_REL_DEBUG_MACINFO, DW_SECTNAME_RELA_DEBUG_MACINFO}, {/*18*/ DW_SECTION_REL_DEBUG_MACRO, DW_SECTNAME_REL_DEBUG_MACRO, DW_SECTNAME_RELA_DEBUG_MACRO}, {/*19*/ DW_SECTION_REL_DEBUG_NAMES, DW_SECTNAME_REL_DEBUG_NAMES, DW_SECTNAME_RELA_DEBUG_NAMES}, }; #endif /* DWARF_WITH_LIBELF */ dwarfutils-20200114/dwarfdump/print_reloc_test.c000066400000000000000000000042541361531463500216610ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2011-2012 SN Systems Ltd. All Rights Reserved This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #ifdef DWARF_WITH_LIBELF #ifndef SELFTEST #define DWARF_RELOC_MIPS #define DWARF_RELOC_PPC #define DWARF_RELOC_PPC64 #define DWARF_RELOC_ARM #define DWARF_RELOC_X86_64 #define DWARF_RELOC_386 #include "print_reloc.h" #endif /* SELFTEST */ #include "print_reloc_decls.h" #include "section_bitmaps.h" #include "esb.h" #include "sanitized.h" int main() { int failcount = 0; unsigned long i = 1; for ( ; i < DW_SECTION_REL_ARRAY_SIZE; ++i) { if (rel_info[i].index != i) { printf(" FAIL rel_info check, i = %lu vs %lu\n", i, (unsigned long)rel_info[i].index); ++failcount; } } if(failcount) { printf("FAIL print_reloc selftest\n"); exit(1); } printf("PASS print_reloc selftest\n"); return 0; } #else /* Without libelf we don't care about this as we will not try to print relocation data. Pretend ok. */ int main() { return 0; } #endif /* DWARF_WITH_LIBELF */ dwarfutils-20200114/dwarfdump/print_section_groups.c000066400000000000000000000213201361531463500225520ustar00rootroot00000000000000/* Copyright (C) 2017-2017 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "sanitized.h" #include "naming.h" /* Two purposes here related to COMDAT: A) get and print the data on sections and groups. B) reset certain global 'print' flags so printing a COMDAT section does not print the major sections that are from group 1 (DW_GROUPDATA_BASE) The functions are called from dwarfdump.c and only once. So static vars are safe. */ static Dwarf_Unsigned group_map_entry_count = 0; static Dwarf_Unsigned selected_group = 0; static Dwarf_Unsigned *sec_nums = 0; static Dwarf_Unsigned *group_nums = 0; static const char ** sec_names = 0; static Dwarf_Unsigned group_count; static Dwarf_Unsigned section_count; static void freeall_groups_tables(void) { free(sec_nums); sec_nums = 0; free(group_nums); group_nums = 0; /* Cast prevents an ugly warning about the const being stripped off. */ free((void*)sec_names); sec_names = 0; group_map_entry_count = 0; selected_group = 0; group_count = 0; section_count = 0; } #define TRUE 1 #define FALSE 0 static struct glfsetting_s { const char *secname; boolean *flag; boolean origset; boolean origflag; } glftab[] = { {".debug_abbrev", &glflags.gf_abbrev_flag,FALSE,FALSE}, {".debug_aranges", &glflags.gf_aranges_flag,FALSE,FALSE}, {".debug_debug_macinfo",&glflags.gf_macinfo_flag,FALSE,FALSE}, {".debug_debug_macro", &glflags.gf_macro_flag,FALSE,FALSE}, {".debug_debug_names", &glflags.gf_debug_names_flag,FALSE,FALSE}, {".debug_eh_frame", &glflags.gf_eh_frame_flag,FALSE,FALSE}, {".debug_frame", &glflags.gf_frame_flag,FALSE,FALSE}, {".gdb_index", &glflags.gf_gdbindex_flag,FALSE,FALSE}, {".debug_info", &glflags.gf_info_flag,FALSE,FALSE}, {".debug_line", &glflags.gf_line_flag,FALSE,FALSE}, {".debug_loc", &glflags.gf_loc_flag,FALSE,FALSE}, /*{".debug_loclists", &glflags.gf_loclists_flag,FALSE,FALSE}, */ {".debug_pubnames", &glflags.gf_pubnames_flag,FALSE,FALSE}, {".debug_pubtypes", &glflags.gf_pubtypes_flag,FALSE,FALSE}, /* SGI only */ {".debug_ranges", &glflags.gf_ranges_flag,FALSE,FALSE}, /*{".debug_rnglists", &glflags.gf_rnglists_flag,FALSE,FALSE}, */ {".debug_static_func", &glflags.gf_static_func_flag,FALSE,FALSE}, /* SGI only */ {".debug_static_var", &glflags.gf_static_var_flag,FALSE,FALSE}, /* SGI only */ {".debug_str", &glflags.gf_string_flag,FALSE,FALSE}, {".debug_types", &glflags.gf_types_flag,FALSE,FALSE}, {".debug_weaknames", &glflags.gf_weakname_flag,FALSE,FALSE}, /* SGI only */ {0,0,0,0} }; /* If a section is not in group N but is in group 1 then turn off its flag. Since sections are never in both (various DW_DLE*DUPLICATE errors if libdwarf tries to set in both), just look in group one. See groups_restore_subsidiary_flags() just below. FIXME: It would be good if, for a wholly missing section related to a flag, that the flag got turned off. */ static void turn_off_subsidiary_flags(UNUSEDARG Dwarf_Debug dbg) { Dwarf_Unsigned i = 0; for( ; i < group_map_entry_count; ++i) { if (group_nums[i] == 1) { unsigned k = 0; const char* oursec = sec_names[i]; for( ; glftab[k].secname; ++k ) { if (!strcmp(oursec,glftab[k].secname)) { if(!glftab[k].origset) { glftab[k].origset = TRUE; glftab[k].origflag = *(glftab[k].flag); } *(glftab[k].flag) = FALSE; } } } } } /* Restoring original condition in the glftab array and in the global flags it points to. So that when processing an archive one can restore the user-chosen flags and print subsequent object groups correctly. New October 16, 2017. */ void groups_restore_subsidiary_flags(void) { unsigned k = 0; /* Duplicative but harmless free. */ freeall_groups_tables(); for( ; glftab[k].secname; ++k ) { if(glftab[k].origset) { *(glftab[k].flag) = glftab[k].origflag; glftab[k].origset = FALSE; glftab[k].origflag = FALSE; } } } /* NEW May 2017. Has a side effect of using the local table set up by print_section_groups_data() and then frees the table data. For multi-object archive reading: main() calls groups_restore_subsidiary_flags() at the end of each object file to restore the original flags that turn_off_subsidiary_flags() changed. */ void update_section_flags_per_groups(Dwarf_Debug dbg) { if (!sec_names) { /* The tables are absent. Internal logic error here somewhere. */ freeall_groups_tables(); return; } if (selected_group == DW_GROUPNUMBER_BASE) { freeall_groups_tables(); return; } if (selected_group == DW_GROUPNUMBER_DWO) { freeall_groups_tables(); return; } turn_off_subsidiary_flags(dbg); freeall_groups_tables(); } /* NEW May 2017. Reports on section groupings like DWO(split dwarf) and COMDAT groups. As a side effect creates local table of section and group data */ void print_section_groups_data(Dwarf_Debug dbg) { int res = 0; Dwarf_Error error = 0; Dwarf_Unsigned i = 0; res = dwarf_sec_group_sizes(dbg,§ion_count, &group_count,&selected_group, &group_map_entry_count, &error); if(res != DW_DLV_OK) { print_error(dbg, "dwarf_sec_group_sizes", res, error); } if (group_count == 1 && selected_group ==1 ) { /* This is the traditional DWARF with no split-dwarf and no COMDAT data. We don't want to print anything as we do not want to see differences from existing output in this case. Simplifies regression testing for now. */ return; } printf("Section Groups data\n"); printf(" Number of Elf-like sections: %4" DW_PR_DUu "\n", section_count); printf(" Number of groups : %4" DW_PR_DUu "\n", group_count); printf(" Group to print : %4" DW_PR_DUu "\n", selected_group); printf(" Count of map entries : %4" DW_PR_DUu "\n", group_map_entry_count); sec_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if(!sec_nums) { printf("ERROR: Unable to allocate %4" DW_PR_DUu " map section values, cannot print group map\n", group_map_entry_count); return; } group_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if(!group_nums) { free(group_nums); printf("ERROR: Unable to allocate %4" DW_PR_DUu " map group values, cannot print group map\n", group_map_entry_count); return; } sec_names = calloc(group_map_entry_count,sizeof(char*)); if(!sec_names) { free(group_nums); free(sec_nums); printf("ERROR: Unable to allocate %4" DW_PR_DUu " section name pointers, cannot print group map\n", group_map_entry_count); return; } res = dwarf_sec_group_map(dbg,group_map_entry_count, group_nums,sec_nums,sec_names,&error); if(res != DW_DLV_OK) { print_error(dbg, "dwarf_sec_group_map", res, error); } for( i = 0; i < group_map_entry_count; ++i) { if (i == 0) { printf(" [index] group section\n"); } printf(" [%5" DW_PR_DUu "] " "%4" DW_PR_DUu " %4" DW_PR_DUu " %s\n",i, group_nums[i],sec_nums[i],sanitized(sec_names[i])); } /* Do not free our allocations. Will do later. */ return; } dwarfutils-20200114/dwarfdump/print_sections.c000066400000000000000000000063731361531463500213510ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "print_sections.h" #include "print_frames.h" /* Print line number information: filename new basic-block [line] [address] */ int dwarf_names_print_on_error = 1; /* referred in dwarfdump.c */ Dwarf_Die current_cu_die_for_print_frames; /* The April 2005 dwarf_get_section_max_offsets() in libdwarf returns all max-offsets, but we only want one of those offsets. This function returns the one we want from that set, making functions needing this offset as readable as possible. (avoiding code duplication). In case of error or missing section it returns a zero size, which seems appropriate. */ Dwarf_Unsigned get_info_max_offset(Dwarf_Debug dbg) { Dwarf_Unsigned debug_info_size = 0; Dwarf_Unsigned debug_abbrev_size = 0; Dwarf_Unsigned debug_line_size = 0; Dwarf_Unsigned debug_loc_size = 0; Dwarf_Unsigned debug_aranges_size = 0; Dwarf_Unsigned debug_macinfo_size = 0; Dwarf_Unsigned debug_pubnames_size = 0; Dwarf_Unsigned debug_str_size = 0; Dwarf_Unsigned debug_frame_size = 0; Dwarf_Unsigned debug_ranges_size = 0; Dwarf_Unsigned debug_pubtypes_size = 0; int res = 0; res = dwarf_get_section_max_offsets(dbg, &debug_info_size, &debug_abbrev_size, &debug_line_size, &debug_loc_size, &debug_aranges_size, &debug_macinfo_size, &debug_pubnames_size, &debug_str_size, &debug_frame_size, &debug_ranges_size, &debug_pubtypes_size); if (res != DW_DLV_OK) { return 0; } return debug_info_size; } /* Dumping a dwarf-expression as a byte stream. */ void dump_block(char *prefix, char *data, Dwarf_Signed len) { char *end_data = data + len; char *cur = data; int i = 0; printf("%s", prefix); for (; cur < end_data; ++cur, ++i) { if (i > 0 && i % 4 == 0) printf(" "); printf("%02x", 0xff & *cur); } } dwarfutils-20200114/dwarfdump/print_sections.h000066400000000000000000000026471361531463500213560ustar00rootroot00000000000000/* Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRINT_SECTIONS_H #define PRINT_SECTIONS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwarf_names_print_on_error; Dwarf_Unsigned get_info_max_offset(Dwarf_Debug dbg); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PRINT_SECTIONS_H */ dwarfutils-20200114/dwarfdump/print_static_funcs.c000066400000000000000000000066131361531463500222040ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* Get all the data in .debug_funcnames An SGI extension. (For a long time, erroneously called .debug_static_funcs here). On error, this allows some dwarf memory leaks. */ extern void print_static_funcs(Dwarf_Debug dbg) { Dwarf_Func *globbuf = NULL; Dwarf_Signed count = 0; int gfres = 0; Dwarf_Error err = 0; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s truename; struct esb_s sanitname; glflags.current_section_id = DEBUG_STATIC_FUNC; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_funcnames", &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ int res = 0; res = dwarf_return_empty_pubnames(dbg,1,&err); if (res != DW_DLV_OK) { printf("FAIL: Erroneous libdwarf call " "of dwarf_return_empty_pubnames: Fix dwarfdump"); return; } } gfres = dwarf_get_funcs(dbg, &globbuf, &count, &err); if (gfres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_funcs", gfres, err); } else if (gfres == DW_DLV_NO_ENTRY) { dwarf_return_empty_pubnames(dbg,0,&err); esb_destructor(&sanitname); return; } else { if (glflags.gf_do_print_dwarf && count > 0) { /* SGI specific so only mention if present. */ printf("\n%s\n",esb_get_string(&sanitname)); } print_all_pubnames_style_records(dbg, "static-func", esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, &err); dwarf_funcs_dealloc(dbg,globbuf,count); } dwarf_return_empty_pubnames(dbg,0,&err); esb_destructor(&sanitname); } /* print_static_funcs() */ dwarfutils-20200114/dwarfdump/print_static_vars.c000066400000000000000000000066271361531463500220460ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* Get all the data in .debug_varnames (an SGI extension) For a long time erroneously called .debug_static_vars bere. */ extern void print_static_vars(Dwarf_Debug dbg) { Dwarf_Var *globbuf = NULL; Dwarf_Signed count = 0; int res = 0; Dwarf_Error err = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s sanitname; glflags.current_section_id = DEBUG_STATIC_VARS; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_varnames", &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ res = dwarf_return_empty_pubnames(dbg,1,&err); if (res != DW_DLV_OK) { printf("FAIL: Erroneous libdwarf call " "of dwarf_return_empty_pubnames: Fix dwarfdump"); return; } } res = dwarf_get_vars(dbg, &globbuf, &count, &err); if (res == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_vars", res, err); } else if (res == DW_DLV_NO_ENTRY) { /* no static vars */ esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); return; } else { if (glflags.gf_do_print_dwarf && count > 0) { /* SGI specific so only mention if present. */ printf("\n%s\n",esb_get_string(&sanitname)); } print_all_pubnames_style_records(dbg, "static-var", esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, &err); esb_destructor(&sanitname); dwarf_vars_dealloc(dbg, globbuf, count); } dwarf_return_empty_pubnames(dbg,0,&err); esb_destructor(&sanitname); } /* print_static_vars */ dwarfutils-20200114/dwarfdump/print_str_offsets.c000066400000000000000000000132041361531463500220520ustar00rootroot00000000000000/* Copyright 2018-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" /* print data in .debug_str_offsets. There is no guarantee this will work because the DWARF5 standard is silent about whether arbitrary non-zero bytes, or odd alignments, or unused data spaces are allowed in the section */ void print_str_offsets_section(Dwarf_Debug dbg) { int res = 0; Dwarf_Str_Offsets_Table sot = 0; Dwarf_Unsigned wasted_byte_count = 0; Dwarf_Unsigned table_count = 0; Dwarf_Error error = 0; Dwarf_Unsigned tabnum = 0; res = dwarf_open_str_offsets_table_access(dbg, &sot,&error); if(res == DW_DLV_NO_ENTRY) { /* No such table */ return; } if(res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_open_str_offsets_table_access", res, error); return; } for(;; ++tabnum) { Dwarf_Unsigned unit_length =0; Dwarf_Unsigned unit_length_offset =0; Dwarf_Unsigned table_start_offset =0; Dwarf_Half entry_size = 0; Dwarf_Half version =0; Dwarf_Half padding =0; Dwarf_Unsigned table_value_count =0; Dwarf_Unsigned i = 0; Dwarf_Unsigned table_entry_value = 0; unsigned rowlim = 4; unsigned count_in_row = 0; res = dwarf_next_str_offsets_table(sot, &unit_length, &unit_length_offset, &table_start_offset, &entry_size,&version,&padding, &table_value_count,&error); if (res == DW_DLV_NO_ENTRY) { /* We have dealt with all tables */ break; } if (res == DW_DLV_ERROR) { print_error_and_continue(dbg, "dwarf_next_str_offsets_table", res,error); return; } if (tabnum == 0) { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_str_offsets", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } else { printf("\n"); } printf(" table %" DW_PR_DUu "\n",tabnum); printf(" tableheader 0x%" DW_PR_XZEROS DW_PR_DUx "\n", unit_length_offset); printf(" arrayoffset 0x%" DW_PR_XZEROS DW_PR_DUx "\n", table_start_offset); printf(" unit length 0x%" DW_PR_XZEROS DW_PR_DUx "\n", unit_length); printf(" entry size %u\n",entry_size); printf(" version %u\n",version); if (padding) { printf("Error: padding is non-zero. Something is wrong.\n"); } printf(" padding 0x%x\n",padding); printf(" arraysize %" DW_PR_DUu "\n",table_value_count); /* Lets print 4 per row. */ count_in_row = 0; for (i=0; i < table_value_count; ++i) { res = dwarf_str_offsets_value_by_index(sot,i, &table_entry_value,&error); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_next_str_offsets_table", res,error); return; } if (!count_in_row) { printf(" Entry [%4" DW_PR_DUu "]: ",i); } printf(" 0x%" DW_PR_XZEROS DW_PR_DUx , table_entry_value); ++count_in_row; if( count_in_row < rowlim) { continue; } printf("\n"); count_in_row = 0; } if (count_in_row) { printf("\n"); } res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, &table_count,&error); if (res == DW_DLV_OK) { printf(" wasted %" DW_PR_DUu " bytes\n", wasted_byte_count); } } if (wasted_byte_count) { res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, &table_count,&error); if (res == DW_DLV_OK) { printf(" finalwasted %" DW_PR_DUu " bytes\n", wasted_byte_count); } else { print_error_and_continue(dbg, "dwarf_open_str_offsets_statistics", res, error); return; } } res = dwarf_close_str_offsets_table_access(sot,&error); if (res != DW_DLV_OK) { print_error_and_continue(dbg, "dwarf_close_str_offsets_table_access", res, error); return; } sot = 0; } dwarfutils-20200114/dwarfdump/print_strings.c000066400000000000000000000056141361531463500212100ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2012 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" /* print data in .debug_str */ extern void print_strings(Dwarf_Debug dbg) { Dwarf_Signed length = 0; char* name = 0; Dwarf_Off offset = 0; int sres = 0; Dwarf_Error err = 0; unsigned loopct = 0; glflags.current_section_id = DEBUG_STR; #if 0 { struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_str", &truename,TRUE); printf("\n%s\n",sanitized(esb_get_string(&truename))); esb_destructor(&truename); } #endif for (loopct = 0; (sres = dwarf_get_str(dbg, offset, &name, &length, &err)) == DW_DLV_OK; ++loopct) { if (!loopct) { print_secname(dbg,".debug_str"); } if (glflags.gf_display_offsets) { printf("name at offset 0x%" DW_PR_XZEROS DW_PR_DUx ", length %4" DW_PR_DSd " is '%s'\n", (Dwarf_Unsigned)offset, length, sanitized(name)); } else { printf("name: length %4" DW_PR_DSd " is '%s'\n", length, sanitized(name)); } offset += length + 1; } if (!loopct) { print_secname(dbg,".debug_str"); } /* An inability to find the section is not necessarily a real error, so do not report error unless we've seen a real record. */ if (sres == DW_DLV_ERROR && offset != 0) { print_error(dbg, "dwarf_get_str failure", sres, err); } } dwarfutils-20200114/dwarfdump/print_types.c000066400000000000000000000077131361531463500206650ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "print_sections.h" #include "print_frames.h" #include "sanitized.h" /* Get all the data in .debug_typenames or debug_pubtypes. */ extern void print_types(Dwarf_Debug dbg, enum type_type_e type_type) { Dwarf_Type *globbuf = 0; Dwarf_Signed count = 0; char *name = 0; int gtres = 0; Dwarf_Error err = 0; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; struct esb_s sanitname; int (*get_types) (Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, Dwarf_Error *) = 0; void (*dealloctype) (Dwarf_Debug, Dwarf_Type *, Dwarf_Signed) = NULL; const char *linetitle = 0; /* We will, now only list either section when there is content. */ if (type_type == DWARF_PUBTYPES) { name = ".debug_pubtypes"; get_types = dwarf_get_pubtypes; dealloctype = dwarf_pubtypes_dealloc; linetitle = "pubtype"; } else { /* SGI_TYPENAME */ /* No need to get the real section name, this section not used in modern compilers. */ name = ".debug_typenames"; get_types = dwarf_get_types; dealloctype = dwarf_types_dealloc; linetitle = "type"; } esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,name, &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ int res = 0; res = dwarf_return_empty_pubnames(dbg,1,&err); if (res != DW_DLV_OK) { printf("FAIL: Erroneous libdwarf call " "of dwarf_return_empty_pubnames: Fix dwarfdump"); return; } } gtres = get_types(dbg, &globbuf, &count, &err); if (gtres == DW_DLV_ERROR) { print_error(dbg, sanitized(esb_get_string(&truename)), gtres, err); } else if (gtres == DW_DLV_NO_ENTRY) { /* no types */ esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); return; } else { if (glflags.gf_do_print_dwarf && count > 0) { printf("\n%s\n",esb_get_string(&sanitname)); } print_all_pubnames_style_records(dbg, linetitle, esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, &err); dealloctype(dbg, globbuf, count); } esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); } /* print_types() */ dwarfutils-20200114/dwarfdump/print_weaknames.c000066400000000000000000000064041361531463500214700ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2009-2011 SN Systems Ltd. All rights reserved. Portions Copyright 2008-2011 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "naming.h" #include "esb.h" #include "esb_using_functions.h" #include "sanitized.h" #include "print_sections.h" /* Get all the data in .debug_weaknames */ extern void print_weaknames(Dwarf_Debug dbg) { Dwarf_Weak *globbuf = NULL; Dwarf_Signed count = 0; int wkres = 0; Dwarf_Error err = 0; struct esb_s sanitname; struct esb_s truename; char buf[DWARF_SECNAME_BUFFER_SIZE]; glflags.current_section_id = DEBUG_WEAKNAMES; esb_constructor_fixed(&truename,buf,sizeof(buf)); get_true_section_name(dbg,".debug_weaknames", &truename,TRUE); { esb_constructor(&sanitname); /* Sanitized cannot be safely reused,there is a static buffer, so we make a safe copy. */ esb_append(&sanitname,sanitized(esb_get_string(&truename))); } esb_destructor(&truename); if (glflags.verbose) { /* For best testing! */ int res = 0; res = dwarf_return_empty_pubnames(dbg,1,&err); if (res != DW_DLV_OK) { printf("FAIL: Erroneous libdwarf call " "of dwarf_return_empty_pubnames: Fix dwarfdump"); return; } } wkres = dwarf_get_weaks(dbg, &globbuf, &count, &err); if (wkres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_weaks", wkres, err); } else if (wkres == DW_DLV_NO_ENTRY) { esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); /* no weaknames */ return; } else { if (glflags.gf_do_print_dwarf && count > 0) { /* SGI specific so only mention if present. */ printf("\n%s\n",esb_get_string(&sanitname)); } print_all_pubnames_style_records(dbg, "weakname", esb_get_string(&sanitname), (Dwarf_Global *)globbuf, count, &err); dwarf_weaks_dealloc(dbg, globbuf, count); } esb_destructor(&sanitname); dwarf_return_empty_pubnames(dbg,0,&err); } dwarfutils-20200114/dwarfdump/runtests.sh000077500000000000000000000141621361531463500203630ustar00rootroot00000000000000#!/bin/sh # # Intended to be run only on local machine. # Run in the dwarfdump directory # Run only after config.h created in a configure # in the source directory # Assumes env vars DWTOPSRCDIR set to the path to source. # Assumes CFLAGS warning stuff set in env var DWCOMPILERFLAGS # Assumes we run the script in the dwarfdump directory. top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/dwarfdump if [ x"$DWCOMPILERFLAGS" = 'x' ] then CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf -Wall -Wextra" echo "CFLAGS basic default default $CFLAGS" else CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf $DWCOMPILERFLAGS" echo "CFLAGS via configure $CFLAGS" fi goodcount=0 failcount=0 echo "TOP topsrc $top_srcdir topbld $top_blddir localsrc $srcdir" chkres() { r=$1 m=$2 if [ $r -ne 0 ] then echo "FAIL $m. Exit status for the test $r" failcount=`expr $failcount + 1` else goodcount=`expr $goodcount + 1` fi } which cc if [ $? -eq 0 ] then CC=cc else which gcc if [ $? -eq 0 ] then CC=gcc else # we will fail CC=cc fi fi #echo "dadebug cflags before runtests.sh sets it $CFLAGS" #CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf -Wall -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror" echo "dwgetopt test" $CC $CFLAGS -o getopttest $srcdir/getopttest.c $srcdir/dwgetopt.c chkres $? "compiling getopttest test" ./getopttest chkres $? "running getopttest" # we will want to know if windows if [ -f getopttest.exe ] then win=y else win=n fi rm -f getopttest getopttest.exe # The following tests are not really relevant: # we do not use system getopt in libdwarf etc. #echo "Now use system getopt to validate our tests" #$CC $CFLAGS -DGETOPT_FROM_SYSTEM -o getopttestnat $srcdir/getopttest.c $srcdir/dwgetopt.c #chkres $? "compiling getopttestnat " #./getopttestnat -c 1 #chkres $? "running getopttestnat -c 1 " #./getopttestnat -c 2 #chkres $? "running getopttestnat -c 2 " #./getopttestnat -c 3 #chkres $? "running getopttestnat -c 3 " #./getopttestnat -c 5 #chkres $? "running getopttestnat -c 5 " #./getopttestnat -c 6 #chkres $? "running getopttestnat -c 6 " #./getopttestnat -c 7 #chkres $? "running getopttestnat -c 7 " #./getopttestnat -c 8 #chkres $? "running getopttestnat -c 8 " #./getopttestnat -c 9 #chkres $? "running getopttestnat -c 9 " #./getopttestnat -c 10 #chkres $? "running getopttestnat -c 10 " #rm ./getopttestnat echo "start selfmakename" $CC $CFLAGS -c $srcdir/esb.c $srcdir/dwarf_tsearchbal.c chkres $? "compiling makename test" $CC -g $CFLAGS $srcdir/makename.c $srcdir/makename_test.c dwarf_tsearchbal.o esb.o -o selfmakename chkres $? "compiling selfmakename test" ./selfmakename chkres $? "running selfmakename " rm -f selfmakename selfmakename.exe echo "start selfhelpertree" $CC $CFLAGS -g $srcdir/helpertree_test.c $srcdir/helpertree.c dwarf_tsearchbal.o -o selfhelpertree chkres $? "compiling helpertree.c selfhelpertree" ./selfhelpertree chkres $? "running selfhelpertree " rm -f selfhelpertree selfhelpertree.exe echo "start selfmc" $CC -DSELFTEST $CFLAGS -g $srcdir/macrocheck.c dwarf_tsearchbal.o -o selfmc chkres $? "compiling macrocheck.c selfmc" ./selfmc chkres $? "running selfmc " rm -f ./selfmc selfmc.exe #echo "start selfesb" #$CC $CFLAGS $srcdir/testesb.c esb.o -o selfesb #chkres $? "compiling selfesb.c selfesb" #./selfesb #chkres $? "running selfesb " #rm -f ./selfesb selfesb.exe echo "start selfsetion_bitmaps" $CC $CFLAGS -g $srcdir/section_bitmaps_test.c $srcdir/section_bitmaps.c -o selfsection_bitmaps chkres $? "compiling bitmaps.c section_bitmaps" ./selfsection_bitmaps chkres $? "running selfsection_bitmaps " rm -f ./selfsection_bitmaps selfsection_bitmaps.exe echo "start selfprint_reloc" $CC $CFLAGS -DSELFTEST=1 -DTESTING=1 $srcdir/print_reloc_test.c esb.o -o selfprint_reloc chkres $? "compiling print_reloc.c selfprint_reloc" ./selfprint_reloc chkres $? "running selfprint_reloc " rm -f ./selfprint_reloc selfprint_reloc.exe # Remove the leading two lines for windows # as windows dwarfdump emits two leading lines # as compared to non-windows dwarfdump droptwoifwin() { i=$1 l=`wc -l < $i` if [ $l -gt 2 ] then l=`expr $l - 2` tail -$l <$i >junk.tmp cp junk.tmp $i fi } # The following stop after 400 lines to limit the size # of the data here. # It is a sanity check, not a full check. f=$srcdir/testobjLE32PE.exe b=$srcdir/testobjLE32PE.base t=junk.testsmallpe echo "start dwarfdump sanity check on pe $f" # Windows dwarfdump emits a couple prefix lines #we do not want. # So let dwarfdump emit more then trim. if [ x$win = "xy" ] then textlim=502 else textlim=500 fi ./dwarfdump $f | head -n $textlim > $t chkres $? "Running dwarfdump $f output to $t base $b" if [ x$win = "xy" ] then echo "drop two lines" droptwoifwin $t fi echo "if update required, mv $top_blddir/dwarfdump/$t $b" which dos2unix if [ $? -eq 0 ] then dos2unix $t fi diff $b $t > $t.diffjunk.testsmallpe.diff chkres $? "diff of $b $t" f=$srcdir/testuriLE64ELf.obj b=$srcdir/testuriLE64ELf.base t=junk.smallLE64ELf echo "start dwarfdump sanity check on $f" ./dwarfdump $f | head -n $textlim > $t chkres $? "running ./dwarfdump $f otuput to $t base $b " if [ x$win = "xy" ] then echo "drop two lines" droptwoifwin $t fi echo "if update required, mv $top_blddir/dwarfdump/$t $b" which dos2unix if [ $? -eq 0 ] then dos2unix $t fi diff $b $t > $t.diff chkres $? "diff of $b $t" f=$srcdir/test-mach-o-32.dSYM b=$srcdir/test-mach-o-32.base t=junk.macho-object32 echo "start dwarfdump sanity check on $f" ./dwarfdump $f | head -n $textlim > $t chkres $? "FAIL dwarfdump/runtests.sh ./dwarfdump $f to $t base $b " if [ x$win = "xy" ] then echo "drop two lines" droptwoifwin $t fi chkres $? "Running dwarfdump on $f" echo "if update required, mv $top_blddir/dwarfdump/$t $b" which dos2unix if [ $? -eq 0 ] then dos2unix $t fi diff $b $t > $t.diff chkres $? "dwarfdump/runtests.sh diff of $b $t" if [ $failcount -ne 0 ] then echo "FAIL $failcount dwarfdump/runtests.sh" exit 1 fi exit 0 dwarfutils-20200114/dwarfdump/sanitized.c000066400000000000000000000152611361531463500202740ustar00rootroot00000000000000/* Copyright 2016-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Definitions for TRUE, FALSE, etc. */ #include "defined_types.h" #include "esb.h" #include "sanitized.h" /* This does a uri-style conversion of control characters. So SOH prints as %01 for example. Which stops corrupted or crafted strings from doing things to the terminal the string is routed to. We do not translate an input % to %% (as in real uri) as that would be a bit confusing for most readers. The conversion makes it possble to print UTF-8 strings reproducibly, sort of (not showing the real glyph!). Only call this in a printf or sprintf, and only call it once in any single printf/sprintf. Othewise you will get bogus results and confusion. */ /* ASCII control codes: We leave newline as is, NUL is end of string, the others are translated. NUL Null 0 00 Ctrl-@ ^@ SOH Start of heading 1 01 Alt-1 Ctrl-A ^A STX Start of text 2 02 Alt-2 Ctrl-B ^B ETX End of text 3 03 Alt-3 Ctrl-C ^C EOT End of transmission 4 04 Alt-4 Ctrl-D ^D ENQ Enquiry 5 05 Alt-5 Ctrl-E ^E ACK Acknowledge 6 06 Alt-6 Ctrl-F ^F BEL Bell 7 07 Alt-7 Ctrl-G ^G BS Backspace 8 08 Alt-8 Ctrl-H ^H HT Horizontal tab 9 09 Alt-9 Ctrl-I ^I LF Line feed 10 0A Alt-10 Ctrl-J ^J VT Vertical tab 11 0B Alt-11 Ctrl-K ^K FF Form feed 12 0C Alt-12 Ctrl-L ^L CR Carriage return 13 0D Alt-13 Ctrl-M ^M SO Shift out 14 0E Alt-14 Ctrl-N ^N SI Shift in 15 0F Alt-15 Ctrl-O ^O DLE Data line escape 16 10 Alt-16 Ctrl-P ^P DC1 Device control 1 17 11 Alt-17 Ctrl-Q ^Q DC2 Device control 2 18 12 Alt-18 Ctrl-R ^R DC3 Device control 3 19 13 Alt-19 Ctrl-S ^S DC4 Device control 4 20 14 Alt-20 Ctrl-T ^T NAK Negative acknowledge 21 15 Alt-21 Ctrl-U ^U SYN Synchronous idle 22 16 Alt-22 Ctrl-V ^V ETB End transmission block 23 17 Alt-23 Ctrl-W ^W CAN Cancel 24 18 Alt-24 Ctrl-X ^X EM End of medium 25 19 Alt-25 Ctrl-Y ^Y SU Substitute 26 1A Alt-26 Ctrl-Z ^Z ES Escape 27 1B Alt-27 Ctrl-[ ^[ FS File separator 28 1C Alt-28 Ctrl-\ ^\ GS Group separator 29 1D Alt-29 Ctrl-] ^] RS Record separator 30 1E Alt-30 Ctrl-^ ^^ US Unit separator 31 1F Alt-31 Ctrl-_ ^_ In addition, characters decimal 141, 157, 127,128, 129 143,144,157 appear to be questionable too. Not in iso-8859-1 nor in html character entities list. We translate all strings with a % to do sanitizing and we change a literal ASCII '%' char to %27 so readers know any % is a sanitized char. We could double up a % into %% on output, but switching to %27 is simpler and for readers and prevents ambiguity. Since we do not handle utf-8 properly nor detect it we turn all non-ASCII to %xx below. */ static struct esb_s localesb = {0,0,0,0,0}; boolean no_sanitize_string_garbage = FALSE; /* do_sanity_insert() and no_questionable_chars() absolutely must have the same idea of questionable characters. Be Careful. */ static void do_sanity_insert( const char *s,struct esb_s *mesb) { const char *cp = s; for( ; *cp; cp++) { unsigned c = *cp & 0xff ; if (c == '%') { /* %xx for this too. Simple and unambiguous */ esb_append_printf(mesb, "%%%02x",c & 0xff); continue; } if (c >= 0x20 && c <=0x7e) { /* Usual case, ASCII printable characters. */ esb_appendn(mesb,cp,1); continue; } #ifdef _WIN32 if (c == 0x0D) { esb_appendn(mesb,cp,1); continue; } #endif /* _WIN32 */ if (c < 0x20) { esb_append_printf(mesb, "%%%02x",c & 0xff); continue; } /* ASSERT: (c >= 0x7f) */ /* ISO-8859 or UTF-8. Not handled well yet. */ esb_append_printf(mesb, "%%%02x",c & 0xff); } } /* This routine improves overall dwarfdump run times a lot by separating strings that might print badly from strings that will print fine. In one large test case it reduces run time from 140 seconds to 13 seconds. */ static int no_questionable_chars(const char *s) { const char *cp = s; for( ; *cp; cp++) { unsigned c = *cp & 0xff ; if (c == '%') { /* Always sanitize a % ASCII char. */ return FALSE; } if (c >= 0x20 && c <=0x7e) { /* Usual case, ASCII printable characters */ continue; } #ifdef _WIN32 if (c == 0x0D) { continue; } #endif /* _WIN32 */ if (c == 0x0A || c == 0x09 ) { continue; } if (c < 0x20) { return FALSE; } if (c >= 0x7f) { /* This notices iso-8859 and UTF-8 data as we don't deal with them properly in dwarfdump. */ return FALSE; } } return TRUE; } void sanitized_string_destructor(void) { esb_destructor(&localesb); } const char * sanitized(const char *s) { const char *sout = 0; if (no_sanitize_string_garbage) { return s; } if (no_questionable_chars(s)) { /* The original string is safe as is. */ return s; } /* Using esb_destructor is quite expensive in cpu time when we build the next sanitized string so we just empty the localesb. One reason it's expensive is that we do the appends in such small batches in do_sanity-insert(). */ esb_empty_string(&localesb); do_sanity_insert(s,&localesb); sout = esb_get_string(&localesb); return sout; } dwarfutils-20200114/dwarfdump/sanitized.h000066400000000000000000000037051361531463500203010ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SANITIZED_H #define SANITIZED_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Eliminate control characters from the input, leaving the input unchanged. Return pointer to an ephemeral location (only callfor printf, and only once per printf! */ const char * sanitized(const char *s); void sanitized_string_destructor(void); /* Set TRUE if you want to simply assume strings to be printed are safe to print. Leave FALSE if you want dangerous or unprintable characters to be switched to the character '?'. */ extern boolean no_sanitize_string_garbage; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* SANITIZED_H */ dwarfutils-20200114/dwarfdump/section_bitmaps.c000066400000000000000000000125221361531463500214620ustar00rootroot00000000000000/* Copyright (C) 2017-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" /* section_bitmaps.h and .c actually involved bits, bit shifting, and bit masks, but now the 'maps' are simple byte arrays. See reloc_map and section_map in command_options.c */ #include "section_bitmaps.h" struct section_map_s map_sectnames[DW_HDR_ARRAY_SIZE] = { {0,0}, {DW_SECTNAME_DEBUG_INFO, DW_HDR_DEBUG_INFO}, {DW_SECTNAME_DEBUG_INFO_DWO, DW_HDR_DEBUG_INFO_DWO}, {DW_SECTNAME_DEBUG_LINE, DW_HDR_DEBUG_LINE}, {DW_SECTNAME_DEBUG_LINE_DWO, DW_HDR_DEBUG_LINE_DWO}, {DW_SECTNAME_DEBUG_PUBNAMES, DW_HDR_DEBUG_PUBNAMES}, {DW_SECTNAME_DEBUG_ABBREV, DW_HDR_DEBUG_ABBREV}, {DW_SECTNAME_DEBUG_ABBREV_DWO, DW_HDR_DEBUG_ABBREV_DWO}, {DW_SECTNAME_DEBUG_ARANGES, DW_HDR_DEBUG_ARANGES}, {DW_SECTNAME_DEBUG_FRAME, DW_HDR_DEBUG_FRAME}, {DW_SECTNAME_DEBUG_LOC, DW_HDR_DEBUG_LOC}, {DW_SECTNAME_DEBUG_LOCLISTS, DW_HDR_DEBUG_LOCLISTS}, {DW_SECTNAME_DEBUG_LOCLISTS_DWO, DW_HDR_DEBUG_LOCLISTS_DWO}, {DW_SECTNAME_DEBUG_RANGES, DW_HDR_DEBUG_RANGES}, {DW_SECTNAME_DEBUG_RNGLISTS, DW_HDR_DEBUG_RNGLISTS}, {DW_SECTNAME_DEBUG_RNGLISTS_DWO, DW_HDR_DEBUG_RNGLISTS_DWO}, {DW_SECTNAME_DEBUG_STR, DW_HDR_DEBUG_STR}, {DW_SECTNAME_DEBUG_STR_DWO, DW_HDR_DEBUG_STR_DWO}, {DW_SECTNAME_DEBUG_STR_OFFSETS, DW_HDR_DEBUG_STR_OFFSETS}, {DW_SECTNAME_DEBUG_STR_OFFSETS_DWO, DW_HDR_DEBUG_STR_OFFSETS_DWO}, {DW_SECTNAME_DEBUG_PUBTYPES, DW_HDR_DEBUG_PUBTYPES}, {DW_SECTNAME_DEBUG_TYPES, DW_HDR_DEBUG_TYPES}, {DW_SECTNAME_TEXT, DW_HDR_TEXT}, {DW_SECTNAME_GDB_INDEX, DW_HDR_GDB_INDEX}, {DW_SECTNAME_EH_FRAME, DW_HDR_EH_FRAME}, {DW_SECTNAME_DEBUG_MACINFO, DW_HDR_DEBUG_MACINFO}, {DW_SECTNAME_DEBUG_MACRO, DW_HDR_DEBUG_MACRO}, {DW_SECTNAME_DEBUG_MACRO_DWO, DW_HDR_DEBUG_MACRO_DWO}, {DW_SECTNAME_DEBUG_NAMES, DW_HDR_DEBUG_NAMES}, {DW_SECTNAME_DEBUG_CU_INDEX, DW_HDR_DEBUG_CU_INDEX}, {DW_SECTNAME_DEBUG_TU_INDEX, DW_HDR_DEBUG_TU_INDEX}, {"Elf Header", DW_HDR_HEADER}, }; /* See section_bitmaps.c, .h Control section header printing. (not DWARF printing) */ static char reloc_map[DW_SECTION_REL_ARRAY_SIZE]; static char section_map[DW_HDR_ARRAY_SIZE]; static boolean all_sections_on; unsigned section_bitmap_array_size(void) { unsigned len = sizeof(map_sectnames)/sizeof(struct section_map_s); return len; } boolean section_name_is_debug_and_wanted(const char *section_name) { unsigned i = 1; if (all_sections_on) { return TRUE; } for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { if(!strcmp(section_name,map_sectnames[i].name) && section_map[map_sectnames[i].value]) { return TRUE; } } return FALSE; } /* For now defaults matches all but .text. */ void set_all_section_defaults(void) { unsigned i = 1; for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { section_map[i] = TRUE; } } void set_all_sections_on(void) { unsigned i = 1; all_sections_on = TRUE; for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { section_map[i] = TRUE; } } void set_all_reloc_sections_on(void) { unsigned i = 1; for ( ; i < DW_SECTION_REL_ARRAY_SIZE; ++i) { reloc_map[i] = TRUE; } } boolean any_section_header_to_print(void) { unsigned i = 1; for ( ; i < DW_HDR_HEADER; ++i) { if(section_map[i]) { return TRUE; } } return FALSE; } /* TRUE if the section map entry specified by the index has been enabled. */ boolean section_map_enabled(unsigned index) { if (index <= 0 || index >= DW_HDR_ARRAY_SIZE) return FALSE; return section_map[index]; } void enable_section_map_entry(unsigned index) { if (index > 0 && index < DW_HDR_ARRAY_SIZE) { section_map[index] = TRUE; } } /* TRUE if the reloc map entry specified by the index has been enabled. */ boolean reloc_map_enabled(unsigned index) { if (index <= 0 || index >= DW_SECTION_REL_ARRAY_SIZE) return FALSE; return reloc_map[index]; } void enable_reloc_map_entry(unsigned index) { if (index > 0 && index < DW_SECTION_REL_ARRAY_SIZE) { reloc_map[index] = TRUE; } } dwarfutils-20200114/dwarfdump/section_bitmaps.h000066400000000000000000000177221361531463500214760ustar00rootroot00000000000000/* Copyright (C) 2017-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef SECTION_BITMAPS_H_INCLUDED #define SECTION_BITMAPS_H_INCLUDED /* section_bitmaps.h and .c actually involved bits, bit shifting, and bit masks, but now the 'maps' are simple byte arrays. See reloc_map and section_map in dwarfdump.c */ /* Value is one of the DW_HDR_DEBUG_* names. */ struct section_map_s { const char *name; unsigned value; }; extern struct section_map_s map_sectnames[] ; #define DW_HDR_DEBUG_INFO 1 #define DW_HDR_DEBUG_INFO_DWO 2 #define DW_HDR_DEBUG_LINE 3 #define DW_HDR_DEBUG_LINE_DWO 4 #define DW_HDR_DEBUG_PUBNAMES 5 #define DW_HDR_DEBUG_ABBREV 6 #define DW_HDR_DEBUG_ABBREV_DWO 7 #define DW_HDR_DEBUG_ARANGES 8 #define DW_HDR_DEBUG_FRAME 9 #define DW_HDR_DEBUG_LOC 10 #define DW_HDR_DEBUG_LOCLISTS 11 #define DW_HDR_DEBUG_LOCLISTS_DWO 12 #define DW_HDR_DEBUG_RANGES 13 #define DW_HDR_DEBUG_RNGLISTS 14 #define DW_HDR_DEBUG_RNGLISTS_DWO 15 #define DW_HDR_DEBUG_STR 16 #define DW_HDR_DEBUG_STR_DWO 17 #define DW_HDR_DEBUG_STR_OFFSETS 18 #define DW_HDR_DEBUG_STR_OFFSETS_DWO 19 #define DW_HDR_DEBUG_PUBTYPES 20 #define DW_HDR_DEBUG_TYPES 21 #define DW_HDR_TEXT 22 #define DW_HDR_GDB_INDEX 23 #define DW_HDR_EH_FRAME 24 #define DW_HDR_DEBUG_MACINFO 25 #define DW_HDR_DEBUG_MACRO 26 #define DW_HDR_DEBUG_MACRO_DWO 27 #define DW_HDR_DEBUG_NAMES 28 #define DW_HDR_DEBUG_CU_INDEX 29 #define DW_HDR_DEBUG_TU_INDEX 30 #define DW_HDR_HEADER 31 #define DW_HDR_ARRAY_SIZE 32 /* Debug section names to be included in printing */ #define DW_SECTNAME_DEBUG_INFO ".debug_info" #define DW_SECTNAME_DEBUG_INFO_DWO ".debug_info.dwo" #define DW_SECTNAME_DEBUG_LINE ".debug_line" #define DW_SECTNAME_DEBUG_LINE_DWO ".debug_line.dwo" #define DW_SECTNAME_DEBUG_PUBNAMES ".debug_pubnames" #define DW_SECTNAME_DEBUG_ABBREV ".debug_abbrev" #define DW_SECTNAME_DEBUG_ABBREV_DWO ".debug_abbrev.dwo" #define DW_SECTNAME_DEBUG_ARANGES ".debug_aranges" #define DW_SECTNAME_DEBUG_FRAME ".debug_frame" #define DW_SECTNAME_DEBUG_LOC ".debug_loc" #define DW_SECTNAME_DEBUG_LOCLISTS ".debug_loclists" #define DW_SECTNAME_DEBUG_LOCLISTS_DWO ".debug_loclists.dwo" #define DW_SECTNAME_DEBUG_RANGES ".debug_ranges" #define DW_SECTNAME_DEBUG_RNGLISTS ".debug_rnglists" #define DW_SECTNAME_DEBUG_RNGLISTS_DWO ".debug_rnglists.dwo" #define DW_SECTNAME_DEBUG_STR ".debug_str" #define DW_SECTNAME_DEBUG_STR_DWO ".debug_str.dwo" #define DW_SECTNAME_DEBUG_STR_OFFSETS ".debug_str_offsets" #define DW_SECTNAME_DEBUG_STR_OFFSETS_DWO ".debug_str_offsets.dwo" /* obsolete SGI-only section was .debug_typenames */ #define DW_SECTNAME_DEBUG_PUBTYPES ".debug_pubtypes" #define DW_SECTNAME_DEBUG_TYPES ".debug_types" #define DW_SECTNAME_TEXT ".text" #define DW_SECTNAME_GDB_INDEX ".gdb_index" #define DW_SECTNAME_EH_FRAME ".eh_frame" #define DW_SECTNAME_DEBUG_SUP ".debug_sup" #define DW_SECTNAME_DEBUG_MACINFO ".debug_macinfo" #define DW_SECTNAME_DEBUG_MACRO ".debug_macro" #define DW_SECTNAME_DEBUG_MACRO_DWO ".debug_macro.dwo" #define DW_SECTNAME_DEBUG_NAMES ".debug_names" #define DW_SECTNAME_DEBUG_CU_INDEX ".debug_cu_index" #define DW_SECTNAME_DEBUG_TU_INDEX ".debug_tu_index" /* Definitions for printing relocations. */ #define DW_SECTION_REL_DEBUG_INFO 1 #define DW_SECTION_REL_DEBUG_LINE 2 #define DW_SECTION_REL_DEBUG_PUBNAMES 3 #define DW_SECTION_REL_DEBUG_ABBREV 4 #define DW_SECTION_REL_DEBUG_ARANGES 5 #define DW_SECTION_REL_DEBUG_FRAME 6 #define DW_SECTION_REL_DEBUG_LOC 7 #define DW_SECTION_REL_DEBUG_LOCLISTS 8 #define DW_SECTION_REL_DEBUG_RANGES 9 #define DW_SECTION_REL_DEBUG_RNGLISTS 10 #define DW_SECTION_REL_DEBUG_TYPES 11 #define DW_SECTION_REL_DEBUG_STR_OFFSETS 12 #define DW_SECTION_REL_DEBUG_PUBTYPES 13 #define DW_SECTION_REL_GDB_INDEX 14 #define DW_SECTION_REL_EH_FRAME 15 #define DW_SECTION_REL_DEBUG_SUP 16 #define DW_SECTION_REL_DEBUG_MACINFO 17 #define DW_SECTION_REL_DEBUG_MACRO 18 #define DW_SECTION_REL_DEBUG_NAMES 19 #define DW_SECTION_REL_ARRAY_SIZE 20 #define DW_SECTNAME_RELA_DEBUG_INFO ".rela.debug_info" #define DW_SECTNAME_RELA_DEBUG_LINE ".rela.debug_line" #define DW_SECTNAME_RELA_DEBUG_PUBNAMES ".rela.debug_pubnames" #define DW_SECTNAME_RELA_DEBUG_ABBREV ".rela.debug_abbrev" #define DW_SECTNAME_RELA_DEBUG_ARANGES ".rela.debug_aranges" #define DW_SECTNAME_RELA_DEBUG_FRAME ".rela.debug_frame" #define DW_SECTNAME_RELA_DEBUG_LOC ".rela.debug_loc" #define DW_SECTNAME_RELA_DEBUG_LOCLISTS ".rela.debug_loclists" #define DW_SECTNAME_RELA_DEBUG_RANGES ".rela.debug_ranges" #define DW_SECTNAME_RELA_DEBUG_RNGLISTS ".rela.debug_rnglists" #define DW_SECTNAME_RELA_DEBUG_TYPES ".rela.debug_types" #define DW_SECTNAME_RELA_DEBUG_STR_OFFSETS ".rela.debug_str_offsets" #define DW_SECTNAME_RELA_DEBUG_PUBTYPES ".rela.debug_pubtypes" #define DW_SECTNAME_RELA_GDB_INDEX ".rela.debug_gdb_index" #define DW_SECTNAME_RELA_EH_FRAME ".rela.eh_frame" #define DW_SECTNAME_RELA_DEBUG_SUP ".rela.debug_sup" #define DW_SECTNAME_RELA_DEBUG_MACINFO ".rela.debug_macinfo" #define DW_SECTNAME_RELA_DEBUG_MACRO ".rela.debug_macro" #define DW_SECTNAME_RELA_DEBUG_NAMES ".rela.debug_names" #define DW_SECTNAME_REL_DEBUG_INFO ".rel.debug_info" #define DW_SECTNAME_REL_DEBUG_LINE ".rel.debug_line" #define DW_SECTNAME_REL_DEBUG_PUBNAMES ".rel.debug_pubnames" #define DW_SECTNAME_REL_DEBUG_ABBREV ".rel.debug_abbrev" #define DW_SECTNAME_REL_DEBUG_ARANGES ".rel.debug_aranges" #define DW_SECTNAME_REL_DEBUG_FRAME ".rel.debug_frame" #define DW_SECTNAME_REL_DEBUG_LOC ".rel.debug_loc" #define DW_SECTNAME_REL_DEBUG_LOCLISTS ".rel.debug_loclists" #define DW_SECTNAME_REL_DEBUG_RANGES ".rel.debug_ranges" #define DW_SECTNAME_REL_DEBUG_RNGLISTS ".rel.debug_rnglists" #define DW_SECTNAME_REL_DEBUG_TYPES ".rel.debug_types" #define DW_SECTNAME_REL_DEBUG_STR_OFFSETS ".rel.debug_str_offsets" #define DW_SECTNAME_REL_DEBUG_PUBTYPES ".rel.debug_pubtypes" #define DW_SECTNAME_REL_GDB_INDEX ".rel.debug_gdb_index" #define DW_SECTNAME_REL_EH_FRAME ".rel.eh_frame" #define DW_SECTNAME_REL_DEBUG_SUP ".rel.debug_sup" #define DW_SECTNAME_REL_DEBUG_MACINFO ".rel.debug_macinfo" #define DW_SECTNAME_REL_DEBUG_MACRO ".rel.debug_macro" #define DW_SECTNAME_REL_DEBUG_NAMES ".rel.debug_names" boolean section_name_is_debug_and_wanted(const char *section_name); unsigned section_bitmap_array_size(void); void set_all_section_defaults(void); boolean any_section_header_to_print(void); void enable_section_map_entry(unsigned index); boolean section_map_enabled(unsigned index); void set_all_sections_on(void); void enable_reloc_map_entry(unsigned index); boolean reloc_map_enabled(unsigned index); void set_all_reloc_sections_on(void); #endif /* SECTION_BITMAPS_H_INCLUDED*/ dwarfutils-20200114/dwarfdump/section_bitmaps_test.c000066400000000000000000000041501361531463500225170ustar00rootroot00000000000000/* Copyright (C) 2017-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" /* section_bitmaps.h and .c actually involved bits, bit shifting, and bit masks, but now the 'maps' are simple byte arrays. See reloc_map and section_map in command_options.c */ #include "section_bitmaps.h" int main() { unsigned i = 1; unsigned arraycount = section_bitmap_array_size(); if (arraycount != DW_HDR_ARRAY_SIZE) { printf("FAIL map_sections.c sections array wrong size " "%u vs %u\n", arraycount,DW_HDR_ARRAY_SIZE); exit(1); } for ( ; i < DW_HDR_ARRAY_SIZE; ++i) { struct section_map_s * mp = map_sectnames+i; if (mp->value != i) { printf("FAIL map_sections.c at entry %s we have " "0x%x vs 0x%x" " mismatch\n", mp->name?mp->name:"value, i); exit(1); } if (!mp->name) { printf("FAIL map_sections.c at entry %u we have no name!\n",i); exit(1); } } printf("PASS section maps\n"); return 0; } dwarfutils-20200114/dwarfdump/strstrnocase.c000066400000000000000000000065651361531463500210430ustar00rootroot00000000000000/* Copyright (C) 2009-2016 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This tries to find the string 'contained' in the string 'container'. it returns true if found, else false. The comparisons are independent of case. Regrettably there is no generally accepted version that does this job, though GNU Linux has strcasestr() which does what we need. Our code here do not behave like strstr or strcasestr in the case of an empty 'contained' argument: we return FALSE (this case is not interesting for dwarfdump). There is a public domain stristr(). But given that dwarfdump is GPL, it would seem (IANAL) that we cannot mix public domain code into the release. The software here is independently written and indeed trivial. The POSIX function tolower() is only properly defined on unsigned char, hence the ugly casts. strstrnocase.c */ #include #include #include "globals.h" boolean is_strstrnocase(const char * container, const char * contained) { const unsigned char *ct = (const unsigned char *)container; for (; *ct; ++ct ) { const unsigned char * cntnd = (const unsigned char *)contained; for (; *cntnd && *ct ; ++cntnd,++ct) { unsigned char lct = tolower(*ct); unsigned char tlc = tolower(*cntnd); if (lct != tlc) { break; } } if (!*cntnd) { /* We matched all the way to end of contained */ /* ASSERT: innerwrong = FALSE */ return TRUE; } if (!*ct) { /* Ran out of container before contained, so no future match of contained is possible. */ return FALSE; } /* No match so far. See if there is more in container to check. */ } return FALSE; } #ifdef TEST static void test(const char *t1, const char *t2,int resexp) { boolean res = is_strstrnocase(t1,t2); if (res == resexp) { return; } printf("Error,mismatch %s and %s. Expected %d got %d\n", t1,t2,resexp,res); } int main() { test("aaaaa","a",1); test("aaaaa","b",0); test("abaaba","ba",1); test("abaaxa","x",1); test("abaabA","Ba",1); test("a","ab",0); test("b","c",0); test("b","",0); test("","c",0); test("","",0); test("aaaaa","aaaaaaaa",0); } #endif dwarfutils-20200114/dwarfdump/tag_attr.c000066400000000000000000000433011361531463500201030ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include #include #include /* For va_start va_arg va_list */ #include /* For errno declaration. */ #include "globals.h" #ifdef HAVE_UNISTD_H #include #endif #include /* For exit() declaration etc. */ #include "libdwarf.h" #include "common.h" #include "esb.h" #include "tag_common.h" #include "dwgetopt.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR,RELEASE DATE*/ boolean ellipsis = FALSE; /* So we can use dwarf_names.c */ /* Expected input format 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff ... The generated tag_attr_combination_table is used and generated quite differently for standard than for extended tags. For standard tags the generated table is indexed by tag number. All the columns are bit flags. For extended tags the generated table is indexed (call it j) by 0 - N-1 and [j][0] is the tag number and the rest of the columns (1 - N-1) are allowed attribute numbers. */ unsigned int tag_attr_combination_table[ATTR_TABLE_ROW_MAXIMUM][ATTR_TABLE_COLUMN_MAXIMUM]; #ifdef HAVE_USAGE_TAG_ATTR /* Working array for a specific tag and will contain its valid attributes */ static Dwarf_Half tag_attr_vector[DW_AT_last] = {0}; static Dwarf_Half tag_parents[DW_TAG_last] = {0}; static Dwarf_Half tag_children[DW_TAG_last] = {0}; static Dwarf_Small tag_attr_legal[DW_TAG_last] = {0}; #endif /* HAVE_USAGE_TAG_ATTR */ static const char *usage[] = { "Usage: tag_attr_build ", " -i input-table-path", " -o output-table-path", " -s (Generate standard attribute table)", " -e (Generate extended attribute table (common extensions))", "" }; const char *program_name = 0; char *input_name = 0; char *output_name = 0; int standard_flag = FALSE; int extended_flag = FALSE; /* process arguments */ static void process_args(int argc, char *argv[]) { int c = 0; boolean usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:se")) != EOF) { switch (c) { case 'i': input_name = dwoptarg; break; case 'o': output_name = dwoptarg; break; case 'e': extended_flag = TRUE; break; case 's': standard_flag = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(argv[0],usage); exit(FAILED); } } /* Two new naming routines May 2016. Instead of directly calling dwarf_get_*() When bad tag/attr numbers are presented we return a warning string through the pointer. The thought is that eventually someone will notice the error. It might, of course, be better to emit an error message and stop. */ static void ta_get_AT_name(unsigned int attrnum,const char **nameout) { int res = 0; res = dwarf_get_AT_name(attrnum,nameout); if (res == DW_DLV_OK) { return; } if (res == DW_DLV_NO_ENTRY) { *nameout = ""; return; } *nameout = ""; return; } static void ta_get_TAG_name(unsigned int tag,const char **nameout) { int res = 0; res = dwarf_get_TAG_name(tag,nameout); if (res == DW_DLV_OK) { return; } if (res == DW_DLV_NO_ENTRY) { *nameout = ""; return; } *nameout = ""; return; } static unsigned maxrowused = 0; static unsigned maxcolused = 0; /* The argument sizes are declared in tag_common.h, so the max usable is toprow-1 and topcol-1. */ static void check_unused_combo(unsigned toprow,unsigned topcol) { if ((toprow-1) != maxrowused) { printf("Providing for %u rows but used 0-%u\n", toprow,maxrowused); printf("Giving up\n"); exit(1); } if ((topcol-1) != maxcolused) { printf("Providing for %u cols but used 0-%u\n", topcol,maxcolused); printf("Giving up\n"); exit(1); } } static void validate_row_col(const char *position, unsigned crow, unsigned ccol, unsigned maxrow, unsigned maxcol) { if (crow >= ATTR_TABLE_ROW_MAXIMUM) { printf("error generating row in tag-attr array, %s " "current row: %u size of static array decl: %u\n", position,crow, ATTR_TABLE_ROW_MAXIMUM); exit(1); } if (crow >= maxrow) { printf("error generating row in tag-attr array, %s " "current row: %u max allowed: %u\n", position,crow,maxrow-1); exit(1); } if (ccol >= ATTR_TABLE_COLUMN_MAXIMUM) { printf("error generating column in tag-attr array, %s " "current col: %u size of static array decl: %u\n", position,ccol, ATTR_TABLE_COLUMN_MAXIMUM); exit(1); } if (ccol >= maxcol) { printf("error generating column in tag-attr array, %s " "current row: %u max allowed: %u\n", position,ccol,maxcol-1); exit(1); } if (crow > maxrowused) { maxrowused = crow; } if (ccol > maxcolused) { maxcolused = ccol; } return; } int main(int argc, char **argv) { unsigned u = 0; unsigned int num = 0; int input_eof = 0; unsigned table_rows = 0; unsigned table_columns = 0; unsigned current_row = 0; FILE * fileInp = 0; FILE * fileOut = 0; const char *aname = 0; unsigned int index = 0; print_version_details(argv[0],FALSE); print_args(argc,argv); process_args(argc,argv); if (!input_name ) { fprintf(stderr,"Input name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileInp = fopen(input_name,"r"); if (!fileInp) { fprintf(stderr,"Invalid input filename, could not open '%s'\n", input_name); print_usage_message(argv[0],usage); exit(FAILED); } if (!output_name ) { fprintf(stderr,"Output name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileOut = fopen(output_name,"w"); if (!fileOut) { fprintf(stderr,"Invalid output filename, could not open: '%s'\n", output_name); print_usage_message(argv[0],usage); exit(FAILED); } if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { fprintf(stderr,"Invalid table type\n"); fprintf(stderr,"Choose -e or -s .\n"); print_usage_message(argv[0],usage); exit(FAILED); } if (standard_flag) { table_rows = STD_ATTR_TABLE_ROWS; table_columns = STD_ATTR_TABLE_COLUMNS; } else { table_rows = EXT_ATTR_TABLE_ROWS; table_columns = EXT_ATTR_TABLE_COLS; } input_eof = read_value(&num,fileInp); /* 0xffffffff */ if (IS_EOF == input_eof) { bad_line_input("Empty input file"); } if (num != MAGIC_TOKEN_VALUE) { bad_line_input("Expected 0xffffffff"); } /* Generate main header, regardless of contents */ fprintf(fileOut,"/* Generated code, do not edit. */\n"); fprintf(fileOut,"/* Generated sourcedate %s */\n",DW_VERSION_DATE_STR); fprintf(fileOut,"\n/* BEGIN FILE */\n\n"); #ifdef HAVE_USAGE_TAG_ATTR /* Generate the data type to record the usage of the pairs tag-attr */ if (standard_flag) { fprintf(fileOut,"#ifndef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#define HAVE_USAGE_TAG_ATTR 1\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); fprintf(fileOut,"#ifdef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#include \"dwarf.h\"\n"); fprintf(fileOut,"#include \"libdwarf.h\"\n\n"); fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," unsigned int count; /* Attribute count */\n"); fprintf(fileOut," Dwarf_Half attr; /* Attribute value */\n"); fprintf(fileOut,"} Usage_Tag_Attr;\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ while (!feof(stdin)) { unsigned int tag; unsigned int curcol = 0; unsigned int cur_attr = 0; unsigned int attr; input_eof = read_value(&tag,fileInp); if (IS_EOF == input_eof) { /* Reached normal eof */ break; } if (standard_flag) { /* In standard case, the row indexed by tag */ if (tag >= table_rows ) { bad_line_input("tag %d exceeds standard table size",tag); } } else { /* In extended case, the row indexed by 0-N and column zero has the tag number. */ if (current_row >= table_rows) { bad_line_input("too many extended table rows. Have %u max %u", current_row,table_rows); } validate_row_col("Reading tag",current_row,0, table_rows,table_columns); tag_attr_combination_table[current_row][0] = tag; } input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly.."); } curcol = 1; cur_attr = 1; #ifdef HAVE_USAGE_TAG_ATTR /* Check if we have duplicated tags */ if (standard_flag) { if (tag_parents[tag]) { bad_line_input("tag 0x%02x value already defined",tag); } tag_parents[tag] = tag; /* Clear out the working attribute vector */ memset(tag_attr_vector,0,DW_AT_last * sizeof(Dwarf_Half)); } #endif /* HAVE_USAGE_TAG_ATTR */ while (num != MAGIC_TOKEN_VALUE) { struct esb_s msg_buf; esb_constructor(&msg_buf); if (standard_flag) { unsigned idx = num / BITS_PER_WORD; unsigned bit = num % BITS_PER_WORD; if (idx >= table_columns) { esb_append_printf(&msg_buf, "too many attributes a: table incomplete " "index %d cols %d.",idx,table_columns); bad_line_input(esb_get_string(&msg_buf)); } validate_row_col("Setting attr bit",tag,idx, table_rows,table_columns); tag_attr_combination_table[tag][idx] |= (((unsigned)1) << bit); } else { if (curcol >= table_columns) { esb_append_printf(&msg_buf, "too many attributes b: table incomplete " "index %d cols %d.",curcol,table_columns); bad_line_input(esb_get_string(&msg_buf)); } validate_row_col("Setting attr col",current_row,curcol, table_rows,table_columns); tag_attr_combination_table[current_row][curcol] = num; curcol++; } #ifdef HAVE_USAGE_TAG_ATTR /* Record the usage only for standard tables */ if (standard_flag) { /* Add attribute to current tag */ if (cur_attr >= DW_AT_last) { esb_empty_string(&msg_buf); esb_append_printf(&msg_buf, "too many attributes c: table incomplete " "index %d cols %d.",cur_attr,DW_AT_last); bad_line_input(esb_get_string(&msg_buf)); } /* Check for duplicated entries */ if (tag_attr_vector[cur_attr]) { bad_line_input("duplicated attributes: table incomplete."); } tag_attr_vector[cur_attr] = num; cur_attr++; } #endif /* HAVE_USAGE_TAG_ATTR */ esb_destructor(&msg_buf); input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly."); } } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the tag-attributes vector for current tag */ if (standard_flag) { if (tag >= DW_TAG_last) { bad_line_input("tag 0x%02x exceeds standard table size",tag); } if (tag_children[tag]) { bad_line_input("tag 0x%02x already defined",tag); } tag_children[tag] = tag; /* Generate reference vector */ aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut,"/* 0x%02x - %s */\n",tag,aname); fprintf(fileOut, "static Usage_Tag_Attr tag_attr_%02x[] = {\n",tag); for (index = 1; index < cur_attr; ++index) { attr = tag_attr_vector[index]; ta_get_AT_name(attr,&aname); fprintf(fileOut," {/* 0x%02x */ 0, %s},\n",attr,aname); } fprintf(fileOut," {/* %4s */ 0, 0}\n};\n\n"," "); /* Record allowed number of attributes */ tag_attr_legal[tag] = cur_attr - 1; } #endif /* HAVE_USAGE_TAG_ATTR */ ++current_row; } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the parent of the individual vectors */ check_unused_combo(table_rows,table_columns); if (standard_flag) { unsigned int tag; unsigned int legal; fprintf(fileOut, "static Usage_Tag_Attr *usage_tag_attr[] = {\n"); for (index = 0; index < DW_TAG_last; ++index) { tag = tag_children[index]; if (tag) { aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " tag_attr_%02x, /* 0x%02x - %s */\n",tag,tag,aname); } else { fprintf(fileOut," 0,\n"); } } fprintf(fileOut," 0\n};\n\n"); /* Generate table with allowed number of attributes */ fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," Dwarf_Small legal; /* Legal attributes */\n"); fprintf(fileOut," Dwarf_Small found; /* Found attributes */\n"); fprintf(fileOut,"} Rate_Tag_Attr;\n\n"); fprintf(fileOut, "static Rate_Tag_Attr rate_tag_attr[] = {\n"); for (tag = 0; tag < DW_TAG_last; ++tag) { if (tag_children[tag]) { legal = tag_attr_legal[tag]; aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " {%2d, 0, /* 0x%02x - %s */},\n",legal,tag,aname); } else { fprintf(fileOut," {0, 0},\n"); } } fprintf(fileOut," {0, 0}\n};\n\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ if (standard_flag) { fprintf(fileOut,"#define ATTR_TREE_ROW_COUNT %d\n\n",table_rows); fprintf(fileOut,"#define ATTR_TREE_COLUMN_COUNT %d\n\n",table_columns); fprintf(fileOut, "static unsigned int tag_attr_combination_table" "[ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = {\n"); } else { fprintf(fileOut,"/* Common extensions */\n"); fprintf(fileOut,"#define ATTR_TREE_EXT_ROW_COUNT %d\n\n",table_rows); fprintf(fileOut,"#define ATTR_TREE_EXT_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut, "static unsigned int tag_attr_combination_ext_table" "[ATTR_TREE_EXT_ROW_COUNT][ATTR_TREE_EXT_COLUMN_COUNT] = {\n"); } for (u = 0; u < table_rows; u++) { unsigned j = 0; const char *name = 0; if (standard_flag) { ta_get_TAG_name(u,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",u,name); } else { unsigned k = tag_attr_combination_table[u][0]; ta_get_TAG_name(k,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",k,name); } fprintf(fileOut," { "); for (j = 0; j < table_columns; ++j ) { fprintf(fileOut,"0x%08x,",tag_attr_combination_table[u][j]); } fprintf(fileOut,"},\n"); } fprintf(fileOut,"};\n"); fprintf(fileOut,"\n/* END FILE */\n"); fclose(fileInp); fclose(fileOut); return (0); } /* A fake so we can use dwarf_names.c */ void print_error (UNUSEDARG Dwarf_Debug dbg, UNUSEDARG const char * msg, UNUSEDARG int res, UNUSEDARG Dwarf_Error localerr) { } dwarfutils-20200114/dwarfdump/tag_attr.list000066400000000000000000000441061361531463500206400ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2015 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* Entries for DWARF5 should not be considered final until the DWARF5 standard is released. list for semantic check of tag-attr relation. 0xffffffff is a "punctuation." The final line of this file must be 0xffffffff. The next line after each 0xffffffff (except the final line) is a tag. The lines after this line before the next 0xffffffff are the attributes that can be given to the tag." For example, 0xffffffff DW_TAG_access_declaration DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_name DW_AT_sibling 0xffffffff means "only DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line, DW_AT_accessibility, DW_AT_name and DW_AT_sibling can be given to DW_TAG_access_declaration." Since DWARF standards are descriptive, not formally prescriptive (for the most part) compilers may add attributes that do not appear in this list. Corrections to the list are always appreciated. And for extensions, the file tag_attr_ext.list is the right place to put such so they do not provoke pointless warnings. This file is applied to the preprocessor, thus any C comment and preprocessor control line is available. */ 0xffffffff DW_TAG_access_declaration DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_description DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_array_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_bit_stride DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_ordering DW_AT_rank DW_AT_sibling DW_AT_specification DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_atomic_type /* DWARF5 */ DW_AT_alignment DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_base_type DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_binary_scale DW_AT_bit_offset DW_AT_bit_size DW_AT_byte_size DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_data_bit_offset DW_AT_data_location DW_AT_decimal_scale DW_AT_decimal_sign DW_AT_description DW_AT_digit_count DW_AT_encoding DW_AT_endianity DW_AT_name DW_AT_picture_string DW_AT_sibling DW_AT_small 0xffffffff DW_TAG_call_site /* DWARF5 */ DW_AT_call_column DW_AT_call_file DW_AT_call_line DW_AT_call_origin DW_AT_call_pc DW_AT_call_return_pc DW_AT_call_tail_call DW_AT_call_target DW_AT_call_target_clobbered DW_AT_type 0xffffffff DW_TAG_call_site_parameter /* DWARF5 */ DW_AT_call_data_location DW_AT_call_data_value DW_AT_call_parameter DW_AT_call_value DW_AT_location DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_catch_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_ranges DW_AT_segment DW_AT_sibling 0xffffffff DW_TAG_class_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_containing_type DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_visibility 0xffffffff DW_TAG_coarray_type /* DWARF5 */ DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_common_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_declaration DW_AT_description DW_AT_linkage_name DW_AT_location DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_visibility 0xffffffff DW_TAG_common_inclusion DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_common_reference DW_AT_declaration DW_AT_sibling DW_AT_visibility 0xffffffff DW_TAG_compile_unit DW_AT_addr_base DW_AT_base_types DW_AT_comp_dir DW_AT_dwo_id DW_AT_dwo_name DW_AT_entry_pc DW_AT_identifier_case DW_AT_high_pc DW_AT_language DW_AT_low_pc DW_AT_macro_info /* before DWARF5 */ DW_AT_macros /* DWARF5 */ DW_AT_main_subprogram DW_AT_name DW_AT_producer DW_AT_ranges DW_AT_rnglists_base DW_AT_segment DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_condition DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_const_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_constant DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_const_value DW_AT_declaration DW_AT_description DW_AT_endianity DW_AT_external DW_AT_linkage_name DW_AT_name DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_dwarf_procedure DW_AT_location 0xffffffff DW_TAG_dynamic_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_description DW_AT_name DW_AT_type DW_AT_sibling 0xffffffff DW_TAG_entry_point DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_address_class DW_AT_description DW_AT_frame_base DW_AT_linkage_name DW_AT_low_pc DW_AT_name DW_AT_return_addr DW_AT_segment DW_AT_sibling DW_AT_static_link DW_AT_type 0xffffffff DW_TAG_enumeration_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_bit_stride DW_AT_byte_size DW_AT_byte_stride DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_enum_class DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_enumerator DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_const_value DW_AT_description DW_AT_name DW_AT_sibling 0xffffffff DW_TAG_file_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_description DW_AT_name DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_formal_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_artificial DW_AT_const_value DW_AT_default_value DW_AT_description DW_AT_endianity DW_AT_is_optional DW_AT_location DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_type DW_AT_variable_parameter 0xffffffff DW_TAG_friend DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_friend DW_AT_sibling 0xffffffff DW_TAG_generic_subrange DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_bit_stride DW_AT_byte_size DW_AT_byte_stride DW_AT_count DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_lower_bound DW_AT_name DW_AT_sibling DW_AT_threads_scaled DW_AT_type DW_AT_upper_bound DW_AT_visibility 0xffffffff DW_TAG_imported_declaration DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_description DW_AT_import DW_AT_name DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_imported_module DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_import DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_imported_unit DW_AT_import 0xffffffff DW_TAG_inheritance DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_data_member_location DW_AT_sibling DW_AT_type DW_AT_virtuality 0xffffffff DW_TAG_inlined_subroutine DW_AT_abstract_origin DW_AT_call_column DW_AT_call_file DW_AT_call_line DW_AT_const_expr DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_ranges DW_AT_return_addr DW_AT_segment DW_AT_sibling DW_AT_start_scope DW_AT_trampoline 0xffffffff DW_TAG_interface_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_alignment DW_AT_description DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_start_scope 0xffffffff DW_TAG_label DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_description DW_AT_low_pc DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_lexical_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_description DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_name DW_AT_ranges DW_AT_segment DW_AT_sibling 0xffffffff DW_TAG_member DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_artificial DW_AT_bit_offset /* allowed in DWARF4 */ DW_AT_bit_size DW_AT_byte_size DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_const_value DW_AT_data_bit_offset DW_AT_data_member_location DW_AT_declaration DW_AT_description DW_AT_external DW_AT_mutable DW_AT_name DW_AT_sibling DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_module DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_declaration DW_AT_description DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_name DW_AT_priority DW_AT_ranges DW_AT_segment DW_AT_sibling DW_AT_specification DW_AT_visibility 0xffffffff DW_TAG_namelist DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_declaration DW_AT_name DW_AT_sibling DW_AT_visibility 0xffffffff DW_TAG_namelist_item DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_namelist_item DW_AT_sibling 0xffffffff DW_TAG_namespace DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_description DW_AT_export_symbols DW_AT_extension DW_AT_name DW_AT_sibling DW_AT_start_scope 0xffffffff DW_TAG_packed_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_partial_unit DW_AT_addr_base DW_AT_base_types DW_AT_comp_dir DW_AT_description DW_AT_dwo_id DW_AT_dwo_name DW_AT_entry_pc DW_AT_identifier_case DW_AT_high_pc DW_AT_language DW_AT_low_pc DW_AT_macro_info DW_AT_macros DW_AT_main_subprogram DW_AT_name DW_AT_producer DW_AT_ranges DW_AT_rnglists_base DW_AT_segment DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_pointer_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_address_class DW_AT_alignment DW_AT_bit_size /* DWARF4 */ DW_AT_byte_size DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_ptr_to_member_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_address_class DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_containing_type DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_type DW_AT_use_location DW_AT_visibility 0xffffffff DW_TAG_reference_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_address_class DW_AT_alignment DW_AT_bit_size /* DWARF4 */ DW_AT_byte_size DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_restrict_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_rvalue_reference_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_address_class /* DW_AT_allocated */ /* DW_AT_associated */ /* DW_AT_data_location */ DW_AT_name /* DW_AT_sibling */ DW_AT_type 0xffffffff DW_TAG_set_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_start_scope DW_AT_sibling DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_shared_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_allocated DW_AT_associated DW_AT_alignment DW_AT_count DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_string_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_start_scope DW_AT_string_length DW_AT_string_length_bit_size DW_AT_string_length_byte_size DW_AT_visibility 0xffffffff DW_TAG_structure_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_export_symbols DW_AT_linkage_name DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_visibility 0xffffffff DW_TAG_subprogram DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_address_class DW_AT_artificial DW_AT_calling_convention DW_AT_containing_type DW_AT_declaration DW_AT_description DW_AT_elemental DW_AT_entry_pc DW_AT_explicit DW_AT_external DW_AT_frame_base DW_AT_high_pc DW_AT_inline DW_AT_linkage_name DW_AT_low_pc DW_AT_main_subprogram DW_AT_name DW_AT_object_pointer DW_AT_prototyped DW_AT_pure DW_AT_ranges DW_AT_recursive DW_AT_reference DW_AT_return_addr DW_AT_rvalue_reference DW_AT_segment DW_AT_sibling DW_AT_specification DW_AT_start_scope DW_AT_static_link DW_AT_trampoline DW_AT_type DW_AT_visibility DW_AT_virtuality DW_AT_vtable_elem_location 0xffffffff DW_TAG_subrange_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_allocated DW_AT_associated DW_AT_bit_stride DW_AT_byte_size DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_stride DW_AT_count DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_lower_bound DW_AT_name DW_AT_sibling DW_AT_threads_scaled DW_AT_type DW_AT_upper_bound DW_AT_visibility 0xffffffff DW_TAG_subroutine_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_address_class DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_prototyped DW_AT_rvalue_reference DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_template_alias DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_template_type_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_default_value DW_AT_description DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_template_value_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_const_value DW_AT_default_value DW_AT_description DW_AT_location DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_thrown_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_try_block DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_entry_pc DW_AT_high_pc DW_AT_low_pc DW_AT_ranges DW_AT_segment DW_AT_sibling 0xffffffff DW_TAG_typedef DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_name DW_AT_sibling DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_type_unit DW_AT_language DW_AT_stmt_list DW_AT_str_offsets_base DW_AT_use_UTF8 0xffffffff DW_TAG_union_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_allocated DW_AT_associated DW_AT_bit_size /* Allowed in DWARF4 */ DW_AT_byte_size DW_AT_data_location DW_AT_declaration DW_AT_description DW_AT_export_symbols DW_AT_name DW_AT_sibling DW_AT_signature DW_AT_specification DW_AT_start_scope DW_AT_visibility 0xffffffff DW_TAG_unspecified_parameters DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_artificial DW_AT_sibling 0xffffffff DW_TAG_unspecified_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_description DW_AT_name /* DW_AT_sibling ? */ 0xffffffff DW_TAG_variable DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_alignment DW_AT_artificial DW_AT_byte_size DW_AT_bit_size DW_AT_const_expr DW_AT_const_value DW_AT_declaration DW_AT_description DW_AT_endianity DW_AT_external DW_AT_linkage_name DW_AT_location DW_AT_name DW_AT_segment DW_AT_sibling DW_AT_specification DW_AT_start_scope DW_AT_type DW_AT_visibility 0xffffffff DW_TAG_variant DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_accessibility DW_AT_abstract_origin DW_AT_declaration DW_AT_discr_list DW_AT_discr_value DW_AT_sibling 0xffffffff DW_TAG_variant_part DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_abstract_origin DW_AT_accessibility DW_AT_declaration DW_AT_discr DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_volatile_type DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line /* DW_AT_allocated ? */ /* DW_AT_associated ? */ /* DW_AT_data_location ? */ DW_AT_name DW_AT_sibling DW_AT_type 0xffffffff DW_TAG_with_stmt DW_AT_accessibility DW_AT_address_class DW_AT_declaration DW_AT_entry_pc DW_AT_high_pc DW_AT_location DW_AT_low_pc DW_AT_ranges DW_AT_segment DW_AT_sibling DW_AT_type DW_AT_visibility 0xffffffff dwarfutils-20200114/dwarfdump/tag_attr_ext.list000066400000000000000000000073561361531463500215260ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* list for semantic check of tag-attr relation. See tag_attr.list for details. Notes: If new top level TAGs are added/removed, update EXT_ATTR_TABLE_ROWS If new child TAGs are added/removed, update EXT_ATTR_TABLE_COLS EXT_ATTR_TABLE_ROWS is defined in tag_tree.c and specifies the maximum number of top level TAGs. Current value is 10. EXT_ATTR_TABLE_COLS is defined in tag_tree.c and specifies the maximum number of entries for the top level TAGs. Current value is 10. */ /* Common DWARF extensions */ 0xffffffff DW_TAG_structure_type DW_AT_containing_type 0xffffffff DW_TAG_compile_unit DW_AT_APPLE_optimized /* Used by LLVM */ DW_AT_GNU_dwo_id 0xffffffff DW_TAG_member DW_AT_GNU_guarded_by /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_pt_guarded_by /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_guarded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_pt_guarded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ 0xffffffff DW_TAG_array_type DW_AT_GNU_vector 0xffffffff DW_TAG_subprogram DW_AT_MIPS_linkage_name /* Used by GNU, SGI-IRIX, and others. */ DW_AT_MIPS_fde /* SGI-IRIX uses this */ DW_AT_GNU_locks_excluded /* gcc.gnu.org/wiki/ThreadSafetyAnnotationsInDWARF */ DW_AT_GNU_exclusive_locks_required DW_AT_GNU_shared_locks_required DW_AT_APPLE_omit_frame_ptr /* Used by LLVM */ DW_AT_APPLE_optimized /* Used by LLVM */ DW_AT_GNU_all_tail_call_sites DW_AT_GNU_all_call_sites 0xffffffff DW_TAG_variable DW_AT_MIPS_linkage_name /* Used by GNU, SGI-IRIX, and others. */ DW_AT_GNU_guarded_by DW_AT_GNU_pt_guarded_by DW_AT_GNU_guarded DW_AT_GNU_pt_guarded 0xffffffff DW_TAG_GNU_template_template_parameter DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name DW_AT_GNU_template_name DW_AT_GNU_guarded_by /* GNU changed the name of 0x2108! */ 0xffffffff DW_TAG_GNU_template_parameter_pack DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name 0xffffffff DW_TAG_GNU_formal_parameter_pack DW_AT_decl_column DW_AT_decl_file DW_AT_decl_line DW_AT_name 0xffffffff DW_TAG_GNU_call_site DW_AT_abstract_origin DW_AT_low_pc DW_AT_sibling DW_AT_GNU_tail_call 0xffffffff DW_TAG_GNU_call_site_parameter DW_AT_GNU_call_site_value DW_AT_abstract_origin DW_AT_location 0xffffffff DW_TAG_constant DW_AT_GNU_numerator DW_AT_GNU_denominator 0xffffffff DW_TAG_subrange_type DW_AT_GNU_bias 0xffffffff DW_TAG_inlined_subroutine DW_AT_GNU_discriminator /* Used by LLVM */ 0xffffffff DW_TAG_lexical_block 0xffffffff dwarfutils-20200114/dwarfdump/tag_common.c000066400000000000000000000100721361531463500204200ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include #include #include /* For va_start va_arg va_list */ #include /* For exit() declaration etc. */ #include /* For errno declaration. */ #include /* For isspace() declaration */ #include "globals.h" #include "naming.h" #include "tag_common.h" static int linecount = 0; static char line_in[MAX_LINE_SIZE]; void bad_line_input(char *format,...) { va_list ap; va_start(ap,format); fprintf(stderr, "tag_(tree,attr) table build failed, line %d: \"%s\". ", linecount, line_in); vfprintf(stderr,format, ap); /* "The object ap may be passed as an argument to another function; if that function invokes the va_arg() macro with parameter ap, the value of ap in the calling function is unspecified and shall be passed to the va_end() macro prior to any further reference to ap." Single Unix Specification. */ va_end(ap); fprintf(stderr,"\n"); exit(FAILED); } void trim_newline(char *line, int max) { char *end = line + max - 1; for (; *line && (line < end); ++line) { if (*line == '\n') { /* Found newline, drop it */ *line = 0; return; } } return; } /* Detect empty lines (and other lines we do not want to read) */ static boolean is_skippable_line(char *pLine) { boolean empty = TRUE; if (pLine[0] == '#') { /* Preprocessor lines are of no interest. */ return TRUE; } for (; *pLine && empty; ++pLine) { empty = isspace(*pLine); } return empty; } /* Reads a value from the text table. Exits with non-zero status if the table is erroneous in some way. */ int read_value(unsigned int *outval, FILE*file) { char *res = 0; unsigned long lval; char *strout = 0; boolean bBlankLine = TRUE; ++linecount; *outval = 0; while (bBlankLine) { res = fgets(line_in, sizeof(line_in), file); if (res == 0) { if (ferror(file)) { fprintf(stderr, "tag_attr: Error reading table, %d lines read\n", linecount); exit(FAILED); } if (feof(file)) { return IS_EOF; } /* Impossible */ fprintf(stderr, "tag_attr: Impossible error reading table, " "%d lines read\n", linecount); exit(FAILED); } bBlankLine = is_skippable_line(line_in); } trim_newline(line_in, sizeof(line_in)); errno = 0; lval = strtoul(line_in, &strout, 0); if (strout == line_in) { bad_line_input("bad number input!"); } if (errno != 0) { int myerr = errno; fprintf(stderr, "tag_attr errno %d\n", myerr); bad_line_input("invalid number on line"); } *outval = (int) lval; return NOT_EOF; } dwarfutils-20200114/dwarfdump/tag_common.h000066400000000000000000000076611361531463500204370ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2010 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2009-2016 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef tag_common_INCLUDED #define tag_common_INCLUDED /* The following is the magic token used to distinguish real tags/attrs from group-delimiters. Blank lines have been eliminated by an awk script. */ #define MAGIC_TOKEN_VALUE 0xffffffff /* These next two should match the last DW_TAG+1 and last DW_AT+1 in the standard set from dwarf.h */ #define DW_TAG_last 0x4a #define DW_AT_last 0x8a /* TAG_TREE.LIST Expected input format 0xffffffff value of a tag value of a standard tag that may be a child of that tag ... 0xffffffff value of a tag value of a standard tag that may be a child of that tag ... 0xffffffff ... No blank lines or commentary allowed, no symbols, just numbers. */ /* TAG_ATTR.LIST Expected input format 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff value of a tag value of a standard attribute that follows that tag ... 0xffffffff ... No blank lines or commentary allowed, no symbols, just numbers. */ /* We don't need really long lines: the input file is simple. */ #define MAX_LINE_SIZE 1000 /* 1 more than the highest number in the DW_TAG defines, this is for standard TAGs. Number of rows. */ #define STD_TAG_TABLE_ROWS 73 /* Enough entries to have a bit for each standard legal tag. */ #define STD_TAG_TABLE_COLUMNS 3 /* TAG tree common extension maximums. */ #define EXT_TAG_TABLE_ROWS 9 #define EXT_TAG_TABLE_COLS 5 /* The following 2 used in tag_tree.c only. They must be large enough but they are only used declaring array during build (not compiled into dwarfdump) so if a bit too large there is no side effect on anything. */ #define TAG_TABLE_ROW_MAXIMUM 80 #define TAG_TABLE_COLUMN_MAXIMUM 8 /* Number of attributes columns per tag. The array is bit fields, BITS_PER_WORD fields per word. Dense and quick to inspect */ #define COUNT_ATTRIBUTE_STD 7 #define STD_ATTR_TABLE_ROWS 74 #define STD_ATTR_TABLE_COLUMNS 5 /* tag/attr tree common extension maximums. */ #define EXT_ATTR_TABLE_ROWS 15 #define EXT_ATTR_TABLE_COLS 10 /* The following 2 used in tag_attr.c only. They must be large enough but they are only used declaring an array during build (not compiled into dwarfdump) so if a bit too large there is no side effect on anything. */ #define ATTR_TABLE_ROW_MAXIMUM 74 #define ATTR_TABLE_COLUMN_MAXIMUM 10 /* Bits per 'int' to mark legal attrs. */ #define BITS_PER_WORD 32 #define IS_EOF 1 #define NOT_EOF 0 extern void bad_line_input(char *format,...); extern void trim_newline(char *line, int max); extern boolean is_blank_line(char *pLine); extern int read_value(unsigned int *outval,FILE *f); /* Define to 1 to support the generation of tag-attr usage */ #define HAVE_USAGE_TAG_ATTR 1 #endif /* tag_common_INCLUDED */ dwarfutils-20200114/dwarfdump/tag_tree.c000066400000000000000000000403221361531463500200700ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2009-2017 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include /* For errno declaration. */ #ifdef HAVE_UNISTD_H #include #endif #include "common.h" #include "tag_common.h" #include "dwgetopt.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ unsigned int tag_tree_combination_table[TAG_TABLE_ROW_MAXIMUM][TAG_TABLE_COLUMN_MAXIMUM]; #ifdef HAVE_USAGE_TAG_ATTR /* Working array for a specific tag and its valid tags */ static Dwarf_Half tag_tree_vector[DW_TAG_last] = {0}; static Dwarf_Half tag_parents[DW_TAG_last] = {0}; static Dwarf_Half tag_children[DW_TAG_last] = {0}; static Dwarf_Small tag_tree_legal[DW_TAG_last] = {0}; #endif /* HAVE_USAGE_TAG_ATTR */ const char * program_name; boolean ellipsis = FALSE; /* So we can use dwarf_names.c */ /* Expected input format 0xffffffff value of a tag value of a standard tag that may be a child ofthat tag ... 0xffffffff value of a tag value of a standard tag that may be a child ofthat tag ... 0xffffffff ... No commentary allowed, no symbols, just numbers. Blank lines are allowed and are dropped. */ static const char *usage[] = { "Usage: tag_tree_build ", "options:\t-t\tGenerate Tags table", " -i Input-file-path", " -o Output-table-path", " -e (Want Extended table (common extensions))", " -s (Want Standard table)", "" }; static char *input_name = 0; static char *output_name = 0; int extended_flag = FALSE; int standard_flag = FALSE; static void process_args(int argc, char *argv[]) { int c = 0; boolean usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:es")) != EOF) { switch (c) { case 'i': input_name = (char *)strdup(dwoptarg); break; case 'o': output_name = (char *)strdup(dwoptarg); break; case 'e': extended_flag = TRUE; break; case 's': standard_flag = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(argv[0],usage); exit(FAILED); } } /* New naming routine May 2016. Instead of directly calling dwarf_get_*() When bad tag/attr numbers are presented we return a warning string through the pointer. The thought is that eventually someone will notice the error. It might, of course, be better to emit an error message and stop. */ static void ta_get_TAG_name(unsigned int tagnum,const char **nameout) { int res = 0; res = dwarf_get_TAG_name(tagnum,nameout); if (res == DW_DLV_OK) { return; } if (res == DW_DLV_NO_ENTRY) { *nameout = ""; return; } *nameout = ""; return; } /* these are used in assignments. */ static unsigned maxrowused = 0; static unsigned maxcolused = 0; /* The argument sizes are declared in tag_common.h, so the max usable is toprow-1 and topcol-1. */ static void check_unused_combo(unsigned toprow,unsigned topcol) { if ((toprow-1) != maxrowused) { printf("Providing for %u rows but used 0-%u\n", toprow,maxrowused); printf("Giving up\n"); exit(1); } if ((topcol-1) != maxcolused) { printf("Providing for %u cols but used 0-%u\n", topcol,maxcolused); printf("Giving up\n"); exit(1); } } static void validate_row_col(const char *position, unsigned crow, unsigned ccol, unsigned maxrow, unsigned maxcol) { if (crow >= TAG_TABLE_ROW_MAXIMUM) { printf("error generating row in tag-attr array, %s " "current row: %u size of static array decl: %u\n", position,crow, TAG_TABLE_ROW_MAXIMUM); exit(1); } if (crow >= maxrow) { printf("error generating row in tree tag array, %s " "current row: %u max allowed: %u\n", position,crow,maxrow-1); exit(1); } if (ccol >= TAG_TABLE_COLUMN_MAXIMUM) { printf("error generating column in tag-attr array, %s " "current col: %u size of static array decl: %u\n", position,ccol, TAG_TABLE_COLUMN_MAXIMUM); exit(1); } if (ccol >= maxcol) { printf("error generating column in tree tag array, %s " "current row: %u max allowed: %u\n", position,ccol,maxcol-1); exit(1); } if (crow > maxrowused) { maxrowused = crow; } if (ccol > maxcolused) { maxcolused = ccol; } return; } int main(int argc, char **argv) { unsigned u = 0; unsigned int num = 0; int input_eof = 0; unsigned table_rows = 0; unsigned table_columns = 0; unsigned current_row = 0; FILE *fileInp = 0; FILE *fileOut = 0; const char *aname = 0; unsigned int index = 0; print_version_details(argv[0],FALSE); print_args(argc,argv); process_args(argc,argv); if (!input_name ) { fprintf(stderr,"Input name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileInp = fopen(input_name,"r"); if (!fileInp) { fprintf(stderr,"Invalid input filename, could not open '%s'\n", input_name); print_usage_message(argv[0],usage); exit(FAILED); } if (!output_name ) { fprintf(stderr,"Output name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileOut = fopen(output_name,"w"); if (!fileOut) { fprintf(stderr,"Invalid output filename, could not open: '%s'\n", output_name); print_usage_message(argv[0],usage); exit(FAILED); } if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { fprintf(stderr,"Invalid table type\n"); fprintf(stderr,"Choose -e or -s .\n"); print_usage_message(argv[0],usage); exit(FAILED); } if (standard_flag) { table_rows = STD_TAG_TABLE_ROWS; table_columns = STD_TAG_TABLE_COLUMNS; } else { table_rows = EXT_TAG_TABLE_ROWS; table_columns = EXT_TAG_TABLE_COLS; } input_eof = read_value(&num,fileInp); /* 0xffffffff */ if (IS_EOF == input_eof) { bad_line_input("Empty input file"); } if (num != MAGIC_TOKEN_VALUE) { bad_line_input("Expected 0xffffffff"); } /* Generate main header, regardless of contents */ fprintf(fileOut,"/* Generated code, do not edit. */\n"); fprintf(fileOut,"/* Generated sourcedate %s */\n",DW_VERSION_DATE_STR ); fprintf(fileOut,"\n/* BEGIN FILE */\n\n"); #ifdef HAVE_USAGE_TAG_ATTR /* Generate the data type to record the usage of the pairs tag-tag */ if (standard_flag) { fprintf(fileOut,"#ifndef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#define HAVE_USAGE_TAG_ATTR 1\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); fprintf(fileOut,"#ifdef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#include \"dwarf.h\"\n"); fprintf(fileOut,"#include \"libdwarf.h\"\n\n"); fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," unsigned int count; /* Tag count */\n"); fprintf(fileOut," Dwarf_Half tag; /* Tag value */\n"); fprintf(fileOut,"} Usage_Tag_Tree;\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ while (!feof(stdin)) { unsigned int tag = 0; unsigned nTagLoc = 0; unsigned int cur_tag = 0; unsigned int child_tag; input_eof = read_value(&tag,fileInp); if (IS_EOF == input_eof) { /* Reached normal eof */ break; } if (standard_flag) { if (current_row >= table_rows ) { bad_line_input("tag value exceeds standard table size"); } } else { if (current_row >= table_rows) { bad_line_input("too many extended table rows."); } validate_row_col("Reading tag",current_row,0, table_rows,table_columns); tag_tree_combination_table[current_row][0] = tag; } input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly.."); } nTagLoc = 1; cur_tag = 1; #ifdef HAVE_USAGE_TAG_ATTR /* Check if we have duplicated tags */ if (standard_flag) { if (tag_parents[tag]) { bad_line_input("tag 0x%02x already defined",tag); } tag_parents[tag] = tag; /* Clear out the working attribute vector */ memset(tag_tree_vector,0,DW_TAG_last * sizeof(Dwarf_Half)); } #endif /* HAVE_USAGE_TAG_ATTR */ while (num != MAGIC_TOKEN_VALUE) { if (standard_flag) { unsigned idx = num / BITS_PER_WORD; unsigned bit = num % BITS_PER_WORD; if (idx >= table_columns) { fprintf(stderr,"Want column %d, have only %d\n", idx,table_columns); bad_line_input("too many TAGs: table incomplete."); } validate_row_col("Update columns bit",tag,idx, table_rows,table_columns); tag_tree_combination_table[tag][idx] |= (((unsigned)1) << bit); } else { if (nTagLoc >= table_columns) { printf("Attempting to use column %d, max is %d\n", nTagLoc,table_columns); bad_line_input("too many subTAGs, table incomplete."); } validate_row_col("Update tagloc",current_row,nTagLoc, table_rows,table_columns); tag_tree_combination_table[current_row][nTagLoc] = num; nTagLoc++; } #ifdef HAVE_USAGE_TAG_ATTR /* Record the usage only for standard tables */ if (standard_flag) { /* Add child tag to current tag */ if (cur_tag >= DW_TAG_last) { bad_line_input("too many TAGs: table incomplete."); } /* Check for duplicated entries */ if (tag_tree_vector[cur_tag]) { bad_line_input("duplicated tag: table incomplete."); } tag_tree_vector[cur_tag] = num; cur_tag++; } #endif /* HAVE_USAGE_TAG_ATTR */ input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly."); } } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the tag-tree vector for current tag */ if (standard_flag) { if (tag >= DW_TAG_last) { bad_line_input("tag value exceeds standard table size"); } if (tag_children[tag]) { bad_line_input("subtag 0x%02x already defined",tag); } tag_children[tag] = tag; /* Generate reference vector */ aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut,"/* 0x%02x - %s */\n",tag,aname); fprintf(fileOut, "static Usage_Tag_Tree tag_tree_%02x[] = {\n",tag); for (index = 1; index < cur_tag; ++index) { child_tag = tag_tree_vector[index]; ta_get_TAG_name(child_tag,&aname); fprintf(fileOut," {/* 0x%02x */ 0, %s},\n",child_tag,aname); } fprintf(fileOut," {/* %4s */ 0, 0}\n};\n\n"," "); /* Record allowed number of attributes */ tag_tree_legal[tag] = cur_tag - 1; } #endif /* HAVE_USAGE_TAG_ATTR */ ++current_row; /* for extended table */ } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the parent of the individual vectors */ if (standard_flag) { unsigned int tag = 0; unsigned int legal = 0; fprintf(fileOut, "static Usage_Tag_Tree *usage_tag_tree[] = {\n"); for (index = 0; index < DW_TAG_last; ++index) { tag = tag_children[index]; if (tag) { aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " tag_tree_%02x, /* 0x%02x - %s */\n",tag,tag,aname); } else { fprintf(fileOut," 0,\n"); } } fprintf(fileOut," 0\n};\n\n"); /* Generate table with allowed number of tags */ fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," Dwarf_Small legal; /* Legal tags */\n"); fprintf(fileOut," Dwarf_Small found; /* Found tags */\n"); fprintf(fileOut,"} Rate_Tag_Tree;\n\n"); fprintf(fileOut, "static Rate_Tag_Tree rate_tag_tree[] = {\n"); for (tag = 0; tag < DW_TAG_last; ++tag) { if (tag_children[tag]) { legal = tag_tree_legal[tag]; aname = 0; ta_get_TAG_name(tag,&aname); fprintf(fileOut, " {%2d, 0 /* 0x%02x - %s */},\n",legal,tag,aname); } else { fprintf(fileOut," {0, 0},\n"); } } fprintf(fileOut," {0, 0}\n};\n\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ check_unused_combo(table_rows, table_columns); if (standard_flag) { fprintf(fileOut,"#define TAG_TREE_COLUMN_COUNT %d\n\n",table_columns); fprintf(fileOut,"#define TAG_TREE_ROW_COUNT %d\n\n",table_rows); fprintf(fileOut, "static unsigned int tag_tree_combination_table" "[TAG_TREE_ROW_COUNT][TAG_TREE_COLUMN_COUNT] = {\n"); } else { fprintf(fileOut,"#define TAG_TREE_EXT_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut,"#define TAG_TREE_EXT_ROW_COUNT %d\n\n",table_rows); fprintf(fileOut,"/* Common extensions */\n"); fprintf(fileOut, "static unsigned int tag_tree_combination_ext_table" "[TAG_TREE_EXT_ROW_COUNT][TAG_TREE_EXT_COLUMN_COUNT] = {\n"); } for (u = 0; u < table_rows; u++) { unsigned j = 0; const char *name = 0; if (standard_flag) { ta_get_TAG_name(u,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",u, name); } else { unsigned k = tag_tree_combination_table[u][0]; ta_get_TAG_name(k,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n", k, name); } fprintf(fileOut," { "); for (j = 0; j < table_columns; ++j ) { fprintf(fileOut,"0x%08x,",tag_tree_combination_table[u][j]); } fprintf(fileOut,"},\n"); } fprintf(fileOut,"};\n"); fprintf(fileOut,"\n/* END FILE */\n"); fclose(fileInp); fclose(fileOut); return (0); } /* A fake so we can use dwarf_names.c */ void print_error (UNUSEDARG Dwarf_Debug dbg, UNUSEDARG const char *msg, UNUSEDARG int res, UNUSEDARG Dwarf_Error localerr) { } dwarfutils-20200114/dwarfdump/tag_tree.list000066400000000000000000000312351361531463500206240ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2012 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* list for semantic check of tag-tree. 0xffffffff is a "punctuation." The final line of this file must be 0xffffffff. The next line after each 0xffffffff (except the final line) stands for "parent-tag." The lines after this line before the next 0xffffffff are the tags that can be children of the "parent-tag." For example, 0xffffffff DW_TAG_array_type DW_TAG_subrange_type DW_TAG_enumeration_type 0xffffffff means "only DW_TAG_subrange_type and DW_TAG_enumeration_type can be children of DW_TAG_array_type. Since DWARF is generally descriptive, not prescriptive, this list is at best a current understanding of appropriate practice. Moreover the the dwarf standard does not actually list the tag-tag dependencies. So mistakes in the list below is certainly possible. Corrections and small-ish sample object files with unusual or interesting tag tree layouts are welcome. Any sample object files should not be proprietary as we may wish to include the object files in the regression test base. This file is applied to the preprocessor, thus any C comment and preprocessor control line is available. */ 0xffffffff DW_TAG_access_declaration 0xffffffff DW_TAG_array_type DW_TAG_subrange_type DW_TAG_dynamic_type DW_TAG_generic_subrange DW_TAG_enumeration_type 0xffffffff DW_TAG_base_type 0xffffffff DW_TAG_call_site DW_TAG_call_site_parameter 0xffffffff DW_TAG_call_site_parameter 0xffffffff DW_TAG_catch_block DW_TAG_formal_parameter DW_TAG_unspecified_parameters DW_TAG_array_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_base_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_class_type DW_TAG_member DW_TAG_inheritance DW_TAG_access_declaration DW_TAG_friend DW_TAG_ptr_to_member_type DW_TAG_subprogram DW_TAG_template_type_parameter /* template instantiations */ DW_TAG_template_value_parameter /* template instantiations */ DW_TAG_typedef DW_TAG_base_type DW_TAG_pointer_type DW_TAG_union_type DW_TAG_coarray_type DW_TAG_dynamic_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_class_type /* Nested classes */ DW_TAG_structure_type /* Nested structures */ DW_TAG_enumeration_type /* Nested enums */ DW_TAG_imported_declaration DW_TAG_template_alias /* C++ 2010 template alias */ 0xffffffff DW_TAG_coarray_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_dynamic_type DW_TAG_array_type DW_TAG_base_type 0xffffffff DW_TAG_common_block DW_TAG_variable 0xffffffff DW_TAG_common_inclusion 0xffffffff DW_TAG_compile_unit DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_dwarf_procedure DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_rvalue_reference_type DW_TAG_restrict_type /* Used by LLVM */ DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_common_block DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_namespace DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_imported_module DW_TAG_template_alias /* C++ 2010 template alias */ DW_TAG_unspecified_type 0xffffffff DW_TAG_type_unit DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_common_block DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_namespace DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_imported_module DW_TAG_template_alias /* C++ 2010 template alias */ 0xffffffff DW_TAG_condition /* COBOL */ DW_TAG_constant DW_TAG_subrange_type 0xffffffff DW_TAG_atomic_type 0xffffffff DW_TAG_const_type 0xffffffff DW_TAG_constant 0xffffffff DW_TAG_dwarf_procedure 0xffffffff DW_TAG_entry_point DW_TAG_formal_parameter DW_TAG_unspecified_parameters DW_TAG_common_inclusion 0xffffffff DW_TAG_enumeration_type DW_TAG_enumerator 0xffffffff DW_TAG_enumerator 0xffffffff DW_TAG_file_type 0xffffffff DW_TAG_formal_parameter 0xffffffff DW_TAG_friend 0xffffffff DW_TAG_imported_declaration 0xffffffff DW_TAG_imported_module 0xffffffff DW_TAG_imported_unit 0xffffffff DW_TAG_inheritance 0xffffffff DW_TAG_inlined_subroutine DW_TAG_formal_parameter DW_TAG_unspecified_parameters DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_lexical_block DW_TAG_typedef DW_TAG_union_type DW_TAG_inlined_subroutine DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_interface_type DW_TAG_member DW_TAG_subprogram 0xffffffff DW_TAG_label 0xffffffff DW_TAG_lexical_block DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_imported_module DW_TAG_label DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_inlined_subroutine DW_TAG_lexical_block DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_namelist DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_formal_parameter 0xffffffff DW_TAG_member 0xffffffff DW_TAG_module 0xffffffff DW_TAG_namelist DW_TAG_namelist_item 0xffffffff DW_TAG_namelist_item 0xffffffff DW_TAG_namespace DW_TAG_array_type DW_TAG_dynamic_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_common_block DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_namelist DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_namespace /* Allow a nested namespace */ DW_TAG_imported_module /* Allow imported module */ 0xffffffff DW_TAG_packed_type 0xffffffff DW_TAG_partial_unit DW_TAG_array_type DW_TAG_class_type DW_TAG_dynamic_type DW_TAG_enumeration_type DW_TAG_imported_declaration DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_common_block DW_TAG_inlined_subroutine DW_TAG_module DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_coarray_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type 0xffffffff DW_TAG_pointer_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_reference_type DW_TAG_restrict_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_ptr_to_member_type 0xffffffff DW_TAG_reference_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_restrict_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_rvalue_reference_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_restrict_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_restrict_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_set_type 0xffffffff DW_TAG_shared_type DW_TAG_atomic_type DW_TAG_const_type DW_TAG_packed_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_restrict_type DW_TAG_rvalue_reference_type DW_TAG_shared_type DW_TAG_volatile_type 0xffffffff DW_TAG_string_type 0xffffffff DW_TAG_structure_type DW_TAG_member DW_TAG_inheritance DW_TAG_access_declaration DW_TAG_friend DW_TAG_ptr_to_member_type DW_TAG_variant_part DW_TAG_subprogram DW_TAG_template_type_parameter /* template instantiations */ DW_TAG_template_value_parameter /* template instantiations */ DW_TAG_typedef DW_TAG_base_type DW_TAG_coarray_type DW_TAG_pointer_type DW_TAG_union_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_structure_type /* nested structures */ DW_TAG_enumeration_type /* nested enums */ DW_TAG_class_type /* nested classes */ DW_TAG_imported_declaration /* References to namespaces */ DW_TAG_template_alias /* C++ 2010 template alias */ 0xffffffff DW_TAG_subprogram DW_TAG_formal_parameter DW_TAG_unspecified_parameters DW_TAG_thrown_type DW_TAG_template_type_parameter DW_TAG_template_value_parameter DW_TAG_pointer_type DW_TAG_common_inclusion DW_TAG_common_block DW_TAG_array_type DW_TAG_coarray_type DW_TAG_class_type DW_TAG_enumeration_type DW_TAG_pointer_type DW_TAG_reference_type DW_TAG_string_type DW_TAG_lexical_block DW_TAG_structure_type DW_TAG_subroutine_type DW_TAG_typedef DW_TAG_union_type DW_TAG_inlined_subroutine DW_TAG_ptr_to_member_type DW_TAG_set_type DW_TAG_subrange_type DW_TAG_generic_subrange DW_TAG_base_type DW_TAG_const_type DW_TAG_atomic_type DW_TAG_constant DW_TAG_file_type DW_TAG_namelist DW_TAG_packed_type DW_TAG_subprogram DW_TAG_variable DW_TAG_volatile_type DW_TAG_label DW_TAG_imported_module /* References to namespaces */ DW_TAG_imported_declaration /* References to namespaces */ 0xffffffff DW_TAG_subrange_type 0xffffffff DW_TAG_generic_subrange 0xffffffff DW_TAG_subroutine_type DW_TAG_formal_parameter DW_TAG_typedef DW_TAG_unspecified_parameters 0xffffffff DW_TAG_template_type_parameter 0xffffffff DW_TAG_template_value_parameter 0xffffffff DW_TAG_thrown_type 0xffffffff DW_TAG_try_block 0xffffffff DW_TAG_typedef 0xffffffff DW_TAG_union_type DW_TAG_friend DW_TAG_member DW_TAG_class_type /* Nested classes */ DW_TAG_enumeration_type /* Nested enums */ DW_TAG_structure_type /* Nested structures */ DW_TAG_typedef /* Nested typedef */ DW_TAG_subprogram DW_TAG_template_type_parameter /* template instantiations */ DW_TAG_template_value_parameter /* template instantiations */ DW_TAG_union_type /* Nested unions */ 0xffffffff DW_TAG_template_alias DW_TAG_template_type_parameter DW_TAG_template_value_parameter 0xffffffff DW_TAG_unspecified_parameters 0xffffffff DW_TAG_unspecified_type 0xffffffff DW_TAG_variable 0xffffffff DW_TAG_variant DW_TAG_variant_part 0xffffffff DW_TAG_variant_part 0xffffffff DW_TAG_volatile_type 0xffffffff DW_TAG_with_stmt 0xffffffff dwarfutils-20200114/dwarfdump/tag_tree_ext.list000066400000000000000000000061661361531463500215110ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2009-2012 SN Systems Ltd. All rights reserved. Portions Copyright (C) 2009-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ #include /* list for semantic check of tag-tree relation. See tag_tree.list for details. Notes: If new top level TAGs are added/removed, update EXT_TAG_TABLE_ROWS If new child TAGs are added/removed, update EXT_TAG_TABLE_COLS EXT_TAG_TABLE_ROWS is defined in tag_tree.c and specifies the maximum number of top level TAGs. Current value is 8. EXT_TAG_TABLE_COLS is defined in tag_tree.c and specifies the maximum number of entries for the top level TAGs. Current value is 5. */ /* Common DWARF extensions */ 0xffffffff DW_TAG_structure_type DW_TAG_variable /* GNU gcc usage. */ DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_class_type DW_TAG_variable /* GNU gcc usage. */ DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_lexical_block DW_TAG_GNU_call_site 0xffffffff DW_TAG_subprogram DW_TAG_GNU_call_site DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_union_type DW_TAG_GNU_template_template_parameter /* template instantiations */ DW_TAG_GNU_template_parameter_pack /* variadic templates */ DW_TAG_GNU_formal_parameter_pack /* variadic templates */ 0xffffffff DW_TAG_inlined_subroutine DW_TAG_GNU_call_site 0xffffffff DW_TAG_GNU_call_site DW_TAG_GNU_call_site_parameter 0xffffffff DW_TAG_GNU_template_parameter_pack DW_TAG_template_type_parameter DW_TAG_template_value_parameter DW_TAG_GNU_template_template_parameter 0xffffffff DW_TAG_GNU_formal_parameter_pack DW_TAG_formal_parameter 0xffffffff dwarfutils-20200114/dwarfdump/test-mach-o-32.base000066400000000000000000000745151361531463500213440ustar00rootroot00000000000000 .debug_info COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit DW_AT_producer Apple LLVM version 8.0.0 (clang-800.0.42.1) DW_AT_language DW_LANG_C99 DW_AT_name /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_stmt_list 0x00000000 DW_AT_comp_dir /tmp/c/dwarf/gcc_m32 DW_AT_low_pc 0x000025c0 DW_AT_high_pc 0x00005b94 LOCAL_SYMBOLS: < 1><0x00000026> DW_TAG_variable DW_AT_name dumpallnamesfile DW_AT_type <0x00000038> DW_AT_external yes(1) DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000084 DW_AT_location DW_OP_addr 0x0005bc7c < 1><0x00000038> DW_TAG_pointer_type DW_AT_type <0x0000003d> < 1><0x0000003d> DW_TAG_typedef DW_AT_type <0x00000048> DW_AT_name FILE DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000099 < 1><0x00000048> DW_TAG_structure_type DW_AT_name __sFILE DW_AT_byte_size 0x00000058 DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007a < 2><0x00000050> DW_TAG_member DW_AT_name _p DW_AT_type <0x00000169> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007b DW_AT_data_member_location DW_OP_plus_uconst 0 < 2><0x0000005e> DW_TAG_member DW_AT_name _r DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007c DW_AT_data_member_location DW_OP_plus_uconst 4 < 2><0x0000006c> DW_TAG_member DW_AT_name _w DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007d DW_AT_data_member_location DW_OP_plus_uconst 8 < 2><0x0000007a> DW_TAG_member DW_AT_name _flags DW_AT_type <0x0000017c> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007e DW_AT_data_member_location DW_OP_plus_uconst 12 < 2><0x00000088> DW_TAG_member DW_AT_name _file DW_AT_type <0x0000017c> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000007f DW_AT_data_member_location DW_OP_plus_uconst 14 < 2><0x00000096> DW_TAG_member DW_AT_name _bf DW_AT_type <0x00000183> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000080 DW_AT_data_member_location DW_OP_plus_uconst 16 < 2><0x000000a4> DW_TAG_member DW_AT_name _lbfsize DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000081 DW_AT_data_member_location DW_OP_plus_uconst 24 < 2><0x000000b2> DW_TAG_member DW_AT_name _cookie DW_AT_type <0x000001a8> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000084 DW_AT_data_member_location DW_OP_plus_uconst 28 < 2><0x000000c0> DW_TAG_member DW_AT_name _close DW_AT_type <0x000001a9> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000085 DW_AT_data_member_location DW_OP_plus_uconst 32 < 2><0x000000ce> DW_TAG_member DW_AT_name _read DW_AT_type <0x000001ba> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000086 DW_AT_data_member_location DW_OP_plus_uconst 36 < 2><0x000000dc> DW_TAG_member DW_AT_name _seek DW_AT_type <0x000001e1> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000087 DW_AT_data_member_location DW_OP_plus_uconst 40 < 2><0x000000ea> DW_TAG_member DW_AT_name _write DW_AT_type <0x00000224> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000088 DW_AT_data_member_location DW_OP_plus_uconst 44 < 2><0x000000f8> DW_TAG_member DW_AT_name _ub DW_AT_type <0x00000183> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000008b DW_AT_data_member_location DW_OP_plus_uconst 48 < 2><0x00000106> DW_TAG_member DW_AT_name _extra DW_AT_type <0x00000249> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000008c DW_AT_data_member_location DW_OP_plus_uconst 56 < 2><0x00000114> DW_TAG_member DW_AT_name _ur DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000008d DW_AT_data_member_location DW_OP_plus_uconst 60 < 2><0x00000122> DW_TAG_member DW_AT_name _ubuf DW_AT_type <0x00000254> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000090 DW_AT_data_member_location DW_OP_plus_uconst 64 < 2><0x00000130> DW_TAG_member DW_AT_name _nbuf DW_AT_type <0x00000267> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000091 DW_AT_data_member_location DW_OP_plus_uconst 67 < 2><0x0000013e> DW_TAG_member DW_AT_name _lb DW_AT_type <0x00000183> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000094 DW_AT_data_member_location DW_OP_plus_uconst 68 < 2><0x0000014c> DW_TAG_member DW_AT_name _blksize DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000097 DW_AT_data_member_location DW_OP_plus_uconst 76 < 2><0x0000015a> DW_TAG_member DW_AT_name _offset DW_AT_type <0x000001fc> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000098 DW_AT_data_member_location DW_OP_plus_uconst 80 < 1><0x00000169> DW_TAG_pointer_type DW_AT_type <0x0000016e> < 1><0x0000016e> DW_TAG_base_type DW_AT_name unsigned char DW_AT_encoding DW_ATE_unsigned_char DW_AT_byte_size 0x00000001 < 1><0x00000175> DW_TAG_base_type DW_AT_name int DW_AT_encoding DW_ATE_signed DW_AT_byte_size 0x00000004 < 1><0x0000017c> DW_TAG_base_type DW_AT_name short DW_AT_encoding DW_ATE_signed DW_AT_byte_size 0x00000002 < 1><0x00000183> DW_TAG_structure_type DW_AT_name __sbuf DW_AT_byte_size 0x00000008 DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000058 < 2><0x0000018b> DW_TAG_member DW_AT_name _base DW_AT_type <0x00000169> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x00000059 DW_AT_data_member_location DW_OP_plus_uconst 0 < 2><0x00000199> DW_TAG_member DW_AT_name _size DW_AT_type <0x00000175> DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000005a DW_AT_data_member_location DW_OP_plus_uconst 4 < 1><0x000001a8> DW_TAG_pointer_type < 1><0x000001a9> DW_TAG_pointer_type DW_AT_type <0x000001ae> < 1><0x000001ae> DW_TAG_subroutine_type DW_AT_type <0x00000175> DW_AT_prototyped yes(1) < 2><0x000001b4> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 1><0x000001ba> DW_TAG_pointer_type DW_AT_type <0x000001bf> < 1><0x000001bf> DW_TAG_subroutine_type DW_AT_type <0x00000175> DW_AT_prototyped yes(1) < 2><0x000001c5> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 2><0x000001ca> DW_TAG_formal_parameter DW_AT_type <0x000001d5> < 2><0x000001cf> DW_TAG_formal_parameter DW_AT_type <0x00000175> < 1><0x000001d5> DW_TAG_pointer_type DW_AT_type <0x000001da> < 1><0x000001da> DW_TAG_base_type DW_AT_name char DW_AT_encoding DW_ATE_signed_char DW_AT_byte_size 0x00000001 < 1><0x000001e1> DW_TAG_pointer_type DW_AT_type <0x000001e6> < 1><0x000001e6> DW_TAG_subroutine_type DW_AT_type <0x000001fc> DW_AT_prototyped yes(1) < 2><0x000001ec> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 2><0x000001f1> DW_TAG_formal_parameter DW_AT_type <0x000001fc> < 2><0x000001f6> DW_TAG_formal_parameter DW_AT_type <0x00000175> < 1><0x000001fc> DW_TAG_typedef DW_AT_type <0x00000207> DW_AT_name fpos_t DW_AT_decl_file 0x00000001 /usr/include/stdio.h DW_AT_decl_line 0x0000004d < 1><0x00000207> DW_TAG_typedef DW_AT_type <0x00000212> DW_AT_name __darwin_off_t DW_AT_decl_file 0x00000003 /usr/include/sys/_types.h DW_AT_decl_line 0x00000047 < 1><0x00000212> DW_TAG_typedef DW_AT_type <0x0000021d> DW_AT_name __int64_t DW_AT_decl_file 0x00000002 /usr/include/i386/_types.h DW_AT_decl_line 0x0000002e < 1><0x0000021d> DW_TAG_base_type DW_AT_name long long int DW_AT_encoding DW_ATE_signed DW_AT_byte_size 0x00000008 < 1><0x00000224> DW_TAG_pointer_type DW_AT_type <0x00000229> < 1><0x00000229> DW_TAG_subroutine_type DW_AT_type <0x00000175> DW_AT_prototyped yes(1) < 2><0x0000022f> DW_TAG_formal_parameter DW_AT_type <0x000001a8> < 2><0x00000234> DW_TAG_formal_parameter DW_AT_type <0x0000023f> < 2><0x00000239> DW_TAG_formal_parameter DW_AT_type <0x00000175> < 1><0x0000023f> DW_TAG_pointer_type DW_AT_type <0x00000244> < 1><0x00000244> DW_TAG_const_type DW_AT_type <0x000001da> < 1><0x00000249> DW_TAG_pointer_type DW_AT_type <0x0000024e> < 1><0x0000024e> DW_TAG_structure_type DW_AT_name __sFILEX DW_AT_declaration yes(1) < 1><0x00000254> DW_TAG_array_type DW_AT_type <0x0000016e> < 2><0x00000259> DW_TAG_subrange_type DW_AT_type <0x00000260> DW_AT_count 0x00000003 < 1><0x00000260> DW_TAG_base_type DW_AT_name sizetype DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_unsigned < 1><0x00000267> DW_TAG_array_type DW_AT_type <0x0000016e> < 2><0x0000026c> DW_TAG_subrange_type DW_AT_type <0x00000260> DW_AT_count 0x00000001 < 1><0x00000273> DW_TAG_variable DW_AT_name cu_version_stamp DW_AT_type <0x00000175> DW_AT_external yes(1) DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000091 DW_AT_location DW_OP_addr 0x0005bc80 < 1><0x00000285> DW_TAG_variable DW_AT_name cu_offset_size DW_AT_type <0x00000175> DW_AT_external yes(1) DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000092 DW_AT_location DW_OP_addr 0x0005bc84 < 1><0x00000297> DW_TAG_variable DW_AT_name namesoptionon DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000081 DW_AT_location DW_OP_addr 0x0005bc98 < 1><0x000002a8> DW_TAG_variable DW_AT_name dupstrused DW_AT_type <0x000002b9> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000000a5 DW_AT_location DW_OP_addr 0x0005bcbc < 1><0x000002b9> DW_TAG_base_type DW_AT_name unsigned int DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 0x00000004 < 1><0x000002c0> DW_TAG_variable DW_AT_name dupstrarray DW_AT_type <0x000002d1> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x000000a4 DW_AT_location DW_OP_addr 0x0005bcc0 < 1><0x000002d1> DW_TAG_array_type DW_AT_type <0x0000023f> < 2><0x000002d6> DW_TAG_subrange_type DW_AT_type <0x00000260> DW_AT_count 0x00000064 < 1><0x000002dd> DW_TAG_variable DW_AT_name dumpallnamespath DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000085 DW_AT_location DW_OP_addr 0x0005bc9c < 1><0x000002ee> DW_TAG_variable DW_AT_name dumpallnames DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000083 DW_AT_location DW_OP_addr 0x0005bca0 < 1><0x000002ff> DW_TAG_variable DW_AT_name checkoptionon DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000082 DW_AT_location DW_OP_addr 0x0005bca4 < 1><0x00000310> DW_TAG_variable DW_AT_name tuhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009c DW_AT_location DW_OP_addr 0x0005bca8 < 1><0x00000321> DW_TAG_variable DW_AT_name cuhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009b DW_AT_location DW_OP_addr 0x0005bcac < 1><0x00000332> DW_TAG_variable DW_AT_name tufissionhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009e DW_AT_location DW_OP_addr 0x0005bcb0 < 1><0x00000343> DW_TAG_variable DW_AT_name cufissionhash DW_AT_type <0x0000023f> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000009d DW_AT_location DW_OP_addr 0x0005bcb4 < 1><0x00000354> DW_TAG_variable DW_AT_name passnullerror DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000098 DW_AT_location DW_OP_addr 0x0005bcb8 < 1><0x00000365> DW_TAG_variable DW_AT_name g_is_info DW_AT_type <0x00000376> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000008f DW_AT_location DW_OP_addr 0x0005b458 < 1><0x00000376> DW_TAG_typedef DW_AT_type <0x00000175> DW_AT_name Dwarf_Bool DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x0000005e < 1><0x00000381> DW_TAG_variable DW_AT_name unittype DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000008e DW_AT_location DW_OP_addr 0x0005b45c < 1><0x00000392> DW_TAG_variable DW_AT_name fissionfordie DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000097 DW_AT_location DW_OP_addr 0x0005b460 < 1><0x000003a3> DW_TAG_variable DW_AT_name stdrun DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x0000008c DW_AT_location DW_OP_addr 0x0005b464 < 1><0x000003b4> DW_TAG_variable DW_AT_name dienumber DW_AT_type <0x00000175> DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000096 DW_AT_location DW_OP_addr 0x0005be50 < 1><0x000003c5> DW_TAG_enumeration_type DW_AT_name Dwarf_Form_Class DW_AT_byte_size 0x00000004 DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x00000596 < 2><0x000003ce> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_UNKNOWN DW_AT_const_value 0x00000000 < 2><0x000003d4> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_ADDRESS DW_AT_const_value 0x00000001 < 2><0x000003da> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_BLOCK DW_AT_const_value 0x00000002 < 2><0x000003e0> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_CONSTANT DW_AT_const_value 0x00000003 < 2><0x000003e6> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_EXPRLOC DW_AT_const_value 0x00000004 < 2><0x000003ec> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_FLAG DW_AT_const_value 0x00000005 < 2><0x000003f2> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LINEPTR DW_AT_const_value 0x00000006 < 2><0x000003f8> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LOCLISTPTR DW_AT_const_value 0x00000007 < 2><0x000003fe> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_MACPTR DW_AT_const_value 0x00000008 < 2><0x00000404> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_RANGELISTPTR DW_AT_const_value 0x00000009 < 2><0x0000040a> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_REFERENCE DW_AT_const_value 0x0000000a < 2><0x00000410> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_STRING DW_AT_const_value 0x0000000b < 2><0x00000416> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_FRAMEPTR DW_AT_const_value 0x0000000c < 2><0x0000041c> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_MACROPTR DW_AT_const_value 0x0000000d < 2><0x00000422> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_ADDRPTR DW_AT_const_value 0x0000000e < 2><0x00000428> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LOCLIST DW_AT_const_value 0x0000000f < 2><0x0000042e> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_LOCLISTSPTR DW_AT_const_value 0x00000010 < 2><0x00000434> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_RNGLIST DW_AT_const_value 0x00000011 < 2><0x0000043a> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_RNGLISTSPTR DW_AT_const_value 0x00000012 < 2><0x00000440> DW_TAG_enumerator DW_AT_name DW_FORM_CLASS_STROFFSETSPTR DW_AT_const_value 0x00000013 < 1><0x00000447> DW_TAG_typedef DW_AT_type <0x000001a8> DW_AT_name Dwarf_Ptr DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x00000076 < 1><0x00000452> DW_TAG_typedef DW_AT_type <0x0000045d> DW_AT_name Dwarf_Unsigned DW_AT_decl_file 0x00000005 /tmp/c/tmp/dwarf-20170709/libdwarf/libdwarf.h DW_AT_decl_line 0x00000060 < 1><0x0000045d> DW_TAG_base_type DW_AT_name long long unsigned int DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 0x00000008 < 1><0x00000464> DW_TAG_subprogram DW_AT_low_pc 0x000025c0 DW_AT_high_pc 0x000034d6 DW_AT_frame_base DW_OP_reg5 DW_AT_name main DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000164 DW_AT_prototyped yes(1) DW_AT_type <0x00000175> DW_AT_external yes(1) < 2><0x0000047c> DW_TAG_formal_parameter DW_AT_location DW_OP_fbreg -496 DW_AT_name argc DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000164 DW_AT_type <0x00000175> < 2><0x0000048c> DW_TAG_formal_parameter DW_AT_location DW_OP_fbreg -500 DW_AT_name argv DW_AT_decl_file 0x00000004 /tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c DW_AT_decl_line 0x00000164 DW_AT_type <0x000012c8> < 2><0x0000049c> DW_TAG_variable DW_AT_location DW_OP_fbreg -504 dwarfutils-20200114/dwarfdump/test-mach-o-32.dSYM000066400000000000000000001641311361531463500212400ustar00rootroot00000000000000 0\|Yn(18__PAGEZERO__TEXT__text__TEXT%__symbol_stub__TEXTT__stub_helper__TEXT@__cstring__TEXT͞__const__TEXT __unwind_info__TEXTH__DATA__nl_symbol_ptr__DATA('__la_symbol_ptr__DATA(1__const__DATAİ__data__DATAX$__common__DATA|__bss__DATA8__LINKEDITJh__DWARFP`Y __debug_line__DWARFP`__debug_pubnames__DWARFj8z__debug_pubtypes__DWARF o __debug_aranges__DWARFv(dž__debug_info__DWARFw-__debug_frame__DWARF٥ٵ__debug_abbrev__DWARF__debug_str__DWARFl__apple_names__DWARF__apple_namespac__DWARF$__apple_types__DWARFn __apple_objc__DWARF5$54516GP7S7a:q< ?PC@D`EGHL NV(XA`YV Zb[l`yaabbc c@cPf*`hFi]mnmynP@05@_{00P@p# :`DY"gp0 `!7pVps00   0#<6=F=\ BjB{EE@HNV[l`r+s>s_pt~ uД@,? ^xp6?HI@]c @m0  nM  oY oz p y  0  p % ; p_  @ @   0 6  G p_ o `~ @   P  " 3  > R( SJ `W_ 0[~        İ  +  PB  P_  Xj  \t  `  d    Ⱥ  ̺  к  Ժ * /S ;{  P T         " . ; PF XU `c hx l p qFCЧ 5^yAD `)ECZ@jC p@P4eW8pSf h}p$PC@D^x@.i`F )<G /`cr0hP`q @ qA@h^;p<P$d02%,@GG-7-P`Ye 0lpl0$ t@  ^)^M#o0=Dn&`6 GUcF@50C # 5 |G @V9tp`P  #p)C ffk(@0: a0z@1H`u`0) 8PI@_tP//`!!!$P>@N N_ar`B*I10`YH  , @ }S 0f `z p         u!&!:!`M!a!u!0!`!P!!!!@""1"`E"Y"n"`""p"""!"t#6#K#P_#@u##P8#9#= $?$$poD$Yd$0$Po$p$@$p$%а,%C%Pd%% % %%@&P"&=&Q&h&y&0&@&d&e&P#&F'`"?'bX'j{'pK'^'I'k'X' (@!4(`lM(kn(i(a(Pc(d(f)#/)0I)Hb)>})H)K)M)4)3* 2*`59*1P*P3`*Jy*I*p*!***pG*3*03+;)+:?+@4O+1i+08z+:+ 2+9+2+4+p5+6+, a,[',0`A,a],@ss,~,,,X,K,@L,-@-)-iC-2Q-8i-p-l-@0-@?->-0.p).L.p....H.pK/K&/7/J/PZ/0i/P$y/&/0*/</@/-/- 0'.0/P00q0*0+0p)0 %0`(11&111$Q1m1(}1$1#1]1 1%1p6_startswithextractstring_startswithextractnum_simple_error_handler_cleanupstr_xfrm_to_sig8_print_die_data_print_debug_fission_header_read_cu_list_char_to_uns4bit_format_sig8_string_get_die_and_siblings_resetsrcfiles_print_die_data_i_printnamestrings_print_subprog_print_comp_dir_print_name_strings_attr_print_single_string_get_number_get_addr_getBaseName_getSeparator_macho_get_section_info_macho_get_byte_order_macho_get_length_size_macho_get_pointer_size_macho_get_section_count_macho_load_section_simple_compare_function_string_is_in_debug_section_simple_value_hashfunc_freecontextlist_rela_free_tdestroy_free_node_reloc_incomplete__dwarf_find_CU_Context__dwarf_make_CU_Context__dwarf_may_have_base_fields_find_context_base_fields_dwarf_ptr_CU_offset__dwarf_next_die_info_ptr_is_cu_tag__dwarf_find_offdie_CU_Context_section_name_ends_with_dwo__dwarf_read_cu_length_plus_is_unknown_UT_value_read_a_name_index_free_inhdr_list_get_inhdr_cur__dwarf_internal_abbrev_by_code_free_inhdr_content_read_uword_val_fill_in_abbrevs_table_freedabs_get_dsc_leb_entries_get_attr_dbg__dwarf_formsig8_internal_dwarf_init_reg_rules_ru_dwarf_initialize_fde_table__dwarf_get_fde_info_for_a_pc_row_dwarf_free_fde_table_dwarf_init_reg_rules_dw_dwarf_init_reg_rules_dw3_init_reg_rules_alloc_dealloc_fde_cie_list_internal_dwarf_find_existing_cie_ptr_chain_up_cie_get_cieptr_given_offset_dwarf_create_cie_from_start_chain_up_fde_qsort_compare_get_gcc_eh_augmentation_gnu_aug_encodings_validate_length_read_encoded_ptr_grp_data_hashfunc_grp_make_entry_grp_compare_function_grp_walk_map_map_sort_compar_grp_walk_for_name__dwarf_grp_destroy_free_node_safe_strncpy__dwarf_setup_load_debugfission_tables_do_decompress_zlib_determine_target_group_this_section_dwarf_relevant_is_a_rela_section_is_a_special_section_semi_dwarf_is_section_name_known_already_enter_section_in_de_debug_sections_array_get_basic_section_data_add_rela_data_to_secdata_insert_sht_list_in_group_map_startswith_set_up_section_add_debug_section_info_is_path_separator__dwarf_read_line_table_header_create_fullest_file_path_read_line_table_program_dwarf_filename_delete_line_context_itself_operandmismatch_special_cat_construct_at_path_from_parts__dwarf_internal_macro_context_dealloc_macro_srcfiles_construct_from_dir_and_name_specialcat_translate_srcfiles_to_srcfiles2__dwarf_internal_macro_context_by_offset_read_operands_table__dwarf_get_macro_ops_count_internal_valid_macro_form_validate_opcode_is_std_moperator__dwarf_skim_forms__dwarf_get_value_ptr__dwarf_get_address_base_attr_value__dwarf_look_in_local_and_tied_by_index__dwarf_die_attr_unsigned_constant__dwarf_get_ranges_base_attr_value_dw_get_special_offset_tied_data_hashfunc_tied_compare_function__dwarf_loop_reading_debug_info_for_cu_tied_make_entry_calculate_allowed_fill_dumptree_inner_tsearch_inner_dwarf_twalk_inner_dwarf_tdestroy_inner_print_entry_resize_table_allocate_ts_entry_copy_abbrev_table_to_new_table_bufferdoublesize_inthissection__dwarf_get_xuhdr__dwarf_search_fission_for_offset_transform_xu_to_dfp__dwarf_search_fission_for_key_dwarf_udata_string_form_dwarf_udata_udata_form_dwarf_udata_strp_form_dwarf_secoffset_form_dwarf_udata_strp_sup_form_dwarf_udata_strx_form_macho_methods_SectionNames_alloc_instance_basics_dwarf_default_macro_opslist_g_is_info_unittype_fissionfordie_stdrun_dwo_secnames__dwarf_apply_relocs_set_up_section.dprefix_set_up_section.zprefix__dwarf_line_table_regs_default_values_dwarf_standard_opcode_operand_count_dwarf_arm_standard_opcode_operand_count__dwarf_read_line_table_header.expbytes_primes_allowed_fill_percent_dwp_secnames_namesoptionon_dumpallnamespath_dumpallnames_checkoptionon_tuhash_cuhash_tufissionhash_cufissionhash_passnullerror_dupstrused_dupstrarray_dienumber_temp_map_data_map_reccount_found_name_in_group_target_group__dwarf_assume_string_in_bounds_zerohashkey__dwarf_add_to_files_list__dwarf_allow_formudata__dwarf_calculate_abbrev_section_end_ptr__dwarf_calculate_info_section_end_ptr__dwarf_calculate_info_section_start_ptr__dwarf_check_string_valid__dwarf_cie_section_offset__dwarf_debugnames_destructor__dwarf_decode_line_string_form__dwarf_decode_line_udata_form__dwarf_decode_s_leb128_chk__dwarf_decode_u_leb128_chk__dwarf_destroy_group_map__dwarf_dsc_destructor__dwarf_dumpsig__dwarf_dwo_groupnumber_given_name__dwarf_errmsgs__dwarf_error__dwarf_error_mv_s_to_t__dwarf_exec_frame_instr__dwarf_extract_address_from_debug_addr__dwarf_extract_local_debug_str_string_given_offset__dwarf_extract_string_offset_via_str_offsets__dwarf_failsafe_error__dwarf_fde_destructor__dwarf_fde_section_offset__dwarf_file_has_debug_fission_cu_index__dwarf_file_has_debug_fission_index__dwarf_file_has_debug_fission_tu_index__dwarf_file_name_is_full_path__dwarf_formudata_internal__dwarf_frame_constructor__dwarf_frame_destructor__dwarf_free_abbrev_hash_table_contents__dwarf_free_all_of_one_debug__dwarf_free_chain_entries__dwarf_get_abbrev_for_code__dwarf_get_addr_from_tied__dwarf_get_addr_index_itself__dwarf_get_address_size__dwarf_get_alloc__dwarf_get_augmentation_type__dwarf_get_debug__dwarf_get_debugfission_for_offset__dwarf_get_dwp_extra_offset__dwarf_get_elf_flags_func_ptr__dwarf_get_fde_list_internal__dwarf_get_fission_addition_die__dwarf_get_ranges_base_attr_from_tied__dwarf_get_return_address_reg__dwarf_get_size_of_val__dwarf_get_string_base_attr_value__dwarf_get_string_from_tied__dwarf_initialize_search_hash__dwarf_insert_in_group_map__dwarf_internal_get_die_comp_dir__dwarf_internal_get_pubnames_like_data__dwarf_internal_globals_dealloc__dwarf_internal_srclines__dwarf_length_of_cu_header__dwarf_length_of_cu_header_simple__dwarf_line_context_constructor__dwarf_line_context_destructor__dwarf_load_debug_info__dwarf_load_debug_types__dwarf_load_section__dwarf_look_in_local_and_tied__dwarf_macro_constructor__dwarf_macro_destructor__dwarf_memcpy_swap_bytes__dwarf_next_cu_header_internal__dwarf_print_header_issue__dwarf_pro_encode_leb128_nm__dwarf_pro_encode_signed_leb128_nm__dwarf_reference_outside_section__dwarf_search_for_signature__dwarf_section_get_target_group_from_map__dwarf_section_in_group_by_name__dwarf_set_line_table_regs_default_values__dwarf_special_no_dbg_error_malloc__dwarf_tdelete__dwarf_tdestroy__dwarf_tdump__dwarf_tfind__dwarf_tied_destroy_free_node__dwarf_tsearch__dwarf_twalk__dwarf_update_chain_list__dwarf_valid_form_we_know__dwarf_what_section_are_we__mh_execute_header_close_a_file_cu_offset_size_cu_version_stamp_dumpallnamesfile_dw5formsarray_dwarf_CU_dieoffset_given_die_dwarf_arrayorder_dwarf_attr_dwarf_attr_offset_dwarf_attrlist_dwarf_bitoffset_dwarf_bitsize_dwarf_bytesize_dwarf_child_dwarf_cie_section_offset_dwarf_cmdline_options_dwarf_convert_to_global_offset_dwarf_create_cie_from_after_start_dwarf_create_fde_from_after_start_dwarf_dealloc_dwarf_dealloc_macro_context_dwarf_dealloc_uncompressed_block_dwarf_debug_addr_index_to_addr_dwarf_debugnames_abbrev_by_code_dwarf_debugnames_abbrev_by_index_dwarf_debugnames_abbrev_form_by_index_dwarf_debugnames_bucket_dwarf_debugnames_cu_entry_dwarf_debugnames_entrypool_dwarf_debugnames_entrypool_values_dwarf_debugnames_foreign_tu_entry_dwarf_debugnames_header_dwarf_debugnames_local_tu_entry_dwarf_debugnames_name_dwarf_debugnames_sizes_dwarf_die_CU_offset_dwarf_die_CU_offset_range_dwarf_die_abbrev_children_flag_dwarf_die_abbrev_code_dwarf_die_abbrev_global_offset_dwarf_die_from_hash_signature_dwarf_die_offsets_dwarf_die_text_dwarf_diename_dwarf_dieoffset_dwarf_dietype_offset_dwarf_discr_entry_s_dwarf_discr_entry_u_dwarf_discr_list_dwarf_encode_leb128_dwarf_encode_signed_leb128_dwarf_errmsg_dwarf_errno_dwarf_expand_frame_instructions_dwarf_fde_cie_list_dealloc_dwarf_fde_section_offset_dwarf_formaddr_dwarf_formblock_dwarf_formexprloc_dwarf_formflag_dwarf_formref_dwarf_formsdata_dwarf_formsig8_dwarf_formsig8_const_dwarf_formstring_dwarf_formudata_dwarf_get_ACCESS_name_dwarf_get_ADDR_name_dwarf_get_ATCF_name_dwarf_get_ATE_name_dwarf_get_AT_name_dwarf_get_CC_name_dwarf_get_CFA_name_dwarf_get_CHILDREN_name_dwarf_get_DEFAULTED_name_dwarf_get_DSC_name_dwarf_get_DS_name_dwarf_get_EH_name_dwarf_get_END_name_dwarf_get_FORM_name_dwarf_get_FRAME_name_dwarf_get_IDX_name_dwarf_get_ID_name_dwarf_get_INL_name_dwarf_get_ISA_name_dwarf_get_LANG_name_dwarf_get_LLEX_name_dwarf_get_LLE_name_dwarf_get_LNCT_name_dwarf_get_LNE_name_dwarf_get_LNS_name_dwarf_get_MACINFO_name_dwarf_get_MACRO_name_dwarf_get_OP_name_dwarf_get_ORD_name_dwarf_get_RLE_name_dwarf_get_SECT_name_dwarf_get_TAG_name_dwarf_get_UT_name_dwarf_get_VIRTUALITY_name_dwarf_get_VIS_name_dwarf_get_address_size_dwarf_get_aranges_section_name_dwarf_get_children_name_dwarf_get_cie_augmentation_data_dwarf_get_cie_index_dwarf_get_cie_info_dwarf_get_cie_info_b_dwarf_get_cie_of_fde_dwarf_get_cu_die_offset_given_cu_header_offset_dwarf_get_cu_die_offset_given_cu_header_offset_b_dwarf_get_debug_addr_index_dwarf_get_debug_str_index_dwarf_get_debugfission_for_die_dwarf_get_debugfission_for_key_dwarf_get_die_address_size_dwarf_get_die_infotypes_flag_dwarf_get_die_section_name_dwarf_get_die_section_name_b_dwarf_get_fde_at_pc_dwarf_get_fde_augmentation_data_dwarf_get_fde_exception_info_dwarf_get_fde_for_die_dwarf_get_fde_info_for_all_regs_dwarf_get_fde_info_for_all_regs3_dwarf_get_fde_info_for_cfa_reg3_dwarf_get_fde_info_for_cfa_reg3_b_dwarf_get_fde_info_for_reg_dwarf_get_fde_info_for_reg3_dwarf_get_fde_info_for_reg3_b_dwarf_get_fde_instr_bytes_dwarf_get_fde_list_dwarf_get_fde_list_eh_dwarf_get_fde_n_dwarf_get_fde_range_dwarf_get_form_class_dwarf_get_frame_section_name_dwarf_get_frame_section_name_eh_gnu_dwarf_get_globals_dwarf_get_harmless_error_list_dwarf_get_line_section_name_from_die_dwarf_get_macro_context_dwarf_get_macro_context_by_offset_dwarf_get_macro_defundef_dwarf_get_macro_import_dwarf_get_macro_op_dwarf_get_macro_section_name_dwarf_get_macro_startend_file_dwarf_get_offset_size_dwarf_get_ranges_section_name_dwarf_get_section_count_dwarf_get_section_info_by_index_dwarf_get_section_info_by_name_dwarf_get_section_max_offsets_dwarf_get_section_max_offsets_b_dwarf_get_section_max_offsets_c_dwarf_get_section_max_offsets_d_dwarf_get_string_section_name_dwarf_get_version_of_die_dwarf_get_xu_hash_entry_dwarf_get_xu_index_header_dwarf_get_xu_index_section_type_dwarf_get_xu_section_names_dwarf_get_xu_section_offset_dwarf_global_cu_offset_dwarf_global_die_offset_dwarf_global_formref_dwarf_global_name_offsets_dwarf_globals_dealloc_dwarf_globname_dwarf_harmless_cleanout_dwarf_harmless_init_dwarf_hasattr_dwarf_hasform_dwarf_highpc_dwarf_highpc_b_dwarf_insert_harmless_error_dwarf_line_is_addr_set_dwarf_line_srcfileno_dwarf_line_subprog_dwarf_line_subprogno_dwarf_lineaddr_dwarf_linebeginstatement_dwarf_lineblock_dwarf_linecontext_dwarf_lineendsequence_dwarf_linelogical_dwarf_lineno_dwarf_lineoff_dwarf_lineoff_b_dwarf_linesrc_dwarf_lowpc_dwarf_macho_finish_dwarf_macho_init_dwarf_macro_context_head_dwarf_macro_operands_table_dwarf_next_cu_header_dwarf_next_cu_header_b_dwarf_next_cu_header_c_dwarf_next_cu_header_d_dwarf_object_finish_dwarf_object_init_dwarf_object_init_b_dwarf_offdie_dwarf_offdie_b_dwarf_offset_list_dwarf_print_memory_stats_dwarf_printf_dwarf_prologue_end_etc_dwarf_read_cie_fde_prefix_dwarf_record_cmdline_options_dwarf_register_printf_callback_dwarf_sec_group_map_dwarf_sec_group_sizes_dwarf_set_default_address_size_dwarf_set_frame_cfa_value_dwarf_set_frame_rule_inital_value_dwarf_set_frame_rule_initial_value_dwarf_set_frame_rule_table_size_dwarf_set_frame_same_value_dwarf_set_frame_undefined_value_dwarf_set_harmless_error_list_size_dwarf_set_reloc_application_dwarf_set_stringcheck_dwarf_siblingof_dwarf_siblingof_b_dwarf_srcfiles_dwarf_srclang_dwarf_srclines_dwarf_srclines_b_dwarf_srclines_comp_dir_dwarf_srclines_dealloc_dwarf_srclines_dealloc_b_dwarf_srclines_files_count_dwarf_srclines_files_data_dwarf_srclines_from_linecontext_dwarf_srclines_include_dir_count_dwarf_srclines_include_dir_data_dwarf_srclines_subprog_count_dwarf_srclines_subprog_data_dwarf_srclines_table_offset_dwarf_srclines_two_level_dwarf_srclines_two_level_from_linecontext_dwarf_srclines_version_dwarf_tag_dwarf_uncompress_integer_block_dwarf_validate_die_sibling_dwarf_whatattr_dwarf_whatform_dwarf_whatform_direct_dwarf_xu_header_free_lookfor_name_main_open_a_file /usr/include/usr/include/i386/usr/include/sys/tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/tmp/c/tmp/dwarf-20170709/libdwarfstdio.h_types.h_types.hsimplereader.clibdwarf.h% ?  g  t  Yff< .gf*t<g /f.h #Xf1t<g 4f/f. h4f/f. h4f/f. i4f/f. i#Xf9t<g #Xf9t<g 1f,f. h1f,f. h1f,f. iC>f O#_X "Xf gg*f$c&$ ft"e vYf  htg Yt6! f"g htgh%f-f:f f t jt !# fu.= f-'hd i t= f f$f f Xt ! $f 4iY fu.= f-'hd i t= f f$f f Xt ! #f 4jYZ * 7= f.'hd i t! Xt ! #f 4iYZ * 7= f.'hd i t! Xt ! #f 4i Yg f"f f  jt !g f4 !u<=<<<. g <<=< < /<.u t"u 5 u!u< =u<<<. g <<? <=< </up6  t <. ><6  <)< e P7 = <"g< <!\7" 3< =uw "< <D! = ;L"< <g)<<= Jg"<Y) \ Yt<<*g <f<!I% `tJ,g+< <J,=+< <J>& =- X- < <*9 J/<f= J* : A t $ fgg 2geht"evt"ev"f+f1f f" KZf#f)ff=,< )= wJ fh< . /"< <e,<<,% /Jgu-< Yuf#< = J< h=f d,s? ? #gggh%Kf >uju uvuu  $g u&9* nB Jg*<4:= <v J JJ!h%<,<=; t> Jg*<4A= <v J ""<)< <"< < < Q 0C <PC 0 J<J <gJ <=YJ<fJ<gJ< <=YJ<fJ<gJ< <=02J JK <@D u <= J!/J Y)6/;\`E -u<=uuvtu><<(<<iu*<< = J9 <" J"g&<,<4<<<?< <u< <!%<-<><< t= Jg*<%>< ;L" J h [< <g< <<=<$<-< <d<XG /f<fK)<< <. <, [<<.<u<g<f *uug uuuuug vtuh(< <  =J7 < "J=#< <  =J3 <L J  =J< <"g< <>1< <  = Jh,<< = J< <#=J = J>< <f gJ <gEK<<0<(<.<1< <v!f%J<< gJ(< gJ :j< <AKG< < <)</< <h06<:JB< < uJ(!1J < Jg< < L uu v < < = Jg Zff'K <f!?%<)< < ^<<N 0uu uvtu2< < < =J g Zff&<0f< = JgJ<g$<fX["f&.*<;fDff-6< $< .< >YJ<$<fJ<"<fJ<"<f Y#<< f e  X uu====+<<" ?C<<>)<<'g < Jw  J ! M Jht<" t"! (J"'h &XJ ! O t#  t ! f"%f0"<*f3*<?4 e?ff $< e$ff $< e$<< V &uuvtu2< < < =J g&Z+<=<XJ< >ff&v<0f< = JgJ<0u(<9f<=J<; 1YJ< h YY#<< f p X<<"t 'ugguv < . =J w <  =J # J  ? JgZ<<=`Y ,u uv <  = J)f << < Z uvvtguh&< <  =Jg X< K&< <  =Jg X< KZY[ uvvtgui%< <  =Jg X< KZY /tmp/c/tmp/dwarf-20170709/libdwarf/usr/include/i386/usr/include/sys/_types/tmp/c/dwarf/usr/include/_types/usr/include/mach-o/usr/include/mach/i386/usr/include/mach/usr/include/usr/include/syslibdwarf.hdwarf_opaque.hdwarf_base_types.hdwarf_error.hdwarf_util.hdwarf_xu_index.h_types.h_size_t.hdwarf_macho.c_uint32_t.hloader.hvm_types.hmachine.hstdio.h _types.h _uint64_t.h[  0#v<*<@<<  =Jq <  =J-2 <"#t,8tAfPtYft0(=J+\<)</*<?<"</='<%<g h< g'<1f9<<>,<=,<,<u(<#2t;tRhY<4f$>+tJ\x<{<@t:%=JTgW<07<%<E<XK]<0X7<%<E<Xg^<c<\<0.7<%<E<%K3<"_xX7 1t<.<=,<K,<KL[S<1f$>+tJVr<u<=t7%=JTgW<07<%<E<XKG<0<7<%<E<X^<c<\<0.7<%<E<%K3<"_xX7 1t<.<=,<K,<N$<f7E<N<V<_<#<!t>J#g*<f#<Z< YY < < < ` -, < = Jg < <= a ) !.<!.==D<.$=)<<  =<f < <a   u<?  . =J<fJ#<&f(J <g<> <a = %< > J f.K< : f< Y: J< =< #< u b = < =<<b = < =< c = < =<  c  =f@c = '< > J.f.J5<f .K!t<4X << /u &dumpallnamesfilescu_version_stampcu_offset_sizenamesoptionondupstruseddupstrarraydumpallnamespathdumpallnamescheckoptionontuhash!cuhash2tufissionhashCcufissionhashTpassnullerroreg_is_infounittypefissionfordiestdrundienumberdmainstartswithextractstringUstartswithextractnumopen_a_filesimple_error_handler8cleanupstrYxfrm_to_sig8$print_die_dataprint_debug_fission_headere read_cu_list close_a_file char_to_uns4bit5 format_sig8_string get_die_and_siblingsp resetsrcfiles print_die_data_i printnamestrings.print_subprogprint_comp_dirprint_name_strings_attroprint_single_stringget_numberZget_addrG&macho_methodsSectionNamesdwarf_macho_init0getBaseNamecdwarf_macho_finishgetSeparatormacho_get_section_infosmacho_get_byte_ordermacho_get_length_sizemacho_get_pointer_size macho_get_section_count?macho_load_section=FILEH__sFILEnunsigned charuint|short__sbufcharfpos_t__darwin_off_t__int64_tlong long int`sizetypeunsigned intvDwarf_BoolDwarf_Form_ClassGDwarf_PtrRDwarf_Unsigned]long long unsigned intDwarf_DebugDwarf_ErrorDwarf_HandlerDwarf_Sig8$Dwarf_Sig8_sLDwarf_DiecsrcfilesdataDwarf_SignedDwarf_Debug_Fission_Per_CUDwarf_Debug_Fission_Per_CU_s_Dwarf_Halfjunsigned shortqDwarf_AttributeDwarf_AddrG<Dwarf_Obj_Access_MethodsHDwarf_Obj_Access_Methods_sintDwarf_Halfunsigned shortDwarf_Obj_Access_SectionDwarf_Obj_Access_Section_syDwarf_Addrlong long unsigned intDwarf_UnsignedcharDwarf_EndiannessDwarf_Smallunsigned charYDwarf_DebugjDwarf_Debug_s|Dwarf_Obj_Access_Interface_sDwarf_HandlerDwarf_ErrorDwarf_Error_sDwarf_Swordlong intDwarf_PtrDwarf_Debug_InfoTypes_sDwarf_CU_ContextDwarf_CU_Context_sS Dwarf_Sig8^ Dwarf_Sig8_s sizetype Dwarf_Debug_Fission_Per_CU_s Dwarf_Bool Dwarf_Byte_Ptr Dwarf_Hash_Table/ Dwarf_Hash_Table_sf long unsigned intr Dwarf_Hash_Table_Entry_s Dwarf_Abbrev_List Dwarf_Die Dwarf_Die_s unsigned int Dwarf_Group_Data_sS Dwarf_Ciej Dwarf_Signedu long long int Dwarf_Fde Dwarf_Section_s Dwarf_Word Dwarf_Xu_Index_Header Dwarf_Xu_Index_Header_s size_t__darwin_size_tDwarf_dbg_sect_sDwarf_Harmless_sDwarf_Printf_Callback_Info_s`dwarf_printf_callback_function_type~Dwarf_Tied_Data_smach_header_64vuint32_tcpu_type_tinteger_tcpu_subtype_tmach_headermacho_access_object_tDwarf_Obj_Access_InterfaceFILE__sFILEshort__sbufJfpos_tU__darwin_off_t`__int64_tsection_64}uint64_tsection%45p666P7u74:q< ?0CPC@D`EMG=L NVO`Y Z[d[9`= a[amabbc c@c -o%[8|=HXzi{#u|#u}#|~# |##u### #$#($#,#0I#8u#<T#@g#C#Du#L#Pn%)/X6iY#<uZ# u  u   uB    uGMNG].g) u  ? uD N u n`~ n`uuu ?`d?uu? ??!?/u=vXuG^Ru\[u`iudpuPz !:O j     !;Wv]a`p%4Udu|du|d|f|gu|h?{iu{j{k{lGhm{nG{oum&Q+{tu,p.{L5--{c.u0{L://{c0>2~a24| 45Uut?p?l .h?d5a6U ux?t?p53l?hd<up66U>ju|Jj?xOmu6J7UQXtXpXGhfZRP77Um|7:Ux\?X8`=TȹPɹLʹH˹88DԹ9f9CnBn99An:<U@~@~@L}Au}BIq:<~F:;}Iu}J}KG<?U+L+NH-?D.R*/S >>@2A?:BR>CRDu ?'CUC0d0XP2RPa3RNo4_L|5_J6_H7_h8@9R:R;_<v=>u?G?CCLDLEuFc AAXAwBf0COCU|OuPC2DU{nt<@DQEUp+8l*h0d`9`EGU<vpvlQvLhwudXwu`xI\zuXa{LTi|LP}L~GEGHoLF?GDGHUwxtIhHLUplLhudI`J\Z_T?PuLuHGDqB_?LMUtpLlh`XTuMMPqNVUplLhudI`J?\uXTH@ RR#G!O~P,_WOO2P'T<uAu~Gu~L~T~_~h~p_~yVXUhthphLliuhiIdku`l\mP nHoDpGWWB,_>WWJX_YUplLhqdub_`_\X`YZUplLj_du`\ ZZU|qxtpuh`R\G[[U|qxtpuhdG8  @ % 3 ]   G$A L ;# `XY 9] c o k| l# m# un#  c C , ! ?0 #! R6 #! 7 # ! "> #! "? #t! R@ #! RA # R` ?u `c `j$ a/ }> A N q]` dRC k "o[c 7 İ <H x ! #! #! #! # ! #!  #!( 9#  %$ a/ ; y T 4!o y#!t #!>#!J#!y #!~ #$! #,` dpa` B   "     b    / 4>  Y e8j# X+! w0#! 2#! 3#! 5# ! 6#0!  <#T!  ?#X!' E#h!6 I#i!F N#j!a R#l!o N W#p!{ j Y#t! N [#|! j \#! | ^#! `#! | b#! c#! e#! f#! g#! h#! i#!, j#!9 k#!J l#![ m#!j n# !y o# ! p# ! q# ! r# ! s# ! t#! w#! y#! #! #!& #!8 #!K #![ #!p #!~ #! #! #! #! #! #! #! #!#!#!(#!D#!c#!{#!#!#!#! #(!#(!#(!#~#(| 03!M7#!T8#73 ]   @% $\%#f3#vWv $u!y#!|#!#!# !#! #! #!' # 3$DhWY#^#h# w# #####S #$#, #4 #3 #H #_ #{ # ##### #! #! #!(#!0 #!; #^ A L u #  ~ , ! 0 #! 6 #! S 7 # ! > #! ? #t! @ #! A #  G^4H* W/ h !{f #!f #!m #r ! #   Y 9 c N  O# P#&Q#4R# C U# N!a  #!u ##! %#!(# S _ Dd u cg  C  p!4#!#!# ! "#! y'#!(# !(+#!!6 2#$!G?#(!_ F#,!hI#0!x4J#4!K#8!L#@!yM#H!yP#P! T#X! W#\!Z#`! ]#d! c#h! d#lf   H 1X'IY(#P4)#`*#r,#}-#.# /#(0#01#82#@3#H 6#P9#T     %.f 5\  2 E !V#!^ #!h #!s # !#!#!#!# j! k#! l#! m#! n# !o#  ! #!/` #!7 #!A  # !O #!g #ls q   !Y#!  #!# :   & 7 8# 9# Hv I#  J# K#v L# %v M#+v N#6v O#<v P# E N EY ^c Fq 6v 7#  8# 9#v :# %v ;#+v <#6v =#'} Y& L N# O# P#  Q#  R# W#& S> T#J U#+4 V#  X#|w  '[`U p l h d ` \ XJ  \`TO \`P   ]`L C]`H f J^5_D  @ p^^ Щ5_`  ާ [__ `aU -x -t& / a{aU1 | Yx t Ap l aaUD | xQ tS s "abUU xpl xnp xh~ xd x` zbbU \|l \x ^bbU c|l cx eccU j|l jx l c} #(!"v #0!)v #4!/v #8!6v #v #$!"v #(!)v #,!/v #0!6v #4!6v #8!=v #  I' I &I < I!I7 $ > 4I: ;   : ;( .@ : ;' I?  : ;I4 : ;I .@ : ;' I.@ : ; ' I : ; I4 : ; I.@ : ;' .@ : ; ' .@ : ;' ? I: ;'  : ;! I: ;8 " : ;# : ;$ : ; %&& : ; '.@ : ; ' I? Apple LLVM version 8.0.0 (clang-800.0.42.1)/tmp/c/tmp/dwarf-20170709/libdwarf/../dwarfexample/simplereader.c/tmp/c/dwarf/gcc_m32dumpallnamesfileFILE__sFILE_p_r_w_flags_file_bf_lbfsize_cookie_close_read_seek_write_ub_extra_ur_ubuf_nbuf_lb_blksize_offsetunsigned charintshort__sbuf_base_sizecharfpos_t__darwin_off_t__int64_tlong long int__sFILEXsizetypecu_version_stampcu_offset_sizenamesoptionondupstrusedunsigned intdupstrarraydumpallnamespathdumpallnamescheckoptionontuhashcuhashtufissionhashcufissionhashpassnullerrorg_is_infoDwarf_BoolunittypefissionfordiestdrundienumberDwarf_Form_ClassDW_FORM_CLASS_UNKNOWNDW_FORM_CLASS_ADDRESSDW_FORM_CLASS_BLOCKDW_FORM_CLASS_CONSTANTDW_FORM_CLASS_EXPRLOCDW_FORM_CLASS_FLAGDW_FORM_CLASS_LINEPTRDW_FORM_CLASS_LOCLISTPTRDW_FORM_CLASS_MACPTRDW_FORM_CLASS_RANGELISTPTRDW_FORM_CLASS_REFERENCEDW_FORM_CLASS_STRINGDW_FORM_CLASS_FRAMEPTRDW_FORM_CLASS_MACROPTRDW_FORM_CLASS_ADDRPTRDW_FORM_CLASS_LOCLISTDW_FORM_CLASS_LOCLISTSPTRDW_FORM_CLASS_RNGLISTDW_FORM_CLASS_RNGLISTSPTRDW_FORM_CLASS_STROFFSETSPTRDwarf_PtrDwarf_Unsignedlong long unsigned intmainargcargvdbgfdfilepathreserrorerrhanderrarghash8errpsimpleerrhandidiesffisdatastartswithextractstringarglookforptroutsprefixlenstartswithextractnumnumoutvopen_a_filenamefsimple_error_handlerunusedcleanupstrxfrm_to_sig8cuhash_inhash_outlocalhashhashin_lenfixed_sizeinit_byteadd_zeroshicharlocharcprint_die_dataprint_melevelpercuprint_debug_fission_headerfsdfissionsecstr_bufnstringoffsizeread_cu_listcu_header_lengthabbrev_offsetaddress_sizeversion_stampoffset_sizeextension_sizesignaturetypeoffsetnext_cu_headerheader_cu_typeis_infocu_numberno_diecu_dieemclose_a_filechar_to_uns4bitformat_sig8_stringdatabuf_sizecpget_die_and_siblingsin_diein_levelcur_diechildsib_dieresetsrcfilessriprint_die_data_itagtagnamelocalnameattrformnumformnameprintnamestringsatlistatcountprint_subprogattrbuflowpchighpcattrcountfilenumlinenumfilenameaformfilenum_shreshresblresalthipchipcoffsetalthipcbaltlopchighformhighclassprint_comp_dirprint_name_strings_attrattrnumfinalformclprint_single_stringstringvalget_numbervalsvaluvalget_addrDwarf_DebugDwarf_Debug_sDwarf_ErrorDwarf_Error_sDwarf_HandlerDwarf_Sig8Dwarf_Sig8_sDwarf_DieDwarf_Die_ssrcfilesdatasrcfilessrcfilescountsrcfilesresDwarf_SignedDwarf_Debug_Fission_Per_CUDwarf_Debug_Fission_Per_CU_spcu_typepcu_indexpcu_hashpcu_offsetpcu_sizeunused1unused2Dwarf_Halfunsigned shortDwarf_AttributeDwarf_Attribute_sDwarf_Addr/tmp/c/dwarf/dwarf_macho.cmacho_methodsDwarf_Obj_Access_MethodsDwarf_Obj_Access_Methods_sget_section_infoget_byte_orderget_length_sizeget_pointer_sizeget_section_countload_sectionrelocate_a_sectionDwarf_Obj_Access_SectionDwarf_Obj_Access_Section_saddrtypelinkinfoentrysizeDwarf_EndiannessDW_OBJECT_MSBDW_OBJECT_LSBDwarf_Smallde_obj_filede_errhandde_errargde_info_readingde_types_readingde_groupnumberde_groupnumbersde_length_sizede_pointer_sizede_assume_string_in_boundsde_alloc_treede_cie_datade_cie_countde_cie_data_ehde_cie_count_ehde_fde_datade_fde_countde_fde_data_ehde_fde_count_ehde_debug_infode_debug_typesde_debug_abbrevde_debug_linede_debug_line_strde_debug_locde_debug_arangesde_debug_macinfode_debug_macrode_debug_namesde_debug_pubnamesde_debug_strde_debug_supde_debug_loclistsde_debug_rnglistsde_debug_framede_debug_frame_eh_gnude_debug_pubtypesde_debug_funcnamesde_debug_typenamesde_debug_varnamesde_debug_weaknamesde_debug_rangesde_debug_str_offsetsde_debug_addrde_debug_gdbindexde_debug_cu_indexde_debug_tu_indexde_elf_symtabde_elf_strtabde_cu_hashindex_datade_tu_hashindex_datade_copy_wordde_same_endiande_elf_must_closede_frame_rule_initial_valuede_frame_reg_rules_entry_countde_frame_cfa_col_numberde_frame_same_value_numberde_frame_undefined_value_numberde_big_endian_objectde_debug_sectionsde_debug_sections_total_entriesde_harmless_errorsde_printf_callbackde_tied_dataDwarf_Obj_Access_Interface_sobjectmethodser_errvaler_static_allocDwarf_Swordlong intDwarf_Debug_InfoTypes_sde_cu_contextde_cu_context_listde_cu_context_list_endde_offdie_cu_contextde_offdie_cu_context_endde_last_offsetde_last_di_ptrde_last_dieDwarf_CU_ContextDwarf_CU_Context_scc_dbgcc_lengthcc_length_sizecc_extension_sizecc_version_stampcc_abbrev_offsetcc_address_sizecc_segment_selector_sizecc_debug_offsetcc_type_signaturecc_type_signature_offsetcc_dwp_offsetscc_signature_presentcc_addr_base_presentcc_ranges_base_presentcc_str_offsets_base_presentcc_is_dwocc_cu_die_offset_presentcc_addr_basecc_ranges_basecc_str_offsets_basecc_cu_die_global_sec_offsetcc_last_abbrev_ptrcc_last_abbrev_endptrcc_abbrev_hash_tablecc_nextcc_is_infocc_unit_typeDwarf_Byte_PtrDwarf_Hash_TableDwarf_Hash_Table_stb_table_entry_counttb_total_abbrev_counttb_entrieslong unsigned intDwarf_Hash_Table_Entry_sat_headDwarf_Abbrev_ListDwarf_Abbrev_List_sdi_debug_ptrdi_abbrev_listdi_cu_contextdi_abbrev_codedi_is_infoDwarf_Group_Data_sgd_number_of_groupsgd_number_of_sectionsgd_map_entry_countgd_mapDwarf_CieDwarf_Cie_sDwarf_FdeDwarf_Fde_sDwarf_Section_sdss_datadss_sizedss_entrysizedss_indexdss_addrdss_data_was_mallocdss_is_in_usedss_group_numberdss_requires_decompressdss_linkdss_reloc_indexdss_reloc_datadss_reloc_sizedss_reloc_entrysizedss_reloc_addrdss_reloc_symtabdss_reloc_linkdss_symtabdss_namedss_numberdss_flagsdss_addralignDwarf_WordDwarf_Xu_Index_HeaderDwarf_Xu_Index_Header_sgx_dbggx_section_datagx_section_lengthgx_versiongx_column_count_sectionsgx_units_in_indexgx_slots_in_hashgx_hash_table_offsetgx_index_table_offsetgx_section_offsets_offsetgx_section_sizes_offsetgx_typegx_section_namesize_t__darwin_size_tDwarf_dbg_sect_sds_nameds_numberds_secdatads_groupnumberds_duperrds_emptyerrds_have_dwarfds_have_zdebugDwarf_Harmless_sdh_maxcountdh_next_to_usedh_firstdh_errs_countdh_errorsDwarf_Printf_Callback_Info_sdp_user_pointerdp_fptrdp_bufferdp_buffer_lendp_buffer_user_provideddp_reserveddwarf_printf_callback_function_typeDwarf_Tied_Data_std_tied_objecttd_is_tied_objecttd_tied_searchSectionNamesmonamedwnamemach_header_64magiccputypecpusubtypefiletypencmdssizeofcmdsflagsreserveduint32_tcpu_type_tinteger_tcpu_subtype_tmach_headermacho_access_object_tintfcbyteorderlensizeptrsizesec_cntsecdsym_bufDwarf_Obj_Access_Interfacedwarf_macho_initfnameret_dbgmacholenmhgetBaseNameszFilenamepSeparatordwarf_macho_finishgetSeparatorpqmacho_get_section_infoobjsection_indexreturn_sectionmacho_get_byte_ordermacho_get_length_sizemacho_get_pointer_sizemacho_get_section_countmacho_load_sectionreturn_datasection_64sectnamesegnameoffsetalignreloffnrelocreserved1reserved2reserved3uint64_tsectionHSAH6  #$%&'().12AmgE\.i{!,FTv`TqS<nS҃1)Tqg#& gC~KAMz浢ODbNeIOS2r"@Pn^ kMr(gLAނ4m=U)ȅXj|&]7ln<L\l| ,<L\l| ,<L\l| ,<L\l|1( !CX$RCe > $ '.[m8|)I)U() !)wp <   oQ=epZxY&)Dj(5 U/Tids2y&HSAH HSAH'N   #(,/1235689;>@BEGH/c 眴2b[[zDt / >r4٨ZSB/bSN/DT vK١h^~zT^H$ޓ,Pl'6I>͓<:niU2%; @=K=IspUv]&|qފe5p0 SpDztE sѫ n{b7fͲ_b4#׵&]Sm )/$;՟}Pa?c |U /||58Of}3Ja9Pg)Km0G^u 7Ne|  > U l   : Q h  5 W !謥E*fv[@}%[[ 7j71!j ],aRm.m$ _66@##()|$Iz+$Ic UA G`G`~`$Vt\$$Vt\` ll!}g$[K $[Kc:%ʐpN$%HJSY*JSa&Hs <+<."6A> qGDgi+Dgiz՜3 L$Τ$o c.|F#!$ݸ &V &VW|;  $A {-d5-N{dhI&s$?DON&:,E"5b.N)k+)k%u$(: ~$(: /G4W+G4W$ ; 3?hV$,}  X; s EWG  p]$'E'$'EV,{qO%ڜa/ j$W$W0q;5")פE%QY/%J, o `Un {L $VVHuSIT _ND3fB$W{C$W{Y L^ڟ D^ڟ % {[ -Gv((=ikN*ik֟ n$q$q $1 HSAH dwarfutils-20200114/dwarfdump/testesb.c000066400000000000000000000306211361531463500177500ustar00rootroot00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2013-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* testesb.c testing esb.c */ #include "config.h" #include "esb.h" #define TRUE 1 static int failcount = 0; static void validate_esb(int instance, struct esb_s* d, size_t explen, size_t expalloc, const char *expout, int line ) { if (esb_string_len(d) != explen) { ++failcount; printf(" FAIL instance %d esb_string_len() %u explen %u line %d\n", instance,(unsigned)esb_string_len(d),(unsigned)explen,line); } if (d->esb_allocated_size != expalloc) { ++failcount; printf(" FAIL instance %d esb_allocated_size %u expalloc %u line %d\n", instance,(unsigned)d->esb_allocated_size,(unsigned)expalloc,line); } if(strcmp(esb_get_string(d),expout)) { ++failcount; printf(" FAIL instance %d esb_get_string %s expstr %s line %d\n", instance,esb_get_string(d),expout,line); } } int main() { #ifdef _WIN32 /* Open the null device used during formatting printing */ if (!esb_open_null_device()) { fprintf(stderr, "esb: Unable to open null device.\n"); exit(1); } #endif /* _WIN32 */ { /* First lets establish standard sprintf on cases of interest. */ struct esb_s d5; char bufs[4]; esb_int i = -33; /* After static alloc we add len, ie, 11 */ esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %d bbb",(int)i); validate_esb(201,&d5,11,15,"aaa -33 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6d bbb",(int)i); validate_esb(202,&d5,14,18,"aaa -33 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6d bbb",6); validate_esb(203,&d5,14,18,"aaa 6 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %06d bbb",6); validate_esb(204,&d5,14,18,"aaa 000006 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %06u bbb",6); validate_esb(205,&d5,14,18,"aaa 000006 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6u bbb",6); validate_esb(206,&d5,14,18,"aaa 6 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %u bbb",12); validate_esb(207,&d5,10,14,"aaa 12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %06x bbb",12); validate_esb(208,&d5,14,18,"aaa 00000c bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6x bbb",12); validate_esb(209,&d5,14,18,"aaa c bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %+d bbb",12); validate_esb(210,&d5,11,15,"aaa +12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %+6d bbb",12); validate_esb(211,&d5,14,18,"aaa +12 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf(&d5,"aaa %6d bbb",(int)i); validate_esb(212,&d5,14,18,"aaa -33 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"a"); validate_esb(1,&d,1,2,"a",__LINE__); esb_append(&d,"b"); validate_esb(2,&d,2,3,"ab",__LINE__); esb_append(&d,"c"); validate_esb(3,&d,3,4,"abc",__LINE__); esb_empty_string(&d); validate_esb(4,&d,0,4,"",__LINE__); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_append(&d,"aa"); validate_esb(6,&d,2,3,"aa",__LINE__); esb_append(&d,"bbb"); validate_esb(7,&d,5,6,"aabbb",__LINE__); esb_append(&d,"c"); validate_esb(8,&d,6,7,"aabbbc",__LINE__); esb_empty_string(&d); validate_esb(9,&d,0,7,"",__LINE__); esb_destructor(&d); } { struct esb_s d; static char oddarray[7] = {'a','b',0,'c','c','d',0}; esb_constructor(&d); /* This used to provoke a msg on stderr. Bad input. Now inserts particular string instead. */ esb_appendn(&d,oddarray,6); validate_esb(10,&d,23,24,"ESBERR_appendn bad call",__LINE__); /* The next one just keeps the previous ESBERR* and adds a 'c' */ esb_appendn(&d,"cc",1); validate_esb(11,&d,24,25,"ESBERR_appendn bad callc",__LINE__); esb_empty_string(&d); validate_esb(12,&d,0,25,"",__LINE__); esb_destructor(&d); } { struct esb_s d; esb_constructor(&d); esb_force_allocation(&d,7); esb_append(&d,"aaaa i"); validate_esb(13,&d,6,7,"aaaa i",__LINE__); esb_destructor(&d); } { struct esb_s d5; const char * s = "insert me %d"; esb_constructor(&d5); esb_force_allocation(&d5,50); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(14,&d5,18,50,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); } { struct esb_s d; struct esb_s e; char* result = NULL; esb_constructor(&d); esb_constructor(&e); esb_append(&d,"abcde fghij klmno pqrst"); validate_esb(15,&d,23,24,"abcde fghij klmno pqrst",__LINE__); result = esb_get_copy(&d); esb_append(&e,result); validate_esb(16,&e,23,24,"abcde fghij klmno pqrst",__LINE__); esb_destructor(&d); esb_destructor(&e); } { struct esb_s d5; char bufs[4]; char bufl[60]; const char * s = "insert me %d"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(17,&d5,18,19,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufl,sizeof(bufl)); esb_append(&d5,"aaa "); esb_append_printf(&d5,s,1); esb_append(&d5,"zzz"); validate_esb(18,&d5,18,60,"aaa insert me 1zzz",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; const char * s = "insert me"; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %s bbb",s); validate_esb(19,&d5,17,18,"aaa insert me bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %12s bbb",s); validate_esb(20,&d5,20,21,"aaa insert me bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_s(&d5,"aaa %-12s bbb",s); validate_esb(21,&d5,20,21,"aaa insert me bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; esb_int i = -33; esb_unsigned u = 0; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %d bbb",i); validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(19,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(20,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %6d bbb",i); validate_esb(21,&d5,14,15,"aaa -2 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %04d bbb",i); validate_esb(22,&d5,12,13,"aaa -002 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",i); validate_esb(23,&d5,14,15,"aaa -00002 bbb",__LINE__); esb_destructor(&d5); i = -200011; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %04d bbb",i); validate_esb(24,&d5,15,16,"aaa -200011 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %06d bbb",i); validate_esb(25,&d5,15,16,"aaa -200011 bbb",__LINE__); esb_destructor(&d5); u = 0x80000000; u = 0x8000000000000000; i = u; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(26,&d5,28,29,"aaa -9223372036854775808 bbb",__LINE__); esb_destructor(&d5); i = 987665432; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %4d bbb",i); validate_esb(27,&d5,17,18,"aaa 987665432 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; esb_unsigned u = 0; u = 37; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %u bbb",u); validate_esb(28,&d5,10,11,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %4u bbb",u); validate_esb(29,&d5,12,13,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %4u bbb",u); validate_esb(30,&d5,12,13,"aaa 37 bbb",__LINE__); esb_destructor(&d5); esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_u(&d5,"aaa %6u bbb",u); validate_esb(31,&d5,14,15,"aaa 37 bbb",__LINE__); esb_destructor(&d5); } { struct esb_s d5; char bufs[4]; esb_int i = -33; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",i); validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__); esb_destructor(&d5); i = 33; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+d bbb",i); validate_esb(18,&d5,11,12,"aaa +33 bbb",__LINE__); esb_destructor(&d5); i = -2; esb_constructor_fixed(&d5,bufs,sizeof(bufs)); esb_append_printf_i(&d5,"aaa %+4d bbb",i); validate_esb(19,&d5,12,13,"aaa -2 bbb",__LINE__); esb_destructor(&d5); } #ifdef _WIN32 /* Close the null device used during formatting printing */ esb_close_null_device(); #endif /* _WIN32 */ if (failcount) { printf("FAIL esb test\n"); exit(1); } printf("PASS esb test\n"); exit(0); } dwarfutils-20200114/dwarfdump/testobjLE32PE.base000066400000000000000000000763641361531463500212720ustar00rootroot00000000000000 .debug_info COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit DW_AT_producer GNU C11 6.3.0 -mtune=generic -march=i586 -g3 -ggdb3 DW_AT_language DW_LANG_C99 DW_AT_name c:/Users/dandelot/test.c DW_AT_low_pc 0x00401460 DW_AT_high_pc 87 DW_AT_stmt_list 0x00000000 DW_AT_GNU_macros 0x00000000 LOCAL_SYMBOLS: < 1><0x0000006a> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_unsigned DW_AT_name unsigned int < 1><0x0000007a> DW_TAG_base_type DW_AT_byte_size 0x00000002 DW_AT_encoding DW_ATE_unsigned DW_AT_name short unsigned int < 1><0x00000090> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_signed DW_AT_name long int < 1><0x0000009c> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_signed DW_AT_name long long int < 1><0x000000ad> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_signed DW_AT_name int < 1><0x000000b4> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_signed_char DW_AT_name char < 1><0x000000bc> DW_TAG_structure_type DW_AT_name _iobuf DW_AT_byte_size 0x00000020 DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d2 DW_AT_sibling <0x00000143> < 2><0x000000cb> DW_TAG_member DW_AT_name _ptr DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d4 DW_AT_type <0x00000143> DW_AT_data_member_location 0 < 2><0x000000d8> DW_TAG_member DW_AT_name _cnt DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d5 DW_AT_type <0x000000ad> DW_AT_data_member_location 4 < 2><0x000000e5> DW_TAG_member DW_AT_name _base DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d6 DW_AT_type <0x00000143> DW_AT_data_member_location 8 < 2><0x000000f3> DW_TAG_member DW_AT_name _flag DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d7 DW_AT_type <0x000000ad> DW_AT_data_member_location 12 < 2><0x00000101> DW_TAG_member DW_AT_name _file DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d8 DW_AT_type <0x000000ad> DW_AT_data_member_location 16 < 2><0x0000010f> DW_TAG_member DW_AT_name _charbuf DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000d9 DW_AT_type <0x000000ad> DW_AT_data_member_location 20 < 2><0x00000120> DW_TAG_member DW_AT_name _bufsiz DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000da DW_AT_type <0x000000ad> DW_AT_data_member_location 24 < 2><0x00000130> DW_TAG_member DW_AT_name _tmpfname DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000db DW_AT_type <0x00000143> DW_AT_data_member_location 28 < 1><0x00000143> DW_TAG_pointer_type DW_AT_byte_size 0x00000004 DW_AT_type <0x000000b4> < 1><0x00000149> DW_TAG_typedef DW_AT_name FILE DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000dc DW_AT_type <0x000000bc> < 1><0x00000155> DW_TAG_array_type DW_AT_type <0x00000149> DW_AT_sibling <0x00000160> < 2><0x0000015e> DW_TAG_subrange_type < 1><0x00000160> DW_TAG_variable DW_AT_name _iob DW_AT_decl_file 0x00000002 c:/mingw/include/stdio.h DW_AT_decl_line 0x000000ef DW_AT_type <0x00000155> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x0000016c> DW_TAG_structure_type DW_AT_name something DW_AT_byte_size 0x00000008 DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000004 DW_AT_sibling <0x00000193> < 2><0x0000017e> DW_TAG_member DW_AT_name a DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000005 DW_AT_type <0x000000ad> DW_AT_data_member_location 0 < 2><0x00000188> DW_TAG_member DW_AT_name b DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000006 DW_AT_type <0x0000006a> DW_AT_data_member_location 4 < 1><0x00000193> DW_TAG_subprogram DW_AT_external yes(1) DW_AT_name main DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000010 DW_AT_prototyped yes(1) DW_AT_type <0x000000ad> DW_AT_low_pc 0x0040146d DW_AT_high_pc 74 DW_AT_frame_base len 0x0001: 9c: DW_OP_call_frame_cfa DW_AT_GNU_all_tail_call_sites yes(1) DW_AT_sibling <0x000001f1> < 2><0x000001ad> DW_TAG_formal_parameter DW_AT_name argc DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000010 DW_AT_type <0x000000ad> DW_AT_location len 0x0002: 9100: DW_OP_fbreg 0 < 2><0x000001bc> DW_TAG_formal_parameter DW_AT_name argv DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000010 DW_AT_type <0x000001f1> DW_AT_location len 0x0002: 9104: DW_OP_fbreg 4 < 2><0x000001cb> DW_TAG_variable DW_AT_name x DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000013 DW_AT_type <0x000000ad> DW_AT_location len 0x0002: 741c: DW_OP_breg4+28 < 2><0x000001d7> DW_TAG_variable DW_AT_name y DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000014 DW_AT_type <0x000000ad> DW_AT_location len 0x0002: 7418: DW_OP_breg4+24 < 2><0x000001e3> DW_TAG_variable DW_AT_name so DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x00000015 DW_AT_type <0x0000016c> DW_AT_location len 0x0002: 7410: DW_OP_breg4+16 < 1><0x000001f1> DW_TAG_pointer_type DW_AT_byte_size 0x00000004 DW_AT_type <0x00000143> < 1><0x000001f7> DW_TAG_subprogram DW_AT_external yes(1) DW_AT_name buffle DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x0000000a DW_AT_prototyped yes(1) DW_AT_type <0x000000ad> DW_AT_low_pc 0x00401460 DW_AT_high_pc 13 DW_AT_frame_base len 0x0001: 9c: DW_OP_call_frame_cfa DW_AT_GNU_all_call_sites yes(1) DW_AT_sibling <0x00000220> < 2><0x00000213> DW_TAG_formal_parameter DW_AT_name v DW_AT_decl_file 0x00000001 c:/Users/dandelot/test.c DW_AT_decl_line 0x0000000a DW_AT_type <0x00000220> DW_AT_location len 0x0002: 9100: DW_OP_fbreg 0 < 1><0x00000220> DW_TAG_pointer_type DW_AT_byte_size 0x00000004 DW_AT_type <0x0000016c> .debug_line: line number info for a single cu Source lines (from CU-DIE at .debug_info offset 0x0000000b): NS new statement, BB new basic block, ET end of text sequence PE prologue end, EB epilogue begin IS=val ISA number, DI=val discriminator value [lno,col] NS BB ET PE EB IS= DI= uri: "filepath" 0x00401460 [ 11, 0] NS uri: "c:/Users/dandelot/test.c" 0x00401463 [ 12, 0] NS 0x0040146b [ 14, 0] NS 0x0040146d [ 17, 0] NS 0x00401476 [ 17, 0] NS 0x0040147b [ 19, 0] NS 0x00401483 [ 20, 0] NS 0x0040148b [ 23, 0] NS 0x00401493 [ 24, 0] NS 0x004014a3 [ 25, 0] NS 0x004014b5 [ 26, 0] NS 0x004014b7 [ 26, 0] NS ET .debug_macro: Macro info for a single cu Macro data from CU-DIE at .debug_info offset 0x0000000b: Macro version: 4 MacroInformationEntries count: 565, bytes length: 16146 [ 0] 0x01 DW_MACRO_define line 0 __STDC__ 1 [ 1] 0x01 DW_MACRO_define line 0 __STDC_VERSION__ 201112L [ 2] 0x01 DW_MACRO_define line 0 __STDC_UTF_16__ 1 [ 3] 0x01 DW_MACRO_define line 0 __STDC_UTF_32__ 1 [ 4] 0x01 DW_MACRO_define line 0 __STDC_HOSTED__ 1 [ 5] 0x01 DW_MACRO_define line 0 __GNUC__ 6 [ 6] 0x01 DW_MACRO_define line 0 __GNUC_MINOR__ 3 [ 7] 0x01 DW_MACRO_define line 0 __GNUC_PATCHLEVEL__ 0 [ 8] 0x01 DW_MACRO_define line 0 __VERSION__ "6.3.0" [ 9] 0x01 DW_MACRO_define line 0 __ATOMIC_RELAXED 0 [ 10] 0x01 DW_MACRO_define line 0 __ATOMIC_SEQ_CST 5 [ 11] 0x01 DW_MACRO_define line 0 __ATOMIC_ACQUIRE 2 [ 12] 0x01 DW_MACRO_define line 0 __ATOMIC_RELEASE 3 [ 13] 0x01 DW_MACRO_define line 0 __ATOMIC_ACQ_REL 4 [ 14] 0x01 DW_MACRO_define line 0 __ATOMIC_CONSUME 1 [ 15] 0x01 DW_MACRO_define line 0 __FINITE_MATH_ONLY__ 0 [ 16] 0x01 DW_MACRO_define line 0 __SIZEOF_INT__ 4 [ 17] 0x01 DW_MACRO_define line 0 __SIZEOF_LONG__ 4 [ 18] 0x01 DW_MACRO_define line 0 __SIZEOF_LONG_LONG__ 8 [ 19] 0x01 DW_MACRO_define line 0 __SIZEOF_SHORT__ 2 [ 20] 0x01 DW_MACRO_define line 0 __SIZEOF_FLOAT__ 4 [ 21] 0x01 DW_MACRO_define line 0 __SIZEOF_DOUBLE__ 8 [ 22] 0x01 DW_MACRO_define line 0 __SIZEOF_LONG_DOUBLE__ 12 [ 23] 0x01 DW_MACRO_define line 0 __SIZEOF_SIZE_T__ 4 [ 24] 0x01 DW_MACRO_define line 0 __CHAR_BIT__ 8 [ 25] 0x01 DW_MACRO_define line 0 __BIGGEST_ALIGNMENT__ 16 [ 26] 0x01 DW_MACRO_define line 0 __ORDER_LITTLE_ENDIAN__ 1234 [ 27] 0x01 DW_MACRO_define line 0 __ORDER_BIG_ENDIAN__ 4321 [ 28] 0x01 DW_MACRO_define line 0 __ORDER_PDP_ENDIAN__ 3412 [ 29] 0x01 DW_MACRO_define line 0 __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ [ 30] 0x01 DW_MACRO_define line 0 __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__ [ 31] 0x01 DW_MACRO_define line 0 __SIZEOF_POINTER__ 4 [ 32] 0x01 DW_MACRO_define line 0 __SIZE_TYPE__ unsigned int [ 33] 0x01 DW_MACRO_define line 0 __PTRDIFF_TYPE__ int [ 34] 0x01 DW_MACRO_define line 0 __WCHAR_TYPE__ short unsigned int [ 35] 0x01 DW_MACRO_define line 0 __WINT_TYPE__ short unsigned int [ 36] 0x01 DW_MACRO_define line 0 __INTMAX_TYPE__ long long int [ 37] 0x01 DW_MACRO_define line 0 __UINTMAX_TYPE__ long long unsigned int [ 38] 0x01 DW_MACRO_define line 0 __CHAR16_TYPE__ short unsigned int [ 39] 0x01 DW_MACRO_define line 0 __CHAR32_TYPE__ unsigned int [ 40] 0x01 DW_MACRO_define line 0 __SIG_ATOMIC_TYPE__ int [ 41] 0x01 DW_MACRO_define line 0 __INT8_TYPE__ signed char [ 42] 0x01 DW_MACRO_define line 0 __INT16_TYPE__ short int [ 43] 0x01 DW_MACRO_define line 0 __INT32_TYPE__ int [ 44] 0x01 DW_MACRO_define line 0 __INT64_TYPE__ long long int [ 45] 0x01 DW_MACRO_define line 0 __UINT8_TYPE__ unsigned char [ 46] 0x01 DW_MACRO_define line 0 __UINT16_TYPE__ short unsigned int [ 47] 0x01 DW_MACRO_define line 0 __UINT32_TYPE__ unsigned int [ 48] 0x01 DW_MACRO_define line 0 __UINT64_TYPE__ long long unsigned int [ 49] 0x01 DW_MACRO_define line 0 __INT_LEAST8_TYPE__ signed char [ 50] 0x01 DW_MACRO_define line 0 __INT_LEAST16_TYPE__ short int [ 51] 0x01 DW_MACRO_define line 0 __INT_LEAST32_TYPE__ int [ 52] 0x01 DW_MACRO_define line 0 __INT_LEAST64_TYPE__ long long int [ 53] 0x01 DW_MACRO_define line 0 __UINT_LEAST8_TYPE__ unsigned char [ 54] 0x01 DW_MACRO_define line 0 __UINT_LEAST16_TYPE__ short unsigned int [ 55] 0x01 DW_MACRO_define line 0 __UINT_LEAST32_TYPE__ unsigned int [ 56] 0x01 DW_MACRO_define line 0 __UINT_LEAST64_TYPE__ long long unsigned int [ 57] 0x01 DW_MACRO_define line 0 __INT_FAST8_TYPE__ signed char [ 58] 0x01 DW_MACRO_define line 0 __INT_FAST16_TYPE__ short int [ 59] 0x01 DW_MACRO_define line 0 __INT_FAST32_TYPE__ int [ 60] 0x01 DW_MACRO_define line 0 __INT_FAST64_TYPE__ long long int [ 61] 0x01 DW_MACRO_define line 0 __UINT_FAST8_TYPE__ unsigned char [ 62] 0x01 DW_MACRO_define line 0 __UINT_FAST16_TYPE__ short unsigned int [ 63] 0x01 DW_MACRO_define line 0 __UINT_FAST32_TYPE__ unsigned int [ 64] 0x01 DW_MACRO_define line 0 __UINT_FAST64_TYPE__ long long unsigned int [ 65] 0x01 DW_MACRO_define line 0 __INTPTR_TYPE__ int [ 66] 0x01 DW_MACRO_define line 0 __UINTPTR_TYPE__ unsigned int [ 67] 0x01 DW_MACRO_define line 0 __has_include(STR) __has_include__(STR) [ 68] 0x01 DW_MACRO_define line 0 __has_include_next(STR) __has_include_next__(STR) [ 69] 0x01 DW_MACRO_define line 0 __GXX_ABI_VERSION 1010 [ 70] 0x01 DW_MACRO_define line 0 __SCHAR_MAX__ 0x7f [ 71] 0x01 DW_MACRO_define line 0 __SHRT_MAX__ 0x7fff [ 72] 0x01 DW_MACRO_define line 0 __INT_MAX__ 0x7fffffff [ 73] 0x01 DW_MACRO_define line 0 __LONG_MAX__ 0x7fffffffL [ 74] 0x01 DW_MACRO_define line 0 __LONG_LONG_MAX__ 0x7fffffffffffffffLL [ 75] 0x01 DW_MACRO_define line 0 __WCHAR_MAX__ 0xffff [ 76] 0x01 DW_MACRO_define line 0 __WCHAR_MIN__ 0 [ 77] 0x01 DW_MACRO_define line 0 __WINT_MAX__ 0xffff [ 78] 0x01 DW_MACRO_define line 0 __WINT_MIN__ 0 [ 79] 0x01 DW_MACRO_define line 0 __PTRDIFF_MAX__ 0x7fffffff [ 80] 0x01 DW_MACRO_define line 0 __SIZE_MAX__ 0xffffffffU [ 81] 0x01 DW_MACRO_define line 0 __INTMAX_MAX__ 0x7fffffffffffffffLL [ 82] 0x01 DW_MACRO_define line 0 __INTMAX_C(c) c ## LL [ 83] 0x01 DW_MACRO_define line 0 __UINTMAX_MAX__ 0xffffffffffffffffULL [ 84] 0x01 DW_MACRO_define line 0 __UINTMAX_C(c) c ## ULL [ 85] 0x01 DW_MACRO_define line 0 __SIG_ATOMIC_MAX__ 0x7fffffff [ 86] 0x01 DW_MACRO_define line 0 __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1) [ 87] 0x01 DW_MACRO_define line 0 __INT8_MAX__ 0x7f [ 88] 0x01 DW_MACRO_define line 0 __INT16_MAX__ 0x7fff [ 89] 0x01 DW_MACRO_define line 0 __INT32_MAX__ 0x7fffffff [ 90] 0x01 DW_MACRO_define line 0 __INT64_MAX__ 0x7fffffffffffffffLL [ 91] 0x01 DW_MACRO_define line 0 __UINT8_MAX__ 0xff [ 92] 0x01 DW_MACRO_define line 0 __UINT16_MAX__ 0xffff [ 93] 0x01 DW_MACRO_define line 0 __UINT32_MAX__ 0xffffffffU [ 94] 0x01 DW_MACRO_define line 0 __UINT64_MAX__ 0xffffffffffffffffULL [ 95] 0x01 DW_MACRO_define line 0 __INT_LEAST8_MAX__ 0x7f [ 96] 0x01 DW_MACRO_define line 0 __INT8_C(c) c [ 97] 0x01 DW_MACRO_define line 0 __INT_LEAST16_MAX__ 0x7fff [ 98] 0x01 DW_MACRO_define line 0 __INT16_C(c) c [ 99] 0x01 DW_MACRO_define line 0 __INT_LEAST32_MAX__ 0x7fffffff [100] 0x01 DW_MACRO_define line 0 __INT32_C(c) c [101] 0x01 DW_MACRO_define line 0 __INT_LEAST64_MAX__ 0x7fffffffffffffffLL [102] 0x01 DW_MACRO_define line 0 __INT64_C(c) c ## LL [103] 0x01 DW_MACRO_define line 0 __UINT_LEAST8_MAX__ 0xff [104] 0x01 DW_MACRO_define line 0 __UINT8_C(c) c [105] 0x01 DW_MACRO_define line 0 __UINT_LEAST16_MAX__ 0xffff [106] 0x01 DW_MACRO_define line 0 __UINT16_C(c) c [107] 0x01 DW_MACRO_define line 0 __UINT_LEAST32_MAX__ 0xffffffffU [108] 0x01 DW_MACRO_define line 0 __UINT32_C(c) c ## U [109] 0x01 DW_MACRO_define line 0 __UINT_LEAST64_MAX__ 0xffffffffffffffffULL [110] 0x01 DW_MACRO_define line 0 __UINT64_C(c) c ## ULL [111] 0x01 DW_MACRO_define line 0 __INT_FAST8_MAX__ 0x7f [112] 0x01 DW_MACRO_define line 0 __INT_FAST16_MAX__ 0x7fff [113] 0x01 DW_MACRO_define line 0 __INT_FAST32_MAX__ 0x7fffffff [114] 0x01 DW_MACRO_define line 0 __INT_FAST64_MAX__ 0x7fffffffffffffffLL [115] 0x01 DW_MACRO_define line 0 __UINT_FAST8_MAX__ 0xff [116] 0x01 DW_MACRO_define line 0 __UINT_FAST16_MAX__ 0xffff [117] 0x01 DW_MACRO_define line 0 __UINT_FAST32_MAX__ 0xffffffffU [118] 0x01 DW_MACRO_define line 0 __UINT_FAST64_MAX__ 0xffffffffffffffffULL [119] 0x01 DW_MACRO_define line 0 __INTPTR_MAX__ 0x7fffffff [120] 0x01 DW_MACRO_define line 0 __UINTPTR_MAX__ 0xffffffffU [121] 0x01 DW_MACRO_define line 0 __GCC_IEC_559 2 [122] 0x01 DW_MACRO_define line 0 __GCC_IEC_559_COMPLEX 2 [123] 0x01 DW_MACRO_define line 0 __FLT_EVAL_METHOD__ 2 [124] 0x01 DW_MACRO_define line 0 __DEC_EVAL_METHOD__ 2 [125] 0x01 DW_MACRO_define line 0 __FLT_RADIX__ 2 [126] 0x01 DW_MACRO_define line 0 __FLT_MANT_DIG__ 24 [127] 0x01 DW_MACRO_define line 0 __FLT_DIG__ 6 [128] 0x01 DW_MACRO_define line 0 __FLT_MIN_EXP__ (-125) [129] 0x01 DW_MACRO_define line 0 __FLT_MIN_10_EXP__ (-37) [130] 0x01 DW_MACRO_define line 0 __FLT_MAX_EXP__ 128 [131] 0x01 DW_MACRO_define line 0 __FLT_MAX_10_EXP__ 38 [132] 0x01 DW_MACRO_define line 0 __FLT_DECIMAL_DIG__ 9 [133] 0x01 DW_MACRO_define line 0 __FLT_MAX__ 3.40282346638528859812e+38F [134] 0x01 DW_MACRO_define line 0 __FLT_MIN__ 1.17549435082228750797e-38F [135] 0x01 DW_MACRO_define line 0 __FLT_EPSILON__ 1.19209289550781250000e-7F [136] 0x01 DW_MACRO_define line 0 __FLT_DENORM_MIN__ 1.40129846432481707092e-45F [137] 0x01 DW_MACRO_define line 0 __FLT_HAS_DENORM__ 1 [138] 0x01 DW_MACRO_define line 0 __FLT_HAS_INFINITY__ 1 [139] 0x01 DW_MACRO_define line 0 __FLT_HAS_QUIET_NAN__ 1 [140] 0x01 DW_MACRO_define line 0 __DBL_MANT_DIG__ 53 [141] 0x01 DW_MACRO_define line 0 __DBL_DIG__ 15 [142] 0x01 DW_MACRO_define line 0 __DBL_MIN_EXP__ (-1021) [143] 0x01 DW_MACRO_define line 0 __DBL_MIN_10_EXP__ (-307) [144] 0x01 DW_MACRO_define line 0 __DBL_MAX_EXP__ 1024 [145] 0x01 DW_MACRO_define line 0 __DBL_MAX_10_EXP__ 308 [146] 0x01 DW_MACRO_define line 0 __DBL_DECIMAL_DIG__ 17 [147] 0x01 DW_MACRO_define line 0 __DBL_MAX__ ((double)1.79769313486231570815e+308L) [148] 0x01 DW_MACRO_define line 0 __DBL_MIN__ ((double)2.22507385850720138309e-308L) [149] 0x01 DW_MACRO_define line 0 __DBL_EPSILON__ ((double)2.22044604925031308085e-16L) [150] 0x01 DW_MACRO_define line 0 __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L) [151] 0x01 DW_MACRO_define line 0 __DBL_HAS_DENORM__ 1 [152] 0x01 DW_MACRO_define line 0 __DBL_HAS_INFINITY__ 1 [153] 0x01 DW_MACRO_define line 0 __DBL_HAS_QUIET_NAN__ 1 [154] 0x01 DW_MACRO_define line 0 __LDBL_MANT_DIG__ 64 [155] 0x01 DW_MACRO_define line 0 __LDBL_DIG__ 18 [156] 0x01 DW_MACRO_define line 0 __LDBL_MIN_EXP__ (-16381) [157] 0x01 DW_MACRO_define line 0 __LDBL_MIN_10_EXP__ (-4931) [158] 0x01 DW_MACRO_define line 0 __LDBL_MAX_EXP__ 16384 [159] 0x01 DW_MACRO_define line 0 __LDBL_MAX_10_EXP__ 4932 [160] 0x01 DW_MACRO_define line 0 __DECIMAL_DIG__ 21 [161] 0x01 DW_MACRO_define line 0 __LDBL_MAX__ 1.18973149535723176502e+4932L [162] 0x01 DW_MACRO_define line 0 __LDBL_MIN__ 3.36210314311209350626e-4932L [163] 0x01 DW_MACRO_define line 0 __LDBL_EPSILON__ 1.08420217248550443401e-19L [164] 0x01 DW_MACRO_define line 0 __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L [165] 0x01 DW_MACRO_define line 0 __LDBL_HAS_DENORM__ 1 [166] 0x01 DW_MACRO_define line 0 __LDBL_HAS_INFINITY__ 1 [167] 0x01 DW_MACRO_define line 0 __LDBL_HAS_QUIET_NAN__ 1 [168] 0x01 DW_MACRO_define line 0 __DEC32_MANT_DIG__ 7 [169] 0x01 DW_MACRO_define line 0 __DEC32_MIN_EXP__ (-94) [170] 0x01 DW_MACRO_define line 0 __DEC32_MAX_EXP__ 97 [171] 0x01 DW_MACRO_define line 0 __DEC32_MIN__ 1E-95DF [172] 0x01 DW_MACRO_define line 0 __DEC32_MAX__ 9.999999E96DF [173] 0x01 DW_MACRO_define line 0 __DEC32_EPSILON__ 1E-6DF [174] 0x01 DW_MACRO_define line 0 __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF [175] 0x01 DW_MACRO_define line 0 __DEC64_MANT_DIG__ 16 [176] 0x01 DW_MACRO_define line 0 __DEC64_MIN_EXP__ (-382) [177] 0x01 DW_MACRO_define line 0 __DEC64_MAX_EXP__ 385 [178] 0x01 DW_MACRO_define line 0 __DEC64_MIN__ 1E-383DD [179] 0x01 DW_MACRO_define line 0 __DEC64_MAX__ 9.999999999999999E384DD [180] 0x01 DW_MACRO_define line 0 __DEC64_EPSILON__ 1E-15DD [181] 0x01 DW_MACRO_define line 0 __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD [182] 0x01 DW_MACRO_define line 0 __DEC128_MANT_DIG__ 34 [183] 0x01 DW_MACRO_define line 0 __DEC128_MIN_EXP__ (-6142) [184] 0x01 DW_MACRO_define line 0 __DEC128_MAX_EXP__ 6145 [185] 0x01 DW_MACRO_define line 0 __DEC128_MIN__ 1E-6143DL [186] 0x01 DW_MACRO_define line 0 __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL [187] 0x01 DW_MACRO_define line 0 __DEC128_EPSILON__ 1E-33DL [188] 0x01 DW_MACRO_define line 0 __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL [189] 0x01 DW_MACRO_define line 0 __REGISTER_PREFIX__ [190] 0x01 DW_MACRO_define line 0 __USER_LABEL_PREFIX__ _ [191] 0x01 DW_MACRO_define line 0 __GNUC_STDC_INLINE__ 1 [192] 0x01 DW_MACRO_define line 0 __NO_INLINE__ 1 [193] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 [194] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 [195] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 [196] 0x01 DW_MACRO_define line 0 __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 [197] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_BOOL_LOCK_FREE 2 [198] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_CHAR_LOCK_FREE 2 [199] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2 [200] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2 [201] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 [202] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_SHORT_LOCK_FREE 2 [203] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_INT_LOCK_FREE 2 [204] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_LONG_LOCK_FREE 2 [205] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_LLONG_LOCK_FREE 2 [206] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 [207] 0x01 DW_MACRO_define line 0 __GCC_ATOMIC_POINTER_LOCK_FREE 2 [208] 0x01 DW_MACRO_define line 0 __GCC_HAVE_DWARF2_CFI_ASM 1 [209] 0x01 DW_MACRO_define line 0 __PRAGMA_REDEFINE_EXTNAME 1 [210] 0x01 DW_MACRO_define line 0 __SIZEOF_WCHAR_T__ 2 [211] 0x01 DW_MACRO_define line 0 __SIZEOF_WINT_T__ 2 [212] 0x01 DW_MACRO_define line 0 __SIZEOF_PTRDIFF_T__ 4 [213] 0x01 DW_MACRO_define line 0 __i386 1 [214] 0x01 DW_MACRO_define line 0 __i386__ 1 [215] 0x01 DW_MACRO_define line 0 i386 1 [216] 0x01 DW_MACRO_define line 0 __SIZEOF_FLOAT80__ 12 [217] 0x01 DW_MACRO_define line 0 __SIZEOF_FLOAT128__ 16 [218] 0x01 DW_MACRO_define line 0 __ATOMIC_HLE_ACQUIRE 65536 [219] 0x01 DW_MACRO_define line 0 __ATOMIC_HLE_RELEASE 131072 [220] 0x01 DW_MACRO_define line 0 __GCC_ASM_FLAG_OUTPUTS__ 1 [221] 0x01 DW_MACRO_define line 0 __i586 1 [222] 0x01 DW_MACRO_define line 0 __i586__ 1 [223] 0x01 DW_MACRO_define line 0 __pentium 1 [224] 0x01 DW_MACRO_define line 0 __pentium__ 1 [225] 0x01 DW_MACRO_define line 0 __code_model_32__ 1 [226] 0x01 DW_MACRO_define line 0 __SEG_FS 1 [227] 0x01 DW_MACRO_define line 0 __SEG_GS 1 [228] 0x01 DW_MACRO_define line 0 _X86_ 1 [229] 0x01 DW_MACRO_define line 0 __stdcall __attribute__((__stdcall__)) [230] 0x01 DW_MACRO_define line 0 __fastcall __attribute__((__fastcall__)) [231] 0x01 DW_MACRO_define line 0 __thiscall __attribute__((__thiscall__)) [232] 0x01 DW_MACRO_define line 0 __cdecl __attribute__((__cdecl__)) [233] 0x01 DW_MACRO_define line 0 _stdcall __attribute__((__stdcall__)) [234] 0x01 DW_MACRO_define line 0 _fastcall __attribute__((__fastcall__)) [235] 0x01 DW_MACRO_define line 0 _thiscall __attribute__((__thiscall__)) [236] 0x01 DW_MACRO_define line 0 _cdecl __attribute__((__cdecl__)) [237] 0x01 DW_MACRO_define line 0 __GXX_MERGED_TYPEINFO_NAMES 0 [238] 0x01 DW_MACRO_define line 0 __GXX_TYPEINFO_EQUALITY_INLINE 0 [239] 0x01 DW_MACRO_define line 0 __MSVCRT__ 1 [240] 0x01 DW_MACRO_define line 0 __MINGW32__ 1 [241] 0x01 DW_MACRO_define line 0 _WIN32 1 [242] 0x01 DW_MACRO_define line 0 __WIN32 1 [243] 0x01 DW_MACRO_define line 0 __WIN32__ 1 [244] 0x01 DW_MACRO_define line 0 WIN32 1 [245] 0x01 DW_MACRO_define line 0 __WINNT 1 [246] 0x01 DW_MACRO_define line 0 __WINNT__ 1 [247] 0x01 DW_MACRO_define line 0 WINNT 1 [248] 0x01 DW_MACRO_define line 0 _INTEGRAL_MAX_BITS 64 [249] 0x01 DW_MACRO_define line 0 __declspec(x) __attribute__((x)) [250] 0x01 DW_MACRO_define line 0 __DECIMAL_BID_FORMAT__ 1 [251] 0x03 DW_MACRO_start_file line 0 file number 1 c:/Users/dandelot/test.c [252] 0x03 DW_MACRO_start_file line 1 file number 2 c:/mingw/include/stdio.h [253] 0x01 DW_MACRO_define line 51 _STDIO_H [254] 0x03 DW_MACRO_start_file line 56 file number 3 c:/mingw/include/_mingw.h [255] 0x01 DW_MACRO_define line 34 __MINGW_H [256] 0x01 DW_MACRO_define line 49 __MINGW32_VERSION 5000001L [257] 0x01 DW_MACRO_define line 50 __MINGW32_MAJOR_VERSION 5 [258] 0x01 DW_MACRO_define line 51 __MINGW32_MINOR_VERSION 0 [259] 0x01 DW_MACRO_define line 52 __MINGW32_PATCHLEVEL 1 [260] 0x03 DW_MACRO_start_file line 66 file number 4 c:/mingw/include/msvcrtver.h [261] 0x01 DW_MACRO_define line 34 _MSVCRTVER_H [262] 0x01 DW_MACRO_define line 42 __MSVCR60_DLL 0x0600 [263] 0x01 DW_MACRO_define line 43 __MSVCR61_DLL 0x0601 [264] 0x01 DW_MACRO_define line 44 __MSVCR70_DLL 0x0700 [265] 0x01 DW_MACRO_define line 45 __MSVCR71_DLL 0x0701 [266] 0x01 DW_MACRO_define line 46 __MSVCR80_DLL 0x0800 [267] 0x01 DW_MACRO_define line 47 __MSVCR90_DLL 0x0900 [268] 0x01 DW_MACRO_define line 48 __MSVCR100_DLL 0x1000 [269] 0x01 DW_MACRO_define line 49 __MSVCR110_DLL 0x1100 [270] 0x01 DW_MACRO_define line 50 __MSVCR120_DLL 0x1200 [271] 0x01 DW_MACRO_define line 68 __MSVCRT_VERSION__ __MSVCR60_DLL [272] 0x04 DW_MACRO_end_file [273] 0x03 DW_MACRO_start_file line 73 file number 5 c:/mingw/include/w32api.h [274] 0x01 DW_MACRO_define line 34 _W32API_H [275] 0x01 DW_MACRO_define line 51 __W32API_VERSION 5000001L [276] 0x01 DW_MACRO_define line 52 __W32API_MAJOR_VERSION 5 [277] 0x01 DW_MACRO_define line 53 __W32API_MINOR_VERSION 0 [278] 0x01 DW_MACRO_define line 54 __W32API_PATCHLEVEL 1 [279] 0x03 DW_MACRO_start_file line 59 file number 6 c:/mingw/include/sdkddkver.h dwarfutils-20200114/dwarfdump/testobjLE32PE.exe000077500000000000000000001616441361531463500211400ustar00rootroot00000000000000MZ@ !L!This program cannot be run in DOS mode. $PELՔ] ,F@@P< $.text+,`P`.data@0@0.rdataP2@0@/4 ` 6@0@.bsspp0.idata@@0.CRTF@0.tls H@0/14XJ@@B/29& L@B/41l@B/55n@B/678r@0B/80?@t@BD$ =wN=s`=D$$ *H&1&=tI==uD$$)t$и먍D$$)uD$$k)k'=UD$$9)tY4$и#$ иD$$($D$$(D$$ (t&'USdP@tD$D$$Ѓ $@)p@@$C p@tB@ @@D$C$s( p@D$C0$_( p@D$CP$K(n( @@ Y\(D$p@D$p@$)($('u<WӍvW]څtpL$ w@9t$$D$(<(t)9tlhu$-NjD$$)Džu׋T$ t$$ <]ta<tCu<1[^_]f;\$tO_-ft$$&u F밍v<]uQ@t CQ@4$M.te[^_]F t&tEe$ M)č|$fBt<uCBuM<$ eMxMMf'WVSt$ >Q@t[^_Í&FV x~F$h uFD$ [^_Q UWVS,D$$ t $ D$(Q@$utE8uqD$D$*Q@$pt$hp@$hp@t$D$*Q@$W\$$w$5hp@e[^_]ÉeD$E$D$YD)ĉT$E|$ <$D$/1ɉE؃f G}fEvf/f\f:OEfM‰v'f\tPHft6f/uf/u f/tf\tftPƍHfu9uEf/f\u.f1fD$|$$PT$hp@U$Uhp@Ɖ|$$T$ev'F9EaVf/tf\t1҉fPf/tf\&f/tf\t)ft!f/fQtbf8\ptWPfuߋE1f1|$D$E$ ut\$$ $He܍e[^_]Éf\tf/yf/tf\t\Ef;Gf\$$$uf9WGEGfEE.Mf/t f\Mf9HPf/{f\qjVSӁTT$$T$tZ1K fC1Cf=fCD<uD$$XvCT[^fCT[^ft18 t8t딐VSӁTT$$T$t_1K fC1Cf=fCD<uD$$XwCT[^Í&CT[^tT[^Í&'UWVS,$@8^|$D$D$<$|$tM!ʁ t€ у)T/tC\t>\f 0t&!ʁ t€у)*f!%tꩀu)$|$\$,$StsdžfF,[^_]fHt&t&{1l _1릉4$1뚉'S\$t+P~dt؃[ 1v'S\$ t$$nt$1[ 鍴&'S\$ t$uz [Ítǃ[Ð& D$t  & 'VSt$$\$ xO$Wt7u,&#t9Ɖ܃[^Í[^Ð%@%@%@%@%@%܁@%؁@%ԁ@%Ё@%́@%ȁ@%ā@%@%@%@%@%@%@%@%@%@%@%|@%h@%d@%`@%\@%X@%T@%P@%L@%H@%D@%@@%<@%8@%4@%0@%,@%(@%$@%t@%p@ffffU];@@;@libgcc_s_dw2-1.dll__register_frame_info__deregister_frame_infolibgcj-16.dll_Jv_RegisterClasses0@Mingw runtime failure: VirtualQuery failed for %d bytes at address %p Unknown pseudo relocation protocol version %d. Unknown pseudo relocation bit size %d. .glob-1.0-mingw32.GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (MinGW.org GCC-6.3.0-1) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 5.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0GCC: (GNU) 6.3.0zR| C R K 8tAB DTH?C@{lpC |C zR| (hAB E AA D H,.AB j zR| $ AB I <JAB F zR| <,AB F- AAA G  AAA A zR| t^BzR| ,N\ 44FAC j AA X`zR| TCC U H `8<AA C d  FAC h  FAC xطzR| 8`AA C LI PC jC C AADXAA E L  CAI sH UC E  AAA <(AC P CI LI gC C CK ZC (C a A iC ] B LC zR| JAA C d<AA CAG`XTC`i AA AAK dPC`FPC`C AA AAA 4jA AC0 A AAJ zR| LlC A A zR| 4IA I AA sAF (TcEA E H AAl4AA CACPn CA AAC M DA AAA C DA AAA TAA CAC@ AA AAC K AA AAA DHL\AA CE @ C AAA CF AA(dIAA G o  AAF ,AB Cd AAA C ,AB FF AAA A @_AA AC O A AAH wA AAzR| <AB F CAA A P AAA A zR| @TAA HPCL  CAC I  CAA L`AA HPCG  CAH M  CAA [ CA@@AA AAFM CA AAC FACq AA (BAC VC Q AA ,D XAC VC R AA eAt<'CQ A 4PqAA C R  AAG N AAzR|  AB A P$p|(6BTdrւ*<LVbrƃ҃ރ$.6@JV`jv(6BTdrւ*<LVbrƃ҃ރ$.6@JV`jvDeleteCriticalSectionEnterCriticalSectionExitProcess-FindClose1FindFirstFileABFindNextFileAaFreeLibraryGetCommandLineAGetLastErrorGetModuleHandleABGetProcAddressInitializeCriticalSection/LeaveCriticalSection2LoadLibraryAuSetUnhandledExceptionFilterTlsGetValueVirtualProtectVirtualQueryP_strdupR_stricollY__getmainargsx__mb_cur_max__p__environ__p__fmode__set_app_type_cexit_errnoE_fpreset__fullpath_iob_isctype_onexit_pctype_setmode<abortDatexitKcalloclfreewfwritemallocmbstowcsmemcpyreallocsetlocalesignalstrcollstrlentolowervfprintf.wcstombsKERNEL32.dllmsvcrt.dll((((((((((((((((((((((((((((((msvcrt.dll0@@@@8p@@`@W' @*#GNU C11 6.3.0 -mtune=generic -march=i586 -g3 -ggdb3 c:/Users/dandelot/test.c`@Wunsigned intshort unsigned intlong intlong long intintchar_iobuf C_ptrC_cntխ_baseC_flag׭ _fileح_charbuf٭_bufsizڭ_tmpfnameCFILEܼI` _iobUsomethingabj mainm@J argc argv xt yt soltC buffle `@   v l @: @../../../src/gcc-6.3.0/libgcc/config/i386/cygwin.S/home/keith/src/mingw/gcc-build/gcc-6.3.0-mingw32-cross-native/mingw32/libgccGNU AS 2.28TGNU C11 6.3.0 -mtune=generic -march=i586 -g -g -g -O2 -O2 -O2 -fbuilding-libgcc -fno-stack-protector ../../../src/gcc-6.3.0/libgcc/libgcc2.c/home/keith/src/mingw/gcc-build/gcc-6.3.0-mingw32-cross-native/mingw32/libgccuintunsigned intshort unsigned intlong long int long doublechar>long int_iobuf _ptr_cnt_base_flag _file_charbuf_bufsiz_tmpfname>FILEW _iobshort intlong unsigned int _argcc _argvdC __mb_cur_max _sys_nerry _sys_errlistn _osver _winver _winmajor _winminor _fmodeEsizetype optind< optopt= opterr> optargA _daylight\ _timezone]KS  _tzname^C daylight} timezone~K tznameChashval_t*htab_hash/ htab_eq6  htab_hash_pointer htab_eq_pointerunsigned charstringop_algno_stringoplibcallrep_prefix_1_byterep_prefix_4_byterep_prefix_8_byteloop_1_byteloopunrolled_loopvector_looplast_alg < F unspec_stringsB unspecv_stringsstringop_strategy zmaxalgnoalign7stringop_algs4unknown_sizesizez processor_costs̥ addleashift_varshift_const mult_initѺ mult_bit$divideԺ (movsx<movzx@large_insnDmove_ratioHmovzbl_loadLint_load Pint_store \fp_movehfp_load lfp_store xmmx_movemmx_load mmx_store sse_movesse_load sse_store mmxsse_to_integerl1_cache_sizel2_cache_sizeprefetch_blocksimultaneous_prefetchesbranch_costfaddfmulfdivfabsfchsfsqrtmemcpy memset scalar_stmt_costscalar_load_costscalar_store_costvec_stmt_costvec_to_scalar_costscalar_to_vec_cost vec_align_load_cost vec_unalign_load_cost vec_store_cost  cond_taken_branch_cost cond_not_taken_branch_cost       ix86_cost  ix86_size_cost ix86_tune_indiceskZX86_TUNE_SCHEDULEX86_TUNE_PARTIAL_REG_DEPENDENCYX86_TUNE_SSE_PARTIAL_REG_DEPENDENCYX86_TUNE_SSE_SPLIT_REGSX86_TUNE_PARTIAL_FLAG_REG_STALLX86_TUNE_MOVXX86_TUNE_MEMORY_MISMATCH_STALLX86_TUNE_FUSE_CMP_AND_BRANCH_32X86_TUNE_FUSE_CMP_AND_BRANCH_64X86_TUNE_FUSE_CMP_AND_BRANCH_SOFLAGS X86_TUNE_FUSE_ALU_AND_BRANCH X86_TUNE_REASSOC_INT_TO_PARALLEL X86_TUNE_REASSOC_FP_TO_PARALLEL X86_TUNE_ACCUMULATE_OUTGOING_ARGS X86_TUNE_PROLOGUE_USING_MOVEX86_TUNE_EPILOGUE_USING_MOVEX86_TUNE_USE_LEAVEX86_TUNE_PUSH_MEMORYX86_TUNE_SINGLE_PUSHX86_TUNE_DOUBLE_PUSHX86_TUNE_SINGLE_POPX86_TUNE_DOUBLE_POPX86_TUNE_PAD_SHORT_FUNCTIONX86_TUNE_PAD_RETURNSX86_TUNE_FOUR_JUMP_LIMITX86_TUNE_SOFTWARE_PREFETCHING_BENEFICIALX86_TUNE_LCP_STALLX86_TUNE_READ_MODIFYX86_TUNE_USE_INCDECX86_TUNE_INTEGER_DFMODE_MOVESX86_TUNE_OPT_AGUX86_TUNE_AVOID_LEA_FOR_ADDRX86_TUNE_SLOW_IMUL_IMM32_MEM X86_TUNE_SLOW_IMUL_IMM8!X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE"X86_TUNE_SINGLE_STRINGOP#X86_TUNE_MISALIGNED_MOVE_STRING_PRO_EPILOGUES$X86_TUNE_USE_SAHF%X86_TUNE_USE_CLTD&X86_TUNE_USE_BT'X86_TUNE_USE_HIMODE_FIOP(X86_TUNE_USE_SIMODE_FIOP)X86_TUNE_USE_FFREEP*X86_TUNE_EXT_80387_CONSTANTS+X86_TUNE_VECTORIZE_DOUBLE,X86_TUNE_GENERAL_REGS_SSE_SPILL-X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL.X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL/X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL0X86_TUNE_SSE_TYPELESS_STORES1X86_TUNE_SSE_LOAD0_BY_PXOR2X86_TUNE_INTER_UNIT_MOVES_TO_VEC3X86_TUNE_INTER_UNIT_MOVES_FROM_VEC4X86_TUNE_INTER_UNIT_CONVERSIONS5X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS6X86_TUNE_USE_VECTOR_FP_CONVERTS7X86_TUNE_USE_VECTOR_CONVERTS8X86_TUNE_SLOW_PSHUFB9X86_TUNE_VECTOR_PARALLEL_EXECUTION:X86_TUNE_AVOID_4BYTE_PREFIXES;X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL<X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL=X86_TUNE_AVX128_OPTIMAL>X86_TUNE_DOUBLE_WITH_ADD?X86_TUNE_ALWAYS_FANCY_MATH_387@X86_TUNE_UNROLL_STRLENAX86_TUNE_SHIFT1BX86_TUNE_ZERO_EXTEND_WITH_ANDCX86_TUNE_PROMOTE_HIMODE_IMULDX86_TUNE_FAST_PREFIXEX86_TUNE_READ_MODIFY_WRITEFX86_TUNE_MOVE_M1_VIA_ORGX86_TUNE_NOT_UNPAIRABLEHX86_TUNE_PARTIAL_REG_STALLIX86_TUNE_PROMOTE_QIMODEJX86_TUNE_PROMOTE_HI_REGSKX86_TUNE_HIMODE_MATHLX86_TUNE_SPLIT_LONG_MOVESMX86_TUNE_USE_XCHGBNX86_TUNE_USE_MOV0OX86_TUNE_NOT_VECTORMODEPX86_TUNE_AVOID_VECTOR_DECODEQX86_TUNE_AVOID_FALSE_DEP_FOR_BMIRX86_TUNE_BRANCH_PREDICTION_HINTSSX86_TUNE_QIMODE_MATHTX86_TUNE_PROMOTE_QI_REGSUX86_TUNE_ADJUST_UNROLLVX86_TUNE_ONE_IF_CONV_INSNWX86_TUNE_LASTX+j W ix86_tune_featuressZix86_arch_indicesX86_ARCH_CMOVX86_ARCH_CMPXCHGX86_ARCH_CMPXCHG8BX86_ARCH_XADDX86_ARCH_BSWAPX86_ARCH_LAST+  ix86_arch_features x86_prefetch_sse+_dont_use_tree_here_ x86_mfence1{Rreg_class;]NO_REGSAREGDREGCREGBREGSIREGDIREGAD_REGSCLOBBERED_REGSQ_REGS NON_Q_REGS INDEX_REGS LEGACY_REGS GENERAL_REGS FP_TOP_REGFP_SECOND_REGFLOAT_REGSSSE_FIRST_REGNO_REX_SSE_REGSSSE_REGSEVEX_SSE_REGSBND_REGSALL_SSE_REGSMMX_REGSFP_TOP_SSE_REGSFP_SECOND_SSE_REGSFLOAT_SSE_REGSFLOAT_INT_REGSINT_SSE_REGSFLOAT_INT_SSE_REGSMASK_EVEX_REGSMASK_REGSALL_REGS LIM_REG_CLASSES!r Pb dbx_register_mapcr dbx64_register_mapdr svr4_dbx_register_maper   x86_64_ms_sysv_extra_clobbered_registersgprocessor_typeqPROCESSOR_GENERICPROCESSOR_I386PROCESSOR_I486PROCESSOR_PENTIUMPROCESSOR_LAKEMONTPROCESSOR_PENTIUMPROPROCESSOR_PENTIUM4PROCESSOR_NOCONAPROCESSOR_CORE2PROCESSOR_NEHALEM PROCESSOR_SANDYBRIDGE PROCESSOR_HASWELL PROCESSOR_BONNELL PROCESSOR_SILVERMONT PROCESSOR_KNLPROCESSOR_SKYLAKE_AVX512PROCESSOR_INTELPROCESSOR_GEODEPROCESSOR_K6PROCESSOR_ATHLONPROCESSOR_K8PROCESSOR_AMDFAM10PROCESSOR_BDVER1PROCESSOR_BDVER2PROCESSOR_BDVER3PROCESSOR_BDVER4PROCESSOR_BTVER1PROCESSOR_BTVER2PROCESSOR_ZNVER1PROCESSOR_max ix86_tune  ix86_arch  ix86_preferred_stack_boundary! ix86_incoming_stack_boundary" ] P regclass_map% signed charUQItype u+long long unsigned intfloatcomplex floatdoublecomplex doublecomplex long double__float128 __unknown__(  __popcount_tab  __clz_tab func_ptr * __CTOR_LIST__ / __DTOR_LIST__ 0  ;@&  ;@% B$ >  : ;  : ; I8  I: ; II! 4: ; I?< .?: ; 'I@B : ; I 4: ; I .?: ; 'I@B%% $ > &I : ;  : ; I8  I: ; II ! 4: ; I?< 4: ;I?< !I/ 'II& I: ; (  : ;  : ;I8  : ;I8 I: ;<'4G: ; c:/Users/dandelotc:/mingw/includec:/mingw/lib/gcc/mingw32/6.3.0/includec:/mingw/include/systest.cstdio.h_mingw.hmsvcrtver.hw32api.hsdkddkver.hstddef.htypes.hstdarg.h`@ =1Z!mI ../../../src/gcc-6.3.0/libgcc/config/i386cygwin.S @""YK0g=YY0/>""SM /home/keith/mingw32-gcc-6.3.0/include../../../src/gcc-6.3.0/libgcc/../include../.././gcc../../../src/gcc-6.3.0/libgcc/../gcc/config/i386../../../src/gcc-6.3.0/libgccstdio.hstdlib.hgetopt.htime.hhashtab.hinsn-constants.hi386.hi386-opts.hlibgcc2.hgbl-ctors.hlibgcc2.c|   @*AA fA__STDC__ 1__STDC_VERSION__ 201112L__STDC_UTF_16__ 1__STDC_UTF_32__ 1__STDC_HOSTED__ 1__GNUC__ 6__GNUC_MINOR__ 3__GNUC_PATCHLEVEL__ 0__VERSION__ "6.3.0"__ATOMIC_RELAXED 0__ATOMIC_SEQ_CST 5__ATOMIC_ACQUIRE 2__ATOMIC_RELEASE 3__ATOMIC_ACQ_REL 4__ATOMIC_CONSUME 1__FINITE_MATH_ONLY__ 0__SIZEOF_INT__ 4__SIZEOF_LONG__ 4__SIZEOF_LONG_LONG__ 8__SIZEOF_SHORT__ 2__SIZEOF_FLOAT__ 4__SIZEOF_DOUBLE__ 8__SIZEOF_LONG_DOUBLE__ 12__SIZEOF_SIZE_T__ 4__CHAR_BIT__ 8__BIGGEST_ALIGNMENT__ 16__ORDER_LITTLE_ENDIAN__ 1234__ORDER_BIG_ENDIAN__ 4321__ORDER_PDP_ENDIAN__ 3412__BYTE_ORDER__ __ORDER_LITTLE_ENDIAN____FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN____SIZEOF_POINTER__ 4__SIZE_TYPE__ unsigned int__PTRDIFF_TYPE__ int__WCHAR_TYPE__ short unsigned int__WINT_TYPE__ short unsigned int__INTMAX_TYPE__ long long int__UINTMAX_TYPE__ long long unsigned int__CHAR16_TYPE__ short unsigned int__CHAR32_TYPE__ unsigned int__SIG_ATOMIC_TYPE__ int__INT8_TYPE__ signed char__INT16_TYPE__ short int__INT32_TYPE__ int__INT64_TYPE__ long long int__UINT8_TYPE__ unsigned char__UINT16_TYPE__ short unsigned int__UINT32_TYPE__ unsigned int__UINT64_TYPE__ long long unsigned int__INT_LEAST8_TYPE__ signed char__INT_LEAST16_TYPE__ short int__INT_LEAST32_TYPE__ int__INT_LEAST64_TYPE__ long long int__UINT_LEAST8_TYPE__ unsigned char__UINT_LEAST16_TYPE__ short unsigned int__UINT_LEAST32_TYPE__ unsigned int__UINT_LEAST64_TYPE__ long long unsigned int__INT_FAST8_TYPE__ signed char__INT_FAST16_TYPE__ short int__INT_FAST32_TYPE__ int__INT_FAST64_TYPE__ long long int__UINT_FAST8_TYPE__ unsigned char__UINT_FAST16_TYPE__ short unsigned int__UINT_FAST32_TYPE__ unsigned int__UINT_FAST64_TYPE__ long long unsigned int__INTPTR_TYPE__ int__UINTPTR_TYPE__ unsigned int__has_include(STR) __has_include__(STR)__has_include_next(STR) __has_include_next__(STR)__GXX_ABI_VERSION 1010__SCHAR_MAX__ 0x7f__SHRT_MAX__ 0x7fff__INT_MAX__ 0x7fffffff__LONG_MAX__ 0x7fffffffL__LONG_LONG_MAX__ 0x7fffffffffffffffLL__WCHAR_MAX__ 0xffff__WCHAR_MIN__ 0__WINT_MAX__ 0xffff__WINT_MIN__ 0__PTRDIFF_MAX__ 0x7fffffff__SIZE_MAX__ 0xffffffffU__INTMAX_MAX__ 0x7fffffffffffffffLL__INTMAX_C(c) c ## LL__UINTMAX_MAX__ 0xffffffffffffffffULL__UINTMAX_C(c) c ## ULL__SIG_ATOMIC_MAX__ 0x7fffffff__SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)__INT8_MAX__ 0x7f__INT16_MAX__ 0x7fff__INT32_MAX__ 0x7fffffff__INT64_MAX__ 0x7fffffffffffffffLL__UINT8_MAX__ 0xff__UINT16_MAX__ 0xffff__UINT32_MAX__ 0xffffffffU__UINT64_MAX__ 0xffffffffffffffffULL__INT_LEAST8_MAX__ 0x7f__INT8_C(c) c__INT_LEAST16_MAX__ 0x7fff__INT16_C(c) c__INT_LEAST32_MAX__ 0x7fffffff__INT32_C(c) c__INT_LEAST64_MAX__ 0x7fffffffffffffffLL__INT64_C(c) c ## LL__UINT_LEAST8_MAX__ 0xff__UINT8_C(c) c__UINT_LEAST16_MAX__ 0xffff__UINT16_C(c) c__UINT_LEAST32_MAX__ 0xffffffffU__UINT32_C(c) c ## U__UINT_LEAST64_MAX__ 0xffffffffffffffffULL__UINT64_C(c) c ## ULL__INT_FAST8_MAX__ 0x7f__INT_FAST16_MAX__ 0x7fff__INT_FAST32_MAX__ 0x7fffffff__INT_FAST64_MAX__ 0x7fffffffffffffffLL__UINT_FAST8_MAX__ 0xff__UINT_FAST16_MAX__ 0xffff__UINT_FAST32_MAX__ 0xffffffffU__UINT_FAST64_MAX__ 0xffffffffffffffffULL__INTPTR_MAX__ 0x7fffffff__UINTPTR_MAX__ 0xffffffffU__GCC_IEC_559 2__GCC_IEC_559_COMPLEX 2__FLT_EVAL_METHOD__ 2__DEC_EVAL_METHOD__ 2__FLT_RADIX__ 2__FLT_MANT_DIG__ 24__FLT_DIG__ 6__FLT_MIN_EXP__ (-125)__FLT_MIN_10_EXP__ (-37)__FLT_MAX_EXP__ 128__FLT_MAX_10_EXP__ 38__FLT_DECIMAL_DIG__ 9__FLT_MAX__ 3.40282346638528859812e+38F__FLT_MIN__ 1.17549435082228750797e-38F__FLT_EPSILON__ 1.19209289550781250000e-7F__FLT_DENORM_MIN__ 1.40129846432481707092e-45F__FLT_HAS_DENORM__ 1__FLT_HAS_INFINITY__ 1__FLT_HAS_QUIET_NAN__ 1__DBL_MANT_DIG__ 53__DBL_DIG__ 15__DBL_MIN_EXP__ (-1021)__DBL_MIN_10_EXP__ (-307)__DBL_MAX_EXP__ 1024__DBL_MAX_10_EXP__ 308__DBL_DECIMAL_DIG__ 17__DBL_MAX__ ((double)1.79769313486231570815e+308L)__DBL_MIN__ ((double)2.22507385850720138309e-308L)__DBL_EPSILON__ ((double)2.22044604925031308085e-16L)__DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L)__DBL_HAS_DENORM__ 1__DBL_HAS_INFINITY__ 1__DBL_HAS_QUIET_NAN__ 1__LDBL_MANT_DIG__ 64__LDBL_DIG__ 18__LDBL_MIN_EXP__ (-16381)__LDBL_MIN_10_EXP__ (-4931)__LDBL_MAX_EXP__ 16384__LDBL_MAX_10_EXP__ 4932__DECIMAL_DIG__ 21__LDBL_MAX__ 1.18973149535723176502e+4932L__LDBL_MIN__ 3.36210314311209350626e-4932L__LDBL_EPSILON__ 1.08420217248550443401e-19L__LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L__LDBL_HAS_DENORM__ 1__LDBL_HAS_INFINITY__ 1__LDBL_HAS_QUIET_NAN__ 1__DEC32_MANT_DIG__ 7__DEC32_MIN_EXP__ (-94)__DEC32_MAX_EXP__ 97__DEC32_MIN__ 1E-95DF__DEC32_MAX__ 9.999999E96DF__DEC32_EPSILON__ 1E-6DF__DEC32_SUBNORMAL_MIN__ 0.000001E-95DF__DEC64_MANT_DIG__ 16__DEC64_MIN_EXP__ (-382)__DEC64_MAX_EXP__ 385__DEC64_MIN__ 1E-383DD__DEC64_MAX__ 9.999999999999999E384DD__DEC64_EPSILON__ 1E-15DD__DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD__DEC128_MANT_DIG__ 34__DEC128_MIN_EXP__ (-6142)__DEC128_MAX_EXP__ 6145__DEC128_MIN__ 1E-6143DL__DEC128_MAX__ 9.999999999999999999999999999999999E6144DL__DEC128_EPSILON__ 1E-33DL__DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL__REGISTER_PREFIX__ __USER_LABEL_PREFIX__ ___GNUC_STDC_INLINE__ 1__NO_INLINE__ 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1__GCC_ATOMIC_BOOL_LOCK_FREE 2__GCC_ATOMIC_CHAR_LOCK_FREE 2__GCC_ATOMIC_CHAR16_T_LOCK_FREE 2__GCC_ATOMIC_CHAR32_T_LOCK_FREE 2__GCC_ATOMIC_WCHAR_T_LOCK_FREE 2__GCC_ATOMIC_SHORT_LOCK_FREE 2__GCC_ATOMIC_INT_LOCK_FREE 2__GCC_ATOMIC_LONG_LOCK_FREE 2__GCC_ATOMIC_LLONG_LOCK_FREE 2__GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1__GCC_ATOMIC_POINTER_LOCK_FREE 2__GCC_HAVE_DWARF2_CFI_ASM 1__PRAGMA_REDEFINE_EXTNAME 1__SIZEOF_WCHAR_T__ 2__SIZEOF_WINT_T__ 2__SIZEOF_PTRDIFF_T__ 4__i386 1__i386__ 1i386 1__SIZEOF_FLOAT80__ 12__SIZEOF_FLOAT128__ 16__ATOMIC_HLE_ACQUIRE 65536__ATOMIC_HLE_RELEASE 131072__GCC_ASM_FLAG_OUTPUTS__ 1__i586 1__i586__ 1__pentium 1__pentium__ 1__code_model_32__ 1__SEG_FS 1__SEG_GS 1_X86_ 1__stdcall __attribute__((__stdcall__))__fastcall __attribute__((__fastcall__))__thiscall __attribute__((__thiscall__))__cdecl __attribute__((__cdecl__))_stdcall __attribute__((__stdcall__))_fastcall __attribute__((__fastcall__))_thiscall __attribute__((__thiscall__))_cdecl __attribute__((__cdecl__))__GXX_MERGED_TYPEINFO_NAMES 0__GXX_TYPEINFO_EQUALITY_INLINE 0__MSVCRT__ 1__MINGW32__ 1_WIN32 1__WIN32 1__WIN32__ 1WIN32 1__WINNT 1__WINNT__ 1WINNT 1_INTEGRAL_MAX_BITS 64__declspec(x) __attribute__((x))__DECIMAL_BID_FORMAT__ 13_STDIO_H 8"__MINGW_H 1__MINGW32_VERSION 5000001L2__MINGW32_MAJOR_VERSION 53__MINGW32_MINOR_VERSION 04__MINGW32_PATCHLEVEL 1B"_MSVCRTVER_H *__MSVCR60_DLL 0x0600+__MSVCR61_DLL 0x0601,__MSVCR70_DLL 0x0700-__MSVCR71_DLL 0x0701.__MSVCR80_DLL 0x0800/__MSVCR90_DLL 0x09000__MSVCR100_DLL 0x10001__MSVCR110_DLL 0x11002__MSVCR120_DLL 0x1200D__MSVCRT_VERSION__ __MSVCR60_DLLI"_W32API_H 3__W32API_VERSION 5000001L4__W32API_MAJOR_VERSION 55__W32API_MINOR_VERSION 06__W32API_PATCHLEVEL 1;"_SDKDDKVER_H )OSVERSION_MASK 0xFFFF0000*SPVERSION_MASK 0x0000FF00+SUBVERSION_MASK 0x000000FF0OSVER(ver) ((ver) & OSVERSION_MASK)1SPVER(ver) (((ver) & SPVERSION_MASK) >> 8)2SUBVER(ver) ((ver) & SUBVERSION_MASK)3WINNTVER(ver) ((ver) >> 16)7NTDDI_VERSION_FROM_WIN32_WINNT(ver) _NTDDI_VERSION_FROM_WIN32_WINNT(ver)8_NTDDI_VERSION_FROM_WIN32_WINNT(ver) ver ##0000>_WIN32_WINNT_NT4 0x0400?_WIN32_WINNT_NT4E 0x0401@_WIN32_WINNT_NT4SP3 0x0403A_WIN32_WINDOWS_95 0x0400B_WIN32_WINDOWS_98 0x0410C_WIN32_WINDOWS_ME 0x0490D_WIN32_WINNT_WIN2K 0x0500E_WIN32_WINNT_WINXP 0x0501F_WIN32_WINNT_WS03 0x0502G_WIN32_WINNT_WIN6 0x0600H_WIN32_WINNT_VISTA 0x0600I_WIN32_WINNT_WS08 0x0600J_WIN32_WINNT_LONGHORN 0x0600K_WIN32_WINNT_WIN7 0x0601L_WIN32_WINNT_WIN8 0x0602M_WIN32_WINNT_WINBLUE 0x0603R_WIN32_IE_IE50 0x0500S_WIN32_IE_IE501 0x0501T_WIN32_IE_IE55 0x0550U_WIN32_IE_IE56 0x0560V_WIN32_IE_IE60 0x0600W_WIN32_IE_IE60SP1 0x0601X_WIN32_IE_IE60SP2 0x0603Y_WIN32_IE_IE70 0x0700Z_WIN32_IE_IE80 0x0800\_WIN32_IE_IE30 0x0300]_WIN32_IE_IE301 0x0301^_WIN32_IE_IE302 0x0302__WIN32_IE_IE40 0x0400`_WIN32_IE_IE401 0x0401e__NTDDI_WIN5 0x05000000f__NTDDI_WIN51 0x05010000g__NTDDI_WIN52 0x05020000h__NTDDI_WIN6 0x06000000i__NTDDI_WIN61 0x06010000j__NTDDI_WIN62 0x06020000k__NTDDI_WIN63 0x06030000l__NTDDI_SP0 0x00000000m__NTDDI_SP1 0x00000100n__NTDDI_SP2 0x00000200o__NTDDI_SP3 0x00000300p__NTDDI_SP4 0x00000400rNTDDI_WIN2K __NTDDI_WIN5 + __NTDDI_SP0sNTDDI_WIN2KSP1 __NTDDI_WIN5 + __NTDDI_SP1tNTDDI_WIN2KSP2 __NTDDI_WIN5 + __NTDDI_SP2uNTDDI_WIN2KSP3 __NTDDI_WIN5 + __NTDDI_SP3vNTDDI_WIN2KSP4 __NTDDI_WIN5 + __NTDDI_SP4xNTDDI_WINXP __NTDDI_WIN51 + __NTDDI_SP0yNTDDI_WINXPSP1 __NTDDI_WIN51 + __NTDDI_SP1zNTDDI_WINXPSP2 __NTDDI_WIN51 + __NTDDI_SP2{NTDDI_WINXPSP3 __NTDDI_WIN51 + __NTDDI_SP3}NTDDI_WS03 __NTDDI_WIN52 + __NTDDI_SP0~NTDDI_WS03SP1 __NTDDI_WIN52 + __NTDDI_SP1NTDDI_WS03SP2 __NTDDI_WIN52 + __NTDDI_SP2NTDDI_VISTA __NTDDI_WIN6 + __NTDDI_SP0NTDDI_VISTASP1 __NTDDI_WIN6 + __NTDDI_SP1NTDDI_VISTASP2 __NTDDI_WIN6 + __NTDDI_SP2NTDDI_LONGHORN NTDDI_VISTANTDDI_WIN6 NTDDI_VISTANTDDI_WIN6SP1 NTDDI_VISTASP1NTDDI_WIN6SP2 NTDDI_VISTASP2NTDDI_WS08 __NTDDI_WIN6 + __NTDDI_SP1NTDDI_WIN7 __NTDDI_WIN61 + __NTDDI_SP0NTDDI_WIN8 __NTDDI_WIN62 + __NTDDI_SP0NTDDI_WINBLUE __NTDDI_WIN63 + __NTDDI_SP0_WIN32_WINNT _WIN32_WINNT_WIN2KWINVER _WIN32_WINNTNTDDI_VERSION NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)_M_IX86 500_M_IX86_FP 0OWindows95 _WIN32_WINDOWS_95PWindows98 _WIN32_WINDOWS_98QWindowsME _WIN32_WINDOWS_MEYWindowsNT4 _WIN32_WINNT_NT4ZWindows2000 _WIN32_WINNT_WIN2K[WindowsXP _WIN32_WINNT_WINXP\Windows2003 _WIN32_WINNT_WS03]WindowsVista _WIN32_WINNT_VISTAeIE3 _WIN32_IE_IE30fIE301 _WIN32_IE_IE301gIE302 _WIN32_IE_IE302hIE4 _WIN32_IE_IE40iIE401 _WIN32_IE_IE401jIE5 _WIN32_IE_IE50kIE5a _WIN32_IE_IE50lIE5b _WIN32_IE_IE50mIE501 _WIN32_IE_IE501nIE55 _WIN32_IE_IE55oIE56 _WIN32_IE_IE56pIE6 _WIN32_IE_IE60qIE601 _WIN32_IE_IE60SP1rIE602 _WIN32_IE_IE60SP2sIE7 _WIN32_IE_IE70__AW_SUFFIXED__(__NAME__) __NAME__ ##A__AW_EXTENDED__(__NAME__) __AW_SUFFIXED__(__NAME__ ##_)__AW_STRING_A__(__TEXT__) __TEXT____AW__WCHAR_T__(__TEXT__) __AW_STRING_A__(L ##__TEXT__)__AW_STRING_W__(__TEXT__) __AW__WCHAR_T__(__TEXT__)__AW_ALIAS__(__NAME__) __AW_SUFFIXED__(__NAME__) __NAME____AW_ALIAS_EX__(__NAME__) __AW_EXTENDED__(__NAME__) __NAME___EXTERN_C extern_BEGIN_C_DECLS _END_C_DECLS m__CRT_GLOB_USE_MSVCRT__ 0x0001r__CRT_GLOB_USE_MINGW__ 0x0002__CRT_GLOB_USE_SINGLE_QUOTE__ 0x0010__CRT_GLOB_BRACKET_GROUPS__ 0x0020__CRT_GLOB_ESCAPE_CHAR__ (char)(127)__MINGW_ANSI_STDIO__ 0x0000000000000001ULL__MINGW_LC_EXTENSIONS__ 0x0000000000000050ULL__MINGW_LC_MESSAGES__ 0x0000000000000010ULL__MINGW_LC_ENVVARS__ 0x0000000000000040ULL__attribute____MINGW_IMPORT extern __attribute__((__dllimport__))_CRTIMP __DECLSPEC_SUPPORTED __int64 long long__int32 long__int16 short__int8 char__small char__hyper long long__MINGW_GNUC_PREREQ(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))__CRT_INLINE extern inline __attribute__((__gnu_inline__))_CRTALIAS __CRT_INLINE __attribute__((__always_inline__))__CRT_ALIAS __CRT_INLINE __attribute__((__always_inline__))__JMPSTUB__(__BUILD_HINT__) __LIBIMPL__(__BUILD_HINT__) __UNUSED_PARAM(x) x __attribute__((__unused__))__MINGW_ATTRIB_NORETURN __attribute__((__noreturn__))__MINGW_ATTRIB_CONST __attribute__((__const__))__MINGW_ATTRIB_MALLOC __attribute__((__malloc__))__MINGW_ATTRIB_PURE __attribute__((__pure__))__MINGW_ATTRIB_NONNULL(arg) __attribute__((__nonnull__(arg)))__MINGW_ATTRIB_DEPRECATED __attribute__((__deprecated__))__MINGW_NOTHROW __attribute__((__nothrow__))__USE_MINGW_ANSI_STDIO (__MINGW_FEATURES__ & __MINGW_ANSI_STDIO__)__paste(prefix,suffix) prefix ## suffix__valueless(token) ((token - 0) == 0) && (__paste(token,10) == 10)_POSIX_C_SOURCE 200809L_EMULATE_GLIBC 1_ISOC99_SOURCE 0x07_MINGW32_SOURCE_EXTENDED 1A__need_NULL B__need_size_t C__need_wchar_t D__need_wint_t E__size_t__ __SIZE_T__ _SIZE_T _SYS_SIZE_T_H _T_SIZE_ _T_SIZE __SIZE_T _SIZE_T_ _BSD_SIZE_T_ _SIZE_T_DEFINED_ _SIZE_T_DEFINED _BSD_SIZE_T_DEFINED_ _SIZE_T_DECLARED ___int_size_t_h _GCC_SIZE_T _SIZET_ __size_t __need_size_t__wchar_t__ __WCHAR_T__ _WCHAR_T _T_WCHAR_ _T_WCHAR __WCHAR_T _WCHAR_T_ _BSD_WCHAR_T_ _WCHAR_T_DEFINED_ _WCHAR_T_DEFINED _WCHAR_T_H ___int_wchar_t_h __INT_WCHAR_T_H _GCC_WCHAR_T _WCHAR_T_DECLARED _BSD_WCHAR_T___need_wchar_t_WINT_T __need_wint_tNULLNULL ((void *)0)__need_NULLK__need_off_t L__need_ssize_t S__need___off64_t ^T__need_off_tl__need___off64_t__need_ssize_t__need_time_te__need___va_list f "__need___va_list'__GNUC_VA_LIST g__VALIST __builtin_va_listq_IOREAD 1r_IOWRT 2s_IORW 0x0080xSTDIN_FILENO 0ySTDOUT_FILENO 1zSTDERR_FILENO 2~EOF (-1)FILENAME_MAX (260)FOPEN_MAX (20)TMP_MAX 32767_P_tmpdir "\\"P_tmpdir _P_tmpdir_wP_tmpdir L"\\"L_tmpnam (16)_IOFBF 0x0000_IOLBF 0x0040_IONBF 0x0004_IOMYBUF 0x0008_IOEOF 0x0010_IOERR 0x0020_IOSTRG 0x0040BUFSIZ 512SEEK_SET 0SEEK_CUR 1SEEK_END 2stdin (&_iob[STDIN_FILENO])stdout (&_iob[STDOUT_FILENO])stderr (&_iob[STDERR_FILENO])__mingw_stdio_redirect____mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __Wformat(F)__Wformat_mingw_printf(F,A) __attribute__((__format__(__mingw_printf__,F,A)))__Wformat(F) __Wformat_ ##F __mingw_ ##F__Wformat_printf __Wformat_mingw_printf(1,2)__Wformat_fprintf __Wformat_mingw_printf(2,3)__Wformat_sprintf __Wformat_mingw_printf(2,3)__Wformat_vprintf __Wformat_mingw_printf(1,0)__Wformat_vfprintf __Wformat_mingw_printf(2,0)__Wformat_vsprintf __Wformat_mingw_printf(2,0)__Wformat_snprintf __Wformat_mingw_printf(3,4)__Wformat_vsnprintf __Wformat_mingw_printf(3,0)_MSVC_PRINTF_QUIRKS 0x0100U_QUERY_MSVC_PRINTF_QUIRKS ~0U, 0U_DISABLE_MSVC_PRINTF_QUIRKS ~_MSVC_PRINTF_QUIRKS, 0U_ENABLE_MSVC_PRINTF_QUIRKS ~0U, _MSVC_PRINTF_QUIRKS__Wformat__mingw_stdio_redirect____mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __Wformat(F)__Wformat_msvcrt_printf(F,A) __attribute__((__format__(__ms_printf__,F,A)))__Wformat(F) __Wformat_ms_ ##F __msvcrt_ ##F__Wformat_ms_printf __Wformat_msvcrt_printf(1,2)__Wformat_ms_fprintf __Wformat_msvcrt_printf(2,3)__Wformat_ms_sprintf __Wformat_msvcrt_printf(2,3)__Wformat_ms_vprintf __Wformat_msvcrt_printf(1,0)__Wformat_ms_vfprintf __Wformat_msvcrt_printf(2,0)__Wformat_ms_vsprintf __Wformat_msvcrt_printf(2,0)__mingw_stdio_redirect____Wformatfeof(__F) ((__F)->_flag & _IOEOF)ferror(__F) ((__F)->_flag & _IOERR)_TWO_DIGIT_EXPONENT 1_THREE_DIGIT_EXPONENT 0_EXPONENT_DIGIT_MASK (_TWO_DIGIT_EXPONENT | _THREE_DIGIT_EXPONENT)__USE_MINGW_PRINTF 0_fileno(__F) ((__F)->_file)fileno(__F) ((__F)->_file)] u  _atexit  __onexit0 .text6*.bss.filegcygming-crtbegin.c_obj@ 0 .text@.data.bssd.rdatacD.jcr.fileigtest.c_buffle` _mainm .text`W.data.bss  '    '?4 X#X@ .textJ` .text` .bss$_@  rp  ___main  .text@  .data.bss(0    .text .bss,.CRT$XDZ.CRT$XDA.CRT$XLA.tls$ZZZ.tls$AAA0    `  .text '#.bss< @ .text  !.bss\.rdatah.file{gfake'   4 q.text*.data.bssh   8.file glibgcc2.c.text<.data.bssh X  @ 4u Wl!@ .text@l.data+ 9  .text4.rdataK0! .text0!.bssh.rdata(\& mp( ~( ) p) ) .text0%.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6v.idata$5.idata$6j.idata$5.idata$6`.idata$5.idata$6V.idata$5.idata$6J.idata$5.idata$6@.idata$5.idata$66.idata$5.idata$6..idata$5.idata$6$.idata$6.idata$5.idata$6.idata$5.idata$6.idata$6.idata$6.idata$5.idata$6.idata$6.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6.idata$5.idata$6.idata$6r.idata$5|.idata$6b.idata$4.idata$5|.idata$5h.idata$6<.idata$5d.idata$6*.idata$5`.idata$6.idata$5\.idata$6.idata$5X.idata$6.idata$5T.idata$6.idata$5P.idata$6.idata$5L.idata$6.idata$5H.idata$6.idata$5D.idata$6.idata$5@.idata$6r.idata$5<.idata$6d.idata$58.idata$6T.idata$54.idata$6B.idata$50.idata$66.idata$5,.idata$6(.idata$5(.idata$6.idata$5$.idata$6.idata$4P.idata$5$.idata$5t.idata$6V.idata$5p.idata$6L.idata$4.idata$5p.file$gcygming-crtend.c + .textx+.data.bssl <.jcr+ +.idata$5.idata$6.idata$5.idata$64__cexit* )* <[l@+ ~0+ +_free* d* D* $h;8Ra`vP__errno* `+ ___xl_c 2N`rt___xl_z  + * 4+ # :Pl]p * L3+ EW_strcoll@* g(+ z__dll___fwritex* (@*  *  * '<_memcpy`* <H]{P* __argcP+ * H+ _tolower0* ___xl_a___xl_d+h*  __CRT_MTd p + ; 8G _strdupp+ __argvY +_calloc* __fmode h {  8+   T_reallocX*      $ h+ ) __end__3 H_signalH* _mallocp* M +[ k  X+  *    @   D O _abort* ] r |  , , +  $  \ 8 P a p { *       0  _strlen8*  4 0L * [ $z +  @ X    d#.>(* H(ft.eh_frame.debug_aranges.debug_info.debug_abbrev.debug_line.debug_frame.debug_macro__mingw32_init_mainargs_mainCRTStartup_WinMainCRTStartup_deregister_frame_fn___JCR_LIST_____gcc_register_frame___gcc_deregister_frame.eh_frame.rdata$zzz.debug_info.debug_abbrev.debug_aranges.debug_macro.debug_line__setargv___cpu_features_init___do_global_dtors___do_global_ctors___dyn_tls_init@12___tlregdtor____w64_mingwthr_add_key_dtor____w64_mingwthr_remove_key_dtor___mingw_TLScallback__pei386_runtime_relocator.debug_frame_fesetenv___mingw_glob___mingw_globfree___mingw_dirname___mingw_opendir___mingw_readdir___mingw_closedir___mingw_rewinddir___mingw_telldir___mingw_seekdir___FRAME_END_____JCR_END___register_frame_ctor.text.startup.ctors.65535__imp__FindFirstFileA@8_VirtualProtect@16___RUNTIME_PSEUDO_RELOC_LIST____imp___fullpath_FindFirstFileA@8__imp___setmode__data_start___FreeLibrary@4___DTOR_LIST____imp__VirtualProtect@16__imp___onexit___p__fmode__imp__GetLastError@0_SetUnhandledExceptionFilter@4__imp__VirtualQuery@12__imp__FindNextFileA@8___tls_start____imp__TlsGetValue@4__libmsvcrt_a_iname__imp__InitializeCriticalSection@4_DeleteCriticalSection@4__rt_psrelocs_start__imp__abort__dll_characteristics____size_of_stack_commit____size_of_stack_reserve____major_subsystem_version_____crt_xl_start_____crt_xi_start_____crt_xi_end____imp__stricoll__imp____mb_cur_max_GetLastError@0__imp____p__environ__imp___pctype_VirtualQuery@12_mingw_initltsdrot_force__imp___iob_GetModuleHandleA@4___register_frame_info__libmoldname_a_iname_hmod_libgcc.weak.___register_frame_info.___EH_FRAME_BEGIN____imp__strdup__imp___isctype__bss_start_____RUNTIME_PSEUDO_RELOC_LIST_END____fpreset__size_of_heap_commit____imp___errno___p__environ__imp__GetProcAddress@8_GetProcAddress@8___crt_xp_start____imp__wcstombs_GetCommandLineA@0___crt_xp_end____imp__signal__minor_os_version____imp__atexit__imp__mbstowcs__head_libmsvcrt_a__image_base____isctype__section_alignment___LoadLibraryA@4_wcstombs__imp__FreeLibrary@4__IAT_end____head_libmoldname_a__RUNTIME_PSEUDO_RELOC_LIST___setlocale__imp____p__fmode__tls_start_ExitProcess@4__imp__strcoll__data_end_____getmainargs_FindClose@4__CTOR_LIST___mbstowcs___set_app_type__bss_end____CRT_fmode___crt_xc_end____tls_index___crt_xc_start_____CTOR_LIST____rt_psrelocs_size__imp__memcpy_FindNextFileA@8__file_alignment____imp__LeaveCriticalSection@4__imp__malloc___EH_FRAME_BEGIN____major_os_version____imp__realloc__IAT_start___stricoll__tls_end__imp__GetModuleHandleA@4__DTOR_LIST____imp___fpreset.weak.___deregister_frame_info.___EH_FRAME_BEGIN___EnterCriticalSection@4__fullpath__size_of_heap_reserve_____crt_xt_start_____ImageBase__subsystem____imp__strlen.weak.__Jv_RegisterClasses.___EH_FRAME_BEGIN____CRT_fenv__imp__calloc__Jv_RegisterClasses__imp____getmainargs___tls_end____imp__ExitProcess@4_mingw_initltssuo_force_InitializeCriticalSection@4___cpu_features__imp__free__imp__SetUnhandledExceptionFilter@4___deregister_frame_info__major_image_version____loader_flags____imp__tolower__CRT_glob__setmode___chkstk_ms__head_libkernel32_a__rt_psrelocs_end__imp___cexit__minor_subsystem_version____imp__FindClose@4__minor_image_version____imp__vfprintf__imp____set_app_type_mingw_initltsdyn_force_TlsGetValue@4__imp__DeleteCriticalSection@4_LeaveCriticalSection@4__imp__GetCommandLineA@0__imp__LoadLibraryA@4__imp__setlocale__RUNTIME_PSEUDO_RELOC_LIST_END____libkernel32_a_iname___dyn_tls_init_callback__tls_used___crt_xt_end___vfprintf__imp__EnterCriticalSection@4__imp__fwritedwarfutils-20200114/dwarfdump/testobjLE32PE.test.c000066400000000000000000000007361361531463500215460ustar00rootroot00000000000000/* This is the test file used to compile testobjLE32PE.exe under MinGW on Windows 8.1 These leading comments mean a recompile would not exactly match line numbers in the DWARF. */ #include struct something { int a; unsigned b; }; int buffle(struct something *v ) { return v->a + 42; } int main(int argc, char **argv) { int x = 12; int y = 24; struct something so; so.a = x; x = buffle(&so); return x +y + 4 +argc; } dwarfutils-20200114/dwarfdump/testuriLE64ELf.base000066400000000000000000000742451361531463500214620ustar00rootroot00000000000000 .debug_info COMPILE_UNIT
: < 0><0x0000000b> DW_TAG_compile_unit DW_AT_producer GNU C11 7.4.0 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strong DW_AT_language DW_LANG_C99 DW_AT_name /home/davea/dwarf/code/dwarfdump/uri.c DW_AT_comp_dir /tmp/dwbld/dwarfdump DW_AT_low_pc 0x00000000 DW_AT_high_pc 618 DW_AT_stmt_list 0x00000000 LOCAL_SYMBOLS: < 1><0x0000002d> DW_TAG_typedef DW_AT_name size_t DW_AT_decl_file 0x00000003 /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h DW_AT_decl_line 0x000000d8 DW_AT_type <0x00000038> < 1><0x00000038> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_unsigned DW_AT_name long unsigned int < 1><0x0000003f> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_unsigned_char DW_AT_name unsigned char < 1><0x00000046> DW_TAG_base_type DW_AT_byte_size 0x00000002 DW_AT_encoding DW_ATE_unsigned DW_AT_name short unsigned int < 1><0x0000004d> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_unsigned DW_AT_name unsigned int < 1><0x00000054> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_signed_char DW_AT_name signed char < 1><0x0000005b> DW_TAG_base_type DW_AT_byte_size 0x00000002 DW_AT_encoding DW_ATE_signed DW_AT_name short int < 1><0x00000062> DW_TAG_base_type DW_AT_byte_size 0x00000004 DW_AT_encoding DW_ATE_signed DW_AT_name int < 1><0x00000069> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_signed DW_AT_name long int < 1><0x00000070> DW_TAG_typedef DW_AT_name __off_t DW_AT_decl_file 0x00000004 /usr/include/x86_64-linux-gnu/bits/types.h DW_AT_decl_line 0x0000008c DW_AT_type <0x00000069> < 1><0x0000007b> DW_TAG_typedef DW_AT_name __off64_t DW_AT_decl_file 0x00000004 /usr/include/x86_64-linux-gnu/bits/types.h DW_AT_decl_line 0x0000008d DW_AT_type <0x00000069> < 1><0x00000086> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 < 1><0x00000088> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000008e> < 1><0x0000008e> DW_TAG_base_type DW_AT_byte_size 0x00000001 DW_AT_encoding DW_ATE_signed_char DW_AT_name char < 1><0x00000095> DW_TAG_const_type DW_AT_type <0x0000008e> < 1><0x0000009a> DW_TAG_structure_type DW_AT_name _IO_FILE DW_AT_byte_size 0x000000d8 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000f5 DW_AT_sibling <0x0000021a> < 2><0x000000a6> DW_TAG_member DW_AT_name _flags DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000f6 DW_AT_type <0x00000062> DW_AT_data_member_location 0 < 2><0x000000b2> DW_TAG_member DW_AT_name _IO_read_ptr DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fb DW_AT_type <0x00000088> DW_AT_data_member_location 8 < 2><0x000000be> DW_TAG_member DW_AT_name _IO_read_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fc DW_AT_type <0x00000088> DW_AT_data_member_location 16 < 2><0x000000ca> DW_TAG_member DW_AT_name _IO_read_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fd DW_AT_type <0x00000088> DW_AT_data_member_location 24 < 2><0x000000d6> DW_TAG_member DW_AT_name _IO_write_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000fe DW_AT_type <0x00000088> DW_AT_data_member_location 32 < 2><0x000000e2> DW_TAG_member DW_AT_name _IO_write_ptr DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000ff DW_AT_type <0x00000088> DW_AT_data_member_location 40 < 2><0x000000ee> DW_TAG_member DW_AT_name _IO_write_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000100 DW_AT_type <0x00000088> DW_AT_data_member_location 48 < 2><0x000000fb> DW_TAG_member DW_AT_name _IO_buf_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000101 DW_AT_type <0x00000088> DW_AT_data_member_location 56 < 2><0x00000108> DW_TAG_member DW_AT_name _IO_buf_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000102 DW_AT_type <0x00000088> DW_AT_data_member_location 64 < 2><0x00000115> DW_TAG_member DW_AT_name _IO_save_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000104 DW_AT_type <0x00000088> DW_AT_data_member_location 72 < 2><0x00000122> DW_TAG_member DW_AT_name _IO_backup_base DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000105 DW_AT_type <0x00000088> DW_AT_data_member_location 80 < 2><0x0000012f> DW_TAG_member DW_AT_name _IO_save_end DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000106 DW_AT_type <0x00000088> DW_AT_data_member_location 88 < 2><0x0000013c> DW_TAG_member DW_AT_name _markers DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000108 DW_AT_type <0x0000025d> DW_AT_data_member_location 96 < 2><0x00000149> DW_TAG_member DW_AT_name _chain DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000010a DW_AT_type <0x00000263> DW_AT_data_member_location 104 < 2><0x00000156> DW_TAG_member DW_AT_name _fileno DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000010c DW_AT_type <0x00000062> DW_AT_data_member_location 112 < 2><0x00000163> DW_TAG_member DW_AT_name _flags2 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000110 DW_AT_type <0x00000062> DW_AT_data_member_location 116 < 2><0x00000170> DW_TAG_member DW_AT_name _old_offset DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000112 DW_AT_type <0x00000070> DW_AT_data_member_location 120 < 2><0x0000017d> DW_TAG_member DW_AT_name _cur_column DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000116 DW_AT_type <0x00000046> DW_AT_data_member_location 128 (-128) < 2><0x0000018a> DW_TAG_member DW_AT_name _vtable_offset DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000117 DW_AT_type <0x00000054> DW_AT_data_member_location 130 (-126) < 2><0x00000197> DW_TAG_member DW_AT_name _shortbuf DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000118 DW_AT_type <0x00000269> DW_AT_data_member_location 131 (-125) < 2><0x000001a4> DW_TAG_member DW_AT_name _lock DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000011c DW_AT_type <0x00000279> DW_AT_data_member_location 136 (-120) < 2><0x000001b1> DW_TAG_member DW_AT_name _offset DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000125 DW_AT_type <0x0000007b> DW_AT_data_member_location 144 (-112) < 2><0x000001be> DW_TAG_member DW_AT_name __pad1 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000012d DW_AT_type <0x00000086> DW_AT_data_member_location 152 (-104) < 2><0x000001cb> DW_TAG_member DW_AT_name __pad2 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000012e DW_AT_type <0x00000086> DW_AT_data_member_location 160 (-96) < 2><0x000001d8> DW_TAG_member DW_AT_name __pad3 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000012f DW_AT_type <0x00000086> DW_AT_data_member_location 168 (-88) < 2><0x000001e5> DW_TAG_member DW_AT_name __pad4 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000130 DW_AT_type <0x00000086> DW_AT_data_member_location 176 (-80) < 2><0x000001f2> DW_TAG_member DW_AT_name __pad5 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000132 DW_AT_type <0x0000002d> DW_AT_data_member_location 184 (-72) < 2><0x000001ff> DW_TAG_member DW_AT_name _mode DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000133 DW_AT_type <0x00000062> DW_AT_data_member_location 192 (-64) < 2><0x0000020c> DW_TAG_member DW_AT_name _unused2 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000135 DW_AT_type <0x0000027f> DW_AT_data_member_location 196 (-60) < 1><0x0000021a> DW_TAG_typedef DW_AT_name FILE DW_AT_decl_file 0x00000006 /usr/include/x86_64-linux-gnu/bits/types/FILE.h DW_AT_decl_line 0x00000007 DW_AT_type <0x0000009a> < 1><0x00000225> DW_TAG_typedef DW_AT_name _IO_lock_t DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000009a < 1><0x0000022c> DW_TAG_structure_type DW_AT_name _IO_marker DW_AT_byte_size 0x00000018 DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a0 DW_AT_sibling <0x0000025d> < 2><0x00000238> DW_TAG_member DW_AT_name _next DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a1 DW_AT_type <0x0000025d> DW_AT_data_member_location 0 < 2><0x00000244> DW_TAG_member DW_AT_name _sbuf DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a2 DW_AT_type <0x00000263> DW_AT_data_member_location 8 < 2><0x00000250> DW_TAG_member DW_AT_name _pos DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x000000a6 DW_AT_type <0x00000062> DW_AT_data_member_location 16 < 1><0x0000025d> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000022c> < 1><0x00000263> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000009a> < 1><0x00000269> DW_TAG_array_type DW_AT_type <0x0000008e> DW_AT_sibling <0x00000279> < 2><0x00000272> DW_TAG_subrange_type DW_AT_type <0x00000038> DW_AT_upper_bound 0 < 1><0x00000279> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x00000225> < 1><0x0000027f> DW_TAG_array_type DW_AT_type <0x0000008e> DW_AT_sibling <0x0000028f> < 2><0x00000288> DW_TAG_subrange_type DW_AT_type <0x00000038> DW_AT_upper_bound 19 < 1><0x0000028f> DW_TAG_structure_type DW_AT_name _IO_FILE_plus DW_AT_declaration yes(1) < 1><0x00000294> DW_TAG_variable DW_AT_name _IO_2_1_stdin_ DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x0000013f DW_AT_type <0x0000028f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002a0> DW_TAG_variable DW_AT_name _IO_2_1_stdout_ DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000140 DW_AT_type <0x0000028f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002ac> DW_TAG_variable DW_AT_name _IO_2_1_stderr_ DW_AT_decl_file 0x00000005 /usr/include/x86_64-linux-gnu/bits/libio.h DW_AT_decl_line 0x00000141 DW_AT_type <0x0000028f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002b8> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x00000095> < 1><0x000002be> DW_TAG_const_type DW_AT_type <0x000002b8> < 1><0x000002c3> DW_TAG_restrict_type DW_AT_type <0x000002b8> < 1><0x000002c8> DW_TAG_variable DW_AT_name stdin DW_AT_decl_file 0x00000007 /usr/include/stdio.h DW_AT_decl_line 0x00000087 DW_AT_type <0x00000263> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002d3> DW_TAG_variable DW_AT_name stdout DW_AT_decl_file 0x00000007 /usr/include/stdio.h DW_AT_decl_line 0x00000088 DW_AT_type <0x00000263> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002de> DW_TAG_variable DW_AT_name stderr DW_AT_decl_file 0x00000007 /usr/include/stdio.h DW_AT_decl_line 0x00000089 DW_AT_type <0x00000263> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002e9> DW_TAG_variable DW_AT_name sys_nerr DW_AT_decl_file 0x00000008 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h DW_AT_decl_line 0x0000001a DW_AT_type <0x00000062> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000002f4> DW_TAG_array_type DW_AT_type <0x000002be> DW_AT_sibling <0x000002ff> < 2><0x000002fd> DW_TAG_subrange_type < 1><0x000002ff> DW_TAG_const_type DW_AT_type <0x000002f4> < 1><0x00000304> DW_TAG_variable DW_AT_name sys_errlist DW_AT_decl_file 0x00000008 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h DW_AT_decl_line 0x0000001b DW_AT_type <0x000002ff> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x0000030f> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_signed DW_AT_name long long int < 1><0x00000316> DW_TAG_base_type DW_AT_byte_size 0x00000008 DW_AT_encoding DW_ATE_unsigned DW_AT_name long long unsigned int < 1><0x0000031d> DW_TAG_typedef DW_AT_name Dwarf_Unsigned DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004a DW_AT_type <0x00000316> < 1><0x00000328> DW_TAG_typedef DW_AT_name Dwarf_Off DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004c DW_AT_type <0x00000316> < 1><0x00000333> DW_TAG_typedef DW_AT_name Dwarf_Addr DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004d DW_AT_type <0x00000316> < 1><0x0000033e> DW_TAG_typedef DW_AT_name Dwarf_Bool DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x0000004e DW_AT_type <0x00000062> < 1><0x00000349> DW_TAG_typedef DW_AT_name Dwarf_Die DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00000218 DW_AT_type <0x00000355> < 1><0x00000355> DW_TAG_pointer_type DW_AT_byte_size 0x00000008 DW_AT_type <0x0000035b> < 1><0x0000035b> DW_TAG_structure_type DW_AT_name Dwarf_Die_s DW_AT_declaration yes(1) < 1><0x00000360> DW_TAG_structure_type DW_AT_byte_size 0x00000004 DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001391 DW_AT_sibling <0x00000377> < 2><0x00000369> DW_TAG_member DW_AT_name check_verbose_mode DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001392 DW_AT_type <0x0000033e> DW_AT_data_member_location 0 < 1><0x00000377> DW_TAG_typedef DW_AT_name Dwarf_Cmdline_Options DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001393 DW_AT_type <0x00000360> < 1><0x00000383> DW_TAG_variable DW_AT_name dwarf_cmdline_options DW_AT_decl_file 0x00000009 /tmp/dwbld/dwarfdump/../libdwarf/libdwarf.h DW_AT_decl_line 0x00001394 DW_AT_type <0x00000377> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x0000038f> DW_TAG_typedef DW_AT_name reg_syntax_t DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000002a DW_AT_type <0x00000038> < 1><0x0000039a> DW_TAG_variable DW_AT_name re_syntax_options DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x000000b5 DW_AT_type <0x0000038f> DW_AT_external yes(1) DW_AT_declaration yes(1) < 1><0x000003a5> DW_TAG_structure_type DW_AT_name re_pattern_buffer DW_AT_byte_size 0x00000040 DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000165 DW_AT_sibling <0x0000047e> < 2><0x000003b2> DW_TAG_member DW_AT_name __buffer DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000016a DW_AT_type <0x0000047e> DW_AT_data_member_location 0 < 2><0x000003bf> DW_TAG_member DW_AT_name __allocated DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000016d DW_AT_type <0x00000038> DW_AT_data_member_location 8 < 2><0x000003cc> DW_TAG_member DW_AT_name __used DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000170 DW_AT_type <0x00000038> DW_AT_data_member_location 16 < 2><0x000003d9> DW_TAG_member DW_AT_name __syntax DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000173 DW_AT_type <0x0000038f> DW_AT_data_member_location 24 < 2><0x000003e6> DW_TAG_member DW_AT_name __fastmap DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000178 DW_AT_type <0x00000088> DW_AT_data_member_location 32 < 2><0x000003f3> DW_TAG_member DW_AT_name __translate DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x0000017e DW_AT_type <0x0000047e> DW_AT_data_member_location 40 < 2><0x00000400> DW_TAG_member DW_AT_name re_nsub DW_AT_decl_file 0x0000000a /usr/include/regex.h DW_AT_decl_line 0x00000181 DW_AT_type <0x0000002d> DW_AT_data_member_location 48 dwarfutils-20200114/dwarfdump/testuriLE64ELf.obj000066400000000000000000000647601361531463500213230ustar00rootroot00000000000000ELF>pc@@G< vG<vG<wGfDG@H@H=H11HAUATUSHdH%(HD$1t_HHL%Ll$"HLHD$D$t)A< HuH51HHuHD$dH3%(u H[]A\A]AVAUATUSHdH%(HD$1HILt$k@DcA%Ek@H H=HksLLDd$D$EH]t'<%tHLLD$D$H]EuHD$dH3%(H[]A\A]A^f%LLfD$HkDH H=aHA%CDAA@HkAA Translating from uri: A supposed hexadecimal input character is not 0-9 or a-f or A-F, it is (shown as hex here): %x Translating from uri: A supposed hexadecimal input character pair runs off the end of the input after 1 hex digit. Translating from uri: A supposed hexadecimal input character pair runs off the end of the input. %%%02x> j8intii b     ( 0 8 @ H P X ]`  ch  bp bt px F T i y %{ - . / 0 2- 3b 5 ] ] c b, y 8%  8?@Acccb  J L M Nb U[ w > ` w *8 @ e~ j~ m8 p8 s x ~~( -0 M8 M8 M8 M8 M8 M8 M8? 0 & '> (key )3 ,3low -3 .3( /~ :# ;b <# =4~ 48 >8 B Cb D3 E3 F G H( I0: JE bM s2l K L M N O P Q( R0 S8 T@ UH VP WX X` Yh Zp [x \ bb l m o p q r s t u v$ w( x, y0 z4 {8 |< }@ ~D H L P T X \ ` d h l p t x |                                        ¹ ù ȹ  ˹$ ̹( b, й0 ӹ4 չ8 ֹ< ׹@ عD ٹH 8P ޹X ߹\ ` d h l p t 3x 3 ( ( ( ( b 3 3 3 ( (   ! ! ! b! b ! b! ! ! ! b ! h (! !n 0! )n 8! 4n @! :t H! ;t H! <t H! ? H! Bx! Cb! F ! G ! H ! I ! J ! Mb 8 b 8  ? @ A- D- M N   P[\I , 8"! #vj$v%outv &cpx'yF(&c{(q)}b&c2~*8++,---.-/!b+80-12U 2T12Qs3_++,4)\562U|8$8&663k+80-12U 2T12Qa5V2U}2T~12U}2T~12U}2T~6"  87Wb8cpW9W:Y:Zb;c[<;c2]7Q68c1Q8c2Q;outS7;^8c;:=#($(%out( &cp*(=v-F&c.b52Uv2T}1+2Uv2T 6">_bE?_K?_@EA6Y+G-QB6 +GC DtE K+80-162T12Q 2R U8$8&FG_HGGU% : ; I$ > $ >   I&I : ;  : ; I8 : ;I8 : ; I !I/ <4: ;I?<7I4: ; I?<!: ;I : ; : ; : ;I 8  : ;  : ; I8  : ;  : ; I8!I/> I: ; ( (  : ;  : ; I8! : ;I8"4: ; I#.?: ;'@B$: ;I%: ;I&4: ;I'4: ;I( U)4: ;I*1RUX Y+1, U-41. 1U/1X Y01112B31RUX Y44151617.: ;'I 8: ;I9: ;I:4: ;I;4: ;I< =4: ;I>.?: ; 'I 4?: ; I@A.1@BB 1C D41E1X YF.?<n: ; nG.?<n: ; H.?<n4U4jU4T4]Te]ejT4U4SVSVS S  V eS4}P~\PP 5P;HP4~0e0=~\1\15s;L\G~ eG~s esG~0 606;%;`0G~0 `0`e2G~\ 1\15s;L\ToVo}s;TVT\U]~ ;TVT\U;L\ 6 `UU`TVTzUSsSsSRR?U?QRQYU0P+0+,P,Y0,?U?QRQRU,R ,j8e8eG~eP~@eDLTe+1@C /home/davea/dwarf/code/dwarfdump/usr/include/x86_64-linux-gnu/bits/usr/lib/gcc/x86_64-linux-gnu/7/include/usr/include/x86_64-linux-gnu/bits/types/usr/include../libdwarfuri.cstdio2.hstddef.htypes.hlibio.hFILE.hstdio.hsys_errlist.hlibdwarf.hregex.hcheckutil.hdefined_types.hglflags.hesb.hglobals.h xxu=t=xX~JZBzPdKYzXv=W=3xRx tZ\K~dYYoXtdKjXJiXn*Zd[IZ}t}ftJ tgf_check_show_resultsprogram_fullname__streamDIE_offsetDIE_overall_offsetsize_tellipsisdebug_str_sizegf_print_unique_errorsdebug_aranges_sizesection_high_offsets_s__fmt_IO_2_1_stderr_gf_count_major_errorsseen_PU__buffer_IO_save_endgf_check_pubname_attrre_syntax_optionstranslate_to_uriorig__fastmap_accuratefde_offset_for_cu_low_IO_write_basedebug_macro_sizegf_check_self_referencesesb_stringDwarf_Off_lockglflagsnewprognamegf_display_children_treedenseshow_form_usedgf_generic_1200_regs_IO_save_base/home/davea/dwarf/code/dwarfdump/uri.cgf_check_macros_chain_cur_columnsys_nerrdebug_frame_sizekindhexpairtochargf_suppress_nested_name_searchgf_do_print_uri_in_inputdebug_loc_sizelong intgf_display_parent_tree__fprintf_chkorig2lneed_CU_high_address_IO_markerre_nsubpHeadDwarf_Unsignedgf_print_usage_tag_attr_fullgf_header_flaghighgf_reloc_flaggf_check_forward_declesb_fixedsigned char_IO_FILEfilenamebooleancurrent_section_idunsigned char__syntaxincrementgf_macinfo_flagdwarfdump_ctype_tableglflags_sgf_eh_frame_flag_IO_FILE_pluslowerneed_CU_base_addressolengf_check_frames_extendedchargf_search_is_onnTracemyocharBucket_Groupuppergf_check_frames_IO_lock_tdebug_abbrev_sizeseen_PU_high_addressgf_check_abbreviationsgf_check_gcc_compilerreg_syntax_tsearch_regex_text_IO_read_ptrpVisitedInfo__newline_anchorconfig_file_pathBucket_Data_posstdin__can_be_nullgf_pubnames_flagsys_errlistdebug_str_offsets_sizeinputesb_rigid_markersprogram_name__translatetranslate_from_urigf_check_linesgf_check_harmlessre_pattern_buffer_offsetDwarf_Addrgf_check_duplicated_attributesseen_PU_base_address_unused2gf_line_print_pcbreak_after_n_unitssection_high_offsets_globalgf_check_attr_encoding__builtin_fwritegf_loc_flag_IO_2_1_stdin_long unsigned intCU_high_address_flags2gf_static_var_flaggf_do_check_dwarfesb_appendDwarf_Die_s_IO_read_basetohex/tmp/dwbld/dwarfdumpline_flag_type_e__fastmapdwconf_s__not_eolgf_pubtypes_flaggf_check_di_gapsDwarf_Bool_old_offsetmacro_check_treegf_line_flagverboseCU_namePU_high_addresslong long intdebug_pubnames_sizegf_check_debug_namesgf_check_attr_tagCU_base_addressgf_suppress_checking_on_dwpdwarf_cmdline_optionsdebug_sup_size_IO_write_enddebug_types_sizegf_check_verbose_modedebug_macinfo_sizeDIE_CU_overall_offsetconfig_file_data_IO_buf_basegf_cu_name_flagsearch_any_textunsigned intfwrite__not_bolesb_allocated_sizeneed_PU_valid_code__pad1__pad2__pad3__pad4__pad5_sbufcheck_errorgf_check_snc_compilerPU_base_addressgf_line_skeleton_flag_flags_modegroup_numberpLinkonceInfoDwarf_Cmdline_Optionsgf_print_summary_all__stack_chk_faildebug_pubtypes_sizegf_suppress_check_extensions_tablesdebug_cu_index_sizegf_record_dwarf_errorgf_search_print_resultsFILEgf_do_print_dwarfcheck_verbose_modegf_stop_indent_levelgf_gdbindex_flaggf_display_offsetsfde_offset_for_cu_highDIE_CU_offsetregex_tcu_namesearch_regf_frame_flagsearch_occurrencesdebug_tu_index_sizesingledw5long long unsigned intconfig_file_tiedpathpTailEntriesgf_search_wide_format__off_tgf_ranges_flaggf_aranges_flagseen_CUgf_static_func_flaggf_info_flaggf_show_global_offsetsbFlagdebug_line_size_IO_backup_base_shortbuf_IO_2_1_stdout_search_match_textgf_found_error_message__allocated_nextgf_types_flag__off64_tCU_low_addressgf_print_usage_tag_attrgf_line_flag_selectiongf_abbrev_flag__usednEntries_IO_buf_endtempstrCU_producernameesb_used_bytesfprintfgf_producer_children_flagPU_namestderrgf_check_namesshort intpRangesInfogf_check_rangesgf_check_reloc_offset_vtable_offsetoutput_filegf_gnu_debuglink_flagocharbucketgf_macro_flaggf_check_type_offsetgf_string_flaggf_check_locations_IO_read_endgf_check_arangesgf_check_abbrev_codedebug_ranges_size_fileno__regs_allocatedBucketgf_weakname_flaggf_debug_names_flaggf_check_fdesgf_check_dwarf_constants__no_subshort unsigned intstdoutesb_sbasegf_check_decl_file_IO_write_ptrgf_section_groups_flaggf_print_str_offsetspFirstgf_check_tag_treeDwarf_Diegf_file_use_no_libelfpNextgf_check_all_compilersGNU C11 7.4.0 -mtune=generic -march=x86-64 -g -O2 -fstack-protector-strongneed_CU_namepLastgf_uri_options_translationgf_use_old_dwarf_loclistmacinfo_check_treeesb_append_printfhexdigdebug_info_sizecurrent_cu_die_for_print_framesGCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0zRx Ytd84BBA A(D@ (A ABBA @pjBBB A(A0D@ 0A(A BBBJ Y   $).x38?Uc`tjuri.chexdigdwarfdump_ctype_table.LC0.LC1.LC2.LC3stderr_GLOBAL_OFFSET_TABLE___fprintf_chktranslate_to_uriesb_appendesb_append_printf__stack_chk_failtranslate_from_urifwrite;BN `gz 2 f i  ) . N; /B I P  W ^ (l q ] | M   N N   _   l     #  0 = J OW ,d Qq ~ V d    [           U   , & -  9 9 E  Q  B         b  c   9) 4 c? J ,\ j C x v   /  I  -        +  4. 6> N  ^ n h        t     ?  L; EN |Z Pf r ~  3 9       1   '    + 7 2 C qO ^[ kg s     n       '  ~    t  ] 1  ) k 5 A  M 6Y e 8 q }    e  y   Y   ?  L e    % 1 = NI U a m y ? ( q >  7         ! n- 9 E Q ] mi  u    p  f H R    6 l 1 # 0  = J W d V q G ~   y  |      V    ' 4 A ( N S[ 0h ;u  E   W A I        <  .  < CJ X Uf t   2 h [   K   s [    * y8 $ F [ T          %  7- 9 B I` k { 9    P i    #G      [" + 8 A]] ag~xxD 0   0I] ` 6!9W rj    k 7  R _  f`}   K     . '9 Up Sy 4 44 ]R       ~ ~#  '  , 0 7 ;   txp  8`t.symtab.strtab.shstrtab.rela.text.data.bss.rodata.str1.8.rodata.str1.1.rodata.rela.debug_info.debug_abbrev.rela.debug_loc.rela.debug_aranges.debug_ranges.rela.debug_line.debug_str.comment.note.GNU-stack.rela.eh_frame @j@=&,12R@2O  \ BW@X? "hb{v@xax #0@a0 #O%G@ b0'W08,9 9@8bH9 <bdwarfutils-20200114/dwarfdump/true_section_name.c000066400000000000000000000067461361531463500220150ustar00rootroot00000000000000/* Copyright 2018-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. SGI has moved from the Crittenden Lane address. */ #include "globals.h" #include "esb.h" #include "esb_using_functions.h" void get_true_section_name(Dwarf_Debug dbg, const char *standard_name, struct esb_s *name_out, Dwarf_Bool add_compr) { Dwarf_Small marked_compressed = 0; Dwarf_Small marked_zlib_compressed = 0; Dwarf_Small marked_shf_compressed = 0; Dwarf_Unsigned compressed_length = 0; Dwarf_Unsigned uncompressed_length = 0; const char *stdname = standard_name; const char *actualname = 0; int cres = 0; Dwarf_Error tnameerr = 0; cres = dwarf_get_real_section_name(dbg, stdname, &actualname, &marked_compressed, &marked_zlib_compressed, &marked_shf_compressed, &compressed_length,&uncompressed_length, &tnameerr); if (cres == DW_DLV_OK) { esb_append(name_out,actualname); if (add_compr) { Dwarf_Bool compr = FALSE; if (marked_compressed) { esb_append(name_out," .zdebug"); compr = TRUE; } if (marked_zlib_compressed) { esb_append(name_out," ZLIB-initial-bytes"); compr = TRUE; } if (marked_shf_compressed) { esb_append(name_out," SHF_COMPRESSED"); compr = TRUE; } if (compr) { char floatbuf[40]; double comprfactor = 0.0; if (compressed_length > 0) { comprfactor = (double)uncompressed_length / (double)compressed_length; } esb_append_printf_u(name_out," CompLen=%" DW_PR_DUu, compressed_length); esb_append_printf_u(name_out," Uncomp=%" DW_PR_DUu, uncompressed_length); sprintf(floatbuf," compression=%.1f",comprfactor); esb_append(name_out, floatbuf); } } return; } else if (cres == DW_DLV_NO_ENTRY) { esb_append(name_out,stdname); return; } /* DW_DLV_ERROR */ esb_append(name_out,stdname); /* avoid error leak */ dwarf_dealloc(dbg,tnameerr,DW_DLA_ERROR); tnameerr = 0; esb_append(name_out," (Error accessing section name)"); return; } dwarfutils-20200114/dwarfdump/uri.c000066400000000000000000000233161361531463500171010ustar00rootroot00000000000000/* Copyright 2011-2012 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "globals.h" #include "esb.h" #include "uri.h" #include #include /* dwarfdump_ctype table. See uritablebuild.c */ static char dwarfdump_ctype_table[256] = { 0, /* NUL 0x00 */ 0, /* control 0x01 */ 0, /* control 0x02 */ 0, /* control 0x03 */ 0, /* control 0x04 */ 0, /* control 0x05 */ 0, /* control 0x06 */ 0, /* control 0x07 */ 0, /* control 0x08 */ 0, /* whitespace 0x09 */ 0, /* whitespace 0x0a */ 0, /* whitespace 0x0b */ 0, /* whitespace 0x0c */ 0, /* whitespace 0x0d */ 0, /* control 0x0e */ 0, /* control 0x0f */ 0, /* control 0x10 */ 0, /* control 0x11 */ 0, /* control 0x12 */ 0, /* control 0x13 */ 0, /* control 0x14 */ 0, /* control 0x15 */ 0, /* control 0x16 */ 0, /* control 0x17 */ 0, /* control 0x18 */ 0, /* control 0x19 */ 0, /* control 0x1a */ 0, /* control 0x1b */ 0, /* control 0x1c */ 0, /* control 0x1d */ 0, /* control 0x1e */ 0, /* control 0x1f */ 1, /* ' ' 0x20 */ 1, /* '!' 0x21 */ 0, /* '"' 0x22 */ 1, /* '#' 0x23 */ 1, /* '$' 0x24 */ 0, /* '%' 0x25 */ 1, /* '&' 0x26 */ 0, /* ''' 0x27 */ 1, /* '(' 0x28 */ 1, /* ')' 0x29 */ 1, /* '*' 0x2a */ 1, /* '+' 0x2b */ 1, /* ',' 0x2c */ 1, /* '-' 0x2d */ 1, /* '.' 0x2e */ 1, /* '/' 0x2f */ 1, /* '0' 0x30 */ 1, /* '1' 0x31 */ 1, /* '2' 0x32 */ 1, /* '3' 0x33 */ 1, /* '4' 0x34 */ 1, /* '5' 0x35 */ 1, /* '6' 0x36 */ 1, /* '7' 0x37 */ 1, /* '8' 0x38 */ 1, /* '9' 0x39 */ 1, /* ':' 0x3a */ 0, /* ';' 0x3b */ 1, /* '<' 0x3c */ 1, /* '=' 0x3d */ 1, /* '>' 0x3e */ 1, /* '?' 0x3f */ 1, /* '@' 0x40 */ 1, /* 'A' 0x41 */ 1, /* 'B' 0x42 */ 1, /* 'C' 0x43 */ 1, /* 'D' 0x44 */ 1, /* 'E' 0x45 */ 1, /* 'F' 0x46 */ 1, /* 'G' 0x47 */ 1, /* 'H' 0x48 */ 1, /* 'I' 0x49 */ 1, /* 'J' 0x4a */ 1, /* 'K' 0x4b */ 1, /* 'L' 0x4c */ 1, /* 'M' 0x4d */ 1, /* 'N' 0x4e */ 1, /* 'O' 0x4f */ 1, /* 'P' 0x50 */ 1, /* 'Q' 0x51 */ 1, /* 'R' 0x52 */ 1, /* 'S' 0x53 */ 1, /* 'T' 0x54 */ 1, /* 'U' 0x55 */ 1, /* 'V' 0x56 */ 1, /* 'W' 0x57 */ 1, /* 'X' 0x58 */ 1, /* 'Y' 0x59 */ 1, /* 'Z' 0x5a */ 1, /* '[' 0x5b */ 1, /* '\' 0x5c */ 1, /* ']' 0x5d */ 1, /* '^' 0x5e */ 1, /* '_' 0x5f */ 0, /* '`' 0x60 */ 1, /* 'a' 0x61 */ 1, /* 'b' 0x62 */ 1, /* 'c' 0x63 */ 1, /* 'd' 0x64 */ 1, /* 'e' 0x65 */ 1, /* 'f' 0x66 */ 1, /* 'g' 0x67 */ 1, /* 'h' 0x68 */ 1, /* 'i' 0x69 */ 1, /* 'j' 0x6a */ 1, /* 'k' 0x6b */ 1, /* 'l' 0x6c */ 1, /* 'm' 0x6d */ 1, /* 'n' 0x6e */ 1, /* 'o' 0x6f */ 1, /* 'p' 0x70 */ 1, /* 'q' 0x71 */ 1, /* 'r' 0x72 */ 1, /* 's' 0x73 */ 1, /* 't' 0x74 */ 1, /* 'u' 0x75 */ 1, /* 'v' 0x76 */ 1, /* 'w' 0x77 */ 1, /* 'x' 0x78 */ 1, /* 'y' 0x79 */ 1, /* 'z' 0x7a */ 1, /* '{' 0x7b */ 1, /* '|' 0x7c */ 1, /* '}' 0x7d */ 1, /* '~' 0x7e */ 0, /* DEL 0x7f */ 1, /* 0x80 */ 1, /* 0x81 */ 1, /* 0x82 */ 1, /* 0x83 */ 1, /* 0x84 */ 1, /* 0x85 */ 1, /* 0x86 */ 1, /* 0x87 */ 1, /* 0x88 */ 1, /* 0x89 */ 1, /* 0x8a */ 1, /* 0x8b */ 1, /* 0x8c */ 1, /* 0x8d */ 1, /* 0x8e */ 1, /* 0x8f */ 1, /* 0x90 */ 1, /* 0x91 */ 1, /* 0x92 */ 1, /* 0x93 */ 1, /* 0x94 */ 1, /* 0x95 */ 1, /* 0x96 */ 1, /* 0x97 */ 1, /* 0x98 */ 1, /* 0x99 */ 1, /* 0x9a */ 1, /* 0x9b */ 1, /* 0x9c */ 1, /* 0x9d */ 1, /* 0x9e */ 1, /* 0x9f */ 0, /* other: 0xa0 */ 1, /* 0xa1 */ 1, /* 0xa2 */ 1, /* 0xa3 */ 1, /* 0xa4 */ 1, /* 0xa5 */ 1, /* 0xa6 */ 1, /* 0xa7 */ 1, /* 0xa8 */ 1, /* 0xa9 */ 1, /* 0xaa */ 1, /* 0xab */ 1, /* 0xac */ 1, /* 0xad */ 1, /* 0xae */ 1, /* 0xaf */ 1, /* 0xb0 */ 1, /* 0xb1 */ 1, /* 0xb2 */ 1, /* 0xb3 */ 1, /* 0xb4 */ 1, /* 0xb5 */ 1, /* 0xb6 */ 1, /* 0xb7 */ 1, /* 0xb8 */ 1, /* 0xb9 */ 1, /* 0xba */ 1, /* 0xbb */ 1, /* 0xbc */ 1, /* 0xbd */ 1, /* 0xbe */ 1, /* 0xbf */ 1, /* 0xc0 */ 1, /* 0xc1 */ 1, /* 0xc2 */ 1, /* 0xc3 */ 1, /* 0xc4 */ 1, /* 0xc5 */ 1, /* 0xc6 */ 1, /* 0xc7 */ 1, /* 0xc8 */ 1, /* 0xc9 */ 1, /* 0xca */ 1, /* 0xcb */ 1, /* 0xcc */ 1, /* 0xcd */ 1, /* 0xce */ 1, /* 0xcf */ 1, /* 0xd0 */ 1, /* 0xd1 */ 1, /* 0xd2 */ 1, /* 0xd3 */ 1, /* 0xd4 */ 1, /* 0xd5 */ 1, /* 0xd6 */ 1, /* 0xd7 */ 1, /* 0xd8 */ 1, /* 0xd9 */ 1, /* 0xda */ 1, /* 0xdb */ 1, /* 0xdc */ 1, /* 0xdd */ 1, /* 0xde */ 1, /* 0xdf */ 1, /* 0xe0 */ 1, /* 0xe1 */ 1, /* 0xe2 */ 1, /* 0xe3 */ 1, /* 0xe4 */ 1, /* 0xe5 */ 1, /* 0xe6 */ 1, /* 0xe7 */ 1, /* 0xe8 */ 1, /* 0xe9 */ 1, /* 0xea */ 1, /* 0xeb */ 1, /* 0xec */ 1, /* 0xed */ 1, /* 0xee */ 1, /* 0xef */ 1, /* 0xf0 */ 1, /* 0xf1 */ 1, /* 0xf2 */ 1, /* 0xf3 */ 1, /* 0xf4 */ 1, /* 0xf5 */ 1, /* 0xf6 */ 1, /* 0xf7 */ 1, /* 0xf8 */ 1, /* 0xf9 */ 1, /* 0xfa */ 1, /* 0xfb */ 1, /* 0xfc */ 1, /* 0xfd */ 1, /* 0xfe */ 0, /* other: 0xff */ }; /* Translate dangerous and some other characters to safe %xx form. */ void translate_to_uri(const char * filename, struct esb_s *out) { const char *cp = 0; for (cp = filename ; *cp; ++cp) { char v[2]; int c = 0xff & (unsigned char)*cp; if (dwarfdump_ctype_table[c]) { v[0] = c; v[1] = 0; esb_append(out,v); } else { esb_append_printf(out, "%%%02x",c); } } } /* This is not very efficient, but it is seldom called. */ static char hexdig(char c) { char ochar = 0; if (c >= '0' && c <= '9') { ochar = (c - '0'); return ochar; } if (c >= 'a' && c <= 'f') { ochar = (c - 'a')+10; return ochar; } if (c >= 'A' && c <= 'F') { ochar = (c - 'A')+10; return ochar; } /* We have an input botch here. */ fprintf(stderr,"Translating from uri: " "A supposed hexadecimal input character is " "not 0-9 or a-f or A-F, it is (shown as hex here): %x\n",c); return ochar; } static char tohex(char c1, char c2) { char out = (hexdig(c1) << 4) | hexdig(c2); return out; } static int hexpairtochar(const char *cp, char*myochar) { char ochar = 0; int olen = 0; char c = cp[0]; if (c) { char c2 = cp[1]; if (c2) { ochar = tohex(c,c2); olen = 2; } else { fprintf(stderr,"Translating from uri: " "A supposed hexadecimal input character pair " "runs off the end of the input after 1 hex digit.\n"); /* botched input. */ ochar = c; olen = 1; } } else { /* botched input. */ fprintf(stderr,"Translating from uri: " "A supposed hexadecimal input character pair " "runs off the end of the input.\n"); ochar = '%'; olen = 0; } *myochar = ochar; return olen; } void translate_from_uri(const char * input, struct esb_s* out) { const char *cp = input; char tempstr[2]; for (; *cp; ++cp) { char c = *cp; if (c == '%') { int increment = 0; char c2 = cp[1]; /* hexpairtochar deals with c2 being NUL. */ if (c2 == '%') { tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); ++cp; continue; } increment = hexpairtochar(cp+1,&c); tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); cp +=increment; continue; } tempstr[0] = c; tempstr[1] = 0; esb_append(out,tempstr); } } #ifdef TEST unsigned errcnt = 0; static void mytestfrom(const char * in,const char *expected,int testnum) { struct esb_s out; esb_constructor(&out); translate_from_uri(in, &out); if (strcmp(expected, esb_get_string(&out))) { printf(" Fail test %d expected \"%s\" got \"%s\"\n", testnum,expected,esb_get_string(&out)); ++errcnt; } esb_destructor(&out); } static void mytest(char *in,char *expected,int testnum) { struct esb_s out; esb_constructor(&out); translate_to_uri(in, &out); if (strcmp(expected, esb_get_string(&out))) { printf(" Fail test %d expected %s got %s\n",testnum,expected,esb_get_string(&out)); ++errcnt; } esb_destructor(&out); } int main() { /* We no longer translate space to %20, that turns out not to help all that much. */ mytest("aaa","aaa",1); mytest(" bc"," bc",2); mytest(";bc","%3bbc",3); mytest(" bc\n"," bc%0a",4); mytest(";bc\n","%3bbc%0a",5); mytest(" bc\r"," bc%0d",6); mytest(";bc\r","%3bbc%0d",7); mytest(" \x01"," %01",8); mytest(";\x01","%3b%01",9); mytestfrom("abc","abc",10); mytestfrom("a%20bc","a bc",11); mytestfrom("a%%20bc","a%20bc",12); mytestfrom("a%%%20bc","a% bc",13); mytestfrom("a%%%%20bc","a%%20bc",14); mytestfrom("a%20","a ",15); /* The following is mistaken input. */ mytestfrom("a%2","a2",16); mytestfrom("a%","a%",17); mytest("%bc","%25bc",18); if (errcnt) { printf("uri errcount ",errcnt); } return errcnt? 1:0; } #endif dwarfutils-20200114/dwarfdump/uri.h000066400000000000000000000024701361531463500171040ustar00rootroot00000000000000/* Copyright 2011-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef URI_H #define URI_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void translate_to_uri(const char * filename, struct esb_s *out); void translate_from_uri(const char * input, struct esb_s *out); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* URI_H */ dwarfutils-20200114/dwarfdump/warningcontrol.h000066400000000000000000000023361361531463500213540ustar00rootroot00000000000000/* Copyright (C) 2016-201t David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef WARNINGCONTROL_H #define WARNINGCONTROL_H #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #endif /* WARNINGCONTROL_H */ dwarfutils-20200114/dwarfexample/000077500000000000000000000000001361531463500166175ustar00rootroot00000000000000dwarfutils-20200114/dwarfexample/CMakeLists.txt000066400000000000000000000025251361531463500213630ustar00rootroot00000000000000set_source_group(SIMPLE_READER_SOURCES "Source Files" simplereader.c) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) add_executable(simplereader ${SIMPLE_READER_SOURCES} ${SIMPLE_READER_HEADERS} ${CONFIGURATION_FILES}) set_folder(simplereader dwarfexample) target_compile_definitions(simplereader PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(simplereader PRIVATE ${DW_FWALL}) target_link_libraries(simplereader PRIVATE ${dwarf-target} ${DW_FZLIB}) set_source_group(FRAME1_SOURCES "Source Files" frame1.c) add_executable(frame1 ${FRAME1_SOURCES} ${FRAME1_HEADERS} ${CONFIGURATION_FILES}) set_folder(frame1 dwarfexample) target_compile_definitions(frame1 PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(frame1 PRIVATE ${DW_FWALL}) target_link_libraries(frame1 PRIVATE ${dwarf-target} ${DW_FZLIB}) set_source_group(FINDFUNCBYPC_SOURCES "Source Files" findfuncbypc.c) add_executable(findfuncbypc ${FINDFUNCBYPC_SOURCES} ${FINDFUNCBYPC_HEADERS} ${CONFIGURATION_FILES}) set_folder(findfuncbypc dwarfexample) target_compile_definitions(findfuncbypc PRIVATE CONFPREFIX={CMAKE_INSTALL_PREFIX}/lib) target_compile_options(findfuncbypc PRIVATE ${DW_FWALL}) target_link_libraries(findfuncbypc PRIVATE ${dwarf-target} ${DW_FZLIB}) dwarfutils-20200114/dwarfexample/ChangeLog000066400000000000000000000000271361531463500203700ustar00rootroot000000000000002020-01-05 placeholder dwarfutils-20200114/dwarfexample/ChangeLog2009000066400000000000000000000007171361531463500207110ustar00rootroot00000000000000August 7, 2009 David Anderson * frame1.c: This is a new example that uses frame functions. July 21, 2009 David Anderson * simplereader.c: After cur_die = sib_die; nothing was printing cur_die, so added a print call after the assignment. July 8, 2009 David Anderson * Makefile: New trivial Makefile to build the example. * simplereader.c: New trivial example using libdwarf. dwarfutils-20200114/dwarfexample/ChangeLog2010000066400000000000000000000010671361531463500207000ustar00rootroot00000000000000April 26, 2010 David Anderson * simplereader.c: Now prints all TAGs regardless of whether a DIE has a DW_AT_name attribute. All names print an "" pair so it's easy to recognize empty names and names with embedded spaces. March 31, 2010 David Anderson * simplereader.c: Added a new option --names which shows additional detail on getting attributes and source file information. January 3, 2010 David Anderson * frame1.c, simplereader.c: Update copyright year. dwarfutils-20200114/dwarfexample/ChangeLog2011000066400000000000000000000003651361531463500207010ustar00rootroot000000000000002011-06-04 DavidAnderson * frame1.c, simplereader.c: Altered indentation to multiples of 4 spaces, no tabs. No substantive change. 2011-01-13 DavidAnderson * New year starts. dwarfutils-20200114/dwarfexample/ChangeLog2012000066400000000000000000000000241361531463500206720ustar00rootroot00000000000000No changes in 2012. dwarfutils-20200114/dwarfexample/ChangeLog2013000066400000000000000000000006431361531463500207020ustar00rootroot000000000000002013-11-24 David Anderson * Makefile: Some compilers (FreeBSD gcc, for example) do not support -gdwarf-4, so changed the compile to -g. 2013-08-13 David Anderson * Add the --check option to verify that dwarf_highpc() and the new dwarf_highpc_b() work properly with both form address and form constant instances of attributes DW_AT_high_pc. dwarfutils-20200114/dwarfexample/ChangeLog2014000066400000000000000000000004301361531463500206750ustar00rootroot000000000000002014-01-30 David Anderson * simplereader.c: Removed dwarf_dealloc from call of string returned by dwarf_diename(). The dwarf_diename() call was incorrectly documented. 2014-01-29 David Anderson * frame1.c,simplereader.c: Remove trailing whitespace. dwarfutils-20200114/dwarfexample/ChangeLog2015000066400000000000000000000021661361531463500207060ustar00rootroot000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-11-26 David Anderson * config.h.in, configure.in, Makefile.in: Deals with zlib when present. * configure: Generated. 2015-11-15 David Anderson * configure.in, Makefile.in: So we now use configure to build. * configure: Generated 2015-09-22 David Anderson * simplereader.c: Removed trailing whitespace. 2015-09-15 Carlos Alberto Enciso * simplereader.c: Fix some C99 issues with local variables declaration in main() and read_cu_list(). Include the 'config.h' and 'stdafx.h' headers for Windows port. Include the Dwarfdump generic open_a_file() and close_a_file() calls. 2015-06-19 David Anderson * frame1.c: Add printf and comments suggesting use of dwarf_get_fde_list_eh() if dwarf_get_fde_list() gets DW_DLV_NO_ENTRY. 2015-05-05 David Anderson * simplereader.c: Added code to help testing in libdwarf DebugFission Package File interfaces. 2015-01-01 David Anderson * A new year begins. dwarfutils-20200114/dwarfexample/ChangeLog2016000066400000000000000000000034401361531463500207030ustar00rootroot000000000000002016-11-24 David Anderson * Makefile.in: Clean *~ 2016-11-04 David Anderson * simplereader.c(printnamestrings): Remove C99-ism in favor of C90 style. 2016-09-30 David Anderson * configure.in: Add additional -fsanitize tests to --enable-sanitize * configure: Regenerated. 2016-09-21 David Anderson * Makefile.in: Added dwfsanitize when -fsanitize=address desired. * configure.in: Added --enable-sanitize option. * configure: Regenerated. * simplereader.c: Added trivial static array for string pointers so such can be freed at normal exit to avoid having malloc space problem reports from valgrind. 2016-09-05 David Anderson * simplereader.c: Adding --dumpallnames option so it becomes easy to analyze string usage in objects. (The analysys to be carried out be other code, not part of the libdwarf distribution.) 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-03-14 DavidAnderson * frame1.c: Fixing various compiler warnings. * simplereader.c: In case a badly spelled argument given, exit with message, do not ignore the mistake. 2016-03-14 DavidAnderson * simplereader.c: --simpleerrhand flag lets us test an error handler when combined with --passnullerror. Fixed various warnings exposed by configure --enable-wall. 2016-03-13 DavidAnderson * simplereader.c: --passnullerror flag lets us test for libdwarf mistakes in handling a NULL error argument. * configure.in: Handle --enable-wall configure choice. * configure: Regenerated. * Makefile.in: Handle --enable-wall. dwarfutils-20200114/dwarfexample/ChangeLog2017000066400000000000000000000010251361531463500207010ustar00rootroot000000000000002017-12-21 David Anderson * simplereader.c: A DIE was not getting deallocated, now it is deallocated, avoiding a memory leak. 2017-12-17 David Anderson * Makefile.in: Add CPPFLAGS, helpful for one user build, harmless to others. 2017-08-21 David Anderson * configure.in: Add unistd.h to AC_CHECK_HEADERS. * configure: Regenerated. * frame1.c: Add #ifdef and include config.h to make windows builds easier. * simplereader.c: Change #ifdef to make windows builds easier. dwarfutils-20200114/dwarfexample/ChangeLog2018000066400000000000000000000025621361531463500207110ustar00rootroot000000000000002018-09-21 David Anderson * Makefile.am: Now config.h.in.cmake gets into releases. 2018-08-21 David Anderson * Makefile.am: Now honors --enable-wall. 2018-08-02 David Anderson * Makefile.am: Removed unused variables and references to them. 2018-07-31 David Anderson * Makefile.am: Moves ChangeLog and other files to the distribution, and out of the set of installed files. 2018-07-16 David Anderson * simplereader.c: Refines the ifdef of HAVE_STDAFX_H 2018-07-16 David Anderson * simplereader.c: Changed // comments to /* */ * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-06-14 David Anderson * Makefile.in,config.h.in,configure,configure.ac: Removed unnecessary configure lines, regenerated configure. 2018-06-13 David Anderson * configure.ac: New option --enable-elf-open setting HAVE_ELF_OPEN * config.h.in: HAVE_ELF_OPEN * configure.ac: Regenerated. * simplereader.c: Now uses open() unless HAVE_ELF_OPEN is explicitly set. 2018-06-05 David Anderson * simplereader.c: Remove erroneous _MSC_VER per Carlos Alberto Enciso. Change WIN32 to _WIN32. 2018-05-12 David Anderson * frame1.c: Adding new code (select with option --just-print-selected-regs) to test a new frame access function. dwarfutils-20200114/dwarfexample/Makefile.am000066400000000000000000000031541361531463500206560ustar00rootroot00000000000000###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = simplereader$(EXEEXT) frame1$(EXEEXT) \ findfuncbypc$(EXEEXT) getdebuglink$(EXEEXT) subdir = dwarfexample ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_findfuncbypc_OBJECTS = findfuncbypc-findfuncbypc.$(OBJEXT) findfuncbypc_OBJECTS = $(am_findfuncbypc_OBJECTS) am__DEPENDENCIES_1 = findfuncbypc_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = findfuncbypc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(findfuncbypc_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_frame1_OBJECTS = frame1-frame1.$(OBJEXT) frame1_OBJECTS = $(am_frame1_OBJECTS) frame1_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) frame1_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(frame1_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_getdebuglink_OBJECTS = getdebuglink-getdebuglink.$(OBJEXT) getdebuglink_OBJECTS = $(am_getdebuglink_OBJECTS) getdebuglink_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) getdebuglink_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(getdebuglink_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_simplereader_OBJECTS = simplereader-simplereader.$(OBJEXT) simplereader_OBJECTS = $(am_simplereader_OBJECTS) simplereader_DEPENDENCIES = $(top_builddir)/libdwarf/libdwarf.la \ $(am__DEPENDENCIES_1) simplereader_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simplereader_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(findfuncbypc_SOURCES) $(frame1_SOURCES) \ $(getdebuglink_SOURCES) $(simplereader_SOURCES) DIST_SOURCES = $(findfuncbypc_SOURCES) $(frame1_SOURCES) \ $(getdebuglink_SOURCES) $(simplereader_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver ChangeLog NEWS DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in AUTOMAKE_OPTIONS = subdir-objects simplereader_SOURCES = simplereader.c simplereader_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf simplereader_CFLAGS = $(DWARF_CFLAGS_WARN) simplereader_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) frame1_SOURCES = frame1.c frame1_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf frame1_CFLAGS = $(DWARF_CFLAGS_WARN) frame1_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) findfuncbypc_SOURCES = findfuncbypc.c findfuncbypc_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf findfuncbypc_CFLAGS = $(DWARF_CFLAGS_WARN) findfuncbypc_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) getdebuglink_SOURCES = getdebuglink.c getdebuglink_CPPFLAGS = -I$(top_srcdir)/libdwarf \ -I$(top_builddir)/libdwarf getdebuglink_CFLAGS = $(DWARF_CFLAGS_WARN) getdebuglink_LDADD = $(top_builddir)/libdwarf/libdwarf.la \ $(DWARF_LIBS) TESTS = runtests.sh AM_TESTS_ENVIRONMENT = DWTOPSRCDIR='$(top_srcdir)'; export DWTOPSRCDIR ; DWCOMPILERFLAGS='$(DWARF_CFLAGS_WARN)'; export DWCOMPILERFLAGS ; EXTRA_DIST = \ ChangeLog \ ChangeLog2009 \ ChangeLog2010 \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CMakeLists.txt \ runtests.sh \ debuglink.base \ dummyexecutable \ dummyexecutable.c \ NEWS \ $(dwarfexample_DATA) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu dwarfexample/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu dwarfexample/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list findfuncbypc$(EXEEXT): $(findfuncbypc_OBJECTS) $(findfuncbypc_DEPENDENCIES) $(EXTRA_findfuncbypc_DEPENDENCIES) @rm -f findfuncbypc$(EXEEXT) $(AM_V_CCLD)$(findfuncbypc_LINK) $(findfuncbypc_OBJECTS) $(findfuncbypc_LDADD) $(LIBS) frame1$(EXEEXT): $(frame1_OBJECTS) $(frame1_DEPENDENCIES) $(EXTRA_frame1_DEPENDENCIES) @rm -f frame1$(EXEEXT) $(AM_V_CCLD)$(frame1_LINK) $(frame1_OBJECTS) $(frame1_LDADD) $(LIBS) getdebuglink$(EXEEXT): $(getdebuglink_OBJECTS) $(getdebuglink_DEPENDENCIES) $(EXTRA_getdebuglink_DEPENDENCIES) @rm -f getdebuglink$(EXEEXT) $(AM_V_CCLD)$(getdebuglink_LINK) $(getdebuglink_OBJECTS) $(getdebuglink_LDADD) $(LIBS) simplereader$(EXEEXT): $(simplereader_OBJECTS) $(simplereader_DEPENDENCIES) $(EXTRA_simplereader_DEPENDENCIES) @rm -f simplereader$(EXEEXT) $(AM_V_CCLD)$(simplereader_LINK) $(simplereader_OBJECTS) $(simplereader_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findfuncbypc-findfuncbypc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame1-frame1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdebuglink-getdebuglink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simplereader-simplereader.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< findfuncbypc-findfuncbypc.o: findfuncbypc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -MT findfuncbypc-findfuncbypc.o -MD -MP -MF $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo -c -o findfuncbypc-findfuncbypc.o `test -f 'findfuncbypc.c' || echo '$(srcdir)/'`findfuncbypc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo $(DEPDIR)/findfuncbypc-findfuncbypc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='findfuncbypc.c' object='findfuncbypc-findfuncbypc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -c -o findfuncbypc-findfuncbypc.o `test -f 'findfuncbypc.c' || echo '$(srcdir)/'`findfuncbypc.c findfuncbypc-findfuncbypc.obj: findfuncbypc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -MT findfuncbypc-findfuncbypc.obj -MD -MP -MF $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo -c -o findfuncbypc-findfuncbypc.obj `if test -f 'findfuncbypc.c'; then $(CYGPATH_W) 'findfuncbypc.c'; else $(CYGPATH_W) '$(srcdir)/findfuncbypc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/findfuncbypc-findfuncbypc.Tpo $(DEPDIR)/findfuncbypc-findfuncbypc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='findfuncbypc.c' object='findfuncbypc-findfuncbypc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(findfuncbypc_CPPFLAGS) $(CPPFLAGS) $(findfuncbypc_CFLAGS) $(CFLAGS) -c -o findfuncbypc-findfuncbypc.obj `if test -f 'findfuncbypc.c'; then $(CYGPATH_W) 'findfuncbypc.c'; else $(CYGPATH_W) '$(srcdir)/findfuncbypc.c'; fi` frame1-frame1.o: frame1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -MT frame1-frame1.o -MD -MP -MF $(DEPDIR)/frame1-frame1.Tpo -c -o frame1-frame1.o `test -f 'frame1.c' || echo '$(srcdir)/'`frame1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/frame1-frame1.Tpo $(DEPDIR)/frame1-frame1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame1.c' object='frame1-frame1.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -c -o frame1-frame1.o `test -f 'frame1.c' || echo '$(srcdir)/'`frame1.c frame1-frame1.obj: frame1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -MT frame1-frame1.obj -MD -MP -MF $(DEPDIR)/frame1-frame1.Tpo -c -o frame1-frame1.obj `if test -f 'frame1.c'; then $(CYGPATH_W) 'frame1.c'; else $(CYGPATH_W) '$(srcdir)/frame1.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/frame1-frame1.Tpo $(DEPDIR)/frame1-frame1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='frame1.c' object='frame1-frame1.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(frame1_CPPFLAGS) $(CPPFLAGS) $(frame1_CFLAGS) $(CFLAGS) -c -o frame1-frame1.obj `if test -f 'frame1.c'; then $(CYGPATH_W) 'frame1.c'; else $(CYGPATH_W) '$(srcdir)/frame1.c'; fi` getdebuglink-getdebuglink.o: getdebuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdebuglink_CPPFLAGS) $(CPPFLAGS) $(getdebuglink_CFLAGS) $(CFLAGS) -MT getdebuglink-getdebuglink.o -MD -MP -MF $(DEPDIR)/getdebuglink-getdebuglink.Tpo -c -o getdebuglink-getdebuglink.o `test -f 'getdebuglink.c' || echo '$(srcdir)/'`getdebuglink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/getdebuglink-getdebuglink.Tpo $(DEPDIR)/getdebuglink-getdebuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getdebuglink.c' object='getdebuglink-getdebuglink.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdebuglink_CPPFLAGS) $(CPPFLAGS) $(getdebuglink_CFLAGS) $(CFLAGS) -c -o getdebuglink-getdebuglink.o `test -f 'getdebuglink.c' || echo '$(srcdir)/'`getdebuglink.c getdebuglink-getdebuglink.obj: getdebuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdebuglink_CPPFLAGS) $(CPPFLAGS) $(getdebuglink_CFLAGS) $(CFLAGS) -MT getdebuglink-getdebuglink.obj -MD -MP -MF $(DEPDIR)/getdebuglink-getdebuglink.Tpo -c -o getdebuglink-getdebuglink.obj `if test -f 'getdebuglink.c'; then $(CYGPATH_W) 'getdebuglink.c'; else $(CYGPATH_W) '$(srcdir)/getdebuglink.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/getdebuglink-getdebuglink.Tpo $(DEPDIR)/getdebuglink-getdebuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='getdebuglink.c' object='getdebuglink-getdebuglink.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdebuglink_CPPFLAGS) $(CPPFLAGS) $(getdebuglink_CFLAGS) $(CFLAGS) -c -o getdebuglink-getdebuglink.obj `if test -f 'getdebuglink.c'; then $(CYGPATH_W) 'getdebuglink.c'; else $(CYGPATH_W) '$(srcdir)/getdebuglink.c'; fi` simplereader-simplereader.o: simplereader.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -MT simplereader-simplereader.o -MD -MP -MF $(DEPDIR)/simplereader-simplereader.Tpo -c -o simplereader-simplereader.o `test -f 'simplereader.c' || echo '$(srcdir)/'`simplereader.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simplereader-simplereader.Tpo $(DEPDIR)/simplereader-simplereader.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simplereader.c' object='simplereader-simplereader.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -c -o simplereader-simplereader.o `test -f 'simplereader.c' || echo '$(srcdir)/'`simplereader.c simplereader-simplereader.obj: simplereader.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -MT simplereader-simplereader.obj -MD -MP -MF $(DEPDIR)/simplereader-simplereader.Tpo -c -o simplereader-simplereader.obj `if test -f 'simplereader.c'; then $(CYGPATH_W) 'simplereader.c'; else $(CYGPATH_W) '$(srcdir)/simplereader.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simplereader-simplereader.Tpo $(DEPDIR)/simplereader-simplereader.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simplereader.c' object='simplereader-simplereader.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(simplereader_CPPFLAGS) $(CPPFLAGS) $(simplereader_CFLAGS) $(CFLAGS) -c -o simplereader-simplereader.obj `if test -f 'simplereader.c'; then $(CYGPATH_W) 'simplereader.c'; else $(CYGPATH_W) '$(srcdir)/simplereader.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? runtests.sh.log: runtests.sh @p='runtests.sh'; \ b='runtests.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dwarfutils-20200114/dwarfexample/NEWS000066400000000000000000000015221361531463500173160ustar00rootroot00000000000000November 11, 2019 Added getdebuglink.c to show how to use libdwarf to find a GNU alternate DWARF file. Add dummyexample.c as a trivial C test case, compiled into the file dummyexample. Compiled as cc -g dummyexample.c -o dummyexample This dummyexample (the executable) is a static, unchanging, file that getdebuglink can use in runtests.sh to verify getdebuglink works. September 05, 2016 simplereader.c: Added the --dumpallnames option so one can get all the strings from debug_info,_types into a file. A simple way to enable further examination of the strings. July 21, 2009 Roni Simonian noticed a call to print_die_data(dbg,cur_die,in_level); was missing so not all DIEs would print. Good Catch! July 8, 2009 Created a sample libdwarf consumer. Using BSD license so anyone can use it. And a trivial Makefile. dwarfutils-20200114/dwarfexample/debuglink.base000066400000000000000000000004501361531463500214160ustar00rootroot00000000000000There is no such file as "a" There is no such file as "b" Section .note.gnu.buildid Build-id type : 3 Build-id ownername: GNU Build-id length : 20 Build-id : 8ad280007cde31cb0b3f24fe8d78cadcfae4537b Path [ 0] /usr/lib/debug/8a/d280007cde31cb0b3f24fe8d78cadcfae4537b.debug dwarfutils-20200114/dwarfexample/dummyexecutable000077500000000000000000000251701361531463500217470ustar00rootroot00000000000000ELF>@8"@8 @! @@@88800  (   TTTDDPtdDDQtdRtd /lib64/ld-linux-x86-64.so.2GNUGNUҀ|1 ?$xS{8 T c "libc.so.6__cxa_finalize__libc_start_mainGLIBC_2.2.5_ITM_deregisterTMCloneTable__gmon_start___ITM_registerTMCloneTableui ,         HH% HtH5 % @% f1I^HHPTLH 3H= DH= UH H9HtH Ht ]f.]@f.H= H5 UH)HHHH?HHtHa Ht ]f]@f.=Y u/H=7 UHt H=: H1 ]fDUH]fUH}EEE]UHH }HuEEEEfDAWAVIAUATL% UH- SAIL)HHGHt 1LLDAHH9uH[]A\A]A^A_Ðf.HH;@ ,\6K| TzRx +zRx $xFJ w?;*3$"D`\bAC P |W+AC f DheBBE B(H0H8M@r8A0A(B BBB    oH }   ooooo  GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0,@ (@D88:intii Yb + v N  K( 0 `8 @ kH *P X mR`  Xh  bp @bt px F \T ^ n %{ ]- d. k/ r0 y2- H3b "5t R WR X b! n 8  8?@A:XXXb yKb+Kb\KPzedblP bx M\z bl% : ; I$ > $ >   I&I : ;  : ; I8 : ;I8 : ; I !I/ <4: ;I?<4: ; I?<!.?: ; 'I@B: ; I4: ; I.?: ; 'I@B: ; I /usr/lib/gcc/x86_64-linux-gnu/7/include/usr/include/x86_64-linux-gnu/bits/usr/includedummyexecutable.cstddef.htypes.hlibio.hstdio.hsys_errlist.h  u=1v=_IO_buf_end_chain_old_offsetsys_nerrdummyexecutable.cshort intsize_t_IO_write_ptr_flags_IO_buf_base_markers_IO_read_endstderr_locklong int_cur_column_IO_2_1_stderr__IO_FILE_plus_posargv_sbuf_IO_FILEunsigned charargc_IO_2_1_stdin__IO_marker_shortbuf_IO_write_base_unused2_IO_read_ptrshort unsigned intmainmyfunc_next__pad1__pad2__pad3__pad4__pad5long unsigned int_IO_save_end_IO_write_end__off64_t__off_t/home/davea/dwarf/code/dwarfexampleGNU C11 7.4.0 -mtune=generic -march=x86-64 -g -fstack-protector-strong_IO_backup_basestdin_flags2_mode_IO_read_base_vtable_offset_IO_save_basesys_errlist_filenostdout_IO_2_1_stdout__IO_lock_t8TtH              `! 7 F m y ,      i  : A Hg t   @e m +  +  " crtstuff.cderegister_tm_clones__do_global_dtors_auxcompleted.7697__do_global_dtors_aux_fini_array_entryframe_dummy__frame_dummy_init_array_entrydummyexecutable.c__FRAME_END____init_array_end_DYNAMIC__init_array_start__GNU_EH_FRAME_HDR_GLOBAL_OFFSET_TABLE___libc_csu_fini_ITM_deregisterTMCloneTable_edatamyfunc__libc_start_main@@GLIBC_2.2.5__data_start__gmon_start____dso_handle_IO_stdin_used__libc_csu_init__bss_startmain__TMC_END___ITM_registerTMCloneTable__cxa_finalize@@GLIBC_2.2.5.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.init.plt.plt.got.text.fini.rodata.eh_frame_hdr.eh_frame.init_array.fini_array.dynamic.data.bss.comment.debug_aranges.debug_info.debug_abbrev.debug_line.debug_str88#TT 1tt$DoN VHH}^o ko z D(    @  0+;0k+".0H/  9dwarfutils-20200114/dwarfexample/dummyexecutable.c000066400000000000000000000005661361531463500221670ustar00rootroot00000000000000/* This is a dummy to create a tiny executable we will use in make check on debuglink Compiled by cc -g dummyexecutable.c -o dummyexecutable On Ubuntu 18.04 10 November 2019 */ #include int myfunc(unsigned x) { int z = x +3; return z; } int main(int argc, char **argv) { int zed = 0; zed = myfunc(zed +2); return zed; } dwarfutils-20200114/dwarfexample/findfuncbypc.c000066400000000000000000001205511361531463500214410ustar00rootroot00000000000000/* Copyright (c) 2019 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* findfuncbypc.c This is an example of code reading dwarf .debug_info. It is kept simple to expose essential features. It does not do all possible error reporting or error handling. It does to a bit of error checking as a help in ensuring that some code works properly... for error checks. To use, try make ./findfuncbypc --pc=0x10000 ./findfuncbypc */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_SYS_TYPES_H #include /* For open() */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include /* For open() */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_UNISTD_H #include /* For close() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #include #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf.h" #include "libdwarf.h" #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ struct srcfilesdata { char ** srcfiles; Dwarf_Signed srcfilescount; int srcfilesres; }; struct target_data_s { Dwarf_Debug td_dbg; Dwarf_Unsigned td_target_pc; /* from argv */ int td_print_details; /* from argv */ int td_reportallfound; /* from argv */ /* cu die data. */ Dwarf_Unsigned td_cu_lowpc; Dwarf_Unsigned td_cu_highpc; int td_cu_haslowhighpc; Dwarf_Die td_cu_die; char * td_cu_name; char * td_cu_comp_dir; Dwarf_Unsigned td_cu_number; struct srcfilesdata td_cu_srcfiles; /* Help deal with DW_AT_ranges */ /* This is base offset of ranges, the value from DW_AT_rnglists_base. */ Dwarf_Unsigned td_cu_ranges_base; /* Following subprog related. Offset has tc_cu_ranges_base added in. */ Dwarf_Off td_ranges_offset; /* DIE data of appropriate DIE */ /* From DW_AT_name */ char * td_subprog_name; Dwarf_Unsigned td_subprog_fileindex; Dwarf_Die td_subprog_die; Dwarf_Unsigned td_subprog_lowpc; Dwarf_Unsigned td_subprog_highpc; int td_subprog_haslowhighpc; Dwarf_Unsigned td_subprog_lineaddr; Dwarf_Unsigned td_subprog_lineno; char * td_subprog_srcfile; /* dealloc */ }; /* Adding return codes to DW_DLV, relevant to our purposes here. */ #define NOT_THIS_CU 10 #define IN_THIS_CU 11 #define FOUND_SUBPROG 12 #define TRUE 1 #define FALSE 0 static int look_for_our_target(Dwarf_Debug dbg, struct target_data_s *target_data, Dwarf_Error *errp); static int examine_die_data(Dwarf_Debug dbg, int is_info,Dwarf_Die die, int level, struct target_data_s *td, Dwarf_Error *errp); static int check_comp_dir(Dwarf_Debug dbg,Dwarf_Die die, int level, struct target_data_s *td,Dwarf_Error *errp); static int get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info, int in_level,int cu_number, struct target_data_s *td, Dwarf_Error *errp); #if 0 DW_UT_compile 0x01 /* DWARF5 */ DW_UT_type 0x02 /* DWARF5 */ DW_UT_partial 0x03 /* DWARF5 */ #endif static int unittype = DW_UT_compile; static Dwarf_Bool g_is_info = TRUE; int cu_version_stamp = 0; int cu_offset_size = 0; static void printusage(void) { printf("Usage example: " "./findfuncbypc --pc=0x10000 ./findfuncbypc\n"); printf(" options list:\n"); printf(" --pc=(hex or decimal pc address)\n"); printf(" --printdetails \n"); printf(" prints some details of the discovery process\n"); printf(" --allinstances\n"); printf(" reports but does does not stop processing\n"); printf(" on finding pc address\n"); printf(" --help or -h prints this usage message an stops.\n"); } static void target_data_destructor( struct target_data_s *td); static int startswithextractnum(const char *arg,const char *lookfor, Dwarf_Unsigned *numout) { const char *s = 0; unsigned prefixlen = strlen(lookfor); Dwarf_Unsigned v = 0; char *endptr = 0; if(strncmp(arg,lookfor,prefixlen)) { return FALSE; } s = arg+prefixlen; /* We are not making any attempt to deal with garbage. Pass in good data... */ v = strtoul(s,&endptr,0); if (!*s || *endptr) { printf("Incoming argument in error: \"%s\"\n",arg); return FALSE; } *numout = v; return TRUE; } int main(int argc, char **argv) { Dwarf_Debug dbg = 0; const char *filepath = 0; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; int i = 0; Dwarf_Unsigned target_pc = 0; #define PATH_LEN 2000 char real_path[PATH_LEN]; struct target_data_s target_data; real_path[0] = 0; memset(&target_data,0, sizeof(target_data)); for(i = 1; i < (argc-1) ; ++i) { if(startswithextractnum(argv[i],"--pc=", &target_pc)) { /* done */ target_data.td_target_pc = target_pc; } else if (!strcmp(argv[i],"--printdetails")){ target_data.td_print_details = TRUE; } else if (!strcmp(argv[i],"--allinstances")){ target_data.td_reportallfound = TRUE; } else if (!strcmp(argv[i],"-h")){ printusage(); exit(0); } else if (!strcmp(argv[i],"--help")){ printusage(); exit(0); } else { printf("Unknown argument \"%s\", give up \n",argv[i]); exit(1); } } if (i >= (argc-1)) { printusage(); exit(1); } filepath = argv[i]; res = dwarf_init_path(filepath, real_path, PATH_LEN, DW_DLC_READ, DW_GROUPNUMBER_ANY,errhand,errarg,&dbg, 0,0,0,&error); if(res == DW_DLV_ERROR) { printf("Giving up, cannot do DWARF processing of %s " "dwarf err %" DW_PR_DUu " %s\n", filepath, dwarf_errno(error), dwarf_errmsg(error)); exit(1); } if(res == DW_DLV_NO_ENTRY) { printf("Giving up, file %s not found\n",filepath); exit(1); } res = look_for_our_target(dbg,&target_data,&error); target_data_destructor(&target_data); res = dwarf_finish(dbg,&error); if(res != DW_DLV_OK) { printf("dwarf_finish failed!\n"); } return 0; } static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf) { Dwarf_Signed sri = 0; for (sri = 0; sri < sf->srcfilescount; ++sri) { dwarf_dealloc(dbg, sf->srcfiles[sri], DW_DLA_STRING); } dwarf_dealloc(dbg, sf->srcfiles, DW_DLA_LIST); sf->srcfilesres = DW_DLV_ERROR; sf->srcfiles = 0; sf->srcfilescount = 0; } static void resetsubprog(Dwarf_Debug dbg,struct target_data_s *td) { td->td_subprog_haslowhighpc = FALSE; if (td->td_subprog_name) { dwarf_dealloc(dbg,td->td_subprog_name,DW_DLA_STRING); td->td_subprog_name = 0; } if (td->td_subprog_die) { dwarf_dealloc(dbg,td->td_subprog_die,DW_DLA_DIE); td->td_subprog_die = 0; } } static void reset_target_data(Dwarf_Debug dbg,struct target_data_s *td) { if (td->td_cu_die) { dwarf_dealloc(dbg,td->td_cu_die,DW_DLA_DIE); td->td_cu_die = 0; } if (td->td_subprog_die) { dwarf_dealloc(dbg,td->td_subprog_die,DW_DLA_DIE); td->td_subprog_die = 0; } td->td_cu_haslowhighpc = FALSE; resetsrcfiles(dbg,&td->td_cu_srcfiles); resetsubprog(dbg,td); } static void target_data_destructor( struct target_data_s *td) { Dwarf_Debug dbg = 0; if (!td || !td->td_dbg) { return; } dbg = td->td_dbg; reset_target_data(dbg,td); if (td->td_subprog_srcfile) { dwarf_dealloc(dbg,td->td_subprog_srcfile,DW_DLA_STRING); td->td_subprog_srcfile = 0; } } static void print_target_info( UNUSEDARG Dwarf_Debug dbg, struct target_data_s *td) { printf("FOUND function \"%s\", requested pc 0x%" DW_PR_DUx "\n", td->td_subprog_name?td->td_subprog_name:"", td->td_target_pc); printf(" function lowpc 0x%" DW_PR_DUx " highpc 0x%" DW_PR_DUx "\n", td->td_subprog_lowpc, td->td_subprog_highpc); printf(" file name index 0x%" DW_PR_DUx "\n", td->td_subprog_fileindex); printf(" in:\n"); printf(" CU %" DW_PR_DUu " %s\n", td->td_cu_number, td->td_cu_name?td->td_cu_name:""); printf(" comp-dir %s\n", td->td_cu_comp_dir?td->td_cu_comp_dir:""); printf(" Src line address 0x%" DW_PR_DUx " lineno %" DW_PR_DUu " %s\n", td->td_subprog_lineaddr, td->td_subprog_lineno, td->td_subprog_srcfile); printf("\n"); } static int read_line_data(UNUSEDARG Dwarf_Debug dbg, struct target_data_s *td, Dwarf_Error *errp) { int res = 0; Dwarf_Unsigned line_version = 0; Dwarf_Small table_type = 0; Dwarf_Line_Context line_context = 0; Dwarf_Signed i = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed endindex = 0; Dwarf_Signed file_count = 0; Dwarf_Unsigned dirindex = 0; res = dwarf_srclines_b(td->td_cu_die,&line_version, &table_type,&line_context,errp); if (res != DW_DLV_OK) { return res; } if (td->td_print_details) { printf(" Srclines: linetable version %" DW_PR_DUu " table count %d\n",line_version,table_type); } if (table_type == 0) { /* There are no lines here, just table header and names. */ int sres = 0; sres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (td->td_print_details) { printf(" Filenames base index %" DW_PR_DSd " file count %" DW_PR_DSd " endindex %" DW_PR_DSd "\n", baseindex,file_count,endindex); } for (i = baseindex; i < endindex; i++) { Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; int vres = 0; const char *name = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindex, &modtime,&flength, &md5data,errp); if (vres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; /* something very wrong. */ return vres; } if (td->td_print_details) { printf(" [%" DW_PR_DSd "] " " directory index %" DW_PR_DUu " %s \n",i,dirindex,name); } } dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } else if (table_type == 1) { const char * dir_name = 0; int sres = 0; Dwarf_Line *linebuf = 0; Dwarf_Signed linecount = 0; Dwarf_Signed dir_count = 0; Dwarf_Addr prev_lineaddr = 0; Dwarf_Unsigned prev_lineno = 0; char * prev_linesrcfile = 0; sres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (td->td_print_details) { printf(" Filenames base index %" DW_PR_DSd " file count %" DW_PR_DSd " endindex %" DW_PR_DSd "\n", baseindex,file_count,endindex); } for (i = baseindex; i < endindex; i++) { Dwarf_Unsigned dirindexb = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; int vres = 0; const char *name = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindexb, &modtime,&flength, &md5data,errp); if (vres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; /* something very wrong. */ return vres; } if (td->td_print_details) { printf(" [%" DW_PR_DSd "] " " directory index %" DW_PR_DUu " file: %s \n",i,dirindexb,name); } } sres = dwarf_srclines_include_dir_count(line_context, &dir_count,errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (td->td_print_details) { printf(" Directories count: %" DW_PR_DSd "\n", dir_count); } for (i =1; i <= dir_count; ++i) { dir_name = 0; sres = dwarf_srclines_include_dir_data(line_context, i,&dir_name,errp); if (sres == DW_DLV_ERROR) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } if (sres == DW_DLV_NO_ENTRY) { printf("Something wrong in dir tables line %d %s\n", __LINE__,__FILE__); break; } if (td->td_print_details) { printf(" [%" DW_PR_DSd "] directory: " " %s \n",i,dir_name); } } /* For this case where we have a line table we will likely wish to get the line details: */ sres = dwarf_srclines_from_linecontext(line_context, &linebuf,&linecount, errp); if (sres != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); line_context = 0; return sres; } /* The lines are normal line table lines. */ for (i = 0; i < linecount; ++i) { Dwarf_Addr lineaddr = 0; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned lineno = 0; char * linesrcfile = 0; sres = dwarf_lineno(linebuf[i],&lineno,errp); if (sres == DW_DLV_ERROR) { return sres; } sres = dwarf_line_srcfileno(linebuf[i],&filenum,errp); if (sres == DW_DLV_ERROR) { return sres; } if (filenum) { filenum -= 1; } sres = dwarf_lineaddr(linebuf[i],&lineaddr,errp); if (sres == DW_DLV_ERROR) { return sres; } sres = dwarf_linesrc(linebuf[i],&linesrcfile,errp); if (td->td_print_details) { printf(" [%" DW_PR_DSd "] " " address 0x%" DW_PR_DUx " filenum %" DW_PR_DUu " lineno %" DW_PR_DUu " %s \n",i,lineaddr,filenum,lineno,linesrcfile); } if (lineaddr > td->td_target_pc) { /* Here we detect the right source and line */ td->td_subprog_lineaddr = prev_lineaddr; td->td_subprog_lineno = prev_lineno; td->td_subprog_srcfile = prev_linesrcfile; return DW_DLV_OK; } prev_lineaddr = lineaddr; prev_lineno = lineno; if (prev_linesrcfile) { dwarf_dealloc(dbg,prev_linesrcfile,DW_DLA_STRING); } prev_linesrcfile = linesrcfile; } /* Here we detect the right source and line (last such in this subprogram) */ td->td_subprog_lineaddr = prev_lineaddr; td->td_subprog_lineno = prev_lineno; td->td_subprog_srcfile = prev_linesrcfile; dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } return DW_DLV_ERROR; #if 0 /* ASSERT: table_type == 2, Experimental two-level line table. Version 0xf006 We do not define the meaning of this non-standard set of tables here. */ /* For ’something C’ (two-level line tables) one codes something like this Note that we do not define the meaning or use of two-level li tables as these are experimental, not standard DWARF. */ sres = dwarf_srclines_two_level_from_linecontext(line_context, &linebuf,&linecount, &linebuf_actuals,&linecount_actuals, &err); if (sres == DW_DLV_OK) { for (i = 0; i < linecount; ++i) { /* use linebuf[i], these are the ’logicals’ entries. */ } for (i = 0; i < linecount_actuals; ++i) { /* use linebuf_actuals[i], these are the actuals entries */ } dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } else if (sres == DW_DLV_NO_ENTRY) { dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; return sres; } else { /*DW_DLV_ERROR */ return sres; } #endif /* 0 */ } static int look_for_our_target(Dwarf_Debug dbg, struct target_data_s *td, Dwarf_Error *errp) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Half version_stamp = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Unsigned typeoffset = 0; Dwarf_Half header_cu_type = unittype; Dwarf_Bool is_info = g_is_info; int cu_number = 0; for(;;++cu_number) { Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; Dwarf_Sig8 signature; memset(&signature,0, sizeof(signature)); reset_target_data(dbg,td); res = dwarf_next_cu_header_d(dbg,is_info,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &offset_size, &extension_size,&signature, &typeoffset, 0, &header_cu_type,errp); if(res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in dwarf_next_cu_header: %s\n",em); target_data_destructor(td); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ target_data_destructor(td); return DW_DLV_NO_ENTRY; } cu_version_stamp = version_stamp; cu_offset_size = offset_size; /* The CU will have a single sibling, a cu_die. */ res = dwarf_siblingof_b(dbg,no_die,is_info, &cu_die,errp); if(res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in dwarf_siblingof_b on CU die: %s\n",em); target_data_destructor(td); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ printf("no entry! in dwarf_siblingof on CU die \n"); target_data_destructor(td); exit(1); } td->td_cu_die = cu_die; res = get_die_and_siblings(dbg,cu_die,is_info,0,cu_number, td,errp); if (res == FOUND_SUBPROG) { read_line_data(dbg,td,errp); print_target_info(dbg,td); if (td->td_reportallfound) { target_data_destructor(td); return res; } reset_target_data(dbg,td); } else if (res == IN_THIS_CU) { char *em = dwarf_errmsg(*errp); printf("Impossible return code in reading DIEs: %s\n",em); target_data_destructor(td); exit(1); } else if (res == NOT_THIS_CU) { /* This is normal. Keep looking */ } else if (res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in reading DIEs: %s\n",em); target_data_destructor(td); exit(1); } else if (res == DW_DLV_NO_ENTRY) { /* This is odd. Assume normal. */ } else { /* DW_DLV_OK. normal. */ } reset_target_data(dbg,td); } return DW_DLV_NO_ENTRY; } /* Recursion, following DIE tree. On initial call in_die is a cu_die (in_level 0 ) */ static int get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info,int in_level,int cu_number, struct target_data_s *td, Dwarf_Error *errp) { int res = DW_DLV_ERROR; Dwarf_Die cur_die=in_die; Dwarf_Die child = 0; td->td_cu_number = cu_number; res = examine_die_data(dbg,is_info,in_die,in_level,td,errp); if (res == DW_DLV_ERROR) { printf("Error in die access , level %d \n",in_level); exit(1); } else if (res == DW_DLV_NO_ENTRY) { return res; } else if ( res == NOT_THIS_CU) { return res; } else if ( res == IN_THIS_CU) { /* Fall through to examine details. */ } else if ( res == FOUND_SUBPROG) { return res; } else { /* DW_DLV_OK */ /* Fall through to examine details. */ } /* Now look at the children of the incoming DIE */ for(;;) { Dwarf_Die sib_die = 0; res = dwarf_child(cur_die,&child,errp); if(res == DW_DLV_ERROR) { printf("Error in dwarf_child , level %d \n",in_level); exit(1); } if(res == DW_DLV_OK) { int res2 = 0; res2 = get_die_and_siblings(dbg,child,is_info, in_level+1,cu_number,td,errp); if (child != td->td_cu_die && child != td->td_subprog_die) { /* No longer need 'child' die. */ dwarf_dealloc(dbg,child,DW_DLA_DIE); } if (res2 == FOUND_SUBPROG) { return res2; } else if (res2 == IN_THIS_CU) { /* fall thru */ } else if (res2 == NOT_THIS_CU) { return res2; } else if (res2 == DW_DLV_ERROR) { return res2; } else if (res2 == DW_DLV_NO_ENTRY) { /* fall thru */ } else { /* DW_DLV_OK */ /* fall thru */ } child = 0; } res = dwarf_siblingof_b(dbg,cur_die,is_info, &sib_die,errp); if(res == DW_DLV_ERROR) { char *em = dwarf_errmsg(*errp); printf("Error in dwarf_siblingof_b , level %d :%s \n", in_level,em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if(cur_die != in_die) { if (child != td->td_cu_die && child != td->td_subprog_die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); } cur_die = 0; } cur_die = sib_die; res = examine_die_data(dbg,is_info,cur_die,in_level,td,errp); if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_OK) { /* fall through */ } else if (res == FOUND_SUBPROG) { return res; } else if (res == NOT_THIS_CU) { /* impossible */ } else if (res == IN_THIS_CU) { /* impossible */ } else {/* res == DW_DLV_NO_ENTRY */ /* impossible */ /* fall through */ } } return DW_DLV_OK; } #if 0 static void get_addr(Dwarf_Attribute attr,Dwarf_Addr *val) { Dwarf_Error error = 0; int res; Dwarf_Addr uval = 0; Dwarf_Error *errp = 0; errp = &error; res = dwarf_formaddr(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } return; } static void get_number(Dwarf_Attribute attr,Dwarf_Unsigned *val) { Dwarf_Error error = 0; int res; Dwarf_Signed sval = 0; Dwarf_Unsigned uval = 0; Dwarf_Error *errp = 0; errp = &error; res = dwarf_formudata(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } res = dwarf_formsdata(attr,&sval,errp); if(res == DW_DLV_OK) { *val = sval; return; } return; } #endif static int getlowhighpc(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG struct target_data_s *td, Dwarf_Die die, UNUSEDARG int level, int *have_pc_range, Dwarf_Addr *lowpc_out, Dwarf_Addr *highpc_out, Dwarf_Error*error) { Dwarf_Addr hipc = 0; int res = 0; Dwarf_Half form = 0; enum Dwarf_Form_Class formclass = 0; *have_pc_range = FALSE; res = dwarf_lowpc(die,lowpc_out,error); if (res == DW_DLV_OK) { res = dwarf_highpc_b(die,&hipc,&form,&formclass,error); if (res == DW_DLV_OK) { if (formclass == DW_FORM_CLASS_CONSTANT) { hipc += *lowpc_out; } *highpc_out = hipc; *have_pc_range = TRUE; return DW_DLV_OK; } } /* Cannot check ranges yet, we don't know the ranges base offset yet. */ return DW_DLV_NO_ENTRY; } static int check_subprog_ranges_for_match(Dwarf_Debug dbg, UNUSEDARG int is_info, Dwarf_Die die, UNUSEDARG int level, struct target_data_s *td, int *have_pc_range, Dwarf_Addr *lowpc_out, Dwarf_Addr *highpc_out, Dwarf_Error *errp) { int res = 0; Dwarf_Ranges *ranges; Dwarf_Signed ranges_count; Dwarf_Unsigned byte_count; Dwarf_Signed i = 0; Dwarf_Addr baseaddr = 0; int done = FALSE; /* Check libdwarf to ensure ranges_base not added again. FIXME */ res = dwarf_get_ranges_a(dbg,td->td_ranges_offset, die, &ranges, &ranges_count, &byte_count, errp); if (res != DW_DLV_OK) { return res; } for (i=0; i < ranges_count && !done; ++i) { Dwarf_Ranges *cur = ranges+i; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; switch(cur->dwr_type) { case DW_RANGES_ENTRY: lowpc = cur->dwr_addr1 +baseaddr; highpc = cur->dwr_addr2 +baseaddr; if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this CU */ break; } *lowpc_out = lowpc; *highpc_out = highpc; *have_pc_range = TRUE; done = TRUE; res = FOUND_SUBPROG; break; case DW_RANGES_ADDRESS_SELECTION: baseaddr = cur->dwr_addr2; break; case DW_RANGES_END: break; default: printf("Impossible debug_ranges content!" " enum val %d \n",(int)cur->dwr_type); exit(1); } } dwarf_ranges_dealloc(dbg,ranges,ranges_count); return res; } /* The return value is not interesting. Getting the name is interesting. */ static int get_name_from_abstract_origin(Dwarf_Debug dbg, int is_info, Dwarf_Die die, char ** name, Dwarf_Error *errp) { int res = 0; Dwarf_Die abrootdie = 0; Dwarf_Attribute ab_attr = 0; Dwarf_Off ab_offset = 0; res = dwarf_attr(die,DW_AT_abstract_origin,&ab_attr,errp); if (res != DW_DLV_OK) { return res; } res = dwarf_global_formref(ab_attr,&ab_offset,errp); if (res != DW_DLV_OK) { return res; } res = dwarf_offdie_b(dbg,ab_offset,is_info,&abrootdie,errp) ; if (res != DW_DLV_OK) { return res; } res = dwarf_diename(abrootdie,name,errp); if (res == DW_DLV_OK) { } return res; } static int check_subprog_details(Dwarf_Debug dbg, int is_info, Dwarf_Die die, UNUSEDARG int level, struct target_data_s *td, int *have_pc_range_out, Dwarf_Addr *lowpc_out, Dwarf_Addr *highpc_out, Dwarf_Error *errp) { int res = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; int finalres = 0; int have_pc_range = FALSE; res = getlowhighpc(dbg,td,die,level,&have_pc_range,&lowpc,&highpc,errp); if (res == DW_DLV_OK) { if (have_pc_range) { int res2 = DW_DLV_OK; char *name = 0; if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this subprogram */ finalres = DW_DLV_OK; } else { td->td_subprog_die = die; td->td_subprog_lowpc = lowpc; *lowpc_out = lowpc; *highpc_out = highpc; *have_pc_range_out = have_pc_range; td->td_subprog_highpc = highpc; td->td_subprog_haslowhighpc = have_pc_range; res2 = dwarf_diename(die,&name,errp); if (res2 == DW_DLV_OK) { td->td_subprog_name = name; } else { get_name_from_abstract_origin(dbg,is_info, die, &name, errp); } if (td->td_subprog_name) { dwarf_dealloc(dbg,td->td_subprog_name, DW_DLA_STRING); } td->td_subprog_name = name; name = 0; /* Means this is an address match */ finalres = FOUND_SUBPROG; } } } { Dwarf_Signed i = 0; Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; res = dwarf_attrlist(die,&atlist,&atcount,errp); if(res != DW_DLV_OK) { return res; } for(i = 0; i < atcount ; ++i) { Dwarf_Half atr = 0; Dwarf_Attribute attrib = atlist[i]; res = dwarf_whatattr(attrib,&atr,errp); if(res != DW_DLV_OK) { /* Something is very wrong here.*/ if (td->td_print_details) { printf("dwarf_whatattr returns bad errcode %d\n", res); } return res; } if (atr == DW_AT_ranges) { int res2 = 0; Dwarf_Off ret_offset = 0; int has_low_hi = FALSE; Dwarf_Addr low = 0; Dwarf_Addr high = 0; res2 = dwarf_global_formref(attrib, &ret_offset,errp); if (res2 != DW_DLV_OK) { return res2; } td->td_ranges_offset = ret_offset + td->td_cu_ranges_base; res = check_subprog_ranges_for_match(dbg, is_info, die, level, td, &has_low_hi, &low, &high, errp); if (res == DW_DLV_OK) { continue; } else if (res == DW_DLV_OK) { continue; } else if (res == DW_DLV_NO_ENTRY) { continue; } else if (res == FOUND_SUBPROG) { td->td_subprog_lowpc = lowpc; td->td_subprog_highpc = highpc; td->td_subprog_haslowhighpc = has_low_hi; finalres = FOUND_SUBPROG; continue; } else { return res; } } else if(atr == DW_AT_decl_file ) { int res3 = 0; Dwarf_Unsigned file_index = 0; res3 = dwarf_formudata(attrib,&file_index,errp); if (res3 != DW_DLV_OK) { return res3; } td->td_subprog_fileindex = file_index; } dwarf_dealloc(dbg,attrib,DW_DLA_ATTR); } dwarf_dealloc(dbg,atlist,DW_DLA_LIST); } return finalres; } static int check_comp_dir(Dwarf_Debug dbg,Dwarf_Die die, int level, struct target_data_s *td,Dwarf_Error *errp) { int res = 0; int resb = 0; int finalres = 0; int have_pc_range = FALSE; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Off real_ranges_offset = 0; int rdone = FALSE; res = getlowhighpc(dbg,td,die, level, &have_pc_range, &lowpc,&highpc,errp); if (res == DW_DLV_OK) { if (have_pc_range) { if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this CU */ res = NOT_THIS_CU; } else { td->td_cu_lowpc = lowpc; td->td_cu_highpc = highpc; /* td->td_cu_haslowhighpc = have_pc_range; */ res = IN_THIS_CU; } } } finalres = IN_THIS_CU; { Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; Dwarf_Signed j = 0; res = dwarf_attrlist(die,&atlist,&atcount,errp); if(res != DW_DLV_OK) { return res; } for(j = 0; j < atcount ; ++j) { Dwarf_Half atr = 0; Dwarf_Attribute attrib = atlist[j]; resb = dwarf_whatattr(attrib,&atr,errp); if(resb != DW_DLV_OK) { /* Something is very wrong here.*/ printf("dwarf_whatattr returns bad errcode %d, " "serious error somewhere.\n", res); return resb; } if(atr == DW_AT_name) { char *name = 0; resb = dwarf_formstring(attrib,&name,errp); if (resb == DW_DLV_OK) { td->td_cu_name = name; } } else if (atr == DW_AT_comp_dir) { char *name = 0; resb = dwarf_formstring(attrib,&name,errp); if (resb == DW_DLV_OK) { td->td_cu_comp_dir = name; } } else if(atr == DW_AT_rnglists_base || atr == DW_AT_GNU_ranges_base) { Dwarf_Off rbase = 0; resb = dwarf_global_formref(attrib,&rbase,errp); if (resb != DW_DLV_OK) { return resb; } td->td_cu_ranges_base = rbase; } else if (atr == DW_AT_ranges) { /* we have actual ranges. */ Dwarf_Off rbase = 0; resb = dwarf_global_formref(attrib,&rbase,errp); if (resb != DW_DLV_OK) { return resb; } real_ranges_offset = rbase; rdone = TRUE; } dwarf_dealloc(dbg,attrib,DW_DLA_ATTR); } dwarf_dealloc(dbg,atlist,DW_DLA_LIST); } if (rdone) { /* We can do get ranges now as we already saw ranges base above (if any). */ int resr = 0; Dwarf_Ranges *ranges; Dwarf_Signed ranges_count; Dwarf_Unsigned byte_count; Dwarf_Signed k = 0; int done = FALSE; resr = dwarf_get_ranges_a(dbg,real_ranges_offset, die, &ranges, &ranges_count, &byte_count, errp); if (resr != DW_DLV_OK) { /* Something badly wrong here. */ return res; } for (k=0; k < ranges_count && !done; ++k) { Dwarf_Ranges *cur = ranges+k; Dwarf_Addr lowpcr = 0; Dwarf_Addr highpcr = 0; Dwarf_Addr baseaddr = td->td_cu_ranges_base; switch(cur->dwr_type) { case DW_RANGES_ENTRY: lowpc = cur->dwr_addr1 +baseaddr; highpc = cur->dwr_addr2 +baseaddr; if (td->td_target_pc < lowpc || td->td_target_pc >= highpc) { /* We have no interest in this CU */ break; } td->td_cu_lowpc = lowpcr; td->td_cu_highpc = highpcr; td->td_cu_haslowhighpc = TRUE; done = TRUE; res = IN_THIS_CU; break; case DW_RANGES_ADDRESS_SELECTION: baseaddr = cur->dwr_addr2; break; case DW_RANGES_END: break; default: printf("Impossible debug_ranges content!" " enum val %d \n",(int)cur->dwr_type); exit(1); } } dwarf_ranges_dealloc(dbg,ranges,ranges_count); } return finalres; #if 0 /* dwarf pdf page 101 */ sf->srcfilesres = dwarf_srcfiles(die,&sf->srcfiles, &sf->srcfilescount, errp); if (sf->srcfilesres == DW_DLV_ERROR) { } /* see pdf, page 95 */ res2 = dwarf_srclines_comp_dir(linecontext, /* see pdf, page 92 */ res2 = dwarf_srclines_b(die,&version,&table_count, &linecontext,errp); /* see dwarf_srclines_dealloc_b() page 91*/ res2 = dwarf_srclines_from_linecontext(linecontext, &linebuf,&linecount,errp); /* files_indexes are page 96 */ int dwarf_srclines_files_indexes(linecontext, &baseindex, &filescount,&endindex,errp); #endif } static int examine_die_data(Dwarf_Debug dbg, int is_info, Dwarf_Die die, int level, struct target_data_s *td, Dwarf_Error *errp) { Dwarf_Half tag = 0; int res = 0; res = dwarf_tag(die,&tag,errp); if(res != DW_DLV_OK) { printf("Error in dwarf_tag , level %d \n",level); exit(1); } if( tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { int have_pc_range = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; res = check_subprog_details(dbg,is_info,die,level,td, &have_pc_range, &lowpc, &highpc, errp); if (res == FOUND_SUBPROG) { td->td_subprog_die = die; return res; } else if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_NO_ENTRY) { /* impossible? */ return res; } else if (res == NOT_THIS_CU) { /* impossible */ return res; } else if (res == IN_THIS_CU) { /* impossible */ return res; } else { /* DW_DLV_OK */ } return DW_DLV_OK; } else if(tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit || tag == DW_TAG_type_unit) { if (level) { /* Something badly wrong, CU DIEs are only at level 0. */ return NOT_THIS_CU; } res = check_comp_dir(dbg,die,level,td,errp); return res; } /* Keep looking */ return DW_DLV_OK; } dwarfutils-20200114/dwarfexample/frame1.c000066400000000000000000000541631361531463500201470ustar00rootroot00000000000000/* Copyright (c) 2009-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* simplereader.c This is an example of code reading dwarf .debug_frame. It is kept as simple as possible to expose essential features. It does not do all possible error reporting or error handling. It specifically calls dwarf_expand_frame_instructions() to verify that works without crashing! To use, try make ./frame1 frame1 gcc/clang may produce .eh_frame without .debug_frame. To read .eh_frame call dwarf_get_fde_list_eh() below instead of dwarf_get_fde_list() . */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_SYS_TYPES_H #include /* For open() */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include /* For open() */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_UNISTD_H #include /* For close() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ #include /* For strcmp* */ #include #include #include "dwarf.h" #include "libdwarf.h" static void read_frame_data(Dwarf_Debug dbg,const char *sec); static void print_fde_instrs(Dwarf_Debug dbg, Dwarf_Fde fde, Dwarf_Error *error); static void print_regtable(Dwarf_Regtable3 *tab3); static void print_cie_instrs(Dwarf_Cie cie,Dwarf_Error *error); static void print_fde_selected_regs( Dwarf_Fde fde); static void print_reg(int r); static int just_print_selected_regs = 0; /* Depending on the ABI we set INITIAL_VAL differently. For ia64 initial value is UNDEF_VAL, for MIPS and others initial value is SAME_VAL. Here we'll set it UNDEF_VAL as that way we'll see when first set. */ #define UNDEF_VAL 2000 #define SAME_VAL 2001 #define CFA_VAL 2002 #define INITIAL_VAL UNDEF_VAL /* Don't really want getopt here. yet. so hand do options. */ int main(int argc, char **argv) { Dwarf_Debug dbg = 0; int fd = -1; const char *filepath = ""; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; int regtabrulecount = 0; int curopt = 0; for(curopt = 1;curopt < argc; ++curopt) { if (strncmp(argv[curopt],"--",2)) { break; } if (!strcmp(argv[curopt],"--just-print-selected-regs")) { just_print_selected_regs++; } } if(curopt == argc ) { fd = 0; /* stdin */ } else if (curopt == (argc-1)) { filepath = argv[curopt]; fd = open(filepath,O_RDONLY|O_BINARY); } else { printf("Too many args, giving up. \n"); exit(1); } if(fd < 0) { printf("Failure attempting to open %s\n",filepath); } res = dwarf_init_b(fd,DW_DLC_READ,DW_GROUPNUMBER_ANY, errhand,errarg, &dbg,&error); if(res != DW_DLV_OK) { printf("Giving up, dwarf_init failed, cannot do DWARF processing\n"); if (res == DW_DLV_ERROR) { printf("Error code %s\n",dwarf_errmsg(error)); } exit(1); } /* Do this setting after init before any real operations. These return the old values, but here we do not need to know the old values. The sizes and values here are higher than most ABIs and entirely arbitrary. The setting of initial_value to the same as undefined-value (the other possible choice being same-value) is arbitrary, different ABIs do differ, and you have to know which is right. In dwarfdump we get the SAME_VAL, UNDEF_VAL, INITIAL_VAL CFA_VAL from dwconf_s struct. */ regtabrulecount=1999; dwarf_set_frame_undefined_value(dbg, UNDEF_VAL); dwarf_set_frame_rule_initial_value(dbg, INITIAL_VAL); dwarf_set_frame_same_value(dbg,SAME_VAL); dwarf_set_frame_cfa_value(dbg,CFA_VAL); dwarf_set_frame_rule_table_size(dbg,regtabrulecount); read_frame_data(dbg,".debug_frame"); read_frame_data(dbg,".eh_frame"); res = dwarf_finish(dbg,&error); if(res != DW_DLV_OK) { printf("dwarf_finish failed!\n"); } close(fd); return 0; } static void read_frame_data(Dwarf_Debug dbg,const char *sect) { Dwarf_Error error; Dwarf_Signed cie_element_count = 0; Dwarf_Signed fde_element_count = 0; Dwarf_Cie *cie_data = 0; Dwarf_Fde *fde_data = 0; int res = DW_DLV_ERROR; Dwarf_Signed fdenum = 0; /* If you wish to read .eh_frame data, use dwarf_get_fde_list_eh() instead. Get debug_frame with dwarf_get_fde_list. */ printf(" Print %s\n",sect); if (!strcmp(sect,".eh_frame")) { res = dwarf_get_fde_list_eh(dbg,&cie_data,&cie_element_count, &fde_data,&fde_element_count,&error); } else { res = dwarf_get_fde_list(dbg,&cie_data,&cie_element_count, &fde_data,&fde_element_count,&error); } if(res == DW_DLV_NO_ENTRY) { printf("No %s data present\n",sect); return; } if( res == DW_DLV_ERROR) { printf("Error reading frame data "); exit(1); } printf( "%" DW_PR_DSd " cies present. " "%" DW_PR_DSd " fdes present. \n", cie_element_count,fde_element_count); /*if(fdenum >= fde_element_count) { printf("Want fde %d but only %" DW_PR_DSd " present\n",fdenum, fde_element_count); exit(1); }*/ for(fdenum = 0; fdenum < fde_element_count; ++fdenum) { Dwarf_Cie cie = 0; res = dwarf_get_cie_of_fde(fde_data[fdenum],&cie,&error); if(res != DW_DLV_OK) { printf("Error accessing cie of fdenum %" DW_PR_DSd " to get its cie\n",fdenum); exit(1); } printf("Print cie of fde %" DW_PR_DSd "\n",fdenum); print_cie_instrs(cie,&error); printf("Print fde %" DW_PR_DSd "\n",fdenum); if (just_print_selected_regs) { print_fde_selected_regs(fde_data[fdenum]); } else { print_fde_instrs(dbg,fde_data[fdenum],&error); } } /* Done with the data. */ dwarf_fde_cie_list_dealloc(dbg,cie_data,cie_element_count, fde_data, fde_element_count); return; } /* Simply shows the instructions at hand for this fde. */ static void print_cie_instrs(Dwarf_Cie cie,Dwarf_Error *error) { int res = DW_DLV_ERROR; Dwarf_Unsigned bytes_in_cie = 0; Dwarf_Small version = 0; char *augmentation = 0; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr instrp = 0; Dwarf_Unsigned instr_len = 0; res = dwarf_get_cie_info(cie,&bytes_in_cie, &version, &augmentation, &code_alignment_factor, &data_alignment_factor, &return_address_register_rule, &instrp,&instr_len,error); if(res != DW_DLV_OK) { printf("Unable to get cie info!\n"); exit(1); } } /* This was written with DWARF2 Dwarf_Frame_Op! FIXME need dwarf_expand_frame_instructions_b() */ static void print_frame_instrs(Dwarf_Frame_Op *frame_op_array, Dwarf_Signed frame_op_count) { Dwarf_Signed i = 0; printf("Base op. Ext op. Reg. Offset. Instr-offset.\n"); for(i = 0; i < frame_op_count; ++i) { Dwarf_Frame_Op *fo = frame_op_array +i; printf("[%2" DW_PR_DSd "]", i); printf(" %2d. ", fo->fp_base_op); printf(" 0x%02x. ", fo->fp_extended_op); printf(" %3d. ", fo->fp_register); /* DWARF3 and later: for DW_CFA_def_cfa_expression, DW_CFA_val_expression, and DW_CFA_expression the fp_offset is a pointer into runtime memory. Printing it is not helpful in a diff. */ if (fo->fp_extended_op == DW_CFA_def_cfa || fo->fp_extended_op == DW_CFA_val_expression || fo->fp_extended_op == DW_CFA_def_cfa_expression ) { /* The offset is really a pointer. */ printf(" (pointer-value) "); } else { /* The offset is a real offset /value of some sort. */ printf(" %6" DW_PR_DSd ". ", fo->fp_offset); } printf(" 0x%08" DW_PR_DUx ". ", fo->fp_instr_offset); printf("\n"); } } static void print_fde_col(Dwarf_Signed k, Dwarf_Addr jsave, Dwarf_Small value_type, Dwarf_Signed offset_relevant, Dwarf_Signed reg_used, Dwarf_Signed offset_or_block_len, Dwarf_Ptr block_ptr, Dwarf_Addr row_pc, Dwarf_Bool has_more_rows, Dwarf_Addr subsequent_pc) { char *type_title = ""; Dwarf_Unsigned rule_id = k; printf(" pc=0x%" DW_PR_DUx ,jsave); if (row_pc != jsave) { printf(" row_pc=0x%" DW_PR_DUx ,row_pc); } printf(" col=%" DW_PR_DSd " ",k); switch(value_type) { case DW_EXPR_OFFSET: type_title = "off"; goto preg2; case DW_EXPR_VAL_OFFSET: type_title = "valoff"; preg2: printf("<%s ", type_title); if (reg_used == SAME_VAL) { printf(" SAME_VAL"); break; } else if (reg_used == INITIAL_VAL) { printf(" INITIAL_VAL"); break; } print_reg(rule_id); printf("="); if (offset_relevant == 0) { print_reg(reg_used); printf(" "); } else { printf("%02" DW_PR_DSd , offset_or_block_len); printf("("); print_reg(reg_used); printf(") "); } break; case DW_EXPR_EXPRESSION: type_title = "expr"; goto pexp2; case DW_EXPR_VAL_EXPRESSION: type_title = "valexpr"; pexp2: printf("<%s ", type_title); print_reg(rule_id); printf("="); printf("expr-block-len=%" DW_PR_DSd , offset_or_block_len); printf(" block-ptr=%" DW_PR_DUx, (Dwarf_Unsigned)(uintptr_t)block_ptr); #if 0 { char pref[40]; strcpy(pref, "<"); strcat(pref, type_title); strcat(pref, "bytes:"); /* The data being dumped comes direct from libdwarf so libdwarf validated it. */ dump_block(pref, block_ptr, offset_or_block_len); printf("%s", "> "); if (glflags.verbose) { struct esb_s exprstring; esb_constructor(&exprstring); get_string_from_locs(dbg, block_ptr,offset,addr_size, offset_size,version,&exprstring); printf("",esb_get_string(&exprstring)); esb_destructor(&exprstring); } } #endif break; default: printf("Internal error in libdwarf, value type %d\n", value_type); exit(1); } printf(" more=%d",has_more_rows); printf(" next=0x%" DW_PR_DUx,subsequent_pc); printf("%s", "> "); printf("\n"); } /* In dwarfdump we use dwarf_get_fde_info_for_cfa_reg3_b() to get subsequent pc and avoid incrementing pc by for the next cfa, using has_more_rows and subsequent_pc passed back. Here, to verify function added in May 2018, we instead use dwarf_get_fde_info_for_reg3_b() which has the has_more_rows and subsequent_pc functions for the case where one is tracking a particular register and not closely watching the CFA value itself. */ static void print_fde_selected_regs( Dwarf_Fde fde) { Dwarf_Error oneferr = 0; /* Arbitrary column numbers for testing. */ static int selected_cols[] = {1,3,5}; static int selected_cols_count = sizeof(selected_cols)/sizeof(selected_cols[0]); Dwarf_Signed k = 0; int fres = 0; Dwarf_Addr low_pc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Ptr fde_bytes = NULL; Dwarf_Unsigned fde_bytes_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; Dwarf_Fde curfde = fde; Dwarf_Cie cie = 0; Dwarf_Addr jsave = 0; Dwarf_Addr high_addr = 0; Dwarf_Addr next_jsave = 0; Dwarf_Bool has_more_rows = 0; Dwarf_Addr subsequent_pc = 0; Dwarf_Error error = 0; int res = 0; fres = dwarf_get_fde_range(curfde, &low_pc, &func_length, &fde_bytes, &fde_bytes_length, &cie_offset, &cie_index, &fde_offset, &oneferr); if (fres == DW_DLV_ERROR) { printf("FAIL: dwarf_get_fde_range err %" DW_PR_DUu " line %d\n", dwarf_errno(oneferr),__LINE__); exit(1); } if (fres == DW_DLV_NO_ENTRY) { printf("No fde range data available\n"); return; } res = dwarf_get_cie_of_fde(fde,&cie,&error); if(res != DW_DLV_OK) { printf("Error getting cie from fde\n"); exit(1); } high_addr = low_pc + func_length; /* Could check has_more_rows here instead of high_addr, If we initialized has_more_rows to 1 above. */ for(jsave = low_pc ; next_jsave < high_addr; jsave = next_jsave) { next_jsave = jsave+1; printf("\n"); for(k = 0; k < selected_cols_count ; ++k ) { Dwarf_Signed reg = 0; Dwarf_Signed offset_relevant = 0; int fires = 0; Dwarf_Small value_type = 0; Dwarf_Ptr block_ptr = 0; Dwarf_Signed offset_or_block_len = 0; Dwarf_Addr row_pc = 0; fires = dwarf_get_fde_info_for_reg3_b(curfde, selected_cols[k], jsave, &value_type, &offset_relevant, ®, &offset_or_block_len, &block_ptr, &row_pc, &has_more_rows, &subsequent_pc, &oneferr); if (fires == DW_DLV_ERROR) { printf("FAIL: reading reg err %" DW_PR_DUu " line %d", dwarf_errno(oneferr),__LINE__); exit(1); } if (fires == DW_DLV_NO_ENTRY) { continue; } print_fde_col( selected_cols[k],jsave, value_type,offset_relevant, reg,offset_or_block_len,block_ptr,row_pc, has_more_rows, subsequent_pc); if (has_more_rows) { next_jsave = subsequent_pc; } else { next_jsave = high_addr; } } } } /* Just prints the instructions in the fde. */ static void print_fde_instrs(Dwarf_Debug dbg, Dwarf_Fde fde, Dwarf_Error *error) { int res; Dwarf_Addr lowpc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Ptr fde_bytes; Dwarf_Unsigned fde_byte_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; Dwarf_Addr arbitrary_addr = 0; Dwarf_Addr actual_pc = 0; Dwarf_Regtable3 tab3; int oldrulecount = 0; Dwarf_Ptr outinstrs = 0; Dwarf_Unsigned instrslen = 0; Dwarf_Frame_Op * frame_op_array = 0; Dwarf_Signed frame_op_count = 0; Dwarf_Cie cie = 0; res = dwarf_get_fde_range(fde,&lowpc,&func_length,&fde_bytes, &fde_byte_length,&cie_offset,&cie_index,&fde_offset,error); if(res != DW_DLV_OK) { printf("Problem getting fde range \n"); exit(1); } arbitrary_addr = lowpc + (func_length/2); printf("function low pc 0x%" DW_PR_DUx " and length 0x%" DW_PR_DUx " and midpoint addr we choose 0x%" DW_PR_DUx "\n", lowpc,func_length,arbitrary_addr); /* 1 is arbitrary. We are winding up getting the rule count here while leaving things unchanged. */ oldrulecount = dwarf_set_frame_rule_table_size(dbg,1); dwarf_set_frame_rule_table_size(dbg,oldrulecount); tab3.rt3_reg_table_size = oldrulecount; tab3.rt3_rules = (struct Dwarf_Regtable_Entry3_s *) malloc( sizeof(struct Dwarf_Regtable_Entry3_s)* oldrulecount); if (!tab3.rt3_rules) { printf("Unable to malloc for %d rules\n",oldrulecount); exit(1); } res = dwarf_get_fde_info_for_all_regs3(fde,arbitrary_addr , &tab3,&actual_pc,error); printf("function actual addr of row 0x%" DW_PR_DUx "\n", actual_pc); if(res != DW_DLV_OK) { printf("dwarf_get_fde_info_for_all_regs3 failed!\n"); exit(1); } print_regtable(&tab3); res = dwarf_get_fde_instr_bytes(fde,&outinstrs,&instrslen,error); if(res != DW_DLV_OK) { printf("dwarf_get_fde_instr_bytes failed!\n"); exit(1); } res = dwarf_get_cie_of_fde(fde,&cie,error); if(res != DW_DLV_OK) { printf("Error getting cie from fde\n"); exit(1); } res = dwarf_expand_frame_instructions(cie, outinstrs,instrslen,&frame_op_array, &frame_op_count,error); if(res != DW_DLV_OK) { printf("dwarf_expand_frame_instructions failed!\n"); exit(1); } printf("Frame op count: %" DW_PR_DUu "\n",frame_op_count); print_frame_instrs(frame_op_array,frame_op_count); dwarf_dealloc(dbg,frame_op_array, DW_DLA_FRAME_BLOCK); free(tab3.rt3_rules); } static void print_reg(int r) { switch(r) { case SAME_VAL: printf(" %d SAME_VAL ",r); break; case UNDEF_VAL: printf(" %d UNDEF_VAL ",r); break; case CFA_VAL: printf(" %d (CFA) ",r); break; default: printf(" r%d ",r); break; } } static void print_one_regentry(const char *prefix, struct Dwarf_Regtable_Entry3_s *entry) { int is_cfa = !strcmp("cfa",prefix); printf("%s ",prefix); printf("type: %d %s ", entry->dw_value_type, (entry->dw_value_type == DW_EXPR_OFFSET)? "DW_EXPR_OFFSET": (entry->dw_value_type == DW_EXPR_VAL_OFFSET)? "DW_EXPR_VAL_OFFSET": (entry->dw_value_type == DW_EXPR_EXPRESSION)? "DW_EXPR_EXPRESSION": (entry->dw_value_type == DW_EXPR_VAL_EXPRESSION)? "DW_EXPR_VAL_EXPRESSION": "Unknown"); switch(entry->dw_value_type) { case DW_EXPR_OFFSET: print_reg(entry->dw_regnum); printf(" offset_rel? %d ",entry->dw_offset_relevant); if(entry->dw_offset_relevant) { printf(" offset %" DW_PR_DSd " " , entry->dw_offset_or_block_len); if(is_cfa) { printf("defines cfa value"); } else { printf("address of value is CFA plus signed offset"); } if(!is_cfa && entry->dw_regnum != CFA_VAL) { printf(" compiler botch, regnum != CFA_VAL"); } } else { printf("value in register"); } break; case DW_EXPR_VAL_OFFSET: print_reg(entry->dw_regnum); printf(" offset %" DW_PR_DSd " " , entry->dw_offset_or_block_len); if(is_cfa) { printf("does this make sense? No?"); } else { printf("value at CFA plus signed offset"); } if(!is_cfa && entry->dw_regnum != CFA_VAL) { printf(" compiler botch, regnum != CFA_VAL"); } break; case DW_EXPR_EXPRESSION: print_reg(entry->dw_regnum); printf(" offset_rel? %d ",entry->dw_offset_relevant); printf(" offset %" DW_PR_DSd " " , entry->dw_offset_or_block_len); printf("Block ptr set? %s ",entry->dw_block_ptr?"yes":"no"); printf(" Value is at address given by expr val "); /* printf(" block-ptr 0x%" DW_PR_DUx " ", (Dwarf_Unsigned)entry->dw_block_ptr); */ break; case DW_EXPR_VAL_EXPRESSION: printf(" expression byte len %" DW_PR_DSd " " , entry->dw_offset_or_block_len); printf("Block ptr set? %s ",entry->dw_block_ptr?"yes":"no"); printf(" Value is expr val "); if(!entry->dw_block_ptr) { printf("Compiler botch. "); } /* printf(" block-ptr 0x%" DW_PR_DUx " ", (Dwarf_Unsigned)entry->dw_block_ptr); */ break; } printf("\n"); } static void print_regtable(Dwarf_Regtable3 *tab3) { int r; /* We won't print too much. A bit arbitrary. */ int max = 10; if(max > tab3->rt3_reg_table_size) { max = tab3->rt3_reg_table_size; } print_one_regentry("cfa",&tab3->rt3_cfa_rule); for(r = 0; r < max; r++) { char rn[30]; snprintf(rn,sizeof(rn),"reg %d",r); print_one_regentry(rn,tab3->rt3_rules+r); } } dwarfutils-20200114/dwarfexample/getdebuglink.c000066400000000000000000000114761361531463500214400ustar00rootroot00000000000000/* David Anderson. 2019. This small program is hereby placed into the public domain to be copied or used by anyone for any purpose. See https://sourceware.org/gdb/onlinedocs/\ gdb/Separate-Debug-Files.html to calculate the crc of a file. */ #include "config.h" #include /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf.h" #include "libdwarf.h" char trueoutpath[2000]; static const char *dlname = ".gnu_debuglink"; static const char *buildidname = ".note.gnu.buildid"; static int doprintbuildid = 1; static int doprintdebuglink = 1; static void one_file_debuglink(char *path) { int res = 0; Dwarf_Debug dbg = 0; unsigned i = 0; char *debuglinkpath = 0; /* must be freed */ unsigned char *crc = 0; char *debuglinkfullpath = 0; unsigned debuglinkfullpath_strlen = 0; unsigned buildid_type = 0; char * buildidownername = 0; unsigned char *buildid = 0; unsigned buildid_length = 0; char ** paths = 0; /* must be freed */ unsigned paths_count = 0; Dwarf_Error error = 0; res = dwarf_init_path(path, trueoutpath, sizeof(trueoutpath), DW_DLC_READ, DW_GROUPNUMBER_ANY, 0,0, &dbg, 0,0,0,&error); if (res == DW_DLV_ERROR) { printf("Error from libdwarf opening \"%s\": %s\n", path, dwarf_errmsg(error)); return; } if (res == DW_DLV_NO_ENTRY) { printf("There is no such file as \"%s\"\n", path); return; } /* We could call dwarf_add_debuglink_global_path() for each additional global path beside the default. Instead of &paths,&paths_count, pass 0,0 and do the paths construction yourself. */ res = dwarf_gnu_debuglink(dbg, &debuglinkpath, &crc, &debuglinkfullpath, &debuglinkfullpath_strlen, &buildid_type, &buildidownername, &buildid, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { printf("Error from libdwarf accessing debuglink " "related sections in \"%s\": %s\n", path, dwarf_errmsg(error)); res = dwarf_finish(dbg,&error); return; } else if (res == DW_DLV_NO_ENTRY) { printf("There is no %s or %s section in \"%s\"\n", dlname,buildidname,path); res = dwarf_finish(dbg,&error); return; } if (doprintdebuglink && crc) { printf(" Section %s\n",dlname); printf(" Debuglink name : %s",debuglinkpath); { unsigned char *crcx = 0; unsigned char *end = 0; crcx = crc; end = crcx + 4; printf(" crc 0X: "); for (; crcx < end; crcx++) { printf("%02x ", *crcx); } } printf("\n"); if (debuglinkfullpath_strlen) { printf(" Debuglink target: %s\n",debuglinkfullpath); } } if (doprintbuildid && buildid) { printf(" Section %s\n",buildidname); printf(" Build-id type : %u\n", buildid_type); printf(" Build-id ownername: %s\n", buildidownername); printf(" Build-id length : %u\n",buildid_length); printf(" Build-id : "); { const unsigned char *cur = 0; const unsigned char *end = 0; cur = buildid; end = cur + buildid_length; for (; cur < end; cur++) { printf("%02x", (unsigned char)*cur); } } printf("\n"); } /* We could ignore the paths and paths_count from libdwarf and develop a list of possible paths ourselves. */ for (i =0; i < paths_count; ++i) { char *pa = paths[i]; printf("Path [%2u] %s\n",i,pa); /* First, op the file to determine if it exists. If not, loop again */ /* if crc is non-null calculate the crc of the opened file and compare the 4-byte values. If they match, this is the desired object file with debug information. Do a dwarf_init_path() initializing (for example) Dwarf_Debug dbg2; Else continue the loop. */ } free(paths); free(debuglinkfullpath); dwarf_finish(dbg,&error); return; } int main(int argc, char **argv) { int i = 1; char *filenamein = 0; for ( ; i < argc; ++i) { filenamein = argv[i]; one_file_debuglink(filenamein); } } dwarfutils-20200114/dwarfexample/runtests.sh000077500000000000000000000031711361531463500210470ustar00rootroot00000000000000#!/bin/sh # # Intended to be run only on local machine. # Run in the dwarfdump directory # Run only after config.h created in a configure # in the source directory # Assumes env vars DWTOPSRCDIR set to the path to source. # Assumes CFLAGS warning stuff set in env var DWCOMPILERFLAGS # Assumes we run the script in the dwarfdump directory. blddir=`pwd` top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/dwarfexample if [ x"$DWCOMPILERFLAGS" = 'x' ] then CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf -Wall -Wextra" echo "CFLAGS basic default default $CFLAGS" else CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf $DWCOMPILERFLAGS" echo "CFLAGS via configure $CFLAGS" fi goodcount=0 failcount=0 echo "TOP topsrc $top_srcdir topbld $top_blddir localsrc $srcdir" chkres() { r=$1 m=$2 if [ $r -ne 0 ] then echo "FAIL $m. Exit status for the test $r" failcount=`expr $failcount + 1` else goodcount=`expr $goodcount + 1` fi } which cc if [ $? -eq 0 ] then CC=cc else which gcc if [ $? -eq 0 ] then CC=gcc else # we will fail CC=cc fi fi echo "getdebuglink test" o=junk.debuglink $blddir/getdebuglink a b $srcdir/dummyexecutable > $blddir/$o chkres $? "running getdebuglink" diff $srcdir/debuglink.base $blddir/$o r=$? if [ $r -ne 0 ] then echo "To update getdebuglink baseline: mv $blddir/$o $srcdir/debuglink.base" fi chkres $r "running getdebuglink diff against baseline" if [ $failcount -gt 0 ] then echo "FAIL $failcount dwarfexample/runtests.sh" exit 1 fi exit 0 dwarfutils-20200114/dwarfexample/simplereader.c000066400000000000000000001046631361531463500214510ustar00rootroot00000000000000/* Copyright (c) 2009-2019 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* simplereader.c This is an example of code reading dwarf .debug_info. It is kept simple to expose essential features. Though it now has a bunch of special options to enable testing of specific libdwarf features so it's no longer all that simple... It does not do all possible error reporting or error handling. It does to a bit of error checking as a help in ensuring that some code works properly... for error checks. The --names option adds some extra printing. The --check option does some interface and error checking. Option new September 2016: --dumpallnames=filepath This causes all the strings from the .debug_info and .debug_types sections to be written to 'filepath'. Any previous contents of the file are wiped out. This could be handy if you want to use the set of strings to investigate ways to improve the density of strings in some way. Options new 03 May 2015: These options do something different. They use specific DWARF5 package file libdwarf operations as a way to ensure libdwarf works properly (these specials used by the libdwarf regresson test suite). Examples given assuming dwp object fissionb-ld-new.dwp from the regressiontests --tuhash=hashvalue example: --tuhash=b0dd19898e8aa823 It prints a DIE. --cuhash=hashvalue example: --cuhash=1e9983f631642b1a It prints a DIE. --cufissionhash=hashvalue example: --tufissionhash=1e9983f631642b1a It prints the fission data for this hash. --tufissionhash=hashvalue example: --tufissionhash=b0dd19898e8aa823 It prints the fission data for this hash. --fissionfordie=cunumber example: --fissionfordie=5 For CU number 5 (0 is the initial CU/TU) it accesses the CU/TU DIE and then uses that DIE to get the fission data. New January 2019: --use-init-fd Instead of using dwarf_init_path(), use dwarf_init_fd() to make particular tests of that interface. To use, try make ./simplereader simplereader */ #include "config.h" /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_SYS_TYPES_H #include /* For open() */ #endif /* HAVE_SYS_TYPES_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include /* For open() */ #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_UNISTD_H #include /* For close() */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf.h" #include "libdwarf.h" #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #else # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* O_BINARY */ struct srcfilesdata { char ** srcfiles; Dwarf_Signed srcfilescount; int srcfilesres; }; #define TRUE 1 #define FALSE 0 static void read_cu_list(Dwarf_Debug dbg); static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me, int level, struct srcfilesdata *sf); static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info, int in_level, struct srcfilesdata *sf); static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf); /* Use a generic call to open the file, due to issues with Windows */ static int namesoptionon = 0; static int checkoptionon = 0; static int dumpallnames = 0; FILE *dumpallnamesfile = 0; static const char * dumpallnamespath = 0; #if 0 DW_UT_compile 0x01 /* DWARF5 */ DW_UT_type 0x02 /* DWARF5 */ DW_UT_partial 0x03 /* DWARF5 */ #endif static int stdrun = TRUE; static int unittype = DW_UT_compile; static Dwarf_Bool g_is_info = TRUE; int cu_version_stamp = 0; int cu_offset_size = 0; /* dienumberr is used to count DIEs. The point is to match fissionfordie. */ static int dienumber = 0; static int fissionfordie = -1; static int passnullerror = 0; /* These hash representations have to be converted to Dwarf_Sig8 before use. */ static const char * cuhash = 0; static const char * tuhash = 0; static const char * cufissionhash = 0; static const char * tufissionhash = 0; /* So we get clean reports from valgrind and other tools we clean up strdup strings. With a primitive technique as we need nothing fancy. */ #define DUPSTRARRAYSIZE 100 static const char *dupstrarray[DUPSTRARRAYSIZE]; static unsigned dupstrused; static void cleanupstr(void) { unsigned i = 0; for (i = 0; i < dupstrused; ++i) { free((char *)dupstrarray[i]); dupstrarray[i] = 0; } dupstrused = 0; } static unsigned char_to_uns4bit(unsigned char c) { unsigned v; if( c >= '0' && c <= '9') { v = c - '0'; } else if( c >= 'a' && c <= 'f') { v = c - 'a' + 10; } else if( c >= 'A' && c <= 'F') { v = c - 'A' + 10; } else { printf("Garbage hex char in %c 0x%x\n",c,c); exit(1); } return v; } static void xfrm_to_sig8(const char *cuhash_in, Dwarf_Sig8 *hash_out) { char localhash[16]; unsigned hashin_len = strlen(cuhash_in); unsigned fixed_size = sizeof(localhash); unsigned init_byte = 0; unsigned i; memset(localhash,0,fixed_size); if (hashin_len > fixed_size) { printf("FAIL: argument hash too long, len %u val:\"%s\"\n",hashin_len, cuhash_in); exit(1); } if (hashin_len < fixed_size) { unsigned add_zeros = fixed_size - hashin_len; for ( ; add_zeros > 0; add_zeros--) { localhash[init_byte] = '0'; init_byte++; } } for (i = 0; i < hashin_len; ++i,++init_byte) { localhash[init_byte] = cuhash_in[i]; } /* So now local hash as a full 16 bytes of hex characters with any needed leading zeros. transform it to 8 byte hex signature */ for (i = 0; i < sizeof(Dwarf_Sig8) ; ++i) { unsigned char hichar = localhash[2*i]; unsigned char lochar = localhash[2*i+1]; hash_out->signature[i] = (char_to_uns4bit(hichar) << 4) | char_to_uns4bit(lochar); } printf("Hex key = 0x"); for (i = 0; i < sizeof(Dwarf_Sig8) ; ++i) { unsigned char c = hash_out->signature[i]; printf("%02x",c); } printf("\n"); } static int startswithextractnum(const char *arg,const char *lookfor, int *numout) { const char *s = 0; unsigned prefixlen = strlen(lookfor); int v = 0; if(strncmp(arg,lookfor,prefixlen)) { return FALSE; } s = arg+prefixlen; /* We are not making any attempt to deal with garbage. Pass in good data... */ v = atoi(s); *numout = v; return TRUE; } static int startswithextractstring(const char *arg,const char *lookfor, const char ** ptrout) { const char *s = 0; unsigned prefixlen = strlen(lookfor); if(strncmp(arg,lookfor,prefixlen)) { return FALSE; } s = arg+prefixlen; *ptrout = strdup(s); dupstrarray[dupstrused] = *ptrout; dupstrused++; if (dupstrused >= DUPSTRARRAYSIZE) { printf("FAIL: increase the value DUPSTRARRAYSIZE for test purposes\n"); exit(1); } return TRUE; } static void format_sig8_string(Dwarf_Sig8*data, char* str_buf,unsigned buf_size) { unsigned i = 0; char *cp = str_buf; if (buf_size < 19) { printf("FAIL: internal coding error in test.\n"); exit(1); } strcpy(cp,"0x"); cp += 2; buf_size -= 2; for (; i < sizeof(data->signature); ++i,cp+=2,buf_size--) { snprintf(cp, buf_size, "%02x", (unsigned char)(data->signature[i])); } return; } static void print_debug_fission_header(struct Dwarf_Debug_Fission_Per_CU_s *fsd) { const char * fissionsec = ".debug_cu_index"; unsigned i = 0; char str_buf[30]; if (!fsd || !fsd->pcu_type) { /* No fission data. */ return; } printf("\n"); if (!strcmp(fsd->pcu_type,"tu")) { fissionsec = ".debug_tu_index"; } printf(" %-19s = %s\n","Fission section",fissionsec); printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx "\n","Fission index ", fsd->pcu_index); format_sig8_string(&fsd->pcu_hash,str_buf,sizeof(str_buf)); printf(" %-19s = %s\n","Fission hash",str_buf); /* 0 is always unused. Skip it. */ printf(" %-19s = %s\n","Fission entries","offset size DW_SECTn"); for( i = 1; i < DW_FISSION_SECT_COUNT; ++i) { const char *nstring = 0; Dwarf_Unsigned off = 0; Dwarf_Unsigned size = fsd->pcu_size[i]; int res = 0; if (size == 0) { continue; } res = dwarf_get_SECT_name(i,&nstring); if (res != DW_DLV_OK) { nstring = "Unknown SECT"; } off = fsd->pcu_offset[i]; printf(" %-19s = 0x%" DW_PR_XZEROS DW_PR_DUx " 0x%" DW_PR_XZEROS DW_PR_DUx " %2u\n", nstring, off, size,i); } } /* If there is no 'error' passed into a dwarf function and there is an error, and an error-handler like this is passed. This example simply returns so we test how well that action works. */ static void simple_error_handler(Dwarf_Error error, Dwarf_Ptr errarg) { Dwarf_Unsigned unused = (Dwarf_Unsigned)(uintptr_t)errarg; printf("\nlibdwarf error detected: 0x%" DW_PR_DUx " %s\n", dwarf_errno(error),dwarf_errmsg(error)); printf("libdwarf errarg. Not really used here %" DW_PR_DUu "\n", unused); return; } int main(int argc, char **argv) { Dwarf_Debug dbg = 0; const char *filepath = 0; int use_init_fd = FALSE; int my_init_fd = 0; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; Dwarf_Sig8 hash8; Dwarf_Error *errp = 0; int simpleerrhand = 0; int i = 0; #define MACHO_PATH_LEN 2000 char macho_real_path[MACHO_PATH_LEN]; macho_real_path[0] = 0; for(i = 1; i < (argc-1) ; ++i) { if(strcmp(argv[i],"--names") == 0) { namesoptionon=1; } else if(startswithextractstring(argv[1],"--dumpallnames=", &dumpallnamespath)) { dumpallnames=1; } else if(strcmp(argv[i],"--check") == 0) { checkoptionon=1; } else if(startswithextractstring(argv[i],"--tuhash=",&tuhash)) { /* done */ } else if(startswithextractstring(argv[i],"--cuhash=",&cuhash)) { /* done */ } else if(startswithextractstring(argv[i],"--tufissionhash=", &tufissionhash)) { /* done */ } else if(startswithextractstring(argv[i],"--cufissionhash=", &cufissionhash)) { /* done */ } else if(strcmp(argv[i],"--passnullerror") == 0) { passnullerror=1; } else if(strcmp(argv[i],"--simpleerrhand") == 0) { simpleerrhand=1; } else if(startswithextractnum(argv[i],"--isinfo=",&g_is_info)) { /* done */ } else if(startswithextractnum(argv[i],"--type=",&unittype)) { /* done */ } else if(startswithextractnum(argv[i],"--fissionfordie=", &fissionfordie)) { /* done */ } else if(!strcmp(argv[i],"--use-init-fd")) { use_init_fd = TRUE; /* done */ } else { printf("Unknown argument \"%s\", give up \n",argv[i]); exit(1); } } filepath = argv[i]; if (dumpallnames) { if (!strcmp(dumpallnamespath,filepath)) { printf("Using --dumpallnames with the same path " "(%s) " "as the file to read is not allowed. giving up.\n", filepath); exit(1); } dumpallnamesfile = fopen(dumpallnamespath,"w"); if(!dumpallnamesfile) { printf("Cannot open %s. Giving up.\n", dumpallnamespath); exit(1); } } if(passnullerror) { errp = 0; } else { errp = &error; } if (simpleerrhand) { errhand = simple_error_handler; /* Not a very useful errarg... */ errarg = (Dwarf_Ptr)1; } if (use_init_fd) { /* For testing a libdwarf init function. We are not finding the true dSYM Macho-object here if that applies, so it's up to the user of simplereader to pass in the correct dSYM object in the dSYM case. dwarf_object_detector_path() could do the dSYM object finding, but to keep this simple we leave that to the reader. */ my_init_fd = open(filepath,O_RDONLY|O_BINARY); if (my_init_fd == -1) { printf("Giving up, cannot open %s\n",filepath); exit(1); } res = dwarf_init(my_init_fd,DW_DLC_READ, errhand,errarg,&dbg,errp); } else { res = dwarf_init_path(filepath, macho_real_path, MACHO_PATH_LEN, DW_DLC_READ, DW_GROUPNUMBER_ANY,errhand,errarg,&dbg, 0,0,0,errp); } if(res != DW_DLV_OK) { printf("Giving up, cannot do DWARF processing\n"); cleanupstr(); exit(1); } if(cuhash) { Dwarf_Die die; stdrun = FALSE; xfrm_to_sig8(cuhash,&hash8); printf("\n"); printf("Getting die for CU key %s\n",cuhash); res = dwarf_die_from_hash_signature(dbg, &hash8,"cu", &die,errp); if (res == DW_DLV_OK) { struct srcfilesdata sf; printf("Hash found.\n"); sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; print_die_data(dbg,die,0,&sf); dwarf_dealloc(dbg,die, DW_DLA_DIE); } else if (res == DW_DLV_NO_ENTRY) { printf("cuhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("cuhash DW_DLV_ERROR %s\n", errp? dwarf_errmsg(error):"an error"); } } if(tuhash) { Dwarf_Die die; stdrun = FALSE; xfrm_to_sig8(tuhash,&hash8); printf("\n"); printf("Getting die for TU key %s\n",tuhash); res = dwarf_die_from_hash_signature(dbg, &hash8,"tu", &die,errp); if (res == DW_DLV_OK) { struct srcfilesdata sf; printf("Hash found.\n"); sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; print_die_data(dbg,die,0,&sf); dwarf_dealloc(dbg,die, DW_DLA_DIE); } else if (res == DW_DLV_NO_ENTRY) { printf("tuhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("tuhash DW_DLV_ERROR %s\n", errp?dwarf_errmsg(error):"error!"); } } if(cufissionhash) { Dwarf_Debug_Fission_Per_CU fisdata; stdrun = FALSE; memset(&fisdata,0,sizeof(fisdata)); xfrm_to_sig8(cufissionhash,&hash8); printf("\n"); printf("Getting fission data for CU key %s\n",cufissionhash); res = dwarf_get_debugfission_for_key(dbg, &hash8,"cu", &fisdata,errp); if (res == DW_DLV_OK) { printf("Hash found.\n"); print_debug_fission_header(&fisdata); } else if (res == DW_DLV_NO_ENTRY) { printf("cufissionhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("cufissionhash DW_DLV_ERROR %s\n", errp?dwarf_errmsg(error):"error..."); } } if(tufissionhash) { Dwarf_Debug_Fission_Per_CU fisdata; stdrun = FALSE; memset(&fisdata,0,sizeof(fisdata)); xfrm_to_sig8(tufissionhash,&hash8); printf("\n"); printf("Getting fission data for TU key %s\n",tufissionhash); res = dwarf_get_debugfission_for_key(dbg, &hash8,"tu", &fisdata,errp); if (res == DW_DLV_OK) { printf("Hash found.\n"); print_debug_fission_header(&fisdata); } else if (res == DW_DLV_NO_ENTRY) { printf("tufissionhash DW_DLV_NO_ENTRY.\n"); } else { /* DW_DLV_ERROR */ printf("tufissionhash DW_DLV_ERROR %s\n", errp?dwarf_errmsg(error):" Some error"); } } if (stdrun) { read_cu_list(dbg); } res = dwarf_finish(dbg,errp); if(res != DW_DLV_OK) { printf("dwarf_finish failed!\n"); } if (use_init_fd) { close(my_init_fd); } if (dumpallnamesfile) { fclose(dumpallnamesfile); } cleanupstr(); return 0; } static void read_cu_list(Dwarf_Debug dbg) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Half version_stamp = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Sig8 signature; Dwarf_Unsigned typeoffset = 0; Dwarf_Unsigned next_cu_header = 0; Dwarf_Half header_cu_type = unittype; Dwarf_Bool is_info = g_is_info; Dwarf_Error error; int cu_number = 0; Dwarf_Error *errp = 0; for(;;++cu_number) { Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; struct srcfilesdata sf; sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; memset(&signature,0, sizeof(signature)); if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_next_cu_header_d(dbg,is_info,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &offset_size, &extension_size,&signature, &typeoffset, &next_cu_header, &header_cu_type,errp); if(res == DW_DLV_ERROR) { char *em = errp?dwarf_errmsg(error):"An error next cu her"; printf("Error in dwarf_next_cu_header: %s\n",em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ return; } cu_version_stamp = version_stamp; cu_offset_size = offset_size; /* The CU will have a single sibling, a cu_die. */ res = dwarf_siblingof_b(dbg,no_die,is_info, &cu_die,errp); if(res == DW_DLV_ERROR) { char *em = errp?dwarf_errmsg(error):"An error"; printf("Error in dwarf_siblingof_b on CU die: %s\n",em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ printf("no entry! in dwarf_siblingof on CU die \n"); exit(1); } get_die_and_siblings(dbg,cu_die,is_info,0,&sf); dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); resetsrcfiles(dbg,&sf); } } static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die, int is_info,int in_level, struct srcfilesdata *sf) { int res = DW_DLV_ERROR; Dwarf_Die cur_die=in_die; Dwarf_Die child = 0; Dwarf_Error error = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } print_die_data(dbg,in_die,in_level,sf); for(;;) { Dwarf_Die sib_die = 0; res = dwarf_child(cur_die,&child,errp); if(res == DW_DLV_ERROR) { printf("Error in dwarf_child , level %d \n",in_level); exit(1); } if(res == DW_DLV_OK) { get_die_and_siblings(dbg,child,is_info, in_level+1,sf); /* No longer need 'child' die. */ dwarf_dealloc(dbg,child,DW_DLA_DIE); child = 0; } /* res == DW_DLV_NO_ENTRY or DW_DLV_OK */ res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,errp); if(res == DW_DLV_ERROR) { char *em = errp?dwarf_errmsg(error):"Error siblingof_b"; printf("Error in dwarf_siblingof_b , level %d :%s \n", in_level,em); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if(cur_die != in_die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); cur_die = 0; } cur_die = sib_die; print_die_data(dbg,cur_die,in_level,sf); } return; } static void get_addr(Dwarf_Attribute attr,Dwarf_Addr *val) { Dwarf_Error error = 0; int res; Dwarf_Addr uval = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_formaddr(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } return; } static void get_number(Dwarf_Attribute attr,Dwarf_Unsigned *val) { Dwarf_Error error = 0; int res; Dwarf_Signed sval = 0; Dwarf_Unsigned uval = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_formudata(attr,&uval,errp); if(res == DW_DLV_OK) { *val = uval; return; } res = dwarf_formsdata(attr,&sval,errp); if(res == DW_DLV_OK) { *val = sval; return; } return; } static void print_subprog(Dwarf_Debug dbg,Dwarf_Die die, int level, struct srcfilesdata *sf, const char *name) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Signed attrcount = 0; Dwarf_Signed i; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned linenum = 0; char *filename = 0; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_attrlist(die,&attrbuf,&attrcount,errp); if(res != DW_DLV_OK) { return; } for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,errp); if(res == DW_DLV_OK) { if(aform == DW_AT_decl_file) { Dwarf_Signed filenum_s = 0; get_number(attrbuf[i],&filenum); filenum_s = filenum; /* Would be good to evaluate filenum_s sanity here, ensuring filenum_s-1 is sensible. */ if((filenum > 0) && (sf->srcfilescount > (filenum_s-1))) { filename = sf->srcfiles[filenum_s-1]; } } if(aform == DW_AT_decl_line) { get_number(attrbuf[i],&linenum); } if(aform == DW_AT_low_pc) { get_addr(attrbuf[i],&lowpc); } if(aform == DW_AT_high_pc) { /* This will FAIL with DWARF4 highpc form of 'class constant'. */ get_addr(attrbuf[i],&highpc); } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } /* Here let's test some alternative interfaces for high and low pc. We only do both dwarf_highpc and dwarf_highpcb_b as an error check. Do not do both yourself. */ if(checkoptionon){ int hres = 0; int hresb = 0; int lres = 0; Dwarf_Addr althipc = 0; Dwarf_Addr hipcoffset = 0; Dwarf_Addr althipcb = 0; Dwarf_Addr altlopc = 0; Dwarf_Half highform = 0; enum Dwarf_Form_Class highclass = 0; /* Reusing errp before checking for err here is bogus. FIXME. */ /* Should work for DWARF 2/3 DW_AT_high_pc, and all high_pc where the FORM is DW_FORM_addr Avoid using this interface as of 2013. */ hres = dwarf_highpc(die,&althipc,errp); /* Should work for all DWARF DW_AT_high_pc. */ hresb = dwarf_highpc_b(die,&althipcb,&highform,&highclass,errp); lres = dwarf_lowpc(die,&altlopc,errp); printf("high_pc checking %s ",name); if (hres == DW_DLV_OK) { /* present, FORM addr */ printf("highpc 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipc); } else if (hres == DW_DLV_ERROR) { printf("dwarf_highpc() error not class address "); } else { /* absent */ } if(hresb == DW_DLV_OK) { /* present, FORM addr or const. */ if(highform == DW_FORM_addr) { printf("highpcb 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipcb); } else { if(lres == DW_DLV_OK) { hipcoffset = althipcb; althipcb = altlopc + hipcoffset; printf("highpcb 0x%" DW_PR_XZEROS DW_PR_DUx " " "highoff 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipcb,hipcoffset); } else { printf("highoff 0x%" DW_PR_XZEROS DW_PR_DUx " ", althipcb); } } } else if (hresb == DW_DLV_ERROR) { printf("dwarf_highpc_b() error!"); } else { /* absent */ } /* Should work for all DWARF DW_AT_low_pc */ if (lres == DW_DLV_OK) { /* present, FORM addr. */ printf("lowpc 0x%" DW_PR_XZEROS DW_PR_DUx " ", altlopc); } else if (lres == DW_DLV_ERROR) { printf("dwarf_lowpc() error!"); } else { /* absent. */ } printf("\n"); } if(namesoptionon && (filenum || linenum)) { printf("<%3d> file: %" DW_PR_DUu " %s line %" DW_PR_DUu "\n",level,filenum,filename?filename:"",linenum); } if(namesoptionon && lowpc) { printf("<%3d> low_pc : 0x%" DW_PR_DUx "\n", level, (Dwarf_Unsigned)lowpc); } if(namesoptionon && highpc) { printf("<%3d> high_pc: 0x%" DW_PR_DUx "\n", level, (Dwarf_Unsigned)highpc); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); } static void print_comp_dir(Dwarf_Debug dbg,Dwarf_Die die, int level, struct srcfilesdata *sf) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Signed attrcount = 0; Dwarf_Signed i; Dwarf_Error *errp = 0; if(passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_attrlist(die,&attrbuf,&attrcount,errp); if(res != DW_DLV_OK) { return; } sf->srcfilesres = dwarf_srcfiles(die,&sf->srcfiles,&sf->srcfilescount, &error); for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,errp); if(res == DW_DLV_OK) { if(aform == DW_AT_comp_dir) { char *name = 0; res = dwarf_formstring(attrbuf[i],&name,errp); if(res == DW_DLV_OK) { printf( "<%3d> compilation directory : \"%s\"\n", level,name); } } if(aform == DW_AT_stmt_list) { /* Offset of stmt list for this CU in .debug_line */ } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); } static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf) { Dwarf_Signed sri = 0; for (sri = 0; sri < sf->srcfilescount; ++sri) { dwarf_dealloc(dbg, sf->srcfiles[sri], DW_DLA_STRING); } dwarf_dealloc(dbg, sf->srcfiles, DW_DLA_LIST); sf->srcfilesres = DW_DLV_ERROR; sf->srcfiles = 0; sf->srcfilescount = 0; } static void print_single_string(Dwarf_Debug dbg, Dwarf_Die die,Dwarf_Half attrnum) { int res = 0; Dwarf_Error error = 0; char * stringval = 0; res = dwarf_die_text(die,attrnum, &stringval,&error); if (res == DW_DLV_OK) { fprintf(dumpallnamesfile,"%s\n",stringval); dwarf_dealloc(dbg,stringval, DW_DLA_STRING); } return; } static void print_name_strings_attr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr) { int res = 0; Dwarf_Half attrnum = 0; Dwarf_Half finalform = 0; enum Dwarf_Form_Class cl = DW_FORM_CLASS_UNKNOWN; Dwarf_Error error = 0; res = dwarf_whatattr(attr,&attrnum,&error); if(res != DW_DLV_OK) { printf("Unable to get attr number"); exit(1); } res = dwarf_whatform(attr,&finalform,&error); if(res != DW_DLV_OK) { printf("Unable to get attr form"); exit(1); } cl = dwarf_get_form_class(cu_version_stamp, attrnum,cu_offset_size,finalform); if (cl != DW_FORM_CLASS_STRING) { return; } print_single_string(dbg,die,attrnum); } static void printnamestrings(Dwarf_Debug dbg, Dwarf_Die die) { Dwarf_Error error =0; Dwarf_Attribute *atlist = 0; Dwarf_Signed atcount = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_attrlist(die,&atlist, &atcount,&error); if (res != DW_DLV_OK) { return; } for (i = 0; i < atcount; ++i) { Dwarf_Attribute attr = atlist[i]; /* Use an empty attr to get a placeholder on the attr list for this IRDie. */ print_name_strings_attr(dbg,die,attr); } dwarf_dealloc(dbg,atlist, DW_DLA_LIST); } static void print_die_data_i(Dwarf_Debug dbg, Dwarf_Die print_me, int level, struct srcfilesdata *sf) { char *name = 0; Dwarf_Error error = 0; Dwarf_Half tag = 0; const char *tagname = 0; int localname = 0; int res = 0; Dwarf_Error *errp = 0; Dwarf_Attribute attr = 0; Dwarf_Half formnum = 0; const char *formname = 0; if (passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_diename(print_me,&name,errp); if(res == DW_DLV_ERROR) { printf("Error in dwarf_diename , level %d \n",level); exit(1); } if(res == DW_DLV_NO_ENTRY) { name = ""; localname = 1; } res = dwarf_tag(print_me,&tag,errp); if(res != DW_DLV_OK) { printf("Error in dwarf_tag , level %d \n",level); exit(1); } res = dwarf_get_TAG_name(tag,&tagname); if(res != DW_DLV_OK) { printf("Error in dwarf_get_TAG_name , level %d \n",level); exit(1); } if (dumpallnames) { printnamestrings(dbg,print_me); } res = dwarf_attr(print_me,DW_AT_name,&attr, errp); if (res != DW_DLV_OK) { /* do nothing */ } else { res = dwarf_whatform(attr,&formnum,errp); if (res != DW_DLV_OK) { printf("Error in dwarf_whatform , level %d \n",level); exit(1); } formname = "form-name-unavailable"; res = dwarf_get_FORM_name(formnum,&formname); if (res != DW_DLV_OK) { formname = "UNKNoWn FORM!"; } dwarf_dealloc(dbg,attr,DW_DLA_ATTR); } if(namesoptionon ||checkoptionon) { if( tag == DW_TAG_subprogram) { if(namesoptionon) { printf( "<%3d> subprogram : \"%s\"\n",level,name); } print_subprog(dbg,print_me,level,sf,name); } if( (namesoptionon) && (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit || tag == DW_TAG_type_unit)) { resetsrcfiles(dbg,sf); printf( "<%3d> source file : \"%s\"\n",level,name); print_comp_dir(dbg,print_me,level,sf); } } else { printf("<%d> tag: %d %s name: \"%s\"",level,tag,tagname,name); if (formname) { printf(" FORM 0x%x \"%s\"",formnum, formname); } printf("\n"); } if(!localname) { dwarf_dealloc(dbg,name,DW_DLA_STRING); } } static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me, int level, struct srcfilesdata *sf) { if (fissionfordie != -1) { Dwarf_Debug_Fission_Per_CU percu; memset(&percu,0,sizeof(percu)); if (fissionfordie == dienumber) { int res = 0; Dwarf_Error error = 0; Dwarf_Error *errp = 0; if (passnullerror) { errp = 0; } else { errp = &error; } res = dwarf_get_debugfission_for_die(print_me, &percu,errp); if(res == DW_DLV_ERROR) { printf("FAIL: Error in dwarf_diename on fissionfordie %d\n", fissionfordie); exit(1); } if(res == DW_DLV_NO_ENTRY) { printf("FAIL: no-entry in dwarf_diename on fissionfordie %d\n", fissionfordie); exit(1); } print_die_data_i(dbg,print_me,level,sf); print_debug_fission_header(&percu); exit(0); } dienumber++; return; } print_die_data_i(dbg,print_me,level,sf); dienumber++; } dwarfutils-20200114/dwarfgen/000077500000000000000000000000001361531463500157355ustar00rootroot00000000000000dwarfutils-20200114/dwarfgen/CMakeLists.txt000066400000000000000000000021541361531463500204770ustar00rootroot00000000000000set_source_group(SOURCES "Source Files" createirepformfrombinary.cc createirepfrombinary.cc dwarfgen.cc irepattrtodbg.cc ireptodbg.cc ../libdwarf/dwgetopt.c) set_source_group(HEADERS "Header Files" createirepfrombinary.h general.h irepattrtodbg.h irepdie.h irepform.h irepframe.h irepline.h irepmacro.h ireppubnames.h irepresentation.h ireptodbg.h strtabdata.h ../libdwarf/dwgetopt.h) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) add_executable(dwarfgen ${SOURCES} ${HEADERS} ${CONFIGURATION_FILES}) set_folder(dwarfgen dwarfgen) target_compile_options(dwarfgen PRIVATE ${DW_FWALLXX}) target_link_libraries(dwarfgen PRIVATE ${dwarf-target} ${DW_FZLIB}) set(SUFFIX $<$:64>) set(LIBDIR lib${SUFFIX}) set(BINDIR bin${SUFFIX}) install(TARGETS dwarfgen DESTINATION RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR} ARCHIVE DESTINATION ${LIBDIR}) #install(FILES dwarfgen.conf DESTINATION lib) install(FILES dwarfgen.1 DESTINATION share/man/man1) dwarfutils-20200114/dwarfgen/COPYING000066400000000000000000000034151361531463500167730ustar00rootroot00000000000000Files here are copyrighted by David Anderson (and possibly others, see the copyright notices in individual files) by the BSD3 copyright (BSD3 is what it is normally called). A typical notice is: Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. David Anderson is at libdwarf-list -at- earthlink =dot= net 280 Bella Vista Drive Hillsborough, California 94010 USA. dwarfutils-20200114/dwarfgen/ChangeLog000066400000000000000000000000271361531463500175060ustar00rootroot000000000000002020-01-05 placeholder dwarfutils-20200114/dwarfgen/ChangeLog2011000066400000000000000000000017101361531463500200120ustar00rootroot00000000000000 2011-11-17 DavidAnderson * createirepformfrombinary.cc,createirepfrombinary.cc, irepattrtodbg.cc: Update copyright year. 2011-12-14 DavidAnderson * createirepfrombinary.cc, dwarfgen.cc, general.h, irepattrtodbg.cc, irepdie.h, irepline.h, irepresentation.h, ireptodbg.cc: Now reads in line table and creates line table output (still just DWARF2 though). 2011-06-12 DavidAnderson * dwarfgen.cc: Use dwarf_producer_init_c(), the newest interface to the producer. 2011-04-23 DavidAnderson * createirepformfrombinary.cc, createirepfrombinary.cc, dwarfgen.cc,general.h,irepattrtodbg.cc, irepattrtodbg.h,irepdie.h, irepform.h,irepframe.h,irepmacro.h,irepresentation.h,ireptodbg.cc, reptodbg.h,strtabdata.h: All the indentation is a multiple of 4 now. All the copyrights are updated. dwarfutils-20200114/dwarfgen/ChangeLog2012000066400000000000000000000000541361531463500200130ustar00rootroot00000000000000ChangeLog2012 is empty, no changes in 2012. dwarfutils-20200114/dwarfgen/ChangeLog2013000066400000000000000000000062111361531463500200150ustar00rootroot000000000000002013-10-31 David Anderson * createirepformfrombinary.cc: Adding support for some CLASS REFERENCE forms. * createirepformfrombinary.cc, creatirepfrombinary.cc: Adding support for some CLASS REFERENCE forms. Fixed dealloc for dwarf_get_pubtypes to avoid duplicate free. * dwarfgen.cc: Added #include so it compiles. * irepattrtodbg.cc,irepattrtodbg.h: Added support for some CLASS REFERENCE forms. * irepdie.h,irepform.h: Added support for some CLASS REFERENCE forms. * irepframe.h: Added 3 comment lines about fde_instrs_ * ireptodbg.cc: Added support for some CLASS REFERENCE forms. 2013-10-17 David Anderson 2013-10-17 David Anderson * ireppubnames.h: deals with debug_pubnames and debug_pubtypes data. * irepdie.h: Remember the producer DIE offset so we can access it for pubnames/pubtypes. * createirepfrombinary.cc: Read in pubnames and pubtypes data. * irepresentation.h: Add in pubnames and pubtypes data. * ireptodbg.cc: Write out applicable pubnames/pubtype data. 2013-10-14 David Anderson * dwarfgen.cc: The declaration of CallbackFunc() now has const char *name to match the corrected declaration in libdwarf.h 2013-08-13 David Anderson * createirepformfrombinary.cc: IRFormReference now allows DW_FORM_data4/8 as reference forms (applies to DWARF2). Made two error outputs look just enough different to tell which test cause the error string. * dwarfgen.cc: Added the -h option to specify transformation of DW_AT_high_pc from form address to form const to create a specific regression test case . * general.h: Added the -h global flag variable transformHighpcToConst as an extern. * irepattrtodbg.cc: Now emits class constant attributes and values. * irepform.h: Now has a new IRFormConstant constructor so we can easily create an attribute on-the-fly internally. Added accessor functions for IRFormConstant values. * ireptodbg.cc: specialAttrTransformations() does the transformation that -h requests: making DW_AT_high_pc be of form constant instead of form address. 2013-02-01 David Anderson * createirepfrombinary.cc,createirepfrombinary.h,dwarfgen.cc, general.h,irepattrtodbg.cc,irepattrtodbg.h,irepdie.h, irepform.h,irepframe.h,irepline.h,irepmacro.h,irepresentation.h, ireptodbg.cc,strtabdata.h: updated copyright year to 2013. * createirepformfrombinary.cc: Added missing implemenation detals for all FORMs and FormFlag. * createirepfrombinary.cc: Rename some local variables for readability based on the realization that dwarf_whatform and dwarf_whatform_direct() are misnamed. * irepattrtodbg.cc: Fixed instances of << cerr when << endl was what was wanted. * ireptodbg.cc: Fixed cast from pointer to int as int is too small, causes build to error off. * irepdie.h,irepform.h: Rename form fields from indirectform_ directform_ to initialform_ and finalform_ based on the realization that dwarf_whatform and dwarf_whatform were misnamed. dwarfutils-20200114/dwarfgen/ChangeLog2014000066400000000000000000000031621361531463500200200ustar00rootroot000000000000002014-12-28 David Anderson * fakemalloc.c: Renamed to fakemalloc.in . 2014-12-28 David Anderson * fakemalloc.c,TESTmallocfail: This makes possible a simple test that we handle malloc failure as sensible as possible. The test requires hand modification of the dwarfgen Makefile. * createirepfrombinary.cc: Now prints the libdwarf error number for better error reporting when there is a libdwarf error (running out of malloc space, for example). 2014-12-09 David Anderson * dwarfgen.cc: Add try/catch for bad malloc and any other disasters.. Add dwarfgen in the string for all the errors leading to exit * dwarf_tsearchhash.c: Add check for NULL return in tsearch_inner() so we don't just core dump when malloc fails. 2014-05-08 David Anderson * dwarfgen.cc: Now uses the newest form of dwarf_producer_init(). The old forms no longer are supported. 2014-02-08 David Anderson * dwarfgen.cc: Added commentary about the callback function setting sect_name_index. 2014-01-29 David Anderson * createirepformfrombinary.cc,createirepfrombinary.cc,createirepfrombinary.h, dwarfgen.cc,general.h,irepattrtodbg.cc,irepattrtodbg.h,irepdie.h, irepform.h,irepframe.h,irepline.h,irepmacro.h,ireppubnames.h, irepresentation.h,ireptodbg.cc,ireptodbg.h,strtabdata.h: Remove trailing whitespace. 2014-01-10 David Anderson * createirepformfrombinary.cc,createirepfrombinary.cc,dwarfgen.cc, irepattrtodbg.cc,ireptodbg.cc: Removed include of elf.h as it is not needed given the include of gelf.h. dwarfutils-20200114/dwarfgen/ChangeLog2015000066400000000000000000000026221361531463500200210ustar00rootroot000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-11-26 David Anderson * config.h.in, configure.in, Makefile.in: Deals with zlib when present. * configure: Generated. 2015-09-15 Carlos Alberto Enciso * createirepformfrombinary.cc: include the 'stdafx.h' for Windows port. Minor typo in the filename description. * createirepfrombinary.cc: include the 'stdafx.h' for Windows port. Use the Dwarfdump generic open_a_file() and close_a_file() calls. * dwarfgen.cc: include the 'stdafx.h' for Windows port. Include the Dwarfdump generic open_a_file(), close_a_file() and create_a_file() calls. Remove the 'extern "C"' around 'dwgetopt.h'. * irepattrtodbg.cc: include the 'stdafx.h' for Windows port. * ireptodbg.cc: include the 'stdafx.h' for Windows port. 2015-07-12 David Anderson * Now uses dwoptarg, dwoptind, not optarg, optind. 2015-02-22 David Anderson * Now uses dwgetopt.h, .c from dwarfdump. * dwarfgen.cc: Now references dwgetopt.h and dwgetopt(). * Makefile.in: Reaches around to libdwarf for dwgetopt. * configure.in: Removed getopt.h check * configure: regenerated 2015-01-06 David Anderson * dwarfgen.cc: Fixed indents and removed trailing whitespace. 2015-01-01 David Anderson * A new year begins. dwarfutils-20200114/dwarfgen/ChangeLog2016000066400000000000000000000034251361531463500200240ustar00rootroot00000000000000David Anderson * Makefile.in: Clean *~ 2016-11-20 David Anderson * Makefile.in: Now we have proper setting of CC and CFLAGS, which was missing before. 2016-10-07 David Anderson * dwarfgen.cc:For the reporting of .debug_str stats (just 3 lines of it) there is now a fixed prefix "Debug_Str:" so it is easier to verify things do not go wrong over time by just comparing those few lines, which should match across and across OS and libelf versions. There will still be 32/64bit differences though as the notion of 'short' string is longer with a 64bit offset in an object.. (pointer size is not the issue). 2016-09-30 David Anderson * configure.in: Add additional -fsanitize tests to --enable-sanitize. * configure: Regenerated. 2016-09-21 David Anderson * Makefile.in: implement sanitize support. * configure.in: Add support for --enable-sanitize * configure: Regenerated. 2016-08-28 David Anderson * dwarfgen.cc: Now calls dwarf_pro_get_string_stats() and prints the string counts information. 2016-08-25 David Anderson * dwarfgen.cc: Clarified and expanded the debug output of dwarfgen about relocations (and added the -r option to expand the output further). * irepresentation.h: Added comments explaining the intent of two small classes. 2016-08-23 David Anderson * dwarfgen.cc: Added the -s option which has .debug_info strings generated into .debug_str. 2016-06-01 David Anderson * Makefile.in: Tweaked for debian build compatibility 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-01-14 David Anderson * irepform.h: Missing return *this from several functions. Fixed. dwarfutils-20200114/dwarfgen/ChangeLog2017000066400000000000000000000020671361531463500200260ustar00rootroot000000000000002017-12-17 David Anderson * dwarfgen.1: The options to dwarfgen are now documented. 2017-10-20 David Anderson * createirepformfrombinary.cc,irepattrtodbg.cc, irepform.h, ireptodbg.cc: Added support for DW_FORM_data16. 2017-10-15 David Anderson * dwarfgen.cc,general.h,ireptodbg.cc: Moved global command-line options into a single global struct to clarify their use for a reader of the code. See 'cmdoptions'. 2017-08-21 David Anderson * config.h.in: Adding HAVE_LIBELF_LIBELF for consistency. * createirepformfrombinary.cc,createirepfrombinary.cc, irepattrtodbg.cc,ireptodbg.cc: Add ifdef HAVE_UNISTD_H. * dwarfgen.cc: Add ifdef HAVE_UNISTD_H, HAVE_LIBELF_LIBELF_H. Improve #ifdefs for Windows builds. 2017-04-21 David Anderson * dwarfgen.cc: Now supports -v with 2,3,4, or 5. 2017-04-20 David Anderson * dwarfgen.cc: Use dwoptarg. Not optarg. oops. 2017-04-20 David Anderson * dwarfgen.cc: Added new options allowing specification of the desired dwarf version. dwarfutils-20200114/dwarfgen/ChangeLog2018000066400000000000000000000134001361531463500200200ustar00rootroot000000000000002018-11-29 David Anderson * createirepfrombinary.cc: Removed trailing whitespace. * dwarfgen.cc: Added option --add-implicit-const to create an object with DW_FORM_implicit_const. * general.h: Added bool addimplicitconst flag for the new option. * irepattrtodbg.cc: For DW_FORM_implicit_const add a call to new libdwarf function dwarf_add_AT_implicit_const(). * ireptodbg.cc: New static function addImplicitConstItem() deals with replacing parts of existing variables with DW_FORM_implicit_const when the new option used. 2018-10-03 David Anderson * dwarfgen.cc: Now uses dwarf_init_b() instead of the original dwarf_init(). 2018-09-21 David Anderson * dwarfgen.cc: S_IRUSR was defined incorrectly (when not provided by system headers). Fixed. * CMakeLists.txt: Updated headers list to include all the local headers. * Makefile.am: Ensured config.h.in.cmake and dwarfgen.1 get into releases. 2018-09-11 David Anderson * ireptodbg.cc: Removed pointless comment. 2018-08-02 David Anderson * irepattrtodbg.cc: Fixed a typo and removed/#if 0 some debugging code * Makefile.am: Removed unused variables and references to them. 2018-07-31 David Anderson * Makefile.am: Moved ChangeLog etc out of /usr/share but have them in the distribution. Now make install puts nothing of dwarfgen in /usr/local/share. 2018-07-31 David Anderson * createirepfrombinary.cc: Delete blank line. * dwarfgen.cc: Adding new option --force-empty-dnames to force out .debug_names section (even if empty). Added dwarf_transform_to_disk_form_a() which does the same as dwarf_transform_to_disk_form() but has a status as the return value and returns its value via a pointer arg. * irepattrtodbg.cc: Removing some useless whitespace. 2018-07-24 David Anderson * dwarfgen.cc: CallbackFunc() was awkwardly declared (now more sensibly declared as static function, still extern "C" as it is called from C (libdwarf)) ErrorHandler() was unused (now deleted). 2018-07-23 David Anderson * createirepformfrombinary.cc: Removed unused local variable. #define UNUSEDARG appropriately * createirepfrombinary.cc: Removed extra ';'. #define UNUSEDARG appropriately mark static functions as such to avoid warnings. Mark arguments UNUSEDARG where appropriate. Test the correct libdwarf return value. Delete unused local variables. * dwarfgen.cc: Declared functions for C callbacks as extern C. #define UNUSEDARG appropriately * general.h: Reformat the header comments to avoid too-long lines. Delete duplicative comments. * irepattrtodbg.cc: Fixed reinterpret casts to be the correct type which made the typedef myintptrt unused (and now deleted). #define UNUSEDARG appropriately Mark arguments UNUSEDARG where appropriate. * irepdie.h, irepform.h: Mark arguments UNUSEDARG where appropriate. * ireptodbg.cc:Fixed reinterpret casts to be the correct type, fixing signed/unsigned comparison warnings. Removed some unused local variables. Fixed a couple declarations to avoid signed/unsigned comparison warnings. #define UNUSEDARG appropriately Mark arguments UNUSEDARG where appropriate. 2018-07-22 David Anderson * dwarfgen.cc: The relocations processing was assuming alignment of 32bit and 64bit values. Now no longer makes that incorrect assumption. 2018-07-16 David Anderson * createirepformfrombinary.cc: Refines ifdef of HAVE_STDAFX_H * createirepfrombinary.cc: Refines ifdef of HAVE_STDAFX_H Delete unused local variable. * dwarfgen.cc: Refines ifdef of HAVE_STDAFX_H. Changes certain function_argument names to avoid shadowing a global. For example, elf -> elf_w * general.h: Remove pointless trailing ; ending IToHex() * irepattrtodbg.cc: Refines ifdef of HAVE_STDAFX_H. Rename local vars to avoid shadowing. Example: form -> form_a * ireptodbg.cc: Refines ifdef of HAVE_STDAFX_H. Rename local vars to avoid shadowing. Example: error -> lerror 2018-07-16 David Anderson * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-06-19 David Anderson * dwarfgen.cc: Now it's intended to build for Linux or Windows and get usable file open modes automatically. 2018-06-14 David Anderson * Makefile.in * config.h.in,configure.ac Removed unnecessary defines and checks. * configure: Regenerated * createirepformfrombinary.cc,createirepfrombinary.cc, irepattrtodbg.cc,ireptodbg.cc: Removed unnecessary #includes * dwarfgen.cc: Removed unnecessary #includes. Switch from gelf.h (GNU only) to libelf.h. 2018-06-14 David Anderson * Added #ifdef for Windows environment builds. _O_WRONLY etc for creating a file. 2018-06-13 David Anderson * configure.ac: New option --enable-elf-open setting HAVE_ELF_OPEN * config.h.in: HAVE_ELF_OPEN * configure.ac: Regenerated. * dwarfgen.cc.c: Now uses open() unless HAVE_ELF_OPEN is explicitly set. 2018-06-05 David Anderson * dwarfdump.c: Change WIN32 to _WIN32. 2018-06-05 David Anderson * configure.ac: Now configure.in gone, using configure.ac. * configure: regenerated. * config.h.in: Regenerated, HAVE_LIBELF_LIBELF gone. 2018-06-05 David Anderson * dwarfgen.cc: Remove erroneous _MSC_VER per Carlos Alberto Enciso. 2018-05-28 David Anderson * createirepformfrombinary.cc,createirepfrombinary.cc, general.h,irepattrtodbg.cc,irepdie.h, irepform.h,ireppubnames.h: Removed trailing blank lines and updated copyright year. dwarfutils-20200114/dwarfgen/Makefile.am000066400000000000000000000021551361531463500177740ustar00rootroot00000000000000###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = dwarfgen$(EXEEXT) subdir = dwarfgen ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_dwarfgen_OBJECTS = dwarfgen-createirepformfrombinary.$(OBJEXT) \ dwarfgen-createirepfrombinary.$(OBJEXT) \ dwarfgen-dwarfgen.$(OBJEXT) dwarfgen-irepattrtodbg.$(OBJEXT) \ dwarfgen-ireptodbg.$(OBJEXT) dwarfgen_OBJECTS = $(am_dwarfgen_OBJECTS) dwarfgen_DEPENDENCIES = \ $(top_builddir)/dwarfdump/dwarfdump-dwgetopt.o \ $(top_builddir)/libdwarf/libdwarf.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = dwarfgen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(dwarfgen_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(dwarfgen_SOURCES) DIST_SOURCES = $(dwarfgen_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp COPYING \ ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in AUTOMAKE_OPTIONS = subdir-objects dwarfgen_SOURCES = \ createirepformfrombinary.cc \ createirepfrombinary.h \ createirepfrombinary.cc \ dwarfgen.cc \ general.h \ irepattrtodbg.cc \ irepattrtodbg.h \ irepdie.h \ irepform.h \ irepframe.h \ irepline.h \ irepmacro.h \ ireppubnames.h \ irepresentation.h \ ireptodbg.cc \ ireptodbg.h \ strtabdata.h # dwarfdump here is so we find dwgetopt.h dwarfgen_CPPFLAGS = -I$(top_srcdir)/libdwarf -I$(top_srcdir)/dwarfdump -I$(top_builddir)/libdwarf dwarfgen_CXXFLAGS = $(DWARF_CXXFLAGS_WARN) dwarfgen_LDADD = \ $(top_builddir)/dwarfdump/dwarfdump-dwgetopt.o \ $(top_builddir)/libdwarf/libdwarf.la \ @DWARF_LIBS@ EXTRA_DIST = \ COPYING \ ChangeLog \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CMakeLists.txt \ NEWS \ README \ dwarfgen.1 \ TESTmallocfail \ $(dwarfgen_DATA) \ dwarf-generator.txt \ fakemalloc.in all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu dwarfgen/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu dwarfgen/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list dwarfgen$(EXEEXT): $(dwarfgen_OBJECTS) $(dwarfgen_DEPENDENCIES) $(EXTRA_dwarfgen_DEPENDENCIES) @rm -f dwarfgen$(EXEEXT) $(AM_V_CXXLD)$(dwarfgen_LINK) $(dwarfgen_OBJECTS) $(dwarfgen_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-createirepformfrombinary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-createirepfrombinary.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-dwarfgen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-irepattrtodbg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarfgen-ireptodbg.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< dwarfgen-createirepformfrombinary.o: createirepformfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepformfrombinary.o -MD -MP -MF $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo -c -o dwarfgen-createirepformfrombinary.o `test -f 'createirepformfrombinary.cc' || echo '$(srcdir)/'`createirepformfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepformfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepformfrombinary.cc' object='dwarfgen-createirepformfrombinary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepformfrombinary.o `test -f 'createirepformfrombinary.cc' || echo '$(srcdir)/'`createirepformfrombinary.cc dwarfgen-createirepformfrombinary.obj: createirepformfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepformfrombinary.obj -MD -MP -MF $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo -c -o dwarfgen-createirepformfrombinary.obj `if test -f 'createirepformfrombinary.cc'; then $(CYGPATH_W) 'createirepformfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepformfrombinary.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepformfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepformfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepformfrombinary.cc' object='dwarfgen-createirepformfrombinary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepformfrombinary.obj `if test -f 'createirepformfrombinary.cc'; then $(CYGPATH_W) 'createirepformfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepformfrombinary.cc'; fi` dwarfgen-createirepfrombinary.o: createirepfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepfrombinary.o -MD -MP -MF $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo -c -o dwarfgen-createirepfrombinary.o `test -f 'createirepfrombinary.cc' || echo '$(srcdir)/'`createirepfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepfrombinary.cc' object='dwarfgen-createirepfrombinary.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepfrombinary.o `test -f 'createirepfrombinary.cc' || echo '$(srcdir)/'`createirepfrombinary.cc dwarfgen-createirepfrombinary.obj: createirepfrombinary.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-createirepfrombinary.obj -MD -MP -MF $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo -c -o dwarfgen-createirepfrombinary.obj `if test -f 'createirepfrombinary.cc'; then $(CYGPATH_W) 'createirepfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepfrombinary.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-createirepfrombinary.Tpo $(DEPDIR)/dwarfgen-createirepfrombinary.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='createirepfrombinary.cc' object='dwarfgen-createirepfrombinary.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-createirepfrombinary.obj `if test -f 'createirepfrombinary.cc'; then $(CYGPATH_W) 'createirepfrombinary.cc'; else $(CYGPATH_W) '$(srcdir)/createirepfrombinary.cc'; fi` dwarfgen-dwarfgen.o: dwarfgen.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-dwarfgen.o -MD -MP -MF $(DEPDIR)/dwarfgen-dwarfgen.Tpo -c -o dwarfgen-dwarfgen.o `test -f 'dwarfgen.cc' || echo '$(srcdir)/'`dwarfgen.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-dwarfgen.Tpo $(DEPDIR)/dwarfgen-dwarfgen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dwarfgen.cc' object='dwarfgen-dwarfgen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-dwarfgen.o `test -f 'dwarfgen.cc' || echo '$(srcdir)/'`dwarfgen.cc dwarfgen-dwarfgen.obj: dwarfgen.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-dwarfgen.obj -MD -MP -MF $(DEPDIR)/dwarfgen-dwarfgen.Tpo -c -o dwarfgen-dwarfgen.obj `if test -f 'dwarfgen.cc'; then $(CYGPATH_W) 'dwarfgen.cc'; else $(CYGPATH_W) '$(srcdir)/dwarfgen.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-dwarfgen.Tpo $(DEPDIR)/dwarfgen-dwarfgen.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dwarfgen.cc' object='dwarfgen-dwarfgen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-dwarfgen.obj `if test -f 'dwarfgen.cc'; then $(CYGPATH_W) 'dwarfgen.cc'; else $(CYGPATH_W) '$(srcdir)/dwarfgen.cc'; fi` dwarfgen-irepattrtodbg.o: irepattrtodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-irepattrtodbg.o -MD -MP -MF $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo -c -o dwarfgen-irepattrtodbg.o `test -f 'irepattrtodbg.cc' || echo '$(srcdir)/'`irepattrtodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo $(DEPDIR)/dwarfgen-irepattrtodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='irepattrtodbg.cc' object='dwarfgen-irepattrtodbg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-irepattrtodbg.o `test -f 'irepattrtodbg.cc' || echo '$(srcdir)/'`irepattrtodbg.cc dwarfgen-irepattrtodbg.obj: irepattrtodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-irepattrtodbg.obj -MD -MP -MF $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo -c -o dwarfgen-irepattrtodbg.obj `if test -f 'irepattrtodbg.cc'; then $(CYGPATH_W) 'irepattrtodbg.cc'; else $(CYGPATH_W) '$(srcdir)/irepattrtodbg.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-irepattrtodbg.Tpo $(DEPDIR)/dwarfgen-irepattrtodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='irepattrtodbg.cc' object='dwarfgen-irepattrtodbg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-irepattrtodbg.obj `if test -f 'irepattrtodbg.cc'; then $(CYGPATH_W) 'irepattrtodbg.cc'; else $(CYGPATH_W) '$(srcdir)/irepattrtodbg.cc'; fi` dwarfgen-ireptodbg.o: ireptodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-ireptodbg.o -MD -MP -MF $(DEPDIR)/dwarfgen-ireptodbg.Tpo -c -o dwarfgen-ireptodbg.o `test -f 'ireptodbg.cc' || echo '$(srcdir)/'`ireptodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-ireptodbg.Tpo $(DEPDIR)/dwarfgen-ireptodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ireptodbg.cc' object='dwarfgen-ireptodbg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-ireptodbg.o `test -f 'ireptodbg.cc' || echo '$(srcdir)/'`ireptodbg.cc dwarfgen-ireptodbg.obj: ireptodbg.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -MT dwarfgen-ireptodbg.obj -MD -MP -MF $(DEPDIR)/dwarfgen-ireptodbg.Tpo -c -o dwarfgen-ireptodbg.obj `if test -f 'ireptodbg.cc'; then $(CYGPATH_W) 'ireptodbg.cc'; else $(CYGPATH_W) '$(srcdir)/ireptodbg.cc'; fi` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/dwarfgen-ireptodbg.Tpo $(DEPDIR)/dwarfgen-ireptodbg.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ireptodbg.cc' object='dwarfgen-ireptodbg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dwarfgen_CPPFLAGS) $(CPPFLAGS) $(dwarfgen_CXXFLAGS) $(CXXFLAGS) -c -o dwarfgen-ireptodbg.obj `if test -f 'ireptodbg.cc'; then $(CYGPATH_W) 'ireptodbg.cc'; else $(CYGPATH_W) '$(srcdir)/ireptodbg.cc'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dwarfutils-20200114/dwarfgen/NEWS000066400000000000000000000003661361531463500164410ustar00rootroot0000000000000026 February, 2015 Now uses dwgetopt() instead of getopt() so all environments have a getopt-like functionality. It reaches around to libdwarf for the source to dwgetopt, but it could equally well reach into dwarfdump for that source. dwarfutils-20200114/dwarfgen/README000066400000000000000000000027451361531463500166250ustar00rootroot00000000000000 David Anderson, September 20, 2010 Updated July 22, 2018 The dwarfgen application is intended as both a vehicle for testing dwarf-generation by libdwarf and as an example of how one uses libdwarf to generate DWARF. In addition, it should be useful as a test vehicle for evaluating future changes to the DWARF standard. It is necessary as a test-vehicle so that the libdwarf producer code can be updated to allow more recent features of DWARF to be supported while trying to guarantee current producer code users are correctly supported. By default dwarfgen produces a fake a.out. By that we mean that no relocation sections are written. Instead, relocations are processed directly by dwarfgen. Perhaps at some point a more a.out-like output will be optionally supported. In its 2018 form the code calling producer functions leaks memory as the return values usually need to be dealloc'd, but only after the code is generated. An example from -fsanitize= is Direct leak of 2688 byte(s) in 28 object(s) allocated from: #0 0x7f51fb2f9602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x5873d9 in _dwarf_p_get_alloc /home/davea/dwarf/regressiontests/../code/libdwarf/pro_alloc.c:76 #2 0x55cdaa in dwarf_add_AT_any_value_uleb /home/davea/dwarf/regressiontests/../code/libdwarf/pro_forms.c:1277 #3 0x495d4a in AddAttrToDie(Dwarf_P_Debug_s*, IRepresentation&, IRCUdata&, Dwarf_P_Die_s*, IRDie&, IRAttr&) /home/davea/dwarf/regressiontests/../code/dwarfgen/irepattrtodbg.cc:176 dwarfutils-20200114/dwarfgen/TESTmallocfail000066400000000000000000000012561361531463500204670ustar00rootroot00000000000000#!/bin/bash # # This runs dwarfgen/libdwarf with a malloc failure # at the $ct'th call to malloc. # To expose errors in malloc failure handling. # Probably any small C file compiled -c will do # to produce test.o For example just use a .o # generated by the build of dwarfgen subj=test.o ct=0 while [ $ct -lt 500 ] do echo '===== START TEST' rm -f core rm -f dwarfgen sed -e "s/FAILCOUNT/$ct/" fakemalloc.c echo TEST $ct grep if fakemalloc.c make ./dwarfgen -h -t obj -c 0 -o $subj ./dwarfgen >junk.x cat junk.x if [ -f core ] then echo "CORE FILE EXISTS, test" $ct fi rm -f core echo '===== END TEST' ct=`expr $ct + 1` done dwarfutils-20200114/dwarfgen/createirepformfrombinary.cc000066400000000000000000000373271361531463500233600ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // createirepformfrombinary.cc // Reads an object and inserts its dwarf data into // an object intended to hold all the dwarf data. #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef HAVE_UNITSTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include // For memset etc #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "createirepfrombinary.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::list; // THis should instantiated only locally, not with 'new'. // It should not be copied. class IRFormInterface { public: IRFormInterface(Dwarf_Debug dbg, Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr): dbg_(dbg),attr_(attr),cudata_(cudata),irattr_(irattr) {}; // Do not free anything we did not create here. ~IRFormInterface() {}; Dwarf_Debug dbg_; Dwarf_Attribute attr_; IRCUdata &cudata_; IRAttr &irattr_; private: // Do not instantiate. IRFormInterface(); IRFormInterface& operator= (const IRFormInterface &ir); }; IRForm *formFactory(Dwarf_Debug dbg, Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr) { IRFormInterface interface(dbg,attr,cudata,irattr); enum Dwarf_Form_Class cl = irattr.getFormClass(); switch(cl) { case DW_FORM_CLASS_UNKNOWN: break; case DW_FORM_CLASS_ADDRESS: { IRFormAddress *f = new IRFormAddress(&interface); // FIXME: do we need to do anything about symbol here? // Yes, if it has a relocation. return f; } break; case DW_FORM_CLASS_BLOCK: { IRFormBlock *f = new IRFormBlock(&interface); return f; } break; case DW_FORM_CLASS_CONSTANT: { IRFormConstant *f = new IRFormConstant(&interface); return f; } break; case DW_FORM_CLASS_EXPRLOC: { IRFormExprloc *f = new IRFormExprloc(&interface); return f; } break; case DW_FORM_CLASS_FLAG: { IRFormFlag *f = new IRFormFlag(&interface); return f; } break; case DW_FORM_CLASS_LINEPTR: { IRFormLinePtr *f = new IRFormLinePtr(&interface); return f; } break; case DW_FORM_CLASS_LOCLISTPTR: { IRFormLoclistPtr *f = new IRFormLoclistPtr(&interface); return f; } break; case DW_FORM_CLASS_MACPTR: { IRFormMacPtr *f = new IRFormMacPtr(&interface); return f; } break; case DW_FORM_CLASS_RANGELISTPTR: { IRFormRangelistPtr *f = new IRFormRangelistPtr(&interface); return f; } break; case DW_FORM_CLASS_REFERENCE: { IRFormReference *f = new IRFormReference(&interface); return f; } break; case DW_FORM_CLASS_STRING: { IRFormString *f = new IRFormString(&interface); return f; } break; case DW_FORM_CLASS_FRAMEPTR: /* SGI/IRIX extension. */ { IRFormFramePtr *f = new IRFormFramePtr(&interface); return f; } break; default: break; } return new IRFormUnknown(); } static void extractInterafaceForms(IRFormInterface *interface, Dwarf_Half *finalform, Dwarf_Half *initialform) { Dwarf_Error error = 0; int res = dwarf_whatform(interface->attr_,finalform,&error); if(res != DW_DLV_OK) { cerr << "Unable to get attr form " << endl; exit(1); } res = dwarf_whatform_direct(interface->attr_,initialform,&error); if(res != DW_DLV_OK) { cerr << "Unable to get attr direct form " << endl; exit(1); } } IRFormAddress::IRFormAddress(IRFormInterface * interface) { Dwarf_Addr val = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_ = DW_FORM_CLASS_ADDRESS; address_ = 0; int res = dwarf_formaddr(interface->attr_,&val, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << endl; exit(1); } // FIXME do we need to do anything about the symbol here? // It might have a relocation and we should determine that. address_ = val; } IRFormBlock::IRFormBlock(IRFormInterface * interface) { Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_BLOCK; fromloclist_= 0; sectionoffset_=0; Dwarf_Block *blockptr = 0; Dwarf_Error error = 0; int res = dwarf_formblock(interface->attr_,&blockptr, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << endl; exit(1); } insertBlock(blockptr); dwarf_dealloc(interface->dbg_,blockptr,DW_DLA_BLOCK); } IRFormConstant::IRFormConstant(IRFormInterface * interface) { Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_CONSTANT; signedness_=SIGN_NOT_SET; uval_=0; sval_=0; Dwarf_Error error = 0; if (finalform == DW_FORM_data16) { Dwarf_Form_Data16 data16; int rd16 = dwarf_formdata16(interface->attr_,&data16, &error); if (rd16 != DW_DLV_OK) { cerr << "Unable to read constant data16 value. " "Impossible error.\n" << endl; exit(1); } setValues16(&data16, SIGN_UNKNOWN); return; } enum Signedness oursign = SIGN_NOT_SET; Dwarf_Unsigned uval = 0; Dwarf_Signed sval = 0; int ress = dwarf_formsdata(interface->attr_, &sval,&error); int resu = dwarf_formudata(interface->attr_, &uval,&error); if(resu == DW_DLV_OK ) { if(ress == DW_DLV_OK) { oursign = SIGN_UNKNOWN; } else { oursign = UNSIGNED; sval = static_cast(uval); } } else { if(ress == DW_DLV_OK) { oursign = SIGNED; uval = static_cast(sval); } else { cerr << "Unable to read constant value. Impossible error.\n" << endl; exit(1); } } setValues(sval, uval, oursign); } IRFormExprloc::IRFormExprloc(IRFormInterface * interface) { Dwarf_Unsigned len = 0; Dwarf_Ptr data = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_EXPRLOC; int res = dwarf_formexprloc(interface->attr_,&len, &data, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << endl; exit(1); } // FIXME: Would be nice to expand to the expression details // instead of just a block of bytes. insertBlock(len,data); } IRFormFlag::IRFormFlag(IRFormInterface * interface) { Dwarf_Bool flagval = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_FLAG; flagval_=0; Dwarf_Error error = 0; int res = dwarf_formflag(interface->attr_,&flagval, &error); if(res != DW_DLV_OK) { cerr << "Unable to read flag value. Impossible error.\n" << endl; exit(1); } setFlagVal(flagval); setFinalForm(finalform); setInitialForm(initialform); } // We are simply assuming (here) that the value is a global offset // to some section or other. // Calling code ensures that is true. // static Dwarf_Unsigned get_section_offset(IRFormInterface * interface) { Dwarf_Unsigned uval = 0; Dwarf_Signed sval = 0; Dwarf_Error error = 0; Dwarf_Off sectionoffset = 0; int resu = 0; // The following allows more sorts of value than // we really want to allow here, but that is // harmless, we believe. int resgf = dwarf_global_formref(interface->attr_, §ionoffset, &error); if(resgf == DW_DLV_OK ) { return sectionoffset; } resu = dwarf_formudata(interface->attr_, &uval,&error); if(resu != DW_DLV_OK ) { int ress = dwarf_formsdata(interface->attr_, &sval,&error); if(ress == DW_DLV_OK) { uval = static_cast(sval); } else { cerr << "Unable to read constant offset value. Impossible error.\n" << endl; exit(1); } } return uval; } IRFormLoclistPtr::IRFormLoclistPtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_LOCLISTPTR; loclist_offset_=0; } // When emitting line data from the producer, this // attribute is automatically emitted by the transform_to_disk // function if there is line data in the generated CU, // not created by interpreting this input attribute. IRFormLinePtr::IRFormLinePtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); } IRFormMacPtr::IRFormMacPtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_MACPTR; macro_offset_=0; } IRFormRangelistPtr::IRFormRangelistPtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_RANGELISTPTR; rangelist_offset_=0; } IRFormFramePtr::IRFormFramePtr(IRFormInterface * interface) { Dwarf_Unsigned uval = get_section_offset(interface); setOffset(uval); Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_FRAMEPTR; frame_offset_=0; } // This is a .debug_info to .debug_info (or .debug_types to .debug_types) // reference. // Since local/global reference target values are not known // till the DIEs are actually emitted, // we eventually use libdwarf (dwarf_get_die_markers) to fix up // the new target value. Here we just record the input value. // IRFormReference::IRFormReference(IRFormInterface * interface) { Dwarf_Off val = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; formclass_ = DW_FORM_CLASS_REFERENCE; reftype_ = RT_NONE; globalOffset_ = 0; cuRelativeOffset_ = 0; targetInputDie_= 0; target_die_= 0; initSig8(); extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); IRCUdata &cudata = interface->cudata_; if(finalform == DW_FORM_ref_sig8) { Dwarf_Sig8 val8; int res = dwarf_formsig8(interface->attr_,&val8, &error); if(res != DW_DLV_OK) { cerr << "Unable to read sig8 reference. Impossible error.\n" << endl; exit(1); } setSignature(&val8); return; } if(finalform == DW_FORM_ref_addr || finalform == DW_FORM_data4 || finalform == DW_FORM_data8) { // FIXME there might be a relocation record. int res = dwarf_global_formref(interface->attr_,&val, &error); if(res != DW_DLV_OK) { cerr << "Unable to read reference. Impossible error.\n" << endl; exit(1); } setOffset(val); return; } // Otherwise it is (if a correct FORM for a .debug_info reference) // a local CU offset, and we record it as such.. int res = dwarf_formref(interface->attr_,&val, &error); if(res != DW_DLV_OK) { cerr << "Unable to read reference.. Impossible error. finalform " << finalform << endl; exit(1); } setCUOffset(val); cudata.insertLocalReferenceAttrTargetRef(val,this); IRDie *targdie = cudata.getLocalDie(val); if (targdie) { // Record local offset's IRDie when it is already known. setTargetInDie(targdie); } } // Global static data used to initialized a sig8 reliably. static Dwarf_Sig8 zero_sig8; // Initialization helper function. void IRFormReference::initSig8() { typeSig8_ = zero_sig8; } IRFormString::IRFormString(IRFormInterface * interface) { char *str = 0; Dwarf_Error error = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; extractInterafaceForms(interface,&finalform,&initialform); setFinalForm(finalform); setInitialForm(initialform); formclass_=DW_FORM_CLASS_STRING; strpoffset_=0; int res = dwarf_formstring(interface->attr_,&str, &error); if(res != DW_DLV_OK) { cerr << "Unable to read string. Impossible error.\n" << endl; exit(1); } setString(str); } dwarfutils-20200114/dwarfgen/createirepfrombinary.cc000066400000000000000000000614531361531463500224710ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // createirepfrombinary.cc // Reads an object and inserts its dwarf data into // an object intended to hold all the dwarf data. #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include // For memset etc #include //open #include //open #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "createirepfrombinary.h" #include "general.h" // For IToHex() using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::list; using std::map; static void readFrameDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep); static void readMacroDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep); static void readCUDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep); static void readGlobals(Dwarf_Debug dbg, IRepresentation & irep); /* Use a generic call to open the file, due to issues with Windows */ extern int open_a_file(const char * name); extern int create_a_file(const char * name); extern void close_a_file(int f); static void errprint(Dwarf_Error err) { cerr << "Error num: " << dwarf_errno(err) << " " << dwarf_errmsg(err) << endl; } class DbgInAutoCloser { public: DbgInAutoCloser(Dwarf_Debug dbg,int fd): dbg_(dbg),fd_(fd) {}; ~DbgInAutoCloser() { Dwarf_Error err = 0; dwarf_finish(dbg_,&err); close(fd_); }; private: Dwarf_Debug dbg_; int fd_; }; void createIrepFromBinary(const std::string &infile, IRepresentation & irep) { Dwarf_Debug dbg = 0; Dwarf_Error err; int fd = open_a_file(infile.c_str()); if(fd < 0 ) { cerr << "Unable to open " << infile << " for reading." << endl; exit(1); } // All reader error handling is via the err argument. int res = dwarf_init_b(fd, DW_GROUPNUMBER_ANY, DW_DLC_READ, 0, 0, &dbg, &err); if(res == DW_DLV_NO_ENTRY) { close_a_file(fd); cerr << "Error init-ing " << infile << " for reading. dwarf_init_b(). Not object file." << endl; exit(1); } else if(res == DW_DLV_ERROR) { close_a_file(fd); cerr << "Error init-ing " << infile << " for reading. dwarf_init_b() failed. " << dwarf_errmsg(err) << endl; exit(1); } DbgInAutoCloser closer(dbg,fd); readFrameDataFromBinary(dbg,irep); readCUDataFromBinary(dbg,irep); readMacroDataFromBinary(dbg,irep); readGlobals(dbg,irep); return; } static void readFrameDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep) { Dwarf_Error err = 0; Dwarf_Cie * cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde * fde_data = 0; Dwarf_Signed fde_count = 0; bool have_standard_frame = true; int res = dwarf_get_fde_list(dbg, &cie_data, &cie_count, &fde_data, &fde_count, &err); if(res == DW_DLV_NO_ENTRY) { // No frame data we are dealing with. #if 0 res = dwarf_get_fde_list_eh(dbg, &cie_data, &cie_count, &fde_data, &fde_count, &err); if(res == DW_DLV_NO_ENTRY) { // No frame data. return; } have_standard_frame = false; #endif /* 0 */ return; } if(res == DW_DLV_ERROR) { cerr << "Error reading frame data " << endl; exit(1); } for(Dwarf_Signed i =0; i < cie_count; ++i) { Dwarf_Unsigned bytes_in_cie = 0; Dwarf_Small version = 0; char * augmentation = 0; Dwarf_Unsigned code_alignment_factor = 0; Dwarf_Signed data_alignment_factor = 0; Dwarf_Half return_address_register_rule = 0; Dwarf_Ptr initial_instructions = 0; Dwarf_Unsigned initial_instructions_length = 0; res = dwarf_get_cie_info(cie_data[i], &bytes_in_cie, &version,&augmentation, &code_alignment_factor, &data_alignment_factor,&return_address_register_rule, &initial_instructions,&initial_instructions_length, &err); if(res != DW_DLV_OK) { errprint(err); cerr << "Error reading frame data cie index " << i << endl; exit(1); } // Index in cie_data must match index in ciedata_, here // correct by construction. IRCie cie(bytes_in_cie,version,augmentation, code_alignment_factor, data_alignment_factor,return_address_register_rule, initial_instructions,initial_instructions_length); if (have_standard_frame) { irep.framedata().insert_cie(cie); } else { irep.ehframedata().insert_cie(cie); } } for(Dwarf_Signed i =0; i < fde_count; ++i) { Dwarf_Addr low_pc = 0; Dwarf_Unsigned func_length = 0; Dwarf_Ptr fde_bytes = 0; Dwarf_Unsigned fde_byte_length = 0; Dwarf_Off cie_offset = 0; Dwarf_Signed cie_index = 0; Dwarf_Off fde_offset = 0; res = dwarf_get_fde_range(fde_data[i], &low_pc, &func_length,&fde_bytes, &fde_byte_length, &cie_offset,&cie_index, &fde_offset, &err); if(res != DW_DLV_OK) { cerr << "Error reading frame data fde index " << i << endl; exit(1); } IRFde fde(low_pc,func_length,fde_bytes,fde_byte_length, cie_offset, cie_index,fde_offset); Dwarf_Ptr instr_in = 0; Dwarf_Unsigned instr_len = 0; res = dwarf_get_fde_instr_bytes(fde_data[i], &instr_in, &instr_len, &err); if(res != DW_DLV_OK) { cerr << "Error reading frame data fde instructions " << i << endl; exit(1); } fde.get_fde_instrs_into_ir(instr_in,instr_len); if (have_standard_frame) { irep.framedata().insert_fde(fde); } else { irep.ehframedata().insert_fde(fde); } } dwarf_fde_cie_list_dealloc(dbg,cie_data,cie_count, fde_data,fde_count); } static void readCUMacroDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep, Dwarf_Unsigned macrodataoffset,IRCUdata &cu) { // Arbitrary, but way too high to be real! // Probably should be lower. Dwarf_Unsigned maxcount = 1000000000; Dwarf_Error error; Dwarf_Signed mcount=0; Dwarf_Macro_Details *md = 0; int res = dwarf_get_macro_details(dbg,macrodataoffset, maxcount, &mcount, &md, &error); if(res == DW_DLV_OK) { IRMacro ¯odata = irep.macrodata(); vector mvec = macrodata.getMacroVec(); mvec.reserve(mcount); Dwarf_Unsigned dieoffset = cu.baseDie().getGlobalOffset(); Dwarf_Macro_Details *mdp = md; for(int i = 0; i < mcount; ++i, mdp++ ) { IRMacroRecord ir(dieoffset,mdp->dmd_offset, mdp->dmd_type, mdp->dmd_lineno, mdp->dmd_fileindex, mdp->dmd_macro?mdp->dmd_macro:""); mvec.push_back(ir); } } dwarf_dealloc(dbg, md, DW_DLA_STRING); } static void get_basic_attr_data_one_attr(Dwarf_Debug dbg, Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr) { Dwarf_Error error; Dwarf_Half attrnum = 0; Dwarf_Half finalform = 0; Dwarf_Half initialform = 0; int res = dwarf_whatattr(attr,&attrnum,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get attr number " << endl; exit(1); } res = dwarf_whatform(attr,&finalform,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get attr form " << endl; exit(1); } res = dwarf_whatform_direct(attr,&initialform,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get attr direct form " << endl; exit(1); } irattr.setBaseData(attrnum,finalform,initialform); enum Dwarf_Form_Class cl = dwarf_get_form_class( cudata.getVersionStamp(), attrnum, cudata.getOffsetSize(), finalform); irattr.setFormClass(cl); if (cl == DW_FORM_CLASS_UNKNOWN) { cerr << "Unable to figure out form class. ver " << cudata.getVersionStamp() << " attrnum " << attrnum << " offsetsize " << cudata.getOffsetSize() << " formnum " << finalform << endl; return; } irattr.setFormData(formFactory(dbg,attr,cudata,irattr)); } static void get_basic_die_data(Dwarf_Debug dbg UNUSEDARG, Dwarf_Die indie,IRDie &irdie) { Dwarf_Half tagval = 0; Dwarf_Error error = 0; int res = dwarf_tag(indie,&tagval,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get die tag "<< endl; exit(1); } Dwarf_Off goff = 0; res = dwarf_dieoffset(indie,&goff,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get die offset "<< endl; exit(1); } Dwarf_Off localoff = 0; res = dwarf_die_CU_offset(indie,&localoff,&error); if(res != DW_DLV_OK) { errprint(error); cerr << "Unable to get cu die offset "<< endl; exit(1); } irdie.setBaseData(tagval,goff,localoff); } static void get_attrs_of_die(Dwarf_Die in_die,IRDie &irdie, IRCUdata &cudata, IRepresentation &irep UNUSEDARG, Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Attribute *atlist = 0; Dwarf_Signed atcnt = 0; std::list &attrlist = irdie.getAttributes(); int res = dwarf_attrlist(in_die, &atlist,&atcnt,&error); std::map attrmap; if(res == DW_DLV_NO_ENTRY) { return; } if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_attrlist failed " << endl; exit(1); } for (Dwarf_Signed i = 0; i < atcnt; ++i) { Dwarf_Attribute attr = atlist[i]; Dwarf_Half attrnum = 0; res = dwarf_whatattr(attr,&attrnum,&error); if (res != DW_DLV_OK) { cout << "ERROR FAIL: unable to get attrnum from attr!" <::iterator m = attrmap.find(attrnum); if (m != attrmap.end()) { // A duplicate! ignore. Compiler bug // in some gcc versions. continue; } attrmap[attrnum] = i; // Use an empty attr to get a placeholder on // the attr list for this IRDie. IRAttr irattr; attrlist.push_back(irattr); // We want a pointer to the final attr to be // recorded for references, not a local temp IRAttr. IRAttr & lastirattr = attrlist.back(); get_basic_attr_data_one_attr(dbg,attr,cudata,lastirattr); } dwarf_dealloc(dbg,atlist, DW_DLA_LIST); } // Invariant: IRDie and IRCUdata are in the irep tree, // not local record references to local scopes. static void get_children_of_die(Dwarf_Die in_die,IRDie&irdie, IRCUdata &ircudata, IRepresentation &irep, Dwarf_Debug dbg) { Dwarf_Die curchilddie = 0; Dwarf_Error error = 0; int res = dwarf_child(in_die,&curchilddie,&error); if(res == DW_DLV_NO_ENTRY) { return; } if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_child failed " << endl; exit(1); } //std::list & childlist = irdie.getChildren(); int childcount = 0; for(;;) { IRDie child; get_basic_die_data(dbg,curchilddie,child); irdie.addChild(child); IRDie &lastchild = irdie.lastChild(); get_attrs_of_die(curchilddie,lastchild,ircudata,irep,dbg); ircudata.insertLocalDieOffset(lastchild.getCURelativeOffset(), &lastchild); get_children_of_die(curchilddie,lastchild,ircudata,irep,dbg); ++childcount; Dwarf_Die tchild = 0; res = dwarf_siblingof(dbg,curchilddie,&tchild,&error); if(res == DW_DLV_NO_ENTRY) { break; } if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_siblingof failed " << endl; exit(1); } dwarf_dealloc(dbg,curchilddie,DW_DLA_DIE); curchilddie = tchild; } dwarf_dealloc(dbg,curchilddie,DW_DLA_DIE); } static void get_linedata_of_cu_die(Dwarf_Die in_die,IRDie&irdie UNUSEDARG, IRCUdata &ircudata, IRepresentation &irep UNUSEDARG, Dwarf_Debug dbg) { Dwarf_Error error = 0; char **srcfiles = 0; Dwarf_Signed srccount = 0; IRCULineData&culinesdata = ircudata.getCULines(); int res = dwarf_srcfiles(in_die,&srcfiles, &srccount,&error); if(res == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_srcfiles failed " << endl; exit(1); } else if (res == DW_DLV_NO_ENTRY) { // No data. return; } std::vector &srcs = culinesdata.get_cu_srcfiles(); for (Dwarf_Signed i = 0; i < srccount; ++i) { IRCUSrcfile S(srcfiles[i]); srcs.push_back(S); /* use srcfiles[i] */ dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); Dwarf_Line * linebuf = 0; Dwarf_Signed linecnt = 0; int res2 = dwarf_srclines(in_die,&linebuf,&linecnt, &error); if(res2 == DW_DLV_ERROR) { errprint(error); cerr << "dwarf_srclines failed " << endl; exit(1); } else if (res2 == DW_DLV_NO_ENTRY) { // No data. cerr << "dwarf_srclines failed NO_ENTRY, crazy " "since srcfiles worked" << endl; exit(1); } std::vector &lines = culinesdata.get_cu_lines(); for(Dwarf_Signed j = 0; j < linecnt ; ++j ) { Dwarf_Line li = linebuf[j]; int lres; Dwarf_Addr address = 0; lres = dwarf_lineaddr(li,&address,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineaddr failed. " << endl; exit(1); } Dwarf_Bool is_addr_set = 0; lres = dwarf_line_is_addr_set(li,&is_addr_set,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_line_is_addr_set failed. " << endl; exit(1); } Dwarf_Unsigned fileno = 0; lres = dwarf_line_srcfileno(li,&fileno,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_srcfileno failed. " << endl; exit(1); } Dwarf_Unsigned lineno = 0; lres = dwarf_lineno(li,&lineno,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineno failed. " << endl; exit(1); } Dwarf_Unsigned lineoff = 0; lres = dwarf_lineoff_b(li,&lineoff,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineoff failed. " << endl; exit(1); } char *linesrctmp = 0; lres = dwarf_linesrc(li,&linesrctmp,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_linesrc failed. " << endl; exit(1); } // libdwarf is trying to generate a full path, // the string here is that generated data, not // simply the 'file' path represented by the // file number (fileno). std::string linesrc(linesrctmp); Dwarf_Bool is_stmt = 0; lres = dwarf_linebeginstatement(li,&is_stmt,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_linebeginstatement failed. " << endl; exit(1); } Dwarf_Bool basic_block = 0; lres = dwarf_lineblock(li,&basic_block,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineblock failed. " << endl; exit(1); } Dwarf_Bool end_sequence = 0; lres = dwarf_lineendsequence(li,&end_sequence,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_lineendsequence failed. " << endl; exit(1); } Dwarf_Bool prologue_end = 0; Dwarf_Bool epilogue_begin = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; lres = dwarf_prologue_end_etc(li,&prologue_end, &epilogue_begin,&isa,&discriminator,&error); if (lres != DW_DLV_OK) { cerr << "dwarf_prologue_end_etc failed. " << endl; exit(1); } IRCULine L(address, is_addr_set, fileno, lineno, lineoff, linesrc, is_stmt, basic_block, end_sequence, prologue_end,epilogue_begin, isa,discriminator); lines.push_back(L); } dwarf_srclines_dealloc(dbg, linebuf, linecnt); } static bool getToplevelOffsetAttr(Dwarf_Die cu_die,Dwarf_Half attrnumber, Dwarf_Unsigned &offset_out) { Dwarf_Error error = 0; Dwarf_Off offset = 0; Dwarf_Attribute attr = 0; int res = dwarf_attr(cu_die,attrnumber,&attr, &error); bool foundit = false; if(res == DW_DLV_OK) { res = dwarf_global_formref(attr,&offset,&error); if(res == DW_DLV_OK) { foundit = true; offset_out = offset; } } return foundit; } // We record the .debug_info info for each CU found // To start with we restrict attention to very few DIEs and // attributes, but intend to get all eventually. static void readCUDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep) { Dwarf_Error error; int cu_number = 0; std::list &culist = irep.infodata().getCUData(); for(;;++cu_number) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Half version_stamp = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_header = 0; Dwarf_Half offset_size = 0; Dwarf_Half extension_size = 0; Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; res = dwarf_next_cu_header_b(dbg,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &offset_size, &extension_size, &next_cu_header, &error); if(res == DW_DLV_ERROR) { errprint(error); cerr <<"Error in dwarf_next_cu_header"<< endl; exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ return; } IRCUdata cudata(cu_header_length,version_stamp, abbrev_offset,address_size, offset_size, extension_size,next_cu_header); // The CU will have a single sibling (well, it is // not exactly a sibling, but close enough), a cu_die. res = dwarf_siblingof(dbg,no_die,&cu_die,&error); if(res == DW_DLV_ERROR) { errprint(error); cerr <<"Error in dwarf_siblingof on CU die "<< endl; exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ cerr <<"no Entry! in dwarf_siblingof on CU die "<< endl; exit(1); } Dwarf_Off macrooffset = 0; bool foundmsect = getToplevelOffsetAttr(cu_die,DW_AT_macro_info, macrooffset); Dwarf_Off linesoffset = 0; bool foundlines = getToplevelOffsetAttr(cu_die,DW_AT_stmt_list, linesoffset); Dwarf_Off dieoff = 0; res = dwarf_dieoffset(cu_die,&dieoff,&error); if(res != DW_DLV_OK) { cerr << "Unable to get cu die offset for macro infomation "<< endl; exit(1); } if(foundmsect) { cudata.setMacroData(macrooffset,dieoff); } if(foundlines) { cudata.setLineData(linesoffset,dieoff); } culist.push_back(cudata); IRCUdata & treecu = irep.infodata().lastCU(); IRDie &cuirdie = treecu.baseDie(); get_basic_die_data(dbg,cu_die,cuirdie); treecu.insertLocalDieOffset(cuirdie.getCURelativeOffset(), &cuirdie); get_attrs_of_die(cu_die,cuirdie,treecu,irep,dbg); get_children_of_die(cu_die,cuirdie,treecu,irep,dbg); get_linedata_of_cu_die(cu_die,cuirdie,treecu,irep,dbg); // Now we have all local DIEs in the CU so we // can identify all targets of local CLASS_REFERENCE // and insert the IRDie * into the IRFormReference treecu.updateReferenceAttrDieTargets(); dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); } // If we want pointers from child to parent now is the time // we can construct them. } // We read thru the CU headers and the CU die to find // the macro info for each CU (if any). // We record the CU macro info for each CU found (using // the value of the DW_AT_macro_info attribute, if any). static void readMacroDataFromBinary(Dwarf_Debug dbg, IRepresentation & irep) { list &cudata = irep.infodata().getCUData(); list::iterator it = cudata.begin(); int ct = 0; for( ; it != cudata.end(); ++it,++ct) { Dwarf_Unsigned macrooffset = 0; Dwarf_Unsigned cudieoffset = 0; bool foundmsect = it->hasMacroData(¯ooffset,&cudieoffset); if(foundmsect) { readCUMacroDataFromBinary(dbg, irep, macrooffset,*it); } } } // Offsets refer to .debug_info, nothing else. static void readGlobals(Dwarf_Debug dbg, IRepresentation & irep) { Dwarf_Error error; Dwarf_Global *globs = 0; Dwarf_Type *types = 0; Dwarf_Signed cnt = 0; int res = 0; IRPubsData &pubdata = irep.pubnamedata(); res = dwarf_get_globals(dbg, &globs,&cnt, &error); if(res == DW_DLV_OK) { std::list &pubnames = pubdata.getPubnames(); for (Dwarf_Signed i = 0; i < cnt; ++i) { Dwarf_Global g = globs[i]; char *name = 0; // dieoff and cuoff may be in .debug_info // or .debug_types Dwarf_Off dieoff = 0; Dwarf_Off cuoff = 0; res = dwarf_global_name_offsets(g,&name, &dieoff,&cuoff,&error); if( res == DW_DLV_OK) { IRPub p(name,dieoff,cuoff); dwarf_dealloc(dbg,name,DW_DLA_STRING); pubnames.push_back(p); } } dwarf_globals_dealloc(dbg, globs, cnt); } else if (res == DW_DLV_ERROR) { cerr << "dwarf_get_globals failed" << endl; exit(1); } res = dwarf_get_pubtypes(dbg, &types,&cnt, &error); if(res == DW_DLV_OK) { std::list &pubtypes = pubdata.getPubtypes(); for (Dwarf_Signed i = 0; i < cnt; ++i) { Dwarf_Type g = types[i]; char *name = 0; // dieoff and cuoff may be in .debug_info // or .debug_types Dwarf_Off dieoff = 0; Dwarf_Off cuoff = 0; res = dwarf_pubtype_name_offsets(g,&name, &dieoff,&cuoff,&error); if( res == DW_DLV_OK) { IRPub p(name,dieoff,cuoff); dwarf_dealloc(dbg,name,DW_DLA_STRING); pubtypes.push_back(p); } } dwarf_types_dealloc(dbg, types, cnt); } else if (res == DW_DLV_ERROR) { cerr << "dwarf_get_globals failed" << endl; exit(1); } } dwarfutils-20200114/dwarfgen/createirepfrombinary.h000066400000000000000000000031011361531463500223150ustar00rootroot00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // createirepfrombinary.h void createIrepFromBinary(const std::string &infile, IRepresentation & irep); dwarfutils-20200114/dwarfgen/dwarf-generator.txt000077500000000000000000000017101361531463500215670ustar00rootroot00000000000000Speculative thoughts on using a script to define what DWARF? to write out in an elf file: Syntax for dw tab entry # is comment levels by indentation like python attrs. indent to the tag they apply to. ;section x ;endsection x :label: [] tag attr [form name] value any attr or tag may have a label. Various forms require specific value formats. values sometims require offsets such as a sibling ref or a fwd/rev ref or a ref to the debug_loc sec DW_FORM_data 1,2 integer DW_FORM_data 4,8 integer or offset depends on context DW_FORM_sdata, udata integer DW_FORM_string "string value" DW_FORM_strp "string value" DW_FORM_block 1,2,4,8 blk-fmt this is blk_fmt hex number decimal number [ dw-expr] sythetic forms: DW_FORM_loclist [label | loclist-itself] loclist-itself offset offset DW_FORM_block [blk_fmt] ... DW_FORM_maclist label DW_FORM_? Line table entries CIE entries FDE entries mac sec entries dwarfutils-20200114/dwarfgen/dwarfgen.1000066400000000000000000000041201361531463500176110ustar00rootroot00000000000000.Dd $Mdocdate$ .Dt DWARFGEN \&1 "dwarfdump and libdwarf" .Os .Sh NAME .Nm dwarfgen .Nd generate example DWARF data. .Sh SYNOPSIS .Nm .Op Fl t Ar type .Op Fl o Ar outpath .Op Fl c cunum .Ar pathname . .Sh DESCRIPTION The .Nm creates DWARF sections as requested by specific options. .Pp Using some information source, create a tree of dwarf information (speaking of a DIE tree). Turn the die tree into dwarfdata using libdwarf producer and write the resulting data in an object file. It is a bit inconsistent in error handling just to demonstrate the various possibilities using the producer library. .Pp Main options: .Bl -tag -compact .It Fl t Ar type what sort of input to read. May be one of: .Bl -tag -compact .It Ar def means predefined (no input is read, the output is based on some canned setups built into dwarfgen). .Ar path is ignored in this case. This is the default, and does not work. .It Ar obj means .Ar path is the object file to read (The dwarf sections are duplicated in the output file.) Requires .Ar path . .It Ar txt .Ar path contains plain text (in a form rather like output by dwarfdump) that defines the dwarf that is to be output. Requires .Ar path . .El . .It Fl o Ar outpath specifies the pathname of the output object. If not supplied, .Pa testout.o is used as the default output path. . .It Fl c Ar cunum supplies a CU number of the .Ql obj .Ar type input to read . .\" not "output" ??? jkl because the dwarf producer wants just one CU. Default is -1 which won't match anything. .El .Pp Other options: .Bl -tag -compact .It Fl h transform high PC to const. .It Fl s output as text. .It Fl r show relocation details. .It Fl v Ar version DWARF version 2, 3, 4, or 5. .It Fl p Ar size pointer size, 4 or 8. .It Fl f Ar offset offset size, 4 or 8. .El . .\" .Sh ENVIRONMENT .\" For sections 1, 6, 7, and 8 only. .\" .Sh FILES .\" .Sh EXIT STATUS .\" For sections 1, 6, and 8 only. .\" .Sh EXAMPLES .\" .Sh DIAGNOSTICS .\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only. .\" .Sh SEE ALSO .\" .Xr foobar 1 .\" .Sh STANDARDS .\" .Sh HISTORY .\" .Sh AUTHORS .\" .Sh CAVEATS .\" .Sh BUGS dwarfutils-20200114/dwarfgen/dwarfgen.cc000066400000000000000000001275241361531463500200540ustar00rootroot00000000000000/* Copyright (C) 2010-2019 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // dwarfgen.cc // // Using some information source, create a tree of dwarf // information (speaking of a DIE tree). // Turn the die tree into dwarfdata using libdwarf producer // and write the resulting data in an object file. // It is a bit inconsistent in error handling just to // demonstrate the various possibilities using the producer // library. // // dwarfgen [-t def|obj|txt] [-o outpath] [-c cunum] path // where -t means what sort of input to read // def means predefined (no input is read, the output // is based on some canned setups built into dwarfgen). // 'path' is ignored in this case. This is the default. // // obj means 'path' is required, it is the object file to // read (the dwarf sections are duplicated in the output file) // // txt means 'path' is required, path must contain plain text // (in a form rather like output by dwarfdump) // that defines the dwarf that is to be output. // // where -o means specify the pathname of the output object. If not // supplied testout.o is used as the default output path. // where -c supplies a CU number of the obj input to output // because the dwarf producer wants just one CU. // Default is -1 which won't match anything. #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include #include #ifdef HAVE_STRING_H #include /* for strchr etc */ #endif /* HAVE_STRING_H */ #ifdef HAVE_SYS_STAT_H #include /* For open() */ #endif /* HAVE_SYS_STAT_H */ #include //open #include "general.h" #include "dwgetopt.h" #ifdef HAVE_LIBELF_H // gelf.h is a GNU-only elf header, so not using it. #include "libelf.h" #elif HAVE_LIBELF_LIBELF_H #include "libelf/libelf.h" #endif #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "ireptodbg.h" #include "createirepfrombinary.h" #ifdef _WIN32 #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #endif /* _WIN32 */ #ifdef _WIN32 #ifndef O_RDONLY /* This is for a Windows environment */ # define O_RDONLY _O_RDONLY #endif #ifdef _O_BINARY /* This is for a Windows environment */ #define O_BINARY _O_BINARY #endif #else /* !_WIN32 */ # ifndef O_BINARY # define O_BINARY 0 /* So it does nothing in Linux/Unix */ # endif #endif /* !_WIN32 */ /* These are for a Windows environment */ #ifdef _WIN32 #ifdef _O_WRONLY #define O_WRONLY _O_WRONLY #endif #ifdef _O_CREAT #define O_CREAT _O_CREAT #endif #ifdef _O_TRUNC #define O_TRUNC _O_TRUNC #endif #ifdef _S_IREAD #define S_IREAD _S_IREAD #endif #ifdef _S_IWRITE #define S_IWRITE _S_IWRITE #endif /* open modes S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH */ #ifndef S_IRUSR #define S_IRUSR _S_IREAD #endif // S_IRUSR #ifndef S_IWUSR #define S_IWUSR _S_IWRITE #endif #ifndef S_IRGRP #define S_IRGRP 0 #endif #ifndef S_IROTH #define S_IROTH 0 #endif #endif /* _WIN32 */ using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; extern "C" { static int CallbackFunc( const char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_symbol_index, void * user_data, int* error); } // End extern "C" // FIXME. This is incomplete. See FIXME just below here. #ifdef WORDS_BIGENDIAN static void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len) { unsigned char *targ = (unsigned char *) s1; const unsigned char *src = (const unsigned char *) s2; if (len == 4) { targ[3] = src[0]; targ[2] = src[1]; targ[1] = src[2]; targ[0] = src[3]; } else if (len == 8) { targ[7] = src[0]; targ[6] = src[1]; targ[5] = src[2]; targ[4] = src[3]; targ[3] = src[4]; targ[2] = src[5]; targ[1] = src[6]; targ[0] = src[7]; } else if (len == 2) { targ[1] = src[0]; targ[0] = src[1]; } /* should NOT get below here: is not the intended use */ else if (len == 1) { targ[0] = src[0]; } else { memcpy(s1, s2, (size_t)len); } return; } #endif /* WORDS_BIGENDIAN */ // There are issues 32/64 here, and endianness. // We are asserting here in dwarfgen that the target // object created is to be DW_DLC_TARGET_LITTLEENDIAN. // FIXME. not general. // op and ol aread MUST NOT overlap. // ip and il should be 2,4,or 8. Nothing else. // These could perfectly well be functions. #ifdef WORDS_BIGENDIAN #define ASNX(op,ol,ip,il) \ do { \ if( ol > il) { \ unsigned sbyte = 0; \ memset(op,0,ol); \ sbyte = ol - il; \ _dwarf_memcpy_swap_bytes(((char *)(op))+sbyte,\ (const void *)(ip),il);\ } else { \ unsigned sbyte = 0; \ sbyte = il - ol; \ _dwarf_memcpy_swap_bytes((char *)(op), \ (const void *)(((const char *)(ip))+sbyte),ol);\ } \ } while (0) #else // LITTLEENDIAN #define ASNX(op,ol,ip,il) \ do { \ if( ol > il) { \ memset(op,0,ol); \ memcpy(((char *)(op)),(const void *)(ip),il);\ } else { \ memcpy((char *)(op), \ (const void *)(((const char *)(ip))),ol);\ } \ } while (0) #endif // ENDIANNESS static void write_object_file(Dwarf_P_Debug dbg, IRepresentation &irep, unsigned machine, unsigned endian, unsigned long dwbitflags, void * user_data); static void write_text_section(Elf * elf,unsigned elfclass); static void write_generated_dbg(Dwarf_P_Debug dbg,Elf * elf, IRepresentation &irep); static string outfile("testout.o"); static string infile; static enum WhichInputSource { OptNone, OptReadText,OptReadBin,OptPredefined} whichinput(OptPredefined); /* Use a generic call to open the file, due to issues with Windows */ int open_a_file(const char * name); int create_a_file(const char * name); void close_a_file(int f); // This is a global so thet CallbackFunc can get to it // If we used the dwarf_producer_init_c() user_data pointer // creatively we would not need a global. static IRepresentation Irep; static Elf * elf = 0; static strtabdata secstrtab; CmdOptions cmdoptions = { false, //transformHighpcToConst DW_FORM_string, // defaultInfoStringForm false, //showrelocdetails false, //adddata16 false, //addimplicitconst false, //addframeadvanceloc false, //addSUNfuncoffsets }; // loff_t is signed for some reason (strange) but we make offsets unsigned. #define LOFFTODWUNS(x) ( (Dwarf_Unsigned)(x)) /* See the Elf ABI for further definitions of these fields. */ class SectionFromDwarf { public: std::string name_; Dwarf_Unsigned section_name_itself_; ElfSymIndex section_name_symidx_; int size_; Dwarf_Unsigned type_; Dwarf_Unsigned flags_; /* type: SHT_REL, RELA: Section header index of the section relocation applies to. SHT_SYMTAB: Section header index of the associated string table. */ Dwarf_Unsigned link_; /* type: SHT_REL, RELA: Section header index of the section relocation applies to. SHT_SYMTAB: One greater than index of the last local symbol.. */ Dwarf_Unsigned info_; private: ElfSectIndex elf_sect_index_; Dwarf_Unsigned lengthWrittenToElf_; public: Dwarf_Unsigned getNextOffset() { return lengthWrittenToElf_; } void setNextOffset(Dwarf_Unsigned v) { lengthWrittenToElf_ = v; } unsigned getSectionNameSymidx() { return section_name_symidx_.getSymIndex(); }; SectionFromDwarf():section_name_itself_(0), section_name_symidx_(0), size_(0),type_(0),flags_(0), link_(0), info_(0), elf_sect_index_(0), lengthWrittenToElf_(0) {} ; ~SectionFromDwarf() {}; void setSectIndex(ElfSectIndex v) { elf_sect_index_ = v;} ElfSectIndex getSectIndex() const { return elf_sect_index_;} SectionFromDwarf(const std::string&name, int size,Dwarf_Unsigned type,Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info): name_(name), size_(size),type_(type),flags_(flags), link_(link), info_(info), elf_sect_index_(0), lengthWrittenToElf_(0) { // Now create section name string section. section_name_itself_ = secstrtab.addString(name.c_str()); ElfSymbols& es = Irep.getElfSymbols(); // Now creat a symbol for the section name. // (which has its own string table) section_name_symidx_ = es.addElfSymbol(0,name); } ; }; vector dwsectab; static ElfSectIndex create_dw_elf(SectionFromDwarf &ds,unsigned elfclass); static SectionFromDwarf & FindMySection(const ElfSectIndex & elf_section_index) { for(unsigned i =0; i < dwsectab.size(); ++i) { if(elf_section_index.getSectIndex() != dwsectab[i].getSectIndex().getSectIndex()) { continue; } return dwsectab[i]; } cerr << "dwarfgen: Unable to find my dw sec data for elf section " << elf_section_index.getSectIndex() << endl; exit(1); } static int FindMySectionNum(const ElfSectIndex & elf_section_index) { for(unsigned i =0; i < dwsectab.size(); ++i) { if(elf_section_index.getSectIndex() != dwsectab[i].getSectIndex().getSectIndex()) { continue; } return i; } cerr << "dwarfgen: Unable to find my dw sec index for elf section " << elf_section_index.getSectIndex() << endl; exit(1); } static unsigned createnamestr(unsigned strtabstroff,unsigned elfclass) { Elf_Scn * strscn =elf_newscn(elf); if(!strscn) { cerr << "dwarfgen: Unable to elf_newscn() on " << outfile << endl; exit(1); } Elf_Data* shstr =elf_newdata(strscn); if(!shstr) { cerr << "dwarfgen: Unable to elf_newdata() on " << outfile << endl; exit(1); } shstr->d_buf = secstrtab.exposedata(); shstr->d_type = ELF_T_BYTE; shstr->d_size = secstrtab.exposelen(); shstr->d_off = 0; shstr->d_align = 1; shstr->d_version = EV_CURRENT; if (elfclass == ELFCLASS32) { Elf32_Shdr * strshdr = elf32_getshdr(strscn); if(!strshdr) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << outfile << endl; exit(1); } strshdr->sh_name = strtabstroff; strshdr->sh_type= SHT_STRTAB; strshdr->sh_flags = SHF_STRINGS; strshdr->sh_addr = 0; strshdr->sh_offset = 0; strshdr->sh_size = 0; strshdr->sh_link = 0; strshdr->sh_info = 0; strshdr->sh_addralign = 1; strshdr->sh_entsize = 0; } else { #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr * strshdr = elf64_getshdr(strscn); if(!strshdr) { cerr << "dwarfgen: Unable to elf64_getshdr() on " << outfile << endl; exit(1); } strshdr->sh_name = strtabstroff; strshdr->sh_type= SHT_STRTAB; strshdr->sh_flags = SHF_STRINGS; strshdr->sh_addr = 0; strshdr->sh_offset = 0; strshdr->sh_size = 0; strshdr->sh_link = 0; strshdr->sh_info = 0; strshdr->sh_addralign = 1; strshdr->sh_entsize = 0; #endif // HAVE_ELF64_GETSHDR } return elf_ndxscn(strscn); } // This functional interface is defined by libdwarf. // Please see the comments in libdwarf2p.1.pdf // (libdwarf2p.1.mm) on this callback interface. // Returns (to libdwarf) an Elf section number, so // since 0 is always empty and dwarfgen sets 1 to be a fake // text section on the first call this returns 2, second 3, etc. static int CallbackFunc( const char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_symbol_index, void * user_data, int* error UNUSEDARG) { // Create an elf section. // If the data is relocations, we suppress the generation // of a section when we intend to do the relocations // ourself (fine for dwarfgen but would // be really surprising for a normal compiler // back end using the producer code). // The section name appears both in the section strings // .shstrtab and // in the elf symtab .symtab and its strings .strtab. unsigned elfclass = 0; if (user_data) { elfclass = *(unsigned *)user_data; } else { cerr << "We created an internal-to-dwarfgen bug here. " << " line " << __LINE__ << " " <<__FILE__ << endl; exit(1); } if (0 == strncmp(name,".rel",4)) { // It is relocation, create no section! return 0; } SectionFromDwarf ds(name,size,type,flags,link,info) ; // It is up to you to provide (to libdwarf, // to generate relocation records) // a symbol index for the section. // In Elf, each section gets an elf symbol table entry. // So that relocations have an address to refer to. // You will create the Elf symbol table, so you have to tell // libdwarf the index to put into relocation records for the // section newly defined here. *sect_name_symbol_index = ds.getSectionNameSymidx(); ElfSectIndex createdsec = create_dw_elf(ds,elfclass); // Do all the data creation before pushing // (copying) ds onto dwsectab! dwsectab.push_back(ds); // The number returned is elf section, not dwsectab[] index return createdsec.getSectIndex(); } // Here we create a new Elf section // This never happens for relocations in dwarfgen, // only a few sections are created by dwarfgen. static ElfSectIndex create_dw_elf(SectionFromDwarf &ds,unsigned elfclass) { Elf_Scn * scn =elf_newscn(elf); if(!scn) { cerr << "dwarfgen: Unable to elf_newscn() on " << ds.name_ << endl; exit(1); } if (elfclass == ELFCLASS32) { Elf32_Shdr * shdr = elf32_getshdr(scn); if(!shdr) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << ds.name_ << endl; exit(1); } shdr->sh_name = ds.section_name_itself_; shdr->sh_type = ds.type_; shdr->sh_flags = ds.flags_; shdr->sh_addr = 0; shdr->sh_offset = 0; shdr->sh_size = ds.size_; shdr->sh_link = ds.link_; shdr->sh_info = ds.info_; shdr->sh_addralign = 1; shdr->sh_entsize = 0; } else { #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr * shdr = elf64_getshdr(scn); if(!shdr) { cerr << "dwarfgen: Unable to elf64_getshdr() on " << ds.name_ << endl; exit(1); } shdr->sh_name = ds.section_name_itself_; shdr->sh_type = ds.type_; shdr->sh_flags = ds.flags_; shdr->sh_addr = 0; shdr->sh_offset = 0; shdr->sh_size = ds.size_; shdr->sh_link = ds.link_; shdr->sh_info = ds.info_; shdr->sh_addralign = 1; shdr->sh_entsize = 0; #endif // HAVE_ELF64_GETSHDR } ElfSectIndex si(elf_ndxscn(scn)); ds.setSectIndex(si); cout << "New Elf section: "<< ds.name_ << " Type="<< ds.type_ << " Flags="<< ds.flags_ << " Elf secnum="<< si.getSectIndex() << " link section=" << ds.link_<< " info=" << ds.info_ << endl ; return si; } static void setinput(enum WhichInputSource *src, const string &type, bool *pathreq) { if(type == "txt") { *src = OptReadText; *pathreq = true; return; } else if (type == "obj") { *src = OptReadBin; *pathreq = true; return; } else if (type == "def") { *src = OptPredefined; *pathreq = false; return; } cout << "dwarfgen: Giving up, only txt obj or def accepted after -t" << endl; exit(1); } int main(int argc, char **argv) { try { int opt; bool pathrequired(false); long cu_of_input_we_output = -1; bool force_empty_dnames = false; // Overriding macro constants from pro_line.h // so we can choose at runtime // and avoid modifying header files. // This is the original set of constants // used for testing. // see also output_v4_test (--output-v4-test // longopt). const char *dwarf_extras ="opcode_base=13," "minimum_instruction_length=1," "line_base=-1," "line_range=4"; int endian = DW_DLC_TARGET_LITTLEENDIAN; const char *dwarf_version = "V2"; const char * isa_name = "x86"; unsigned long ptrsizeflagbit = DW_DLC_POINTER32; unsigned long dwarfoffsetsizeflagbit = DW_DLC_OFFSET32; /* DW_DLC_ELF_OFFSET_SIZE 32/64 winds up determining the ELFCLASS 32/64 in write_object_file() */ unsigned long elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_32; unsigned machine = EM_386; /* from elf.h */ int output_v4_test = 0; unsigned global_elfclass = 0; int longindex; static struct dwoption longopts[] = { {"adddata16",dwno_argument,0,1000}, {"force-empty-dnames",dwno_argument,0,1001}, {"add-implicit-const",dwno_argument,0,1002}, {"add-frame-advance-loc",dwno_argument,0,1003}, {"add-sun-func-offsets",dwno_argument,0,1004}, {"output-pointer-size",dwrequired_argument,0,'p'}, {"output-offset-size",dwrequired_argument,0,'f'}, {"output-dwarf-version",dwrequired_argument,0,'v'}, {"output-v4-test",dwno_argument,0,1005}, {"default-form-strp",dwno_argument,0,'s'}, {"show-reloc-details",dwno_argument,0,'r'}, {"high-pc-as-const",dwno_argument,0,'h'}, {0,0,0,0}, }; // -p is pointer size // -f is offset size, overriding the above // -v is version number for dwarf output while((opt=dwgetopt_long(argc,argv, "o:t:c:hsrv:p:f:", longopts,&longindex)) != -1) { switch(opt) { case 1000: if(longindex == 0) { // To test adding the DWARF5 // DW_FORM_data16 // libdwarf reading is thus testable. cmdoptions.adddata16 = true; } else { cerr << "dwarfgen: Invalid lnogoption input " << longindex << endl; exit(1); } break; case 1001: // To test having an empty .debug_dnames // section. // libdwarf reading is thus testable. force_empty_dnames = true; break; case 1002: // To test creating DWARF5 // DW_FORM_implicit_const. // libdwarf reading is thus testable. cmdoptions.addimplicitconst = true; break; case 1003: // To test dwarf_add_fde_inst_a(). // libdwarf reading is thus testable. cmdoptions.addframeadvanceloc = true; break; case 1004: // To test creating DWARF5 // DW_AT_SUN_func_offsets. // libdwarf reading is thus testable. cmdoptions.addSUNfuncoffsets = true; break; case 1005: //{"output-v4-test",dwno_argument,0,1005} output_v4_test = 1; break; case 'c': // At present we can only create a single // cu in the output of the libdwarf producer. cu_of_input_we_output = atoi(dwoptarg); break; case 'r': cmdoptions.showrelocdetails=true; break; case 's': // --default-form-strp cmdoptions.defaultInfoStringForm = DW_FORM_strp; break; case 'p': /* pointer size: value 4 or 8. */ if (!strcmp("4",dwoptarg)) { ptrsizeflagbit = DW_DLC_POINTER32; elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_32; } else if (!strcmp("8",dwoptarg)) { ptrsizeflagbit = DW_DLC_POINTER64; elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_64; } else { cerr << "dwarfgen: Invalid p option input " << dwoptarg << endl; exit(1); } break; case 'f': /* offset size for DWARF: value 4 or 8. */ if (!strcmp("4",dwoptarg)) { dwarfoffsetsizeflagbit = DW_DLC_OFFSET32; } else if (!strcmp("8",dwoptarg)) { dwarfoffsetsizeflagbit = DW_DLC_OFFSET64; } else { cerr << "dwarfgen: Invalid f option input " << dwoptarg << endl; exit(1); } break; case 'v': /* Version 2 3 4 or 5 */ if (!strcmp("5",dwoptarg)) { dwarf_version = "V5"; } else if (!strcmp("4",dwoptarg)) { dwarf_version = "V4"; } else if (!strcmp("3",dwoptarg)) { dwarf_version = "V3"; } else if (!strcmp("2",dwoptarg)) { dwarf_version = "V2"; } else { cerr << "dwarfgen: Invalid v option input " << dwoptarg << endl; exit(1); } break; case 't': setinput(&whichinput,dwoptarg,&pathrequired); break; case 'h': cmdoptions.transformHighpcToConst = true; break; case 'o': outfile = dwoptarg; break; case '?': cerr << "dwarfgen: Invalid quest? option input " << endl; exit(1); default: cerr << "dwarfgen: Invalid option input " << endl; exit(1); } } if ( (dwoptind >= argc) && pathrequired) { cerr << "dwarfgen: Expected argument after options!" " Giving up." << endl; exit(EXIT_FAILURE); } if(pathrequired) { infile = argv[dwoptind]; } if (output_v4_test) { dwarf_extras ="opcode_base=13," "minimum_instruction_length=1," "line_base=-1," "line_range=4"; endian = DW_DLC_TARGET_LITTLEENDIAN; dwarf_version = "V4"; isa_name = "x86_64"; ptrsizeflagbit = DW_DLC_POINTER64; dwarfoffsetsizeflagbit = DW_DLC_OFFSET32; elfoffsetsizeflagbit = DW_DLC_ELF_OFFSET_SIZE_64; machine = EM_X86_64; /* from elf.h */ } if(whichinput == OptReadBin) { createIrepFromBinary(infile,Irep); } else if (whichinput == OptReadText) { cerr << "dwarfgen: dwarfgen: text read not supported yet" << endl; exit(EXIT_FAILURE); } else if (whichinput == OptPredefined) { cerr << "dwarfgen: predefined not supported yet" << endl; exit(EXIT_FAILURE); } else { cerr << "dwarfgen: Impossible: unknown input style." << endl; exit(EXIT_FAILURE); } // We no longer use the libdwarf interfaces returning // DW_DLV_BADADDR (though they still exist in libdwarf) // as that sort of return (mixing returned-pointer with // an error value) was ugly. // We use the latest calls instead, returning // DW_DLV_OK, DW_DLV_NO_ENTRY, or DW_DLV_ERROR // as an int. Dwarf_Ptr errarg = 0; Dwarf_Error err = 0; // The point of user_data is, as here, to // have crucial data available to the callback // function implementation. void *user_data = &global_elfclass; Dwarf_P_Debug dbg = 0; unsigned long dwbitflags = DW_DLC_WRITE| endian | ptrsizeflagbit| elfoffsetsizeflagbit| dwarfoffsetsizeflagbit| DW_DLC_SYMBOLIC_RELOCATIONS; // We use DW_DLC_SYMBOLIC_RELOCATIONS so we can // read the relocations and do our own relocating. // See calls of dwarf_get_relocation_info(). int res = dwarf_producer_init( dwbitflags, CallbackFunc, 0, // errhand errarg, user_data, isa_name, dwarf_version, dwarf_extras, &dbg, &err); if(res == DW_DLV_NO_ENTRY) { cerr << "dwarfgen: Failed dwarf_producer_init() NO_ENTRY" << endl; exit(EXIT_FAILURE); } if(res == DW_DLV_ERROR) { cerr << "dwarfgen: Failed dwarf_producer_init() ERROR" << endl; cerr << "dwarfgen errmsg " << dwarf_errmsg(err)<e_ident[EI_MAG0] = ELFMAG0; ehp->e_ident[EI_MAG1] = ELFMAG1; ehp->e_ident[EI_MAG2] = ELFMAG2; ehp->e_ident[EI_MAG3] = ELFMAG3; ehp->e_ident[EI_CLASS] = elfclass; ehp->e_ident[EI_DATA] = elfendian; ehp->e_ident[EI_VERSION] = EV_CURRENT; ehp->e_machine = machine; // We do not bother to create program headers, so // mark this as ET_REL. ehp->e_type = ET_REL; ehp->e_version = EV_CURRENT; unsigned strtabstroff = secstrtab.addString(".shstrtab"); // an object section with fake .text data (just as an example). write_text_section(elf,elfclass); write_generated_dbg(dbg,elf,irep); // Create the section name string section. unsigned shstrindex = createnamestr(strtabstroff,elfclass); ehp->e_shstrndx = shstrindex; } else { #ifdef HAVE_ELF64_GETEHDR static Elf64_Ehdr * ehp = 0; ehp = elf64_newehdr(elf); if(!ehp) { cerr << "dwarfgen: Unable to elf64_newehdr() on " << outfile << endl; exit(1); } ehp->e_ident[EI_MAG0] = ELFMAG0; ehp->e_ident[EI_MAG1] = ELFMAG1; ehp->e_ident[EI_MAG2] = ELFMAG2; ehp->e_ident[EI_MAG3] = ELFMAG3; ehp->e_ident[EI_CLASS] = elfclass; ehp->e_ident[EI_DATA] = elfendian; ehp->e_ident[EI_VERSION] = EV_CURRENT; ehp->e_machine = machine; // We do not bother to create program headers, so // mark this as ET_REL. ehp->e_type = ET_REL; ehp->e_version = EV_CURRENT; unsigned strtabstroff = secstrtab.addString(".shstrtab"); // an object section with fake .text data (just as an example). write_text_section(elf,elfclass); write_generated_dbg(dbg,elf,irep); // Create the section name string section. unsigned shstrindex = createnamestr(strtabstroff,elfclass); ehp->e_shstrndx = shstrindex; #endif // HAVE_ELF64_GETEHDR } // Get it all written to the output file. off_t ures = elf_update(elf,cmd); if(ures == (off_t)(-1LL)) { cerr << "dwarfgen: Unable to elf_update() on " << outfile << endl; int eer = elf_errno(); cerr << "Error is " << eer << " " << elf_errmsg(eer) << endl; exit(1); } cout << " output image size in bytes " << ures << endl; elf_end(elf); close_a_file(fd); } // an object section with fake .text data (just as an example). static void write_text_section(Elf * elf_w,unsigned elfclass) { unsigned osecnameoff = secstrtab.addString(".text"); Elf_Scn * scn1 =elf_newscn(elf_w); if(!scn1) { cerr << "dwarfgen: Unable to elf_newscn() on " << outfile << endl; exit(1); } Elf_Data* ed1 =elf_newdata(scn1); if(!ed1) { cerr << "dwarfgen: Unable to elf_newdata() on " << outfile << endl; exit(1); } const char *d = "data in section"; ed1->d_buf = (void *)d; ed1->d_type = ELF_T_BYTE; ed1->d_size = strlen(d) +1; ed1->d_off = 0; ed1->d_align = 4; ed1->d_version = EV_CURRENT; if (elfclass == ELFCLASS32) { Elf32_Shdr * shdr1 = elf32_getshdr(scn1); if(!shdr1) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << outfile << endl; exit(1); } shdr1->sh_name = osecnameoff; shdr1->sh_type= SHT_PROGBITS; shdr1->sh_flags = 0; shdr1->sh_addr = 0; shdr1->sh_offset = 0; shdr1->sh_size = 0; shdr1->sh_link = 0; shdr1->sh_info = 0; shdr1->sh_addralign = 1; shdr1->sh_entsize = 0; } else { #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr * shdr1 = elf64_getshdr(scn1); if(!shdr1) { cerr << "dwarfgen: Unable to elf32_getshdr() on " << outfile << endl; exit(1); } shdr1->sh_name = osecnameoff; shdr1->sh_type= SHT_PROGBITS; shdr1->sh_flags = 0; shdr1->sh_addr = 0; shdr1->sh_offset = 0; shdr1->sh_size = 0; shdr1->sh_link = 0; shdr1->sh_info = 0; shdr1->sh_addralign = 1; shdr1->sh_entsize = 0; #endif // HAVE_ELF64_GETSHDR } } static void InsertDataIntoElf(Dwarf_Signed d,Dwarf_P_Debug dbg,Elf *elf_i) { Dwarf_Signed elf_section_index = 0; Dwarf_Unsigned length = 0; Dwarf_Ptr bytes = dwarf_get_section_bytes(dbg,d, &elf_section_index,&length,0); Elf_Scn *scn = elf_getscn(elf_i,elf_section_index); if(!scn) { cerr << "dwarfgen: Unable to elf_getscn on disk transform # " << d << endl; exit(1); } ElfSectIndex si(elf_section_index); SectionFromDwarf & sfd = FindMySection(si); Elf_Data* ed =elf_newdata(scn); if(!ed) { cerr << "dwarfgen: elf_newdata died on transformed index " << d << endl; exit(1); } ed->d_buf = bytes; ed->d_type = ELF_T_BYTE; ed->d_size = length; ed->d_off = sfd.getNextOffset(); sfd.setNextOffset(ed->d_off + length); ed->d_align = 1; ed->d_version = EV_CURRENT; cout << "Inserted " << length << " bytes into elf section index " << elf_section_index << endl; } #if 0 static string printable_rel_type(unsigned char reltype) { enum Dwarf_Rel_Type t = (enum Dwarf_Rel_Type)reltype; switch(t) { case dwarf_drt_none: return "dwarf_drt_none"; case dwarf_drt_data_reloc: return "dwarf_drt_data_reloc"; case dwarf_drt_segment_rel: return "dwarf_drt_segment_rel"; case dwarf_drt_first_of_length_pair: return "dwarf_drt_first_of_length_pair"; case dwarf_drt_second_of_length_pair: return "dwarf_drt_second_of_length_pair"; default: break; } return "drt-unknown (impossible case)"; } #endif static Dwarf_Unsigned FindSymbolValue(ElfSymIndex symi,IRepresentation &irep) { ElfSymbols & syms = irep.getElfSymbols(); ElfSymbol & es = syms.getElfSymbol(symi); Dwarf_Unsigned symv = es.getSymbolValue(); return symv; } #if 0 static int dump_bytes(const char *msg,void *val,int len) { char *p = (char *)val; int i = 0; cout << msg << " "; for (; i < len; ++i) { char x = *(p+i); cout << IToHex(x,2) <<" "; } cout << endl; } #endif /* Lets not assume that the quantities are aligned. */ static void bitreplace(char *buf, Dwarf_Unsigned newval, size_t newvalsize UNUSEDARG, int length) { if(length == 4) { Dwarf_Unsigned my4 = newval; Dwarf_Unsigned oldval = 0; ASNX(&oldval,sizeof(oldval),buf,(unsigned)length); oldval += my4; ASNX(buf,(unsigned)length,&oldval,sizeof(oldval)); } else if (length == 8) { Dwarf_Unsigned my8 = newval; Dwarf_Unsigned oldval = 0; memcpy(&oldval,buf,length); oldval += my8; memcpy(buf,&oldval,length); } else { cerr << "dwarfgen: Relocation is length " << length << " which we do not yet handle." << endl; exit(1); } } // This remembers nothing, so is dreadfully slow. static char * findelfbuf(Elf *elf_f UNUSEDARG ,Elf_Scn *scn, Dwarf_Unsigned offset, unsigned length) { Elf_Data * edbase = 0; Elf_Data * ed = elf_getdata(scn,edbase); unsigned bct = 0; for (;ed; ed = elf_getdata(scn,ed)) { bct++; if(offset >= LOFFTODWUNS(ed->d_off + ed->d_size) ) { continue; } if(offset < LOFFTODWUNS(ed->d_off)) { cerr << "dwarfgen: Relocation at offset " << offset << " cannot be accomplished, no buffer. " << endl; exit(1); } Dwarf_Unsigned localoff = offset - ed->d_off; if((localoff + length) > ed->d_size) { cerr << "dwarfgen: Relocation at offset " << offset << " cannot be accomplished, size mismatch. " << endl; exit(1); } char *lclptr = reinterpret_cast(ed->d_buf) + localoff; return lclptr; } cerr << " Relocation at offset " << offset << " cannot be accomplished, past end of buffers" << endl; return 0; } static void write_generated_dbg(Dwarf_P_Debug dbg,Elf * elf_w, IRepresentation &irep) { Dwarf_Error err = 0; Dwarf_Signed sectioncount = 0; int res = dwarf_transform_to_disk_form_a(dbg,§ioncount,&err); if (res != DW_DLV_OK) { if (res == DW_DLV_ERROR) { string msg(dwarf_errmsg(err)); cerr << "Dwarfgen fails: " << msg << endl; exit(1); } /* ASSERT: rex == DW_DLV_NO_ENTRY */ cerr << "Dwarfgen fails, some internal error " << endl; exit(1); } Dwarf_Signed d = 0; for(d = 0; d < sectioncount ; ++d) { InsertDataIntoElf(d,dbg,elf_w); } // Since we are emitting in final form sometimes, we may // do relocation processing here or we could (but do not) // emit relocation records into the object file. // The following is for DW_DLC_SYMBOLIC_RELOCATIONS. Dwarf_Unsigned reloc_sections_count = 0; int drd_version = 0; res = dwarf_get_relocation_info_count(dbg,&reloc_sections_count, &drd_version,&err); if( res != DW_DLV_OK) { cerr << "dwarfgen: Error getting relocation info count." << endl; exit(1); } cout << "Relocations sections count= " << reloc_sections_count << " relversion=" << drd_version << endl; for( Dwarf_Unsigned ct = 0; ct < reloc_sections_count ; ++ct) { // elf_section_index is the elf index of the // section to be relocated, and the section number // in the object file which we are creating. // In dwarfgen we do not use this as we do not create // relocation sections. Here it is always zero. Dwarf_Signed elf_section_index = 0; // elf_section_index_link is the elf index of the // section the relocations apply to, such as .debug_info. // An elf index, not dwsectab[] index. Dwarf_Signed elf_section_index_link = 0; // relocation_buffer_count is the number of relocations // of this section. Dwarf_Unsigned relocation_buffer_count = 0; Dwarf_Relocation_Data reld; res = dwarf_get_relocation_info(dbg,&elf_section_index, &elf_section_index_link, &relocation_buffer_count, &reld,&err); // elf_section_index_link // refers to the output section numbers, not to dwsectab. if (res != DW_DLV_OK) { cerr << "dwarfgen: Error getting relocation record " << ct << "." << endl; exit(1); } int dwseclink = FindMySectionNum(elf_section_index_link); ElfSectIndex sitarg = dwsectab[dwseclink].getSectIndex(); string linktarg= dwsectab[dwseclink].name_; long int targsec = sitarg.getSectIndex(); cout << "Relocs for sec=" << ct << " ourlinkto=" << elf_section_index_link << " linktoobjsecnum=" << targsec << " name=" << linktarg << " reloc-count=" << relocation_buffer_count << endl; Elf_Scn *scn = elf_getscn(elf_w,elf_section_index_link); if(!scn) { cerr << "dwarfgen: Unable to elf_getscn # " << elf_section_index_link << endl; exit(1); } for (Dwarf_Unsigned r = 0; r < relocation_buffer_count; ++r) { Dwarf_Relocation_Data rec = reld+r; ElfSymIndex symi(rec->drd_symbol_index); Dwarf_Unsigned newval = FindSymbolValue(symi,irep); char *buf_to_update = findelfbuf(elf_w,scn, rec->drd_offset,rec->drd_length); if(buf_to_update) { if(cmdoptions.showrelocdetails) { cout << "Reloc "<< r << " symindex=" << rec->drd_symbol_index << " targoffset= " << IToHex(rec->drd_offset) << " newval = " << IToHex(newval) << endl; } bitreplace(buf_to_update, newval,sizeof(newval), rec->drd_length); } else { if(cmdoptions.showrelocdetails) { cout << "Reloc "<< r << "does nothing"<= FAILCOUNT ??? */ if (count == FAILCOUNT) { return 0; } count++; return __libc_malloc(len); } dwarfutils-20200114/dwarfgen/general.h000066400000000000000000000050541361531463500175270ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // general.h // The following needed in code using this. #ifndef GENERAL_H #define GENERAL_H #include #include // iomanip for setw etc // Run time flags from command line. extern struct CmdOptions { bool transformHighpcToConst; int defaultInfoStringForm; bool showrelocdetails; bool adddata16; bool addimplicitconst; bool addframeadvanceloc; bool addSUNfuncoffsets; } cmdoptions; template std::string IToHex(T v,unsigned l=0) { if(v == 0) { // For a zero value, ostringstream does not insert 0x. // So we do zeroes here. std::string out = "0x0"; if(l > 3) { out.append(l-3,'0'); } return out; } std::ostringstream s; s.setf(std::ios::hex,std::ios::basefield); s.setf(std::ios::showbase); if (l > 0) { s << std::setw(l); } s << v ; return s.str(); } template std::string BldName(const std::string & prefix, T v) { std::ostringstream s; s << prefix; s << v; return s.str(); } #endif /* GENERAL_H */ dwarfutils-20200114/dwarfgen/irepattrtodbg.cc000066400000000000000000000350331361531463500211220ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // irepattrtodbg.cc #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include // For BldName #include // iomanp for setw etc #include #include #include #include #include // For memset etc #include "general.h" #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "ireptodbg.h" #include "irepattrtodbg.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::list; using std::map; static Dwarf_Error error; static unsigned fakeaddrnum; // We are not going to 'validate' the FORM for this Attribute. // or this Die. We just assume that what we are handed is // what we are to produce. We do test the attribute // at times, partly to ensure we use as many of the dwarf_add_AT* // functions as possible. // Correctness/appropriateness must be evaluated elsewhere. void AddAttrToDie(Dwarf_P_Debug dbg, IRepresentation & Irep, IRCUdata &cu, Dwarf_P_Die outdie, UNUSEDARG IRDie & irdie, IRAttr &irattr) { int attrnum = irattr.getAttrNum(); enum Dwarf_Form_Class formclass = irattr.getFormClass(); // IRForm is an abstract base class. IRForm *form_a = irattr.getFormData(); int res = 0; switch(formclass) { case DW_FORM_CLASS_UNKNOWN: cerr << "ERROR AddAttrToDie: Impossible DW_FORM_CLASS_UNKNOWN, attrnum " <(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_ADDRESS cast fails, attrnum " <getAddress(); string symname = BldName("addrsym",fakeaddrnum++); Dwarf_Addr pcval = addr; ElfSymbols& es = Irep.getElfSymbols(); ElfSymIndex esi = es.addElfSymbol(pcval,symname); Dwarf_Unsigned sym_index = esi.getSymIndex(); // FIXME: we should allow for DW_FORM_indirect here. // Relocation later will fix value. Dwarf_P_Attribute a = 0; res = dwarf_add_AT_targ_address_c(dbg, outdie,attrnum,0,sym_index,&a,&error); if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_targ_address fails, attrnum " <(form_a); // FIXME: Handle form indirect // DW_FORM_block2 // DW_FORM_block // DW_FORM_block4 // DW_FORM_block1 Dwarf_Unsigned block_len = f->getBlockLen(); Dwarf_Small * block_data = f->getBlockBytes(); Dwarf_P_Attribute attrb =0; res = dwarf_add_AT_block_a(dbg,outdie,attrnum, block_data, block_len, &attrb, &error); if (res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_block_a: " " fails," " attrnum " << attrnum << " res "<< res << endl; } } break; case DW_FORM_CLASS_CONSTANT: { IRFormConstant *f = dynamic_cast(form_a); Dwarf_Half formv = f->getFinalForm(); // FIXME: Handle form indirect IRFormConstant::Signedness sn = f->getSignedness(); Dwarf_P_Attribute a = 0; if (formv == DW_FORM_data16) { Dwarf_Form_Data16 val = f->getData16Val(); res = dwarf_add_AT_data16(outdie, attrnum,&val,&a,&error); if (res != DW_DLV_OK) { cerr << "ERROR AddAttrToDie: " "dwarf_add_AT_ data16 class constant fails," " attrnum " << attrnum << " res "<getSignedVal(); res = dwarf_add_AT_implicit_const(outdie,attrnum, sval,&a,&error); if (res != DW_DLV_OK) { cerr << "ERROR AddAttrToDie: " "dwarf_add_AT_implicit_const fails," " attrnum " << attrnum << " res "<getSignedVal(); if (formv == DW_FORM_sdata) { res = dwarf_add_AT_any_value_sleb_a( outdie,attrnum, sval,&a,&error); } else { //cerr << "ERROR how can we know " // "a non-sdata const is signed?, attrnum " << // attrnum <getUnsignedVal(); if (formv == DW_FORM_udata) { res = dwarf_add_AT_any_value_uleb_a( outdie,attrnum, uval_i,&a,&error); } else { res = dwarf_add_AT_unsigned_const_a(dbg, outdie,attrnum, uval_i,&a,&error); } } if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_ class constant fails," << dwarf_errmsg(error) << " attrnum " << attrnum << " Continuing" << endl; } } break; case DW_FORM_CLASS_EXPRLOC: { //FIXME } break; case DW_FORM_CLASS_FLAG: { IRFormFlag *f = dynamic_cast(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_FLAG cast fails, attrnum " <getFlagVal(),&a,&error); if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_flag fails, attrnum " <(form_a); if (!r) { cerr << "ERROR Impossible DW_FORM_CLASS_REFERENCE cast fails, attrnum " <getReferenceType(); switch (reftype) { case IRFormReference::RT_NONE: cerr << "ERROR CLASS REFERENCE unknown reftype " <getTargetInDie(); Dwarf_P_Die targetoutdie = 0; if(targetofref) { targetoutdie = targetofref->getGeneratedDie(); } if(!targetoutdie) { if(!targetofref) { cerr << "ERROR CLASS REFERENCE targetdie of reference unknown" <getSignature(),&a,&error); if( res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_ref_sig8 fails, attrnum " << IToHex(attrnum) << endl; } } } } break; case DW_FORM_CLASS_STRING: { IRFormString *f = dynamic_cast(form_a); if (!f) { cerr << "ERROR Impossible DW_FORM_CLASS_STRING cast fails, attrnum " <(f->getString().c_str()); switch(attrnum) { case DW_AT_name: res = dwarf_add_AT_name_a(outdie,mystr,&a,&error); break; case DW_AT_producer: res = dwarf_add_AT_producer_a(outdie,mystr,&a,&error); break; case DW_AT_comp_dir: res = dwarf_add_AT_comp_dir_a(outdie,mystr,&a,&error); break; default: res = dwarf_add_AT_string_a(dbg,outdie,attrnum,mystr, &a,&error); break; } if(res != DW_DLV_OK) { cerr << "ERROR dwarf_add_AT_string fails, attrnum " <(formclass) <::iterator it = classReferenceFixupList_.begin(); it != classReferenceFixupList_.end(); ++it) { IRDie* d = it->target_; Dwarf_P_Die sourcedie = it->sourcedie_; Dwarf_P_Die targetdie = d->getGeneratedDie(); Dwarf_Error lerror = 0; int res = dwarf_fixup_AT_reference_die(it->dbg_, it->attrnum_,sourcedie,targetdie,&lerror); if(res != DW_DLV_OK) { cerr << "Improper dwarf_fixup_AT_reference_die call" << endl; } } } dwarfutils-20200114/dwarfgen/irepattrtodbg.h000066400000000000000000000032761361531463500207700ustar00rootroot00000000000000#ifndef IREPATTRTODBG_H #define IREPATTRTODBG_H /* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // irepattrtodbg.h void AddAttrToDie(Dwarf_P_Debug dbg, IRepresentation & Irep, IRCUdata &cu, Dwarf_P_Die outdie,IRDie & irdie,IRAttr &irattr); #endif /* IREPATTRTODBG_H */ dwarfutils-20200114/dwarfgen/irepdie.h000066400000000000000000000270351361531463500175360ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepdie.h // // class IRCUdata; class IRDie; class IRAttr { public: IRAttr():attr_(0),finalform_(0),initialform_(0), formclass_(DW_FORM_CLASS_UNKNOWN),formdata_(0) { }; IRAttr(Dwarf_Half attr,Dwarf_Half finalform, Dwarf_Half initialform): attr_(attr),finalform_(finalform),initialform_(initialform), formclass_(DW_FORM_CLASS_UNKNOWN),formdata_(0) { }; IRAttr(const IRAttr &r) { // copy constructor attr_ = r.attr_; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; if(r.formdata_) { formdata_ = r.formdata_->clone(); } else { formdata_ = 0; } }; ~IRAttr() { delete formdata_; }; IRAttr & operator=( const IRAttr &r) { if(this == &r) { return *this; } attr_ = r.attr_; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; if(formdata_) { delete formdata_; formdata_ = r.formdata_->clone(); } else { formdata_ = r.formdata_->clone(); } return *this; } void setBaseData(Dwarf_Half attr, Dwarf_Half finalform, Dwarf_Half initialform){ attr_ = attr; finalform_ = finalform; initialform_ = initialform; }; void setFormClass(enum Dwarf_Form_Class cl) { formclass_ = cl; }; enum Dwarf_Form_Class getFormClass() const {return formclass_; }; void dropFormData() { if(formdata_) {delete formdata_; formdata_ = 0; }; } void setFormData(IRForm *f) { if (formdata_) { delete formdata_; formdata_ = 0; } formdata_ = f; }; Dwarf_Half getFinalForm() const { return initialform_; }; Dwarf_Half getDirectForm() const { return finalform_; }; Dwarf_Half getAttrNum() const { return attr_; }; IRForm * getFormData() { return formdata_;}; private: Dwarf_Half attr_; Dwarf_Half finalform_; // In most cases finalform == initialform form. // Otherwise, initialform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; IRForm *formdata_; }; class IRDie { public: IRDie():tag_(0),globalOffset_(0), cuRelativeOffset_(0), generatedDie_(0) {}; ~IRDie() {}; void addChild(const IRDie & newdie ) { children_.push_back(newdie); }; std::string getName() { std::list::iterator it = attrs_.begin(); for( ; it != attrs_.end() ; ++it) { if (it->getAttrNum() == DW_AT_name) { IRForm *f = it->getFormData(); const IRFormString * isv = dynamic_cast(f); if(isv) { return isv->getString(); } } } return ""; }; std::list & getAttributes() {return attrs_; }; std::list & getChildren() {return children_; }; bool hasNewestChild(IRDie **lastch) { size_t N = children_.size(); if(N < 1) { return false; } *lastch = &children_.back(); return true; }; // lastChild and lastAttr will throw if no entry exists. IRDie &lastChild() { return children_.back(); }; IRAttr &lastAttr() { return attrs_.back(); }; void setBaseData(Dwarf_Half tag,Dwarf_Unsigned goff, Dwarf_Unsigned cuoff) { tag_ = tag; globalOffset_=goff; cuRelativeOffset_ = cuoff; }; Dwarf_Unsigned getGlobalOffset() const { return globalOffset_;}; Dwarf_Unsigned getCURelativeOffset() const { return cuRelativeOffset_;}; void setGeneratedDie(Dwarf_P_Die p_die) { generatedDie_ = p_die;}; Dwarf_P_Die getGeneratedDie() const { return generatedDie_;}; unsigned getTag() {return tag_; } private: // We rely on the IRDie container being one which does not // invalidate pointers with addition/deletion. std::list children_; std::list attrs_; unsigned tag_; // The following are data from input. Dwarf_Unsigned globalOffset_; Dwarf_Unsigned cuRelativeOffset_; // the following is generated during output. Dwarf_P_Die generatedDie_; }; struct OffsetFormEntry { OffsetFormEntry(): off_(0),form_(0){}; OffsetFormEntry(Dwarf_Unsigned o, IRFormReference* f): off_(o),form_(f){}; ~OffsetFormEntry(){}; Dwarf_Unsigned off_; IRFormReference *form_; }; struct ClassReferenceFixupData { ClassReferenceFixupData(): dbg_(0), attrnum_(0), sourcedie_(0), target_(0) {} ~ClassReferenceFixupData(){}; ClassReferenceFixupData( Dwarf_P_Debug dbg, Dwarf_Half attrnum, Dwarf_P_Die sourcedie, IRDie *d): dbg_(dbg), attrnum_(attrnum), sourcedie_(sourcedie), target_(d) {}; Dwarf_P_Debug dbg_; // The source die and attrnum suffice because the definition of // DWARF guarantees only one attribute of any given attribute number // can exist on a given DIE. Dwarf_Half attrnum_; Dwarf_P_Die sourcedie_; IRDie *target_; }; class IRCUdata { public: IRCUdata(): cu_header_length_(0), abbrev_offset_(0), next_cu_header_offset_(0), version_stamp_(0), address_size_(0), length_size_(0), extension_size_(0), has_macrodata_(false), macrodata_offset_(0), has_linedata_(false), linedata_offset_(0), cudie_offset_(0) {}; IRCUdata(Dwarf_Unsigned len,Dwarf_Half version, Dwarf_Unsigned abbrev_offset, Dwarf_Half addr_size, Dwarf_Half length_size, Dwarf_Half extension_size, Dwarf_Unsigned next_cu_header UNUSEDARG): cu_header_length_(len), abbrev_offset_(abbrev_offset), next_cu_header_offset_(addr_size), version_stamp_(version), address_size_(addr_size), length_size_(length_size), extension_size_(extension_size), has_macrodata_(false), macrodata_offset_(0), has_linedata_(false), linedata_offset_(0), cudie_offset_(0) {}; ~IRCUdata() { }; bool hasMacroData(Dwarf_Unsigned *offset_out,Dwarf_Unsigned *cudie_off) { *offset_out = macrodata_offset_; *cudie_off = cudie_offset_; return has_macrodata_; } bool hasLineData(Dwarf_Unsigned *offset_out,Dwarf_Unsigned *cudie_off) { *offset_out = linedata_offset_; *cudie_off = cudie_offset_; return has_linedata_; } void setMacroData(Dwarf_Unsigned offset,Dwarf_Unsigned cudieoff) { has_macrodata_ = true; macrodata_offset_ = offset; cudie_offset_ = cudieoff; }; void setLineData(Dwarf_Unsigned offset,Dwarf_Unsigned cudieoff) { has_linedata_ = true; linedata_offset_ = offset; cudie_offset_ = cudieoff; }; IRDie & baseDie() { return cudie_; }; Dwarf_Half getVersionStamp() { return version_stamp_; }; Dwarf_Half getOffsetSize() { return length_size_; }; Dwarf_Unsigned getCUdieOffset() { return cudie_offset_; }; IRCULineData & getCULines() { return cu_lines_; }; void insertLocalDieOffset(Dwarf_Unsigned localoff,IRDie* dieptr) { cuOffInLocalToIRDie_[localoff] = dieptr; }; void insertLocalReferenceAttrTargetRef(Dwarf_Unsigned localoff, IRFormReference* attrptr) { cuOffInLocalToIRFormRef_.push_back(OffsetFormEntry(localoff, attrptr)); }; IRDie * getLocalDie(Dwarf_Unsigned localoff) { std::map::iterator pos; pos = cuOffInLocalToIRDie_.find(localoff); if(pos != cuOffInLocalToIRDie_.end()) { return pos->second; } return NULL; }; void insertClassReferenceFixupData(ClassReferenceFixupData &c) { classReferenceFixupList_.push_back(c); } void updateClassReferenceTargets(); std::string getCUName() { return cudie_.getName(); }; // Use cuOffInLocalToIRDie_ and // cuOffInLocalToIRAttr_ to update attr targets. void updateReferenceAttrDieTargets() { for(std::list::iterator it = cuOffInLocalToIRFormRef_.begin(); it != cuOffInLocalToIRFormRef_.end(); ++it) { IRFormReference* r = it->form_; IRDie * tdie = getLocalDie(it->off_); if(tdie) { r->setTargetInDie(tdie); } else { // Missing die in r // Should be impossible. } } } private: Dwarf_Unsigned cu_header_length_; Dwarf_Unsigned abbrev_offset_; Dwarf_Unsigned next_cu_header_offset_; Dwarf_Half version_stamp_; Dwarf_Half address_size_; Dwarf_Half length_size_; Dwarf_Half extension_size_; bool has_macrodata_; Dwarf_Unsigned macrodata_offset_; bool has_linedata_; Dwarf_Unsigned linedata_offset_; Dwarf_Unsigned cudie_offset_; IRCULineData cu_lines_; // If true, is 32bit dwarf,else 64bit. Gives the size of a reference. bool dwarf32bit_; IRDie cudie_; // Refers to cu-local offsets in the input CU and which DIE // in the input they target for this CU. // Used to find the target DIE for the IRAttrs // referenced by cuOffInLocalToIRAttr_ std::map cuOffInLocalToIRDie_; // Refers to IRAttrs which make a CU local reference // meaning CLASS_REFERENCE IRFormReference to a cu-local die // Once Input dies read in this and cuOffInLocalToIRDie_ // are used to update the IRAttr itself. std::list cuOffInLocalToIRFormRef_; // The data needed to get the Dwarf_P_Die set for // some class reference instances. std::list classReferenceFixupList_; }; class IRDInfo { public: IRDInfo() {}; ~IRDInfo() {}; IRCUdata &lastCU() { return cudata_.back(); } std::list& getCUData() {return cudata_; }; private: std::list cudata_; }; dwarfutils-20200114/dwarfgen/irepform.h000066400000000000000000000610051361531463500177330ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepform.h // // class IRCUdata; class IRDie; class IRAttr; class IRFormInterface; // An Abstract class. class IRForm { public: //virtual void emitvalue() = 0; //IRForm & operator=(const IRForm &r); virtual IRForm * clone() const =0; virtual ~IRForm() {}; IRForm() {}; virtual enum Dwarf_Form_Class getFormClass() const = 0; private: }; class IRFormUnknown : public IRForm { public: IRFormUnknown(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_UNKNOWN) {} ~IRFormUnknown() {}; IRFormUnknown(IRFormInterface *); IRFormUnknown(const IRFormUnknown &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; } virtual IRFormUnknown * clone() const { return new IRFormUnknown(*this); } IRFormUnknown & operator=(const IRFormUnknown &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; return *this; }; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; }; // An address class entry refers to some part // (normally a loadable) section of the object file. // Not to DWARF info. Typically into .text or .data for example. // We therefore want a section number and offset (generally useless for us) // or preferably an elf symbol as that has a value // and an elf section number. // We often/usually know neither here so we do not even try. // Later we will make one up if we have to. class IRFormAddress : public IRForm { public: IRFormAddress(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_ADDRESS), address_(0) {}; IRFormAddress(IRFormInterface *); ~IRFormAddress() {}; IRFormAddress & operator=(const IRFormAddress &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; address_ = r.address_; return *this; }; IRFormAddress(const IRFormAddress &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; address_ = r.address_; } virtual IRFormAddress * clone() const { return new IRFormAddress(*this); }; void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} Dwarf_Addr getAddress() { return address_;}; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: void setAddress(Dwarf_Addr addr) { address_ = addr; }; Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Addr address_; }; class IRFormBlock : public IRForm { public: IRFormBlock(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_BLOCK), fromloclist_(0),sectionoffset_(0) {} IRFormBlock(IRFormInterface *); ~IRFormBlock() {}; IRFormBlock & operator=(const IRFormBlock &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; blockdata_ = r.blockdata_; fromloclist_ = r.fromloclist_; sectionoffset_ = r.sectionoffset_; return *this; }; IRFormBlock(const IRFormBlock &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; blockdata_ = r.blockdata_; fromloclist_ = r.fromloclist_; sectionoffset_ = r.sectionoffset_; } virtual IRFormBlock * clone() const { return new IRFormBlock(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} Dwarf_Unsigned getBlockLen() {return blockdata_.size();} Dwarf_Small* getBlockBytes() { // Standard guarantees vector content is simply array. return &blockdata_[0]; }; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; void insertBlock(Dwarf_Block *bl) { Dwarf_Small *d = static_cast(bl->bl_data); Dwarf_Unsigned len = bl->bl_len; blockdata_.clear(); blockdata_.insert(blockdata_.end(),d+0,d+len); fromloclist_ = bl->bl_from_loclist; sectionoffset_ = bl->bl_section_offset; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; std::vector blockdata_; Dwarf_Small fromloclist_; Dwarf_Unsigned sectionoffset_; }; class IRFormConstant : public IRForm { public: enum Signedness {SIGN_NOT_SET,SIGN_UNKNOWN,UNSIGNED, SIGNED }; IRFormConstant(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_CONSTANT), signedness_(SIGN_NOT_SET), uval_(0), sval_(0) { memset(&data16_,0,sizeof(data16_)); }; IRFormConstant(IRFormInterface *); ~IRFormConstant() {}; IRFormConstant(Dwarf_Half finalform, Dwarf_Half initialform, enum Dwarf_Form_Class formclass, IRFormConstant::Signedness signedness, Dwarf_Unsigned uval, Dwarf_Signed sval) { finalform_ = finalform; initialform_ = initialform; formclass_ = formclass; signedness_ = signedness; uval_ = uval; sval_ = sval; }; IRFormConstant(Dwarf_Half finalform, Dwarf_Half initialform, enum Dwarf_Form_Class formclass UNUSEDARG, Dwarf_Form_Data16 & data16) { finalform_ = finalform; initialform_ = initialform; formclass_ = DW_FORM_CLASS_CONSTANT; signedness_ = SIGN_UNKNOWN; uval_ = 0; sval_ = 0; data16_ = data16; }; IRFormConstant & operator=(const IRFormConstant &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; signedness_ = r.signedness_; uval_ = r.uval_; sval_ = r.sval_; data16_ = r.data16_; return *this; }; IRFormConstant(const IRFormConstant &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; signedness_ = r.signedness_; uval_ = r.uval_; sval_ = r.sval_; data16_ = r.data16_; } virtual IRFormConstant * clone() const { return new IRFormConstant(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} Dwarf_Form_Class getFormClass() const { return formclass_; }; Signedness getSignedness() const {return signedness_; }; Dwarf_Signed getSignedVal() const {return sval_;}; Dwarf_Unsigned getUnsignedVal() const {return uval_;}; Dwarf_Form_Data16 getData16Val() const {return data16_;}; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; // Starts at SIGN_NOT_SET. // SIGN_UNKNOWN means it was a DW_FORM_data* of some // kind so we do not really know. Signedness signedness_; // Both uval_ and sval_ are always set to the same bits. Dwarf_Unsigned uval_; Dwarf_Signed sval_; Dwarf_Form_Data16 data16_; void setValues16(Dwarf_Form_Data16 *v, enum Signedness s UNUSEDARG) { uval_ = 0; sval_ = 0; data16_ = *v; } void setValues(Dwarf_Signed sval, Dwarf_Unsigned uval, enum Signedness s) { signedness_ = s; uval_ = uval; sval_ = sval; } }; class IRFormExprloc : public IRForm { public: IRFormExprloc(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_EXPRLOC) {}; IRFormExprloc(IRFormInterface *); ~IRFormExprloc() {}; IRFormExprloc & operator=(const IRFormExprloc &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; exprlocdata_ = r.exprlocdata_; return *this; }; IRFormExprloc(const IRFormExprloc &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; exprlocdata_ = r.exprlocdata_; } virtual IRFormExprloc * clone() const { return new IRFormExprloc(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; std::vector exprlocdata_; void insertBlock(Dwarf_Unsigned len, Dwarf_Ptr data) { char *d = static_cast(data); exprlocdata_.clear(); exprlocdata_.insert(exprlocdata_.end(),d+0,d+len); }; }; class IRFormFlag : public IRForm { public: IRFormFlag(): initialform_(0), finalform_(0), formclass_(DW_FORM_CLASS_FLAG), flagval_(0) {}; IRFormFlag(IRFormInterface*); ~IRFormFlag() {}; IRFormFlag & operator=(const IRFormFlag &r) { if(this == &r) return *this; initialform_ = r.initialform_; finalform_ = r.finalform_; formclass_ = r.formclass_; flagval_ = r.flagval_; return *this; }; IRFormFlag(const IRFormFlag &r) { initialform_ = r.initialform_; finalform_ = r.finalform_; formclass_ = r.formclass_; flagval_ = r.flagval_; } virtual IRFormFlag * clone() const { return new IRFormFlag(*this); } enum Dwarf_Form_Class getFormClass() const { return formclass_; }; void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} void setFlagVal(Dwarf_Bool v) { flagval_ = v;} Dwarf_Bool getFlagVal() { return flagval_; } private: Dwarf_Half initialform_; // In most cases initialform_ == finalform_. // Otherwise, initialform == DW_FORM_indirect. Dwarf_Half finalform_; enum Dwarf_Form_Class formclass_; Dwarf_Bool flagval_; }; class IRFormLinePtr : public IRForm { public: IRFormLinePtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_LINEPTR), debug_line_offset_(0) {}; IRFormLinePtr(IRFormInterface *); ~IRFormLinePtr() {}; IRFormLinePtr & operator=(const IRFormLinePtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; debug_line_offset_ = r.debug_line_offset_; return *this; }; IRFormLinePtr(const IRFormLinePtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; debug_line_offset_ = r.debug_line_offset_; } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm(void) {return finalform_; } virtual IRFormLinePtr * clone() const { return new IRFormLinePtr(*this); } enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off debug_line_offset_; void setOffset(Dwarf_Unsigned uval) { debug_line_offset_ = uval; }; }; class IRFormLoclistPtr : public IRForm { public: IRFormLoclistPtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_LOCLISTPTR), loclist_offset_(0) {}; IRFormLoclistPtr(IRFormInterface *); ~IRFormLoclistPtr() {}; IRFormLoclistPtr & operator=(const IRFormLoclistPtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; loclist_offset_ = r.loclist_offset_; return *this; }; IRFormLoclistPtr(const IRFormLoclistPtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; loclist_offset_ = r.loclist_offset_; } virtual IRFormLoclistPtr * clone() const { return new IRFormLoclistPtr(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off loclist_offset_; void setOffset(Dwarf_Unsigned uval) { loclist_offset_ = uval; }; }; class IRFormMacPtr : public IRForm { public: IRFormMacPtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_MACPTR), macro_offset_(0) {}; IRFormMacPtr(IRFormInterface *); ~IRFormMacPtr() {}; IRFormMacPtr & operator=(const IRFormMacPtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; macro_offset_ = r.macro_offset_; return *this; }; IRFormMacPtr(const IRFormMacPtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; macro_offset_ = r.macro_offset_; } virtual IRFormMacPtr * clone() const { return new IRFormMacPtr(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off macro_offset_; void setOffset(Dwarf_Unsigned uval) { macro_offset_ = uval; }; }; class IRFormRangelistPtr : public IRForm { public: IRFormRangelistPtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_RANGELISTPTR), rangelist_offset_(0) {}; IRFormRangelistPtr(IRFormInterface *); ~IRFormRangelistPtr() {}; IRFormRangelistPtr & operator=(const IRFormRangelistPtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; rangelist_offset_ = r.rangelist_offset_; return *this; }; IRFormRangelistPtr(const IRFormRangelistPtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; rangelist_offset_ = r.rangelist_offset_; } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} virtual IRFormRangelistPtr * clone() const { return new IRFormRangelistPtr(*this); } enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off rangelist_offset_; void setOffset(Dwarf_Unsigned uval) { rangelist_offset_ = uval; }; }; class IRFormFramePtr : public IRForm { public: IRFormFramePtr(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_FRAMEPTR), frame_offset_(0) {}; IRFormFramePtr(IRFormInterface *); ~IRFormFramePtr() {}; IRFormFramePtr & operator=(const IRFormFramePtr &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; frame_offset_ = r.frame_offset_; return *this; }; IRFormFramePtr(const IRFormFramePtr &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; frame_offset_ = r.frame_offset_; } virtual IRFormFramePtr * clone() const { return new IRFormFramePtr(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; Dwarf_Off frame_offset_; void setOffset(Dwarf_Unsigned uval) { frame_offset_ = uval; }; }; class IRFormReference : public IRForm { public: IRFormReference(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_REFERENCE), reftype_(RT_NONE), globalOffset_(0),cuRelativeOffset_(0), targetInputDie_(0), target_die_(0) {initSig8();}; IRFormReference(IRFormInterface *); ~IRFormReference() {}; IRFormReference & operator=(const IRFormReference &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; reftype_ = r.reftype_; globalOffset_ = r.globalOffset_; cuRelativeOffset_ = r.cuRelativeOffset_; typeSig8_ = r.typeSig8_; targetInputDie_ = r.targetInputDie_; target_die_ = r.target_die_; return *this; }; IRFormReference(const IRFormReference &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; reftype_ = r.reftype_; globalOffset_ = r.globalOffset_; cuRelativeOffset_ = r.cuRelativeOffset_; typeSig8_ = r.typeSig8_; targetInputDie_ = r.targetInputDie_; target_die_ = r.target_die_; } virtual IRFormReference * clone() const { return new IRFormReference(*this); } void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} void setOffset(Dwarf_Off off) { globalOffset_ = off; reftype_ = RT_GLOBAL;}; void setCUOffset(Dwarf_Off off) { cuRelativeOffset_= off; reftype_ = RT_CUREL;}; void setSignature(Dwarf_Sig8 * sig) { typeSig8_ = *sig; reftype_ = RT_SIG;}; const Dwarf_Sig8 *getSignature() { return &typeSig8_;}; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; enum RefType { RT_NONE,RT_GLOBAL, RT_CUREL,RT_SIG }; enum RefType getReferenceType() { return reftype_;}; Dwarf_P_Die getTargetGenDie() { return target_die_;}; IRDie * getTargetInDie() { return targetInputDie_;}; void setTargetGenDie(Dwarf_P_Die targ) { target_die_ = targ; }; void setTargetInDie(IRDie* targ) { targetInputDie_ = targ; }; private: void initSig8(); Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; enum RefType reftype_; // gobalOffset_ on input target set if and only if RT_GLOBAL Dwarf_Off globalOffset_; // cuRelativeOffset_ on input targetset if and only if RT_CUREL Dwarf_Off cuRelativeOffset_; // typeSig8_ on input target set if and only if RT_SIG Dwarf_Sig8 typeSig8_; // For RT_SIG we do not need extra data. // For RT_CUREL and RT_GLOBAL we do. // For RT_CUREL. Points at the target input DIE // after all input DIEs set up for a CU . IRDie * targetInputDie_; // FIXME Dwarf_P_Die target_die_; //for RT_CUREL, this is known // for sure only after all target DIEs generated! // RT_GLOBAL. FIXME }; class IRFormString: public IRForm { public: IRFormString(): finalform_(0), initialform_(0), formclass_(DW_FORM_CLASS_STRING), strpoffset_(0) {}; ~IRFormString() {}; IRFormString(IRFormInterface *); IRFormString(const IRFormString &r) { finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; formdata_= r.formdata_; strpoffset_= r.strpoffset_; } virtual IRFormString * clone() const { return new IRFormString(*this); } IRFormString & operator=(const IRFormString &r) { if(this == &r) return *this; finalform_ = r.finalform_; initialform_ = r.initialform_; formclass_ = r.formclass_; formdata_ = r.formdata_; strpoffset_ = r.strpoffset_; return *this; }; void setInitialForm(Dwarf_Half v) { initialform_ = v;} void setFinalForm(Dwarf_Half v) { finalform_ = v;} Dwarf_Half getInitialForm() { return initialform_;} Dwarf_Half getFinalForm() {return finalform_;} void setString(const char *s) {formdata_ = s; }; const std::string & getString() const {return formdata_; }; enum Dwarf_Form_Class getFormClass() const { return formclass_; }; private: Dwarf_Half finalform_; // In most cases directform == indirect form. // Otherwise, directform == DW_FORM_indirect. Dwarf_Half initialform_; enum Dwarf_Form_Class formclass_; std::string formdata_; Dwarf_Unsigned strpoffset_; }; // Factory Method. IRForm *formFactory(Dwarf_Debug dbg, Dwarf_Attribute attr, IRCUdata &cudata,IRAttr & irattr); dwarfutils-20200114/dwarfgen/irepframe.h000066400000000000000000000143171361531463500200660ustar00rootroot00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepframe.h // class IRCie { public: IRCie(): cie_byte_length_(0), version_(0), code_alignment_factor_(1), data_alignment_factor_(1), return_address_register_rule_(0) {}; IRCie(Dwarf_Unsigned length, Dwarf_Unsigned version, const std::string &augmentation, Dwarf_Unsigned code_align, Dwarf_Signed data_align, Dwarf_Half return_reg_rule, const void * init_instrs, Dwarf_Unsigned instrs_len): cie_byte_length_(length), version_(version), augmentation_(augmentation), code_alignment_factor_(code_align), data_alignment_factor_(data_align), return_address_register_rule_(return_reg_rule) { const Dwarf_Small *x = reinterpret_cast(init_instrs); for(Dwarf_Unsigned i = 0; i < instrs_len; ++i) { initial_instructions_.push_back(x[i]); } } void insert_fde_index(unsigned i) { fde_index_.push_back(i); }; ~IRCie() {}; void get_basic_cie_data(Dwarf_Unsigned * version, std::string * aug, Dwarf_Unsigned * code_align, Dwarf_Signed * data_align, Dwarf_Half * ret_addr_reg) { *version = version_; *aug = augmentation_; *code_align = code_alignment_factor_; *data_align = data_alignment_factor_; *ret_addr_reg = return_address_register_rule_; } void get_init_instructions(Dwarf_Unsigned *len, void **bytes) { *len = initial_instructions_.size(); *bytes = reinterpret_cast(&initial_instructions_[0]); }; private: // Byte length 0 if not known yet. Dwarf_Unsigned cie_byte_length_; Dwarf_Unsigned version_; std::string augmentation_; Dwarf_Unsigned code_alignment_factor_; Dwarf_Signed data_alignment_factor_; Dwarf_Half return_address_register_rule_; std::vector initial_instructions_; // fde_index is the array of indexes into fdedata_ // that are fdes used by this cie. std::vector fde_index_; }; class IRFde { public: IRFde(): low_pc_(0), func_length_(0), cie_offset_(0), cie_index_(-1), fde_offset_(0) {}; IRFde(Dwarf_Addr low_pc,Dwarf_Unsigned func_length, Dwarf_Ptr fde_bytes, Dwarf_Unsigned fde_length, Dwarf_Off cie_offset,Dwarf_Signed cie_index_in, Dwarf_Off fde_offset): low_pc_(low_pc), func_length_(func_length), cie_offset_(cie_offset), cie_index_(cie_index_in), fde_offset_(fde_offset) { const Dwarf_Small *x = reinterpret_cast(fde_bytes); for(Dwarf_Unsigned i = 0; i < fde_length; ++i) { fde_bytes_.push_back(x[i]); } }; ~IRFde() {}; Dwarf_Unsigned cie_index() { return cie_index_; }; void get_fde_base_data(Dwarf_Addr *lowpc, Dwarf_Unsigned * funclen, Dwarf_Unsigned *cie_index_input) { *lowpc = low_pc_; *funclen = func_length_; *cie_index_input = cie_index_; }; void get_fde_instrs_into_ir(Dwarf_Ptr ip,Dwarf_Unsigned len ) { const Dwarf_Small *x = reinterpret_cast(ip); for(Dwarf_Unsigned i = 0; i < len; ++i) { fde_instrs_.push_back(x[i]); } }; void get_fde_instructions(Dwarf_Unsigned *len, void **bytes) { *len = fde_instrs_.size(); *bytes = reinterpret_cast(&fde_instrs_[0]); }; void fde_instrs () { }; private: Dwarf_Addr low_pc_; Dwarf_Unsigned func_length_; // fde_bytes_ may be empty if content bytes not yet created. std::vector fde_bytes_; // fde_instrs_ is simply a vector of bytes. // it might be good to actually parse the // instructions. std::vector fde_instrs_; // cie_offset may be 0 if not known yet. Dwarf_Off cie_offset_; // cie_index is the index in ciedata_ of // the applicable CIE. Begins with index 0. Dwarf_Signed cie_index_; // fde_offset may be 0 if not yet known. Dwarf_Off fde_offset_; }; class IRFrame { public: IRFrame() {}; ~IRFrame() {}; void insert_cie(IRCie &cie) { ciedata_.push_back(cie); } void insert_fde(IRFde &fdedata) { fdedata_.push_back(fdedata); unsigned findex = fdedata_.size() -1; Dwarf_Signed cindex = fdedata.cie_index(); if( cindex != -1) { IRCie & mycie = ciedata_[cindex]; mycie.insert_fde_index(findex); } } std::vector &get_cie_vec() { return ciedata_; }; std::vector &get_fde_vec() { return fdedata_; }; private: std::vector ciedata_; std::vector fdedata_; }; dwarfutils-20200114/dwarfgen/irepline.h000066400000000000000000000076721361531463500177310ustar00rootroot00000000000000#ifndef IREPLINE_H #define IREPLINE_H /* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepline.h // class IRCULine { public: IRCULine(Dwarf_Addr addr,Dwarf_Bool isset, Dwarf_Unsigned fileno, Dwarf_Unsigned lineno, Dwarf_Unsigned linecol, const std::string & linename, Dwarf_Bool is_stmt, Dwarf_Bool bb, Dwarf_Bool endseq, Dwarf_Bool prol_end, Dwarf_Bool epil_beg, Dwarf_Unsigned isa, Dwarf_Unsigned discrim): address_(addr), isaddrset_(isset), srcfileno_(fileno), lineno_(lineno), linecol_(linecol), linesrc_(linename), is_stmt_(is_stmt), basic_block_(bb), end_sequence_(endseq), prologue_end_(prol_end), epilogue_begin_(epil_beg), isa_(isa), discriminator_(discrim) {}; const std::string &getpath() { return linesrc_; }; Dwarf_Addr getaddr() { return address_;}; bool getaddrset() { return isaddrset_;}; bool getendsequence() { return end_sequence_; }; Dwarf_Unsigned getlineno() { return lineno_; }; Dwarf_Unsigned getlinecol() { return linecol_; }; bool getisstmt() { return is_stmt_; }; bool getisblock() { return basic_block_; }; bool getepiloguebegin() { return epilogue_begin_; }; bool getprologueend() { return prologue_end_; }; Dwarf_Unsigned getisa() { return isa_; }; Dwarf_Unsigned getdiscriminator() { return discriminator_; }; ~IRCULine() {}; private: // Names taken from the DWARF4 std. document, sec 6.2.2. Dwarf_Addr address_; bool isaddrset_; Dwarf_Unsigned srcfileno_; Dwarf_Unsigned lineno_; Dwarf_Signed linecol_; // aka lineoff std::string linesrc_; // Name for the file, constructed by libdwarf. bool is_stmt_; bool basic_block_; bool end_sequence_; bool prologue_end_; bool epilogue_begin_; int isa_; int discriminator_; }; class IRCUSrcfile { public: IRCUSrcfile(std::string file): cusrcfile_(file) {}; ~IRCUSrcfile() {}; std::string &getfilepath() {return cusrcfile_;}; private: std::string cusrcfile_; }; class IRCULineData { public: IRCULineData() {}; ~IRCULineData() {}; std::vector &get_cu_lines() { return culinedata_; }; std::vector &get_cu_srcfiles() { return cusrcfiledata_; }; private: std::vector cusrcfiledata_; std::vector culinedata_; }; #endif // IREPLINE_H dwarfutils-20200114/dwarfgen/irepmacro.h000066400000000000000000000043011361531463500200650ustar00rootroot00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepmacro.h // class IRMacroRecord { public: IRMacroRecord() {}; ~IRMacroRecord() {}; IRMacroRecord(Dwarf_Off cuDieOffset,Dwarf_Off offset,Dwarf_Small type, Dwarf_Signed lineno, Dwarf_Signed lineindex, const std::string ¯o):cuDieOffset_(cuDieOffset), offset_(offset), type_(type),lineno_(lineno),lineindex_(lineindex), macro_(macro) {}; private: Dwarf_Off cuDieOffset_; Dwarf_Off offset_; Dwarf_Small type_; Dwarf_Signed lineno_; Dwarf_Signed lineindex_; std::string macro_; }; class IRMacro { public: IRMacro() {}; ~IRMacro() {}; std::vector &getMacroVec() { return macrorec_; }; private: std::vector macrorec_; }; dwarfutils-20200114/dwarfgen/ireppubnames.h000066400000000000000000000057151361531463500206100ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // ireppubnames.h // // class IRPub{ public: IRPub():dieoffset_(0),cudieoffset_(0) { }; IRPub(const std::string &name, Dwarf_Unsigned dieoffset,Dwarf_Unsigned cudieoffset): name_(name),dieoffset_(dieoffset),cudieoffset_(cudieoffset) { }; IRPub(const IRPub&r) { name_ = r.name_; dieoffset_ = r.dieoffset_; cudieoffset_ = r.cudieoffset_; }; IRPub& operator=( const IRPub&r) { if(this == &r) { return *this; } name_ = r.name_; dieoffset_ = r.dieoffset_; cudieoffset_ = r.cudieoffset_; return *this; }; void setBaseData(const std::string &name, Dwarf_Unsigned dieoffset, Dwarf_Unsigned cudieoffset){ name_ = name; dieoffset_ = dieoffset; cudieoffset_ = cudieoffset; }; const std::string& getName() {return name_;}; Dwarf_Unsigned getDieOffset() {return dieoffset_;}; Dwarf_Unsigned getCUdieOffset() {return cudieoffset_;} private: std::string name_; Dwarf_Unsigned dieoffset_; Dwarf_Unsigned cudieoffset_; }; // For .debug_pubnames and .debug_pubtypes. // By the Dwarf Std sec 6.1.1 "Lookup by Name" // these names and offsets refer to the .debug_info section. class IRPubsData { public: IRPubsData() {}; ~IRPubsData() {}; std::list& getPubnames() {return pubnames_; }; std::list& getPubtypes() {return pubtypes_; }; private: std::list pubnames_; std::list pubtypes_; }; dwarfutils-20200114/dwarfgen/irepresentation.h000066400000000000000000000131141361531463500213210ustar00rootroot00000000000000/* Copyright (C) 2010-2016 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // irepresentation.h // The internal (to dwarfgen) representation of debug information. // All the various components (info, frame, etc) // will be stored here in an internal-to-dwarfgen form. // // #include "irepform.h" #include "irepline.h" #include "irepdie.h" #include "irepmacro.h" #include "irepframe.h" #include "ireppubnames.h" #include "strtabdata.h" // The elf symbols are used to tie relocations to values. // We do relocations ourselves in dwarfgen so the data is not needed // once the dwarf .debug_* sections created in elf. // We don't write the symbols out as an elf section. // The position in the vector of symbols is the 'elf symbol index' // we create. // Symbol 0 is 'no symbol'. // Symbol 1 is .text class ElfSymbol { public: ElfSymbol():symbolValue_(0), nameIndex_(0) {}; ElfSymbol(Dwarf_Unsigned val, const std::string&name, strtabdata&stab): symbolValue_(val),name_(name) { nameIndex_ = stab.addString(name); }; ~ElfSymbol() {}; Dwarf_Unsigned getSymbolValue() const { return symbolValue_;} private: Dwarf_Unsigned symbolValue_; std::string name_; // The offset in the string table. unsigned nameIndex_; }; // It's very easy to confuse the section number in an elf file // with an array index in dwarfgen. // So this class hold an elf section number // and gives those a recognizable type. class ElfSectIndex { public: ElfSectIndex():elfsect_(0) {}; ~ElfSectIndex() {}; ElfSectIndex(unsigned v):elfsect_(v) {}; unsigned getSectIndex() const { return elfsect_; } void setSectIndex(unsigned v) { elfsect_ = v; } private: unsigned elfsect_; }; // It's very easy to confuse the symbol number in an elf file // with a symbol number in dwarfgen. // So this class hold an elf symbol number number // and gives those a recognizable type. class ElfSymIndex { public: ElfSymIndex():elfsym_(0) {}; ~ElfSymIndex() {}; ElfSymIndex(unsigned v):elfsym_(v) {}; unsigned getSymIndex() const { return elfsym_; } void setSymIndex(unsigned v) { elfsym_ = v; } private: unsigned elfsym_; }; class ElfSymbols { public: ElfSymbols() { // The initial symbol is 'no symbol'. std::string emptyname(""); elfSymbols_.push_back(ElfSymbol(0,emptyname,symstrtab_)); // We arbitrarily make this symbol .text now, though // not needed yet. std::string textname(".text"); elfSymbols_.push_back(ElfSymbol(0,textname,symstrtab_)); baseTextAddressSymbol_.setSymIndex(elfSymbols_.size()-1); } ~ElfSymbols() {}; ElfSymIndex getBaseTextSymbol() const {return baseTextAddressSymbol_;}; ElfSymIndex addElfSymbol(Dwarf_Unsigned val, const std::string&name) { elfSymbols_.push_back(ElfSymbol(val,name,symstrtab_)); ElfSymIndex indx(elfSymbols_.size()-1); return indx; }; ElfSymbol & getElfSymbol(ElfSymIndex symi) { size_t i = symi.getSymIndex(); if (i >= elfSymbols_.size()) { std::cerr << "Error, sym index " << i << " to big for symtab size " << elfSymbols_.size() << std::endl; exit(1); } return elfSymbols_[i]; } private: std::vector elfSymbols_; strtabdata symstrtab_; ElfSymIndex baseTextAddressSymbol_; }; class IRepresentation { public: IRepresentation() {}; ~IRepresentation(){}; IRFrame &framedata() { return framedata_; }; IRFrame &ehframedata() { return ehframedata_; }; IRMacro ¯odata() { return macrodata_; }; IRDInfo &infodata() { return debuginfodata_; }; IRPubsData &pubnamedata() {return pubnamedata_;}; ElfSymbols &getElfSymbols() { return elfSymbols_;}; unsigned getBaseTextSymbol() { return elfSymbols_.getBaseTextSymbol().getSymIndex();}; private: // The Elf symbols data to use for relocations ElfSymbols elfSymbols_; IRFrame framedata_; IRFrame ehframedata_; IRMacro macrodata_; IRPubsData pubnamedata_; // .debug_info and its line data are inside debuginfodata_; IRDInfo debuginfodata_; // .debug_types and its line data are in debugtypesdata_. IRDInfo debugtypesdata_; }; dwarfutils-20200114/dwarfgen/ireptodbg.cc000066400000000000000000000764041361531463500202360ustar00rootroot00000000000000/* Copyright (C) 2010-2019 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ireptodbg.cc #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #if HAVE_UNISTD_H #include #endif #ifdef HAVE_STDLIB_H #include /* for exit() */ #endif /* HAVE_STDLIB_H */ #include #include #include #include #include #include // For memset etc #include "strtabdata.h" #include "dwarf.h" #include "libdwarf.h" #include "irepresentation.h" #include "ireptodbg.h" #include "irepattrtodbg.h" #include "general.h" using std::string; using std::cout; using std::cerr; using std::endl; using std::vector; using std::map; using std::list; using std::map; static Dwarf_Error error; typedef std::map pathToUnsignedType; // The first special transformation is converting DW_AT_high_pc // from FORM_addr to an offset and we choose FORM_uleb // The attrs ref passed in is (sometimes) used to generate // a new attrs list for the caller. static void specialAttrTransformations(Dwarf_P_Debug dbg UNUSEDARG, IRepresentation & Irep UNUSEDARG, Dwarf_P_Die ourdie UNUSEDARG, IRDie &inDie, list& attrs, unsigned level UNUSEDARG) { if(!cmdoptions.transformHighpcToConst) { // No transformation of this sort requested. return; } Dwarf_Half dietag = inDie.getTag(); if(dietag != DW_TAG_subprogram) { return; } bool foundhipc= false; bool foundlopc= false; Dwarf_Addr lopcval = 0; Dwarf_Addr hipcval = 0; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); Dwarf_Half attrform = attr.getFinalForm(); Dwarf_Form_Class formclass = attr.getFormClass(); if(attrnum == DW_AT_high_pc) { if (attrform == DW_FORM_udata) { // Already the right form for the test. // Nothing to do. return; } if (formclass != DW_FORM_CLASS_ADDRESS) { return; } IRForm*f = attr.getFormData(); IRFormAddress *f2 = dynamic_cast(f); hipcval = f2->getAddress(); foundhipc = true; continue; } if(attrnum == DW_AT_low_pc) { if (formclass != DW_FORM_CLASS_ADDRESS) { return; } IRForm*f = attr.getFormData(); IRFormAddress *f2 = dynamic_cast(f); lopcval = f2->getAddress(); foundlopc = true; continue; } continue; } if(!foundlopc || !foundhipc) { return; } Dwarf_Addr hipcoffset = hipcval - lopcval; // Now we create a revised attribute. list revisedattrs; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); if(attrnum == DW_AT_high_pc) { // Here we want to create a constant form // to test that a const high_pc works. // This is new in DWARF5. IRAttr attr2(attrnum, DW_FORM_udata, DW_FORM_udata); attr2.setFormClass(DW_FORM_CLASS_CONSTANT); IRFormConstant *f = new IRFormConstant( DW_FORM_udata, DW_FORM_udata, DW_FORM_CLASS_CONSTANT, IRFormConstant::UNSIGNED, hipcoffset, 0); attr2.setFormData(f); revisedattrs.push_back(attr2); // Avoid memoryleak attr.dropFormData(); continue; } revisedattrs.push_back(attr); continue; } attrs = revisedattrs; } /* Create a data16 data item out of nothing... */ static void addData16DataItem(Dwarf_P_Debug dbg UNUSEDARG, IRepresentation & Irep UNUSEDARG, Dwarf_P_Die ourdie UNUSEDARG, IRDie &inDie, IRDie &inParent, list& attrs, unsigned level) { static bool alreadydone = false; if (alreadydone) { return; } if(!cmdoptions.adddata16) { // No transformation of this sort requested. return; } if (level < 2) { return; } Dwarf_Half dietag = inDie.getTag(); Dwarf_Half parenttag = inParent.getTag(); if(dietag != DW_TAG_variable || parenttag != DW_TAG_subprogram) { return; } list revisedattrs; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); if(attrnum == DW_AT_name){ // Avoid memoryleak attr.dropFormData(); continue; } if(attrnum == DW_AT_const_value){ // Avoid memoryleak attr.dropFormData(); continue; } revisedattrs.push_back(attr); } // add two new attrs. Dwarf_Half attrnum = DW_AT_name; const char *attrname("vardata16"); IRAttr attr2(attrnum, DW_FORM_string, DW_FORM_string); attr2.setFormClass(DW_FORM_CLASS_STRING); IRFormString *f = new IRFormString(); f->setInitialForm(DW_FORM_string); f->setFinalForm(DW_FORM_string); f->setString(attrname); attr2.setFormData(f); revisedattrs.push_back(attr2); Dwarf_Form_Data16 data16 = { 0x01,0x08, 0x02,0x07, 0x03,0x06, 0x04,0x05, 0x05,0x04, 0x06,0x03, 0x07,0x02, 0x08,0x01 }; IRAttr attrc(DW_AT_const_value, DW_FORM_data16,DW_FORM_data16); attrc.setFormClass(DW_FORM_CLASS_CONSTANT); IRFormConstant *fc = new IRFormConstant( DW_FORM_data16, DW_FORM_data16, DW_FORM_CLASS_CONSTANT, data16); attrc.setFormData(fc); revisedattrs.push_back(attrc); attrs = revisedattrs; alreadydone = true; } int testvals[3] = { -2018, -2019, -2018 }; const char *testnames[3] = { "myimplicitconst1", "myimplicitconst2newabbrev", "myimplicitconst3share1abbrev" }; static void addSUNfuncoffsets(Dwarf_P_Debug dbg , IRepresentation & Irep UNUSEDARG, UNUSEDARG Dwarf_P_Die ourdie, IRDie &inDie, UNUSEDARG IRDie &inParent, list& attrs, UNUSEDARG unsigned level) { if(!cmdoptions.addSUNfuncoffsets) { // No transformation of this sort requested. return; } Dwarf_Half dietag = inDie.getTag(); if (dietag == DW_TAG_compile_unit) { } if (dietag != DW_TAG_compile_unit) { return; } // add new attr. Dwarf_Half attrnum = DW_AT_SUN_func_offsets; IRFormBlock *f = new IRFormBlock(); Dwarf_Signed signar[5] = {-1,2000,-2500000000ll,60000000000ll,-2}; Dwarf_Unsigned block_len = 0; void *block_ptr; int res = dwarf_compress_integer_block_a(dbg, 5,signar, &block_len,&block_ptr,&error); if (res == DW_DLV_ERROR) { cerr << " FAIL: Unable to generate via " << "dwarf_compress_integer_block_a: err " << dwarf_errmsg(error) << endl; return; } else if (res == DW_DLV_NO_ENTRY) { cerr << " FAIL: NO_ENTRY impossible but got it" << " from dwarf_compress_integer_block_a: err " << endl; return; } f->setInitialForm(DW_FORM_block); f->setFinalForm(DW_FORM_block); Dwarf_Block bl; bl.bl_len = block_len; bl.bl_data = block_ptr; bl.bl_from_loclist = false; bl.bl_section_offset = 0; // FAKE f->insertBlock(&bl); IRAttr attr1(attrnum, DW_FORM_block, DW_FORM_block); attr1.setFormClass(DW_FORM_CLASS_BLOCK); attr1.setFormData(f); attrs.push_back(attr1); } static void addImplicitConstItem(Dwarf_P_Debug dbg UNUSEDARG, IRepresentation & Irep UNUSEDARG, Dwarf_P_Die ourdie UNUSEDARG, IRDie &inDie, IRDie &inParent, list& attrs, unsigned level) { static int alreadydone = 0; if (alreadydone > 2) { // The limit here MUST be below the size of // testvals[] and testnames[] above. // Some abbrevs should match // if the test case is right. Others not. return; } if(!cmdoptions.addimplicitconst) { // No transformation of this sort requested. return; } if (level < 2) { return; } Dwarf_Half dietag = inDie.getTag(); Dwarf_Half parenttag = inParent.getTag(); if(dietag != DW_TAG_variable || parenttag != DW_TAG_subprogram) { return; } list revisedattrs; for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; Dwarf_Half attrnum = attr.getAttrNum(); if(attrnum == DW_AT_name){ // Avoid memory leak. attr.dropFormData(); continue; } if(attrnum == DW_AT_const_value){ // Avoid memory leak. attr.dropFormData(); continue; } revisedattrs.push_back(attr); } // add two new attrs. Dwarf_Half attrnum = DW_AT_name; const char *attrname(testnames[alreadydone]); IRAttr attr2(attrnum, DW_FORM_string, DW_FORM_string); attr2.setFormClass(DW_FORM_CLASS_STRING); IRFormString *f = new IRFormString(); f->setInitialForm(DW_FORM_implicit_const); f->setFinalForm(DW_FORM_implicit_const); f->setString(attrname); attr2.setFormData(f); revisedattrs.push_back(attr2); Dwarf_Signed myconstval = testvals[alreadydone]; IRAttr attrc(DW_AT_const_value, DW_FORM_implicit_const,DW_FORM_implicit_const); attrc.setFormClass(DW_FORM_CLASS_CONSTANT); IRFormConstant *fc = new IRFormConstant( DW_FORM_implicit_const, DW_FORM_implicit_const, DW_FORM_CLASS_CONSTANT, IRFormConstant::SIGNED, 0,myconstval); attrc.setFormData(fc); revisedattrs.push_back(attrc); attrs = revisedattrs; ++alreadydone; } // Here we emit all the DIEs for a single Die and // its children. When level == 0 the inDie is // the CU die. static Dwarf_P_Die HandleOneDieAndChildren(Dwarf_P_Debug dbg, IRepresentation &Irep, IRCUdata &cu, IRDie &inDie, IRDie &inParent, unsigned level) { list& children = inDie.getChildren(); // We create our target DIE first so we can link // children to it, but add no content yet. Dwarf_P_Die gendie = 0; int res =dwarf_new_die_a(dbg,inDie.getTag(),NULL,NULL, NULL,NULL,&gendie,&error); if (res != DW_DLV_OK) { cerr << "Die creation failure. "<< endl; exit(1); } inDie.setGeneratedDie(gendie); Dwarf_P_Die lastch = 0; for ( list::iterator it = children.begin(); it != children.end(); it++) { IRDie & ch = *it; Dwarf_P_Die chp = HandleOneDieAndChildren(dbg,Irep, cu,ch,inDie,level+1); int res2 = 0; if(lastch) { // Link to right of earlier sibling. res2 = dwarf_die_link_a(chp,NULL,NULL,lastch,NULL,&error); } else { // Link as first child. res2 = dwarf_die_link_a(chp,gendie,NULL,NULL, NULL,&error); } if (res2 != DW_DLV_OK) { cerr << "Die link failure. "<< endl; exit(1); } lastch = chp; } { list& attrs = inDie.getAttributes(); // Now any special transformations to the attrs list. specialAttrTransformations(dbg,Irep,gendie,inDie,attrs,level); addData16DataItem(dbg,Irep,gendie,inDie,inParent,attrs,level); addImplicitConstItem(dbg,Irep,gendie,inDie,inParent,attrs,level); addSUNfuncoffsets(dbg,Irep,gendie,inDie,inParent,attrs,level); // Now we add attributes (content), if any, to the // output die 'gendie'. for (list::iterator it = attrs.begin(); it != attrs.end(); it++) { IRAttr & attr = *it; AddAttrToDie(dbg,Irep,cu,gendie,inDie,attr); } } return gendie; } static void HandleLineData(Dwarf_P_Debug dbg, IRepresentation & Irep UNUSEDARG, IRCUdata&cu) { Dwarf_Error lerror = 0; // We refer to files by fileno, this builds an index. pathToUnsignedType pathmap; IRCULineData& ld = cu.getCULines(); std::vector & cu_lines = ld.get_cu_lines(); //std::vector &cu_srcfiles = ld.get_cu_srcfiles(); if(cu_lines.empty()) { // No lines data to emit, do nothing. return; } // To start with, we are doing a trivial generation here. // To be refined 'soon'. FIXME // Initially we don't worry about dwarf_add_directory_decl(). bool firstline = true; bool addrsetincu = false; for(unsigned k = 0; k < cu_lines.size(); ++k) { IRCULine &li = cu_lines[k]; const std::string&path = li.getpath(); unsigned pathindex = 0; pathToUnsignedType::const_iterator it = pathmap.find(path); if(it == pathmap.end()) { Dwarf_Error l2error = 0; Dwarf_Unsigned idx = 0; int res = dwarf_add_file_decl_a( dbg,const_cast(path.c_str()), 0,0,0,&idx,&l2error); if(res != DW_DLV_OK) { cerr << "Error from dwarf_add_file_decl() on " << path << endl; exit(1); } pathindex = idx; pathmap[path] = pathindex; } else { pathindex = it->second; } Dwarf_Addr a = li.getaddr(); bool addrsetinline = li.getaddrset(); bool endsequence = li.getendsequence(); if(firstline || !addrsetincu) { // We fake an elf sym index here. Dwarf_Unsigned elfsymidx = 0; if(firstline && !addrsetinline) { cerr << "Error building line, first entry not addr set" << endl; exit(1); } int res = dwarf_lne_set_address_a(dbg, a,elfsymidx,&lerror); if(res != DW_DLV_OK) { cerr << "Error building line, dwarf_lne_set_address" << endl; exit(1); } addrsetincu = true; firstline = false; } else if( endsequence) { int res = dwarf_lne_end_sequence_a(dbg, a,&lerror); if(res != DW_DLV_OK) { cerr << "Error building line, dwarf_lne_end_sequence" << endl; exit(1); } addrsetincu = false; continue; } Dwarf_Signed linecol = li.getlinecol(); // It's really the code address or (when in a proper compiler) // a section or function offset. // libdwarf subtracts the code_offset from the address passed // this way or from dwarf_lne_set_address() and writes a small // offset in a DW_LNS_advance_pc instruction. Dwarf_Addr code_offset = a; Dwarf_Unsigned lineno = li.getlineno(); Dwarf_Bool isstmt = li.getisstmt()?1:0; Dwarf_Bool isblock = li.getisblock()?1:0; Dwarf_Bool isepiloguebegin = li.getepiloguebegin()?1:0; Dwarf_Bool isprologueend = li.getprologueend()?1:0; Dwarf_Unsigned isa = li.getisa(); Dwarf_Unsigned discriminator = li.getdiscriminator(); int lires = dwarf_add_line_entry_c(dbg, pathindex, code_offset, lineno, linecol, isstmt, isblock, isepiloguebegin, isprologueend, isa, discriminator, &lerror); if(lires != DW_DLV_OK) { cerr << "Error building line, dwarf_add_line_entry" << endl; exit(1); } } if(addrsetincu) { cerr << "CU Lines did not end in an end_sequence!" << endl; } } // This emits the DIEs for a single CU and possibly line data // associated with the CU. // The DIEs form a graph (which can be created and linked together // in any order) and which is emitted in tree preorder as // defined by the DWARF spec. // static void emitOneCU( Dwarf_P_Debug dbg,IRepresentation & Irep, IRCUdata&cu, int cu_of_input_we_output UNUSEDARG) { // We descend the the tree, creating DIEs and linking // them in as we return back up the tree of recursing // on IRDie children. Dwarf_Error lerror; IRDie & basedie = cu.baseDie(); Dwarf_P_Die cudie = HandleOneDieAndChildren(dbg,Irep, cu,basedie,basedie,0); // Add base die to debug, this is the CU die. // This is not a good design as DWARF3/4 have // requirements of multiple CUs in a single creation, // which cannot be handled yet. Dwarf_Unsigned res = dwarf_add_die_to_debug(dbg,cudie,&lerror); if(res != DW_DLV_OK) { cerr << "Unable to add_die_to_debug " << endl; exit(1); } // Does fixup of IRFormReference targets. cu.updateClassReferenceTargets(); HandleLineData(dbg,Irep,cu); } // .debug_info creation. // Also creates .debug_line static void transform_debug_info(Dwarf_P_Debug dbg, IRepresentation & irep,int cu_of_input_we_output) { int cu_number = 0; std::list &culist = irep.infodata().getCUData(); // For now, just one CU we write (as spoken by Yoda). for ( list::iterator it = culist.begin(); it != culist.end(); it++,cu_number++) { if(cu_number == cu_of_input_we_output) { IRCUdata & primecu = *it; emitOneCU(dbg,irep,primecu,cu_of_input_we_output); break; } } } static void transform_cie_fde(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output UNUSEDARG) { Dwarf_Error err = 0; std::vector &cie_vec = Irep.framedata().get_cie_vec(); std::vector &fde_vec = Irep.framedata().get_fde_vec(); Dwarf_Unsigned cievecsize = cie_vec.size(); if (!cievecsize) { // If debug_frame missing try for eh_frame. // Just do one section, not both, for now. cie_vec = Irep.ehframedata().get_cie_vec(); fde_vec = Irep.ehframedata().get_fde_vec(); cievecsize = cie_vec.size(); } for(Dwarf_Unsigned i = 0; i < cievecsize ; ++i) { IRCie &ciein = cie_vec[i]; Dwarf_Unsigned version = 0; string aug; Dwarf_Unsigned code_align = 0; Dwarf_Signed data_align = 0; Dwarf_Half ret_addr_reg = -1; void * bytes = 0; Dwarf_Unsigned bytes_len = 0; Dwarf_Unsigned out_cie_index = 0; ciein.get_basic_cie_data(&version, &aug, &code_align, &data_align, &ret_addr_reg); ciein.get_init_instructions(&bytes_len,&bytes); // version implied: FIXME, need to let user code set output // frame version. char *str = const_cast(aug.c_str()); int res = dwarf_add_frame_cie_a(dbg, str, code_align, data_align, ret_addr_reg, bytes,bytes_len, &out_cie_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating cie from input cie " << i << endl; exit(1); } vector fdeindex; // This inner loop is C*F so a bit slow. for(size_t j = 0; j < fde_vec.size(); ++j) { IRFde &fdein = fde_vec[j]; Dwarf_Unsigned code_len = 0; Dwarf_Addr code_virt_addr = 0; Dwarf_Unsigned cie_input_index = 0; fdein.get_fde_base_data(&code_virt_addr, &code_len, &cie_input_index); if(cie_input_index != i) { // Wrong cie, ignore this fde right now. continue; } Dwarf_P_Fde fdeout = 0; res = dwarf_new_fde_a(dbg,&fdeout,&err); if(res != DW_DLV_OK) { cerr << "Error creating new fde " << j << endl; exit(1); } Dwarf_Unsigned ilen = 0; void *instrs = 0; fdein.get_fde_instructions(&ilen, &instrs); res = dwarf_insert_fde_inst_bytes(dbg, fdeout, ilen, instrs,&err); if(res != DW_DLV_OK) { cerr << "Error inserting frame instr block " << j << endl; exit(1); } Dwarf_P_Die irix_die = 0; Dwarf_Signed irix_table_offset = 0; Dwarf_Unsigned irix_excep_sym = 0; Dwarf_Unsigned code_virt_addr_symidx = Irep.getBaseTextSymbol(); Dwarf_Unsigned fde_index = 0; Dwarf_Unsigned end_symbol_index = 0; Dwarf_Unsigned offset_from_end_symbol = 0; res = dwarf_add_frame_info_c( dbg, fdeout,irix_die, out_cie_index, code_virt_addr, code_len, code_virt_addr_symidx, end_symbol_index, offset_from_end_symbol, irix_table_offset,irix_excep_sym, &fde_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating new fde " << j << endl; exit(1); } } } if (cmdoptions.addframeadvanceloc) { // Add a whole new fde, cie, and some instructions Dwarf_Unsigned code_align = 1; Dwarf_Signed data_align = 1; Dwarf_Half ret_addr_reg = 2; // fake, of course. void * bytes = 0; Dwarf_Unsigned bytes_len = 0; Dwarf_Unsigned out_cie_index = 0; const char *augstr = ""; int res = dwarf_add_frame_cie_a(dbg, (char *)augstr, code_align, data_align, ret_addr_reg, bytes,bytes_len, &out_cie_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating made-up addframeadvanceloc cie " << endl; exit(1); } Dwarf_P_Fde fdeout = 0; res = dwarf_new_fde_a(dbg,&fdeout,&err); if(res != DW_DLV_OK) { cerr << "Error creating addframeadvance fde " << endl; exit(1); } // These lead to a set of adv_loc ops values in the output // for the fde which looks odd in -f // output (-vvv -f makes more sense), might be // better to have some additional frame instrs in there // so plain -f looks more sensible. std::list adval; adval.push_back(48); adval.push_back(64); adval.push_back(17219); adval.push_back(4408131); adval.push_back(18308350787ull); // 0x30 0x40 0x4343 0x434343 0x434343434 unsigned i = 3; for( list::iterator it = adval.begin(); it != adval.end();it++ , ++i ) { Dwarf_Unsigned v = *it; res = dwarf_add_fde_inst_a(fdeout, DW_CFA_advance_loc,v,0,&err); if (res != DW_DLV_OK) { cerr << "Error adding advance_loc" << v << endl; exit(1); } res = dwarf_add_fde_inst_a(fdeout, DW_CFA_same_value,i,0,&err); if (res != DW_DLV_OK) { cerr << "Error adding dummy same_value op" << v << endl; exit(1); } } // We increase code len to account for the // big advance_loc values inserted above. Dwarf_P_Die irix_die = 0; Dwarf_Signed irix_table_offset = 0; Dwarf_Unsigned irix_excep_sym = 0; Dwarf_Unsigned code_virt_addr_symidx = Irep.getBaseTextSymbol(); Dwarf_Unsigned fde_index = 0; Dwarf_Unsigned end_symbol_index = 0; Dwarf_Unsigned offset_from_end_symbol = 0; Dwarf_Addr code_virt_addr = 0; Dwarf_Addr code_len = 0x444343434; res = dwarf_add_frame_info_c( dbg, fdeout,irix_die, out_cie_index, code_virt_addr, code_len, code_virt_addr_symidx, end_symbol_index, offset_from_end_symbol, irix_table_offset,irix_excep_sym, &fde_index, &err); if(res != DW_DLV_OK) { cerr << "Error creating advance_loc fde " << endl; exit(1); } } } static void transform_macro_info(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output UNUSEDARG) { IRMacro ¯odata = Irep.macrodata(); std::vector ¯ov = macrodata.getMacroVec(); for(size_t m = 0; m < macrov.size() ; m++ ) { // FIXME: we need to coordinate with generated // CUs . cout << "FIXME: macros not really output yet " << m << " " << macrov.size() << endl; } Dwarf_Unsigned reloc_count = 0; int drd_version = 0; int res = dwarf_get_relocation_info_count(dbg,&reloc_count, &drd_version,&error); if( res != DW_DLV_OK) { cerr << "Error getting relocation info count." << endl; exit(1); } for( Dwarf_Unsigned ct = 0; ct < reloc_count ; ++ct) { } } // Starting at a Die, look through its children // in its input to find which one we have by // comparing the input-die global offset. static Dwarf_P_Die findTargetDieByOffset(IRDie& indie, Dwarf_Unsigned targetglobaloff) { Dwarf_Unsigned globoff = indie.getGlobalOffset(); if(globoff == targetglobaloff) { return indie.getGeneratedDie(); } std::list dielist = indie.getChildren(); for ( list::iterator it = dielist.begin(); it != dielist.end(); it++) { IRDie &ldie = *it; Dwarf_P_Die foundDie = findTargetDieByOffset(ldie, targetglobaloff); if(foundDie) { return foundDie; } } return NULL; } // If the pubnames/pubtypes entry is in the // cu we are emitting, find the generated output // Dwarf_P_Die in that CU // and attach the pubname/type entry to it. static void transform_debug_pubnames_types_inner(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output UNUSEDARG, IRCUdata&cu) { // First, get the target CU. */ Dwarf_Unsigned targetcuoff= cu.getCUdieOffset(); IRDie &basedie = cu.baseDie(); IRPubsData& pubs = Irep.pubnamedata(); std::list &nameslist = pubs.getPubnames(); if(!nameslist.empty()) { for ( list::iterator it = nameslist.begin(); it != nameslist.end(); it++) { IRPub &pub = *it; Dwarf_Unsigned pubcuoff= pub.getCUdieOffset(); Dwarf_Unsigned ourdieoff= pub.getDieOffset(); if (pubcuoff != targetcuoff) { continue; } Dwarf_P_Die targdie = findTargetDieByOffset(basedie, ourdieoff); if(targdie) { // Ugly. Old mistake in libdwarf declaration. char *mystr = const_cast(pub.getName().c_str()); Dwarf_Unsigned res = dwarf_add_pubname( dbg,targdie, mystr, &error); if(!res) { cerr << "Failed to add pubname entry for offset" << ourdieoff << "in CU at offset " << pubcuoff << endl; exit(1); } } else { cerr << "Did not find target pubname P_Die for offset " << ourdieoff << "in CU at offset " << pubcuoff << endl; } } } std::list &typeslist = pubs.getPubtypes(); if(!typeslist.empty()) { for ( list::iterator it = typeslist.begin(); it != typeslist.end(); it++) { IRPub &pub = *it; Dwarf_Unsigned pubcuoff= pub.getCUdieOffset(); Dwarf_Unsigned ourdieoff= pub.getDieOffset(); if (pubcuoff != targetcuoff) { continue; } Dwarf_P_Die targdie = findTargetDieByOffset(basedie, ourdieoff); if(targdie) { // Ugly. Old mistake in libdwarf declaration. char *mystr = const_cast(pub.getName().c_str()); Dwarf_Unsigned res = dwarf_add_pubtype( dbg,targdie, mystr, &error); if(!res) { cerr << "Failed to add pubtype entry for offset" << ourdieoff << "in CU at offset " << pubcuoff << endl; exit(1); } } else { cerr << "Did not find target pubtype P_Die for offset " << ourdieoff << "in CU at offset " << pubcuoff << endl; } } } } // This looks for pubnames/pubtypes // to generate based on an object file input. static void transform_debug_pubnames_types(Dwarf_P_Debug dbg, IRepresentation & Irep,int cu_of_input_we_output) { int cu_number = 0; std::list &culist = Irep.infodata().getCUData(); // For now, just one CU we write (as spoken by Yoda). for ( list::iterator it = culist.begin(); it != culist.end(); it++,cu_number++) { if(cu_number == cu_of_input_we_output) { IRCUdata & primecu = *it; transform_debug_pubnames_types_inner( dbg,Irep,cu_of_input_we_output,primecu); break; } } } void transform_irep_to_dbg(Dwarf_P_Debug dbg, IRepresentation & Irep,int cu_of_input_we_output) { transform_debug_info(dbg,Irep,cu_of_input_we_output); transform_cie_fde(dbg,Irep,cu_of_input_we_output); transform_macro_info(dbg,Irep,cu_of_input_we_output); transform_debug_pubnames_types(dbg,Irep,cu_of_input_we_output); } dwarfutils-20200114/dwarfgen/ireptodbg.h000066400000000000000000000031151361531463500200650ustar00rootroot00000000000000/* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // ireptodbg.h void transform_irep_to_dbg(Dwarf_P_Debug dbg, IRepresentation & Irep, int cu_of_input_we_output); dwarfutils-20200114/dwarfgen/strtabdata.h000066400000000000000000000057511361531463500202470ustar00rootroot00000000000000#ifndef STRTABDATA_H #define STRTABDATA_H /* Copyright (C) 2010-2013 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the example nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // strtabdata.h // Creates a string table in a way consistent with // elf string tables. The zero index is a null byte always. class strtabdata { public: strtabdata(): data_(new char[1000]), datalen_(1000), nexttouse_(0) { data_[0] = 0; nexttouse_ = 1;}; ~strtabdata() { delete[]data_; }; unsigned addString(const std::string & newstr) { // The 1 is for the terminating null byte. unsigned nsz = newstr.size() +1; unsigned needed = nexttouse_ + nsz; if (needed >= datalen_) { unsigned baseincr = nsz; unsigned altincr = datalen_*2; if(altincr> baseincr) { baseincr = altincr; } unsigned newsize = datalen_ + baseincr; char *newdata = new char [newsize]; memcpy(newdata, data_, nexttouse_); delete [] data_; data_ = newdata; datalen_ = newsize; } memcpy(data_ + nexttouse_, newstr.c_str(),nsz); unsigned newstrindex = nexttouse_; nexttouse_ += nsz; return newstrindex; }; void *exposedata() {return (void *)data_;}; unsigned exposelen() const {return nexttouse_;}; private: char * data_; // datalen_ is the size in bytes pointed to by data_ . unsigned datalen_; // nexttouse_ is the index of the next (unused) byte in // data_ , so it is also the amount of space in data_ that // is in use. unsigned nexttouse_; }; #endif /* STRTABDATA_H */ dwarfutils-20200114/install-sh000077500000000000000000000354631361531463500161570ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # $RANDOM is not portable (e.g. dash); use it when possible to # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so # create the $tmpdir first (and fail if unsuccessful) to make sure # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dwarfutils-20200114/libdwarf/000077500000000000000000000000001361531463500157325ustar00rootroot00000000000000dwarfutils-20200114/libdwarf/CHANGES000066400000000000000000000074761361531463500167430ustar00rootroot00000000000000 ------------------------------------------------------------- April 14, 2000 davea@sgi.com Corrected minor bugs in production of 32bit dwarf with 64 bit pointers. Fixed omissions in legal DIE children of a DIE. Make small changes in description of regster output in frame information access. ------------------------------------------------------------- Mar 7, 2000 davea@sgi.com Corrected line table reading so it will handle reading an object with a diffent number of standard op codes than at libdwarf compile time. This was possible all along, but libdwarf did not do it right. ------------------------------------------------------------- Dec 8, 1999 davea@sgi.com Changed nearly all files. Adding the capability to read and produce the new, accepted by committee, but not released-publically 64bit extension proposal dwarf data. This allows dwarf compilation units with 64bit section offsets and 32bit sections offsets to be mixed. So that offsets can grow very large with 64-bit pointer applications (though 64bit pointers and 64bit offsets are not the same notion). In addition, removed all the contents (or nearly all) of the dwarf_funcs.c dwarf_weaks.c dwarf_vars.c, and dwarf_types.c, as the data format is identical to dwarf globals (pubnames) and there is no need to duplicate all that code. All these sections whose contents were gutted are things that are formatted exactly like pubnames, and all are sgi extensions. Now the implementation uses pubnames code (dwarf_global.c) to do the work for all the pubnames-like sections. The (minor, IMO) difference is that in case of an incorrect dwarf file (leading to libdwarf being unable to process something in one of the sgi-specific pubnames-like sections) the dwarf error string may reference pubnames when weaks, static functions, static variables, or global typenames are actually the problem. This is fixable, however the price would appear to be that even globals would need to call a helper function (to pass in the correct error return). Right now the dwarf_weaks.c calls the dwarf_global.c function, for example, with no extra arguments indicating the true section involved. (Other approaches keeping the original error codes exist. Producing the code uniquely via macros seems unappealing. Inline functions would be ok though. This version does not inline the functions we are talking about, such as dwarf_global_name_offsets() when called from dwarf_type_name_offsets().) Since these extra sections are SGI only and only really used by SGI's workshop product, and the performance hit is small, the extra function calls in reading each seem acceptable. ------------------------------------------------------------- Sep 29,1999 davea@sgi.com Changed many files, so that it is easy to switch from 32bit-offset-only (like cygnus and dwarf2 v 2.0.0) to sgi/mips 64 bit dwarf. See NEWS for more info on 32bit-offset. ------------------------------------------------------------- Since Oct 95 and before May, 1996 Added the function dwarf_get_cie_of_fde() which makes it possible to remember a single fde/cie set out of a block usefully. Enhanced doc of dwarf_bitoffset() Added new function dwarf_global_formref() so all reference forms can be retrieved. Fixed bug in retrieving array bounds: was failing to sign extend formsdata. Added function dwarf_get_fde_info_for_all_regs(), which makes retrieval of the complete set of registers (as needed by debuggers and exception handlers) effectively N times faster than getting them one a time where N is the number of registers. Added support for exception table handling (really just support for a reference to an exception table for c++ exceptions). Fixed a bug where useless extra space (several megabytes) were malloc'ed for the abbreviations table by the libdwarf consumer code. davea@sgi.com ------------------------------------------------------------- dwarfutils-20200114/libdwarf/CMakeLists.txt000066400000000000000000000104051361531463500204720ustar00rootroot00000000000000set_source_group(SOURCES "Source Files" dwarf_abbrev.c dwarf_alloc.c dwarf_arange.c dwarf_debuglink.c dwarf_die_deliv.c dwarf_dnames.c dwarf_dsc.c dwarf_elf_access.c dwarf_elf_load_headers.c dwarf_elfread.c dwarf_elf_rel_detector.c dwarf_error.c dwarf_form.c dwarf_frame.c dwarf_frame2.c dwarf_funcs.c dwarf_gdbindex.c dwarf_global.c dwarf_groups.c dwarf_harmless.c dwarf_generic_init.c dwarf_init_finish.c dwarf_leb.c dwarf_line.c dwarf_loc.c dwarf_machoread.c dwarf_macro.c dwarf_macro5.c dwarf_names.c dwarf_object_read_common.c dwarf_object_detector.c dwarf_original_elf_init.c dwarf_peread.c dwarf_pubtypes.c dwarf_query.c dwarf_ranges.c dwarfstring.h dwarfstring.c dwarf_stringsection.c dwarf_tied.c dwarf_str_offsets.c dwarf_tsearchhash.c dwarf_types.c dwarf_util.c dwarf_vars.c dwarf_weaks.c dwarf_xu_index.c dwarf_print_lines.c malloc_check.c pro_alloc.c pro_arange.c pro_die.c pro_dnames.c pro_encode_nm.c pro_error.c pro_expr.c pro_finish.c pro_forms.c pro_funcs.c pro_frame.c pro_init.c pro_line.c pro_reloc.c pro_reloc_stream.c pro_reloc_symbolic.c pro_pubnames.c pro_section.c pro_types.c pro_vars.c pro_macinfo.c pro_weaks.c) set_source_group(HEADERS "Header Files" dwarf.h dwarf_abbrev.h dwarf_alloc.h dwarf_arange.h dwarf_base_types.h dwarf_debuglink.h dwarf_die_deliv.h dwarf_dnames.h dwarf_dsc.h dwarf_elf_access.h dwarf_elf_defines.h dwarf_elfread.h dwarf_elf_rel_detector.h dwarf_elf_reloc_386.h dwarf_elf_reloc_aarch64.h dwarf_elf_reloc_arm.h dwarf_elf_reloc_mips.h dwarf_elf_reloc_ppc64.h dwarf_elf_reloc_ppc.h dwarf_elf_reloc_sparc.h dwarf_elf_reloc_x86_64.h dwarf_elfstructs.h dwarf_error.h dwarf_frame.h dwarf_funcs.h dwarf_gdbindex.h dwarf_global.h dwarf_harmless.h dwarf_incl.h dwarf_line.h dwarf_loc.h dwarf_machoread.h dwarf_macro.h dwarf_macro5.h dwarf_names.h dwarf_object_detector.h dwarf_opaque.h dwarf_pe_descr.h dwarf_peread.h dwarf_reading.h dwarf_reloc_arm.h dwarf_reloc_mips.h dwarf_reloc_ppc.h dwarf_reloc_ppc64.h dwarf_reloc_x86_64.h dwarf_tied_decls.h dwarf_tsearch.h dwarf_str_offsets.h dwarf_types.h dwarf_util.h dwarf_vars.h dwarf_weaks.h dwarf_xu_index.h libdwarfdefs.h dwarf_macho_loader.h malloc_check.h memcpy_swap.h pro_alloc.h pro_arange.h pro_die.h pro_encode_nm.h pro_error.h pro_expr.h pro_frame.h pro_incl.h pro_line.h pro_log_extra_flag_strings.c pro_macinfo.h pro_opaque.h pro_reloc.h pro_reloc_stream.h pro_reloc_symbolic.h pro_section.h pro_types.h pro_util.h) set_source_group(CONFIGURATION_FILES "Configuration Files" ${CMAKE_SOURCE_DIR}/config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) list(LENGTH DWARF_TARGETS targetCount) math(EXPR targetCount "${targetCount} - 1") 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}) set_folder(${target} libdwarf) target_include_directories(${target} PUBLIC ${LIBELF_INCLUDE_DIRS}) target_compile_options(${target} PRIVATE ${DW_FWALL}) msvc_posix(${target}) target_link_libraries(${target} PUBLIC ${LIBELF_LIBRARIES}) set_target_properties(${target} PROPERTIES OUTPUT_NAME dwarf) set(SUFFIX $<$:64>) set(LIBDIR lib${SUFFIX}) set(BINDIR bin${SUFFIX}) install(TARGETS ${target} RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR} ARCHIVE DESTINATION ${LIBDIR}) endforeach() if(UNIX AND BUILD_SHARED) target_link_libraries(dwarf-shared PUBLIC z) endif() if (DO_TESTING) set_source_group(TESTLEB "Source Files" dwarf_leb_test.c dwarf_leb.c pro_encode_nm.c ) add_executable(selfleb ${TESTLEB}) target_compile_options(selfleb PRIVATE ${DW_FWALL}) add_test(NAME selfleb COMMAND selfleb) endif() if (DO_TESTING) set_source_group(TESTTIED "Source Files" dwarf_tied_test.c dwarf_tied.c dwarf_tsearchhash.c ) add_executable(selftied ${TESTTIED}) target_compile_options(selftied PRIVATE ${DW_FWALL}) add_test(NAME selftied COMMAND selftied) set_source_group(TESTSTRING "Source Files" test_dwarfstring.c dwarfstring.c dwarfstring.h) add_executable(teststring ${TESTSTRING}) target_compile_options(selftied PRIVATE ${DW_FWALL}) add_test(NAME teststring COMMAND teststring) endif() dwarfutils-20200114/libdwarf/CODINGSTYLE000066400000000000000000000053301361531463500174420ustar00rootroot00000000000000This document is a brief description of the main coding style conventions in libdwarf. Many of them will be obvious from the code, but over time some accidental diffences crept in. Code should be indented in multiples of 4 spaces, and tabs should not be used to indent the source code. Use the dicheck program to check indenting. dwarf.h and libdwarf.h must have all arguments commented out as these are public headers. Because a prototype like int dwarf_example_prototype(Dwarf_Debug foo); would be made unusable by a legitimate preprocessor definition such as #define foo + The struct naming convention is 'struct Camel_Caps_s' for the struct and 'Camel_Caps' for any typedef for the struct. Admittedly having both camel caps and an underbar is an unusual convention, but it is the way the coding was begun in the early 1990's and we should remain consistent now. All user-referenceable data and functions and user_visible types should begin with DW_ or dwarf_. Non-static libdwarf global data and functions should begin with _dwarf (a somewhat questionable approach, but workable). Function names should be all lower case with underbars for readability. There should never be static data in any function. Nor should there ever be static data outside of libdwarf functions. libdwarf can be called from multiple threads (but only from one thread per Dwarf_Debug) and multiple Dwarf_Debug objects can be open at one time. Instead place such data per-dbg into the Dwarf_Debug structure in dwarf_opaque.h. Similarly for the producer code. Function-local variables should be lower-case with underbars for readability. It's ok for a small loop with counters to use single letter names like i or k or m. structure members should have a struct-specific 2-character prefix to the name (followed by an underbar). That makes it much easier to grep for uses of members. Try to keep lines under 80 characters in length. Ensure every if() has {} to enclose the actions. There is a slight preference for if( over if(. Similarly with for (, while (, and switch (. Not obsessing about these space-issues... Use libdwarf.h types for all the data objects you define, though sometimes an 'unsigned' or 'int' or 'size_t' is ok in restricted circumstances. Dwarf_Unsigned Dwarf_Signed are the preferred integer types for general use. No .c file should ever have an 'extern *' to access some external. Instead, such external references should be defined in a header file and every .c with a reference to the external should #include the relevant header. Being obsessive about this ensures that when the definition changes it will match the function declaration. There are a couple violations of this as of 2012, and those should be fixed! ------------ dwarfutils-20200114/libdwarf/COPYING000066400000000000000000000020131361531463500167610ustar00rootroot00000000000000 The files: libdwarf.h dwarf.h and all the .h and .c files in this implementation of libdwarf are copyrighted according to the file LIBDWARFCOPYRIGHT (which mentions the LGPL version 2.1). Each file mentions the LGPL. The full text of the LGPL 2.1 is provided in LGPL.txt The libdwarf documentation: libdwarf2.1.mm is based on material submitted to the UI PLSIG as proposed interfaces for dwarf, but completely rewritten. Copyright ownership is therefore SGI (but see the document for details) and it seems clear that the intent was there was to be free copying with no fees. libdwarf2p.1.mm is documentation of a set of interfaces (not part of the UI PLSIG proposals) and the document was written from scratch at SGI. Copyright ownership is therefore SGI (but see the document for details) and it seems clear that the intent was there was to be free copying with no fees. 17 March 2014:Updated to remove reference to dwarf.v2.mm. dwarfutils-20200114/libdwarf/ChangeLog000066400000000000000000000010211361531463500174760ustar00rootroot000000000000002020-01-14: David Anderson * dwarf_names.c,dwarf_names.h,dwarf_names_enum.h, dwarf_names_new.h,libdwarf_version.h: Updated version string. 2020-01-05: David Anderson * dwarf_query.c(dwarf_offset_list): Coverity Scan CID 206598. Now checks for DW_DLV_ERROR where it failed to do so before, and returns an error instead of letting it slip through. 2020-01-03: David Anderson * dwarf_load_elf_headers.c(dwarf_elf_load_rela_32): Coverity Scan uncovered a memory leak in one case. CID 206524 dwarfutils-20200114/libdwarf/ChangeLog2006000066400000000000000000001053241361531463500200210ustar00rootroot000000000000002006-12-05 David Anderson * dwarf_error.c, libdwarf.h: added DW_DLE_FRAME_REGISTER_COUNT_MISMATCH. * dwarf_frame.c (_dwarf_exec_frame_instr): removed references to compile-time constants for register table size. Now uses run-time-chosen sizes. Now uses heap for reg table instead of stack. Now uses SIMPLE_ERROR_RETURN macro to simplify the code. 2006-11-08 David Anderson * pro_expr.c (dwarf_add_expr_gen): DW_OP_deref_size, DW_OP_xderef_size, and DW_OP_pick were incorrect, missing & operator. Would coredump. Thanks to Alan Chambers for mentioning the coredump. 2006-09-26 David Anderson * dwarf_die_deliv.c (dwarf_offdie): Now returns the correct die (worked before, almost always, but worked by accident). Thanks to Mattias Lindblad for supplying a test case. 2006-09-01 David Anderson * libdwarf2.1.mm (dwarf_loclist_n): Minor refinement of the description. * libdwarf2.1.ps: regenerated 2006-08-31 David Anderson * libdwarf2.1.mm (dwarf_loclist_n): A location expression sets ld_lopc to 0, ld_hipc to all-bits-on, and this is now documented. * libdwarf2.1.ps: regenerated 2006-06-14 David Anderson * dwarf_opaque.h dwarf_frame.h dwarf_frame.c dwarf_init_finish.c dwarf_frame2.c: Corrected handling of eh_frame zP encoding. Thanks to Cristi Vlasceanu for noticing it was broken. * Makefile.in: remove libdwarf.so in 'clean' rule. Thanks to Cristi Vlasceanu for noticing it was missing. 2006-04-28 David Anderson * dwarf_frame.c: Changed local variable type to avoid compiler warning. 2006-04-21 David Anderson * dwarf_frame.c: Initialized local to 0, wrong value. Thanks to Cristi Vlasceanu for noticing. 2006-04-18 David Anderson * All *.c: Ran indent so all c files follow a standard look. 2006-04-16 David Anderson * dwarf.h: Remove #if 0 around some #defines, it is ok to leave the defines visible (the defines are HP extensions). * libdwarf.h: Add new dwarf3 interface to frames. (which actually is also a better interface to dwarf2 info, not strictly for dwarf3). * dwarf_alloc.c: Add 'constructor/destructor' pointers to the initialization table so we can handle a more flexible (dwarf3) frame interface.Call the functions at the appropriate times. * dwarf_frame.c: Using macro FDE_NULL_CHECKS_AND_SET_DBG reduce duplicate coding.Internal code now handles dwarf2 and dwarf3 and interfaces to exported interfaces appropriately. * dwarf_frame.h: Alter internal struct to handle frames more flexibly. * dwarf_frame2.c: Remove unused local variable. * dwarf_init_finish.c: Add initialization of new Dwarf_Debug struct entries allowing handling of run-time-config of frame info. * dwarf_loc.c: Add DWARF3 operators, such as DW_OP_call4. * dwarf_opaque.h: Declaration of new Dwarf_Debug struct entries allowing handling of run-time-config of frame info. * pro_expr.c: Add entries allowing creation of DWARF3 DW_OP such as call2. * pro_section.c: Change crucial code handling section lengths, using a macro BEGIN_LEN_SIZE to clarify and correct a few places. 2006-03-31 David Anderson * libdwarf.h: Added dwarf_get_fde_info_for_cfa_reg3() prototype preparing for dwarf3 frame interface. * dwarf_frame.c: Now uses separate rule, not DW_FRAME_CFA_COL, to record CFA. * dwarf_frame.h: Add commentary on frame access. 2006-03-30 David Anderson * Makefile.in configure.in: Adding --enable-shared --enable-nonshared --disable-shared and --disable-nonshared. * configure: regenerated with 2.59 autoconf. * README: Added explanation on changing dwarf.h libdwarf.h. 2006-03-29 David Anderson * dwarf_print_lines.c dwarf_sort_line.c: Clean up initialization code for line table reading. When returning rules table data to caller ensure fully filled out yet no overrun (handling case where rules table sizes not defined identically by caller and library). * dwarf.h: New commentary on ABI/register-number issues. * libdwarf.h: New commentary on ABI/register-number issues. 2006-03-26 David Anderson * dwarf_line.c: file_entry_count local was not initialized. Initialized some locals at declaration. Thanks to Mikael Vidstedt for noticing. 2006-03-23 David Anderson * dwarf_error.c: added error strings for codes 200,201 * dwarf_line.c dwarf_line.h dwarf_print_lines.c dwarf_sort_line.c: Moved line prefix reading to a common routine, filling in a new internal struct to make it simple. Removed much duplicate code. Added more support for dwarf3 line table standard opcodes. Now prints details (with -v -v) of standard opcodes it does not understand (if any present). 2006-03-13 David Anderson * dwarf.h: add ALTIUM #defines (extensions to dwarf) * libdwarf.h: Alter arguments to new functions dwarf_get_fde_augmentation_data() and dwarf_get_cie_augmentation_data() used by GNU eh_frame. * dwarf_frame.h: Add new fields so we can handle GNU eh_frame. * dwarf_frame.c: Remove erroneous load_sections calls (wrong for eh_frame data) and correct the new dwarf_get_fde_augmentation_data() and dwarf_get_cie_augmentation_data() implementation. * dwarf_frame2.c: Implement support for GNU eh_frame. * dwarf_line.h: Correct handling of DWARF3 opcode base check. * dwarf_line.c: Add new macro use to get DWARF3 opcode base handling correct. * dwarf_print_lines.c: Add new macro use to get DWARF3 opcode base handling correct. * dwarf_sort_lines.c: Add new macro use to get DWARF3 opcode base handling correct. 2006-03-08 David Anderson * dwarf_frame2.c: ensure local variables initialized to avoid coredump. 2006-03-08 David Anderson * dwarf_die_deliv.c: Remove Richard Stukey's -1 and replace with a simpler more complete fix. 2006-03-07 David Anderson * Makefile.in: Add dwarf_line2.c dwarf_frame3.c to files to build. * dwarf_addr_finder.c: Add comments about file purpose. * dwarf_frame.c: Move IRIX specific function out of this file. * dwarf_frame3.c: Move IRIX specific function to this new file. * dwarf_frame.h: Add interface declaration. * dwarf_line.c: Move IRIX specific function out of this file. * dwarf_line2.c: Move IRIX specific function to this new file. * dwarf_line.h: Add interface declaration. * dwarf_frame2.c: Altered comments so indent handles them better, ran indent. 2006-03-07 David Anderson * dwarf_die_deliv.c (dwarf_siblingof): -1 to point to end of cu, not one-past-end. With thanks to Richard Stuckey. * libdwarf2.1.mm: document existing function dwarf_get_fde_exception_info() * dwarf_frame.h: Add new internal interfaces. * dwarf_frame.c: Remove cie/fde reader to dwarf_frame2.c. * dwarf_frame2.c: Contains heavily refactored cie/fde reader, preparing for eh_frame support and avoids some searching in fde creation. Removes duplicated code into new internal functions. * Makefile.in: Adding comment about flag for malloc_checking code. Add dwarf_frame2.c to source list. * libdwarf.h: added declarations for eh_frame information, though these are not yet supported. * dwarf.h: Added defines for eh_frame information, though these are not yet used. 2006-02-23 David Anderson * dwarf_line.h dwarf_line.c: added dwarf_line_srcfileno() to complement dwarf_lineno. * libdwarf2.1.mm: document dwarf_line_srcfileno(). 2005-11-25 David Anderson * dwarf.h: Now matches 2005 DWARF3 public review document. 2005-11-08 David Anderson * dwarf_alloc.c, dwarf_init_finish.c, dwarf_sort_line.c, malloc_check.c: remove malloc.h include, it is not needed, stdlib.h suffices. 2005-10-24 David Anderson * dwarf.h: Updated to match DWARF3 public review document. 2005-10-03 David Anderson * dwarf_alloc.c: Change some entries to BASE_ALLOC. * dwarf_global.h: Add argument to interface so we do not universally use DW_DLA_GLOBAL, but cater to compatibility. * dwarf_funcs.c, dwarf_global.c, dwarf_weaks.c, dwarf_funcs.c, dwarf_types.c: Restored use of DW_DLA_* instead of universally using DW_DLA_GLOBAL. * dwarf_pubtypes.c: added comments about DW_DLA_GLOBAL use. 2005-08-01 David Anderson * malloc_check.c: Moved the #ifdef WANT_LIBBDWARF_MALLOC_CHECK down after #includes so the test is meaningful. 2005-07-15 David Anderson * libdwarf.h: New DW_DLA codes and full .debug_types support added. new dealloc functions declared. * Makefile.in: Add dwarf_pubtypes.o (.debug_pubtypes support). * dwarf_abbrev.c: Add dealloc() calls where needed. * dwarf_alloc.c: Add dwarf_malloc_check calls, rename and update _DW_RESERVE to DW_RESERVE, make hash table declaration in array more readable. Add optional final dealloc loop. * dwarf_alloc.h: Increase the index array to add .debug_pubtypes support. * dwarf_base_types.h: Increase the index array to add .debug_pubtypes support. * dwarf_die_deliv.c: Add dealloc calls to get full dealloc. * dwarf_error.c: Document new error codes for .debug_pubtypes. * dwarf_init_finish.c: Add .debug_pubtypes support, add dwarf_malloc_check_complete() call for alloc checking. * dwarf_form.c: Document dwarf_formstring() use. * dwarf_frame.c: Add dwarf_fde_cie_list_dealloc() for complete dealloc. * dwarf_global.h: Add _dwarf_internal_globals_dealloc declaration for libdwarf-internal use. * dwarf_global.c dwarf_funcs.c dwarf_types.c dwarf_vars.c dwarf_weaks.c: Add new dealloc public routines for complete dealloc and add .debug_pubtypes support. * dwarf_pubtypes.c: Support for .debug_pubtypes. * dwarf_malloc_check.h dwarf_malloc_check.c : New checking for complete accurate dealloc (off by default). * dwarf_opaque.h: Add internal .debug_pubtypes support. * libdwarf2.1.mm: Document new dealloc code, correct dwarf_formstring documentation. 2005-07-14 David Anderson * dwarf_line.c: Added dwarf_srclines_dealloc and call it for dwarf_srclines output. Does complete deallocation, unlike previous method, which was incomplete deallocation. Thanks to Alan Alexander for pointing out there was incomplete deallocation. * dwarf_print_lines.c: remove references and allocation of line_context. Memory was leaking due to unreferenced variable. * libdwarf2.1.mm: Document new dwarf_srclines_dealloc() deallocation routine for dwarf_srclines(). 2005-07-13 David Anderson * dwarf_init_finish.c (dwarf_init): if _dwarf_setup() fails, free elf resources with elf_end() call. Thanks to Cristi Vlasceanu for pointing out that a memory leak existed here. 2005-06-13 David Anderson * dwarf_frame.c (_dwarf_exec_frame_instr): Corrected test so that .o files (pre-relocation) are less likely to generate DW_DLE_DF_NEW_LOC_LESS_OLD_LOC error. Renamed local variable for better readability. 2005-04-13 David Anderson * dwarf_error.c: Error codes 194 and 195 were missing strings, added them to table. * dwarf_frame.c: Check for newer gcc .eh_frame augmentation strings and avoid trying to handle these for now. * dwarf_global.c: Add an error check for pubnames-style sections for bad offset. * dwarf_init_finish.c: Add dwarf_get_section_max_offsets() to allow clients to do additional error checking. This code will have to change again, so leaving it undocumented. As written it's not useful for COMDAT style DWARF sections. * libdwarf.h: Added prototype for dwarf_get_section_max_offsets(). 2005-03-31 David Anderson * mips_extensions.mm: Documented the libexc/.debug_funcnames dependency and the 64bit-offset DWARF extension. * mips_extensions.ps: Regenerated. 2005-03-21 David Anderson * dwarf_line.c: Added commentary. * libdwarf2.1.mm: Documented dwarf_lineendsequence() better. * libdwarf2.1.ps: Regenerated. * libdwarf.h: Added DW_DLE_FRAME_AUGMENTATION_UNKNOWN as error code 195. * dwarf_init_finish.c: Corrected comment spelling. * dwarf_frame.h dwarf_frame.c: Added handling for much (but not all) of gcc 3.3 gcc 3.4 .eh_frame 'z' augmentation. Gives error on attempting to get z augmentation data since such is not completely handled. 2005-03-18 David Anderson * dwarf_frame.h dwarf_frame.c: The gcc .eh_frame info did not print correctly so we now access the correct section data so it prints. Still no support for dwarf3 frame operators. * dwarf_macro.c: Detect end-of-macros properly (stopped too soon before). 2005-02-14 David Anderson * pro_incl.h: Added #elif defined(HAVE_LIBELF_H) enabling build on a platform missing normal elf.h. 2005-02-11 David Anderson * dwarf_base_types.h: Added DW_CIE_VERSION3 define. * dwarf_die_deliv.c: Allowed CURRENT_VERSION_STAMP3. * dwarf_frame.c: Allowed DW_CIE_VERSION3. * dwarf_frame.h: Define DW_DEBUG_FRAME_VERSION3. * dwarf_line.c: Allow CURRENT_VERSION_STAMP3. * dwarf_line.h: Add lc_version_number to line structure. * dwarf_opaque.h: Add CURRENT_VERSION_STAMP3 and comment showing version numbers (DWARF3 vs DWARF2) by DWARF section. 2004-11-21 David Anderson * configure.in libdwarfdefs.h: Now tests more precisely for __uint32_t and __uint64_t (previous test was not sufficient for debian/mips). Regenerated configure config.h.in. 2004-10-28 David Anderson * LIBDWARFCOPYRIGHT Makefile.in NEWS config.h dwarf_abbrev.c dwarf_abbrev.h dwarf_addr_finder.c dwarf_alloc.c dwarf_alloc.h dwarf_arange.c dwarf_arange.h dwarf_base_types.h dwarf_die_deliv.c dwarf_die_deliv.h dwarf_error.c dwarf_error.h dwarf_form.c dwarf_frame.c dwarf_frame.h dwarf_funcs.c dwarf_funcs.h dwarf_global.c dwarf_global.h dwarf_incl.h dwarf_init_finish.c dwarf_leb.c dwarf_line.c dwarf_line.h dwarf_loc.c dwarf_loc.h dwarf_macro.c dwarf_macro.h dwarf_opaque.h dwarf_print_lines.c dwarf_query.c dwarf_sort_line.c dwarf_string.c dwarf_stubs.c dwarf_types.c dwarf_types.h dwarf_util.c dwarf_util.h dwarf_vars.c dwarf_vars.h dwarf_weaks.c dwarf_weaks.h libdwarfdefs.h pro_alloc.c pro_alloc.h pro_arange.c pro_arange.h pro_die.c pro_die.h pro_encode_nm.c pro_encode_nm.h pro_error.c pro_error.h pro_expr.c pro_expr.h pro_finish.c pro_forms.c pro_frame.c pro_frame.h pro_funcs.c pro_funcs.h pro_incl.h pro_init.c pro_line.c pro_line.h pro_macinfo.c pro_macinfo.h pro_opaque.h pro_pubnames.c pro_pubnames.h pro_reloc.c pro_reloc.h pro_reloc_stream.c pro_reloc_stream.h pro_reloc_symbolic.c pro_reloc_symbolic.h pro_section.c pro_section.h pro_types.c pro_types.h pro_util.c pro_util.h pro_vars.c pro_vars.h pro_weaks.c pro_weaks.h: Copyright update with 2004 and new SGI official address. 2004-10-26 David Anderson * acconfig.h: removed. Was old style autoconf usage. * configure.in: Updated AC_DEFINE usage, adding args 2 & 3. * config.guess: Updated. timestamp='2004-06-11'. * config.sub: Updated. timestamp='2004-03-12'. * configure config.h.in: regenerated with autoconf 2.58. 2004-06-09 David Anderson * dwarf_frame.c (_dwarf_exec_frame_instr): Was not setting ru_offset to 1 in DW_CFA_def_cfa_offset case, now it does. 2004-02-24 David Anderson * dwarf_frame.c (_dwarf_exec_frame_instr): DW_CFA_def_cfa_register case, was setting offset, which is incorrect. Thanks to Tom Hughes for pointing this out. 2004-02-03 David Anderson * dwarf_util.h: DECODE_LEB128_UWORD DECODE_LEB128_SWORD were simply wrong if Dwarf_Word or Dwarf_Sword longer than 4 bytes. Upper bits left random. Large values not extracted correctly. 2004-01-15 David Anderson * dwarf_alloc.c pro_alloc.c pro_init.c: changing BSD-ish bzero() to posix-standard memset() calls. * configure.in: remove bstring.h test, add alloca.h test. No longer useing bzero, some environments have alloca in malloc.h, no alloca.h. If neither exist it's up to you to deal with it. * dwarf_line.c dwarf_print_lines.c dwarf_sort_line.c: Test HAVE_ALLOCA_H * configure config.h.in: regenerated 2003-12-31 David Anderson * dwarf_init_finish.c: added #error to detect and describe absence of libelf.h. * README: Added mention of libelf.h requirement, minor cleanout of obsolete comments, added configure example. * Makefile.in: Removed bogus LIBS line, updated copyright date. * acconfig.h: Updated copyright date. * config.guess config.sub: new versions from automake-1.6. * config.h.in configure: Regenerated. 2003-12-15 David Anderson * dwarf_init_finish.c (_dwarf_setup): test for (section_size) was wrong for eh_frame section. Changed this one to (section_size == 0) so it is like all the others testing section_size. Thanks to David Mosberger for pointing out this inconsistency. 2003-12-08 David Anderson * dwarf_line.h: reference in comment to li_dbg meant to refer to li_offset. Corrected and amplified comment. 2003-10-06 David Anderson * dwarf_abbrev.c dwarf_die_deliv.c dwarf_form.c dwarf_loc.c dwarf_util.c: applied indent(1). 2003-10-02 David Anderson * dwarf_loc.c: Implemented dwarf_get_loclist_entry(), implemented new dwarf_loclist_n() fully implementing loclist support. * dwarf_stubs.c: removed dwarf_get_loclist_entry stub. * libdwarf2.1.mm: Documented dwarf_loclist_n() and updated documentation on dwarf_loclist(). 2003-09-29 David Anderson * dwarf_abbrev.c: Ensure the .debug_abbrev section is loaded. * dwarf_arange.c dwarf_global.c: Recent dwarf committee discussions have revealed we were wrong in not allowing padding in aranges. * dwarf_die_deliv.c dwarf_query.c: handle DW_FORM_indirect. * dwarf_form.c: Add dwarf_whatform_direct() so folks can report on DW_FORM_indirect use. Fill in new Dwarf_Locdesc fields. * dwarf_loc.c: Handle .debug_loc partially. Fill in new Dwarf_Locdesc fields. Load .debug_loc if not present and if it's needed. * dwarf_opaque.h: Added ar_attribute_form_direct field so we can report DW_FORM_indirect in libdwarf-using code (where such wants to). * dwarf_util.c: Don't confuse DW_FORM_indirect uleb length with other lengths. * libdwarf2.1.mm: Document new function dwarf_whatform_direct() Not needed by ordinary clients, just for clients wanting to print certain debug info. 2003-04-15 Brian Ford * configure.in (AC_C_BIGENDIAN): Move after AC_PROG_CC so a proper working compiler is used for the test. 2003-01-21 David Anderson * dwarf_die_deliv.c (dwarf_next_cu_header, dwarf_offdie): Add calls to dwarf_load_object() to load .debug_info, .debug_abbrev * dwarf_init_finish.c (_dwarf_setup): Remove calls to dwarf_load_object for .debug_info, .debug_abbrev sections. * dwarf_opaque.h: Add new fields to Dwarf_Debug so we don't need to pre-load .debug_info, .debug_abbrev * dwarf_util.h: Fix READ_AREA_LENGTH macro so it uses only length itself to determine which format the length is. 2003-01-14 David Anderson * dwarf_loc.c: Made comment at head of dwarf_loclist() a bit clearer. 2002-11-22 Tom Hughes * dwarf_macro.c: Corrected bugs in macro-info functions. 2002-10-29 David Anderson * dwarf_init_finish.c: The libelf_sgi mods left a HAVE_ELF64_GETSHDR ifdef in the wrong place so folks without Elf64 could not build. Fixed. 2002-10-21 David Anderson * dwarf_form.c: the form_ref functions were failing to add in cc_extension_size when checking for offset legality. Thanks to Kelly O'Hair for pointing out the 4 places this was wrong. Used cu_context local pointer to avoid numerous double indirections. 2002-08-14 David Anderson * dwarf_string.c (dwarf_get_str): Return DW_DLV_NO_ENTRY when offset is just at the end of the sections, making it possible to use dwarf_get_str to print the section independently. * libdwarf2.1.mm, libdwarf2.1.ps: Document the revised dwarf_get_str interface (which was not fully thought thru before). * dwarf_line.c (dwarf_srcfiles): Avoid core dump when DW_AT_comp_dir absent (it's not required). 2002-07-31 David Anderson * pro_types.c (_dwarf_transform_simplename_to_disk): correct generation of .debug_info size field. Thanks to Kelly O'Hair for pointing out the bug. 2002-05-23 Daniel Gohman * dwarf_init_finish.c: Add support for using SGI's ELF library as an alternative to using AT&T-style libelf. Add a new function _dwarf_load_section to handle loading of sections. * dwarf_opaque.h: Add entries to Dwarf_Debug_s to store section indicies. * most consumer files: Load sections on demand so that unneeded sections don't get loaded. * dwarf_init_finish.c: Fixed an incorrect check for duplicate .eh_frame sections. 2002-04-25 Kelly O'Hair * pro_section.c (_dwarf_pro_generate_debuginfo): add required dwarf2 sec 7.5.3 trailing null byte to .debug_abbrev per compilation-unit. 2002-03-31 David Anderson * dwarf_abbref.c (dwarf_get_abbrev): change DW_DLE_DEBUG_ABBREV_NULL to DW_DLE_DWARF_ABBREV_NULL. Former was wrong code. * libdwarf2.1.mm: correct argument reference, returned_abbrev not returned_fde in dwarf_get_abbrev discussion. 2002-03-07 David Anderson * libdwarf.h: added struct Elf declaration to reduce dependency on header include ordering. 2002-02-11 David Anderson * libdwarf2.1.mm libdwarf2.1.ps: dwarf_offdie can return DW_DLV_NO_ENTRY and that is now documented. * dwarf_loc.c: if the length of a location description is zero that is ok, not an error. dwarf2 sec 2.4.1. 2002-01-10 David Anderson * dwarf_opaque.h, dwarf_init_finish.c: if libdwarf does the elf_begin() it must also do the elf_end() to avoid a memory leak, and now does this correctly. 2002-01-10 David Anderson * dwarf_init_finish.c: Using a variable to hold ELF_C_READ_MMAP. Really motivated by code not added to this source. * dwarf_die_deliv.c: Added comments, moved a couple variables to local scope from function scope. * dwarf.h: Added some #defines which were specified in the Dwarf 2.1 Dwarf draft 5 (now called dwarf 3 draft 5). 2001-09-18 David Anderson davea@sgi.com * all files: applied gnu indent with -bad -bap -nbbo -br -ce -brs -l72 -lc72 -hnl -nprs -fca -i4 -lp -psl -npcs Code should use this set in libdwarf. 2001-08-21 "kelly o'hair" * pro_section.c: If one called dwarf_add_file_decl() or dwarf_add_directory_decl() but never added a line, .debug_line was not produced. This was a mistake, as if any file or directory was provided .debug_line should be produced. 2001-08-06 davea@sgi.com * libdwarf2.1.mm: documented dwarf_dealloc rules more clearly. (.ps updated too) * mips_extensions.mm: documented the way SGI gets frame stack pointer out of debug_frame. (.ps updated too) 2001-06-14 davea@sgi.com * dwarf_leb.c: changed around where bytes counted in _dwarf_decode_s_leb128 so it's easier to tell it is correct. And removed one loop completely: it was an early attempt at performance improvement and is no longer relevant. * dwarf_global.c: added new dwarf_get_cu_die_offset_given_cu_header_offset function to get CU die offset (as the long name says). A variety of functions return cu-header-offsets, so this is useful at times. Used locals to reduce the number of indirections and make things easier to follow. * dwarf_arange.c: added new dwarf_get_arange_cu_header_offset function so dwarfdump could print the cu header offset (which appears in the arange headers). * libdwarf2.1.mm: documented the above new functions. 2001-06-07 davea@sgi.com * dwarf_leb.c: shift operator was not being applied to full size of Dwarf_Signed/Unsigned for 64bit Dwarf_Signed/Unsigned (ILP32 compile) so large numbers not decoded if signed. * pro_encode_nm.c: added {} in a couple if/else for 'clarity' and to make inserting debug printf easier. * pro_expr.c: Added comments explaining why possible compiler (gcc) warnings are ok, the result is safe. 2001-05-30 davea@sgi.com * pro_reloc_stream.c: Wrote Set_REL32_info and Set_REL64_info macros from generic ELF abi documents to make use acceptable when IRIX elfaccess.h is not available. 2001-05-30 "kelly o'hair" * Makefile.in: was missing pro_macinfo.o pro_encode_nm.o dwarf_macro.o from the OBJS list. 2001-05-22 davea@sgi.com * dwarf_frame.c, pro_expr.c: Added comments on why casts are safe in spite of gcc warnings (4 places total). 2001-05-18 Dan Gritter * dwarf_loc.c DW_OP_bregx operands are unsigned reg num followed by signed offset. 2001-04-11 David Anderson * dwarf_die_deliv.c: check for 0 abbreviation code and return a 'no entry' return value when found. (normal dwarf2, 0 means no DIE, the end of some set of DIEs.) 2001-01-16 David Anderson * pro_die.c: set ar_reloc_len field in all cases. 2000-12-14 David Anderson * dwarf_frame.h: clarified some comments. 2000-12-14 Ulrich Drepper * dwarf_line.c: Now sets DW_LNE_end_sequence to default_is_stmt, the correct value, not is_stmt. 2000 Aug 24 davea@sgi.com dwarf_error.c: a dwarf_init() failure resulted in this using a static Dwarf_Error struct. And dwarf_dealloc did not deal properly with that. dwarf_alloc.c dwarf_alloc.h: these had DYNAMIC_CHUNK protected code which was never used. Deleted the unused code. Added a small comment (hopefully useful) to dwarf_alloc.h. And now deals correctly with a null dbg on DW_DLA_ERROR due to failed dwarf_init() call (or due to other error in calling libdwarf that results in libdwarf not knowing the dbg, a likely far more common case) and frees the memory. This used to result in chaos (depending on your luck...). 2000 Aug 23 davea@sgi.com libdwarf2.1.mm, ps. Failed to mention that dwarf_finish() has to be accompanied by elf_end() if dwarf_init() was used to initialize libdwarf to truly release all stuff. Added text to dwarf_finish() describing how to do that. 2000 April 14 davea@sgi.com dwarf_abbrev.c - 1.22 - When it is a null abbrev entry, return it correctly so it can be printed (meaning fill out all the return-parameters so the caller can do the right thing). dwarf_init_finish.c - 1.48 - For most sections, simply having an empty section (present but empty) is just fine. There is no reason to register an error in such a case. Copyright has changed. See LIBDWARFCOPYRIGHT and NEWS dwarfdump/print_die.c - 1.42 - Explain what combo checker is doing and make it more maintainable (and fix bug which would not be hit, but was real enough). dwarfdump/tag_tree.list - 1.2 - Add valid parent/child relationships so checker does not report valid entries as bogus. dwarf_form.c - 1.26 - Correct dwarf reader to use appropriate size, not de_length_size. This is part of the handling of the new dwarf2 64bit facilities. I overlooked this small aspect before in one place dwarf_query.c - 1.48 - Use correct size, not de_length_size. For offset size. libdwarf2.1.mm - 1.41 - Tried to make frame register output args meaning clearer libdwarf2.1.ps - 1.19 - Tried to make frame register output args meaning clearer pro_forms.c - 1.33 - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2 spec. even if pointer size is 64 bits. pro_init.c - 1.18 - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2 spec. even if pointer size is 64 bits. davea@sgi.com 2000 March 7 dwarf_line.c - 1.48 dwarf_line.h - 1.16 dwarf_print_lines.c - 1.10 dwarf_sort_line.c - 1.8 - Now handles opcode_base of line section to be other than that at compile time of libdwarf. Important as the dwarf2 committee is adding a new standard opcode davea@sgi.com 2000 Feb 24 pro_forms.c 1.31 ar_next field not always zeroed before. Could lead to infinite loop in the producer code. Now the field is always zeroed. Makefile.in - 1.3 Jason Merrill provided fix so gcc will work on libdwarf print_sections.c - 1.54 - casts to avoid warnings davea@sgi.com 1999 Dec 14 acconfig.h - 1.3 config.h.in - 1.5 configure - 1.4 configure.in - 1.5 - HAVE_DWARF2_99_EXTENSION HAVE_OLD_DWARF2_32BIT_OFFSET refinements added. CHANGES - 1.3 Makefile.base - 1.98 NEWS - 1.5 config.h - 1.4 config.h.in - 1.4 configure.in - 1.4 dwarf_alloc.c - 1.36 dwarf_arange.c - 1.19 dwarf_arange.h - 1.6 dwarf_die_deliv.c - 1.51 dwarf_frame.c - 1.62 dwarf_frame.h - 1.23 dwarf_funcs.c - 1.10 dwarf_funcs.h - 1.3 dwarf_global.c - 1.21 dwarf_global.h - 1.7 dwarf_init_finish.c - 1.45 dwarf_line.c - 1.44 dwarf_opaque.h - 1.52 dwarf_print_lines.c - 1.8 dwarf_query.c - 1.45 dwarf_types.c - 1.10 dwarf_types.h - 1.3 dwarf_util.c - 1.40 dwarf_util.h - 1.22 dwarf_vars.c - 1.11 dwarf_vars.h - 1.3 dwarf_weaks.c - 1.10 dwarf_weaks.h - 1.3 libdwarf2.1.mm - 1.40 libdwarf2.1.ps - 1.18 pro_arange.c - 1.15 pro_die.c - 1.23 pro_frame.c - 1.29 pro_init.c - 1.15 pro_macinfo.c - 1.7 pro_opaque.h - 1.14 pro_pubnames.c - 1.18 pro_reloc_stream.c - 1.5 pro_section.c - 1.70 pro_section.h - 1.16 pro_types.c - 1.12 - Allowing generation of correct dwarf2 with the 1999 64bit dwarf extension, and reading all forms of dwarf2 compatibly (all 32/64bit dwarf2 section forms). This adds the ability to consume and produce both sgi 64bit and the new dwarf2 committee-approved 64bit dwarf extension. As a result of the new dwarf2 stuff , a producer (compiler) can mix 32 and 64bit dwarf (for a 64bit object) and the linker will work seamlessly. (as long as section sizes don't get over 2GBytes). And the producer is easily configured to produce mips/sgi style 64bit dwarf or the new form of 64bit dwarf. This also eliminates a fair amount of rather silly duplicated code. davea@sgi.com 1999 Nov 4 pro_section.c - 1.69 - A pointer size entity had an offset-size value used at one place. davea@sgi.com 1999 Sep 30 dwarf_arange.c - 1.18 - Changed // comment to /* */. // failed to compile with C89 compiler... davea@sgi.com 1999 Sep 29 Changed all the producer code substantially to allow generating assembler code for the dwarf2 (rather similar to what gcc does) allowing symbolic relocations. MIPS output still generates the binary form. davea@sgi.com 1999 Aug 20 Stan Shebs (shebs@cygnus.com) pointed out that the pro_util.h use of R_MIPS* was a problem compiling on Sun. Since the producer code is not really used at present except for MIPS/sgi, I've added #ifndefs to pro_util.h which provide zero values when does not provide the macros. When anyone needs the producer code to actually *work* for non-MIPS something better will have to be done. This has no effect on those simply compiling libdwarf for use by dwarfdump. davea@sgi.com 1999 July 21 Changed the READ_UNALAGNED macro to call a function depending on endianness of the host and the object being read. So all the dwarf_* source changed in a trivial way. Added support for printing egcs eh_frame section. Added a local memcpy-like function to do the cross-endian thing where applicable (called by READ_UNALIGNED macro). Because the .eh_frame section after linking can have some zeroed out bytes at the end of the CIE/FDE data the code looking for CIEs and FDEs now assumes a zero CIE/FDE length means it has reached the end of the CIE/FDE data. davea@sgi.com 1999 June 14 Fred Fish fnf@ninemoons.com contributed autoconf'ing of the libdwarf and dwarfdump source. mips_extensions.* Documented additional old errors in the Dwarf Version 2 spec. The ChangeLog before this is incomplete. ------------------------------------------------------------- Since Oct 95 and before May, 1996 davea@sgi.com David Anderson Added the function dwarf_get_cie_of_fde() which makes it possible to remember a single fde/cie set out of a block usefully. Enhanced doc of dwarf_bitoffset() Added new function dwarf_global_formref() so all reference forms can be retrieved. Fixed bug in retrieving array bounds: was failing to sign extend formsdata. Added function dwarf_get_fde_info_for_all_regs(), which makes retrieval of the complete set of registers (as needed by debuggers and exception handlers) effectively N times faster than getting them one a time where N is the number of registers. Added support for exception table handling (really just support for a reference to an exception table for c++ exceptions). Fixed a bug where useless extra space (several megabytes) were malloc'ed for the abbreviations table by the libdwarf consumer code. ------------------------------------------------------------- June 10, 1999 Changelog started. ------------------------------------------------------------- dwarfutils-20200114/libdwarf/ChangeLog2007000066400000000000000000000274241361531463500200260ustar00rootroot000000000000002007-12-09 DavidAnderson * dwarf_sort_line.c dwarf_print_lines.c darf_frame.c: Forgot to commit yesterday. Today's commit includes renaming _dwarf_fde_section_offset _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines to dwarf_* name while retaining support for the now obsolete _dwarf_* form. 2007-12-08 DavidAnderson * config.h.in, configure.in: Latest linux libelf.h requires _GNU_SOURCE to get off64_t defined so dwarfdump compiles. Only define _GNU_SOURCE if libelf.h defines off64_t. Regenerated configure. * config.guess, config.sub: Updated to 2.61 * acconfig.h: Deleted, removing autoconf complaint. 2007-11-14 David Anderson * dwarf_frame2.c (gnu_aug_encodings): Now allows 'S' augmentation character in eh_frame. 2007-10-16 David Anderson * dwarf_alloc.c: Reformat a comment. * dwarf_die_deliv.c (dwarf_siblingof): When there is no trailing null-DIE in the section, ensure we don't test the contents of a byte past section end. * dwarf_frame.c: Changed spelling of a local variable so it is easier to grep for and to read. * dwarf_macro.c (free_macro_stack): Was free()ing memory that _dwarf_get_alloc() had supplied, which could lead to core dump. Fixed potential memory leaks (said leaks only possible with an error in the macro data, not with valid macro section data). 2007-10-15 David Anderson * dwarf_alloc.c: The code supporting the special build flag DWARF_SIMPLE_MALLOC was broken and could coredump libdwarf (which did not affect normal use of libdwarf). * dwarf_opaque.h: Remove the field de_simple_malloc_current as it is no longer used. 2007-09-04 David Anderson * pro_forms.c: Add commentary relating to the recent DWARF4 DW_AT_high_pc change. Correct FSF address. * libdwarf2p.1.mm: Document dwarf_add_AT_dataref() and dwarf_add_AT_ref_address(). * libdwarf2p.1.pdf: Regenerate. * dwarf.h: Update FSF address. * dwarf_opaque.h: Add DWARF4 entry (version stamp). Update FSF address. * dwarf_die_deliv.c: Add check for .debug_info version 4 (version stamp). Update FSF address. * libdwarf.h pro_macinfo.h pro_line.h dwarf_incl.h pro_alloc.h pro_section.h libdwarfdefs.h pro_util.h dwarf_vars.h dwarf_funcs.h pro_error.h dwarf_alloc.h pro_arange.h dwarf_arange.h pro_die.h dwarf_global.h pro_expr.h pro_reloc_stream.h pro_incl.h pro_encode_nm.h dwarf_line.h pro_frame.h pro_opaque.h dwarf_error.h dwarf_base_types.h dwarf_abbrev.h pro_types.h pro_reloc_symbolic.h dwarf_weaks.h dwarf_util.h dwarf_loc.h malloc_check.h dwarf_die_deliv.h acconfig.h dwarf_frame.h dwarf_macro.h pro_reloc.h dwarf_types.h pro_funcs.c Makefile.in pro_forms.c pro_line.c dwarf_print_lines.c pro_alloc.c pro_init.c dwarf_addr_finder.c pro_section.c dwarf_form.c dwarf_query.c dwarf_vars.c dwarf_pubtypes.c dwarf_frame3.c dwarf_funcs.c pro_error.c pro_arange.c dwarf_alloc.c dwarf_arange.c pro_die.c dwarf_sort_line.c dwarf_global.c dwarf_init_finish.c pro_weaks.c pro_pubnames.c pro_expr.c pro_reloc_stream.c pro_finish.c pro_encode_nm.c dwarf_line.c pro_frame.c dwarf_error.c dwarf_abbrev.c pro_types.c dwarf_leb.c pro_reloc_symbolic.c dwarf_string.c pro_vars.c dwarf_line2.c dwarf_weaks.c dwarf_frame2.c dwarf_util.c dwarf_loc.c LIBDWARFCOPYRIGHT malloc_check.c dwarf_die_deliv.c dwarf_frame.c dwarf_stubs.c dwarf_macro.c pro_reloc.c dwarf_types.c pro_macinfo.c: Update FSF address. 2007-07-26 David Anderson * pro_frame.c: Added commentary about some missing DWARF3 support. * dwarf_srclines_dealloc.c: File unused, now deleted. 2007-07-04 David Anderson * libdwarf.h: dwarf_get_loclist_entry() is implemented, removed the erroneous 'unimplemented' comment. * libdwarf2.1.mm: Improved the dwarf_get_loclist_entry() documentation. * libdwarf2.1.pdf: regenerated * dwarf_loclist_entry.c: Removed from distribution, the source has nothing of interest. 2007-07-03 David Anderson * libdwarf.h: Add declaration of dwarf_loclist_from_expr(); * dwarf_loc.c: Implement dwarf_loclist_from_expr() and add sign-extension macro calls to case DW_OP_const4s numbers. Removed unused local variables. * dwarf_form.c: Removed unused local variables. * libdwarf2.1.mm: Document dwarf_loclist_from_expr(). * libdwarf2.1.pdf: Regenerated. 2007-07-01 David Anderson * dwarf_frame2.c: Add commentary. * dwarf_frame.c: Add in block_len for DW_CFA_val_expression so libdwarf does not get confused by this frame expression operator. Thanks to Cristian Vlasceanu for providing a test case. 2007-06-29 David Anderson * README: added a note that a few warnings about conversions from pointer to integer are normal at libdwarf compile time. 2007-05-25 David Anderson * dwarf_frame2.c (_dwarf_get_fde_list_internal): Correct cie-list-creation so it adds to the tail of the list. gcc 4.1.2 generates cie-use in an order the code did not properly handle. 2007-05-08 David Anderson * Makefile.in: Now generates pdf files. * mips_extensions.mm: The only changes were to eliminate unsupported macro (.PM) and to try to get correct output from groff. No technical content change intended. The pdf/postscript output remains a little odd though. * libdwarf2.1.mm: Remove troff comment line. 2007-04-18 Chris Quenelle * dwarf_addr_finder.c: repaired comment * dwarf_form.c: add support for DW_AT_SUN_func_offsets * pro_alloc.c: add memory block tracking to find and fix lingering allocations. This is more important for very large and intensive compiles. * pro_die.c: Implement "markers" which are a generic way to do things like relocations. You can set a marker on any die, and when dwarf is produced in binary form, you get back a list of your markers with the offset of each one in the binary output. This is used by the Sun compilers to implement die references that span compile unit blocks. (I may remove this, it might be unused code related to partial_units and comdat support) * pro_die.c: Also check for loops in the die relationships so that if you add a child twice, or other errors, you won't get an infinite loop or a crash. Also start passing a DBG structure to all allocation calls to help with memory block tracking. * pro_expr.c: Add a public function to "reset" an expr. This allows the same expr object to be reused over and over to save memory if you're creating many many expressions for a location list. * pro_finish.c: Free any left over blocks when the user calls dwarf_producer_finish. * pro_forms.c: More support for compressed integer blocks. Modify error diagnostics so that user-defined attributes can be any type. Add support for dwarf_add_AT_ref_address which is just like dwarf_add_AT_address, only it produces a DW_FORM_ref_addr instead of DW_FORM_addr. This is needed for cross-CU die pointers. * pro_incl.h: add macros to control the spelling of relocation types. * pro_init.c: use new macros to control reloc types * pro_line.h: correct minimum instruction length on x86 * pro_opaque.h: add support for markers (see above) and also ability have libdwarf tell the caller where the string constants are so that they can be recorded as strings in case the binary output of libdwarf needs to be converted back into assembly. That's what Dwarf_P_Per_Sect_String_Attrs is about. Remove de_mem_list as it is never used. * pro_reloc_stream.c: repair prototype and comment for _dwarf_pro_reloc_name_stream64, and use relocation type macros. * pro_section.c: support for markers (see above) and for tracking inline string attributes. Add code to sort the attributes so that abbreviation table entries will be reduced. Change treatment of DW_FORM_ref_addr to be more correct. Some support for packing in the middle of sections, this will probably be removed. Also pass DBg structure to more allocations. * pro_util.h: relocation type values can't be zero. 2007-04-10 David Anderson for free() declaration. * dwarf_print_lines.c pro_section.c dwarf_query.c dwarf_alloc.c dwarf_arange.c dwarf_sort_line.c dwarf_global.c dwarf_line.c dwarf_abbrev.c dwarf_srclines_dealloc.c dwarf_frame2.c dwarf_util.c dwarf_loc.c dwarf_die_deliv.c dwarf_frame.c dwarf_macro.c: indent run with standard libdwarf options. 2007-02-20 David Anderson * libdwarf.h: Add support for .debug_ranges with dwarf_get_ranges() and dwarf_ranges_dealloc(). * dwarf_init_finish.c: Add support for .debug_ranges. * dwarf_base_types.h: Add support for .debug_ranges functions. * dwarf_alloc.c, dwarf_alloc.h: Add support for .debug_ranges alloc/dealloc. * dwarf_opaque.h: Add support for .debug_ranges. * libdwarf2.1.mm: Documented dwarf_get_ranges() and dwarf_ranges_dealloc() (rev 1.72). * libdwarf2.1.pdf: Regenerated. 2008-12-09 DavidAnderson * dwarf_alloc.c: Remove useless comments and tweak a few comments. 2008-12-08 DavidAnderson * dwarf_opaque.h: Add di_abbrev_code field to record a DIE abbreviation value so consumers can report it. * libdwarf.h: Add dwarf_die_abbrev_code() interface. * dwarf_query.c: Add dwarf_die_abbrev_code() interface. * dwarf_die_deliv.c: Set di_abbrev_code for consumers. * libdwarf2.1.mm: Documented dwarf_die_abbrev_code(). * libdwarf2.1.pdf: Regenerated. * pro_util.h: Removed gratuitous tabs. Used a space instead. 2008-12-07 DavidAnderson * dwarf.h: Entered DWARF4 defines known so far. * dwarf_opaque.h: Updated dwarf 4 section-version comment with the latest info. 2008-12-07 DavidAnderson * dwarf_original_elf_init.c: Delete unused local variables. * pro_forms.c: Delete unused local variables and initialize local variables at definition. * dwarf_pubtypes.c, dwarf_line.c: Delete accidental duplicated /* comment-start. * malloc_check.c: In the 'do nothing' case, create an extern declaration to eliminate a compiler warning. 2008-11-19 DavidAnderson * dwarf_die_deliv.c: Handle the case where DW_AT_sibling uses DW_FORM_ref_addr. * dwarf_util.c: Add a comment about DW_FORM_ref_addr. * dwarf_opaque.h: Add a comment about CU fields, comment out an unused CU header field. * dwarf_query.c: Added dwarf_die_CU_offset_range() so dwarfdump can check for additional errors. * dwarf_form.c: Clarifying a comment. * dwarf_print_lines.c: Add additional print detail on line table headers (used by dwarfdump). * libdwarf2.1.mm: Documenting the new function dwarf_die_CU_offset_range(). * libdwarf2.1.pdf: Regenerated. * libdwarf.h: Added dwarf_die_CU_offset_range() interface declaration. 2008-10-13 DavidAnderson * dwarf_frame2.c: Removed last use of DW_FRAME_LAST_REG_NUM: use dbg->de_frame_reg_rules_entry_count instead. 2008-09-30 DavidAnderson * dwarf_print_lines.c: Print corrected warning about bogus prologue length. * dwarf_line.c: Work around bogus prologue length compiler bug. * dwarf_line.h: Rename arguments. 2008-09-29 DavidAnderson * libdwarf2.1.mm: Documented requirement that dwarf_get_fde_n() dwarf_get_fde_at_pc() pass a pointer to an fde table that contains at least 1 entry. * libdwarf2.1.pdf: regenerated. * dwarf_opaque.h: Add new fields for cie/fde specific fields for eh. * dwarf_frame2.c: Initialize the new Dwarf_debug and Dwarf_Fde fields. * dwarf_frame.c: Access the new Dwarf_Fde fields. * dwarf_frame.h: Define a new Dwarf_Fde field so we keep eh and non-eh distinct. 2008-09-29 DavidAnderson * All .c files: Mechanically removed tab characters with the expand tool. 2008-09-29 DavidAnderson * libdwarf.h: DW_DLE_LINE_SET_ADDR_ERROR no longer used. The tests which generated it were bogus. * dwarf_print_lines.c: Print a warning if there are any apparently wasted bytes after the line prologue and before the line table instructions. Match the new prologue reading function prototype. * dwarf_sort_line.c: Match the new prologue reading function prototype. * dwarf_line.c: Modify the prologue reading function so it correctly finds the beginning of instructions even when there are 'wasted' bytes after the prologue. Drop bogus tests for minimum-instruction-size matching the ABI pointer size. Removing the tests removed all uses of DW_DLE_LINE_SET_ADDR_ERROR. * dwarf_line.h: Modify the prototype for the prologue reading function so it is possible for a caller to know about the possibly wasted bytes after a prologue. 2008-09-02 DavidAnderson * dwarf_init_finish.c (_dwarf_setup): Delete unused local variable 'section_error'. 2008-08-14 DavidAnderson * libdwarf2p.1.mm: Make it clearer that dwarf_get_pubnames, dwarf_get_varnames, etc return a result across all compilation units (an entire section), not just for a single compilation unit. Document version 1.68. * libdwarf2p.1.pdf: Regenerated. 2008-08-08 DavidAnderson * libdwarf2p.1.mm: Removed some long time spelling mistakes: no technical change in content. Document version 1.67. * libdwarf2p.1.pdf: Regenerated. 2008-08-05 DavidAnderson * libdwarf.h, dwarf_error.c: DW_DLA_PUBTYPE_CONTEXT was a mistake, DW_DLE_PUBTYPE_CONTEXT was intended and is now the spelling (neither is used). * dwarf_pubtypes.c dwarf_vars.c dwarf_funcs.c dwarf_global.c dwarf_weaks.c: tabs removed and previous strange formatting generated by a tool removed (4 space indent per level now present). 2008-08-05 DavidAnderson * libdwarf2.1.mm: There were numerous places the apostrophe was used incorrectly, thru is now spelled through, and a few other small typographical errors were corrected. The document revision id printed is now 1.67. There is no technical change in content. * libdwarf2.1.pdf: Regenerated. 2008-06-17 DavidAnderson * libdwarf.h: Add DW_DLE_STRP_OFFSET_BAD error code. * dwarf_form.c: Add runtime check for strp offset. * dwarf_error.c: Add DW_DLE_STRP_OFFSET_BAD error code string. * dwarf_init_finish.c, dwarf_opaque.h, dwarf_elf_access.h: Remove CR characters that crept in. 2008-06-13 DavidAnderson * libdwarf.h: Remove __SGI_FAST_LIBELF dwarf_original_elf_init.c: Remove __SGI_FAST_LIBELF and fix some indentation botches. * dwarf_init_finish.c: Fix typo in variable name introduced a few days ago. * dwarf_elf_access.c: Remove __SGI_FAST_LIBELF and fix some indentation botches. 2008-05-20 DavidAnderson * dwarf_init_finish.c: Expand tabs to spaces. 2008-05-20 DavidAnderson * dwarf_init_finish.c(dwarf_object_init): When there is no DWARF information return DW_DLV_NO_ENTRY gracefully. Thanks to Carlos Alberto Enciso for pointing out the bug. 2008-04-12 DavidAnderson * pro_section.c: Initialize local variables to zero. Change leading tabs to spaces. * pro_reloc_stream.c: Initialize local variables to zero. Change leading tabs to spaces. * pro_reloc.c: Initialize local variables to zero. Change leading tabs to spaces. 2008-04-04 DavidAnderson * dwarf_base_types.h: Removed unused macro definition. * dwarf_util.c: Altered abbreviations hash table for a small performance improvement and space saving. * dwarf_util.h: Changed declaration for space saving in dwarf abbreviations table. 2008-04-04 DavidAnderson * libdwarf.h: A trivial change to make a declaration look better. * dwarf_abbrev.h: We record tags in more than 16 bits now just in case we encounter such a thing (increased ab_tag field size), though we should not find such. * dwarf_abbrev.c: Adding a comment about the dwarf TAG value. * dwarf_util.c: Initialize local variables at declaration for safety. Removed truncation of some values: internally record more bits. Rewrote handling of the abbrev table as the old one did not scale to large numbers of abbreviations (things got very slow). * dwarf_util.h: Now has a larger field size in the argument to _dwarf_get_abbrev_for_code (not quite necessary but not harmful). * dwarf_die_deliv.c: Initializing local variables at declaration and removing truncation of bits from some uleb values. * dwarf_die_deliv.h: Increased size of ab_code field. * dwarf_opaque.h: Added a comment about abbreviations. * dwarf_base_types.h: Revised to match addition of new allocation table entry. * dwarf_alloc.h: Document macro definitions and increase one to match new table size. * dwarf_alloc.c: Arrange handling of new DW_DLA_HASH_TABLE_ENTRY (most of the work done in dwarf_util.c). 2008-02-27 DavidAnderson * libdwarf.h: Fixed minor typo in latest libdwarf.h that gcc did not complain about. Noted by Josh Fuhs. 2008-02-26 DavidAnderson * dwarf_alloc.h: Add comment giving placement of DWARF_SIMPLE_MALLOC. * pro_opaque.h: Remove de_access field, it is never used. * libdwarf.h: Add new data structures to allow reading of non-Elf object files. * dwarf_original_elf_init.c: dwarf_init(), dwarf_elf_init() moved here from dwarf_init_finish.c. * Makefile.in: Build new source files dwarf_original_elf_init.c and dwarf_elf_access.c. * dwarf_init_finish.c: All dependencies on libelf and elf have been removed. * dwarf_opaque.h: The elf related info is removed and Dwarf_Debug_s now contains a new structure (from libdwarf.h) to hide object information. * dwarf_elf_access.c: All the Elf-using code is now in this source file and elf details are kept in a struct defined and used here. Non-libelf and non-elf object access code would write a new source file with their own details using this as an example. * dwarf_elf_access.h: Prototypes for calling between dwarf_original_elf_init.c and dwarf_elf_access.c. 2008-02-18 DavidAnderson * libdwarf.h: Declare new object-access functions and structures. * dwarf_original_elf_init.c: Traditional dwarf_init() and dwarf_elf_init() are moved to this new source file. * Makefile.in: Add new source files. * dwarf_init_finish.c: Now uses the function pointers, not libelf specific fields or ifdefs. * pro_opaque.h: Remove de_access field, it is unused. * dwarf_opaque.h: New fields for new object-access functions. * dwarf_elf_access.c: New implementation details for elf access functions moved here from dwarf_init_finish.c. * dwarf_elf_access.h: New function interface so dwarf_elf_access.c and dwarf_original_elf_init.c can communicate. 2008-02-08 DavidAnderson * dwarf_print_lines.c: Added commentary to clarify that dwarf_print_lines() and _dwarf_print_lines are intentionally identical. Initialized local variables so they are alll visibly set to some sensible value. 2008-02-07 DavidAnderson * dwarf_frame.c (_dwarf_fde_section_offset): A typo in the last release made this an infinite loop. A one character change fixed it. Thanks to Carlos Alberto Enciso for noticing the bug. 2008-02-04 DavidAnderson * dwarf_incl.h, pro_incl.h: Moved #include of dwarf.h before libdwarf.h * pro_forms.c: Some newer attributes are now handled. * dwarf_print_lines.c: Removed unused #include. * dwarf_sort_line.c: Removed alloca use in favor of malloc and removed the alloca #include. * dwarf_line.c: Removed unused #include. * dwarf_line2.c: Removed unused #include. 2008-02-04 DavidAnderson * libdwarf.h: Fix commentary mistakes. 2008-02-02 DavidAnderson * libdwarf.h: Add DW_DLC_OFFSET_SIZE_64 for run-time selection of DWARF3 64bit extension producer offset generation. * libdwarf2p.1.mm: Document DW_DLC_OFFSET_SIZE_64. * pro_init.c (dwarf_producer_init): Now standard DWARF3 is the default. * configure.in: Add --enable-dwarf-format-sgi-irix for those wanting IRIX offset-style DWARF2. Add --enable-dwarf-format-strict-32bit for those wanting strictly 32bit offsets. Otherwise default to generating 64bit offsets from the producer code, but allow the DWARF3 extended 64bit offsets if the flag DW_DLC_OFFSET_SIZE_64 is turned on in the call to dwarf_producer_init(). * config.h.in: Provide undefs for the offset macros. 2008-01-25 DavidAnderson * pro_die.c: Changed leading tabs to spaces. 2008-01-23 DavidAnderson * pro_die.c: Using di_last_child field dwarf_die_link goes from O(N) to O(1) in adding a child. Thanks to Daniel Gollub for the suggestion. An omission in linking left/right children is fixed. Changed some leading TABs to spaces. * pro_opaque.h: Add di_last_child field. 2008-01-14 DavidAnderson * libdwarf2p.1.mm: Added missing backslash to correct formatting error. Thanks to Daniel Golub for pointing out the ommission. * libdwarf2.p1.pdf: Regenerated. dwarfutils-20200114/libdwarf/ChangeLog2009000066400000000000000000000451371361531463500200310ustar00rootroot000000000000002009-12-30 DavidAnderson * configure: Regenerated with autoconf 2.64. * config.guess, config.sub: Delete these. * configure.in, README: The --enable-nonshared option was coded incorrectly. The configure options are --enable-shared and --disable-nonshared work correctly. Options --disable-shared and --enable-nonshared work correctly as well (these are the default values). 2009-12-29 DavidAnderson * gennames.c: Add cast to int in printf so that the printf with * as the field width sees an int, not size_t. * Makefile.in: Add depenencies for libdwarf.so to match libdwarf.a 2009-12-26 DavidAnderson * libdwarf.h, pro_section.c, pro_reloc_symbolic.c: Reformatted a few lines that were badly formatted. Initialized local variables where a few were not initialized (this did not affect correctness, just readability). 2009-11-27 DavidAnderson * dwarf_form.c: Was an incorrect implemenation of the reading of DW_FORM_sec_offset. * libdwarf2.1.mm: Improved the documentation on reading DW_FORM_sec_offset. See dwarf_global_formref() documentation. * libdwarf2.1.pdf: Regenerate. 2009-11-27 DavidAnderson * libdwarf.h, dwarf_form.c, dwarf_query.c: Adding new form-class for the old DW_AT_MIPS_fde SGI/IRIX extension (offset into .debug_frame). 2009-11-27 DavidAnderson * libdwarf.h: Added dwarf_formexprloc() and a new error code for it. * dwarf_query.c: The new dwarf_get_form_class() function had a typo for the address class. * dwarf_form.c: dwarf_formexprloc() added so one can read DW_FORM_exprloc location expressions. * dwarf_error.c: New error added for dwarf_formexprloc(). * libdwarf2.1.mm: Document dwarf_formexprloc(). * libdwarf2.1.pdf: Regenerate. 2009-11-27 DavidAnderson * libdwarf.h: Defines typedef Dwarf_Sig8 and the new function dwarf_formsig8(). * dwarf_error.c: Now deals with the latest error codes, including a new one for dwarf_formsig8(). * libdwarf2.1.mm: Document dwarf_formsig8(). * libdwarf2.1.pdf: Regenerate. 2009-11-24 DavidAnderson * libdwarf.h: Added enum dwarf_form_class_e and dwarf_get_form_class() so clients have a simple way to get the form-class mentioned in the DWARF specification. * dwarf_query.c: Implemented dwarf_get_form_class(). * dwarf_die_deliv.c: Added dwarf_next_cu_header_b() function as more useful than dwarf_next_cu_header(). * dwarf_opaque.h: Added commentary about CU record. * dwarf_elf_access.c: Added commentary about the CU header data. * libdwarf2.1.mm: Document dwarf_next_cu_header_b() and suggest users convert to it. Document dwarf_get_form_class(). Rev 1.84 * libdwarf2.1.pdf: Regenerate. 2009-11-23 DavidAnderson * dwarf_line.c: file_name_is_full_path() did not allow for lower case in Windows root path detection (with --enable-windowspath at configure time). Now it does. 2009-11-17 DavidAnderson * gennames.c: Check the return value from fgets(). * dwarf_form.c, dwarf_util.c: Handle DW_FORM_sec_offset, new in DWARF4. * libdwarf2.1.mm: Add comment to macro example to clarify its limitation (it cannot always work). * libdwarf2.1.pdf: Regenerate. 2009-09-30 DavidAnderson * libdwarf.h: Added dwarf_insert_fde_inst_bytes() to simplify copying an fde. Added dwarf_get_cie_index() to provide a direct specific way to get a cie index for an fde. * libdwarf2.1.mm: Minor reformatting to make things easier to read. This is revision 1.82. Documented the new function dwarf_get_cie_index(). * libdwarf2.1.pdf: Regenerated. * dwarf.h: Corrected typo, DW_CFA_cfa_offset_extended_sf is really spelled DW_CFA_offset_extended_sf. Added final new attributes, tag, language. * pro_alloc.c: Reformatting a comment so the line is not so long. * libdwarf2p.1.mm: Clarified that some arguments in fde creation are MIPS/IRIX only (other targets should just pass 0). This is revision 1.27. Document the new function dwarf_insert_fde_inst_bytes(). * libdwarf2p.1.pdf: Regenerated. * config.h.in: Added HAVE_WINDOWS_PATH. * configure.in: Added --enable-windowspath to set HAVE_WINDOWS_PATH. * configure: Regenerated. * pro_section.c: Now allows use of a block of fde instructions from dwarf_insert_fde_inst_bytes(). Some indentation fixed too. * dwarf_line.c: Added detection of Windows full path if HAVE_WINDOWS_PATH defined at library build time. * pro_frame.c: Now handles dwarf3 CFA operations (but not the expression operands yet). Removed some duplicated code in a switch statement. Fixed commentary typos. Created new function dwarf_insert_fde_inst_bytes(). * pro_frame.h: Added fields to support dwarf_insert_fde_inst_bytes(). * dwarf_arange.c: dwarf_get_arange_cu_header_offset() was failing to load .debug_info, so a legitimate use of the function might crash a client. * dwarf_frame2.c: If there are CIE records but no FDEs this is not considered a 'NO ENTRY' case. It is strange but not a formal error and we might want to access the orphan CIE records (to print them when debugging a compiler, for example). * README: Documented --enable-windowspath. * dwarf_frame.c: Adding dwarf_get_cie_index() convenience function. 2009-09-09 DavidAnderson * libdwarf2p.1.mm: Improved the discussion of dwarf_transform_to_disk_form. * libdwarf2p.1.pdf: Regenerated. 2009-08-12 DavidAnderson * pro_section.c: The Dwarf_Die argument to fde creation functions is really optional (NULL is ok) and only used for an IRIX/MIPS extension. So the code now allows a NULL Dwarf_Die argument for these functions. * libdwarf2p.1.mm: Rev 1.24, 11 Aug 2009 now documents the argument as NULL for most users. * libdwarf2p.1.pdf: Regenerated Rev 1.24, 11 Aug 2009. 2009-08-07 DavidAnderson * libdwarf.h: Added to Dwarf_Regtable_Entry_s and Dwarf_Regtable_Entry_s comments. * libdwarf2.1.mm: Revised dwarf_set_frame_rule_table_size() description, making it a bit more complete. * libdwarf2.1.pdf: Regenerated, rev 1.81, 07 August 2009. 2009-08-05 DavidAnderson * libdwarf.h: Interface to dwarf_expand_frame_instructions() changed, the original could not really work right. * libdwarf2.1.mm: Documented revised dwarf_expand_frame_instructions(). * libdwarf2.1.pdf: Regenerated, rev 1.80, 05 August 2009. * dwarf_frame.c: Fixed dwarf_expand_frame_instructions(); 2009-08-05 DavidAnderson * gennames.c: Change include from getopt.h to unistd.h so the code is more universally compilable. 2009-07-24 DavidAnderson * dwarf_frame.c: Change debug printf to use libdwarf.h DW_PR macros instead of %d. 2009-07-20 DavidAnderson * libdwarf.h: Added DW_DLE_NO_ELF64_SUPPORT. * dwarf_elf_access.c: If one has no Elf64 libelf support at build time and runtime one finds an Elf64 object then we return an error (DW_DLE_NO_ELF64_SUPPORT). Pretending we could handle the elf64 was a bug. * dwarf_error.c: Adding strings for new error codes. * dwarf_elf_access.c: Add error code argument. * dwarf_elf_access.h: Add error code argument. * dwarf_original_elf_init.c: Report the correct error code instead of a generic code. 2009-07-16 DavidAnderson * libdwarf.h: Add an error message define relating to rela relocations. * dwarf_alloc.c: Add code to free malloc space (related to rela relocations). * config.h.in: Add ifdef for Sun host machines so rela processing does not segv. * dwarf_opaque.h: Add a flag to the section data to note that we malloced space when rela relocations are involved. * dwarf_elf_access.c: Refine is_32bit_abs_reloc() and is_64bit_abs_reloc() for easier debugging. Add malloc call when doing rela processing as some host libelf libraries make some libelf data areas read-only (Solaris and Irix for example). The malloc space avoids getting a segv. 2009-07-13 DavidAnderson * dwarf_elf_access.c: some cases had = where == was needed in the reloc switch code. 2009-07-05 DavidAnderson * dwarf_opaque.h: New data for .rela and unify section data information. The changes will require consumers supporting non-elf-objects to make small (hopefully simple) changes. * dwarf_init_finish.c: Note existence of .rela sections. * pro_forms.c: Explicitly allow DW_AT_const_value, DW_AT_entry_pc, DW_AT_call_file, DW_AT_call_line. * dwarf_ranges.c: Use simplified _dwarf_load_section() interface. Change an accidental C++ style // comment to oldstyle C comment. * dwarf_print_lines.c, dwarf_form.c, dwarf_query.c, dwarf_vars.c, dwarf_pubtypes.c, dwarf_frame3.c, dwarf_funcs.c, dwarf_arange.c, dwarf_global.c, dwarf_init_finish.c, dwarf_line.c, dwarf_opaque.h, dwarf_string.c, dwarf_weaks.c dwarf_util.c, dwarf_loc.c, dwarf_frame.c, dwarf_macro.c, dwarf_types.c: Use simplified _dwarf_load_section() interface. 2009-07-05 DavidAnderson * dwarf_init_finish.c: Unified some common code into a new local function , reducing file by 60 lines. * dwarf_init_finish.c: Has long checked the wrong field for duplicate debug_info and debug_abbrev. Fixed. Also noted SGI IRIX only sections by adding comments. 2009-07-04 DavidAnderson * libdwarf.h: Adding new function dwarf_CU_dieoffset_given_die(), and comments on dwarf_get_cu_die_offset_given_cu_header_offset(); * libdwarf2.1.mm: documenting dwarf_CU_dieoffset_given_die(). * libdwarf2.1.pdf: Regenerated. * dwarf_opaque.h: New structure Dwarf_Section_s consolidates section information into one struct per section with index and size so we remove many Dwarf_Debug_s fields. * dwarf_print_lines.c, dwarf_form.c, dwarf_query.c, dwarf_vars.c, dwarf_pubtypes.c, dwarf_frame3.c, dwarf_funcs.c, dwarf_alloc.c, dwarf_arange.c, dwarf_init_finish.c , dwarf_ranges.c, dwarf_line.c, dwarf_abbrev.c, dwarf_string.c, dwarf_weaks.c, dwarf_frame2.c, dwarf_util.c, dwarf_loc.c, dwarf_die_deliv.c, dwarf_frame.c, dwarf_macro.c, dwarf_types.c, Reflect Dwarf_Section_s addition using its fields. Simplify years list of SGI copyright using y-y replacing comma list. Minor reformatting for consistency with 4-space indentation. Initialize uninitialized local variables at declaration. * dwarf_addr_finder.c, dwarf_print_lines.c: Initialize 'res' local variables at declaration to DW_DLV_ERROR. * dwarf_global.c: Add dwarf_CU_dieoffset_given_die(). Reflect Dwarf_Section_s addition using its fields. Simplify years list of SGI copyright using y-y replacing comma list. Minor reformatting for consistency with 4-space indentation. Initialize uninitialized local variables at declaration. 2009-06-06 DavidAnderson * configure.in: The new option --enable_namestable switches build time to generate a runtime binary search in the dwarf_get_TAG_name() etc functions instead of the default switch statement (for the rare case one knows a compiler generates poor switch code). * configure: regenerated. * libdwarf.h: Correct format mistakes and omissions in the Dwarf_Regtable_Entry3_s comments. Add prototypes for dwarf_get_TAG_name() and the related new functions. * dwarf_frame.c: Add {} to clarify some 'if' ranges. Remove code updating the DW_FRAME_CFA_COL row when finishing up establishing the current frame table. The code should never have been there. Fixed some indentation of function formal parameters. Removed use of DW_FRAME_CFA_COL and use de_frame_cfa_col_number instead. In dwarf_get_fde_info_for_reg (the older interface) correctly return the cfa table column in the 'old style'. * gennames.c: Copied from dwarfdump.c (with changes). This generates dwarf_names.c so that libdwarf has functions like dwarf_get_TAG_name() which returns functions like dwarf_get_TAG_name() which returns the tag as a string (through a pointer argument). * dwarf.h: The first word of a comment is now capitalized (1 place). * common.c: New, used by gennames.c. * common.h: New, used by gennames.c * Makefile.in: Now contains changes which build and run gennames and create dwarf_names.o (which is part of libdwarf). * libdwarf2.1.mm: Document the new libdwarf functions. * libdwarf2.1.pdf: Regenerated as rev 1.76, 6 June 2009. 2009-06-05 DavidAnderson * dwarf.h: added new DWARF4 attribute (etc) defines. 2009-05-10 DavidAnderson * dwarf_frame.c: Remove use of DW_FRAME_UNDEFINED_VAL in favor of the value in the dbg structure. Adding comments about the meaning of an error case. 2009-05-07 DavidAnderson * Makefile.in: Ensure temp files all get deleted. 2009-05-04 DavidAnderson * dwarf_die_deliv.c: Update _dwarf_get_size_of_val() call (with its new address_size argument). * dwarf_frame.c: Use the new ci_address_size instead of de_pointer_size. * dwarf_frame.h: Added ci_address_size to cie in preparation for this value in DWARF4. * dwarf_util.h: Adding address_size functions and arguments declarations so address_size can vary by CU. * dwarf_util.c: Adding address_size functions and arguments so address_size can vary by CU. * dwarf_loc.c: Adding function dwarf_loclist_from_expr_a() as a version with an address size argument. * dwarf_frame2.c: Now initializes new ci_address_size field. * dwarf_line.c: Now uses address size for CU instead of default de_pointer_size. * dwarf_ranges.c: File left out of svn before. Implements dwarf_get_ranges() and dwarf_get_ranges_a(), the latter is new with address size passed in via a DIE pointer. * dwarf_arange.c: Added commentary. Removed erroneous insistence that every aranges group have the same address_size as the main elf object. * dwarf_query.c: Adding address size to internal calls. * dwarf_print_lines.c: Added '(file number is %d)' to -l -v -v -v output as the file number and traditional C zero-origin index index of a line table header are not the same value (see DWARF3 documentation, the end of section 6.2.5.3). * libdwarf2.1.mm: Documented dwarf_loclist_from_expr_a() and dwarf_get_ranges_a(). * libdwarf2.1.pdf: Regenerated. * libdwarf.h: Add commentary. Add dwarf_loclist_from_expr_a() and dwarf_get_ranges_a() interfaces so address_size passed in. 2009-04-04 DavidAnderson * libdwarf.h, dwarf_frame.c: Added dwarf_set_frame_cfa_value(). Added dwarf_set_frame_rule_initial_value() as proper spelling of dwarf_set_frame_rule_inital_value(), keeping the old spelling for compatibility. * libdwarf2.1.mm: Documented Added dwarf_set_frame_cfa_value(), corrected spelling to dwarf_set_frame_rule_initial_value(). * libdwarf2.1.pdf: Regenerated. * dwarf_opaque.h: Added field de_frame_cfa_col_number so that we do not need to use magic macros at execution time. * dwarf_init_finish.c: Now sets de_frame_cfa_col_number, de_frame_same_value_number, and de_frame_undefined_value_number. 2009-02-02 DavidAnderson * dwarf.h: Added dwarf extensions reported by John Bishop. 2009-03-30 DavidAnderson * dwarf.h: Added dwarf extensions reported on the dwarf-workgroup mailing list by John DelSignore. 2009-03-19 DavidAnderson * libdwarf.h: Expanded comments. * dwarf_die_deliv.c: Expanded comments. 2009-03-16 DavidAnderson * libdwarf.h: Fixed several instances of inconsistent indentation. Documented arguments to dwarf_uncompress_integer_block(). 2009-02-17 DavidAnderson * dwarf_print_lines.c,dwarf_line.c,dwarf_frame.c: C99-isms of // comments and declarations-in-code do not belong in libdwarf. 2009-02-14 DavidAnderson * libdwarf.h: Add support for compile-time definition of the format for Dwarf_Unsigned types. Using macros for DW_PR_DUx etc. * dwarf_print_lines.c: Use the DW_PR_DUx macros. * configure.in: Define --enable-nonstandardprintf * config.h.in: new #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT * configure: Regenerated. * config.guess, config.sub: Latest version from GNU. * dwarf_line.c: Use the DW_PR_DUx macros. * dwarf_frame2.c: Use the DW_PR_DUx macros. * README: document --enable-nonstandardprintf 2009-02-13 DavidAnderson * libdwarf.h: Added argument to dwarf_print_lines() for better error reporting. Added dwarf_check_lineheader() which allows some error reporting when not calling dwarf_print_lines(). * dwarf_print_lines.c: Implements dwarf_check_lineheader() now. * dwarf_sort_line.c: Match up with new arguments to dwarf_read_line_table_prefix(). * dwarf_line.c: Implement new arguments to dwarf_read_line_table_prefix() for better error reporting. Allow erroneous ARM-compiler line table header to be used. * dwarf_line.h: Adding new argument to dwarf_read_line_table_prefix so we can report back on minor errors in the line table prefix. 2009-01-31 DavidAnderson * libdwarf.h: Corrected DW_DLE_LAST. * dwarf_frame.c: Remove accidental use of C99 mid-block variable definition. dwarfutils-20200114/libdwarf/ChangeLog2010000066400000000000000000000217721361531463500200200ustar00rootroot000000000000002010-10-13 DavidAnderson * dwarf.h: Added DW_LANG_Go as 0x0015 per discussion on mailing list. 2010-09-29 DavidAnderson * README: Document that there is no install target and update some of the old references to postscript to refer to pdf. * Makefile.in: A dummy install target provided though it gets ignored by make. 2010-09-20 DavidAnderson * libdwarf/libdwarf.h: Added commentary about markers. * libdwarf/libdwarf2p.1.mm: Documented the marker calls. * libdwarf/libdwarf2p.1.pdf: Regeenerated, ver 1.29. 2010-06-30 DavidAnderson * dwarf.h: Add DW_ISA_ARM values for DW_LNS_set_isa. 2010-06-01 DavidAnderson * README: Document issues with building on MacOSX and how to deal with them. * Makefile.in: Added comment about ar -s for MacOSX users. * dwarf.h: Added comment about the gap in FORM number use just before 0x20. 2010-03-30 DavidAnderson * dwarf_frame2.c: Tightned up a harmless error message string and deleted an unused local variable. * dwarf_harmless.c: Detected more errors in the implementation and fixed them. * dwarf_elf_access.c: If EM_MIPS not defined, define it to 8, the standard value for EM_MIPS. Refine the rela relocations code for MIPS 64 BE vs LE. * dwarf_arange.h: Added new fields to properly represent segments in aranges as documented in DWARF4. * dwarf_arange.c: dwarf_get_aranges was thinking an entry with 0,0 (end of a set) was the end of the aranges for a CU. But that is not guaranteed by the DWARF standards, there can be multiple sets in one CU, see the standard, section 7.20 (DWARF2,3,4). Created local function, removing lots of duplicated code. Added some support for DWARF4 segment value in tuples. Added dwarf_get_arange_info_b() so all DWARF4 information can be retrieved by client code. * libdwarf.h: Aded new interface dwarf_get_arange_info_b(), 2010-03-28 DavidAnderson * libdwarf.h: Adding dwarf_get_harmless_error_list(), dwarf_insert_harmless_error(), and dwarf_set_harmless_error_list_size() functions. Some errors that are detectable are not sufficient to warrant rejecting an object or refusing to process it. * dwarf_harmless.c: Implementing the harmless error functions. * dwarf_harmless.h: Declaration of the libdwarf_internal dwarf_harmless_init and dwarf_harmless_cleanout functions. * dwarf_error.c: Added DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE error string. * dwarf_util.h: Clarify some comments on READ_AREA_LENGTH macro. * dwarf_opaque.h: Add structure and field to record harmless errors for a dbg. * dwarf_frame.h: Add commentary. Change ci_length from Dwarf_Word to Dwarf_Unsigned for consistency with other such length fields. * Makefile.in: Add dwarf_harmless.o to the list of objects. * dwarf_alloc.c: Add call to dwarf_harmless_cleanout() on close of a dbg. * dwarf_init_finish.c: Add call to dwarf_harmless_init to initialize the fields for recording harmless errors. * dwarf_frame2.c: Add handling of Arm "armcc+" augmentation string. Create validate_length() local function to check that the fde/cie length matches the requirements of the specification, implementing the DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE test (a harmless error). Removed an earlier formally incorrect test. * libdwarf2.1.mm: Documented the harmless error calls. The version is now 1.90. * libdwarf2.1.pdf: Regenerated as 1.90. 2010-02-14 DavidAnderson * dwarf.h: Add GNU template defines. * libdwarf.h: Add new error code DW_DLE_NOT_REF_FORM for the DWARF 4 case where DW_FORM_data4/8 no longer valid global reference forms. * libdwarf2.1.mm: Document the manner that DW_OP_implicit_value is returned as a location description set. * libdwarf2.1.pdf: Regenerate. Rev 1.89. * dwarf_error.c: Add two new DW_DLE error strings. * dwarf_frame.h: define DW_DEBUG_FRAME_VERSION4 for DWARF4 support. Add address size and segment size fields to the internal CIE structure. * dwarf_query.c: The form-class code was not correct, DWARF4 has DW_FORM_sec_offset, not DWARF3. Some places did not use the CU context address size when reading an address. * dwarf_form.c: Use the CU-context address size instead of the overall object address/offset size. Initialize all local variables at the point of declaration. Refine some commentary. Use the CU version number to guide processing of some FORMs. * dwarf_print_lines.c, dwarf_query.c: Use the CU-context address size instead of the overall object address/offset size. Handle DW_LNE user extensions as well as possible. * dwarf_arange.c: Delete some erroneous code (already ifdefd out) as the address size need not match the de_pointer_size. If segment-selector non-zero, read it properly. DWARF2 and DWARF3 left this documented in an incorrect and unusable fashion (DWARF4 documents it properly). * dwarf_die_deliv.c: Delete erroneous code (previously ifdefd out) as the address size need not match the de_pointer_size. * dwarf_sort_line.c, dwarf_line.c: Deal with DW_DLE extended line operations past those defined by the standard (such as user-defined operations). * dwarf_line.h: For user-defined line extended operations, provide a sanity check of DW_LNE_LEN_MAX. * dwarf_base_types.h: Add DW_CIE_VERSION4 for DWARF4. Add other defines so each defined version number (sections differ) has a name for the relevant section. * dwarf_frame2.c: Add address size to argument lists so the proper CIE address size (a new field in DWARF4 CIEs) are honored. Also read the new DWARF4 segment_size field. Use the address size instead of the object-derived de_pointer_size. * dwarf_util.c: Return address_size instead of de_pointer_size. * dwarf_loc.c: DWARF4 uses DW_FORM_sec_offset, not DW_FORM_data4 or DW_FORM_data8 when specifying offsets to other sections. Add DWARF4 DW_OP_implicit_value and DW_OP_stack_value. * dwarf_frame.c: Initialize a local variable at the point of declaration. 2010-02-04 DavidAnderson * libdwarf2.1.mm: Fix a spelling error. * libdwarf2.1.mm: Regenerate. Rev 1.88. 2010-02-01 DavidAnderson * dwarf_frame.c: The DW_CFA_remember_state and DW_CFA_restore_state operations were not recording/restoring the cfa_rule, now they do. 2010-01-27 DavidAnderson * dwarf_form.c: form_refsig8() had an uninitialized local variable. 2010-01-25 DavidAnderson * libdwarf2.1.mm: Rev 1.87. Improved the discussion of frame information. * libdwarf2.1.pdf: regenerated. 2010-01-25 DavidAnderson * pro_opaque.h, pro_init.c, pro_section.c, pro_reloc_stream.c, pro_reloc_symbolic.c: Rename the function pointer members de_func and de_func_b to de_callback_func and de_callback_func_b respectively. 2010-01-17 DavidAnderson * dwarf.h, libdwarf.h: Updated commentary about frame interfaces. * libdwarf2.1.mm: New descriptions of DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3. Document rev 1.86 . * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.mm: Fixed a couple of typos. Rev 1.28. * libdwarf2p.1.pdf: Regenerated. * configure.in: Added support for configure --enable-oldframcol. * config.h.in: Added support for configure --enable-oldframcol. * dwarf_init_finish.c: Added support for configure --enable-oldframecol (see DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3). By default the frame column is now DW_FRAME_CFA_COL3. --enable-oldframecol changes the default to DW_FRAME_CFA_COL. * configure: Regenerated. * dwarf_opaque.h: Added one blank line and deleted one, hopefully aiding clarity. * dwarf_frame.c: Added commentary about the frame interfaces to emphasize the newer ones. 2010-01-13 DavidAnderson * dwarf_print_lines.c: Changed 'include files count' to 'files count'. 2010-01-04 DavidAnderson * pro_section.c, pro_opaque.h: A pretty-print tool generated some odd formatting (long ago) and there were silly blank lines present as well. This makes things more readable. 2010-01-03 DavidAnderson * common.h, common.c: Remove line end characters. Update copyright for 2010. * All other files: Update copyright year. dwarfutils-20200114/libdwarf/ChangeLog2011000066400000000000000000000371231361531463500200160ustar00rootroot000000000000002011-12-14 DavidAnderson * libdwarf.h, dwarf_error.c: Add a new error code for DW_OP location codes. * dwarf_loc.c: Implement support for new DW_OP_GNU codes. 2011-12-13 DavidAnderson * dwarf.h: Added some GNU extensions. * libdwarf.h: Added dwarf_lineoff_b() as dwarf_lineoff() wrongly returns a signed column number. Added dwarf_add_lineentry_b() as preparation for creating DWARF3/4 output. * dwarf_line.h: Added new struct fields to accomodate DWARF3/4 isa and discriminator fields. * dwarf_line.c: Now deals with the VLIW line calculations in DWARF4. Adds support for computing the discriminator and isa fields. Adds dwarf_lineoff_b() (and dwarf_lineoff is now deprecated). Adds dwarf_prologue_end_etc() which returns some DWARF3/4 line fields. * dwarf_print_lines.c: Adds handling of DWARF3/4 line operations and fields and prints the details. * libdwarf2.1.mm: Documents the new functions in dwarf_line.c Version set to 2.02. * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.mm: Documents the new function dwaf_add_line_entry_b(). Version set to 1.32. * libdwarf2p.1.pdf: Regenerated. * pro_incl.h: Add parentheses so the WRITE_UNALIGNED macro works correctly in all circumtances. * pro_opaque.h: Add DEBUG_RANGES and dEBUG_TYPES to the list of sections we could generate. Define struct Dwarf_P_Line_Inits_s to hold initialization values for line table data so we can later make the choices at runtime rather than compile time. The new struct is a field of the Dwarf_P_Debug struct. * pro_line.h: Added some DWARF3/4 support and preparations for emitting DWARF3/4. * pro_line.c: Define dwarf_add_line_entry_b() for DWARF3/4 line fields, and _dwarf_init_default_line_header_vals() to provide a default set of values, the defaults match what was previously done. Add support for the new DWARF3/4 line table fields. * pro_section.c: Add the beginnings of support for creating new DWARF3/4 sections and the new standard opcodes. Move the field-writing code to small functions making the line table writing smaller and easier to read. Added the beginnings of allowing writing DWARF3/4 line table fields. Some if() missing {} were modified by adding {} to avoid future problems. 2011-12-08 DavidAnderson * dwarf_frame.c: Corrected a typo by adding a space to a comment. * libdwarf2p.1.mm: A sentence about dwarf_lne_end_sequence() was missing its introductory words. New version is 1.31. * libdwarf2p.1.pdf: Regenerated. 2011-11-02 DavidAnderson * dwarf.h: Spelling fix: specfic->specific. Rearranged a few comments about MIPS/SGI for a better appearance. 2011-10-29 DavidAnderson * dwarf_alloc.c: Add support for the .debug_types section. * dwarf_arange.c,dwarf_global.c: Add commentary about debug_info vs debug_types and a new argument to an internal function. * dwarf_arange.h,dwarf_global.h: Add comment that this is debug_info related only. * dwarf_die_deliv.c: Now handles .debug_types as well as .debug_info, and context information for the two sections is kept seperate. * dwarf_elf_access.c: Add a check for relocations of .debug_types. * dwarf_error.c: Added error strings related to .debug_types. * dwarf_form.c: Changes for .debug_types, mainly due to removing 'info_' from certain struct member names. * dwarf_init_finish.c: Notice the .debug_types section. New function dwarf_get_section_max_offsets_b() returns the size of debug_types (added to existing arguments). * dwarf_opaque.h: Fields named *_info_* have the info_ removed as they apply to debug_types as well. A new struct Dwarf_Debug_InfoTypes holds the data for either of .debug_types and .debug_info sections. Separating them so the sections can be accessed simultaneously. Moved data items from Dwarf_Debug to the new struct. DIE structs now have a 'is_info' field so a CU and a DIE know whether they are from .debug_info or .debug_types. * dwarf_query.c: The query functions now work for debug_info and debug_query as appropriate. * dwarf_util.h: Added _dwarf_load_debug_types() and altered a couple internal function prototypes with an 'is_info' flag argument. * dwarf_util.c: Added _dwarf_load_debug_types(). Altered functions so the deal with .debug_types or .debug_info as appropriate. * libdwarf.h: Added debug_types error codes. Added dwarf_siblingof_b() and dwarf_offdie_b() and Added dwarf_next_cu_header_c() and dwarf_get_cu_die_offset_given_cu_header_offset_b() to account for .debug_types or .debug_info as required. Added dwarf_get_die_infotypes_flag() so client code can know if a DIE is debug_info or debug_types based. Added dwarf_get_section_max_offsets_b(), adding a debug_types size argument. * libdwarf2.1.mm: Documented the new functions. New version is 2.0 (somewhat arbitrarily changed from 1.x to 2.0) * libdwarf2.1.pdf: Regenerated 2011-10-26 DavidAnderson * Makefile.in, README: Added Make settings of PREINCS POSTINCS PRELIBS, POSTLIBS to simplify building when libdwarf or libelf are not in the normal locations. Documented usable ways to deal with unusual situations at build time. 2011-10-09 DavidAnderson . * dwarf_die_deliv.c, dwarf_elf_access.c: Fix bad indentation. 2011-10-05 DavidAnderson . * dwarf_die_deliv.c: When relocations fail, record a 'harmless error' and continue the CU loading. No way to be sure the error is really harmless, of course. But it seems to often be harmless. For some if() tests add {} to make the clause extent clear. * dwarf_harmless.c: Add a comment prefix to dwarf_harmless_init(). 2011-10-03 DavidAnderson * dwarf_line.c: Introduce {} in a test to avoid future mistakes. 2011-09-23 DavidAnderson * dwarf_arange.c: Test for a zero address-size: that indicates broken dwarf generation. * dwarf_line.c: Test for irrational line number header data and error off with DW_DLE_LINE_NUMBER_HEADER_ERROR if we find it. Add accidentally-omitted check for version 4. * dwarf_error.c, libdwarf.h: New error code DW_DLE_LINE_NUMBER_HEADER_ERROR. 2011-09-16 DavidAnderson * dwarf_elf_access.c: Give up relocating if the Elf symtab header sh_entrysize is zero, and refine the test for invalid symbol index to be a >= test. * dwarf_error.c: Define text message for DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO. * libdwarf.h: New error code DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO. 2011-09-15 DavidAnderson * dwarf_elf_access.c: Adding fields to the object structs dwarf uses and using them for error checks when processing relocations. * dwarf_error.c: Adding descriptions of new error messages for Elf object file interpretation problems. * dwarf_init_finish.c: Adding 'entrysize' field about objects do dwarf_elf_access.c can check for object and relocation data errors and avoid a coredump. And we memset() a struct to ensure there are no uninitialized contents. * dwarf_opaque.h: Adding new dss_entrysize and dss_reloc_entrysize fields so elf error checks can be added to dwarf_elf_access.c. These changes mean you must recompile all of libdwarf source, not just a subset, when rebuilding (the first time one sees this change). * libdwarf.h: Adding entrysize element to Dwarf_Obj_Access_Section_s. Non-elf object formats can just set this field zero and ignore it. Added new elf-specific error codes for the new checks in dwarf_elf_access.c. 2011-09-14 DavidAnderson * BLDLIBDWARFTAR: Moved a local disk file. Irrelevant to everyone but DA. * dwarf_arange.c: check that the address_size and segment selector size fields are sensible. * dwarf_die_deliv.c,dwarf_frame2.c: Give DW_DLE_ADDRESS_SIZE_ERROR or DW_DLE_CU_ADDRESS_SIZE_BAD if the address size read from a section is obviously wrong. Similarly for a bad segment-selector-size give DW_DLE_SEGMENT_SIZE_BAD. * dwarf_error.c: Added text for the DW_DLE_SEGMENT_SIZE_BAD error. * dwarf_frame.c: If dwarf_set_default_address_size() is handed an address_size that we cannot handle, ignore the input so we don't wind up coredumping the library or consumer code. * libdwarf2.1.mm: Updated list of error codes a little bit. Rev 1.99 * libdwarf2.1.pdf: Regenerated. 2011-09-08 DavidAnderson * dwarf_frame.c: Fixed bad indents. 2011-09-02 DavidAnderson * libdwarf2.1.mm: Document the new function dwarf_set_default_address_size(). Updated revision to 1.97. * libdwarf2.1.pdf: Regenerated. * dwarf_frame.c: Implement dwarf_set_default_address_size(). * libdwarf.h: Declare the new function dwarf_set_default_address_size(). * dwarf_form.c(dwarf_formref): Removed c99-ish declaration so C90 can compile the code. * Makefile.in, configure.in: If building shared lib CFLAGS gets -fPIC added in. * configure: Fegenerated. * dwarf_loc.c: New test returns DW_DLE_LOC_BAD_TERMINATION in case of compiler bug in location expression. * dwarf_error.c, libdwarf.h: Define and document the new error. * pro_opaque.h: Fixed a bad indent. 2011-06-12 DavidAnderson * libdwarf.h: Added dwarf_producer_init_c() and its callback functions. Adds a user_data void* to the init and callback functions for user convenience. * libdwarf2p.1.m: Documented dwarf_producer_init_c(). Rev 1.30. * libdwarf2p.1.pdf: Regenerated * pro_init.c: Implement dwarf_producer_init_c(). * pro_opaque.h: Add fields for dwarf_producer_init_c(). * pro_reloc_stream.c: Implement dwarf_producer_init_c() callback. * pro_reloc_symbolic.c: Implement dwarf_producer_init_c() callback. * pro_section.c: Implement dwarf_producer_init_c() callback. 2011-06-09 DavidAnderson * dwarf_form.c: Code getting access to CU context and dbg was repeated many times. Refactored the common code into a file-static subprogram. 2011-06-08 DavidAnderson * libdwarf2.1.mm,libdwarf2.1.pdf: Now discusses DW_AT_data_member_location in the context if dwarf_loclist_n(). Rev 1.96 2011-06-08 DavidAnderson * dwarf_init_finish.c: Inserted missing include of dwarf_harmless.h. 2011-06-07 DavidAnderson * dwarf_elf_access.c: Added EM_QUALCOMM_DSP6 machine so that relocations work on a Qualcomm relocatable object in the dwarf regressiontests. * dwarf_util.c: Fixed indent problems added in previous change. 2011-06-07 DavidAnderson * dwarf_util.c(_dwarf_get_abbrev_for_code): If there is no section padding the code could read-from-memory one past the end of the section which could (in very rare circumstances) coredump an application. In addition, earlier in the same funcion we did not account for the case where we had already read to end of section. Both fixed. 2011-06-06 DavidAnderson * dwarf_error.c: Fix a typo in an error string. * dwarf_query.c: Implement the new function dwarf_get_verion_of_die(). * libdwarf.h: Add prototype for dwarf_get_verion_of_die(). * libdwarf2.1.mm: for dwarf_form_{s,u}data, mention the DW_FORM_data{4,8} class ambiguity. Document the new function dwarf_get_verion_of_die(). Document version now 1.95. * libdwarf2.1.pdf: Regenerate. 2011-06-04 DavidAnderson * NEWS: Mention the non-elf documentation oversight. * dwarf_arange.c,dwarf_elf_access.c, dwarf_frame3.c, dwarf_funcs.c,dwarf_global.c,dwarf_init_finish.c, dwarf_line.c,dwarf_loc.c,dwarf_macro.c,dwarf_print_lines.c, dwarf_pubtypes.c,dwarf_query.c,dwarf_ranges.c,dwarf_string.c, dwarf_types.c,dwarf_vars.c, dwarf_weaks.c: Everything loading a section now checks the result for 'empty' and returns DW_DLV_NO_ENTRY explicitly. This makes it easier to do nothing safely when there is no data. 2011-06-04 DavidAnderson * dwarf_line.c (_dwarf_internal_srclines): Created new local functions to unify some repeated code in into function calls. One of the earlier inline-repetitions was coded wrong. Added {} to ensure clarity on the intended scope a couple places. Added initializers to a couple of local variables. 2011-06-04 DavidAnderson * dwarf_alloc.c: Added include "dwarf_harmless.h" so a prototype is visible here. * dwarf_form.c (dwarf_convert_to_global_offset,dwarf_global_formref): Deleted unused local variables. * dwarf_frame.c (dwarf_initialize_fde_table): Uses local instead of ignoring it (avoids compiler warning). * dwarf_frame2.c (_dwarf_get_fde_list_internal): Delete unused local variable. * dwarf_line.c (dwarf_srcfiles): Call uses variable expected signedness now, avoiding compiler warning. * dwarf_print_lines.c: Printf was missing %, gcc -Wall pointed out the mistake. 2011-04-23 DavidAnderson * pro_error.c (_dwarf_p_error): The code attempting to deal with an unexpected error code was doing an inappropriate cast and an inappropriate (possibly out-of-bounds) reference to an array of strings. Removed the cast and removed the questionable array reference. * dwarf_frame.c: A couple lines were indented badly. Fixed the indentation. * pro_line.h: Now __x86_64 also gets MIN_INST_LENGTH 1 2011-03-29 DavidAnderson * everything: Redid all indentations for consistency. Updated copyrights. Interfaces did not change, existing clients should not encounter difficulty. 2011-03-13 DavidAnderson * libdwarf.h, dwarf_error.c: Added DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH. 2011-01-20 DavidAnderson * dwarf.h: Added some Apple attribute extensions. 2011-01-13 DavidAnderson * dwarf_print_lines.c: Handles DW_FORM_exprloc now. With -vvv it now prints the dwarf version of the line table header. * dwarf_line.c: Handles DW_FORM_exprloc now. 2011-01-13 DavidAnderson * libdwarf.h: Added new function dwarf_get_die_address_size(). * libdwarf2.1.mm: Documented new function dwarf_get_die_address_size(). Rev 1.91, 12 January 2011 * libdwarf2.1.pdf: Regenerated. * dwarf_form.c: Corrected handling of DW_FORM_exprloc. * dwarf_query.c: Implemented dwarf_get_die_address_size(). Corected handling of DW_FORM_exprloc. * dwarf_util.c: Added handling of DW_FORM_exprloc and DW_FORM_flag_present. dwarfutils-20200114/libdwarf/ChangeLog2012000066400000000000000000000162201361531463500200120ustar00rootroot000000000000002012-11-30 David Anderson * dwarf.h: defines for some added DW_OP_GNU operators * dwarf_loc.c: Added support for some DW_OP_GNU operators. 2012-11-29 David Anderson * dwarf_elf_access.c,dwarf_init_finish.c,dwarf_loc.c, dwarf_reloc_arm.h,dwarf_reloc_x86_64.h,libdwarf.h: Fix indents so dicheck gives no warnings. 2012-11-29 David Anderson * dwarf_addr_finder.c: Add const to a couple const arrays. * gennames.c: Add const to a couple const variables. * dwarf_form.c: dwarf_formflag() was incorrectly returning 1 instead of the actual flag value when non-zero flag value. Now returns the real flag byte value. * dwarf_opaque.h: Moved debug_section area info into a new array in Dwarf_Debug struct. * dwarf_init_finish.c: Instead of a file-static array, the array is moved to the Dwarf_Debug struct and accesses are adjusted to match. * pro_section.c: Add const to an array declaration. * libdwarf2.1.mm: Updated dwarf_formflag() documentation. Now version is 2.06. * libdwarf2.1.pdf: Regenerated. 2012-11-22 David Anderson * dwarf_loc.c: Removed the last dbg->de_length_size instances from _dwarf_get_locdesc() to reflect the incoming argument with the offset size (length size). 2012-11-21 David Anderson * dwarf_loc.c: Updated argument list and implementation for dwarf_loclist_from_expr_b(), adding offset size (length size). * libdwarf.h: Updated argument list for dwarf_loclist_from_expr_b(). * libdwarf2.1.mm: Updated dwarf_loclist_from_expr_b() documentation. Now version is 2.05. * libdwarf2.1.pdf: Regenerated. 2012-11-20 David Anderson * dwarf_line.h: Fixing two small formatting inconsistencies. 2012-11-17 David Anderson * dwarf_original_elf_init.c: Expanded comment about HAVE_ELF_C_READ_MMAP (which is not settable by configure and is not really needed). * configure regenerated with autoconf 2.69 * libdwarf2.1.mm: Document dwarf_encode_leb128() and and dwarf_encode_signed_leb128(). * libdwarf2.1.pdf: Regenerated. 2012-11-17 David Anderson * dwarf_arange.c,dwarf_base_types.h,dwarf_die_deliv.c, dwarf_elf_access.c,dwarf_form.c,dwarf_frame.c, dwarf_frame2.c,dwarf_harmless.c,dwarf_init_finish.c, dwarf_line.c,dwarf_line.h,dwarf_loc.c,dwarf_macro.c, dwarf_original_elf_init.c,dwarf_print_lines.c,dwarf_query.c dwarf_ranges.c,dwarf_reloc_arm.h,dwarf_reloc_mips.h, dwarf_reloc_ppc.h,dwarf_reloc_ppc64.h,dwarf_reloc_x86_64.h, dwarf_util.c,dwarf_util.h,pro_forms.c,pro_frame.c, pro_incl.h,pro_init.c,pro_section.c: Update copyright on files changed recently. 2012-11-15 CarlosAlbertoEnciso * dwarf.h: Incorrect comments for registers (64 to 108). * dwarf_arange.c: Consistent layout for if statements. * dwarf_base_type.h: Minor comment type. * dwarf_die_deliv.c: Consistent layout for if and while statements. * dwarf_elf_access.c: Consistent layout for if statements. For Windows, include header files with relocation definitions. Populate new fields 'type' (section type) and 'info' (target section for relocation) in data structure 'Dwarf_Obj_Access_Section_s'. Minor typo error in function 'is_32bit_abs_reloc' for the case 'EM_PPC64', to use the correct symbol 'R_PPC64_DTPREL32' and 'R_PPC64_DTPREL32'. * dwarf_form.c: Consistent layout for if statements. * dwarf_frame.c: Consistent layout for if, for and while statements. * dwarf_frame2.c: Consistent layout for if statements. * dwarf_harmless.c: Consistent layout for if and for statements. * dwarf_init_finish.c: Consistent layout for if statements. Use HAVE_ELF_H, HAVE_LIBELF_H, HAVE_LIBELF_LIBELF_H to control the inclusion of the libelf symbols. New function 'add_debug_section_info' and new data structure 'dbg_sect_s' to deal properly with .rel and .rela section types independently of the section name. The new algorithm to setup the debug sections is implemented in '_dwarf_setup'. * dwarf_line.c: Consistent layout for if statements. * dwarf_line.h: Consistent layout for if statements. * dwarf_loc.c: Consistent layout for if and switch statements. * dwarf_macro.c: Consistent layout for if statements. * dwarf_original_elf_init.c: Consistent layout for if statements. * dwarf_print_lines.c: Consistent layout for if statements. * dwarf_query.c: Consistent layout for if and switch statements. * dwarf_ranges.c: Consistent layout for if and for statements. * dwarf_reloc_arm.h: New file; relocations definitions for ARM. * dwarf_reloc_mips.h: New file; relocations definitions for MIPS. * dwarf_reloc_ppc.h: New file; relocations definitions for PPC. * dwarf_reloc_ppc64.h: New file; relocations definitions for PPC64. * dwarf_reloc_x86_64.h: New file; relocations definitions for X86_64. * dwarf_sort_line.c: Consistent layout for while statements. * dwarf_util.c: Consistent layout for if, for and while statements. New functions 'dwarf_encode_leb128', 'dwarf_encode_signed_leb128' to encode a value as unsiged LEB128 and signed LEB128. * dwarf_util.h: Consistent layout for the macros DECODE_LEB128_UWORD, DECODE_LEB128_SWORD, SKIP_LEB128_WORD, CHECK_DIE, READ_UNALIGNED, SIGN_EXTEND, READ_AREA_LENGTH to include proper tabbing. * libdwarf.h: Consistent layout for some typedef definitions. New fields 'type' (section type) and 'info' (target section for relocation) in data structure 'Dwarf_Obj_Access_Section_s'. Prototypes for new functions 'dwarf_encode_leb128' and 'dwarf_encode_signed_leb128', defined in dwarf_util.c. * pro_forms.c: Consistent layout for if statements. * pro_frame.c: Consistent layout for if statements. * pro_incl.h: For Windows, include the stdafx.h header file. * pro_init.c: Consistent layout for if statements. * pro_section.c: Consistent layout for if statements. 2012-11-14 DavidAnderson * dwarf_loc.c: DW_OP_GNU_implicit_pointer requires a version stamp to work correctly. Created a new function dwarf_loclist_from_expr_b() to allow clients to expicitly pass the version stamp. Most clients can continue to use the old interface. * libdwarf.h: Declaring new function dwarf_loclist_from_expr_b() * libdwarf2.1.mm: Documenting dwarf_loclist_from_expr_b() * libdwarf2.1.pdf: Regenerated. 2012-10-31 DavidAnderson * CODINGSTYLE: Added some small details here. 2012-04-04 DavidAnderson * libdwarf.h: A pointer "*" was right next to a "/*" so a space introduced between them for clarity. Fixed comments on DW_DLC_SIZE_64 and DW_DLC_SIZE_32. * dwarf_die_deliv.c: Two local variables were declared in the middle of code, accidentally creating C99 dependencies. Both trivially fixed with no change in logic. 2012-01-01 DavidAnderson * A new year starts. dwarfutils-20200114/libdwarf/ChangeLog2013000066400000000000000000000301451361531463500200150ustar00rootroot000000000000002013-12-26 David Anderson * pro_section.c, pro_types.c, pro_vars.c, pro_weaks.c, pro_forms.c, pro_frame.c,pro_funcs.c,pro_init.c,pro_line.c,pro_macinfo.c, pro_pubnames.c,pro_reloc.c,pro_reloc_stream.c,pro_reloc_symbolic.c, pro_expr.h,pro_macinfo.h,pro_reloc.h,pro_reloc_stream.h, pro_reloc_symbolic.h,pro_section.h,pro_types.h,pro_util.h: Remove trailing whitespace from the code. 2013-11-24 David Anderson * pro_expr.c(dwarf_add_expr_gen): Moved use of a pointer to be after where the pointer tested for NULL. * pro_forms.c(local_add_AT_address): Moved use of a pointer to be after where the pointer tested for NULL. Both bugs found by the STACK code analysis tool from MIT. 2013-10-31 David Anderson * dwarf_error.c: Added DW_DLE_AT_FIXUP_NULL and DW_DLE_AT_FIXUP_DUP. * libdwarf.h.in: Added those two defines plus dwarf_add_AT_reference_b() and dwarf_fixup_AT_reference_die() for CLASS REFERENCE attribute handling. Also, dwarf_add_AT_with_ref_sig8() for refsig8 references. * libdwarf2p.1.mm: version 1.34 20 October. Document new interfaces. Fixed typo in dwarf_add_AT_targ_address_b() documentation. * libdwarf2p.1.pdf: Regenerated. * pro_die.c. Added commentary. * pro_forms.c: Added reference support with dwarf_add_AT_reference_b() and refactoring to avoid duplicating code. Added dwarf_add_AT_with_ref_sig8() * pro_section.c: now only adds DW_AT_sibling automatically if it was not present already. Still only adds it in the same automatically-selected places. Some renaming of local variables for clarity around line 1743. One line reformatted, it was looking very odd, line 2217. 2013-10-17 David Anderson * dwarf_error.c: Add DW_DLE_DEBUGPUBTYPES_ERROR string. * libdwarf.h.in: Add DW_DLE_DEBUGPUBTYPES_ERROR and fix DW_DLE_LAST. Add dwarf_add_pubtype() interface. * libdwarf2.1.mm: References to Dwarf_Pubtype changed to Dwarf_Type, using the same interface type as for .debug_types (an SGI extension). Now at rev 2.15. Clarified that pubnames and pubtypes only apply to .debug_info. * libdwarf2.1.pdf: Regenerated. * pro_opaque.h: Added DEBUG_PUBTYPES and updated NUM_DEBUG_SECTIONS. * pro_pubnames.c: Added dwarf_add_pubtype() support. * pro_section.c: Added support for pubtypes. 2013-10-14 David Anderson * libdwarf.h.in: Dwarf_Callback_Func_c, Dwarf_Callback_Func_b and Dwarf_Callback_Func name argument was lacking a const qualifier leading to compiler warnings. Now has const qualifier. 2013-08-15 David Anderson * dwarf_alloc.c: Now uses dwarf_printf instead of printf. And frees the dwarf_printf dp_buffer if appropriate. * dwarf_line.c, dwarf_print_lines.c: Now use dwarf_printf instead of printf. * dwarf_line.c: Update copyright year. * dwarf_opaque.h: Add de_printf_callback to Dwarf_Debug struct. Add dwarf_printf to function prototypes. * dwarf_util.c: Implement dwarf_printf. * libdwarf.h.in: Now specifies struct Dwarf_Printf_Callback_Info_s and dwarf_register_printf_callback(); * libdwarf2.1.mm: Version 2.14. Fixed three tables with too-long lines. Documented the new printf callback registration functions. * libdwarf2.1.pdf: Regenerated. 2013-08-13 David Anderson * dwarf_init_finish.c: * dwarf_query.c: Added dwarf_highpc_b() so consumers can deal with DW_AT_high_pc with form constant (a feature of DWARF4). * libdwarf.h.in: Added dwarf_highpc_b(), dwarf_add_AT_any_value_sleb(), dwarf_add_AT_any_value_uleb(). to give producers more flexibility. Moved the Dwarf_Form_Class declaration closer to the head of the file so the new function prototypes can reference it. * libdwarf2.1.mm: Version 2.13. Added dwarf_highpc_b(). * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.mm: Version 1.33. Documents dwarf_add_AT_any_value_sleb() and dwarf_add_AT_any_value_uleb(). Fixes a one-character typo that was truncating the document severely. * libdwarf2p.1.pdf: Regenerated. * pro_forms.c: Implements dwarf_add_AT_any_value_sleb() and dwarf_add_AT_any_value_uleb(). 2013-08-09 David Anderson * dwarf_init_finish.c: Spelling, change _dwarf_assume_string_bad-> _dwarf_assume_string_in_bound to reflect the actual meaning. * dwarf_alloc.c: Change a debug message for DWARF_SIMPLE_MALLOC to write to stdout, not stderr. All non-fatal messages now print to stdout. * libdwarf2.1.mm: Now version 2.12. Corrected the description of dwarf_set_stringcheck(). * libdwarf2.1.pdf: Regenerated. 2013-08-08 David Anderson * dwarf_form.c: When a FORM_string attribute is in debug_types it is now correctly dealt with. 2013-08-07 David Anderson * dwarf_init_finish.c: Changed a nonfatal error to write it to stdout instead of stderr to make it easier to understand the context of the error (which involves the number of debug sections, not something anyone should ever see). 2013-07-28 David Anderson * dwarf_abbrev.c, dwarf_frame.c, dwarf_frame3.c,dwarf_line.c, pro_reloc_stream.c, pro_section.c: Rename local variables to avoid compiler warnings about local variables reusing outer scope (including global) names. * dwarf_elf_access.c: Add AARCH64 support. * dwarf_reloc_arm.h: Add AARCH64 support. * libdwarf2.1.mm: dwarf_highpc() documentation admits it does not work properly for DWARF4 in all cases. dwarf_highpc() needs to be fixed. * libdwarf2.1.pdf: Regenerated 2013-06-08 David Anderson * libdwarf2.1.mm: Improved the documentation of dwarf_highpc() function to suggest how to interpret the value (pc or offset). * libdwarf2.1.pdf: Regenerated. 2013-03-08 David Anderson * dwarf_elf_access.c: Now we handle K10M and L10M as having relocations named as in x86, x86_64. 2013-02-07 David Anderson * dwarf_elf_access.c: FreeBSD did not have R_PPC64_ADDR32 as a relocation name, so changed one name to be the name usable in Ubuntu and FreeBSD, R_PPC_ADDR32. 2013-02-01 David Anderson * libdwarf2.1.mm: Improved the documentation of the badly-named functions dwarf_whatform() and dwarf_whatform_direct(). * libdwarf2.1.pdf: Regenerated. * libdwarf.h.in: The arguments to dwarf_whatform[_direct]() are renamed for clarity. They are commented out, so this is just improving documentation. 2013-01-20 David Anderson * libdwarf.h: Removed. * libdwarf.h.in: Added. Identical content to standard libdwarf. * configure.in: Generates libdwarf.h. Notices if struct _Elf in libelf.h and generates libdwarf.h appropriately. * configure: Regenerated * README now mentions the libdwarf.h generation at configure time. 2013-01-28 David Anderson * dwarf_frame.c: Fix a macro so it does not test unsigned numbers as being less than zero. Fixes a compiler warning. * malloc_check.c: Add void as the parameter list of a parameter-less function. Fixes a compiler warning. 2013-01-26 David Anderson * libdwarf.h: Remove the lc_number3 field to restore interface binary compatibility with earlier releases. * dwarf_loc.c, dwarf_loc.h: No longer uses the removed lc_number3 or lr_number3 fields. 2013-01-25 David Anderson * dwarf_alloc.c: Changed some local names to avoid compiler warnings about redefining names in inner contexts. * dwarf_frame2.c: Changed some local names to avoid compiler warnings about redefining names in inner contexts. Added const to some declarations to avoid warnings about const being cast away. * dwarf_init_finish.c: Added const to some declarations to avoid warnings about const being cast away. Changed some local names to avoid compiler warnings about redefining names in inner contexts. * dwarf_line.c, dwarf_print_lines.c: Added const to some declarations to avoid warnings about const being cast away. Added static to function definition to reflect its use and to avoid warning about lack of a visible prototype. * gennames.c: Using C89/90 void to declare functions with no arguments to avoid compiler warnings about using old style declarations. Changed some local names to avoid compiler warnings about redefining names in inner contexts. Added const to some declarations to avoid warnings about const being cast away. * pro_incl.h: WRITE_UNALIGNED macros now cast with const to avoid warnings about const being cast away. * pro_macinfo.c,pro_section.c,pro_section.h: Added const to some declarations to avoid warnings about const being cast away. 2013-01-25 David Anderson * common.c: Add 'const' on string declarations to avoid compiler warnings. * dwarf_loc.h: Add the new field lc_number3 to handle DW_OP_GNU_const_type properly. * dwarf_loc.c: Handle DW_OP_GNU_const_type properly. * libdwarf.h: Add lr_number3 so we can handle DW_OP_GNU_const_type properly. This destroys binary compatibility. Not a good idea. See Jan 26, above. 2013-01-25 David Anderson * dwarf_loc.c: Use cc_length_size, not cc_length to get the offset size. Nasty bug. * dwarf_opaque.h: Change commentary to clarify the cc_length field content to hopefully avoid making that mistake again. 2013-01-15 David Anderson * dwarf.h: defines for some added DW_OP_GNU operators * dwarf_loc.c: Added support for some DW_OP_GNU operators. * config.h.in, configure.in: Define and set HAVE_STRUCT_UNDERSCORE_ELF as FreeBSD names struct _Elf instead of struct Elf. * configure: Regenerated. * dwarf_alloc.c: Initialize a local var at declaration, add const to array of strings type declaration. * dwarf_alloc.h: Change ah_structs_per_chunk to Dwarf_Sword to eliminate a compiler warning. * dwarf_arange.c: Change a couple Dwarf_Unsigned to Dwarf_Signed to eliminate a compiler warning. * dwarf_die_deliv.c: Change local to Dwarf_Unsigned to eliminate signed compare warning (and actually signed was wrong anyway!). * dwarf_error.c: Fix comparison to eliminate signed/unsigned compare warning. * dwarf_form.c: Index variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_frame.c: Local variables changed to unsigned to eliminate signed/unsigned comparison warnings. * dwarf_frame3.c: Local variables changed to unsigned to eliminate signed/unsigned comparison warnings. * dwarf_init_finish.c: Local variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_leb.c: Local variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_line.c: Changed index variable to unsigned to eliminate signed/unsigned comparison warning. * dwarf_loc.c: Delete two unused local variables. * dwarf_loc.c: Delete two unused local variables. * dwarf_macro.c: Fixed comparisons eliminate signed/unsigned comparison warning. * dwarf_opaque.h: Changed cc_abbrev_offset and de_fde_count to unsigned (which they should have been all along) to eliminate signed/unsigned comparison warnings. * dwarf_print_lines.c: Local variable changed to unsigned to eliminate signed/unsigned comparison warning. * dwarf_util.c: Add include of pro_encode_nm.h to avoid a compiler warning. Changed index variable to unsigned to eliminate signed/unsigned comparison warning. * libdwarf.h: Add ability to handle struct _Elf. * pro_alloc.c: Move an include of malloc.h as it is not needed if stdlib.h is present. * pro_forms.c: Changed index variable to unsigned to eliminate signed/unsigned comparison warning. * pro_util.h: Add specific allowance for FreeBSD include and relocation. dwarfutils-20200114/libdwarf/ChangeLog2014000066400000000000000000000500541361531463500200170ustar00rootroot000000000000002014-12-31: David Anderson * dwarf_error.c: Add DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION. * libdwarf.h.in: Add DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION. * dwarf_form.c(dwarf_formexprloc): Call the new function _dwarf_reference_outside_section() as a check for an exprloc with data that is outside the section it belongs in. Ie, a bug somewhere. Return error DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION if applicable. * dwarf_frame2.c(read_encoded_ptr): Pass error down so we set a complete Dwarf_Error record at the point of error. Just three functions that could use this were changed. * dwarf_leb.c(_dwarf_decode_u_leb128): Presented with bogus leb values we stop scanning the leb number before overrunning our value-output buffer (and dumping core). The change is reasonably adequate but will not catch all cases. * dwarf_query.c(dwarf_attrlist): Call _dwarf_reference_outside_section to check the pointer is valid. * dwarf_util.c,dwarf_util.h: Implement _dwarf_reference_outside_section(). 2014-12-28: David Anderson * dwarf_alloc.c: Added global _dwarf_failsafe_error to enable better error reporting when malloc arena has no space left. On dwarf_dealloc() avoids attempting a free() of the static struct. * dwarf_error.c,libdwarf.h.in: New error code DW_DLE_FAILSAFE_ERRVAL for the malloc-arena-exhausted case. Now use that static instead of aborting. * dwarf_error.h: New field and library-private extern declaration for the malloc-arena-exhausted case. * libdwarf2.1.mm: Documented the handling of Dwarf_Error when malloc space exhausted. * libdwarf2.1.pdf: Regenerated. Rev 2.23. 2014-09-10: David Anderson * dwarf_tsearchhash.c(calculate_allowed_fill): Moved a declaration to avoid using a C99 feature. * dwarf_query.c(dwarf_highpc_b): Moved a declaration to avoid using aC99 feature. * dwarf_util.c(dwarf_print): Moved a declaration to avoid using aC99 feature. 2014-08-11 David Anderson, avoiding some compiler warnings. *dwarf_xu_index.c,dwarf_macro.c: Failed to cast the pointer returned by _dwarf_get_macro (one place in each file). 2014-08-04 David Anderson, avoiding some compiler warnings. * dwarf_alloc.c, dwarf_alloc.h: Change some uses of Dwarf_Ptr to be char * so we avoid adding (etc) to Dwarf_Ptr. * dwarf_gdbindex.c: Cast _dwarf_get_alloc() return properly. * dwarf_loc.c: Cast Dwarf_Ptr to char * in a couple places. * dwarf_query.c,dwarf_sort_line.c,pro_arange.c: Change names of local variables to avoid compiler warning about shadowing other locals. * dwarf_tsearchhash.c: Changed to avoid compiler warnings about const casts whereever possible. * libdwarf.h.in: Added prototypes for DWARF5 dwarf_get_SECT_name() and dwarf_get_MACRO_name(). * pro_alloc.c: Add include of pro_alloc.h. * pro_forms.c: Made _dwarf_add_AT_reference_internal() static to avoid warning. * pro_types.c: Add include of pro_types.h. 2014-08-02 David Anderson * dwarf_gdbindex.c: Fix an argument list by adding section name. * libdwarf.h.in: Fix an argument list by adding section name. Clarify some commentary on dwarf_get_xu* function declarations. * libdwarf2.1.mm: Documented the new gdbindex and dwarf_get_xu* functions. * libdwarf2.1.pdf: Regenerate. Version 2.22. 2014-07-12 David Anderson * dwarf_die_deliv.c: Remove trailing whitespace. Implement dwarf_get_die_section_name() allow clients to get the Elf section name actually used for the section. * dwarf_xu_index.c: Remmove traling whitespace and fix indents. 2014-07-11 David Anderson * dwarf_opaque.h: Various CU context fields were not clarified by comments, so comments added. 2014-07-11 David Anderson * dwarf_opaque.h: Clarified a couple comments. 2014-07-11 David Anderson * dwarf_xu_index.c: Now extracts the offset and size table data correctly. 2014-07-10 David Anderson * dwarf_die_deliv.c: Clarify a comment a little bit. No change in the code. 2014-07-10 David Anderson * dwarf_error.c,libdwarf.h.in: Added new error codes. * dwarf_xu_index.c: Now extracts the hash table values from .debug_tu_index and .debug_cu_index sections. 2014-07-09 David Anderson * dwarf_alloc.c,dwarf_xu_index.c,dwarf_xu_index.h: Removed trailing whitespace characters. 2014-07-09 David Anderson * Makefile.in: Added dwarf_xu_index.o. Moved dwarf_macro.o to get closer to alphabetical order in the list. * dwarf.h: Added DW_SECT codes so the .debug_[tc]u.index sections can be interpreted properly. DWARF5. * dwarf_alloc.c: Added dwarf_xu_index.h #include. Added struct Dwarf_Xu_Index_Header_s to alloced structs. Added a couple lines of commentary about .gdb_index section access type. * dwarf_alloc.h: Increased ALLOC_AREA_INDEX_TABLE_MAX to 57 for the new alloc type. * dwarf_die_deliv.c: Removed trailing whitespace. * dwarf_elf_access.c: Added commentary. * dwarf_error.c: Added new error codes for .debug_tu_index and .debug_cu_index sections code. * dwarf_init_finish.c: Add handling of .debug_tu_index and .debug_cu_index sections. * dwarf_opaque.h: Add de_debug_cu_index and de_debug_tu_index to Dwarf_Debug_s struct. * dwarf_xu_index.c: New code for the newly handled DWARF5 sections .debug_tu_index and .debug_cu_index . * dwarf_xu_index.h: Defines struct Dwarf_Xu_Index_Header_s. * libdwarf.h.in: Declares new functions implementing some of the new section interfaces. 2014-07-05 David Anderson * dwarf_arange.c(dwarf_get_aranges_list): Remove the length variable as its calculated value is unused. rename length to area_length for clarity. Calculate arange_ptr_past_end early and correctly. Ensure that the test for version 4 is a >= to reflect normal standards upgrades. * dwarf_die_deliv.c(dwarf_find_offdie_CU_Context): Add commentary about offsets and lengths for clarity. Rename fields for clarity about local vs global offset. Use the newly named fields for precise tests of section overflow of a type unit. * dwarf_frame.h: Add commentary about pointers in the cie_fde_prefix_s structure. * dwarf_global.c(_dwarf_internal_get_pubnames_like_data): Add commentary about the of fields. * dwarf_opaque.h: Improve commentary about offsets. 2014-07-03 David Anderson * dwarf_die_deliv.c: Fixed CU type offset check. Created local variable so we do not repeat a calculation so the error does not recur and simplifying nearby code. * gdb_index.c: Remove unused local variable. * dwarf_opaque.h: Change offset entries from Dwarf_Word to Dwarf_Unsigned to ensure we do not remove bits from values. * dwarf_query.c: Remove unused local variable and a comment referencing that unused variable. * pro_reloc_stream.c: Remove unused local variable. 2014-07-01 David Anderson * dwarf_alloc.c, dwarf_gdbindex.c, dwarf_init_finish.c, dwarf_opaque.h, libdwarf.h.in: Fixed indent errors and removed trailing whitespace. 2014-07-01 David Anderson * libdwarf.h.in: Matched up gdbindex symboltable interfaces with the C source. * dwarf_gdbindex.c: Implement Symbol table access. 2014-06-30 David Anderson * libdwarf.h.in: Remove useless interface to gdbindex. * dwarf_gdbindex.c: Implement TU list access code. Implement access to the address area. 2014-06-29 David Anderson * dwarf_error.c: Added error codes for gdbindex access. * libdwarf.h.in: Revised gdbindex function interface: simpler. * dwarf_gdbindex.c, dwarf_gdbindex.h: Implement gdbindex functions. 2014-06-28 David Anderson * Makefile.in: Add dwarf_gdbindex.o to objects. * dwarf_alloc.c: Add new type Dwarf_Gdbindex_s to allocatable types. * dwarf_elf_access.c: Add a comment reflecting lack of need to relocate a .gdb_index section. * dwarf_error.c: Add new error strings for gdb_index related errors. * dwarf_init_finish.c: Add .gdb_index section to the sections we read. Refactor a test into a function this_section_dwarf_relevant() to make code more readable. * dwarf_opaque.h: Add de_debug_gdbindex to Dwarf_Debug_s. * libdwarf.h.in: Add opaque types for .gdb_index section interfaces. Add DW_DLA_GDBINDEX for allocatability of the new type. Add new GDB_INDEX error codes in DW_DLA list. Declare new gdb_index interfaces. 2014-05-19 David Anderson * dwarf_init_finish.c: Removed unused local variable. * dwarf_opaque.h: Added _dwarf_extract_string_offset_via_str_offsets() to communicate the argument list to other libdwarf source files. * dwarf_query.c: Fixed botch in call argument list, the dwarf_opaque.h change exposed it. Deleted an unused local variable. * pro_reloc_symbolic.c: Deleted an unused local variable. 2014-05-18 David Anderson * libdwarf2.1.mm: Fixed a typo in the H3 line for dwarf_get_debug_add_index(). * libdwarf2.1.pdf: Regenerated. Rev 2.20, May 18 2014. 2014-05-18 David Anderson * dwarf_loc.: Fixed offset update for DW_OP_constx/addrx. 2014-05-18 David Anderson * dwarf_form.c: Removed trailing whitespace, added commentary. * dwarf_loc.c: Added commentary. 2014-05-18 David Anderson * libdwarf.h.in, dwarf_form.c: Restored the function dwarf_get_debug_addr_index(). It is useful as a convenience for apps like dwarfdump. 2014-05-18 David Anderson * dwarf_die_deliv.c,dwarf_error.c,dwarf_form.c,dwarf_init_finish.c, dwarf_opaque.h,dwarf_query.c,dwarf_util.c,libdwarf.h.in: Fixed numerous indent errors and removed trailing whitespace. 2014-05-17 David Anderson * dwarf.h: Minor comment enhancement. * dwarf_loc.c: Fixed code for DW_OP_constx, DW_OP_addrx, DW_OP_GNU_addr_index, DW_OP_GNU_const_index. * dwarf_form.c: DW_FORM_addr_index, DW_FORM_addrx, DW_FORM_strx, DW_FORM_GNU_str_index * dwarf_opaque.h: added new field dss_name to help debugging. * dwarf_query.c: Returns DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION when debug_addr is missing so address cannot be literally extracted. New functions: dwarf_get_debug_addr_index() and dwarf_get_debug_str_index(). * libdwarf.h.in: New error codes for FORM errors. New function declarations: dwarf_get_debug_addr_index() and dwarf_get_debug_str_index(). 2014-05-14 David Anderson * dwarf_die_deliv.c: Refactored several interfaces and used DW_DLV_OK (etc) returned values internally much more than before to get the desired behavior easily. * dwarf_error.c: Error strings for 8 new error numbers. * dwarf_form.c: DW_FORM_addr_index, DW_FORM_addrx support added. * dwarf_init_finish.c: Sections .debug_addr and .debug_addr.dwo now handled if present. * dwarf_opaque.h: New Dwarf_CU_Context fields added so we can get CU DIE attributes for DW_FORM_addrx DW_FORM_strx etc. New de_debug* fields added for the new DebugFission sections. * dwarf_query.c: Using the revised _dwarf_get_size_of_val() internal function. Handling DW_FORM_GNU_str_index, DW_FORM_strx. New functions (internal) for DW_FORM_strx, DW_FORM_addrx and the GNU version of these to avoid duplicating code. * dwarf_util.c: Implement revised _dwarf_get_size_of_val(). Handling DW_FORM_GNU_str_index, DW_FORM_strx. * dwarf_util.h: Updated _dwarf_get_size_of_val() declaration. * libdwarf2.1.mm: Revision 2.8. May 15 2014. Documented a restriction to a sensible view to strings that dwarf_errmsg() returns. However without actually changing anything to take advantage of that restriction. * libdwarf2.1.pdf: Regenerated. 2014-05-11 David Anderson * dwarf_error.c: Added 3 new error strings. * dwarf_form.c: Added DW_FORM_GNU_str_index and partial DW_FORM_GNU_addr_index handling. * dwarf_init_finish.c: Refactored initial section setup so we can handle dwo (DebugFission) or regular sections. * dwarf_query.c: Add support for DW_FORM_GNU_str_index. Partial support for DW_FORM_GNU_addr_index. * dwarf_util.c: Add support for DW_FORM_GNU_str_index, DW_FORM_GNU_addr_index. * libdwarf.h.in: 4 new error codes in DW_DLE_ list. Last now 248. 2014-05-09 David Anderson * Makefile.in: Write ar std-out to ar-output-temp so the text is not needlessly filling a terminal window. 2014-05-08 David Anderson * dwarf.h: Adds DW_AT_GNU_dwo_id, DW_AT_GNU_dwo_name and other GNU extensions. * libdwarf.h.in: Producer code changes: The dwarf_producer_init_d() is new and has new arguments. The older dwarf_producer_init() and _b _c versions are removed. Only one producer callback declaration exists now: Dwarf_Callback_Func. * pro_init.c: Implements the new dwarf_producer_init_d() function and initializes fields at runtime to select what DWARF to emit. Messy and confusing initialization code rewritten to depend on the runtime arguments to dwarf_producer_init_d, not library compile-time. * pro_opaque.h: New runtime fields set by initialization code. * pro_reloc.c: Fix a couple comment indentations. * pro_forms.c: Add curly braces in an if to avoid a hard-to-find bug (there was none yet, but it was a trap...). * pro_reloc_symbolic.c,pro_reloc_stream.c: Remove use of obsolete callback functions. * pro_section.c: Ensure only IRIX isa/abi target generates an exception CIE entry. Remove use of obsolete callbacks. * pro_util.h: Remove confusing and unreadable relocation number ifdefs that depended on settings at library compile-time. Most of the content of the file is deleted now. See isa_relocs[] in pro_init.c * dwarf_error.c: Added error code (used by producer code). * libdwarf2p.1.mm: Now version 1.36. Updated dwarf_producer_init() documentation. * libdwarf2p.1.pdf: Regenerated. 2014-04-14 David Anderson * pro_forms.c: Modified a comment about DW_FORM_ref_addr. No logic change. * bldDWindex.sh: Deleted. This shell script was intended for DWARF2 postscript post-processing and was never useful. 2014-04-12 David Anderson * dwarf_die_deliv.c,dwarf_query.c: Gets the version stamp passed to _dwarf_get_size_of_val() so DW_FORM_ref_addr handled correctly. * dwarf_form.c: Handle DW_FORM_ref_addr as the V2 specification says (V3 and later continue to be handled unchanged.). * dwarf_util.c: Handle DW_FORM_ref_addr as the V2 specification says (V3 and later continue to be handled unchanged.). * dwarf_addr_finder.c: Removed a mistaken handling of DW_FORM_ref_addr. No one should be using this function's features though... * pro_forms.c: Made a comment clearer about DW_FORM_ref_addr. * pro_section.c: Made a comment clearer, removed #if 0 code. 2014-04-02 David Anderson * libdwarf2.1.mm: Examples using dwarf_offdie_b() were miscoded (is_info argument not provided). Now fixed. Now at version 2.17. * libdwarf2.1.pdf: Regenerated 2014-03-17 David Anderson * dwarf.v2.mm,dwarf.v2.pdf,index.v2.mm,index.v2.pdf: Removed these files, they are now on dwarfstd.org. * Makefile.in: Removed mention of the deleted files. * README, COPYING: Removed mention of the deleted files. 2014-02-08 David Anderson * libdwarf2p.1.mm: Now version 1.35. Added a few words about the sect_name_index field in the callback from libdwarf to your code for each new Elf section to be generated. * libdwarf2p.1.pdf: Regenerated. 2014-02-02 David Anderson * dwarf_alloc.c: Added commentary. * dwarf_loc.c: Fixed two indents. * gennames.c: Removed trailing newlines from the printf output (dwarf_names_new.h is the file generated). * libdwarf.h.in: Removed trailing whitespace. 2014-02-01 David Anderson * dwarf_alloc.c: Instead of doing a long list of address compares, use the hash 'tree' and tfind() to determine if we malloced the space or simply took an address from .debug_info ( or other in-memory section) when we returned a _dwarf_get_alloc() pointer to the user. 2014-01-31 David Anderson * configure.in: The test to generate HAVE___UINT32_T_IN_SYS_TYPES_H was in a strange place. Moved it up a few lines. * configure: Regenerated. * dwarf_alloc.c: Added comment hinting at how dwarf_dealloc can be further simplified. 2014-01-30 David Anderson * dwarf_loc.c: Add support for DW_FORM_exprloc to dwarf_loclist_n(). * libdwarf2.1.mm: Document support for DW_FORM_exprloc.Version 2.16 * libdwarf2.1.pdf: Regenerate. * dwarf.h, dwarf_form.c, dwarf_line.c, dwarf_query.c, dwarf_util.c: Add limited support for DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. 2014-01-30 David Anderson * dwarf_alloc.c: Refactored and added relevant commentary. Added a check for debug_types in dwarf_dealloc(). * dwarf_init_finish.c: Corrected a comment and made one line declation-is-initialization. * dwarf_opaque.h: Added commentary. 2014-01-29 David Anderson * common.h,dwarf.h,dwarf_abbrev.c,dwarf_abbrev.h,dwarf_addr_finder.c, dwarf_alloc.c,dwarf_alloc.h,dwarf_arange.c,dwarf_arange.h, dwarf_base_types.h,dwarf_die_deliv.c,dwarf_die_deliv.h, dwarf_elf_access.c,dwarf_elf_access.h,dwarf_error.c,dwarf_error.h, dwarf_form.c,dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c, dwarf_frame3.c,dwarf_funcs.c,dwarf_funcs.h,dwarf_global.c, dwarf_global.h,dwarf_harmless.c,dwarf_harmless.h,dwarf_incl.h, dwarf_init_finish.c,dwarf_line.c,dwarf_line.h,dwarf_line2.c, dwarf_loc.h,dwarf_macro.h,dwarf_opaque.h,dwarf_reloc_arm.h, dwarf_reloc_mips.h,dwarf_reloc_ppc.h,dwarf_reloc_ppc64.h, dwarf_reloc_x86_64.h,dwarf_tsearch.h,dwarf_types.h,dwarf_util.h, dwarf_vars.h,dwarf_weaks.h,libdwarfdefs.h,malloc_check.h, pro_alloc.h,pro_arange.h,pro_die.h,pro_encode_nm.h,pro_error.h, pro_frame.h,pro_incl.h,pro_line.h,pro_opaque.h,dwarf_tsearch.h: Remove trailing whitespace. 2014-01-29 David Anderson * dwarf_tsearch.h, dwarf_tsearchhash.c: New files implementing a hashed tree with tsearch() interfaces. * Makefile.in: Add dwarf_tsearchhash.c to the build. * dwarf_init_finish.c: Remove references to malloc_check and _dwarf_setup_debug() and include of "malloc_check.h" as those are no longer needed. * dwarf_line.c: Removed a superfluous _dwarf_get_alloc(). The result of the call was never used. * dwarf_opaque.h: Removed Dwarf_Alloc_Hdr_s references and simple malloc references. added de_alloc_tree as base of a hash database replacing most of dwarf_alloc.c. * dwarf_query.c: Removed an unused local variable. * dwarf_alloc.h,dwarf_alloc.c: Removed simple malloc support and all the complicated code handling allocation record-keeping in favor of much simpler code calling functions using a tsearch-like interface. 2014-01-10 David Anderson * dwarf_print_lines.c,dwarf_macro.c: Remove trailing whitespace. * dwarf_ranges.c, dwarf_sort_lines.c: Remove trailing whitespace. * dwarf_query.c, dwarf_pubtypes.c: Remove trailing whitespace. * dwarf_original_elf_init.c,dwarf_loc.c: Remove trailing whitespace. * gennames.c: Fix a printf so the generated dwarf_names.c does not have a trailing space. 2014-01-10 David Anderson * gennames.c: Added comment clarifying why error is set before the call to fgets, and fixing the declaration order to avoid c99-ism. * dwarf_frame2.c: Use /* not // for comments in C. dwarfutils-20200114/libdwarf/ChangeLog2015000066400000000000000000001124671361531463500200270ustar00rootroot000000000000002015-12-31 David Anderson * configure.in: Now allows --enable-shared and --disable-nonshared * configure: regenerated. 2015-12-30 David Anderson * dwarf_elf_access.c(dwarf_elf_object_access_load_section): now test for a NULL data pointer from libelf. Problem caused by DWARF related section being marked SHT_NOBITS. 2015-12-29 David Anderson * dwarf_loc2.c: ll_dbg was not set, two places. dwarf_loc_head_c_dealloc() was not iterating through the list of locdescs. Fixed now. 2015-12-19 David Anderson * dwarf_macro5.c: specialcat() had a bug. Fixed indent/trailing whitespace. * dwarf_macro5.n: Fixed indent/trailing whitespace. * dwarf_line.c: Fixed indent/trailing whitespace. * dwarf_opaque.h: Fixed indent/trailing whitespace. 2015-12-19 David Anderson * dwarf_line.c: Rename a function and make it callable from other files: _dwarf_file_name_is_full_path(). Refactor creating _dwarf_internal_get_die_comp_dir(). * dwarf_macro5.c: Use _dwarf_internal_get_die_comp_dir() and _dwarf_file_name_is_full_path() for DWARF4/5 macro file names. * dwarf_macro5.h: New fields in macro context for the base file name. * dwarf_opaque.h: New field of comp_dir name on CU Context. * dwarf_util.c: Implement _dwarf_internal_get_die_comp_dir(). * dwarf_util.h: Declare _dwarf_internal_get_die_comp_dir(). 2015-12-18 David Anderson * dwarf_query: One line had trailing whitespace. Fixed. * dwarf_macro5.c: Was not getting import offset right. Off by one error. 2015-12-16 David Anderson * dwarf_query.c(dwarf_die_offsets): Added commentary.. Revised the code so it's a bit easier to read and reason about. 2015-12-15 David Anderson * dwarf_form.c: Refactored to simplify DWARF5 macro code. * dwarf_macro5.c,dwarf_macro5.h,dwarf_opaque.h,libdwarf.h.in: Now support for DWARF5 macros is nearly complete. 2015-12-13 David Anderson * dwarf_error.c: Add DW_DLE_MACRO_PAST_END * libdwarf.h.in: Add DW_DLE_MACRO_PAST_END and dwarf_get_macro_ops_count() declaration. * dwarf_macro5.c: Implement dwarf_get_macro_ops_count() and refactor a little bit. * dwarf_macro5.h: New fields supporting dwarf_get_macro_ops_count(). 2015-12-12 David Anderson * dwarf_error.c,libdwarf.h.in: Adding DW_DLE_MACRO_OP_UNHANDLED. * dwarf_macro5.c: Now validates form numbers when there is an extension operator. Fixed indents too. 2015-12-11 David Anderson * dwarf_alloc.c: Remove () around simple return value. * dwarf_error.c: Two new error codes for DWARF5 macro section. * dwarf5_macro.c,dwarf5_macro.h: Add functions to let reader read/print .debug_macro section header. Fixed _dwarf_macro_constructor declaration and implementation to return DW_DLV_OK. * libdwarf.h.in: Add functions to let reader read/print .debug_macro section header. 2015-12-08 David Anderson * dwarf.h,dwarf_frame.c: Add DW_CFA_METAWARE_info. * dwarf_frame.h: Add aug_metaware to enum. * dwarf_frame2.c: Add aug_metaware handling. * dwarf_util.c: Delete unused local variable. 2015-12-08 David Anderson * dwarf_die_deliv.c,dwarf_query.c,dwarf_util.c,libdwarf.h.in: Fix indents, remove trailing whitespace. Remove some useless () in return statements. 2015-12-08 David Anderson * dwarf_init_finish.c: Added a cast to strncmp() call to avoid warning. * dwarf_abbrev.c,dwarf_die_deliv.c,dwarf_error.c,dwarf_opaque.h, dwarf_query.c,dwarf_util.c,dwarf_util.h: Now check for valid forms when reading forms. Return error code as appropriate (now _dwarf_get_abbrev_for_code returns DW_DLV* as appropriate instead of a pointer). Left error placeholders for eventual merge with DWARF5 macro code. * libdwarf.h.in: New error code for FORM problems,DW_DLE_UNKNOWN_FORM. 2015-12-03 David Anderson * dwarf_macro5.c, dwarf_macro5.c: sentinal->sentinel. 2015-12-02 David Anderson * Makefile.in: Bug building .so. Change $dwfzlib to $(dwfzlib) to fix. 2015-11-30 David Anderson * dwarf_alloc.c,dwarf_macro5.c,dwarf_macro5.h,libdwarf.h.in: Remove trailing whitespace. 2015-11-30 David Anderson * Makefile.in: Add dwarf_macro5.o to build list. * dwarfdump.c: Add macro_flag flag to signal print of DWARF5 debug_macro data. * dwarf.h: Fix spelling of DWARF5 DW_MACRO fields. * dwarf_alloc.c: Add DW_DLA_MACRO_CONTEXT to alloc list. * dwarf_alloc.h: Add 1 to ALLOC_AREA_INDEX_TABLE_MAX. * dwarf_init_finish.c: New function dwarf_get_section_max_offsets_c returns sizes of all sections, including DWARF5. * dwarf_macro5.c: New,for DWARF5 macro access. Implements dwarf_get_macro_context() etc. * dwarf_macro5.h: Declare new internal macro structs. * libdwarf.h.in: Declare new macro interfaces. 2015-11-28 David Anderson * dwarf_frame.c: Added dwarf_get_frame_section_name(), dwarf_get_frame_section_name_eh_gnu() for better section name reporting for clients that care about that. * libdwarf.h.in: Declared the new section name interfaces. * libdwarf2.1.mm: Documented the new functions. Version 2.36. * libdwarf2.1.pdf: Regenerated. 2015-11-27 David Anderson * dwarf_die_deliv.c: Added dwarf_get_die_section_name_b(). * dwarf_line.c: Added dwarf_get_ranges_section_name() dwarf_get_aranges_section_name(), dwarf_get_line_section_name_from_die(), dwarf_get_string_section_name. * libdwarf.h.in: Added new function names. * libdwarf2.1.mm: Version 2.35. Documented new functions. * libdwarf2.1.pdf: Regenerated. 2015-11-26 David Anderson * config.h.in, configure.in, Makefile.in: Deals with zlib when present. * configure: Generated. * libdwarf/dwarf_error.c: New error codes for zlib use. * dwarf_init_finish.c: Supports zlib and .zdebug sections. * dwarf_opaque.h: New fields for zlib support. * libdwarf.h.in: New error codes for zlib use. 2015-11-25 David Anderson * dwarf.h: Removed trailing space. * dwarf_elf_access.c: Small preparation for handling .zdebug. * dwarf_init_finish.c: Preparation for handling .zdebug zlib compressed dwarf .debug_ sections. Uses new function and new SET_UP_SECTION macro to shorten code and ensure no unwanted differences present. * dwarf_tied.c: Remove trailing whitespace. * dwarf_opaque.h: New fields in preparation for .zdebug handling. 2015-11-24 David Anderson * dwarf_tied.c: Code reading tied CU headers only worked by accident but is fixed. Reads only as far as needed in tied for the signature being referenced. 2015-11-15 David Anderson * Makefile.in,configure.in: These now support building in separate clean directory. * configure: Regenerated. 2015-11-11 David Anderson * dwarf_opaque.h: Delete two useless blank lines. 2015-11-09 David Anderson * libdwarf.h.in: Removed unimplemented function declarationfrom the file. * libdwarf2.1.mm: Updated with new interface functions for DWARF5 and split dwarf. Version2.33 * libdwarf2.1.mm: Regenerated. 2015-11-08 David Anderson * dwarf_alloc.c: Fixed indents, trailing whitespace. * dwarf_loc2.c: Fixed indents, trailing whitespace. * dwarf_form.c: Made too-long line into 2 lines. * dwarf_loc.h: Removed duplicate Dwarf_Loc_c_s etc declarations. * dwarf_util.c(_dwarf_error_mv_s_to_t),dwarf_util.h: New function to eliminate duplicative code.: * dwarf_query.c): Fix bug in dwarf_get_offset_size(). Use new _dwarf_error_mv_s_to_t() to get error on correct dbg. Fixed indents, trailing whitespace. * dwarf_ranges.c: Use new _dwarf_error_mv_s_to_t() to get error on correct dbg. Fixed indents, trailing whitespace. 2015-11-07 David Anderson * dwarf_alloc.c: Added new checks so user mixing up tied dbg with regular dbg won't lead to crashes when calling dwarf_dealloc or dwarf_finish(). Zeroed out some fields to recognize space deallocated. * dwarf_die_deliv.c: Added support of split dwarf DW_AT_[GNU_]ranges_base * dwarf_form.c: Load string from tieddbg when appropriate. * dwarf_harmless.c: On free() zero out a field to show that was done. * dwarf_loc.c: Correct the handling of split dwarf loclist. * dwarf_opaque.h: Add cc_ranges_base_present for split dwarf. Add _dwarf_get_ranges_base_attr_from_tied() for split dwarf. * dwarf_query.c: Get and remember skeleton compilaton unit DW_AT_[GNU_]ranges_base from tied objects for split dwarf. * dwarf_ranges.c: If a tied object present, look for ranges there, not in split dwarf object. * dwarf_util.c: Housekeeping zeros out fields to ensure not used after dealloc. 2015-11-01 David Anderson * configure.in: Added -O0 to --enable-wall. So if a coredump while debugging gdb will work well. * configure: Regenerated. 2015-11-01 David Anderson * Makefile.in: Split out dwarf_loc2 to put the DWARF5 expression code all in one place. * dwarf_alloc.c,dwarf_alloc.h: Three new opaque structs for DWARF5 expression interfaces. * dwarf_error.c: New error codes for DWARF5 expression interfaces. * dwarf_frame.c: Altered internal interfaces to support DWARF5 expression reading. * dwarf_loc.c: Refactored to support DWARF5 and moved some code into dwarf_loc2.c to segregate the new interfaces for clarity. * dwarf_loc.h: Definitions of new library-internal structs (opaque to callers). * dwarf_loc2.c: Contains the new DWARF5 location expression interface code. It is not separately compiled, it is #included by dwarf_loc.c. * dwarf_opaque.h: Commentary change. * dwarf_query.c: dwarf_get_offset_size() new. Refactored to avoid duplicating code. * libdwarf.h.in: DWARF5 location expression interfaces refined and commentary improved.q 2015-10-28 David Anderson * dwarf_loc2.c: New file with the new code for DWARF5 location expressions put here. Not separate compile, this is brought into dwarf_loc.c via a #include there 2015-10-26 David Anderson * Makefile.in: Handle the configure --enable-wall option. * configure.in: Add --enable-wall so we can easily get gcc's -Wall option for the build. * configure: Regenerated. * dwarf_error.c: Amplify the text for DW_DLE_LOCLIST_INTERFACE_ERROR. * dwarf_loc.c(_dwarf_read_loc_expr_op): Correct a sanity test recently introduced. Ensure the location fields all set. #if 0 some code that will be fixed with the new location interface set. * dwarf_loc.h: Revised the prototypes and commentary for the new location list interfaces. 2015-10-25 David Anderson * checkexamples.c: Add commentary to example9. * dwarf_alloc.c: Add DW_DLA_LOC_BLOCK_C and DW_CLA_LOCDESC_C allocation descriptions to array. * dwarf_alloc.h: Increase ALLOC_AREA_INDEX_TABLE_MAX to match. * dwarf_base_types.h: Increase MAX_DW_DLA to match. * dwarf_die_deliv.c: Switch some returns from pointer to the standard int DW_DLV_OK etc and return pointer through an argument. Identify which CUs are dwo by checking name for a .dwo ending. Fix whitespace endings. * dwarf_error.c: Add DW_DLE 309 to 311 errors to descriptions array. * dwarf_form.c: Remove trailing whitespace. Reformat one line so it is not so long. * dwarf_line.c: Add {} on if for clarity. Fix whitespace endings. * dwarf_line_table_reader.c: Fix whitespace endings. * dwarf_loc.c: Refactor loc. expr. reader into a routine that reads one expression, _darf_read_loc_expr_op().. Add DWARF5 operators. Add preliminary dwo expression support (which will change but this is a start). Old expression interface now explicitly supports only DWARF 2,3,4. No DWARF5. Add preliminary loclist_c support (it will change). Add commentary about the old loclist interface. * dwarf_loc.h: First cut of new interfaces (functional, not public structs). * dwarf_opaque.h: Add cc_is_dwo flag to cu context struct. * libdwarf.h.in: Rework some loclist commentary. Add first try at new loclist interfaces for DWARF2,3,4,5. New error codes for new loclist/dwo code. * libdwarf2.1.mm: Rev 2.32. New wording on old loclist interfaces. 2015-10-15 David Anderson * dwarf_util.c,dwarf_query.c: Added DW_FORM_strp_sup as same idea as DW_FORM_GNU_strp_alt. 2015-10-15 David Anderson * checkexamples.c: Fixed data type in the example code. * dwarf.h: Updated comment about DW_FORM_GNU_strp_alt * dwarf_elf_access.c: Fixed trailing whitespace and removed debug printf that got left in. * dwarf_error.c: Add new TIED file errors. DW_DLE_NO_TIED_FILE_AVAILABLE, DW_DLE_NO_TIED_STRING_AVAILABLE. * dwarf_form.c: Added support for DW_FORM_GNU_strp_alt. * dwarf_init_finish.c: #if 0 routine all_sig8bits_zero(). * dwarf_line.c: Now always notice windows-like c: etc as start of a full path. Ensure directories with \ are turned to / in line tables. (for full such transforms configure with --enable-windowspath ) Remove some debug #ifdef lines. Alter the linecontext interface to pass back table count, not linecount. * dwarf_line.h: Add commentary and lc_table_count field. * dwarf_line_table_reader_common.c: Fix indent/trailing whitespace. Now sets lc_table_count; * dwarf_opaque.h: Add _dwarf_get_string_from_tied() interface. * dwarf_print_lines.c: Remove trailing whitespace and some debug printf.. * libdwarf.h.in: New error codes. Fix trailing whitespace. Expand commentary. 2015-10-13 David Anderson * dwarf_line.c: Refactored so we have only one piece of code creating file paths from line table data. deleted obsolete code that was #if 0. * libdwarf.h.in: Fleshed out linecontext versions of two-level table readng. Revised a new interface (dwarf_srclines_b) to make it possible to do a read of just the line header. * libdwarf2.1.mm: Documented new functions. Fixed the example code so it is actually correct 2015-10-06 David Anderson * Makefile.in: Removed source files from the build that are only useful to IRIX and only in the context of building an IRIX runtime system. * dwarf_alloc.c: Added constructor/destructor code to Dwarf_Line_Context allocator. * dwarf_elf_access.c: Added additional #defines so we have the IA64 defines we need to compile certain test cases on freebsd. * dwarf_error.c: Two new error codes for Dwarf_Line_Context checking. * dwarf_line_table_reader_common.c: New file. We can compile the line reading with and without detailed print lines for dwarfdump. Now only one body of line reading code to maintain. * dwarf_line.c: Moved code out to dwarf_line_table_reader_common.c Refactored to support skeleton line tables (DWARF5) Eliminated an internal struct, it is no longer needed. a little better. Supports experimental two-level line tables too. * dwarf_print_lines.c: Uses dwarf_line_table_reader_common.c to do much of its work now. * libdwarf.h.in: New interfaces for nicer access to line table headers. * libdwarf2.1.mm: Partial documentation of the new libdwarf line table interfaces. 2015-10-01 David Anderson * dwarf_global.h: Now the last __sgi related macro (else, endif) have /* __sgi */. 2015-09-30 David Anderson * dwarf_global.c,dwarf_line.c,dwarf_line.h,dwarf_line2.c, dwarf_line_table_reader_common.c,dwarf_sort_line.c,libdwarf.h.in: The SGI IRIX only fields in dwarf_line.h ifdef __sgi now. And all code referencing them that way too. Balancing #endif has /* __sgi */ now for searchability. Functions only usable on SGI IRIX only compiled in if __sgi macro defined. * libdwarf2.1.mm: Added a comment related to experimental two-level line tables. 2015-09-29 David Anderson * dwarf_die_deliv.c,dwarf_line.c,dwarf_print_lines.c: Now looks for and adds the extra offset from debug_fission: DW_SECT_LINE. 2015-09-29 David Anderson * dwarf_line.c,dwarf_line.h,dwarf_line_table_reader_common.c, dwarf_print_lines.c: Moved the prefix reading subroutine into common so the prefix-printing can have print code added (with ifdef so production does not have it). 2015-09-29 David Anderson * dwarf_line.c,dwarf_line_table_reader_common.c,dwarf_print_lines.c, dwarf_line.h,dwarf_line2.c,libdwarf.h.in: Moved some code from dwarf_line_table_reader_common.c to dwarf_line.c. Fixed indent and trailing whitespace. Fixed the 'section offset' code by using the proper value from dss_ptr.. 2015-09-28 David Anderson * dwarf_line_table_reader_common.c: New file is the line table reader extracted from dwarf_line.c. Now compiled into dwarf_line.c and dwarf_print_lines.c with correct two-level line table calculations. No more coding the table twice. * dwarf_line.c,dwarf_print_lines.c: Now #include dwarf_line_table_reader_common.c * Makefile.in: Reflects new source depedencies. * dwarf_line2.c: An internal function interface changed, so accomodated it here. * libdwarf.h.in, dwarf_error.c: New error code, DW_DLE_BAD_LINE_TABLE_OPERATION. Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: Makefile.in modified: dwarf_error.c modified: dwarf_line.c modified: dwarf_line2.c modified: dwarf_line_table_reader_common.c modified: dwarf_print_lines.c modified: libdwarf.h.in 2015-09-28 David Anderson * dwarf_line.c,dwarf_line.h,dwarf_print_lines.c: made li_ and lr_ line register structs agree on spelling of suffix of each name. Now dwarf_srclines (and two-level) use the line register struct instead of a list of local variables. 2015-09-26 David Anderson * dwarf_elf_access.c: Removed some trailing spaces. * dwarf_line.c: Update the li_is_actuals_table (new field) where a new line is emitted. For later safe dealloc. Fixed indents and removed trailing spaces. Fixed the dwarf_srclines_dealloc to work properly on all the line table variations. * dwarf_line.h: Removed trailing spaces. Added li_is_actuals_table so the dealloc can work properly. * dwarf_print_lines.c: Fixed the Logicals and Actuals table formatting, Now prints the subprograms table too. * libdwarf.h.in: Added dwarf_get_LNCT_name() to function list. 2015-09-25 David Anderson * dwarf_print_lines.c: A first cut at detailed line tables. Not yet computing state register values for all two-level line tables here. 2015-09-25 David Anderson * dwarf_line.h: added a comment. * dwarf_print_lines.c: Now finds actuals and logicals tables and prints them. Incomplete but perhaps useful. 2015-09-24 David Anderson * dwarf_line.c: Renamed a local var for clarity. Added commentary for clarity. Fixed a memory leak for skeleton lined tables. Added required free() calls on error to avoid memory leaks. Moved an 'overrun' check into a loop to check on every loop iteration. * dwarf_line.h: Added commentary. 2015-09-23 David Anderson * dwarf_abbref.c,dwarf_die_deliv.c,dwarf_init_finish.c,dwarf_query.c: Removed unused local variables. * dwarf_line.c: Corrected bugs in the two-level line table support and improved error checking. Revamped the line table header reading code for clarity. See dw-linetableheader.txt . * dw-linetableheader.txt: The line table headers are a bit complicated (mostly by the experimental two-level line table support) so this file shows the header fields in order by version. * dwarf_form.c: Fixed nested comment, removed unused local variables.. * dwarf_loc.c: Cast return from _dwarf_get_alloc() to remove a compile warning. * dwarf_tied.c: Removed unused local variable. * dwarf_xu_index.c: Removed unused local variables. 2015-09-22 David Anderson * libdwarf/dwarf.h,dwarf_elf_access.c,dwarf_form.c,dwarf_line.h: Fixed indentation errors. * dwarf_line.c: Fixed indentation and corrected an error introduced a couple days ago. 2015-09-19 David Anderson * dwarf.h: Adding commentary. a DW_LNS for two-level line tables looks wrong.. * dwarf_die_deliv.c: Adding commentary. * dwarf_line.c: An internal function now has a leading _ and a context argument.. Added local names of popular pointers. * dwarf_print_lines.c,dwarf_sort_line.c: An internal function now has a leading _ and a context argument.. * dwarf_opaque.h: Added cc_segment_selector_size to contex structure. * libdwarf.h.in: Added commentary on two-level line table functions etc. 2015-09-17 David Anderson * dwarf.h, dwarf_alloc.c,dwarf_base_types.h,dwarf_init_finish.c, dwarf_line.c,dwarf_line.h,dwarf_line2.c,dwarf_util.c,libdwarf.h.in: Adding support for experimental 2-level line table. 2015-09-15 David Anderson * dwarf_form.c(_dwarf_extract_string_offset_via_str_offsets): Modified comment to reflect the current DWARF5 draft (we need not guess about correctness). 2015-09-15 David Anderson * dwarf_query.c, dwarf_form.c: We were failing check for off-end-of debug_str_offsets section correctly and had a dwarf_dealloc where it was not wanted. 2015-09-15 David Anderson * dwarf_query.c(_dwarf_extract_address_from_debug_addr): At line 540 we were deleting a dwarf_error that might not be there. Now conditional on DW_DLV_ERROR. This and around line 605 are the very rare situation we can turn one error code off and possibly or definitely substitute another error. Normally we just return the original error as the 'lowest level error.' 2015-09-15 David Anderson * dwarf_elf_access.c: Added conditional R_MIPS_64 and R_MIPS_TLS_TPREL64 defines as the headers I have for freebsd 32bit VM do not define those and we need them for testinga couple object files. 2015-09-15 Carlos Alberto Enciso * dwarf_elf_access.c: For Windows version, some compilers generate EM_PPC64 elf type, but the generated code is 32 bits. Set the correct value for 'dbg->de_pointer_size'. * dwarf_init_finish.c: For Windows version, remove the incorrect hard code value for 'dbg->de_pointer_size'. * dwgetopt.h: Add the guard 'extern "C"'. 2015-09-15 David Anderson and Carlos Alberto Enciso * dwarf_form.c (dwarf_formsig8_const): Was failing to return its return code. * dwarf_xu_index.c (_dwarf_search_fission_for_offset): Was failing to return its return code. 2015-09-14 David Anderson * dwarf_form.c,dwarf_global.c,dwarf_line.c,dwarf_macro.c,dwarf_util.c: Fixed indents and removed trailing whitespace. 2015-09-14 David Anderson * libdwarf2.1.mm: Revision 2.30. Fixed awkward line in UTF-8 section. * libdwarf2.1.pdf: Regenerated 2015-09-14 David Anderson * libdwarf2.1.mm: Revision 2.29. Added text to Items Changed section. Added a top level UTF-8 strings section. * libdwarf2.1.pdf: Regenerated 2015-09-14 David Anderson * libdwarf2.1.mm: Revision 2.28. Now describes dwarf_set_tied_dbg(). * libdwarf2.1.pdf: Regenerated 2015-09-13 David Anderson * libdwarf.h.in,dwarf_error.c: New error code for improved string checking. * dwarf_form.c,dwarf_string.c:Now call the string checker on all strings and do a more thorough check. * dwarf_util.c, dwarf_util.h: Revised the interfaces to the string checker to make it more useful and accurate. 2015-09-12 David Anderson * dwarf_die_deliv.c,dwarf_form.c,dwarf_opaque.h, dwarf_original_elf_init.c,dwarf_query.c,dwarf_tied.c: Now we can find addresses in the base from the dwp. 2015-09-11 David Anderson * Makefile.in: clean now removes test executable ./dwarftied * dwarf.h: Adding DW_AT_GNU_macros attribute, 0x2119. 2015-09-11 David Anderson * dwarf.h: Adding DW_AT_GNU_discriminator attribute, 0x2136. 2015-09-11 David Anderson * Makefile.in,dwarf_alloc.c,dwarf_die_deliv.c,dwarf_error.c,dwarf_form.c, dwarf_opaque.h,dwarf_original_elf_init.c,dwarf_query.ckdwarf_tied.c, libdwarf.h.in: Added dwarf_tied.c and -x tied= options. So libdwarf can follow DW_FORM_addrx to get the address from another object. 2015-09-05 David Anderson * dwarf.h: Fixed indentation of two lines with the 0x values incorrectly indented. 2015-07-12 David Anderson * dwarf_init_finish.c: Added commentary about .rela * dwgetopt.c,dwgetopt.h,dwgetopttest.c: Use dwoptind dwoptarg etc, not optind, optarg, optopt opeerror etc. * gennames.h: use dwoptarg dwoptind, not optarg, optind. 2015-05-08 David Anderson * dwarf_die_deliv.c, dwarf_frame2.c, dwarf_frame2.c, dwarf_frame.c: The debugging-only #if 0 now have comments so grep for 'if 0' is not alarming. * dwgetopt.c,pro_forms.c,pro_section.c: Removed unused code bracketed with '#if 0'. 2015-05-01 David Anderson * dwarf.h: Added DW_DEFAULTED* and DW_IDX* DWARF5 macros. * dwarf_abbrev.c: Expanded comments about the interface used by dwarfdump -a. It is NOT guaranteed to work on all objects. It continues to work usefully on a plain .o . * dwarf_alloc.h: Added code to clean when there are fission package file sections .debug_cu_index or .debug_tu_index. * dwarf_die_deliv.c: Significant changes to internals to support DWARF5 debug fission dwp package objects. Added dwarf_die_from_hash_signature() which lets one find DWP DIE information from a hash signature. * dwarf_error.c: Fifteen new DW_DLE* error messages added related to new DWARF5 sections and to debug fission package files. * dwarf_form.c: New commentary about offsets rrelated to DWP package files. New interface dwarf_formsig8_const() to read the DW_FORM_data8 a DW_AT_dwo_id uses. * dwarf_global.c: Added commentary about an old interface and DWARF5 (the old interface does not support DWARF5, newer (but not new) interfaces do). * dwarf_incl.h: Add dwarf_xu_index.h include. * dwarf_init_finish.c: Removed a couple dwo-section readers (they were not real) Added new DWARF5 section readers and the appropriate .dwo section readers. * dwarf_line.c,dwarf_loc.c: Added support for getting the correct line * dwarf_macro.c: Added comment that .debug_macinfo section not supported in DWP Package File (and .debug_macinfo is not in DWARF5). section offset in a DWP package file. * dwarf_opaque.h: Many New fields for the new sections and DWP Package File support. Various new functions (libdwarf internal) for the new sections. * dwarf_query.c: Added support for DWP Package File offsets. * dwarf_tsearch.h: Added ifndef DWARF_TSEARCH so #include more than once does not lead to difficulty. * dwarf_util.c: Added support for DWP Package File data. * dwarf_xu_index.c: Added support for DWP Package File data so it can all be read properly. * dwarf_xu_index.h: Added ifndef DWARF_XU_INDEX_H so #include more than once does not lead to difficulty. * libdwarf.h.in: Added dwarf_get_IDX_name() and dwarf_get_IDX_name(). Added fifteen new DW_DLE error codes. New function dwarf_die_from_hash_signature(). * libdwarf2.1.mm: Rev 2.27. Documented interfaces dwarf_next_cu_header_d(),dwarf_die_from_hash_signature(), dwarf_get_debugfission_for_die(),dwarf_get_debugfission_for_key(). * libdwarf2.1.pdf: Regenerated. 2015-04-23 David Anderson * dwarf.h: Delete spurious blank lines. * dwarf_base_types.h: New defines. DW_CIE_VERSION* DW_CU_VERSION** DW_ARANGES_VERSION* DW_LINE_VERSION* DW_LOC_VERSION* DW_LINE_STR_VERSION5, DW_MACRO_VERSION5, DW_LINE_LOC, DW_NAMES_VERSION5, DW_PUBNAMES_VERSION*, DW_PUBTYPES_VERSION*, DW_STR_OFFSETS_VERSION5, DW_SUP_VERSION*, DW_CU_INDEX_VERSION5, DW_TU_INDEX_VERSION5, making version comparisons more precise and including DWARF5. * dwarf_arange.c: CURRENT_VERSION_STAMP -> DW_ARANGES_VERSION2 * dwarf_die_deliv.c,dwarf_global.c,dwarf_line.c, : Use the new DW_*_VERSION* version names. * dwarf_init_finish.c: Added to 3 comments. * dwarf_loc.c: Use the new DW_*_VERSION* version names. Use a local variable to simpify some comparisons for readability. * dwarf_opaque.h: Update the comments about version numbers. Added new comments foreshadowing changes for DebugFission and DWP. REMOVE CURRENT_VERSION_STAMP* macros as they are no longer used. 2015-03-10 David Anderson * dwgetopt.c: Was mishandling options missing their required argument. 2015-03-09 David Anderson * dwgetopt.c: Fixed a bug in handling options. See dwarfdump build for testing code and test runs for dwgetopt.c 2015-02-22 David Anderson * dwgetopt.h, dwgetopt.c: Copied from dwarfdump so libdwarf can compile without dwarfdump source present. * Makefile.in: Builds dwgetopt.o * gennames.c: Now uses dwgetopt.o 2015-02-12 David Anderson * dwarf_original_elf_init.c(dwarf_elf_init_file_ownership): When dwarf_elf_object_access_init() returns DW_DLV_ERROR the Dwarf_Error was not getting set. Now it is set. 2015-02-04 David Anderson * dwarf.h: Added new TAGs etc from DWARF5. Since DWARF5 is not a completed standard these new things could change. * dwarf_die_deliv.c: Refactored calculation of end_of CU to ensure uniformity. Added checks to catch attempts to read past end and coredump (can happen when the DWARF is erroneous). Notice when bogus attribute wraps memory so the next DIE would be at an earlier address in memory than the current die (DW_DLE_NEXT_DIE_LOW_ERROR). * dwarf_error.c: DW_DLE_NEXT_DIE_LOW_ERROR error code added. * dwarf_form.c: Added check to ensure we do not run off the end of the string section (.debug_str). * dwarf_opaque.h: Declare new internal function _dwarf_calculate_section_end_ptr(). * dwarf_query.c(dwarf_attrlist): A little bit of refactoring/reordering done to catch errors. Created new function _dwarf_calculate_section_end_ptr(). * dwarf_xu_index.c: Removed trailing space, one line.. * libdwarf.h.in: Added define of DW_DLE_NEXT_DIE_LOW_ERROR. 2015-01-31 David Anderson * Makefile.in,common.c,common.h,dwarf_abbrev.c,dwarf_abbrev.h, dwarf_addr_finder.c,dwarf_alloc.c,dwarf_alloc.h,dwarf_arange.c, dwarf_arange.h,dwarf_base_types.h,dwarf_die_deliv.c,dwarf_die_deliv.h, dwarf_elf_access.c,dwarf_elf_access.h,dwarf_error.h,dwarf_form.c, dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c,dwarf_frame3.c,dwarf_funcs.c, dwarf_funcs.h,dwarf_gdbindex.c,dwarf_global.c,dwarf_global.h, dwarf_incl.h,dwarf_leb.c,dwarf_line.c,dwarf_line.h,dwarf_line2.c, dwarf_loc.c,dwarf_loc.h,dwarf_macro.c,dwarf_macro.h, dwarf_opaque.h,dwarf_original_elf_init.c,dwarf_print_lines.c, dwarf_pubtypes.c,dwarf_query.c,dwarf_ranges.c,dwarf_reloc_arm.h: Removed obsolete postal address and oss.sgi.com address from copyright. 2015-01-30 David Anderson * dwarf_init_finish.c: Now uses Dwarf_Sig8 for .debug_cu_index. * dwarf_opaque.h: Use Dwarf_Sig8 for the dfp_hash field. * libdwarf.h.in: dwarf_get_xu_hash_entry() uses Dwarf_Sig8 now. 2015-01-30 David Anderson * dwarf.h: Adding some DWARF5 defines. Use with caution: DWARF5 is not yet final. * gennames.c: Local array needed to be bigger due to a longer attribute list. 2015-01-28 David Anderson * libdwarf2.1.mm: Fixed .H 2 to .H 3 on dwarf_get_TAG_name etc. Removed duplication of 3 lines of Global Namespace operations. Added doc of dwarf_dwarf_get_debug_str_index() and fixed a level 2 header (starting the quoted string with a period caused trouble in the output). * libdwarf2.1.pdf. Regenerated. Version 2.25. 2015-01-25 David Anderson * dwarf_form.c(dwarf_convert_to_global_offset): Removed yesterday's change. The cu_context offset value already has debugfission offset built in. 2015-01-24 David Anderson * dwarf_form.c: dwarf_convert_to_global_offset() was not accounting for debugfission data (dwp). * dwarf_die_deliv.c(dwarf_offdie_b): Was not adding cc_extension_size into cu header offset (cc_extension_size is rarely non-zero, but its omission was a bug here). * dwarf_util.h: Improved a line of commentary. 2015-01-21 David Anderson * Makefile.in: Now with separate dwarf_names.h and dwarf_names.c rules so parallel make works properly. * dwarf.h: Improved the comment on DW_SECT_TYPES as that is not actually part of DWARF5 but is reserved. * dwarf_die_deliv.c: Added dwarf_get_debugfission_for_die(). Now dwarfdump and other clients can access and print fission data for a specific CU easily. * dwarf_init_finish.c(load_debugfission_tables): Deleted unused local variable. * dwarf_opaque.h: Now uses libdwarf.h DW_FISSION_SECT_COUNT for clarity (libdwarf-only name). * libdwarf.h.in: Add DW_DLE_FISSION_VERSION_ERROR as part of error checking. Add prototype for dwarf_get_debugfission_for_die() and declare its struct argument. 2015-01-18 David Anderson * dwarf_abbrev.c: Added comment, debugfission not supported in the non-cu-specific interface. * dwarf_alloc.c, dwarf_base_types.h: Add DW_DLA_FISSION_PERCU support. * dwarf_die_deliv.c: Added _dwarf_get_fission_addition_die() and _dwarf_get_fission_addition() for debugfission support. * dwarf_error.c: Add DW_DLE_FISSION_INDEX_WRONG error string. * dwarf_form.c: Add debugfission support for str_offsets. * dwarf_init_finish.c: Load debugfission tables if such exist in an object. * dwarf_line.c: Add debugfission support for .debug_line.dwo * dwarf_loc.c: Add debugfission support for .debug_loc.dwo * dwarf_macro.c: Add comment that debugfission not supported in the non-CU-specific interface. * dwarf_opaque.h: Add structures for debugfission: Dwarf_Fission_Offsets_s,Dwarf_Fission_Per_CU_s, Dwarf_Fission_Section_Offset_s. declare the new functions in dwarf_die_deliv.c * dwarf_util.c: Remove a few lines of traling whitespace. * dwarf_uxu_index.c: Correct bogus formatting. * libdwarf.h.in: Add DW_DLE_FISSION_INDEX_WRONG . 2015-01-12 David Anderson * dwarf_init_finish.c(_dwarf_setup): Move freeresult declaration before statements. * dwarf_util.c: Add comments about va_end(). 2015-01-11 David Anderson * dwarf_init_finish.c(_dwarf_setup): For all returns in _dwarf_setup() free the sections malloc space. 2015-01-08 David Anderson * cmplrs/dwarf_addr_finder.h: Fix a comment and remove a trailing whitespace. * dwarf.h: Blank line added accidentally. * dwarf_alloc.c: Removed trailing whitespace. * dwarf_init_finish.c: Remove trailing whitespace. Fix indent. * dwarf_leb.c: Remove trailing whitespace. Fix indent. * dwarf_line.h: Fix macro backslash location, lining things up. * dwarf_util.c: Remove trailing whitespace. 2015-01-06 David Anderson * dwarf_alloc.c, dwarf_base_types.h, dwarf_elf_access.c, dwarf_error.c,dwarf_error.h,dwarf_form.c,dwarf_init_finish.c, dwarf_leb.c,dwarf_query.c,pro_section.c: Fixed indents and removed trailing whitespace. 2015-01-06 David Anderson * dwarf_frame.c( _dwarf_get_fde_info_for_a_pc_row): Cast the pointer returned from _dwarf_get_alloc(), somehow this cast was omitted. * dwarf_alloc.c(dwarf_dealloc): Ensure a NULL 'space' pointer input is not touched before checking if it is set. * dwarf_init_finish.c(_dwarf_setup): For badly formed Elf ensure we do not use stale pointers. 2015-01-05 David Anderson * dwarf_original_elf_init.c(dwarf_finish): If the Dwarf_Debug is not initialized do not use it. 2015-01-03 David Anderson * libdwarf2p.1.mm: Somehow dwarf_transform_to_disk_form() was not documented. Now it is. * libdwarf2p.1.pdf: Regenerated, version 1.38. 2015-01-03 David Anderson * dwarf_allo.c: Comment the allocation table base more carefully. * dwarf_base_types.h: Making DW_DLA defines more readable, more consistent with other instances. * libdwarf.h.in: Adding producer error codes. The producer library has some places error values are misidentified. Main effect: documentation. * dwarf_error.c: Add the strings for the new error codes. 2015-01-01 David Anderson * A new year begins. dwarfutils-20200114/libdwarf/ChangeLog2016000066400000000000000000001300331361531463500200150ustar00rootroot000000000000002016-12-25 David Anderson * dwarf.h: DWARF5 changed DW_FORM_ref_sup to DW_FORM_ref_sup4 and added DW_FORM_ref_sup8. 2016-12-20 David Anderson * libdwarfdefs.h: Removed definition of SHF_COMPRESSED. There was no reason to define it early in a local header file. * dwarf_init_finish.c: Added definition of SHF_COMPRESSED. Making it a late definition avoids a conflict with Centos-7.3. 2016-12-06 David Anderson * dwarf.h: Comments mention certain values unused in DWARF2 and later as being from DWARF1. 2016-11-24 David Anderson * libdwarf/gennames.c: Update version string. 2016-11-24 David Anderson * Makefile.in: Clean *~ 2016-11-16 David Anderson * dwarf_die_deliv.c(dwarf_child): Added a check for 'at end of DIEs', removed pointless parens in returns, and added {} to make an if() follow normal form. * dwarf_query.c: Removed pointless parens in return. * dwarf_util.c(_dwarf_get_size_of_val): Changed return 0 to return DW_DLV_OK so it reads as is supposed to. For DW_FORM_block1 check a pointer for validity before dereferencing. In _dwarf_check_string_valid() added comments clarifying the intent of the function. 2016-11-11 David Anderson * dwarf_init_finish.c: Remove a few bytes of trailing whitespace. * dwarf_leb.c(_dwarf_decode_s_leb128_chk): Now we avoid using code with undefined behavior. And add new test cases in the #ifdef TESTING code that shows the problem is fixed. 2016-11-04 David Anderson * libdwarf.h.in: Removed trailing whitespace, three places. Added DW_DLE_ZLIB_UNCOMPRESS_ERROR. * dwarf_arange.c(dwarf_get_aranges_list): Add checks for the sanity of aranges headers and values to catch corrupted dwarf.. * dwarf_errmsg_list.c: Add DW_DLE_ZLIB_UNCOMPRESS_ERROR to identify impossible zlib compression. * dwarf_form.c:(dwarf_formblock): Check for overrun of a section-end. Return witw DW_DLE_FORM_BLOCK_LENGTH_ERROR as the error when such corrupt dwarf is encountered. * dwarf_init_finish.c(do_decompress_zlib): Check for corrupted zlib compression information and set DW_DLE_ZLIB_UNCOMPRESS_ERROR when a corrupted expanded-length is found. * dwarf_macro5.c(_dwarf_skim_forms): For DW_FORM_STRING call _dwarf_check_string_valid() to ensure a string does not run off the end of a malloc block. * dwarf_util.c(_dwarf_check_string_valid): Remove and add a blank line to get the usual way functions begin with declarations, a blank line, then code. No change in logic. 2016-11-01 David Anderson * dwarf.h: Adding Ada GNAT gcc attributes DW_AT_GNU_numerator, DW_AT_GNU_denominator, DW_AT_GNU_bias. 2016-10-21 David Anderson * gennames.c: Update version string. 2016-10-15 David Anderson * libdwarf.h.in: Added DWARF5 values to enum Dwarf_Form_Class. * dwarf_query.c(dwarf_get_form_class): Added DWARF5 support. 2016-10-11 David Anderson * pro_forms.c, pro_section.c: Restoring DW_AT_MIPS_linkage_name and DW_AT_MIPS_abstract_name (lost by accident in July 2007) and adding DW_AT_linkage_name (DWARF5, but usable in earlier DWARF versions if you wish to use it). 2016-10-07 David Anderson * libdwarf2p.1.mm: Improved the documentation of dwarf_pro_set_default_string_form(). * libdwarf2p.1.pdf: Version 1.46. Regenerated. * pro_die.c: Now the code allows modification of the start of real strings in .debug_str easily. Was a bit brittle before, allowed offset of 1 to work but not zero. * pro_opaque.h: Add dse_has_table_offset member to eliminate brittleness in the logic for .debug_str. * pro_init.c: Use dse_has_table_offset member to eliminate brittleness in the logic for .debug_str. 2016-10-04 David Anderson * dwarf_elf_access.c: Remove trailing whitespace. * dwarf_form.c: Fix an indent. * dwarf_init_finish.c: Comment the #if 0 so it is clear these are for debugging only. * dwarf_leb.c: Remove trailing whitespace. * dwarf_line.c: Remove unused #if 0/#endif code. * dwarf_macro5.c: Remove some obsolete #if 0 code. Comment the remaining #if 0 so it is clear these are for debugging only. Remove trailing whitespace. * dwarf_util.h: Delete obsolete #if 0 macro. * dwgetopt.c: Comment the #if 0 so it is clear these are for debugging only. * pro_frame.h: Delete never-used #if 0 macro. 2016-10-04 David Anderson * dwarf_util.c(_dwarf_check_string_valid): removed accidental test code. 2016-10-04 David Anderson * dwarf_leb.c: The 'make tests' test code had some warnings, which are now fixed. * libdwarf.h.in: Adding error codes. * dwarf_util.c(_dwarf_check_string_valid): Uses passed-in error code in case pointer out of bounds. _dwarf_get_size_of_val now calls _dwarf_check_string_valid() on a DW_FORM_string. * dwarf_util.h: _dwarf_check_string_valid() interface changed. * dwarf_errmsg_list.c: Adding error codes. * dwarf_form.c, dwarf_frame2.c, dwarf_global.c, dwarf_line.c, dwarf_line_table_reader_common.c, dwarf_macro.c, dwarf_macro5.c, dwarf_string.c: Using the new _dwarf_check_string_valid interface and new error codes. * dwarf_elf_access.c: Added commentary about a libelf call and possible outcomes. 2016-10-03 David Anderson * Makefile.in: Now run tests at build time to ensure DW_DLE macros correct. * dwarf_errmsg_list.c: Add new error code and add test code to verify DW_DLE_ macros specified correctly. * dwarf_sort_line.c: While this file is not used, for consistency it uses the checking macros so deleting the non-checking ones would not look odd. * dwarf_util.c: Add a check for running off end of abbreviation data at a spot that was missed till now. * dwarf_util.h: Delete unused non-checking DECODE_LEB128_UWORD and DECODE_LEB128_SWORD and SKIP_LEB128_WORD macros. * libdwarf.h.in: Add DW_DLE_ABBREV_OFF_END and correct the numbering (again). Now critical parts are checked at build time. 2016-09-30 David Anderson * dwarf_leb.c: One comparison was accidentally signed vs unsigned. Now both unsigned. 2016-09-30 David Anderson * Makefile.in: Ensure test executable removed by make clean. 2016-09-30 David Anderson * dwarf_leb.c: Fix decode and encode leb to avoid runtime warning from left-shift signed value, we got into undefined behavior. Add test code used by 'make tests'. * Makefile.in: Add leb testing to 'make tests' * configure.in: Add additional -fsanitize tests. * configure: Regenerated. 2016-09-28 David Anderson * dwarf_opaque.h: New interface for _dwarf_extract_string_offset_via_str_offsets(). Remove duplicate declaration of the function. * dwarf_form.c(_dwarf_extract_string_offset_via_str_offsets): Had a test for end of section on what was sometimes the wrong section. Now section end passed in and correct. Depending on circumstances such as where elf data was in memory, the result was a single regression test would get a DW_DLE_LEB_IMPROPER error ... or not get it. * dwarf_macro5.c: A test for DW_DLV_OK was testing the wrong local variable. 2016-09-28 David Anderson * dwarf_errmsg_list.c: Added error codes for duplicated DWARF5 .debug_loclists and .debug_rnglists sections. * dwarf_init_finish.c: Adds incomplete support for DWARF5 .debug_names.c, .debug_loclists, and .debug_rnglists Adds dwarf_get_section_max_offsets_d() to return all the possible DWARF section sizes across all DWARF2..5 * dwarf_line_table_reader_common.c: DW_LNCT renamed as DW_LNCT_GNU as the DWARF5 standard has some differences from the experimental version (no named)DW_LNCT_GNU. * dwarf_loc2.c: Renames DW_LLE to DW_LLEX as these are the non-standard experimental version (not the same as the DWARF5 standard). * dwarf_opaque.h: Updated version number comments. Added new section support data in Dwarf_Debug_s. * dwarf_ranges.c(dwarf_get_ranges_a): deleted unused local variable. * libdwarf.h.in: New error codes. Declaration for dwarf_get_section_max_offsets_d() added. Now has all the DWARF5 dwarf_get_*_name() function declarations too. * dwarf_error.h: Deleted two unwanted blank lines. 2016-09-28 David Anderson * gennames.c: Now the comparison function to qsort guarantees a stable sort by also referencing the original array location (a new data item in the struct). Needed for consistent output. 2016-09-28 David Anderson * dwarf_alloc.c: Special function _dwarf_special_no_dbg_error_malloc() was failing to return a value. Serious bug. Now it returns a value. 2016-09-27 David Anderson * dwarf.h: The previous experimental DW_LLE_ non-standard names are renamed as DW_LLEX_ temporarily. Do not use the LLEX names. 2016-09-27 David Anderson * dwarf.h: Added commentary about DW_children_yes[no] which are non-standard. Use DW_CHILDREN_yes[no] instead. 2016-09-27 David Anderson * dwarf.h: Update with the probably-final DWARF5 tags, attributes, etc. 2016-09-26 David Anderson * dwarf_query.c: Removed four lines of code associated with DWARF5 DW_MACRO_define_strx that should not have existed. There are as yet no testcases using strx, though one fuzzed testcase (liu/NULLdereference0519.elf) made it appear such was in use. 2016-09-25 David Anderson * dwarf_opaque.h: Accidentally had a function pointer definition _dwarf_get_elf_flags_func_ptr but now has a typedef of _dwarf_get_elf_flags_func_ptr_type instead. * dwarf_init_finish.c: Add definition of _dwarf_get_elf_flags_func. 2016-09-23 David Anderson * gennames.c: gennames -t generated incorrect tables. gcc -fsanitize=address noticed out of bounds references in the generated code. The code has been wrong for quite a while. It's likely no one was using the table form, gennames -s is generally better to use anyway. * pro_frame.c: Was using strdup() and now uses _dwarf_p_get_alloc() and strcpy() so we do not leak a string. 2016-09-22 David Anderson * dwarf_abbrev.c: Was calling _dwarf_error() with NULL dbg when a real dbg was available. fixed. * dwarf_alloc.c: Was testing for the static DW_DLA_ERROR too late in dwarf_dealloc(). So the address sanitizer reported the erroneous address calculation that resulted. * dwarf_error.c,dwarf_error.h: Now DE_STANDARD,DE_STATIC,DE_MALLOC let dwarf_dealloc free up Dwarf_Error resources properly. 2016-09-22 David Anderson * dwarf_ranges.c: dwarf_get_ranges_a() was allocating at the wrong place and not freeing all it should. 2016-09-21 David Anderson * dwarf_errmsg_list.c,libdwarf.h.in: Added DW_DLE_LINE_TABLE_BAD. * dwarf_line_table_reader_common.c: Added tests to prevent running off end of line table. Second commit is fix 3 line indent error. 2016-09-21 David Anderson * configure.in: Support --enable-sanitize * configure: Regenerated. * dwarf_alloc.c: Rearrange DW_DLA_STRING check to avoid calculating and using an address that may not exist. And check earlier for a NULL dbg. * dwarf_die_deliv.c: Add offset and length checks to catch corrupt dwarf. * dwarf_errmsg_list.c: Add DW_DLE_LOCLIST_OFFSET_BAD error code. * dwarf_form.c: Delete three completely blank lines for consistency in formatting.. * dwarf_loc.c: Add offset and length checks to catch corrupt dwarf. Correct the initialization of loc_section_end in _dwarf_read_loc_section(). * dwarf_ranges.c: Add free() in two places to avoid memory leak. * dwarf_util.c: Add length error checks for DW_FORM_block* . Correct initialization of end_abbrev_ptr in _dwarf_get_abbrev_for_code(). * libdwarf.h.in: Add DW_DLE_LOCLIST_OFFSET_BAD. 2016-09-17 David Anderson * libdwarf.h.in: Added error code DW_DLE_SIBLING_LIST_IMPROPER. * dwarf_errmsg_list.c: Added DW_DLE_SIBLING_LIST_IMPROPER. * dwarf_die_deliv.c: Vulnerability DW201609-001. Added a check to catch invalid DWARF instead of reading a byte inappropriately (that might not even be addressable). The error code generated is DW_DLE_SIBLING_LIST_IMPROPER. 2016-09-15 David Anderson * configure.in: Add check for unistd.h . * configure: Regenerated. * gennames.c: Add HAVE_UNISTD_H check for the include of unistd.h. 2016-09-15 David Anderson * dwarf_elf_access.c: Depends on libelf.h, so if libelf.h is missing (as shown in the generated config.h) the compile stops with an error. 2016-09-15 David Anderson * libdwarf.h.in: New interface functions dwarf_producer_finish_a() and dwarf_add_die_to_debug_a() declared, providing libdwarf-standard int return value. * libdwarf2p.1.mm: Document dwarf_producer_finish_a() and dwarf_add_die_to_debug_a(). * libdwarf2p.1.pdf: Regenerated. Rev 1.45. * pro_init.c: Remove use of C99 type uint32_t and use DW_TSHASHTYPE instead. * pro_finish.c: Implement dwarf_producer_finish_a(). * pro_die.c: Implement dwarf_add_die_to_debug_a(). 2016-09-14 David Anderson * dwarf_dsc.h: Removed accidental typedef redeclaration of Dwarf_Dsc_Head: it is already in libdwarf.h and FreeBSD compiler complained. * pro_section.c: Removed trailing whitespace from three lines. Fixed indentation on one line. 2016-09-13 David Anderson * pro_section.c: new interface dwarf_get_section_bytes_a(). * libdwarf.h.in: Declaration for dwarf_get_section_bytes_a() added. * libdwarf2p.1.mm: Document dwarf_get_section_bytes_a(). * libdwarf2p.1.pdf: Regenerated. Rev 1.44. 2016-09-12 David Anderson * libdwarf.h.in: Declaring dwarf_new_die_a() and dwarf_die_link_a(). Renamed yesterday's new function dwarf_transform_to_disk_form_b() to dwarf_transform_to_disk_form_a() for consistency with the new dwarf_new_die_a(). * pro_die.c: Implementing dwarf_new_die_a() and dwarf_die_link_a() with easier to use error handling than dwarf_new_die() and dwarf_die_link(). * libdwarf2p.1.mm: Document the new and renamed *_a() functions. * libdwarf2p.1.pdf: Regenerated. Rev 1.43. 2016-09-11 David Anderson * dwarf_errmsg_list.c: Adding DW_DLE_LEB_OUT_ERROR. * libdwarf.h.in: Adding DW_DLE_LEB_OUT_ERROR and dwarf_transform_to_disk_form_b(), first steps to making type-safe producer functions. * libdwarf2p.1.mm: Document dwarf_transform_to_disk_form_b(). * libdwarf2p.1.pdf: Rev 1.42. * pro_arange.c: Altered internal interface to _dwarf_transform_arange_to_disk(). * pro_die.c: Altered internal error return to use DW_DLV_ERROR. * pro_macinfo.c,pro_macinfo.h: Altered internal interface to _dwarf_pro_transform_macro_info_to_disk(). * pro_section.c: Implemented dwarf_transform_to_disk_form_b() and changed internals to use DW_DLV_OK/DW_DLV_ERROR. Many places where errors were ignored now have checks for error. * pro_section.h: Added GET_CHUNK_ERR to return DW_DLV_ERROR on error. Altered internal function _dwarf_transform_arange_to_disk() and _dwarf_transform_simplename_to_disk() to the newer interface. * pro_types.h: Internal declaration of _dwarf_transform_simplename_to_disk() now uses the new interface. 2016-09-11 David Anderson * dwarf_dsc.c: Set the internal flag so we do not redo the leb decoding over and over. 2016-09-08 David Anderson * Makefile.in: Add dwarf_dsc.c to the build to access DW_AT_discr_list attributes. * dwarf.h: Added comment that DW_AT_discr_list is DWARF2. * dwarf_alloc.c, dwarf_alloc.h: Added DW_DLA_DSC_HEAD support. * dwarf_dsc.c: Implement the new discriminant list functions. * dwarf_dsc.h: Internal discriminant types. * libdwarf.h.in: A new opaque type and new functions dwarf_discr_list etc. * dwarf_errmsg_list.c: New error code for discriminants: DW_DLE_DISCR_ARRAY_ERROR. * checkexample.c: Added a new example. for dwarf_descr_list(). 2016-09-01 David Anderson * libdwarf2.1.mm: Improved the wording for dwarf_diename() and dwarf_die_text(). * libdwarf2.1.pdf: Regenerated as Version 2.51. 2016-08-28 David Anderson * libdwarf.h.in: Added dwarf_pro_get_string_stats() for producer library users to know how libdwarf handled DW_AT_name etc. * pro_die.c: Corrected the tsearch-related compare/hash functions to work correctly. * pro_finish.c: Implements dwarf_pro_get_string_stats(). * pro_init.c: Hash function for tsearch implemented correctly now. * pro_opaque.h: Changed the hash data structure so it can work correctly. Added the statistics struct to the Dwarf_P_Debug structure. * libdwarf2p.1.mm: Documents dwarf_pro_get_string_stats(). * libdwarf2p.1.pdf: Revision 1.41. Regenerated. 2016-08-27 David Anderson * pro_section.c, pro_reloc_stream.c: In a couple of places names were shadowing other names. Fixed. No change in functionality. 2016-08-25 David Anderson * libdwarf.h.in: Added new error code relating to DW_FORM_strp relocations. * dwarf_errmsg_list.c: Added DW_DLE_DEBUGSTR_UNEXPECTED_REL string. * pro_die.c: Added a comment related to DW_FORM_strp. * pro_opaque.h: Added/modified commentary. * pro_section.c: Now sets the correct section symbol for relocations for strings in .debug_str. * pro_reloc.c: Added commentary, deleted blank lines. * pro_reloc_stream.c: Moved declarations to inner contexts where possible. Refined looping for clarity. 2016-08-23 David Anderson * libdwarf2p.1.mm: Document dwarf_pro_set_default_string_form. * libdwarf2p.1.pdf: Regenerated. Rev 1.40. 2016-08-23 David Anderson * dwarf_alloc.c,dwarf_frame.c: Remove trailing whitespace. * dwarf_errmsg_list.c: Has four new error codes to deal with emitting .debug_str from the producer. * gennames.c: Added 'static' to a static function to avoid compiler warnings. * libdwarf.h.in: Four new error codes. A new producer function: dwarf_pro_set_default_string_form() which causes debug_info strings to be emitted in .debug_str where that seems like it might save space. * pro_alloc.c: A new debug_str producer string hashtab free helper function to clean up the .debug_str hash table.. * pro_die.c: Now calls a single function to emit strings and can emit in either .debug_info or .debug_str. * pro_die.h: Declares _dwarf_pro_set_string_attr() now. * pro_forms.c: Some local variables are always initialized now at declaration point. Now uses common code to set up strings. * pro_init.c: Initializes debug_str hash table for strings And sets up the section properly. Defines the hashfunc. * pro_opaque.h: Fixes some spacing awkwardness. Adds .debug_str hash data and eliminates unused data. * pro_section.c: Now emits .debug_str when such is wanted. 2016-06-13 David Anderson * dwarf_alloc.c: Dwarf_Fde_s now has a destructor. * dwarf_frame.c,dwarf_frame.h: Now dwarf_get_fde_info_for_reg3 memoizes frame data making one pattern of use (from dwarfdump) much much faster. 2016-06-13 David Anderson * dwarf_frame.c: Revised some local assignments so we are sure the same value used as intended. Added some {} on if for consistency with libdwarf use. * gennames.c: Update version string. 2016-06-12 David Anderson * libdwarf/gennames.c: Update version string. 2016-06-12 David Anderson * dwarf_frame.c: Adding dwarf_get_fde_info_for_cfa_reg3_b() which lets dwarfdump print frame data a bit more quickly. It is unclear whether other applications will find this new interface to be of value. * dwarf_frame.h,dwarf_frame3.c: Internal interfaces changed slightly to allow the new function to work. * libdwarf.h.in: Added dwarf_get_fde_info_for_cfa_reg3_b() declaration. * libdwarf2.1.mm: Documents dwarf_get_fde_info_for_cfa_reg3_b(). Rev.2.50 * libdwarf2.1.pdf: Regenerated. 2016-06-08 David Anderson * dwarf_init_finish.c, dwarf_line_table_reader_common.c: Remove trailing whitespace. Fix one indent. 2016-06-08 David Anderson * gennames.c: Update version string. 2016-06-07 David Anderson * Makefile.in: Use $(SONAME) rather than libdwarf.so.1 whereever possible. 2016-06-01 David Anderson * Makefile.in: Tweaks for debian build compatibility. * gennames.c: Use DW_VERSION_DATE_STR instead of __DATE__ __TIME__ 2016-05-23 David Anderson * dwarf_errmsg_list.c, libdwarf.h.in: Added DW_DLE_COMPRESSED_EMPTY_SECTION. * dwarf_init_finish.c: If load_section gets DW_DLV_NO_ENTRY just return that. If requres-decompress but has no data call it a corrupt Elf section (given what sections libdwarf is interested in). * dwarf_line_table_reader_common.c: Only deal with line table format entries if the count is > 0. 2016-05-23 David Anderson * Makefile.in: add SONAME libdwarf.so.1 to dynamic section when building shared libdwarf.so We have not made an incompatible interface change since May 19, 2014 (and that was to the producer code not to what DWARF readers use). 2016-05-22 David Anderson * libdwarf.h.in, dwarf_errmsg_list.c: Adding DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH error code. Fixed unsigned/signed comparison warning in the table test code. * dwarf_line.c: If we find a null pointer from include directores we substitute "" for the reader. * dwarf_line_table_reader_common.c: Detect a corrupted DWARF5 directory count vs directory format count problem and return an error. 2016-05-20 David Anderson * dwarf_macro5.c: Was failing to initialize mc_cu_context leading to coredump. If dwarf_srcfiles() returned zero as the count of source files an erroneous calloc() would result in an objection from valgrind: an erroneous calloc of zero bytes of srcfiles pointers would never be freed. 2016-05-19 David Anderson * Makefile.in: HOST_CFLAGS now references CFLAGS at the request of the Debian project. * configure.in: Now defaults to -fPIC always (though in a nonshared build one could reasonably turn it off with --disable-fpic) Adds several messages reporting configure actions. * configure: Regenerated. 2016-05-18 David Anderson * dwarf_form.c: Directly check expression length against section length in case expression length very very large. * dwarf_query.c: _dwarf_calculate_info_section_*() routines made clearer and the *_start_ptr() instance also now returns the length (via a pointer arg). * dwarf_xu_index.c: Check data read from the section so a wildly large columns count or slots count will be caught and an error returned. 2016-05-16 David Anderson * dwarf_elf_access.c: Check more thoroughly for corrupt relocation records and return an error if such found. * dwarf_macro5.c: Remove trailing whitespace. 2016-05-10 David Anderson * dwarf_arange.c,dwarf_die_deliv.c: All read operations check for overrun. * dwarf_errmsg_list.c: DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE, DW_DLE_LOCEXPR_OFF_SECTION_END, and DW_DLE_POINTER_SECTION_UNKNOWN added to error values. * dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_global.c,dwarf_line.c, dwarf_line_table_reader_common.c,dwarf_loc.c,dwarf_loc2.c, dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, dwarf_ranges.c,dwarf_util.c, dwarf_xu_index.c: All read operations check for overrun. * dwarf_opaque.h: Put the 4 SGI-only section data items next to each other to make it clear they are such. * dwarf_util.h: Added some checks to READ_AREA_LENGTH_CK * libdwarf.h.in: Defined the new error names. 2016-05-07-b David Anderson * libdwarf2.1.mm,libdwarf2p.1.mm: Fixed spelling errors. * libdwarf2.1.pdf,libdwarf2p.1.pdf: Regenerated. 2016-05-07 David Anderson * libdwarf.h.in, dwarf_errmsg_list.c: New error codes for stopping due to corrupted frame data. * dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c,dwarf_line.c: Notice frame area overrun and generate error. 2016-05-06 David Anderson * dwarf_errmsg_list.c: Added DW_DLE_ZLIB_SECTION_SHORT. * dwarf_form.c: Now checking for section overrun. * dwarf_init_finish.c: Now checking zlib reading for section overrun. * dwarf_macro5.c: Now checking for section overrun and also fixing double delete caused by having _dwarf_get_alloc() space pointing at other _dwarf_get_alloc() space. Because in case of error the order of free of such is unpredictable! * dwarf_macro5.h: Added comment on mc_srcfiles member. * libdwarf.h.in: Added DW_DLE_ZLIB_SECTION_SHORT. 2016-05-05 David Anderson * dwarf_form.c: Add a test so that a really large form_block length will not be considered safe (due to unsigned arithmetic overflow). Fixed the new check-code reading string offsets section so the endpoint in the check is that section, not debug_info. * dwarf_query.c: New function _dwarf_calculate_info_section_start_ptr() helps in some checking. * dwarf_util.h: Add a test so arithmetic overflow will not show a bogus value as being ok. * libdwarf.h.in,dwarf_errmsg_list.c: Add error code DW_DLE_FORM_BLOCK_LENGTH_ERROR so we have a specific error for this case. * dwarf_line.c: %lld switched to "%" DW_PR_DSd * dwarf_opaque.h: Added function declaration for _dwarf_calculate_info_section_start_ptr(). 2016-05-04 David Anderson * dwarf_macro5.c(construct_at_path_from_parts): Move 3 lines of code up to test for NULL pointer. So we do not dereference the pointer. 2016-05-03 David Anderson * dwarf_die_deliv.c: Add checks for overrun of end of section due to corrupted DWARF. * dwarf_arange.c,dwarf_util.c: first use of READ_UNALIGNED_CK. * dwarf_errmsg_list.c, libdwarf.h.in: DW_DLE_READ_LITTLEENDIAN_ERROR and DW_DLE_READ_BIGENDIAN_ERROR are errors possible in READ_UNALIGNED_CK. DW_DLE_LINE_OFFSET_WRONG_FORM gives a more meaningful description of a particular corruption problem (not a new test, just a new error name). * dwarf_elf_access.c: Add a check on relocations to ensure we do not write off the end of the section. * dwarf_query.c: Using local variables for shorter lines. * dwarf_util.h: Implement READ_UNALIGNED_CK macros. * dwarf_leb.c: Improve a couple comments. * dwarf_line.c: Now use DW_DLE_LINE_OFFSET_WRONG_FORM. Add operandmismatch() to get better debug information in case of corrupted dwarf. Revise the code for clarity. * dwarf_macro5.c: Duplicate free() could result if dwarf_finish() was used to clean up from a dwarf macro context. Two functions are really static so the function type set properly now. 2016-04-30 David Anderson * dwarf_frame.c, dwarf_line_table_reader_common.c, dwarf_loc2.c: switch to using DECODE_LEB*_CK. * dwarf_frame.c: Delete unused local variables. Use DECODE_LEB*_CK for better error checking. * dwarf_frame2.c, dwarf_frame.h: Internal functions get new arguments to support DECODE_LEB*_CK. * dwarf_arange.c: Using UNUSEDARG to suppress warning. * dwarf_line_table_reader_common.c: Use DECODE_LEB*_CK for better error checking. * dwarf_loc2.c: Use DECODE_LEB*_CK for better error checking. 2016-04-30 David Anderson * dwarf_die_deliv.c: Deleted unused local variable. * dwarf_form.c,dwarf_macro.c, dwarf_macro5.c: Now uses DCODE_LEB128*_CK nearly everywhere for better checking for corrupted data. * dwarf_opaque.h:New argument to _dwarf_get_addr_index_itself() for better data checks.. * dwarf_query.c: Uses revised _dwarf_get_addr_index_itself() interface. * dwarf_util.c: Fixed formatting errors. 2016-04-29 David Anderson * dwarf_line_table_reader_common.c, dwarf_macro.c, dwarf_macro5.c, dwarf_util.c, dwarf_util.h: Now use DECODE_LEB128_*CK macros simplifying the code while catching errors/corruption in DWARF data. 2016-04-28 David Anderson * dwarf_die_deliv.c: Now _dwarf_next_die_info_ptr() has a section length argument. * dwarf_query.c, dwarf_util.c: Now uses the checked version of leb reading. * dwarf_util.h: Now _dwarf_get_size_of_val() has section_end_ptr argument for checking leb values do not overrun end of section. 2016-04-27 David Anderson * dwarf_frame2.c: Now notices a frame-length field which is too large to be meaningful and returns an error.. 2016-04-27 David Anderson * Makefile.in: Now dwarf_error.o dependency on dwarf_errmsg_list.c is explicit. * dwarf_errmsg_list.c: New error strings. * libdwarf.h.in: New error values for when running off end of section and line range and address size where zero leads to trouble.. * dwarf_abbrev.c,dwarf_die_deliv.c, dwarf_frame.c, dwarf_frame.h, dwarf_frame2.c,dwarf_frame3.c,dwarf_leb.c, dwarf_line.c, dwarf_line.h, dwarf_line_table_reader_common.c, dwarf_query.c,dwarf_util.c,dwarf_util.h: Add checks for running off end of section. 2016-04-26 David Anderson * Makefile.in: The new errmsg_check dependency line was a bit wrong. libdwarf.h should not have $(srcdir) 2016-04-25 David Anderson * dwarf_errmsg_list.c: When -DTESTING ensure all the error messages have a value in () so we can check that value. 2016-04-25 David Anderson * dwarf_tied.c: A C11-ism crept in. Fixed. Added 'static' to local function declaration. Removed unused local variable. * dwarf_errmsg_list.c: Now checks that the number in () matches the index (and still checks that the array size is the declared size) when compiled -DTESTING. 2016-04-25 David Anderson * dwarf_errmsg_list.c: Fixed indent mistakes. * dwarf_leb.c: Fixed places were leb128_length was assumed non-null (dwarf_form.c passes NULL!). 2016-04-25 David Anderson * Makefile.in: Added testing of the _dwarf_errmsgs array. * dwarf_error.c: Moved _dwarf_errmsgs out of dwarf_error.c into dwarf_errmsg_list.c * dwarf_errmsg_list.c: Now has error strings and test code. 2016-04-25 David Anderson * dwarf_error.c: The error description "DW_DLE_GDB_INDEX_INDEX_ERROR(264)" was missing the comma so following errors were reporting the wrong string. 2016-04-21 Carlos Alberto Enciso * Use the _WIN32 macro to identify a WINDOWS specific code. 2016-03-14 David Anderson * dwarf_util.c: Changed 'byte' to 'byte pair' in a comment. Where we read abbreviation AT/FORM lists. 2016-03-14 David Anderson * dwarf_error.c(_dwarf_errno): Now prints to stdout and does abort(1) when it has to give up. Instead of using stderr and abort(). It is not a good idea for applications to fail to provide error handling, so no one should notice this change. * libdwarf2.1.mm: Documents behavior in case there is no error handling provided by our caller. * libdwarf2.1.pdf: Regenerated. Rev 2.48. 2016-03-14 David Anderson * libdwarf2.1.mm: Documents Dwarf_Handler error handler function. * libdwarf2.1.pdf: Regenerated. Rev 2.47. 2016-03-13 David Anderson * dwarf_query.c: Use dwarf_formstring to read string attributes as it handles all the string types already. Now dwarf_diename() and dwarf_die_text() call dwarf_formstring() so DW_FORM_strp_sup and DW_FORM_GNU_strp_alt are properly handled(along with all the other string FORMs). * dwarf_form.c: Handle an error in dwarf_formstring() (for tied files, or the lack thereof) differently so it all works properly even if the incoming error argument is null. 2016-03-12 David Anderson * dwarf_abbrev.c: Uses renamed fields abbrev internal struct. Removes some gratuitous (). Adds clarifying {} * dwarf_abbrev.h: renames Dwarf_Abbrev_s struct fields from ab_tag to dab_tag, etc. Adds global section offset to the fields. * dwarf_die_deliv.c: Uses renamed Abbrev_List fields. Adds dwarf_die_abbrev_global_offset() function so clients can properly identify where an abbrev entry is in .debug_abbrev. * dwarf_die_deliv.h: renames Dwarf_Abbrev_List struct fields from ab_tag to abl_tag etc. Adds abl_goffset, abl_count. * dwarf_query.c,dwarf_util.c: Uses renamed Dwarf_Abbrev_List fields. * libdwarf.h.in: Adds function dwarf_die_abbrev_global_offset(). * libdwarf2.1.mm: Documents dwarf_die_abbrev_global_offset(). * libdwarf2.1.pdf: Regenerated. Rev 2.46. 2016-03-11 David Anderson * dwarf_die_deliv.c: Fixed issues with handling NULL Dwarf_Error* and with mistakes treating DW_DLV_NO_ENTRY as if it were DW_DLV_ERROR. * dwarf_form.c: Only do dwarf_errno(*error) when error is non-null. * dwarf_macro5.c, dwarf_query.c, dwarf_ranges.c: Avoid the possibility of doing dwarf_errno(*error) when error is null. * dwarf_util.c(_dwarf_error_mv_s_to_t): Added code to ensure that nothing crash-worthy happens even if a future internal caller calls it with one or more NULL arguments. * libdwarf2.1.mm: Added a few words about Error Handling in general to clarify earlier wording (earlier wording was not as explicit as it should have been). * libdwarf2.1.pdf: Regenerated. Version 2.45 * dwarf_sort_line.c: Though no longer built or used, added an initializer to a local variable for correctness. * dwarf_addr_finder.c: Though no longer compiled or used (is IRIX only), cleaned up local variable declarations that were not up to the current standard usage in libdwarf. 2016-03-11 David Anderson * Makefile.in: Added a comment about pr and pdf-building. 2016-03-09 David Anderson * libdwarf2.1.mm: Slightly altered the dwarf_offsets_list() documentation. * libdwarf2.1.pdf: Rev 2.44. Regenerated. 2016-03-09 David Anderson * dwarf_form.c: Correct and amplify a comment. 2016-03-01 David Anderson * libdwarf2.1.mm: Documented dwarf_dietype() and dwarf_offset_list(). * libdwarf2.1.pdf: Regenerated. Rev 2.43 * checkexamples.c: Added example for dwarf_offset_list(). 2016-02-19 Carlos Alberto Enciso * dwarf_alloc.h, dwarf_alloc.c, dwarf_base_types.h, dwarf_opaque.h: New allocator type (DW_DLA_CHAIN_2), to allow a list of addressed types (address, offset). There was Memory corruption due to incorrect usage of memory allocator type. * dwarf_query.c: Use the new allocator type. 2016-02-14 David Anderson * libdwarf2.1.mm: dwarf_exprloc -> dwarf_formexprloc. The spelling error was introduced in version 2.41. * libdwarf2.1.pdf: Regenerated. Version 2.42 2016-02-13 David Anderson * libdwarf2.1.mm: Added dwarf_lineoff_b() documentation. Fixed a typo in dwarf_formexprloc() documentation. * libdwarf2.1.pdf: Regenerated. Version 2.41 * Makefile.in: Add HOSTCFLAGS HOSTLDFLAGS HOSTCC to make it easier to cross-compile. Remove common.c, common.h (a few lines of code moved to gennames.c). * README: document use of HOSTCC * common.c,common.h: Delete. A few lines of code moved to gennames.c. * configure.in: for AC_TRY_RUN add [],[] for else and for cross-compile cases. * configure: Regenerated. * dwarf_die_deliv.c, dwarf_frame2.c, dwarf_line.c, dwarf_macro5.c, dwarf_print_lines.c, dwarf_ranges.c: Renamed to avoid shadowing variables with same name. For clarity. * gennames.c: Incorporates a few lines from common.c so common.c, common.h can be deleted. 2016-02-10 David Anderson * README: Improved a comment about Dwarf_Obj_Access_Methods. * dwarf_elf_access.c: New function _dwarf_get_elf_flags_func() extracts the sh_flags field from Elf sections. In an odd way so we preserve binary and source compatibility.+ * dwarf_error.c,libdwarf.h.in: New error DW_DLE_ELF_FLAGS_NOT_AVAILABLE. * dwarf_init_finish.c: Use new (global) function pointer _dwarf_get_elf_flags_func_ptr to access extra Elf data without breaking compatibility. Add additional way (SHF_COMPRESSED) to detect zlib compression and expand the compressed data. 2016-02-08 David Anderson * dwarf_alloc.c: Drop VALTYPE, use DW_TSHASHTYPE instead. Use DW_TSHASHTYPE in the hash functions. * dwarf_tied.c: Use DW_TSHASHTYPE in the hash function. * dwarf_tsearchhash.c: Add back the UNUSEDARG to avoid unused argument warnings. 2016-02-07 David Anderson * dwarf_init_finish.c: Fix indents. remove a trailing space. * dwarf_tsearch.h,dwarf_tsearchhash.c: Now DW_TSHASHTYPE (if not defined otherwise) defines the type returned by the hash function used in tsearchhash. * pro_alloc.c: Removed trailing whitespace. 2016-02-07 David Anderson * README: Mention https://github.com/jrfonseca/drmingw/tree/master/src/mgwhelp * dwarf_init_finish.c: If SHT_RELA not defined define it as 4 in hopes that will not cause trouble for mingw. For Elf objects 4 is the correct value and is defined in elf.h 2016-02-06 David Anderson * dwarf_elf_access.c,dwarf_original_elf_init.c,dwarf_tsearchhash.c, libdwarfdefs.h: Remove trailing whitespace. 2016-02-06 David Anderson * configure.in: defines HAVE_UNUSED_ATTRIBUTE if the gcc '__attribute__ ((unused))' compiles ok. * config.h.in, configure: Regenerated. * libdwarfdefs.h: Test HAVE_UNUSED_ATTRIBUTE and define UNUSEDARG appropriately. * dwarf_alloc.c,dwarf_elf_access.c,dwarf_form.c,dwarf_frame2.c, dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, dwarf_line_table_reader_common.c,dwarf_macro5.c, dwarf_original_elf_init.c,dwarf_print_lines.c,dwarf_ranges.c, dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, pro_alloc.c,pro_frame.c,pro_init.c,pro_reloc.c, pro_reloc_stream.c,pro_section.c: Use UNUSEDARG to suppress meaningless unused-parameter warnings from gcc. 2016-02-06 David Anderson * dwarf_tsearchhash.c: The original default hash table size (a prime number) was very small. Now its closer to 100. 2016-02-06 David Anderson * dwarf_frame.h: Added fde_fd_eh_table_value. Added fde->fd_gnu_eh_aug_present so presence/absence is unambiguous. * dwarf_frame.c: Added code to set fd_eh_table_value when appropriate, though there is no interface for dwarfdump to get the value yet. * dwarf_frame2.c: Update the new fields appropriately. Corrected some comments about the eh_frame cie_id field. 2016-02-05 David Anderson * dwarf_frame2.c: Comments in get_cieptr_given_offset() were slightly incorrect and one calculation was pointlessly full of casts. Fixed commentary about the CIE_pointer (CIE id or FDE id) field in a frame header. * dwarf_loc2.c: Fixed compiler warning on signed/unsigned comparison by changing local variable int->Dwarf_Unsigned.. * pro_init.c: Removed extraneous semicolon to avoid warning for C90. 2016-01-26 David Anderson * dwarf_abbrev.c: Remove useless blank line. * dwarf_macro5.c: Add check for macro_import offset correctness. 2016-01-21 David Anderson * libdwarf.h.in: Typo, */* fixed to be * /* * configure.in: Added new gcc compiler options to --enable-wall. * configure: regenerated. * dwarf_die_deliv.c dwarf_frame.c,dwarf_frame2.c,dwarf_gdbindex.c, dwarf_gdbindex.h,dwarf_line.c,dwarf_line.h, dwarf_line_table_reader_common.c,dwarf_macro5.c,dwarf_query.c, dwarf_tsearchhash.c: Eliminated use of int/Dwarf_Signed in favor of unsigned types where signed served no purpose. Added ommitted return DW_DLV_NO_ERROR in dwarf_frame2.c. Other than 'unused parameter' fixed the warnings from gcc. No interfaces changed though. To keep binary compatibility. 2016-01-20 David Anderson * dwarf_query.c: New function dwarf_die_text() is a general way to get strings from various attributes in a DIE. * libdwarf.h.in: Add prototype for dwarf_die_text(). * libdwarf2.1.mm: Document dwarf_die_text(). * libdwarf2.1.pdf: Regenerated. Version 2.40. 2016-01-19 David Anderson * Makefile.in: Remove dwarf_stubs.o. * configure.in: Add various gcc opts to --enable-wall to get appropriate coverage. * configure: regenerated. * dwarf_macro5.c: File-local functions now declared static. * dwarf_query.c: File-local functions now declared static. * dwarf_stubs.c: No longer this function. It never had a prototype declaration and never had more than return DW_DLV_ERROR as an implementation. * dwarf_util.c: Remove trailing whitespace. * dwarf_original_elf_init.c(dwarf_set_tied_dbg): Added check for null dbg. * dwgetopt.c: Add include of dwgetopt.h. #if 0 a testing-only function. All functions prototyped, no (). * libdwarf.h.in: Comment out argument names for safety. Added dwarf_get_tied_dbg(), dwarf_dietype_offset(), dwarf_pubtype_type_die_offset() declarations. Sorted the dwarf_get_TAG_name() etc function names. * pro_alloc.c: Documented and commented a useless function, dwarf_p_dealloc(). . * pro_alloc.h: Prototyped both the useful and useless global-to-libdwarf producer functions _dwarf_p_dealloc and dwarf_p_dealloc. * libdwarf2.1.mm: Documented dwarf_get_tied_dbg(), dwarf_fde_section_offset(), and dwarf_cie_section_offset() * libdwarf2.1.pdf: Regenerated. Rev 2.39 2016-01-19 David Anderson * dwarf_form.c,dwarf_macro5.c: Ensure declarations before executable statements * dwarf_loc.c: Cast pointer to Dwarf_Small* so pointer arithmetic works (standard conformance). Ensure declarations before executable statements * dwarf_macro5.c: Ensure declarations before executable statements. * dwarf_query.c: Ensure declarations before executable statements. Add dwarf_dietype_offset() convenience function. * dwarf_util.c: Use a local name that does not conflict with standards. use mydw_errno, not errno. * dwarf_frame2.c(dwarf_read_cie_fde_prefix): Add tests to ensure we do not access past end of a section. 2016-01-19 David Anderson * dwarf_form.c, dwarf_frame2.c,: Fix indentation and trailing whitespace. 2016-01-19 David Anderson * dwarf_line.c, dwarf_line_table_reader_common.c, dwarf_loc.c, dwarf_macro5.c, dwarf_query.c, pro_die.c: Remove silly second ; from ;; where appropriate. 2016-01-19 David Anderson * libdwarf.h.in, dwarf_error.c: New error numbers. DW_DLE_LINE_STRP_OFFSET_BAD, DW_DLE_STRING_FORM_IMPROPER. * dwarf_form.c: Added suport for DW_FORM_line_strp into dwarf_form_string(). 2016-01-17 David Anderson * dwarf_frame2.c: Added additional checks for bad frame section. Looking for premature end of frame data. 2016-01-16 David Anderson * libdwarf2.1.mm: Documented DWARF5 macro operations. Version 2.38 * libdwarf2.1.pdf: Regenerated. * libdwarf2p.1.pdf: Regenerated following a trivial clarification on cie production made a couple days ago. 2016-01-15 David Anderson * pro_frame.h, pro_frame.c: The code adding a CIE for output (dwarf_add_frame_cie()) was simply assuming that the augmentation string passed in was in stable storage. Now it uses strdup() to guarantee there no surprises. 2016-01-14 David Anderson * dwarf_query.c(dwarf_die_offsets): 'res ==' corrected to 'res ='. 2016-01-12 David Anderson * dwarf_macro5.c: Fixed DW_MACRO_define/undef calls of _dwarf_check_string_valid(). Arranged to get the macro unit offset out when creating context. * libdwarf.h.in: Fixed declaration of dwarf_get_macro_context() to get the macro unit offset out of it so it can work properly in all contexts. dwarfutils-20200114/libdwarf/ChangeLog2017000066400000000000000000000440771361531463500200320ustar00rootroot00000000000000 2017-12-01 David Anderson * gennames.c: Update version string. 2017-12-01 David Anderson * dwarf_frame2.c: dwarf_get_fde_augmentation_data() could return data that would result in segfaulting in a caller. Now the length is checked and if in error then DW_DLE_AUG_DATA_LENGTH_BAD is set as the error. 2017-11-08 David Anderson * dwarf_die_deliv.c(_dwarf_die_next_info_ptr): Dereferencing a pointer not fully checked could lead to segv in libdwarf. * dwarf_frame.c(_dwarf_get_return_address_reg): Dereferencing a pointer not fully checked could lead to segv in libdwarf. * dwarf_frame2.c(dwarf_create_cie_from_after_start): Dereferencing a pointer not fully checked could lead to segv in libdwarf. * dwarf_line_table_reader_common.c(_dwarf_read_line_table_header): DW201711-002 fix. Dereferencing pointers not fully checked could lead to segv in libdwarf. * dwarf_query.c(_dwarf_die_attr_unsigned_constant): Dereferencing a pointer not fully checked could lead to segv in libdwarf. 2017-11-01 David Anderson * dwarf_frame.c(_dwarf_exec_frame_instr): An invalid frame section with a DW_CFA_advance_loc1 could result in dereferencing an invalid pointer. Now fixed. 2017-10-29 David Anderson * dwarf.h: There was a typo in DW_FORM_strx4. 2017-10-20 David Anderson * dwarf_form.c: New function: dwarf_formdata16() reads DW_FORM_data16. * dwarf_query.c,dwarf_util.c: Added support for DW_FORM_data16. * libdwarf.h.in: Declarations for new functions dwarf_add_AT_data16() and dwarf_formdata16() and new datatype Dwarf_Form_Data16 (since there is no numerical type we can use at present). 2017-10-15 David Anderson * dwgetopt.c: Removing unused local variable 'found'. 2017-10-15 David Anderson * dwgetopt.c,dwgetopt.h: Now handles simple long argument names cases. 2017-10-05 David Anderson * gennames.c: Update version string. 2017-10-13 David Anderson * dwarf.h,libdwarf/dwarf_loc.c: Corrected spelling to match its use in DWARF5: DW_SECT_LOC -> DW_SECT_LOCLISTS 2017-10-05 David Anderson * tag_attr.list,dwarf.h,dwarf_die_deliv.c, dwarf_opaque.h, dwarf_query.c,libdwarf.h.in: Changed DW_AT_ranges_base spelling to DW_AT_rnglists_base to match the final DWARF5 standard. 2017-09-26 David Anderson * gennames.c: Update version string. * dwarf_abbrev.c: See DW201709-001. A carefully constructed invalid abbrev section could result in a caller getting an invalid memory reference. So an addtional 'if' statement catches the error now. 2017-08-22 David Anderson * gennames.c: Update version string. 2017-08-21 David Anderson * Makefile.in: Now 'make test', not 'make tests'. So consistent test name with dwarfdump. * configure.cmake: Improving the handling of libelf (mainly for Windows) and simplifying this file. * dwarf_init_finish.c: Fixed indentation errors. * gennames.c: Update version string. 2017-07-27 David Anderson * dwarf_init_finish.c(_dwarf_setup): Removed some dead code and that simplified the the logic. Comments fixed as some in this area were not correct (stale comments). 2017-07-24 David Anderson * configure.in, configure.cmake, config.h.in: Renamed LOCATION_OF_LIBELFHEADER to HAVE_LOCATION_OF_LIBELFHEADER for consistency with config.h.in generally. * configure: Regenerated 2017-07-24 David Anderson * configure.in, configure.cmake, config.h.in: Consistent use of LOCATION_OF_LIBELFHEADER so Windows can build libdwarf with configure or cmake. * configure: Regenerated 2017-07-08 David Anderson * gennames.c: Update version string. 2017-07-06 David Anderson * dwarf_query.c(_dwarf_get_value_ptr): Did an add that could overflow and segv given certain fuzzing and a certain run time data layout. Fixed so the bad data is detected now and libdwarf returns an error code. A place in _dwarf_extract_address_from_debug_addr() that an overflow might possibly occur fixed too. 2017-06-29 David Anderson * dwarf_elf_access.c: Added R_SPARC_TLS_DTPOFF32 for the EM_SPARC32PLUS. 2017-06-03 David Anderson * dwarf_form.c,dwarf_frame2.c: Now use _dwarf_decode_s_leb128_chk(), the checked form. * dwarf_leb.c: Deleted _dwarf_decode_u_leb128() and _dwarf_decode_s_leb128(), they are no longer used. * dwarf_reloc_386.h: Removed some trailing whitespace. * dwarf_util.h: Removed READ_UNALIGNED macro. Removed declarations of the deleted two functions _dwarf_decode_u_leb128() and _dwarf_decode_s_leb128() 2017-05-30 David Anderson * dwarf_die_deliv.c: Added commentary about the DW_AT_dwo_id found only in experimental DWARF4. * libdwarf.h.in: Added commentary about Dwarf_Sig8 struct. 2017-05-28 David Anderson * gennames.c: Update version string. 2017-05-25 David Anderson * gennames.c: Update version string. * dwarf_reloc_386.h: Added so dwarfdump can print i386 relocations sensibly. * dwarf_elf_access.c: For WIN32 added dwarf_reloc_386.h include. 2017-05-18 David Anderson * dwarf_elf_access.c: Added R_X86_64_PC32 to the list of relocations we can expect to see. 2017-05-18 David Anderson * dwarf_opaque.h: Now names _dwarf_destroy_group_map so the group map destructor can be called when cleaning up a Dwarf_Debug. * dwarf_alloc.c: Call _dwarf_destroy_group_map(). * dwarf_groups.c: Implemented _dwarf_destroy_group_map() to clean up the map. 2017-05-18 David Anderson * dwarf_init_finish.c: One argument was unused in is_a_special_section_semi_dwarf() so removed that argument. Function is local (static) so safe to change it. Avoids a compiler warning. 2017-05-18 David Anderson * libdwarf2.1.mm: Filling in documentation of the new sections. Rev 2.58. There is more on this to do. * libdwarf2.1.pdf: Regenerated. * dwarf_groups.c: Inserted a space so things lined up, one place. 2017-05-18 David Anderson * libdwarf2.1.mm: Documenting new functions including .debug_names access and group operations. Rev 2.57. There is more on this to do. * libdwarf2.1.pdf: Regenerated. 2017-05-18 David Anderson * libdwarf2.1.mm: Documenting new functions including .debug_names access and group operations. Rev 2.56. 2017-05-14 David Anderson * libdwarf2.1.mm: Added a comment about a special case of dwarf_get_section_count(). Rev 2.55 now. * CMakeLists.txt, Makefile.in: Add dwarf_groups.c(.o), a new source file. * dwarf_elf_access.c: Added trailing _doas to a local variable so related uses easily found with grep. Added some sections to the relocatables sections list. * dwarf_errmsg_list.c: Added six new error codes related to groups. * dwarf_groups.c: New file to deal with both split-dwarf and comdat groups. Added section name to the struct for improved reporting from dwarfdump. Much easier to understand groups this way. Added array of dwo section names so those group 2 names get the right group (and obviously get it right). * dwarf_init_finish.c: most of the new code for groups is in this file. Now accomodates non-dwarf SHT_GROUP sections by figuring out they should be ignored. Fixed some indentation issues. Added critical commentary to make it easier to follow the handling of groups. * dwarf_die_deliv.c: Named a local for a call so the call would not have an unadorned 0. * dwarf_opaque.h: New fields for comdat groups. A new small struct, Dwarf_Group_Data_s has the data so it's all in one place. * dwarf_query.c: Trailing blank lines deleted. Added a few lines of #if 0 code, for debugging. * libdwarf.h.in: New error codes and new functions for section groups. 2017-04-29 David Anderson * pro_arange.c,pro_init.c, pro_opaque.h, pro_section.c, pro_types.c: Renamed de_reloc_name function pointer as de_relocate_by_name_symbol. Most relocation points use a single section-name elf symbol as the relocation reference. Renamed de_reloc_pair function pointer as de_relocate_pair_by_symbol. dump_bytes() debug code is now #if 0. Deleted set but not used local variable in _dwarf_pro_generate_debuginfo(). 2017-04-21 David Anderson * pro_section.c: Improved commentary on the abbrev section offset and on the backpatch of overall CU length once CU generated. 2017-04-20 David Anderson * dwarf_die_deliv.c: declaration of local separated from definition for easier insertion of debug stuff. Nothing substantive done. * dwarf_errmsg_list.c,libdwarf.h.in: Added DW_DLE_UNIT_TYPE_NOT_HANDLED. * dwarf_util.c: Fixed setup of debug_info header field reader. output code. 2017-04-20 David Anderson * pro_section.c: A harmless(!) comment-within-comment removed. 2017-04-20 David Anderson * gennames.c: Update version string. 2017-04-20 David Anderson * configure.in: Added additional gcc -W to --enable-wall. * configure: Regenerated. * dwarf_errmsg_list.c: Added new error codes in new DWARF5 support. * dwarf_line_table_reader_common.c: Improved comments and added specific code for DWARF5 (just clarity here, no real change). * dwarf_opaque.h: Removed unused declaration of cc_at_comp_dir. * dwarf_print_lines.c: Update copyright year. * libdwarf.h.in: Added new DW_DLE codes. * pro_alloc.c: Added tdestroy for the de_debug_line_str_hashtab to support a .debug_line_str section. * pro_arange.c: Renamed local variables for greater clarity and fixed an improper length write to be offset_size. * pro_die.c: Generalized _dwarf_insert_or_find_in_debug_str() so it can apply to the debug_str or debug_line_str sections. * pro_finish.c: We have new statistics arrangement to aid in getting statistics on debug_str and debug_line_str independently. So a little change needed to get things to compile. * pro_frame.c: Now sets cie_version properly for all DWARF versions. * pro_frame.h: cie_version field changed to proper size (Dwarf_Half). * pro_init.c: Support for .debug_line_str strings added. Corrected ancient serious botch in setting up 64bit output. Tweaked the version setup a little (no real change). Moved _dwarf_init_default_line_header_vals() call to where it actually works right for getting version number. * pro_line.c: Unified handling of include directories and files so that we can reuse code readily. Eliminating one internal struct declaration. * pro_line.h: Added new fields for DWARF5 data. Deleted struct Dwarf_P_Inc_Dir_s. * pro_opaque.h: Rearranged section codes and strings and added in DWARF5 sections. Added fields to Dwarf_P_Line_Inits_s for DWARF5 support. Revised struct Dwarf_P_Stats_s and Dwarf_P_Debug_s for DWARF5 support. * pro_section.c: Added DWARF5 sections to tables and began the addition to generation of these sections. Refactored debug_line header output for clarity, DWARF5 support, and to avoid code duplication. 2017-04-19 David Anderson * dwarf_opaque.h: Deleted the unused field cc_at_comp_dir. 2017-04-17 David Anderson * pro_init.c(common_init): Handling of 64bit offsets was coded wrong, the length field would be emitted incorrectly (confusing standard 64bit offset dwarf with non-standard IRIX 64bit offset dwarf). 2017-04-17 David Anderson * gennames.c: Update version string. * dwarf_dnames.c: Fixed indentation of a few lines. * dwarf_frame2.c: Deleted the argument fde_eh_encoding_out from the local function get_gcc_eh_augmentation() as is not needed and got an annoying compiler warning. * dwarf_print_lines.c: Removed trailing whitespace. 2017-04-16 David Anderson * CMakeLists.txt: Added in the new files dwarf_dnames.c, .h 2017-04-16 David Anderson * README: A common build problem and the fix are mentioned. * configure.in: Added more checking messages and results so easier diagnose problems. * config.h.in,configure: Regenerated with GNU Autoconf 2.69 2017-04-15 David Anderson * dwarf_print_lines.c: Added a comment , a reminder that _dwarf_print_line_context_record() was never implemented. * libdwarf.h.in: Deleted mistaken declarations dwarf_srcfiles_b(), dwarf_get_macro(), and dwarf_get_all_defined_macros(). No such functions were ever defined. 2017-04-12 David Anderson * gennames.c: Update version string. 2017-04-12 David Anderson * dwarf_alloc.c: Renamed function as _dwarf_debugnames_destructor(). * dwarf_dnames.c: Implemented a suite of new functions to allow reading .debug_names. dwarf_debugnames_header() is the entry point to get .debug_names information. * dwarf_dnames.h: new structs and fields to complete getting access to .debug_names section data. * dwarf_form.c: Refactored so dwarf_dnames.c has access to getting form data. * dwarf_opaque.h: Declare new internal .debug_names access functions. * libdwarf.h.in: Declare new .debug_names functions and new error codes. * pro_section.c: Partial outline for generation of DWARF5 .debug_names added. 2017-04-02 David Anderson * dwarf.h: Corrected comment about DW_IDX_type_unit. * dwarf_alloc.c, dwarf_alloc.h: Added support for .debug_names and Dwarf_Dnames_Head. * dwarf_dnames.c,dwarf_dnames.h: Skeleton implemenatation of .debug_denames section reader. * dwarf_errmsg_list.c: Added new *DEBUG_NAMES* error codes. * libdwarf.h.in: New *DEBUG_NAMES* and new Dwarf_Dnames_Head type. * pro_opaque.h: Now defines DEBUG_NAMES * pro_section.c: Now defines _dwarf_pro_generate_debug_names, and _dwarf_pro_generate_debug_names. A skeleton implementation. 2017-04-02 David Anderson * checkexamples.c: Slight change in a comment. * libdwarf.h.in: Added commentary. * libdwarf2.1.mm: Document dwarf_init_b(), dwarf_elf_init_b() and dwarf_object_init_b(). * libdwarf2.1.pdf: Regenerate. Version 2.54 2017-04-02 David Anderson * gennames.c: Update version string. 2017-04-02 David Anderson * dwarf_init_finish.c(determine_target_group): Correct the default group number code so the if() tests work properly. 2017-03-30 David Anderson * gennames.c: Update version string. 2017-03-30 David Anderson * dwarf_arange.c: Now uses DW_DLE_ADDRESS_SIZE_ZERO to be more precise about the error found in the object. * dwarf_die_deliv.c: Adding DWARF5 cu header reading. Adding support to more fully support split dwarf. Fixed some potential leaks (in case of erroneous DWARF). New functions that add functionality where needed to deal with reading split dwarf DWARF5. * dwarf_errmsg_list.c: Clarified DW_DLE_ADDRESS_SIZE_ERROR string and added DW_DLE_IMPROPER_DWO_ID DW_DLE_GROUPNUMBER_ERROR and DW_DLE_ADDRESS_SIZE_ZERO. * dwarf_form.c,dwarf_loc.c: Fixed trailing whitespace. * dwarf_init_finish.c: Added support so split dwarf can be read properly. New function dwarf_object_init_b() is part of that support. * dwarf_opaque.c: Added de_groupnumber. Clarified some fields with commentary. * dwarf_original_elf_init.c: New functions dwarf_init_b() dwarf_elf_init_b() for groupnumber support. * dwarf_query.c: Removed trailing whitespace. * dwarf_xu_index.c: Moved static declaration so it is useful in more places in this source. * libdwarf.h.in: Added DW_GROUPNUMBER_ANY, DW_GROUPNUMBER_BASE, DW_GROUPNUMBER_DWO as part of giving better split dwarf support. Declared the new global functions mentioned just above. 2017-03-23 David Anderson * dwarf_query.c(dwarf_dietype_offset): dwarf_dietype_offset() leaked a Dwarf_Attribute. The one line fix removes the leak. 2017-03-23 David Anderson * gennames.c: Update version string. 2017-03-21 David Anderson * dwarf_form.c: Vulnerability DW201703-006 and DW201703-001 fixed. Some types of form were not checked as being in bounds. * dwarf_leb.c: Vulnerability DW201703-002 fixed. A check for out of bounds was done after the relevant dereference. Fixed. * dwarf_loc.c: Vulnerability DW201703-005 fixed. _dwarf_read_loc_expr_op() was failing to check for a bounds violation. * dwarf_query.c: Vulnerability DW201703-006. A call to _dwarf_reference_outside_section() did not pass a sufficiently careful argument list, so a bounds violation was missed. 2017-03-21 David Anderson * checkexamples.c: Updated dwarf_discr_list example with a cast to match function declaration. * libdwarf2.1.mm: Updated dwarf_discr_list example with a cast to match function declaration. * libdwarf2.1.pdf: Regenerated. Version 2.53 2017-03-04 David Anderson * dwarf_loc2.c(_dwarf_get_locdesc_c): Renamed to _dwarf_get_locdesc_op_c and corrected the handling so offsets properly dealt with and so a final empty operator is synthesized properly into an end operator like DWARF5. 2017-01-30 David Anderson * dwarf_die_deliv.c(_dwarf_make_CU_Context): Recent change in dwarf.h for DWARF5 package files required a small change here. * dwarf_xu_index.c(dwarf_get_xu_section_names): Recent change in dwarf.h for DWARF5 package files required a small change here and in dwp_secnames[]. * dwarf.h: Now matches final DWARF5. 2017-01-23 David Anderson * config.h.in.cmake,configure,configure.cmake,configure.in, CMakeLists.txt,Makefile.in: Add checks for sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h so relocations noticed for Solaris. Better diagostic about not-building archive or shared library. * configure: Regenerated * dwarf_elf_access.c: Ifdef added for sys/elf_386.h,sys/elf_amd64.h, sys/elf_SPARC.h so Solaris relocations are found. * Makefile.in 2017-01-02 David Anderson * dwarf.h: DWARF5 added new DW_UT codes compared to earlier DWARF5 drafts. dwarfutils-20200114/libdwarf/ChangeLog2018000066400000000000000000001214311361531463500200210ustar00rootroot000000000000002018-12-21 David Anderson * pdfbld.sh: Now more flexible for creating one or both pdfs. * libdwarf2.1.pdf: Regenerated rev 2.70 per yesterday's .mm changes. 2018-12-20 David Anderson * dwarf_elf_access.c,memcpy_swap.h,pro_alloc.h,pro_dnames.h: Removing trailing whitespace, trailing blank lines. 2018-12-20 David Anderson * dwarf_dnames.c,pro_dnames.h,pro_die.h: Remove some uses of Dwarf_ufixed. * pro_section.c: Remove some uses of Dwarf_ufixed and instead of 2,4,8 use DWARF_HALF_SIZE, DWARF_23BIT_SIZE or DWARF_64BIT_SIZE as appropriate. 2018-12-20 David Anderson * Makefile.am: Adding new header memcpy_swap.h to the headers list. * dwarf_gdbindex.c,dwarf_init_finish.c,dwarf_machoread.c, dwarf_object_detector.c, dwarf_peread.c: Include memcpy_swap.h. Use the new _dwarf_memcpy_noswap_bytes instead of memcpy directly. * pro_init.c: Include memcpy_swap.h. Use the new _dwarf_memcpy_noswap_bytes instead of memcpy directly. Delete local declaration now memcpy_swap.h used here. * dwarf_machoread.h,dwarf_peread.h: mo_copy_word declaration adjustment to match the new _dwarf_memcpy_noswap_bytes * dwarf_incl.h: Put before "dwarf.h" and "libdwarf.h" includes (and don't use <> on dwarf.h or libdwarf.h as they may only be locally defined) * dwarf_opaque.h: void return on de_copy_word now. Delete ugly redeclaration of _dwarf_memcpy_swap_bytes. * dwarf_util.c: Implement dwarf_get_endian_copy_function so dwarfdump can swap bytes where it needs to (as in printing frame instruction bytes). And implement _dwarf_memcpy_noswap_bytes with a void return. _dwarf_memcpy_swap_bytes now also with void return. * libdwarf.h.in: Declare the new function dwarf_get_endian_copy_function(). * pro_alloc.h: Add idempotency and ifdef __cplusplus. * pro_incl.h: Delete pointless blank lines in the macro definition area. * pro_opaque.h: delete include. No longer needed as de_copy_word no longer uses size_t. 2018-12-19 David Anderson * dwarf_elf_access.c(dwarf_get_elf): Now uses the new format per-object-type to quickly figure out if there is an Elf * open. 2018-12-19 David Anderson * dwarf_errmsg_list.h: Added DW_DLE_IMAGE_FILE_UNKNOWN_TYPE. * dwarf_error.c: Added dwarf_errmsg_by_number() so one can get more complete messages when all we have is an error number. * dwarf_object_detector.c: For PE objects the correct machine id for 64bit is 0x8664, not 0x8886. * libdwarf.h.in: Added dwarf_errmsg_by_number() and DW_DLE_IMAGE_FILE_UNKNOWN_TYPE. Fixed a couple trailing white-space instances. * pro_section.c: Removed the blank last line of the file. 2018-12-07 David Anderson * pro_die.c pro_finish.c pro_forms.c pro_line.c: Some lines were too long and one test for error (from the last set of changes) was written in a usable but non-standard way so that's now done in the standard way. 2018-12-05 David Anderson * dwarf_query.c: Removed useless blank lines. * libdwarf.h.in: Many new producer functions so the better return values of DW_DLV_OK/DW_DLV_ERROR are available for every producer call. The older functions are present and continue to work. * libdwarf2p.1.mm: Document the old (a couple got left out earlier) and new producer functions. * libdwarf2p.1.pdf: Regenerated. Version 1.48. * pro_arange.c, pro_die.c, pro_expr.c, pro_forms.c, pro_frame.c,pro_funcs.c,pro_line.c,pro_opaque.h, pro_pubnames.c,pro_reloc.c,pro_section.c,pro_types.c, pro_vars.c,pro_weaks.c: New functions provided so caller code is easier to read. The new interfaces are more type-safe than before. 2018-11-29 David Anderson * dwarf_abbrev.c: Now deals with DW_FORM_implicit_const properly. * dwarf_arange.c: Remove trailing whitespace. * dwarf_die_deliv.c: Now deals with DW_FORM_implicit_const properly. * dwarf_machoread.c,dwarf_object_detector.c, dwarf_peread.c: Remove trailing whitespace and fix indentation. * dwarf_opaque.h: Add ar_implicit_const to Dwarf_Attribute_s to deal with the implicit const FORM. * dwarf_query.c: Now deals with DW_FORM_implicit_const properly. * dwarf_util.c: Remove trailing whitespace and fix indentation. Now deals with DW_FORM_implicit_const properly. * libdwarf.h.in: Declare new function dwarf_add_AT_implicit_const(). * libdwarf_version.h: Updated version string. * pro_die.h: Add abb_implicits to Dwarf_P_Abbrev_s deal with the implicit const FORM. * pro_forms.c: Implement dwarf_add_AT_implicit_const(). * pro_opaque.h: Add Dwarf_Signed dsa_implicitvalue to Dwarf_Sort_Abbrev_s for implicit value(s). * pro_section.c: Now deals with DW_FORM_implicit_const properly. * pro_section.h: Now SECTION_TYPE defaults to 1 as the suggested section type, which is SHT_PROGBITS in Elf. See the comments there. Used to depend on a #ifdef and sometimes was defined SHT_MIPS_DWARF. * libdwarf2p.1.mm: Document the new implicit const function. * libdwarf2p.1.pdf: Regenerate. Version 1.47. 2018-11-28 David Anderson * CMakeLists.txt: The previous change failed to deal with the new pe .h files properly. Fixed. And, the SOURCES and HEADERS lists are now on shorter lines so they fit in 70 characters. 2018-11-26 David Anderson * Makefile.am: Added new files * dwarf_pe_descr.h,dwarf_peread.c,dwarf_peread.h: New files implementing reading DWARF from PE object files. * dwarf_arange.c: Notice some zero length things in .debug_aranges and ignore them. Only ever seen in a PE dll with DWARF . Odd. Needs further checking. * dwarf_die_deliv.c: Here too, check for zero length CU and just move along. Same dll. Odd. Needs further checking. * dwarf_generic_init.c: Call the pe setup code. * dwarf_init_finish.c: Delete useless blank line. * dwarf_machoread.c: Add checks to catch corrupted object files. * dwarf_opaque.h: Add _dwarf_pe_setup(). * dwarf_util.h: Some macro lines were too long. Shortened so they are easier to read/verify. * libdwarf_version.h: Updated version string. * CMakeLists.txt: Added new pe files. 2018-11-24 David Anderson * dwarf_object_detector.c: The same ASNAR bug fixed here now. * libdwarf_version.h: Updated date string. 2018-11-22 David Anderson * dwarf_machoread.c: A bug in the ASNAR macro for big-endian hosts lead to coredump reading mach-o objects (of any endianness) on such hosts. 2018-11-20 David Anderson * Makefile.am: The setup for cross-builds was incomplete for errmsg_check. Fixed. * dwarf_base_types.h: Removed a nested include of libdwarfdefs.h. * dwarf_incl.h: Moved the include of libdwarfdefs.h to here. * dwarf_errmsg_list.h: Added new (as yet unused) error messages. * dwarf_machoread.c: Added overview commentary. * dwarf_test_errmsg_list.c: Improved error messages in a few cases so errors detected are more self-explanatory. * libdwarf.h.in: Added new (as yet unused) error message defines. 2018-11-06 David Anderson * dwarf_machoread.c(_dwarf_macho_object_access_init): Following a malloc the null check referenced the wrong variable! 2018-11-05 David Anderson * dwarf_machoread.c: Added a sanity check on mo_command_count before adding it to anything. Now malloc a Dwarf_Obj_Access_Interface_s so we use a local function consistently. We were freeing on an address of a local variable... But only if a mach-o object was seriously corrupted. * dwarf_object_detector.c: We now know we misinterpreted a comment in the macho-loader header. DW_ENDIAN_SAME (and _OPPOSITE) were inappropriate. Endianness detection for PE and mach-o objects are fixed. * libdwarf.h.in,dwarf_object_detector.h: Dropping DW_ENDIAN_SAME and DW_ENDIAN_OPPOSITE as we no longer use them. * dwarf_macho_loader.h: Added commentary about the MH_MAGIC etc values. * libdwarf_version.h: Updated date string. 2018-11-01 David Anderson * libdwarf_version.h: Updated date string. * dwarf_machoread.c(dwarf_macho_load_dwarf_section_details64): Had an off-by-one error (which was already corrected in the *details32 function). If the last section was DWARF related this bug caused a DWARF section to appear unavailable. 2018-10-30 David Anderson * libdwarf_version.h: Updated date string. 2018-10-24 David Anderson * libdwarf2.1.mm: Added documentation on new functions dwarf_object_detector_fd(), dwarf_object_detector_path(), and dwarf_init_path(). Fixed indentation many places (many still to fix). * libdwarf2.1.pdf: Regenerated Reg 2.68. * dwarf_macho_loader.h: Renamed from macho-loader.h * Makefile.am: reflects name change. * dwarf_machoread.c: Uses renamed macho structs. * dwarf_machoread.h: Renames a couple macho structs. Aligns fieldnames with the similar item in libdwarf.h. * dwarf_object_detector.c: A build on 32bit machine noticed a function-prototype inconsistency in declaring dwarf_object_detector_path(). Fixed. Now allows outpath, outlen of the dwarf_object_detector_path() call to be zero, suppressing macho dSYM subdirectory checks. 2018-10-23 David Anderson * dw_elfstructs.h: Adding this for use with object readers. * dwarf_init_finish.c: Fixed placement of blank line to match standard source formatting. * macho-loader.h: Now avoids direct use of integral types. Uses macro to setup each member. * dwarf_machoread.c: New macro ASNAR handles endianness and uses the new struct member format in macho-loader.h * dwarf_object_detector.c * dwarf_reading.h: Simplified as a result of the new ASNAR macro and the structs it helps with. * libdwarf_version.h: New version string. 2018-10-20 David Anderson * dwarf_machoread.c,dwarf_machoread.h: Moved macros from the .h to the .c. * dwarf_object_detector: Removed the need to know the correct type of fields in object-defined headers. We know the lengths and layouts and that suffices because we copy everything anyway to deal with endianness. No more need to define t16 or t32 as the 'right' type. 2018-10-19 David Anderson * dwarf_version.h: Updated date string. * dwarf_errmsg_list.h: New errors DW_DLE_ELF_CLASS_BAD(420), DW_DLE_ELF_ENDIAN_BAD(421), DW_DLE_ELF_VERSION_BAD(422), DW_DLE_FILE_TOO_SMALL(423),DW_DLE_PATH_SIZE_TOO_SMALL(424), DW_DLE_BAD_TYPE_SIZE(425) for new checks for object correctness. Of more than one object type. * dwarf_generic_init.c: The new function dwarf_init_path has a new type for the call to dwarf_object_detector. * dwarf_object_detector.c: Now works in the libdwarf context. Contains checks for Elf, Mach-o and PE object files as well as recognizing archives ( such as .a). * dwarf_object_detector.h: Tweaked into final form. * dwarf_opaque.h: Added de_filesize field as we usually now know the file size for checking offsets. * libdwarf.h.in: Added the DW_DLE named above. declared dwarf_object_detector_path() and dwarf_object_detector_fd() as public functions. * pro_alloc.c: #ifdefd the include of malloc.h. 2018-10-17 David Anderson * macho-loader.h: A header for reading mach-o dsym objects. * dwarf_generic_init.c,dwarf_init_finish.c: Now modified to support reading mach-o. * dwarf_machoread.c,dwarf_machoread.h: Contains the mach-o specific details. * dwarf_object_read_common.c: New, has a * dwarf_opaque.h * dwarf_original_elf_init.c: now allows elf or mach-o objects and calls the appropriate setup code. * dwarf_reading.h: new common header for reading without libelf. * pro_section.c: Fix trailing whitespace. 2018-10-15 David Anderson * dwarf_version.h: Updated date string. * dwarf_die_deliv.c: Now a sibling-offset error returns an error of DW_DLE_SIBLING_OFFSET_WRONG. Now the code avoids adding a corrupt value to a pointer (thus properly detecting DW_DLE_SIBLING_OFFSET_WRONG). * libdwarf.h.in: Added DW_DLE_SIBLING_OFFSET_WRONG. * dwarf_errmsg_list.h: Added DW_DLE_SIBLING_OFFSET_WRONG to the errmsg strings list. 2018-10-14 David Anderson * dwarf_version.h: Updated date string. * pro_section.c: An extra 0-byte was being added in generated DWARF at the end of section as if the top level was a sibling chain, and GNU readelf noticed the wasted byte. No longer added. 2018-10-02 David Anderson * dwarf_generic_init.c,dwarf_original_elf_init.c: Fixed remaining indent issues. 2018-10-02 David Anderson * Makefile.am: Tweaks for the object detector files. * dwarf_errmsg_list.h,libdwarf.h.in: New error codes. * dwarf_generic_init.c,dwarf_original_elf_init.c: * Removed a function that just caused confusion, it was doing two jobs. Now each job called where needed. * dwarf_object_detector.c,dwarf_object_detector.h: tweeks for better error codes and trailing spaces and indent issues. * dwarf_opaque.h: Removed deleted function. 2018-10-02 David Anderson * dwarf_object_detector.h,dwarf_object_detector.c: To be used soon. 2018-09-29 David Anderson * gennames.c: Fixed an indent issue in a comment. 2018-09-28 Carlos Alberto Enciso * dwgetopt: Use size_t to remove conversion warning on Windows platform. * getnames.c: Generate '#ifdef __cplusplus/#endif' include guards to allow the inclusion of header files by C++ code. 2018-09-21 David Anderson * CMakeLists.txt: Add dwarf_generic_init.c into sources list. * Makefile.am: Ensure all cmake files get into releases. 2018-09-18 David Anderson * dwarf_generic_init.c: Moved dwarf_finish() here from dwarf_original_elf_init.c. * dwarf_original_elf.c: Moved dwarf_finish() out of this file. * dwarf_init_finish.c: Corrected a comment. frmo->from 2018-09-18 David Anderson * dwarf_generic_init.c: Moved dwarf_init() and dwarf_init_b() to this new file. From dwarf_original_elf_init.c. These functions will allow handling non-elf object DWARF in the future. * dwarf_original_elf_init.c: Functions moved to dwarf_generic_init.c and _dwarf_elf_init_file_ownership no longer static so it can be called from dwarf_generic_init.c. * Makefile.am: Add the new source file to the sources list. 2018-09-12 David Anderson * dwarf_version.h: Updated date string. * libdwarf.h.in: Corrected the use of HAVE_NONSTANDARD_PRINTF_64_FORMAT. 2018-09-11 David Anderson * libdwarf.h.in: Restored use of HAVE_NONSTANDARD_PRINTF_64_FORMAT for those needing that feature. 2018-09-02 David Anderson * Makefile.am: Changed the way to build gennames executable to the automake way, eliminating make warnings when building. * Makefile.in: regenerated. 2018-08-23 David Anderson * CMakeLists.txt: Adjusted to fit new/changed file names. 2018-08-21 David Anderson * Makefile.am: Now honors --enable-wall. * dwarf_die_deliv.c,pro_section.c: Removed unused local variables. 2018-08-14 David Anderson * libdwarf.h.in: DW_HARMLESS_ERROR_MSG_STRING_SIZE now 300, c compiler noted 200 was too small for a harmless-error sprintf string in dwarf_frame2.c (line 192). * Makefile.am. Added CPPFLAGS_FOR_BUILD where it was accidentally omitted. * libdwarf_version.h: Updated the version date string. 2018-08-09 David Anderson * Makefile.am: Added AM_TESTS_ENVIRONMENT enabling make check from any build directory. Also,add dwarf_test_errmsg_list.c to the files in a release so make check can work * runtests.sh: Handle the environment variable AM_TESTS_ENVIRONMENT sets: DWTOPSRCDIR 2018-08-07 David Anderson * libdwarf2.1.mm: Revised the argument list of dwarf_get_real_section_name() to add compression size information. * libdwarf2.1.pdf: Regenerated version 2.67. * dwarf_die_deliv.c: Added compression-size arguments to call to dwarf_get_real_section_name() and updated the string additions to match. * dwarf_init_finish.c: Update compression before/after sizes in new fields dss_compressed_length dss_uncompressed_length.. * dwarf_opaque.h: Add the new dss_ fields. * libdwarf.h.in: Revised prototype of dwarf_get_real_section_name() 2018-08-06 David Anderson * libdwarf2.1.mm: Revised the argument list of dwarf_get_real_section_name() so it works properly. * libdwarf2.1.pdf: Regenerated version 2.66. * dwarf_die_deliv.c: Added third argument to call to dwarf_get_real_section_name() and updated the string * dwarf_opaque.h: Added flag dss_ZLIB_compressed so we can report compression more accurately. 2018-08-05 David Anderson * dwarf_die_deliv.c: Was failing to report SHF_COMPRESSED in dwarfdump do to mistake here (statement with no side effect!). 2018-08-05 David Anderson * libdwarf_version.h: Updated version string. * dwarf_errmsg_list.h: Support the new error code. * dwarf_opaque.h: Fields to support dwarf_get_real_section_name(). * dwarf_die_deliv.c: Implements dwarf_get_real_section_name(). * dwarf_init_finish.c: Changes to support dwarf_get_real_section_name(). * libdwarf.h.in: Declare dwarf_get_real_section_name(). Add a new error code. * libdwarf2.1.mm: Document dwarf_get_real_section_name(). * libdwarf2.1.pdf: Regenerate. Version 2.65. 2018-08-04 David Anderson * dwarf_util.h: Remove trailing whitespace. * pro_dnames.h: Preliminary structs for writing .debug_names * pro_section.c: Corrected a comment. Removed some debug code. Fixed indent mistakes. * pro_opaque.h: Fixed indent error. * pro_init.c: Extracted Bernstein hash into its own function. Fixed indent errors. 2018-08-02 David Anderson * libdwarf_version.h: Updated version date. * pro_section.c: #if 0 or comment out some debug code. * dwarf_util.c:Replaced accidental loss of 'do'. * Makefile.am: Removed unused variables and references to them. 2018-07-31 David Anderson * Makefile.am: Move all but libdwarf*pdf out of the /usr/local/share install set, keep them all in the distribution set. 2018-07-31 David Anderson * Makefile.am: add pro_dnames.h pro_dnames.c for .debug_names support.. * dwarf_errmsg_list.h: Add DW_DLE_DUP_ATTR_ON_DIE error code. * dwarf_frame2.c: Move qsort_compare up to top of file to avoid a forward declaration. * dwarf_init_finish.c: Additional comments. * dwarf_util.c: Corrected comment. Moved local variable declarations down to where needed. * libdwarf.h.in: Declare new function dwarf_force_debug_names() used for testing. * pro_die.h: Add comment. * pro_dnames.c: Remove junk whitespace. * pro_forms.c(_dwarf_pro_add_at_to_die): Add DW_AT_data_member_location, DW_AT_trampoline to the allowed set. * pro_opaque.h: Add de_dnames_sect to Dwarf_P_Debug_s. * pro_section.c: Now sorts abbreviations by attribute number. Refactors header generation to make it easier to read the code. Refactors _dwarf_pro_getabbrev() for clarity (using newly-sorted abbreviation list). 2018-07-30 David Anderson * pro_dnames.c, pro_dnames.h: New, these just placeholders for the moment. To write out .debug_names. 2018-08-02 David Anderson * Makefile.am: Removed unused variables and references to them. 2018-07-24 David Anderson * libdwarf_version.h: Updated version string. * dwarf_line_table_reader_common.h:Removed trailing whitespace and fixed indentations. * pro_line.c: Removed trailing whitespace. * pro_reloc.c,pro_reloc.h: Defines _dwarf_pro_pre_alloc_specific_reloc_slots(). Deletes _dwarf_pro_pre_alloc_n_reloc_slots() * pro_reloc_symbolic.c: Now uses _dwarf_pro_pre_alloc_specific_reloc_slots() so static analysis can understand what the code does. Fixes Coverity CID 186978. * pro_arange.c: Now uses _dwarf_pro_pre_alloc_specific_reloc_slots instead of _dwarf_pro_pre_alloc_n_reloc_slots. 2018-07-24 David Anderson * dwarf_init_finish.c(set_up_section): A simple revision eliminates any copying and simplifies the logic. And eliminates the use of safe_strcpy(). * dwarf_util.h, dwarf_util.c: Remove safe_strcpy(). 2018-07-23 David Anderson * Makefile.am: Make it impossible for Make to build the libdwarf pdf files. We do not want users to be required to have the pdf tools. * pdfbld.sh: A script to build the libdwarf pdf files when required (the .mm files rarely change). 2018-07-23 David Anderson * libdwarf_version.h: Updated version string. * pro_line.c: Added comments on the oddness of some return values (signed vs unsigned and error returns). * dwarf_die_deliv.c: Removed a statement that had no effect (A leftover of recent changes). * gennames.c: Signed vs unsigned compare was accidental in the code this generates. Changed the local var to unsigned. 2018-07-22 David Anderson * dwarf_init_finish.c: Now calls _dwarf_safe_strcpy() so we are sure there is no string overrun. * dwarf_util.c: Implements _dwarf_safe_strcpy(). * dwarf_util.h: Declares _dwarf_safe_strcpy(). 2018-07-22 David Anderson * pro_reloc_symbolic.c(_dwarf_symbolic_relocs_to_disk): Coverity CID 186884. A much cleaner and more readable fix. 2018-07-21 David Anderson * libdwarf_version.h: Updated version string. * dwarf_init_finish.c: Coverity CID 186884. Revised the logic for clarity and added comments too. * libdwarf_version.h: Update version string. * dwarf_dnames.c: Coverity CID 186887. Encapsulating DECODE_LEB128_UWORD_CK in a function so we can catch an error and free appropriate resources. Fixed cases of error where DW_DLV_OK returned. * dwarf_abbrev.c,dwarf_arange.c,dwarf_die_deliv.c, dwarf_ranges.c,dwarf_tsearchhash.c: Removed trailing whitespace. * dwarf_xu_index.c: Coverity CID 186894. We know the string length (2) so we just assign the bytes directly avoiding any possibility of overrun. * pro_reloc_symbolic.c(_dwarf_symbolic_relocs_to_disk): Coverity CID 186978. Was dereferencing a pointer after zeroing the pointer, now fixed and the obfuscating single-call function code moved to where used, deleted function. * dwarf_macro.c: Coverity CID 186980. Removed code testing for zero count as it is impossible to get to that spot with count==0. * pro_forms.c: The new return of error is now return ((Dwarf_P_Attribute) DW_DLV_BADADDR); to at least avoid a warning about this necessary uglyness of pointer/integer confusion. The dwarf reader (consumer) interfaces have none of this. 2018-07-20 David Anderson * dwarf_line_table_reader_common.h: Encapsulating DECODE_LEB128_UWORD_CK in a function so we can catch an error and free appropriate resources. 2018-07-20 David Anderson * dwarf_frame.c: Coverity CID 186901. Removed duplicate check for dbg null. * dwarf_macro5.c: Coverity CID 186890. Was testing wrong status value. resattr -> lres 2018-07-20 David Anderson * dwarf_arange.c(dwarf_get_aranges_list): Coverity CID 186976. This function has a serious problem, it reads agranges without knowing the CU version number so anything with segment_selector != 0 could be read wrong. Unless the compiler authors did in early versions what DWARF4 called for in aranges: a segment selector value. * dwarf_elf_access.c(update_entry): Coverity CID 187700. If we do not have ELF64 symbol type available avoid letting us fall through to dereference a null pointer. * dwarf_print_lines.c(dwarf_print_lines): Coverity CID 186985. Coverity CID 186973 Remove if(){} as it is not needed. * dwarf_macro.c(dwarf_get_macro_details): Coverity CID 186980. Removed dead code for count==0 as count will be at least 1. * pro_arange.c: Coverity CID 186974. Delete redundant check for null. * pro_section.c(dwarf_pro_getabbrev): Coverity CID 186983. Avoid dereferencing forms/attrs if they are null. * pro_forms.c(dwarf_add_AT_location_expr): Coverity CID 186984. Was potentially reading more from input than could possibly exist in the fixed-maximum-length input. Coverity CID 186975. Make block_size Dwarf_Unsigned to (possibly) avoid this warning. * pro_expr.c(dwarf_add_expr_gen): Coverity CID 186987. Add break; to the last case in the switch. * pro_macinfo.c(dwarf_vendor_ext): Coverity CID 186988. Coverity CIE 186981 Deleting dead code. * pro_types.c(_dwarf_transform_simplename_to_disk)): Coverity CID 186977. Delete dead code. * pro_init.c(common_init): Coverity CID 187001. Now we avoid dereferencing a potentially NULL pointer abiname. * pro_frame.c(dwarf_add_fde_inst): Coverity CID 186979. Added missing check of 'res' variable. 2018-07-20 David Anderson * libdwarf_version.h: Updated version string. * pro_frame.c: Coverity CID 186989. Dereferenced tmpaug before NULL check. Fixed. * pro_section.c: Coverity CID 186990. copy-paste error changed val_len to val_len2. * dwarf_abbrev.c: Coverity CID 186982. dwarf_get_abbrev_count() could leak Dwarf_Error. No longer can. * dwarf_print_lines.c: Coverity CID 186973. Remove useless code. * dwarf_ranges.c: Coverity CID 186909. Ensure null not dereferenced. * dwarf_dnames.c: Coverity CID 186899. If needed !firstdab, not firstdab. Also, free local allocations on error. * dwarf_dsc.c: Coverity CID 186898. Null check on wrong variable. * dwarf_tsearchhash.c: Coverity CID 186893. Leak on error fixed. * dwarf_query.c: Coverity CID 186892. Testing res, now res3. * dwarf_macro5.c: Coverity CID 186891. Dead code moved to correct place. Coverity CID 186906. Only increment curopsonly if non-null. * dwarf_dnames.c: Coverity CID 186889. Fixed leak on error. * dwarf_die_deliv.c: Coverity CID 186888. Fixed: Removed assignment overridden later. Coverity CID 186904: deref before: null check, dataptr,dis. * dwarf_frame2.c: Coverity CID 186885. Fixed: loop inappropriate. Coverity CID 186908. Fixed test res->resf. * dwarf_line_table_reader_common.h: Coverity CID 186886. Fixed leak. 2018-07-16 David Anderson * dwarf_incl.h: Refine ifdef of HAVE_STDAFX_H. * dwarf_tsearch.h: Correcting web references in comments. * pro_incl.h: Refine ifdef of HAVE_STDAFX_H. 2018-07-16 David Anderson * Makefile.am: New, used by autotools to create configure. * configure.ac, Makefile.in, config.h.in: Deleted. 2018-07-09 David Anderson * dwarf_dnames.c: free(tmp) -> free(dab) 2018-06-19 David Anderson * configure.ac, config.h.in: Removed HAVE_NONSTANDARD_PRINTF_64_FORMAT. * configure: Regenerated. 2018-06-19 David Anderson * pro_util.h: Deleted unused sizeof_sbyte macro, simplified sizeof_ubyte to 1. 2018-06-19 David Anderson * dwarf_base_types.h,dwarf_die_deliv.c,dwarf_dnames.c, dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_init_finish.c, dwarf_loc2.h,dwarf_macro5.c,dwarf_query.c,dwarf_str_offsets.c, dwarf_util.c,pro_opaque.h: Now defining using DWARF_32BIT_SIZE DWARF_64BIT_SIZE DWARF_HALF_SIZE instead of using sizeof(Dwarf_Unsigned) or sizeof(Dwarf_Half). Making it clearer we're reading the size the standard says the items are. 2018-06-14 David Anderson * libdwarf.h.in: Simplified definitions of Dwarf_Unsigned etc and DW_PR*. 2018-06-12 David Anderson * dwarf_arange.c dwarf_base_types.h dwarf_die_deliv.c, dwarf_dnames.c,dwarf_form.c,dwarf_frame.c,dwarf_global.c, dwarf_line_table_reader_common.h,dwarf_loc.c,dwarf_macro5.c, dwarf_opaque.h,dwarf_str_offsets.c,dwarf_util.c,libdwarfdefs.h, pro_arange.c,pro_section.c,pro_types.c,pro_util.h: Now, if Dwarf_Half is not defined 16 bits it is likely that everything will still work right. We don't use sizeof(Dwarf_Half) now. 2018-06-12 David Anderson * libdwarf.h.in: Removed Dwarf_Frame_Op3 struct declaration. It was never used and was a bad idea. A functional interface is a likely replacement. 2018-05-30 David Anderson * Fix botch in revised Makefile.in. 2018-05-30 David Anderson * Makefile.in: Add gennames dependency on libdwarf_version.h * libdwarf_version.h: Create to hold the DW_VERSION_DATE_STR string. 2018-05-26 David Anderson * gennames.c: Update version string * dwarf_arange.c: Instead of load_section(dbg,.debug_info, and then *_abbrevr, call the combined _info and _abbrev function _dwarf_load_debug_info() as is done everywhere else. 2018-05-24 David Anderson * dwarf_aranges.c: Calling dwarf_get_aranges() without loading .debug_info and .debug_abbrev resulted in an error when checking for the sanity of an offset into .debug_info: DW_DLE_ARANGE_OFFSET_BAD. Now libdwarf ensures the needed sections are loaded because the 'section length' of compressed sections is only correct after such are loaded. 2018-05-17 David Anderson * config.h.in: Added #undef HAVE_VSNPRINTF HAVE_SNPRINTF * configure: regenerated. * configure.ac: Added AC_CHECK_FUNCS(snprintf) AC_CHECK_FUNCS(vsnprintf) * dwarf_alloc.c(_dwarf_free_all_of_one_debug): Added fclose of dbg->de_printf_callback_null_device_handle. * dwarf_opaque.h: Added de_printf_callback_null_device_handle Dwarf_Debug member. * dwarf_arange.c,dwarf_die_deliv.c,dwarf_frame2.c, gennames.c: Use static buffers, not on-stack char array targets for sprintf/snprintf. Testing HAVE_SNPRINTF(HAVE_VSNPRINTF) and use c99 function if present, else c90 * dwarf_util.c: Putting null_device_handle in Dwarf_Debug struct Use static buffers, not on-stack char array targets for sprintf/snprintf. Testing HAVE_SNPRINTF(HAVE_VSNPRINTF) and use c99 function if present, else c90. 2018-05-16 David Anderson * dwarf_leb.c, dwarf_util.c: Removed use of C99 like vsnprintf. Now using C90. 2018-05-15 David Anderson * dwarf_incl.h: Inserted include here. stddef.h defines really basic useful C90 things like NULL. * dwarf_opaque.h: Remove nested include stddef.h. 2018-05-15 David Anderson * dwarf_incl.h: Removed dwarf_alloc.h include * dwarf_abbrev.c,dwarf_alloc.c,dwarf_arange.c,dwarf_die_deliv.c, dwarf_dnames.c,dwarf_dsc.c,dwarf_error.c,dwarf_form.c dwarf_frame.c, dwarf_frame2.c,dwarf_gdbindex.c,dwarf_global.c,dwarf_incl.h, dwarf_init_finish.c,dwarf_line.c,dwarf_loc.c,dwarf_macro.c, dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c,dwarf_ranges.c, dwarf_str_offsets.c,dwarf_util.c,dwarf_xu_index.c: Added explicit include dwarf_alloc.h. 2018-05-15 David Anderson * Makefile.in: dwarf_frame3.c now gone from build. It should be removed. Nothing in it is used. * dwarf_incl.h: Removed dwarf_error.h include * dwarf_*: put includes in local normal order and added include dwarf_error.h as needed (in many files). 2018-05-15 David Anderson * dwarf_incl.h: Removed dwarf_util.h include * dwarf_abbrev.c,dwarf_alloc.c,dwarf_arange.c,dwarf_die_deliv.c, dwarf_dnames.c,dwarf_form.c,dwarf_frame.c,dwarf_frame2.c, dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, dwarf_loc.c,dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, dwarf_ranges.c,dwarf_str_offsets.c,dwarf_util.c,dwarf_xu_index.c, dwarf_string.c,dwarf_macro.c: Added include dwarf_util.h. 2018-05-15 David Anderson * dwarf_die_deliv.c,dwarf_dsc.c,dwarf_error.c, dwarf_init_finish.c,dwarf_original_elf_init.c, pro_error.c,pro_line.c: Removed the unnecessary inclusion of elf.h. * dwarf_incl.h: Removed the unnecessary inclusion of elf.h, limits.h, and dwarf_xu_index.h. 2018-05-15 David Anderson * dwarf_abbrev.c,dwarf_alloc.c,dwarf_die_deliv.c, dwarf_dsc.c,dwarf_dsc.h,dwarf_elf_access.c,dwarf_error.h, dwarf_gdbindex.h,dwarf_global.h,dwarf_groups.c, dwarf_harmless.c,dwarf_harmless.h,dwarf_leb.c,dwarf_loc.h, dwarf_loc2.h,dwarf_opaque.h,dwarf_print_lines.c, dwarf_ranges.c,dwarf_string.c,dwarf_tsearch.h, dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, dwarf_xu_index.h,pro_alloc.c,pro_die.h,pro_finish.c, pro_util.h: Removed trailing blank lines. Updated copyright year. 2018-05-15 David Anderson * dwarf_loc2.c, dwarf_line_table_reader_common.c, dwarf_errmsg_list.c: Renamed to end in .h, not .c, as these are all targets of #include. * dwarf_test_errmsg_list.c: New file with the test code extracted from dwarf_errmsg_list.c and #including the new dwarf_errmsg_list.h * Makefile.in: Renamings .c to .h and the errmsg checking builds the new dwarf_test_errmsg_list.c The -DTESTING in building dwarf_test_errmsg_list.c is no longer necessary. * dwarf_error.c, dwarf_line.c,dwarf_print_lines.c: Reflect the .c->h renamings 2018-05-14 David Anderson * libdwarf.h.in: Removed trailing whitespace. 2018-05-14 David Anderson * libdwarf2.1.mm: Documented dwarf_get_fde_info_for_reg3_b(). Refined some comments about frame data. * libdwarf2.1.pdf: Regenerated. Version 2.64 2018-05-14 David Anderson * gennames.c: Updated version string. 2018-05-14 David Anderson * dwarf_frame2.c: Do a thorough check of every non-zero augmentation data length in a way that will catch integer overflows. * dwarf_str_offsets.c: Fixed a botch in the original dwarf_dealloc in dwarf_close_str_offsets_table_access(). 2018-05-14 David Anderson * dwarf_frame.c: Implemented dwarf_get_fde_info_for_reg3_b(). * libdwarf.h.in: Fixed arg list for dwarf_get_fde_info_for_reg3_b. 2018-05-14 David Anderson * libdwarf.h.in: Declare new frame function, next commit will have the code in dwarf_frame.c. 2018-05-01 Carlos Alberto Enciso * gennames.c: Reversed the order of calling process_args() vs print_args(). There is no visible difference for linux/unix, and is just to match the convention now used in dwarfdump for the ordering. 2018-04-22 David Anderson * gennames.c: Updated version string. * libdwarf.h.in: Removed trailing comma from enumeration list. 2018-04-19 David Anderson * dwgetopt.c: Changed to match correction in dwarfdump version. 2018-04-17 David Anderson * dwgetopt.c: Changed to match correction in dwarfdump version. 2018-04-16 David Anderson * dwarf_str_offsets.c: Removed debug call to dump_bytes() * gennames.c: Updated version string. 2018-04-14 David Anderson * CMakeLists.txt: Added new source/header files to cmake. 2018-04-14 David Anderson * libdwarf2.1.mm: Complete doc on the new .debug_str_offsets interfaces. * Regenerated. Rev 2.63. 2018-04-13 David Anderson * gennames.c: Updated version string. * Makefile.in: Added dwarf_str_offsets.o to target list. * checkexamples.c: Added example code for the .debug_str_offsets section interfaces. * dwarf_alloc.h: Update ALLOC_AREA_INDEX_TABLE_MAX for new allocatable. * dwarf_alloc.c:Add #include and array entry for DW_DLA_STR_OFFSETS * libdwarf.h.in: * dwarf_errmsg_list.c: Added new .debug_str_offsets section reader error codes. * dwarf_str_offsets.h: New. Hidden struct for .debug_str_offsets interfaces. * dwarf_str_offsets.c: New for .debug_str_offsets. * libdwarf2.1.mm: Incomplete doc on the new interfaces. 2018-03-29 David Anderson * configure.ac: Now uses AC_COMPILE_IFELSE instead of AC_TRY_COMPILE. Substantial changes along those lines. * config.h.in, configure: Regenerated. 2018-03-28 David Anderson * configure.ac: Replaces configure.in and uses AC_COMPILE_IFELSE instead of the deprecated AC_TRY_COMPILE. * configure: Regenerated. * config.h.in: Regenerated 2018-03-27 David Anderson * configure.in: Cross compiling tested, working. * configure: regenerated. 2018-03-25 David Anderson * configure.in: Support for cross compiling * configure: regenerated. * Makefile.in: Support for cross compiling 2018-03-25 David Anderson * Makefile.in: Add comments about what is built for build system (as opposed to host or target). 2018-03-24 David Anderson * checkexamples.c: This is just example code for libdwarf2.1.mm, not part of libdwarf. Now checked by cc for errors and organized in the same order the examples appear in the .mm. * dwarf_errmsg_list.c: Added error code DW_DLE_LINE_HEADER_CORRUPT. * dwarf_line.c(_dwarf_set_line_table_regs_default_values): Add line-table header version number argument so the function works for DWARF5 (and earlier as well). Now uses dwarf_srclines_files_indexes() several places, simplifying the code. * dwarf_line.h: Adds new fields to Dwarf_Line_Context_s so that dwarf_srclines_files_indexes() logic is simple. * dwarf_line_table_reader_common.c: Passes version number to _dwarf_set_line_table_regs_default_values() so it works right for DWARF5 (and for earlier DWARF). * libdwarf.h.in: Added DW_DLE_LINE_HEADER_CORRUPT to error list. Added function dwarf_srclines_files_indexes(). * libdwarf2.1.mm: Rev 2.61. Document the new function dwarf_srclines_files_indexes() and update all examples for formatting and correct C. * libdwarf2.1.pdf: Regenerated, Rev 2.61. 2018-03-22 David Anderson * dwarf_line.c, dwarf_print_lines.c: Index file numbers for all versions of DWARF (DWARF5 indexes starting at 0). 2018-03-21 David Anderson * gennames.c: Updated version string. 2018-03-21 David Anderson * dwarf_elf_access.c: Allow for relocations on .debug_str_offsets. * dwarf_errmsg_list.c: Clarified meaning of DW_DLE_DIE_ABBREV_LIST_NULL, added new errors DW_DLE_STR_OFFSETS_BASE_WRONG_FORM, DW_DLE_DATA16_OUTSIDE_SECTION, DW_DLE_LNCT_MD5_WRONG_FORM * dwarf_form.c: Added support for DWARF5 new FORMs. * dwarf_line.c: Added dwarf_srclines_files_data_b() so clients needing DWARF5 line table support can get the DW_LNCT_MD5 value if it is present. * dwarf_line.h: Added support for the DWARF5 MD5 data. * dwarf_line_table_reader_common.c: Added DW_LNCT_MD5 support. * dwarf_opaque.h: Added _dwarf_extract_data16 so we do not have code duplication reading this data. * dwarf_print_lines.c: If MD5 present, we now print it. * dwarf_query.c: Correct handling of form for DW_AT_str_offsets_base. * dwarf_util.c: Add support for DWARF5 FORMs. * libdwarf.h.in: Define the values of the new DW_DLE codes mentioned above. Declare new function dwarf_srclines_files_data_b() * libdwarf2.1.mm: Document new function. Rev 2.61. * libdwarf2.1.pdf: Generated Rev 2.61 2018-01-05 David Anderson * dwarf_macro5.c(_dwarf_get_macro_ops_count_internal): A test duplicated the preceding loop condition so the body of the test was dead code. Removed the dead code. 2018-01-29 David Anderson * dwarf_arange.c: Improve and comment checks for stepping off the end of arange data. * dwarf_die_deliv.c: Make an error code returned a bit more specific. DW_DLA_DIE_BAD becomes DW_DLE_ABBREV_MISSING. * dwarf_errmsg_list.c: Added new error codes DW_DLE_ABBREV_MISSING DW_DLE_NO_TAG_FOR_DIE DW_DLE_LOWPC_WRONG_CLASS DW_DLE_HIGHPC_WRONG_FORM. * dwarf_form.c: Used DW_DLE_NO_TAG_FOR_DIE instead of DW_DLA_DIE_BAD to make an error return more specific. * dwarf_frame2.c: Add new checks for corrupted dwarf frame data. * dwarf_query.c: Added error check and changed DW_DLE_DIE_BAD to DW_DLE_ABBREV_MISSING in one place. Other DWARF corruption checks and error refinements added. * libdwarf.h.in: Added the defines for the new DW_DLE codes. 2018-01-29 David Anderson * gennames.c: Update version string. dwarfutils-20200114/libdwarf/LGPL.txt000066400000000000000000000635041361531463500172410ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! dwarfutils-20200114/libdwarf/LIBDWARFCOPYRIGHT000066400000000000000000000030371361531463500203430ustar00rootroot00000000000000 ====== Update January 31, 2015: The SGI postal address and oss.sgi.com address in the original copyright are no longer correct. So the final 8 lines of the original copyright have been deleted from the current copyright. ====== original copyright example. Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, Mountain View, CA 94043, or: http://www.sgi.com For further information regarding this notice, see: http://oss.sgi.com/projects/GenInfo/NoticeExplan dwarfutils-20200114/libdwarf/Makefile.am000066400000000000000000000117651361531463500200000ustar00rootroot00000000000000###Copyright (C) 2018 Vincent Torri &2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = test_dwarfstring$(EXEEXT) \ test_extra_flag_strings$(EXEEXT) test_linkedtopath$(EXEEXT) subdir = libdwarf ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/dw_compiler.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libdwarfdevdir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libdwarf_la_DEPENDENCIES = am_libdwarf_la_OBJECTS = libdwarf_la-dwarf_abbrev.lo \ libdwarf_la-dwarf_alloc.lo libdwarf_la-dwarf_arange.lo \ libdwarf_la-dwarf_debuglink.lo libdwarf_la-dwarf_die_deliv.lo \ libdwarf_la-dwarf_dnames.lo libdwarf_la-dwarf_dsc.lo \ libdwarf_la-dwarf_elf_access.lo \ libdwarf_la-dwarf_elf_load_headers.lo \ libdwarf_la-dwarf_elfread.lo \ libdwarf_la-dwarf_elf_rel_detector.lo \ libdwarf_la-dwarf_error.lo libdwarf_la-dwarf_form.lo \ libdwarf_la-dwarf_frame.lo libdwarf_la-dwarf_frame2.lo \ libdwarf_la-dwarf_funcs.lo libdwarf_la-dwarf_gdbindex.lo \ libdwarf_la-dwarf_generic_init.lo libdwarf_la-dwarf_global.lo \ libdwarf_la-dwarf_groups.lo libdwarf_la-dwarf_harmless.lo \ libdwarf_la-dwarf_init_finish.lo libdwarf_la-dwarf_leb.lo \ libdwarf_la-dwarf_line.lo libdwarf_la-dwarf_loc.lo \ libdwarf_la-dwarf_machoread.lo libdwarf_la-dwarf_macro.lo \ libdwarf_la-dwarf_macro5.lo libdwarf_la-dwarf_names.lo \ libdwarf_la-dwarf_object_detector.lo \ libdwarf_la-dwarf_object_read_common.lo \ libdwarf_la-dwarf_original_elf_init.lo \ libdwarf_la-dwarf_peread.lo libdwarf_la-dwarf_print_lines.lo \ libdwarf_la-dwarf_pubtypes.lo libdwarf_la-dwarf_query.lo \ libdwarf_la-dwarf_ranges.lo libdwarf_la-dwarf_str_offsets.lo \ libdwarf_la-dwarfstring.lo libdwarf_la-dwarf_stringsection.lo \ libdwarf_la-dwarf_tied.lo libdwarf_la-dwarf_tsearchhash.lo \ libdwarf_la-dwarf_types.lo libdwarf_la-dwarf_util.lo \ libdwarf_la-dwarf_vars.lo libdwarf_la-dwarf_weaks.lo \ libdwarf_la-dwarf_xu_index.lo libdwarf_la-malloc_check.lo \ libdwarf_la-pro_alloc.lo libdwarf_la-pro_arange.lo \ libdwarf_la-pro_die.lo libdwarf_la-pro_dnames.lo \ libdwarf_la-pro_encode_nm.lo libdwarf_la-pro_error.lo \ libdwarf_la-pro_expr.lo libdwarf_la-pro_finish.lo \ libdwarf_la-pro_forms.lo libdwarf_la-pro_frame.lo \ libdwarf_la-pro_funcs.lo libdwarf_la-pro_init.lo \ libdwarf_la-pro_line.lo \ libdwarf_la-pro_log_extra_flag_strings.lo \ libdwarf_la-pro_macinfo.lo libdwarf_la-pro_pubnames.lo \ libdwarf_la-pro_reloc.lo libdwarf_la-pro_reloc_stream.lo \ libdwarf_la-pro_reloc_symbolic.lo libdwarf_la-pro_section.lo \ libdwarf_la-pro_types.lo libdwarf_la-pro_vars.lo \ libdwarf_la-pro_weaks.lo libdwarf_la_OBJECTS = $(am_libdwarf_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libdwarf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libdwarf_la_CFLAGS) \ $(CFLAGS) $(libdwarf_la_LDFLAGS) $(LDFLAGS) -o $@ am_test_dwarfstring_OBJECTS = \ test_dwarfstring-test_dwarfstring.$(OBJEXT) \ test_dwarfstring-dwarfstring.$(OBJEXT) test_dwarfstring_OBJECTS = $(am_test_dwarfstring_OBJECTS) test_dwarfstring_LDADD = $(LDADD) test_dwarfstring_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_dwarfstring_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am_test_extra_flag_strings_OBJECTS = \ test_extra_flag_strings-test_extra_flag_strings.$(OBJEXT) \ test_extra_flag_strings-pro_log_extra_flag_strings.$(OBJEXT) \ test_extra_flag_strings-dwarfstring.$(OBJEXT) test_extra_flag_strings_OBJECTS = \ $(am_test_extra_flag_strings_OBJECTS) test_extra_flag_strings_LDADD = $(LDADD) test_extra_flag_strings_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_extra_flag_strings_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am_test_linkedtopath_OBJECTS = \ test_linkedtopath-test_linkedtopath.$(OBJEXT) \ test_linkedtopath-dwarfstring.$(OBJEXT) \ test_linkedtopath-dwarf_debuglink.$(OBJEXT) test_linkedtopath_OBJECTS = $(am_test_linkedtopath_OBJECTS) test_linkedtopath_LDADD = $(LDADD) test_linkedtopath_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_linkedtopath_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libdwarf_la_SOURCES) $(test_dwarfstring_SOURCES) \ $(test_extra_flag_strings_SOURCES) \ $(test_linkedtopath_SOURCES) DIST_SOURCES = $(libdwarf_la_SOURCES) $(test_dwarfstring_SOURCES) \ $(test_extra_flag_strings_SOURCES) \ $(test_linkedtopath_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(libdwarfdev_DATA) HEADERS = $(include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ $(top_srcdir)/test-driver COPYING ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DWARF_CFLAGS_WARN = @DWARF_CFLAGS_WARN@ DWARF_CXXFLAGS_WARN = @DWARF_CXXFLAGS_WARN@ DWARF_LIBS = @DWARF_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ dwarf_namestable = @dwarf_namestable@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ release_info = @release_info@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ struct_elf = @struct_elf@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ version_info = @version_info@ MAINTAINERCLEANFILES = Makefile.in ### libdwarf lib_LTLIBRARIES = libdwarf.la libdwarf_la_SOURCES = \ dwarf.h \ dwarf_abbrev.c \ dwarf_abbrev.h \ dwarf_alloc.c \ dwarf_alloc.h \ dwarf_arange.c \ dwarf_arange.h \ dwarf_base_types.h \ dwarf_debuglink.c \ dwarf_debuglink.h \ dwarf_die_deliv.c \ dwarf_die_deliv.h \ dwarf_dnames.c \ dwarf_dnames.h \ dwarf_dsc.c \ dwarf_dsc.h \ dwarf_elf_access.c \ dwarf_elf_access.h \ dwarf_elf_defines.h \ dwarf_elf_load_headers.c \ dwarf_elfread.c \ dwarf_elfread.h \ dwarf_elf_rel_detector.c \ dwarf_elf_rel_detector.h \ dwarf_elf_reloc_386.h \ dwarf_elf_reloc_aarch64.h \ dwarf_elf_reloc_arm.h \ dwarf_elf_reloc_mips.h \ dwarf_elf_reloc_ppc64.h \ dwarf_elf_reloc_ppc.h \ dwarf_elf_reloc_sparc.h \ dwarf_elf_reloc_x86_64.h \ dwarf_elfstructs.h \ dwarf_errmsg_list.h \ dwarf_error.c \ dwarf_error.h \ dwarf_form.c \ dwarf_frame.c \ dwarf_frame.h \ dwarf_frame2.c \ dwarf_funcs.c \ dwarf_funcs.h \ dwarf_gdbindex.c \ dwarf_gdbindex.h \ dwarf_generic_init.c \ dwarf_global.c \ dwarf_global.h \ dwarf_groups.c \ dwarf_harmless.c \ dwarf_harmless.h \ dwarf_incl.h \ dwarf_init_finish.c \ dwarf_leb.c \ dwarf_line.c \ dwarf_line.h \ dwarf_line_table_reader_common.h \ dwarf_loc.c \ dwarf_loc.h \ dwarf_loc2.h \ dwarf_macho_loader.h \ dwarf_machoread.c \ dwarf_machoread.h \ dwarf_macro.c \ dwarf_macro.h \ dwarf_macro5.c \ dwarf_macro5.h \ dwarf_names.c \ dwarf_names.h \ dwarf_object_detector.c \ dwarf_object_detector.h \ dwarf_object_read_common.c \ dwarf_object_read_common.h \ dwarf_opaque.h \ dwarf_original_elf_init.c \ dwarf_pe_descr.h \ dwarf_peread.c \ dwarf_peread.h \ dwarf_print_lines.c \ dwarf_pubtypes.c \ dwarf_query.c \ dwarf_ranges.c \ dwarf_reading.h \ dwarf_reloc_386.h \ dwarf_reloc_arm.h \ dwarf_reloc_mips.h \ dwarf_reloc_ppc.h \ dwarf_reloc_ppc64.h \ dwarf_reloc_x86_64.h \ dwarf_str_offsets.c \ dwarf_str_offsets.h \ dwarfstring.c \ dwarfstring.h \ dwarf_stringsection.c \ dwarf_tied.c \ dwarf_tied_decls.h \ dwarf_tsearchhash.c \ dwarf_tsearch.h \ dwarf_types.c \ dwarf_types.h \ dwarf_util.c \ dwarf_util.h \ dwarf_vars.c \ dwarf_vars.h \ dwarf_weaks.c \ dwarf_weaks.h \ dwarf_xu_index.c \ dwarf_xu_index.h \ libdwarf.h \ libdwarf_version.h \ libdwarfdefs.h \ malloc_check.c \ malloc_check.h \ memcpy_swap.h \ pro_alloc.c \ pro_alloc.h \ pro_arange.c \ pro_arange.h \ pro_die.c \ pro_die.h \ pro_dnames.h \ pro_dnames.c \ pro_encode_nm.c \ pro_encode_nm.h \ pro_error.c \ pro_error.h \ pro_expr.c \ pro_expr.h \ pro_finish.c \ pro_forms.c \ pro_frame.c \ pro_frame.h \ pro_funcs.c \ pro_incl.h \ pro_init.c \ pro_line.c \ pro_line.h \ pro_log_extra_flag_strings.c \ pro_macinfo.c \ pro_macinfo.h \ pro_opaque.h \ pro_pubnames.c \ pro_reloc.c \ pro_reloc.h \ pro_reloc_stream.c \ pro_reloc_stream.h \ pro_reloc_symbolic.c \ pro_reloc_symbolic.h \ pro_section.c \ pro_section.h \ pro_types.c \ pro_types.h \ pro_util.h \ pro_vars.c \ pro_weaks.c libdwarf_la_CFLAGS = $(DWARF_CFLAGS_WARN) libdwarf_la_LIBADD = @DWARF_LIBS@ libdwarf_la_LDFLAGS = -fPIC -no-undefined -version-info @version_info@ @release_info@ TESTS = $(check_PROGRAMS) $(check_TESTS) AM_TESTS_ENVIRONMENT = DWTOPSRCDIR='$(top_srcdir)'; export DWTOPSRCDIR; include_HEADERS = $(top_srcdir)/libdwarf/dwarf.h libdwarf.h libdwarfdevdir = $(datadir)/libdwarf/libdwarf-devel libdwarfdev_DATA = \ libdwarf2.1.pdf \ libdwarf2p.1.pdf test_dwarfstring_SOURCES = test_dwarfstring.c \ dwarfstring.h dwarfstring.c test_dwarfstring_CFLAGS = $(CFLAGS_WARN) test_dwarfstring_CPPFLAGS = \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src test_extra_flag_strings_SOURCES = test_extra_flag_strings.c \ pro_log_extra_flag_strings.c \ dwarfstring.h dwarfstring.c test_extra_flag_strings_CFLAGS = $(CFLAGS_WARN) test_extra_flag_strings_CPPFLAGS = -DTESTING \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src test_linkedtopath_SOURCES = test_linkedtopath.c \ dwarfstring.h dwarfstring.c \ dwarf_debuglink.h dwarf_debuglink.c \ dwarf_error.h test_linkedtopath_CFLAGS = $(RO_CFLAGS_WARN) -DTESTING test_linkedtopath_CPPFLAGS = -DTESTING \ -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src check_TESTS = testdebuglink.sh EXTRA_DIST = \ COPYING \ LGPL.txt \ LIBDWARFCOPYRIGHT \ CHANGES \ ChangeLog \ ChangeLog2006 \ ChangeLog2007 \ ChangeLog2008 \ ChangeLog2009 \ ChangeLog2010 \ ChangeLog2011 \ ChangeLog2012 \ ChangeLog2013 \ ChangeLog2014 \ ChangeLog2015 \ ChangeLog2016 \ ChangeLog2017 \ ChangeLog2018 \ CODINGSTYLE \ baseline.ltp \ dwarf_leb_test.c \ dwarf_tied_test.c \ dwarf_names_new.h \ dwarf_names_enum.h \ gennames.c \ dwarf_test_errmsg_list.c \ libdwarf2.1.mm \ libdwarf2p.1.mm \ mips_extensions.mm \ mips_extensions.pdf \ dwgetopt.h \ dwgetopt.c \ CMakeLists.txt \ libdwarf.h.in \ testdebuglink.sh \ generated_libdwarf.h.in \ pdfbld.sh \ NEWS \ README \ CODINGSTYLE \ $(libdwarf_DATA) \ $(libdwarfdev_DATA) CLEANFILES = all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libdwarf/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu libdwarf/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libdwarf.la: $(libdwarf_la_OBJECTS) $(libdwarf_la_DEPENDENCIES) $(EXTRA_libdwarf_la_DEPENDENCIES) $(AM_V_CCLD)$(libdwarf_la_LINK) -rpath $(libdir) $(libdwarf_la_OBJECTS) $(libdwarf_la_LIBADD) $(LIBS) clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list test_dwarfstring$(EXEEXT): $(test_dwarfstring_OBJECTS) $(test_dwarfstring_DEPENDENCIES) $(EXTRA_test_dwarfstring_DEPENDENCIES) @rm -f test_dwarfstring$(EXEEXT) $(AM_V_CCLD)$(test_dwarfstring_LINK) $(test_dwarfstring_OBJECTS) $(test_dwarfstring_LDADD) $(LIBS) test_extra_flag_strings$(EXEEXT): $(test_extra_flag_strings_OBJECTS) $(test_extra_flag_strings_DEPENDENCIES) $(EXTRA_test_extra_flag_strings_DEPENDENCIES) @rm -f test_extra_flag_strings$(EXEEXT) $(AM_V_CCLD)$(test_extra_flag_strings_LINK) $(test_extra_flag_strings_OBJECTS) $(test_extra_flag_strings_LDADD) $(LIBS) test_linkedtopath$(EXEEXT): $(test_linkedtopath_OBJECTS) $(test_linkedtopath_DEPENDENCIES) $(EXTRA_test_linkedtopath_DEPENDENCIES) @rm -f test_linkedtopath$(EXEEXT) $(AM_V_CCLD)$(test_linkedtopath_LINK) $(test_linkedtopath_OBJECTS) $(test_linkedtopath_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_alloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_arange.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_dnames.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_dsc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_elfread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_form.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_frame.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_frame2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_funcs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_global.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_groups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_harmless.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_leb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_line.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_loc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_machoread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_macro.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_macro5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_names.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_peread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_query.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_ranges.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_tied.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_vars.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_weaks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-dwarfstring.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-malloc_check.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_alloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_arange.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_die.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_dnames.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_encode_nm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_expr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_finish.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_forms.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_frame.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_funcs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_line.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_macinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_pubnames.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_reloc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_section.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_types.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_vars.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwarf_la-pro_weaks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dwarfstring-dwarfstring.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dwarfstring-test_dwarfstring.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_extra_flag_strings-dwarfstring.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_linkedtopath-dwarfstring.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_linkedtopath-test_linkedtopath.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< libdwarf_la-dwarf_abbrev.lo: dwarf_abbrev.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_abbrev.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_abbrev.Tpo -c -o libdwarf_la-dwarf_abbrev.lo `test -f 'dwarf_abbrev.c' || echo '$(srcdir)/'`dwarf_abbrev.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_abbrev.Tpo $(DEPDIR)/libdwarf_la-dwarf_abbrev.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_abbrev.c' object='libdwarf_la-dwarf_abbrev.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_abbrev.lo `test -f 'dwarf_abbrev.c' || echo '$(srcdir)/'`dwarf_abbrev.c libdwarf_la-dwarf_alloc.lo: dwarf_alloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_alloc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_alloc.Tpo -c -o libdwarf_la-dwarf_alloc.lo `test -f 'dwarf_alloc.c' || echo '$(srcdir)/'`dwarf_alloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_alloc.Tpo $(DEPDIR)/libdwarf_la-dwarf_alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_alloc.c' object='libdwarf_la-dwarf_alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_alloc.lo `test -f 'dwarf_alloc.c' || echo '$(srcdir)/'`dwarf_alloc.c libdwarf_la-dwarf_arange.lo: dwarf_arange.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_arange.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_arange.Tpo -c -o libdwarf_la-dwarf_arange.lo `test -f 'dwarf_arange.c' || echo '$(srcdir)/'`dwarf_arange.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_arange.Tpo $(DEPDIR)/libdwarf_la-dwarf_arange.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_arange.c' object='libdwarf_la-dwarf_arange.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_arange.lo `test -f 'dwarf_arange.c' || echo '$(srcdir)/'`dwarf_arange.c libdwarf_la-dwarf_debuglink.lo: dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_debuglink.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_debuglink.Tpo -c -o libdwarf_la-dwarf_debuglink.lo `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_debuglink.Tpo $(DEPDIR)/libdwarf_la-dwarf_debuglink.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debuglink.c' object='libdwarf_la-dwarf_debuglink.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_debuglink.lo `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c libdwarf_la-dwarf_die_deliv.lo: dwarf_die_deliv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_die_deliv.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_die_deliv.Tpo -c -o libdwarf_la-dwarf_die_deliv.lo `test -f 'dwarf_die_deliv.c' || echo '$(srcdir)/'`dwarf_die_deliv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_die_deliv.Tpo $(DEPDIR)/libdwarf_la-dwarf_die_deliv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_die_deliv.c' object='libdwarf_la-dwarf_die_deliv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_die_deliv.lo `test -f 'dwarf_die_deliv.c' || echo '$(srcdir)/'`dwarf_die_deliv.c libdwarf_la-dwarf_dnames.lo: dwarf_dnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_dnames.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_dnames.Tpo -c -o libdwarf_la-dwarf_dnames.lo `test -f 'dwarf_dnames.c' || echo '$(srcdir)/'`dwarf_dnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_dnames.Tpo $(DEPDIR)/libdwarf_la-dwarf_dnames.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_dnames.c' object='libdwarf_la-dwarf_dnames.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_dnames.lo `test -f 'dwarf_dnames.c' || echo '$(srcdir)/'`dwarf_dnames.c libdwarf_la-dwarf_dsc.lo: dwarf_dsc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_dsc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_dsc.Tpo -c -o libdwarf_la-dwarf_dsc.lo `test -f 'dwarf_dsc.c' || echo '$(srcdir)/'`dwarf_dsc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_dsc.Tpo $(DEPDIR)/libdwarf_la-dwarf_dsc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_dsc.c' object='libdwarf_la-dwarf_dsc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_dsc.lo `test -f 'dwarf_dsc.c' || echo '$(srcdir)/'`dwarf_dsc.c libdwarf_la-dwarf_elf_access.lo: dwarf_elf_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elf_access.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elf_access.Tpo -c -o libdwarf_la-dwarf_elf_access.lo `test -f 'dwarf_elf_access.c' || echo '$(srcdir)/'`dwarf_elf_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elf_access.Tpo $(DEPDIR)/libdwarf_la-dwarf_elf_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elf_access.c' object='libdwarf_la-dwarf_elf_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elf_access.lo `test -f 'dwarf_elf_access.c' || echo '$(srcdir)/'`dwarf_elf_access.c libdwarf_la-dwarf_elf_load_headers.lo: dwarf_elf_load_headers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elf_load_headers.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Tpo -c -o libdwarf_la-dwarf_elf_load_headers.lo `test -f 'dwarf_elf_load_headers.c' || echo '$(srcdir)/'`dwarf_elf_load_headers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Tpo $(DEPDIR)/libdwarf_la-dwarf_elf_load_headers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elf_load_headers.c' object='libdwarf_la-dwarf_elf_load_headers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elf_load_headers.lo `test -f 'dwarf_elf_load_headers.c' || echo '$(srcdir)/'`dwarf_elf_load_headers.c libdwarf_la-dwarf_elfread.lo: dwarf_elfread.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elfread.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elfread.Tpo -c -o libdwarf_la-dwarf_elfread.lo `test -f 'dwarf_elfread.c' || echo '$(srcdir)/'`dwarf_elfread.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elfread.Tpo $(DEPDIR)/libdwarf_la-dwarf_elfread.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elfread.c' object='libdwarf_la-dwarf_elfread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elfread.lo `test -f 'dwarf_elfread.c' || echo '$(srcdir)/'`dwarf_elfread.c libdwarf_la-dwarf_elf_rel_detector.lo: dwarf_elf_rel_detector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_elf_rel_detector.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Tpo -c -o libdwarf_la-dwarf_elf_rel_detector.lo `test -f 'dwarf_elf_rel_detector.c' || echo '$(srcdir)/'`dwarf_elf_rel_detector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Tpo $(DEPDIR)/libdwarf_la-dwarf_elf_rel_detector.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_elf_rel_detector.c' object='libdwarf_la-dwarf_elf_rel_detector.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_elf_rel_detector.lo `test -f 'dwarf_elf_rel_detector.c' || echo '$(srcdir)/'`dwarf_elf_rel_detector.c libdwarf_la-dwarf_error.lo: dwarf_error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_error.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_error.Tpo -c -o libdwarf_la-dwarf_error.lo `test -f 'dwarf_error.c' || echo '$(srcdir)/'`dwarf_error.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_error.Tpo $(DEPDIR)/libdwarf_la-dwarf_error.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_error.c' object='libdwarf_la-dwarf_error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_error.lo `test -f 'dwarf_error.c' || echo '$(srcdir)/'`dwarf_error.c libdwarf_la-dwarf_form.lo: dwarf_form.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_form.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_form.Tpo -c -o libdwarf_la-dwarf_form.lo `test -f 'dwarf_form.c' || echo '$(srcdir)/'`dwarf_form.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_form.Tpo $(DEPDIR)/libdwarf_la-dwarf_form.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_form.c' object='libdwarf_la-dwarf_form.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_form.lo `test -f 'dwarf_form.c' || echo '$(srcdir)/'`dwarf_form.c libdwarf_la-dwarf_frame.lo: dwarf_frame.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_frame.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_frame.Tpo -c -o libdwarf_la-dwarf_frame.lo `test -f 'dwarf_frame.c' || echo '$(srcdir)/'`dwarf_frame.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_frame.Tpo $(DEPDIR)/libdwarf_la-dwarf_frame.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_frame.c' object='libdwarf_la-dwarf_frame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_frame.lo `test -f 'dwarf_frame.c' || echo '$(srcdir)/'`dwarf_frame.c libdwarf_la-dwarf_frame2.lo: dwarf_frame2.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_frame2.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_frame2.Tpo -c -o libdwarf_la-dwarf_frame2.lo `test -f 'dwarf_frame2.c' || echo '$(srcdir)/'`dwarf_frame2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_frame2.Tpo $(DEPDIR)/libdwarf_la-dwarf_frame2.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_frame2.c' object='libdwarf_la-dwarf_frame2.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_frame2.lo `test -f 'dwarf_frame2.c' || echo '$(srcdir)/'`dwarf_frame2.c libdwarf_la-dwarf_funcs.lo: dwarf_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_funcs.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_funcs.Tpo -c -o libdwarf_la-dwarf_funcs.lo `test -f 'dwarf_funcs.c' || echo '$(srcdir)/'`dwarf_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_funcs.Tpo $(DEPDIR)/libdwarf_la-dwarf_funcs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_funcs.c' object='libdwarf_la-dwarf_funcs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_funcs.lo `test -f 'dwarf_funcs.c' || echo '$(srcdir)/'`dwarf_funcs.c libdwarf_la-dwarf_gdbindex.lo: dwarf_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_gdbindex.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_gdbindex.Tpo -c -o libdwarf_la-dwarf_gdbindex.lo `test -f 'dwarf_gdbindex.c' || echo '$(srcdir)/'`dwarf_gdbindex.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_gdbindex.Tpo $(DEPDIR)/libdwarf_la-dwarf_gdbindex.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_gdbindex.c' object='libdwarf_la-dwarf_gdbindex.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_gdbindex.lo `test -f 'dwarf_gdbindex.c' || echo '$(srcdir)/'`dwarf_gdbindex.c libdwarf_la-dwarf_generic_init.lo: dwarf_generic_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_generic_init.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_generic_init.Tpo -c -o libdwarf_la-dwarf_generic_init.lo `test -f 'dwarf_generic_init.c' || echo '$(srcdir)/'`dwarf_generic_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_generic_init.Tpo $(DEPDIR)/libdwarf_la-dwarf_generic_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_generic_init.c' object='libdwarf_la-dwarf_generic_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_generic_init.lo `test -f 'dwarf_generic_init.c' || echo '$(srcdir)/'`dwarf_generic_init.c libdwarf_la-dwarf_global.lo: dwarf_global.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_global.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_global.Tpo -c -o libdwarf_la-dwarf_global.lo `test -f 'dwarf_global.c' || echo '$(srcdir)/'`dwarf_global.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_global.Tpo $(DEPDIR)/libdwarf_la-dwarf_global.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_global.c' object='libdwarf_la-dwarf_global.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_global.lo `test -f 'dwarf_global.c' || echo '$(srcdir)/'`dwarf_global.c libdwarf_la-dwarf_groups.lo: dwarf_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_groups.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_groups.Tpo -c -o libdwarf_la-dwarf_groups.lo `test -f 'dwarf_groups.c' || echo '$(srcdir)/'`dwarf_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_groups.Tpo $(DEPDIR)/libdwarf_la-dwarf_groups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_groups.c' object='libdwarf_la-dwarf_groups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_groups.lo `test -f 'dwarf_groups.c' || echo '$(srcdir)/'`dwarf_groups.c libdwarf_la-dwarf_harmless.lo: dwarf_harmless.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_harmless.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_harmless.Tpo -c -o libdwarf_la-dwarf_harmless.lo `test -f 'dwarf_harmless.c' || echo '$(srcdir)/'`dwarf_harmless.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_harmless.Tpo $(DEPDIR)/libdwarf_la-dwarf_harmless.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_harmless.c' object='libdwarf_la-dwarf_harmless.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_harmless.lo `test -f 'dwarf_harmless.c' || echo '$(srcdir)/'`dwarf_harmless.c libdwarf_la-dwarf_init_finish.lo: dwarf_init_finish.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_init_finish.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_init_finish.Tpo -c -o libdwarf_la-dwarf_init_finish.lo `test -f 'dwarf_init_finish.c' || echo '$(srcdir)/'`dwarf_init_finish.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_init_finish.Tpo $(DEPDIR)/libdwarf_la-dwarf_init_finish.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_init_finish.c' object='libdwarf_la-dwarf_init_finish.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_init_finish.lo `test -f 'dwarf_init_finish.c' || echo '$(srcdir)/'`dwarf_init_finish.c libdwarf_la-dwarf_leb.lo: dwarf_leb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_leb.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_leb.Tpo -c -o libdwarf_la-dwarf_leb.lo `test -f 'dwarf_leb.c' || echo '$(srcdir)/'`dwarf_leb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_leb.Tpo $(DEPDIR)/libdwarf_la-dwarf_leb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_leb.c' object='libdwarf_la-dwarf_leb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_leb.lo `test -f 'dwarf_leb.c' || echo '$(srcdir)/'`dwarf_leb.c libdwarf_la-dwarf_line.lo: dwarf_line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_line.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_line.Tpo -c -o libdwarf_la-dwarf_line.lo `test -f 'dwarf_line.c' || echo '$(srcdir)/'`dwarf_line.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_line.Tpo $(DEPDIR)/libdwarf_la-dwarf_line.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_line.c' object='libdwarf_la-dwarf_line.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_line.lo `test -f 'dwarf_line.c' || echo '$(srcdir)/'`dwarf_line.c libdwarf_la-dwarf_loc.lo: dwarf_loc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_loc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_loc.Tpo -c -o libdwarf_la-dwarf_loc.lo `test -f 'dwarf_loc.c' || echo '$(srcdir)/'`dwarf_loc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_loc.Tpo $(DEPDIR)/libdwarf_la-dwarf_loc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_loc.c' object='libdwarf_la-dwarf_loc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_loc.lo `test -f 'dwarf_loc.c' || echo '$(srcdir)/'`dwarf_loc.c libdwarf_la-dwarf_machoread.lo: dwarf_machoread.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_machoread.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_machoread.Tpo -c -o libdwarf_la-dwarf_machoread.lo `test -f 'dwarf_machoread.c' || echo '$(srcdir)/'`dwarf_machoread.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_machoread.Tpo $(DEPDIR)/libdwarf_la-dwarf_machoread.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_machoread.c' object='libdwarf_la-dwarf_machoread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_machoread.lo `test -f 'dwarf_machoread.c' || echo '$(srcdir)/'`dwarf_machoread.c libdwarf_la-dwarf_macro.lo: dwarf_macro.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_macro.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_macro.Tpo -c -o libdwarf_la-dwarf_macro.lo `test -f 'dwarf_macro.c' || echo '$(srcdir)/'`dwarf_macro.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_macro.Tpo $(DEPDIR)/libdwarf_la-dwarf_macro.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_macro.c' object='libdwarf_la-dwarf_macro.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_macro.lo `test -f 'dwarf_macro.c' || echo '$(srcdir)/'`dwarf_macro.c libdwarf_la-dwarf_macro5.lo: dwarf_macro5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_macro5.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_macro5.Tpo -c -o libdwarf_la-dwarf_macro5.lo `test -f 'dwarf_macro5.c' || echo '$(srcdir)/'`dwarf_macro5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_macro5.Tpo $(DEPDIR)/libdwarf_la-dwarf_macro5.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_macro5.c' object='libdwarf_la-dwarf_macro5.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_macro5.lo `test -f 'dwarf_macro5.c' || echo '$(srcdir)/'`dwarf_macro5.c libdwarf_la-dwarf_names.lo: dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_names.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_names.Tpo -c -o libdwarf_la-dwarf_names.lo `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_names.Tpo $(DEPDIR)/libdwarf_la-dwarf_names.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_names.c' object='libdwarf_la-dwarf_names.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_names.lo `test -f 'dwarf_names.c' || echo '$(srcdir)/'`dwarf_names.c libdwarf_la-dwarf_object_detector.lo: dwarf_object_detector.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_object_detector.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_object_detector.Tpo -c -o libdwarf_la-dwarf_object_detector.lo `test -f 'dwarf_object_detector.c' || echo '$(srcdir)/'`dwarf_object_detector.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_object_detector.Tpo $(DEPDIR)/libdwarf_la-dwarf_object_detector.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_object_detector.c' object='libdwarf_la-dwarf_object_detector.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_object_detector.lo `test -f 'dwarf_object_detector.c' || echo '$(srcdir)/'`dwarf_object_detector.c libdwarf_la-dwarf_object_read_common.lo: dwarf_object_read_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_object_read_common.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_object_read_common.Tpo -c -o libdwarf_la-dwarf_object_read_common.lo `test -f 'dwarf_object_read_common.c' || echo '$(srcdir)/'`dwarf_object_read_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_object_read_common.Tpo $(DEPDIR)/libdwarf_la-dwarf_object_read_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_object_read_common.c' object='libdwarf_la-dwarf_object_read_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_object_read_common.lo `test -f 'dwarf_object_read_common.c' || echo '$(srcdir)/'`dwarf_object_read_common.c libdwarf_la-dwarf_original_elf_init.lo: dwarf_original_elf_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_original_elf_init.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Tpo -c -o libdwarf_la-dwarf_original_elf_init.lo `test -f 'dwarf_original_elf_init.c' || echo '$(srcdir)/'`dwarf_original_elf_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Tpo $(DEPDIR)/libdwarf_la-dwarf_original_elf_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_original_elf_init.c' object='libdwarf_la-dwarf_original_elf_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_original_elf_init.lo `test -f 'dwarf_original_elf_init.c' || echo '$(srcdir)/'`dwarf_original_elf_init.c libdwarf_la-dwarf_peread.lo: dwarf_peread.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_peread.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_peread.Tpo -c -o libdwarf_la-dwarf_peread.lo `test -f 'dwarf_peread.c' || echo '$(srcdir)/'`dwarf_peread.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_peread.Tpo $(DEPDIR)/libdwarf_la-dwarf_peread.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_peread.c' object='libdwarf_la-dwarf_peread.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_peread.lo `test -f 'dwarf_peread.c' || echo '$(srcdir)/'`dwarf_peread.c libdwarf_la-dwarf_print_lines.lo: dwarf_print_lines.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_print_lines.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_print_lines.Tpo -c -o libdwarf_la-dwarf_print_lines.lo `test -f 'dwarf_print_lines.c' || echo '$(srcdir)/'`dwarf_print_lines.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_print_lines.Tpo $(DEPDIR)/libdwarf_la-dwarf_print_lines.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_print_lines.c' object='libdwarf_la-dwarf_print_lines.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_print_lines.lo `test -f 'dwarf_print_lines.c' || echo '$(srcdir)/'`dwarf_print_lines.c libdwarf_la-dwarf_pubtypes.lo: dwarf_pubtypes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_pubtypes.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_pubtypes.Tpo -c -o libdwarf_la-dwarf_pubtypes.lo `test -f 'dwarf_pubtypes.c' || echo '$(srcdir)/'`dwarf_pubtypes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_pubtypes.Tpo $(DEPDIR)/libdwarf_la-dwarf_pubtypes.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_pubtypes.c' object='libdwarf_la-dwarf_pubtypes.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_pubtypes.lo `test -f 'dwarf_pubtypes.c' || echo '$(srcdir)/'`dwarf_pubtypes.c libdwarf_la-dwarf_query.lo: dwarf_query.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_query.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_query.Tpo -c -o libdwarf_la-dwarf_query.lo `test -f 'dwarf_query.c' || echo '$(srcdir)/'`dwarf_query.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_query.Tpo $(DEPDIR)/libdwarf_la-dwarf_query.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_query.c' object='libdwarf_la-dwarf_query.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_query.lo `test -f 'dwarf_query.c' || echo '$(srcdir)/'`dwarf_query.c libdwarf_la-dwarf_ranges.lo: dwarf_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_ranges.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_ranges.Tpo -c -o libdwarf_la-dwarf_ranges.lo `test -f 'dwarf_ranges.c' || echo '$(srcdir)/'`dwarf_ranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_ranges.Tpo $(DEPDIR)/libdwarf_la-dwarf_ranges.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_ranges.c' object='libdwarf_la-dwarf_ranges.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_ranges.lo `test -f 'dwarf_ranges.c' || echo '$(srcdir)/'`dwarf_ranges.c libdwarf_la-dwarf_str_offsets.lo: dwarf_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_str_offsets.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_str_offsets.Tpo -c -o libdwarf_la-dwarf_str_offsets.lo `test -f 'dwarf_str_offsets.c' || echo '$(srcdir)/'`dwarf_str_offsets.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_str_offsets.Tpo $(DEPDIR)/libdwarf_la-dwarf_str_offsets.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_str_offsets.c' object='libdwarf_la-dwarf_str_offsets.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_str_offsets.lo `test -f 'dwarf_str_offsets.c' || echo '$(srcdir)/'`dwarf_str_offsets.c libdwarf_la-dwarfstring.lo: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarfstring.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarfstring.Tpo -c -o libdwarf_la-dwarfstring.lo `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarfstring.Tpo $(DEPDIR)/libdwarf_la-dwarfstring.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='libdwarf_la-dwarfstring.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarfstring.lo `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c libdwarf_la-dwarf_stringsection.lo: dwarf_stringsection.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_stringsection.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_stringsection.Tpo -c -o libdwarf_la-dwarf_stringsection.lo `test -f 'dwarf_stringsection.c' || echo '$(srcdir)/'`dwarf_stringsection.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_stringsection.Tpo $(DEPDIR)/libdwarf_la-dwarf_stringsection.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_stringsection.c' object='libdwarf_la-dwarf_stringsection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_stringsection.lo `test -f 'dwarf_stringsection.c' || echo '$(srcdir)/'`dwarf_stringsection.c libdwarf_la-dwarf_tied.lo: dwarf_tied.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_tied.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_tied.Tpo -c -o libdwarf_la-dwarf_tied.lo `test -f 'dwarf_tied.c' || echo '$(srcdir)/'`dwarf_tied.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_tied.Tpo $(DEPDIR)/libdwarf_la-dwarf_tied.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tied.c' object='libdwarf_la-dwarf_tied.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_tied.lo `test -f 'dwarf_tied.c' || echo '$(srcdir)/'`dwarf_tied.c libdwarf_la-dwarf_tsearchhash.lo: dwarf_tsearchhash.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_tsearchhash.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Tpo -c -o libdwarf_la-dwarf_tsearchhash.lo `test -f 'dwarf_tsearchhash.c' || echo '$(srcdir)/'`dwarf_tsearchhash.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Tpo $(DEPDIR)/libdwarf_la-dwarf_tsearchhash.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_tsearchhash.c' object='libdwarf_la-dwarf_tsearchhash.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_tsearchhash.lo `test -f 'dwarf_tsearchhash.c' || echo '$(srcdir)/'`dwarf_tsearchhash.c libdwarf_la-dwarf_types.lo: dwarf_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_types.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_types.Tpo -c -o libdwarf_la-dwarf_types.lo `test -f 'dwarf_types.c' || echo '$(srcdir)/'`dwarf_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_types.Tpo $(DEPDIR)/libdwarf_la-dwarf_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_types.c' object='libdwarf_la-dwarf_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_types.lo `test -f 'dwarf_types.c' || echo '$(srcdir)/'`dwarf_types.c libdwarf_la-dwarf_util.lo: dwarf_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_util.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_util.Tpo -c -o libdwarf_la-dwarf_util.lo `test -f 'dwarf_util.c' || echo '$(srcdir)/'`dwarf_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_util.Tpo $(DEPDIR)/libdwarf_la-dwarf_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_util.c' object='libdwarf_la-dwarf_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_util.lo `test -f 'dwarf_util.c' || echo '$(srcdir)/'`dwarf_util.c libdwarf_la-dwarf_vars.lo: dwarf_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_vars.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_vars.Tpo -c -o libdwarf_la-dwarf_vars.lo `test -f 'dwarf_vars.c' || echo '$(srcdir)/'`dwarf_vars.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_vars.Tpo $(DEPDIR)/libdwarf_la-dwarf_vars.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_vars.c' object='libdwarf_la-dwarf_vars.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_vars.lo `test -f 'dwarf_vars.c' || echo '$(srcdir)/'`dwarf_vars.c libdwarf_la-dwarf_weaks.lo: dwarf_weaks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_weaks.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_weaks.Tpo -c -o libdwarf_la-dwarf_weaks.lo `test -f 'dwarf_weaks.c' || echo '$(srcdir)/'`dwarf_weaks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_weaks.Tpo $(DEPDIR)/libdwarf_la-dwarf_weaks.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_weaks.c' object='libdwarf_la-dwarf_weaks.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_weaks.lo `test -f 'dwarf_weaks.c' || echo '$(srcdir)/'`dwarf_weaks.c libdwarf_la-dwarf_xu_index.lo: dwarf_xu_index.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-dwarf_xu_index.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-dwarf_xu_index.Tpo -c -o libdwarf_la-dwarf_xu_index.lo `test -f 'dwarf_xu_index.c' || echo '$(srcdir)/'`dwarf_xu_index.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-dwarf_xu_index.Tpo $(DEPDIR)/libdwarf_la-dwarf_xu_index.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_xu_index.c' object='libdwarf_la-dwarf_xu_index.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-dwarf_xu_index.lo `test -f 'dwarf_xu_index.c' || echo '$(srcdir)/'`dwarf_xu_index.c libdwarf_la-malloc_check.lo: malloc_check.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-malloc_check.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-malloc_check.Tpo -c -o libdwarf_la-malloc_check.lo `test -f 'malloc_check.c' || echo '$(srcdir)/'`malloc_check.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-malloc_check.Tpo $(DEPDIR)/libdwarf_la-malloc_check.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='malloc_check.c' object='libdwarf_la-malloc_check.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-malloc_check.lo `test -f 'malloc_check.c' || echo '$(srcdir)/'`malloc_check.c libdwarf_la-pro_alloc.lo: pro_alloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_alloc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_alloc.Tpo -c -o libdwarf_la-pro_alloc.lo `test -f 'pro_alloc.c' || echo '$(srcdir)/'`pro_alloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_alloc.Tpo $(DEPDIR)/libdwarf_la-pro_alloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_alloc.c' object='libdwarf_la-pro_alloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_alloc.lo `test -f 'pro_alloc.c' || echo '$(srcdir)/'`pro_alloc.c libdwarf_la-pro_arange.lo: pro_arange.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_arange.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_arange.Tpo -c -o libdwarf_la-pro_arange.lo `test -f 'pro_arange.c' || echo '$(srcdir)/'`pro_arange.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_arange.Tpo $(DEPDIR)/libdwarf_la-pro_arange.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_arange.c' object='libdwarf_la-pro_arange.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_arange.lo `test -f 'pro_arange.c' || echo '$(srcdir)/'`pro_arange.c libdwarf_la-pro_die.lo: pro_die.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_die.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_die.Tpo -c -o libdwarf_la-pro_die.lo `test -f 'pro_die.c' || echo '$(srcdir)/'`pro_die.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_die.Tpo $(DEPDIR)/libdwarf_la-pro_die.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_die.c' object='libdwarf_la-pro_die.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_die.lo `test -f 'pro_die.c' || echo '$(srcdir)/'`pro_die.c libdwarf_la-pro_dnames.lo: pro_dnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_dnames.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_dnames.Tpo -c -o libdwarf_la-pro_dnames.lo `test -f 'pro_dnames.c' || echo '$(srcdir)/'`pro_dnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_dnames.Tpo $(DEPDIR)/libdwarf_la-pro_dnames.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_dnames.c' object='libdwarf_la-pro_dnames.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_dnames.lo `test -f 'pro_dnames.c' || echo '$(srcdir)/'`pro_dnames.c libdwarf_la-pro_encode_nm.lo: pro_encode_nm.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_encode_nm.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_encode_nm.Tpo -c -o libdwarf_la-pro_encode_nm.lo `test -f 'pro_encode_nm.c' || echo '$(srcdir)/'`pro_encode_nm.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_encode_nm.Tpo $(DEPDIR)/libdwarf_la-pro_encode_nm.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_encode_nm.c' object='libdwarf_la-pro_encode_nm.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_encode_nm.lo `test -f 'pro_encode_nm.c' || echo '$(srcdir)/'`pro_encode_nm.c libdwarf_la-pro_error.lo: pro_error.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_error.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_error.Tpo -c -o libdwarf_la-pro_error.lo `test -f 'pro_error.c' || echo '$(srcdir)/'`pro_error.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_error.Tpo $(DEPDIR)/libdwarf_la-pro_error.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_error.c' object='libdwarf_la-pro_error.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_error.lo `test -f 'pro_error.c' || echo '$(srcdir)/'`pro_error.c libdwarf_la-pro_expr.lo: pro_expr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_expr.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_expr.Tpo -c -o libdwarf_la-pro_expr.lo `test -f 'pro_expr.c' || echo '$(srcdir)/'`pro_expr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_expr.Tpo $(DEPDIR)/libdwarf_la-pro_expr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_expr.c' object='libdwarf_la-pro_expr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_expr.lo `test -f 'pro_expr.c' || echo '$(srcdir)/'`pro_expr.c libdwarf_la-pro_finish.lo: pro_finish.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_finish.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_finish.Tpo -c -o libdwarf_la-pro_finish.lo `test -f 'pro_finish.c' || echo '$(srcdir)/'`pro_finish.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_finish.Tpo $(DEPDIR)/libdwarf_la-pro_finish.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_finish.c' object='libdwarf_la-pro_finish.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_finish.lo `test -f 'pro_finish.c' || echo '$(srcdir)/'`pro_finish.c libdwarf_la-pro_forms.lo: pro_forms.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_forms.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_forms.Tpo -c -o libdwarf_la-pro_forms.lo `test -f 'pro_forms.c' || echo '$(srcdir)/'`pro_forms.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_forms.Tpo $(DEPDIR)/libdwarf_la-pro_forms.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_forms.c' object='libdwarf_la-pro_forms.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_forms.lo `test -f 'pro_forms.c' || echo '$(srcdir)/'`pro_forms.c libdwarf_la-pro_frame.lo: pro_frame.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_frame.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_frame.Tpo -c -o libdwarf_la-pro_frame.lo `test -f 'pro_frame.c' || echo '$(srcdir)/'`pro_frame.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_frame.Tpo $(DEPDIR)/libdwarf_la-pro_frame.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_frame.c' object='libdwarf_la-pro_frame.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_frame.lo `test -f 'pro_frame.c' || echo '$(srcdir)/'`pro_frame.c libdwarf_la-pro_funcs.lo: pro_funcs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_funcs.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_funcs.Tpo -c -o libdwarf_la-pro_funcs.lo `test -f 'pro_funcs.c' || echo '$(srcdir)/'`pro_funcs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_funcs.Tpo $(DEPDIR)/libdwarf_la-pro_funcs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_funcs.c' object='libdwarf_la-pro_funcs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_funcs.lo `test -f 'pro_funcs.c' || echo '$(srcdir)/'`pro_funcs.c libdwarf_la-pro_init.lo: pro_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_init.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_init.Tpo -c -o libdwarf_la-pro_init.lo `test -f 'pro_init.c' || echo '$(srcdir)/'`pro_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_init.Tpo $(DEPDIR)/libdwarf_la-pro_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_init.c' object='libdwarf_la-pro_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_init.lo `test -f 'pro_init.c' || echo '$(srcdir)/'`pro_init.c libdwarf_la-pro_line.lo: pro_line.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_line.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_line.Tpo -c -o libdwarf_la-pro_line.lo `test -f 'pro_line.c' || echo '$(srcdir)/'`pro_line.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_line.Tpo $(DEPDIR)/libdwarf_la-pro_line.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_line.c' object='libdwarf_la-pro_line.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_line.lo `test -f 'pro_line.c' || echo '$(srcdir)/'`pro_line.c libdwarf_la-pro_log_extra_flag_strings.lo: pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_log_extra_flag_strings.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Tpo -c -o libdwarf_la-pro_log_extra_flag_strings.lo `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Tpo $(DEPDIR)/libdwarf_la-pro_log_extra_flag_strings.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_log_extra_flag_strings.c' object='libdwarf_la-pro_log_extra_flag_strings.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_log_extra_flag_strings.lo `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c libdwarf_la-pro_macinfo.lo: pro_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_macinfo.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_macinfo.Tpo -c -o libdwarf_la-pro_macinfo.lo `test -f 'pro_macinfo.c' || echo '$(srcdir)/'`pro_macinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_macinfo.Tpo $(DEPDIR)/libdwarf_la-pro_macinfo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_macinfo.c' object='libdwarf_la-pro_macinfo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_macinfo.lo `test -f 'pro_macinfo.c' || echo '$(srcdir)/'`pro_macinfo.c libdwarf_la-pro_pubnames.lo: pro_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_pubnames.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_pubnames.Tpo -c -o libdwarf_la-pro_pubnames.lo `test -f 'pro_pubnames.c' || echo '$(srcdir)/'`pro_pubnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_pubnames.Tpo $(DEPDIR)/libdwarf_la-pro_pubnames.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_pubnames.c' object='libdwarf_la-pro_pubnames.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_pubnames.lo `test -f 'pro_pubnames.c' || echo '$(srcdir)/'`pro_pubnames.c libdwarf_la-pro_reloc.lo: pro_reloc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_reloc.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_reloc.Tpo -c -o libdwarf_la-pro_reloc.lo `test -f 'pro_reloc.c' || echo '$(srcdir)/'`pro_reloc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_reloc.Tpo $(DEPDIR)/libdwarf_la-pro_reloc.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_reloc.c' object='libdwarf_la-pro_reloc.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_reloc.lo `test -f 'pro_reloc.c' || echo '$(srcdir)/'`pro_reloc.c libdwarf_la-pro_reloc_stream.lo: pro_reloc_stream.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_reloc_stream.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_reloc_stream.Tpo -c -o libdwarf_la-pro_reloc_stream.lo `test -f 'pro_reloc_stream.c' || echo '$(srcdir)/'`pro_reloc_stream.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_reloc_stream.Tpo $(DEPDIR)/libdwarf_la-pro_reloc_stream.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_reloc_stream.c' object='libdwarf_la-pro_reloc_stream.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_reloc_stream.lo `test -f 'pro_reloc_stream.c' || echo '$(srcdir)/'`pro_reloc_stream.c libdwarf_la-pro_reloc_symbolic.lo: pro_reloc_symbolic.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_reloc_symbolic.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Tpo -c -o libdwarf_la-pro_reloc_symbolic.lo `test -f 'pro_reloc_symbolic.c' || echo '$(srcdir)/'`pro_reloc_symbolic.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Tpo $(DEPDIR)/libdwarf_la-pro_reloc_symbolic.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_reloc_symbolic.c' object='libdwarf_la-pro_reloc_symbolic.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_reloc_symbolic.lo `test -f 'pro_reloc_symbolic.c' || echo '$(srcdir)/'`pro_reloc_symbolic.c libdwarf_la-pro_section.lo: pro_section.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_section.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_section.Tpo -c -o libdwarf_la-pro_section.lo `test -f 'pro_section.c' || echo '$(srcdir)/'`pro_section.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_section.Tpo $(DEPDIR)/libdwarf_la-pro_section.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_section.c' object='libdwarf_la-pro_section.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_section.lo `test -f 'pro_section.c' || echo '$(srcdir)/'`pro_section.c libdwarf_la-pro_types.lo: pro_types.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_types.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_types.Tpo -c -o libdwarf_la-pro_types.lo `test -f 'pro_types.c' || echo '$(srcdir)/'`pro_types.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_types.Tpo $(DEPDIR)/libdwarf_la-pro_types.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_types.c' object='libdwarf_la-pro_types.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_types.lo `test -f 'pro_types.c' || echo '$(srcdir)/'`pro_types.c libdwarf_la-pro_vars.lo: pro_vars.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_vars.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_vars.Tpo -c -o libdwarf_la-pro_vars.lo `test -f 'pro_vars.c' || echo '$(srcdir)/'`pro_vars.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_vars.Tpo $(DEPDIR)/libdwarf_la-pro_vars.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_vars.c' object='libdwarf_la-pro_vars.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_vars.lo `test -f 'pro_vars.c' || echo '$(srcdir)/'`pro_vars.c libdwarf_la-pro_weaks.lo: pro_weaks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -MT libdwarf_la-pro_weaks.lo -MD -MP -MF $(DEPDIR)/libdwarf_la-pro_weaks.Tpo -c -o libdwarf_la-pro_weaks.lo `test -f 'pro_weaks.c' || echo '$(srcdir)/'`pro_weaks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdwarf_la-pro_weaks.Tpo $(DEPDIR)/libdwarf_la-pro_weaks.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_weaks.c' object='libdwarf_la-pro_weaks.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdwarf_la_CFLAGS) $(CFLAGS) -c -o libdwarf_la-pro_weaks.lo `test -f 'pro_weaks.c' || echo '$(srcdir)/'`pro_weaks.c test_dwarfstring-test_dwarfstring.o: test_dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-test_dwarfstring.o -MD -MP -MF $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo -c -o test_dwarfstring-test_dwarfstring.o `test -f 'test_dwarfstring.c' || echo '$(srcdir)/'`test_dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-test_dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_dwarfstring.c' object='test_dwarfstring-test_dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-test_dwarfstring.o `test -f 'test_dwarfstring.c' || echo '$(srcdir)/'`test_dwarfstring.c test_dwarfstring-test_dwarfstring.obj: test_dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-test_dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo -c -o test_dwarfstring-test_dwarfstring.obj `if test -f 'test_dwarfstring.c'; then $(CYGPATH_W) 'test_dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/test_dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-test_dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-test_dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_dwarfstring.c' object='test_dwarfstring-test_dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-test_dwarfstring.obj `if test -f 'test_dwarfstring.c'; then $(CYGPATH_W) 'test_dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/test_dwarfstring.c'; fi` test_dwarfstring-dwarfstring.o: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-dwarfstring.o -MD -MP -MF $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo -c -o test_dwarfstring-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_dwarfstring-dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c test_dwarfstring-dwarfstring.obj: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -MT test_dwarfstring-dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo -c -o test_dwarfstring-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_dwarfstring-dwarfstring.Tpo $(DEPDIR)/test_dwarfstring-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_dwarfstring-dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dwarfstring_CPPFLAGS) $(CPPFLAGS) $(test_dwarfstring_CFLAGS) $(CFLAGS) -c -o test_dwarfstring-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` test_extra_flag_strings-test_extra_flag_strings.o: test_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-test_extra_flag_strings.o -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo -c -o test_extra_flag_strings-test_extra_flag_strings.o `test -f 'test_extra_flag_strings.c' || echo '$(srcdir)/'`test_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_extra_flag_strings.c' object='test_extra_flag_strings-test_extra_flag_strings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-test_extra_flag_strings.o `test -f 'test_extra_flag_strings.c' || echo '$(srcdir)/'`test_extra_flag_strings.c test_extra_flag_strings-test_extra_flag_strings.obj: test_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-test_extra_flag_strings.obj -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo -c -o test_extra_flag_strings-test_extra_flag_strings.obj `if test -f 'test_extra_flag_strings.c'; then $(CYGPATH_W) 'test_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/test_extra_flag_strings.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-test_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_extra_flag_strings.c' object='test_extra_flag_strings-test_extra_flag_strings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-test_extra_flag_strings.obj `if test -f 'test_extra_flag_strings.c'; then $(CYGPATH_W) 'test_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/test_extra_flag_strings.c'; fi` test_extra_flag_strings-pro_log_extra_flag_strings.o: pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-pro_log_extra_flag_strings.o -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo -c -o test_extra_flag_strings-pro_log_extra_flag_strings.o `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_log_extra_flag_strings.c' object='test_extra_flag_strings-pro_log_extra_flag_strings.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-pro_log_extra_flag_strings.o `test -f 'pro_log_extra_flag_strings.c' || echo '$(srcdir)/'`pro_log_extra_flag_strings.c test_extra_flag_strings-pro_log_extra_flag_strings.obj: pro_log_extra_flag_strings.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-pro_log_extra_flag_strings.obj -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo -c -o test_extra_flag_strings-pro_log_extra_flag_strings.obj `if test -f 'pro_log_extra_flag_strings.c'; then $(CYGPATH_W) 'pro_log_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/pro_log_extra_flag_strings.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Tpo $(DEPDIR)/test_extra_flag_strings-pro_log_extra_flag_strings.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pro_log_extra_flag_strings.c' object='test_extra_flag_strings-pro_log_extra_flag_strings.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-pro_log_extra_flag_strings.obj `if test -f 'pro_log_extra_flag_strings.c'; then $(CYGPATH_W) 'pro_log_extra_flag_strings.c'; else $(CYGPATH_W) '$(srcdir)/pro_log_extra_flag_strings.c'; fi` test_extra_flag_strings-dwarfstring.o: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-dwarfstring.o -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo -c -o test_extra_flag_strings-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo $(DEPDIR)/test_extra_flag_strings-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_extra_flag_strings-dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c test_extra_flag_strings-dwarfstring.obj: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -MT test_extra_flag_strings-dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo -c -o test_extra_flag_strings-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_extra_flag_strings-dwarfstring.Tpo $(DEPDIR)/test_extra_flag_strings-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_extra_flag_strings-dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_extra_flag_strings_CPPFLAGS) $(CPPFLAGS) $(test_extra_flag_strings_CFLAGS) $(CFLAGS) -c -o test_extra_flag_strings-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` test_linkedtopath-test_linkedtopath.o: test_linkedtopath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-test_linkedtopath.o -MD -MP -MF $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo -c -o test_linkedtopath-test_linkedtopath.o `test -f 'test_linkedtopath.c' || echo '$(srcdir)/'`test_linkedtopath.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo $(DEPDIR)/test_linkedtopath-test_linkedtopath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_linkedtopath.c' object='test_linkedtopath-test_linkedtopath.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-test_linkedtopath.o `test -f 'test_linkedtopath.c' || echo '$(srcdir)/'`test_linkedtopath.c test_linkedtopath-test_linkedtopath.obj: test_linkedtopath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-test_linkedtopath.obj -MD -MP -MF $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo -c -o test_linkedtopath-test_linkedtopath.obj `if test -f 'test_linkedtopath.c'; then $(CYGPATH_W) 'test_linkedtopath.c'; else $(CYGPATH_W) '$(srcdir)/test_linkedtopath.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-test_linkedtopath.Tpo $(DEPDIR)/test_linkedtopath-test_linkedtopath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_linkedtopath.c' object='test_linkedtopath-test_linkedtopath.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-test_linkedtopath.obj `if test -f 'test_linkedtopath.c'; then $(CYGPATH_W) 'test_linkedtopath.c'; else $(CYGPATH_W) '$(srcdir)/test_linkedtopath.c'; fi` test_linkedtopath-dwarfstring.o: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarfstring.o -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo -c -o test_linkedtopath-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo $(DEPDIR)/test_linkedtopath-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_linkedtopath-dwarfstring.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarfstring.o `test -f 'dwarfstring.c' || echo '$(srcdir)/'`dwarfstring.c test_linkedtopath-dwarfstring.obj: dwarfstring.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarfstring.obj -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo -c -o test_linkedtopath-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarfstring.Tpo $(DEPDIR)/test_linkedtopath-dwarfstring.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarfstring.c' object='test_linkedtopath-dwarfstring.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarfstring.obj `if test -f 'dwarfstring.c'; then $(CYGPATH_W) 'dwarfstring.c'; else $(CYGPATH_W) '$(srcdir)/dwarfstring.c'; fi` test_linkedtopath-dwarf_debuglink.o: dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarf_debuglink.o -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo -c -o test_linkedtopath-dwarf_debuglink.o `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debuglink.c' object='test_linkedtopath-dwarf_debuglink.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarf_debuglink.o `test -f 'dwarf_debuglink.c' || echo '$(srcdir)/'`dwarf_debuglink.c test_linkedtopath-dwarf_debuglink.obj: dwarf_debuglink.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -MT test_linkedtopath-dwarf_debuglink.obj -MD -MP -MF $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo -c -o test_linkedtopath-dwarf_debuglink.obj `if test -f 'dwarf_debuglink.c'; then $(CYGPATH_W) 'dwarf_debuglink.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_debuglink.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Tpo $(DEPDIR)/test_linkedtopath-dwarf_debuglink.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dwarf_debuglink.c' object='test_linkedtopath-dwarf_debuglink.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_linkedtopath_CPPFLAGS) $(CPPFLAGS) $(test_linkedtopath_CFLAGS) $(CFLAGS) -c -o test_linkedtopath-dwarf_debuglink.obj `if test -f 'dwarf_debuglink.c'; then $(CYGPATH_W) 'dwarf_debuglink.c'; else $(CYGPATH_W) '$(srcdir)/dwarf_debuglink.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-libdwarfdevDATA: $(libdwarfdev_DATA) @$(NORMAL_INSTALL) @list='$(libdwarfdev_DATA)'; test -n "$(libdwarfdevdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libdwarfdevdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdwarfdevdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(libdwarfdevdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(libdwarfdevdir)" || exit $$?; \ done uninstall-libdwarfdevDATA: @$(NORMAL_UNINSTALL) @list='$(libdwarfdev_DATA)'; test -n "$(libdwarfdevdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libdwarfdevdir)'; $(am__uninstall_files_from_dir) install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? test_dwarfstring.log: test_dwarfstring$(EXEEXT) @p='test_dwarfstring$(EXEEXT)'; \ b='test_dwarfstring'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_extra_flag_strings.log: test_extra_flag_strings$(EXEEXT) @p='test_extra_flag_strings$(EXEEXT)'; \ b='test_extra_flag_strings'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_linkedtopath.log: test_linkedtopath$(EXEEXT) @p='test_linkedtopath$(EXEEXT)'; \ b='test_linkedtopath'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) testdebuglink.sh.log: testdebuglink.sh @p='testdebuglink.sh'; \ b='testdebuglink.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libdwarfdevdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-includeHEADERS install-libdwarfdevDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-libdwarfdevDATA .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-includeHEADERS install-info \ install-info-am install-libLTLIBRARIES install-libdwarfdevDATA \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-includeHEADERS \ uninstall-libLTLIBRARIES uninstall-libdwarfdevDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: dwarfutils-20200114/libdwarf/NEWS000066400000000000000000000642631361531463500164440ustar00rootroot00000000000000November 26, 2019 The dwarf_init*() functions no longer use libelf so calling dwarf_get_elf() cannot succeed unless dwarf_elf_init() or dwarf_elf_init_b() was used to open a Dwarf_Debug on an object file. This change actually happened around 5 May 2019 but was not documented properly till 26 November. January 15, 2019 All references to C data types spelled *int16* *int32* or *int64* have been removed. Dwarf_Unsigned is used instead. This simplifies builds in certain environments. December 05, 2018 Many new producer functions provided. Now no matter what producer task is to be done there is a version that returns DW_DLV_OK/DW_DLV_ERROR and no ugly casting of return values is needed to check for success/failure. All the old interfaces continue to work. One can switch from Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die die, char* name, Dwarf_Error* error); (requires a cast to check return code DW_DLV_BADADDR) to int dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie, char* current_working_directory, Dwarf_P_Attribute * outattr, Dwarf_Error* error); (no cast,type safe) for example. The libdwarf2p.1.mm document table-of-contents lists only the latest functions, but all the documentation of all the earlier versions remain in the document as subsections. October 24, 2018 Now supports reading MacOS dSYM object files. May 17, 2017 Now supports some COMDAT groups as well as split-dwarf. Some new functions added so consumer code can know what the sections and groups contain. Some compilers emit groups findable only with relocation data: libdwarf does not understand those groups. April 02, 2017 The consumer code now reads DWARF5 split-dwarf sections. The functions dwarf_init_b() and dwarf_elf_init_b() and dwarf_object_init_b() have a groupnumber argument added. For non-split-dwarf objects the original dwarf_init() and dwarf_elf_init() and dwarf_object_init() functions continue to work properly. September 11, 2016 The producer code is getting a new batch of functions. For each existing producer call returning a value other than DW_DLV_OK/DW_DLV_ERROR/DW_DLV_NO_ENTRY a new function returning one of those three codes with a pointer argument added to return the actual desired value (that used to be the 'return'). The existing calls require the caller to do ugly casting to determine whether the call did its work or got an error. The new calls have type-safe interfaces that separate the desired result from the error-indication. So producer calls look more like consumer calls. The existing historical producer interfaces will remain unchanged and will continue to be supported. The existing interfaces will simply call the new interfaces so there is no code duplication: Old and new use the same implementation. Source and binary compatibility is retained, but users of the producer code can, when they wish, partially or fully convert to the new interfaces. This work will be ongoing and gradual, not 'all at once'. August 27, 2016 Now the producer is capable of producing .debug_str strings. Strings are never duplicated in .debug_str. See dwarf_pro_set_default_string_form() in libdwarf2p.1.pdf May 23, 2016 When building a shared-library the soname is set in the dynamic section "libdwarf.so.1". Much more testing of object correctness is done to catch corrupted dwarf and corrupted object files. March 14, 2016 When libdwarf callers provide neither an error argument nor an error-handler function pointer libdwarf gives up on detecting an error. Before now it emitted a short message on stderr and did abort(). Now it emits a short message on stdout and does abort(). Having libdwarf just stop application processing (stopping the entire application) was never good application-development policy, so one hopes no one ever relied on doing no-error-handling themselves. So one hopes no one will actually notice this change. The change makes it much easier to test that the error handling is all behaving as intended. March 1, 2016 Much support of GNU extensions to dwarf and of DWARF5 features now exist in libdwarf. Including the ability to deal with the most usual forms of split-dwarf. Handling of zlib compression of dwarf is now automatic (assuming you had zlib visible when configuring libdwarf). May 01, 2015 dwarf_next_cu_header_d() is the latest extension for CU reading. Earlier versions still supported. dwarf_die_from_hash_signature() added so readers can use a hash to access a dwp package file DIE. New support for some of DWARF5 and for dwp debug-fission package file reading. February 25, 2015 Now gennames uses dwgetopt() instead of getopt. So it will more easily build where no getopt() available. We copied dwgetopt.h, .c here (rather than reaching around to dwarfdump) to keep the libdwarf build more easily buildable separate from dwarfdump. January 8, 2015 When malloc fails (out of space) dwarfdump will now use a statically-allocated Dwarf_Error_s struct so it can get the original malloc failure (or other error) reported back to the calling client. Some checks for invalid Elf files were changed to actually report errors properly. Thanks to Edward Williamson for providing test cases with odd errors in the Elf and DWARF. May 19, 2014 REASON FOR RELEASE Now handles DebugFission (part of the unreleased standard named DWARF5) in which debug information can be split from objects and gathered into seperate object files. MINOR POINT: Added a caveat that dwarf_errmsg() returned string pointers are not necessarily pointers that can be relied on to be valid for the duration of the current executable. It's best for consumers to print or copy the string right away and then forget the returned pointer. This restriction is probably already met by most conservative consumer code: earlier, nothing was said about the lifetime of the string! Eventually it would be nice to actually have more ephemeral strings as then some much better error strings could easily be produced with no leakage and no growth in the size of the running executable. For now, though, all dwarf_errmsg() strings continue to point to static strings. Just please don't depend on it! BINARY & SOURCE INCOMPATIBLITY: The Producer code drops old dwarf_producer_init* functions and provides an old name with a new interface: dwarf_producer_init(). The producer callback function is renamed Dwarf_Callback_Func. Hence code calling the libdwarf producer must change. Code calling the consumer interface is not affected. The determination of what/how to emit DWARF is now determined at run time, not at build time. It's now much simpler to get the sort of output you want. Provision is made for emitting DWARF3,4,5 and 5 (though that provision is at a very early stage and not much supported yet). The postal addresses for SGI in the copyright comments changed from time to time and are no longer accurate. So they are gradually being removed. March 17, 2014 The dwarf.v2.mm and index.v2.mm and their pdf files have been removed from the distribution. Those files are available on dwarfstd.org and they are 20 years old, so removed from libdwarf. January 29, 2014 Now using dwarf_tsearch() instead of the original complicated allocation code. October 14, 2013 The Callback_Func declarations in libdwarf.h were missing a const on the name argument. Adding it removes compiler warnings. But removing it means client code calling producer functions has to change to get their callback function declarations/definitions to match. The change does not affect those calling the consumer interfaces. August 15, 2013 Now the printf (stdout) here go through a callback function instead of actually using stdout. That way dwarfdump and other apps have full control of libdwarf output from dwarf_print_lines() for example. It also means callers of dwarf_print_lines() need to have called dwarf_register_printf_callback() to get any actual print output. January 26, 2013 Retracted the incompatible change. The interfaces are again compatible with previous releases and the January 25 release is withdrawn. Has all the fixes of Jan 25 present in the code. January 25, 2013 The definition of the Dwarf_Loc struct could not handle DW_OP_GNU_const_type so it had to change. The new field added makes this version of libdwarf incompatible with any existing dwarfdump. Rebuild dwarfdump and dwarfdump2 to use it with this libdwarf. Moved firmly into C89/C90 usage by more complete use of const and be using int x(void) for example to prototype parameter-less functions. Compiles close to cleanly with gcc options -Wsystem-headers -Wall -Wsign-compare -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign November 29, 2012 The function dwarf_formflag() now returns the actual flag value instead of just 1 or 0. It has been coded wrong a very long time. The DWARF documents (DWARF2 on) have always made it clear any non-zero value means true and zero means false. Now consumers can properly note the value the compiler actually put into the flag byte. November 17, 2012 New headers contain the relocation codes for various object ABIs. These headers are needed in libdwarf and expected by builds of dwarfdump[2] for best dwarfdump[2] relocation handling. It is best to build libdwarf and dwarfdump together for best handling of relocatable objects. GNU compilers may generate the operator DW_OP_GNU_implicit_pointer which is generated differently in DWARF2 versus DWARF3/4. Hence a new interface to libdwarf dwarf_loclist_from_expr_b() adds the compilation unit DWARF version number to the argument list (as compared to dwarf_loclist_from_expr_a()). Hopefully few consumers will need to change to use the new interface. December 13, 2011 dwarf_lineoff() is now deprecated, dwarf_lineoff_b() is strongly recommended instead. dwarf_add_line_entry() does not have all the line fields needed for generating DWARF3/4, use dwarf_add_line_entry_b() instead. Generation of DWARF3/4 is not yet functional, this new function is a first step. October 29, 2011 Added support for reading .debug_types (type unit) data. October 26,2011 Revised the Makefile.in and README to make building libdwarf easier to accomplish with unusual locations of libelf headers or other headers or libraries. June 04,2011 Non-Elf objects could be used with libdwarf, but no one has contributed non-elf-reading code for libdwarf and a crucial detail was not documented so those writing such object-reading code have not done it entirely correctly. Fundamentally such code must treat a section index of 0 as a real but empty section with no name (an empty name). dwarf_elf_access.c and dwarf_elf_init_finish.c have some comments on this point now. March 29,2011 All the code changed a lot because indentations were all over the map, now they are consistent. Additions were made to DWARF4 support. Now we use dicheck (a new open source application) to check indentation. Library users will not see any change, all interfaces remain as before. January 12,2010 A libdwarf user has noticed that the April 4, 2009 consumer function changes introduced a problem: the default CFA column was DW_FRAME_CFA_COL even when a newer DWARF3 consumer frame interface like dwarf_get_fde_info_for_all_regs3() is used. The libdwarf2.1.pdf documentation stated the default should be DW_FRAME_CFA_COL3 in that case. The introduction of a caller-specified frame-column function (dwarf_set_frame_cfa_value()) in that April 4, 2009 release was flawed in that it failed to match the documentation. Now the default frame column is DW_FRAME_CFA_COL3 unless the configure option --enable-oldframecol is used at libdwarf build time. If you are using libdwarf old frame consumer interfaces dwarf_get_fde_info_for_reg(), dwarf_get_fde_info_for_cfa_reg(), and dwarf_get_fde_info_for_all_regs() and want unchanged operation then please configure libdwarf with --enable-oldframecol . or add the call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL) after calling a libdwarf initialization function. It is impossible to configure a single libdwarf.a so that it transparently defaults to both DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3. A call such as dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL3) or dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL) (or some other name/value of your choosing) following the dwarf_init() call gives your application full control of the frame cfa column independent of the libdwarf configure option. See the libdwarf2.1.pdf documentation for details. We strongly recommend that you use dwarf_set_frame_cfa_value() to avoid a configure-time dependency. July 7, 2009 Implemented support for elf 'rela' relocations so libdwarf and dwarfdump can read *nix .o files with such relocations reasonably, at least for some machines (see dwarf_elf_access.c for EM_ in 'case' statements.) This changes the binary access for non-Elf object users (folks who have coded there own non-Elf access routines do reference internals of dwarf_opaque.h), but the new data can be left zero and the rest of the code should work fine. dwarf_opaque.h gathers section data in Dwarf_Section_s structs which simplifies the code in dwarf_init_finish.c and clarifies what fields are section related. July 4, 2009 When something erroneous is detected in a die information about the CU context may be of interest. So we added dwarf_CU_dieoffset_given_die(), a function which allows clients to find the relevant CU die for any die. The consumer can use normal attribute access functions to print information about that CU die (and the erroneous die, of course). See the libdwarf consumer document for more information. April 27, 2009 Interface additions: dwarf_loclist_from_expr_a() and dwarf_get_ranges_a() are new interfaces like dwarf_loclist_from_expr() and dwarf_get_ranges() respectively, but with arguments allowing full support for different CIEs in an executable having different address-sizes (and their compilation unit DIEs if .debug_info is present). dwarf_get_loclist_entry() does not support differing address sizes per CIE/CU. April 4, 2009 Added new functions dwarf_set_frame_cfa_value() dwarf_set_frame_same_value(), and dwarf_set_frame_undefined_value(). These are essential for ABIs where the real register numbers exceed 1033 (such as ppc). Failing to use these leads to frame instructions DW_CFA_undefined and DW_CFA_same_value emitting values that cannot be interpreted correctly by a libdwarf consumer. See dwarfdump for examples of use. Feb 14, 2009 Added configure option --enable-nonstandardprintf which makes it easy to get printf of Dwarf_Unsigned (etc) types correct even for non-standard compilers. Dec 30, 2008 Added interfaces for getting and printing the .debug_ranges data. Dec 8, 2008 Record the abbreviation 'code' (index) in each DIE. Making it possible for a pretty-printer to print the abbreviation code. Sep 30, 2008 Phil Mucci provided an a.out test chase which demonstrates a bug in 64bit DWARF2 output by gcc. Now libdwarf works around this and with -v -v -v -v prints a warning. Sep 29, 2008 Thanks to Phil Mucci for providing a little-endian 64bit test object file that exposed a problem when there are 'extra' bytes (possibly unused) after a line table prologue header and before the line table itself. This releases fixes the bug. Thanks to Matthew Legendre for pointing out that we were sharing de_fde_count for eh and non-eh and that could cause erroneous error returns in a couple of functions. These counts are now separate. April 9, 2008 libdwarf would behave badly if one compilation unit had more than 64K abbreviations: It was both very slow dealing with abbreviations and would get mixed up and error-off. Increased the size of some internal variables and rewrote abbreviation lookup. February 18, 2008 It is now possible to write one's own access to objects, making it possible to use a different library than libelf or even read a completely different object format than ELF. See dwarf_object_init() and see the new source files dwarf_original_elf_init.c and dwarf_elf_access.c for example code using the new function-pointer approach as it's implementation. Thanks to Josh Fuhs for doing the design and 99% of the work to make this happen. February 2, 2008 Now pro_init() defaults to standard DWARF3 generated offset sizes. But if a new flag DW_DLC_OFFSET_SIZE_64 or'd into flags passed to dwarf_produser_init() or dwarf_producer_init_b, the DWARF3 extended offset size is generated (if the address size is 64 bit). The new configure option --enable-dwarf-format-strict-32bit forces pro_init() to always cause 32bit offset dwarf generation. The new configure option --enable-dwarf-format-sgi-irix forces the old SGI IRIX 64bit offset generation for 64bit pointer size objects. This is intended to simplify standard DWARF3 generation with the now-normal use of 32bit DWARF offsets for both 32 and 64 bit pointer objects. It does require that anyone wanting SGI IRIX dwarf generation with its non-standard offsets for 64bit objects use the new --enable-dwarf-format-sgi-irix configure time option. This has no effect on dwarf reader code. It affects code calling the libdwarf producer interfaces. December 8, 2007 Had to add an ugly configure conditional as libelf has unconditional use of off64_t in recent libelf.h July 3, 2007 A new interface function, dwarf_loclist_from_expr(), allows easy extraction of dwarf expression bytes from expressions in frame data. May 8, 2007 Now documents released as .mm and .pdf (no longer as .ps). May 7, 2007 Incorporates Sun Microsystems extensions to dwarf.h and to the consumer and producer libraries. The changes include corrections so the producer library cleans up it's memory use on a call to dwarf_producer_finish(dbg). Thanks to Chris Quenelle of Sun for these contributions. March 20, 2007 nroff/troff and the AT&T -mm package are not widely available, so now the Makefile refers to groff, which works quite nicely. February 20, 2007 Documented libdwarf thread safety in README. Fixed memory leak in dwarf macro reading code. Removed use of static data in dwarf macro reading code: now uses stack/heap (for thread safety). February 9, 2007 Maintenance of libdwarf is now outside SGI as David Anderson has left SGI. March 29, 2006 The March 27, 2006 version accomodates DWARF3. Some people have been using the library without altering dwarf.h, libdwarf.h to accomodate large numbers of registers. This exposed a bug (an off-by-one error) but also makes it clear additional documentation is needed. So in libdwarf large new comments near 'TARGET DEPENDENCY' attempt to explain better. Oct 03, 2005 The July version had an incompatible interface: old dealloc code did not always work right. The incompatibility is now fixed and the new features remain. July 15, 2005 New optional alloc-check code optionally checks all allocated memory is freed (malloc_check.h malloc_check.c) Various new dealloc routines written as the previous approach of letting client code do detailed dealloc turned out not to dealloc all memory. To get the new checking you must manually change a line in malloc_check.h and rebuild libdwarf. Mar 31, 2005 Documented the libexc.so/.debug_funcnames dependency and the 64bit-offset DWARF extension in mips_extentions.{mm,ps}. Mar 21, 2005 gcc 3.3 and 3.4 .eh_frame 'z' augmentations are not handled correctly, so libdwarf gives an error when attempting to print such. gcc 2 'eh' augmentation is simpler and prints correctly. (.eh_frame is a GNU section, not DWARF2/3, and what is recorded in .eh_frame is not specified by DWARF2/3, though .eh_frame does resemble DWARF2/3 .debug_frame). Oct 28, 2004 Updated contact address in copyright: SGI moved 1/4 mile in 2003 to a new address: 1500 Crittenden Lane. Documented additional vendor extensions. Oct 27, 2004 Added known vendor extensions to dwarf2/3 to dwarf.h HP, GNU, PGI and UPC extensions are now recorded. Recorded vendor extensions from Concurrent. Feb 3, 2004 If 'Dwarf_Word' is 64 bits, two macros reading leb numbers fail to initialize upper bits of the values read. First noticed with bogus line numbers printing from dwarfdump. Now we use already-existing functions, avoiding the problem. Oct 02, 2003 Support .debug_loc section fully. Sept 29, 2003 Support DW_FORM_indirect properly. Supports loclists in part (but not multiple loclist entries yet). Support 'padding bytes' at end of .debug_arange and .debug_pubnames and .debug_pubtypes per CU (recent dwarf committee email made it clear this is appropriate). May 23, 2002 Libdwarf now asks for sections only when they are used, so that unneeded sections aren't loaded. Support for using SGI's ELF library as an alternative to using AT&T libelf-style has been added (the SGI ELF library is presently only available internally to SGI). Jan 10, 2002 Fixed memory leak in dwarf_finish(). Aug 21, 2001 If one called dwarf_add_file_decl() or dwarf_add_directory_decl() but never added a line, .debug_line was not produced. This was a mistake, as if any file or directory was provided .debug_line should be produced. Now it is produced. June 14, 2001 Given a cu header offset, it was not easy to derive the CU header DIE offset. Created the new function dwarf_get_cu_die_offset_given_cu_header_offset() do get the CU header DIE offset. Added the function dwarf_get_arange_cu_header_offset() so the cu header offset could be retrieved from .debug_aranges information. June 07, 2001 Major bug in dwarf_leb.c decoding large integers (Dwarf_Signed 64 bit where library is compiled in ILP32) found and fixed. May 21, 2001 Some small fixes have been found by various folks, so it seems time to prepare a new source release. See ChangeLog for details. April 15, 2000 The libdwarf copyright has changed to version 2.1 of the GNU Lesser General Public License. Anyone holding a version of libdwarf that was published before this new copyright is allowed to use the copyright published in that earlier libdwarf source on the earlier source or to use this new copyright on the earlier source, at their option. December 08, 1999 The dwarf committee has adopted the offset-extension proposal. This allows compatibly emitting dwarf with 64bit offsets. The dwarf reader now automatically figures out which is in use. The dwarf writer configures itself at the time the writer initialization routine is called, though the writer is restricted, at libdwarf compile time, to one of mips/sgi pure 32/pure 64 offsets/pointers. 32bit offsets only (per dwarf 2.0.0 and cygnus) 32bit offsets with extension to 64bit offsets allowed (the offset-extension newly passed). In addition, a great deal of duplicate code for the sgi .debug_weaknames, .debug_funcnames, .debug_varnames and .debug_typenames sections has been removed: a single set of functions does the real work now. Sept 29, 1999 Just found out that cygnus is, on 64bit targets, generating 32bit offsets (as elf32 has, for example) with 64 bit pointers (in references to text and data). Whereas sgi has always generated 64bit dwarf with 64 bit offsets (as in elf64) and 64bit pointers for 64bit pointer objects. I'll call the sgi approach 64-bit and the cygnus approach 32bit-offsets. Cygnus is following the DWARF2 spec as written, so they are right in doing only 32bit-offsets. Folks at sgi (including me) think that, as for elf64, the offsets in dwarf for 64bit pointer-apps should be 64 bits. We think it is only a matter of time before we really *need* 64bit offsets and when that happens it will be on an important app. Disk space is cheap, so lets just go 64 bit on 64bit apps (such as ia64 apps) to avoid a future problem. I(davea@sgi.com) think the 'pointer-size' references in the dwarf spec were really written for 64-bit pointer apps. I don't recall serious consideration of 64bit pointer apps in the committee deliberations (I did miss a couple of meetings) and think 64bit offsets are consistent with dwarf2, even though the speci was not written for such. We think true full 64 bit dwarf2 is the right way to go (the spec changes are obvious: file and section offsets become 64bit with 64bit pointer objects. MIPS/SGI is definitely 64-bit offsets for 64 bit objects, cygnus is definitely 32bit-offsets for earlier 64bit pointer environments. At any rate, now the dwarf reader allows and accomodates both and the dwarf producer also accomodates both. Some tweaking of the pro_init.c or dwarf_init_finish.c files may be necessary in future: no other changes should be needed to accomodate the two 64bit approaches, as the library (and dwarfdump) now deal with both forms. August 20, 1999 Added some #ifndef/#define to pro_util.h to let libdwarf build on more hosts. (since those hosts don't need the producer code, AFAIK, zero values suffice for missing #defines.) July 21, 1999 Now reader transparently reads either-endianness data from an either-endianness object. Updated dwarf.h and libdwarf.h to recognize GNU egcs dwarf extensions and to print the egcs eh_frame section. June 10, 1999 gnu configure version of libdwarf made available for the first time. Still allows only same-endian-as-host in objects. August, 1994 libdwarf source made available for ftp on sgigate.sgi.com /ftp/pub June, 1994 Consumer interface changed completely, following "Candy Machine Interfaces" chapter from "Writing Solid Code" by Steve Maguire (Microsoft Press). April, 1993 Initial version of libdwarf for dwarf version 2 written at sgi. dwarfutils-20200114/libdwarf/README000066400000000000000000000242571361531463500166240ustar00rootroot00000000000000To build libdwarf.a, type ./configure make To build libdwarf.so, type ./configure --enable-shared --disable-nonshared make To build both, type ./configure --enable-shared make April 16, 2017: Some people have had build problems, getting errors like: "dwarf_elf_access.c:238:21: warning: assignment makes pointer from integer without a cast [enabled by default] if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {" That suggests that the libelf headers needed are missing. On Ubuntu the command 'sudo apt-get install libelf-dev' should solve this problem. January 30, 2013: libdwarf.h is no longer in the distribution, but libdwarf.h.in is identical to libdwarf.h. 'configure' copies libdwarf.h.in to libdwarf.h and whether libelf.h defines 'struct _Elf' or 'struct Elf' configure attempts to create libdwarf.h appropriately. No real install target is provided here, so 'make install' does not do much. One can copy either or both of libdwarf.a libdwarf.so to somewhere fairly standard (but intended for software you build) like '/usr/local/lib'. Or anywhere else you want to copy it. To use dwarf or libdwarf, you may want to copy dwarf.h and a generated libdwarf.h somewhere convenient (possibly /usr/local/include), and you may need to copy the libdwarf to a convenient spot (/usr/local/lib is a traditional place for libraries one builds oneself on Unix and Linux). This copying is not needed to build dwarfdump. Multi Threading, or using threads with libdwarf (Thread Safety): Nothing in libdwarf does any locking. Every Dwarf_Debug (such as returned by dwarf_init()) is fully independent of all other Dwarf_Debug-s. However, calls to libdwarf can change a Dwarf_Debug. So it is unsafe to have two different threads accessing a single Dwarf_Debug simultaneously. It is therefore sufficient to ensure than any one Dwarf_Debug is only accessed from a single thread. Warnings like "warning: cast from pointer to integer of different size" at compile time are to be expected in dwarf_frame.c and dwarf_frame2.c. Do not be alarmed. Warnings like "warning: passing argument 1 of ‘dbg->de_callback_func_c’ discards ‘const’ qualifier from pointer target type [enabled by default]" at compile time are to be expected in some pro*.c source files. Fixing the public prototype could cause some producer-library user's code to fail to compile so we live with the warnings. When cross-compiling, gennames has to be built by the native compiler. So try make HOSTCC=cc gennames as a first step before the normal make. If your headers are not in the expected places, use the make command line to add flags and include directories. For example ./configure PREINCS="-I /usr/local/share/include" POSTINCS="-I /home/x/include" make PREINCS content is inserted before CFLAGS as make(1) is running. POSTINCS content is added after the CFLAGS value. To set LDFLAGS (which is used when building a .so and in building gennames to create some source here), do so at configure time, for example: ./configure LDFLAGS="-L /var/tmp" Or use PRELIBS and/or POSTLIBS at 'make' time similar to the use of PREINCS and POSTINCS. If you are using the old frame interfaces and depend on the use of DW_FRAME_CFA_COL you must add --enable-oldframecol to the ./configure options to configure libdwarf. See NEWS and libdwarf2.1.mm/pdf . To generate SGI IRIX 64 bit offsets (in the producer code) configure with --enable-dwarf-format-sgi-irix. To configure with only 32bit offsets (aka DWARF2) configure with --enable-dwarf-format-strict-32bit. By default the producer now generates 32bit offsets by default but one can turn on DWARF3 64bit offset generation at runtime by ORing DW_DLC_OFFSET_SIZE_64 onto the flags in the call to dwarf_producer_init() (or dwarf_producer_init_b) [when the address size is specified as 64 bit]. Mac OSX (June 2010): Since MacOSX does not use elf, there is no elf.h header in the headers provided on MacOSX. Use a search engine (like google) to find an elf.h you can use. http://www.rockbox.org/tracker/9006?getfile=16683 might be useful. In addition, the archive (ar) program on MacOSX does not automatically generate some data so modify the generated Makefile to add -s to the options to ar. Windows (February 2016): Those wishing to read DWARF2 or later from Windows PE files (using Mingw) should take a look at https://github.com/jrfonseca/drmingw/tree/master/src/mgwhelp which shows simple LGPL code that implements the necessary object reading interfaces for PE objects. dwarf_pe.cpp fills out the Dwarf_Obj_Access_Methods object interface and opens an object (see dwarf_object_init()) using the PE object access making the full libdwarf API available. To enable dection of Windows pathnames as full paths add --enable-windowspath. Doing this does mean things like A:foo and \anything are treated as full paths (these are unlikely path names on a POSIX system but are legal POSIX partial paths). Back to Linux/Unix: It is possible to request a shared library (libdwarf.so) build with --enable-shared To turn off the build of the archive library (libdwarf.a) specify --disable-nonshared but in this case you must specify --enable-shared or nothing will build! TARGET DEPENDENCIES of .debug_frame: dwarf.h These should be revised if you have more than the defined 63 'normal' registers. It's not harmful to have these too large! Too small will lead to errors reading .debug_frame and .eh_frame. DW_FRAME_HIGHEST_NORMAL_REGISTER DW_FRAME_LAST_REG_NUM These you might revise, but can safely ignore if simply using dwarfdump. If using the producer code you will want to get these exactly right for your architecture. DW_FRAME_RA_COL DW_FRAME_STATIC_LINK DW_FRAME_CFA_COL libdwarf.h The DW_FRAME_REG_INITIAL_VALUE #define should be set to the value appropriate to your architecture. See libdwarf.h for details. If DW_REG_TABLE_SIZE is not set large enough attempts to fill in the .debug_frame tables will get an error. Should be at least as large as DW_FRAME_LAST_REG_NUM. If it's too large nothing is harmed (but some extra space taken at run time). If your printf does not support C standard %llx etc, (such as MSWindows with long long), configure option --enable-nonstandardprintf and defines like DW_PR_DUx etc in libdwarf.h provide a way to configure for that relatively easily. The .debug_frame is so very architecture dependent and because the host (where libdwarf/dwarfdump are executed) and target (the objects read) could be different. It's currently not supported to have dwarfdump/libdwarf determine the architecture on-the-fly and do-the-right-thing. Just setting DW_FRAME_LAST_REG_NUM and DW_FRAME_HIGHEST_NORMAL_REGISTER and DW_REG_TABLE_SIZE high enough will likely suffice for most purposes and most compilers/architectures.. See comments in dwarf.h/libdwarf.h. It's perfectly safe to ignore the above suggestions as long as libdwarf does not get a DW_DLE_DF_REG_NUM_TOO_HIGH error. (which would only happen on reading .debug_frame or .eh_frame data). If you intend to use the libdwarf dwarf-producer code for .debug_frame information you must do a thorough analysys and revise dwarf.h substantially to match the output target architecture. In general, in the producer code, numbers are copied from and to integers with memcpy(). In case of endianness problems, constants set in dwarf_producer_init() can fix the problems. If one wants to produce a *different-endian* output the best solution is to change the integer memcpy calls to call thru a new dbg-based function pointer and have it 'do the right thing' to adjust endianness. Set the function pointer correctly in dwarf_producer_init() and the rest of the code will just call thru the function pointer. Tedious work to find and change the memcpy calls to be dbg->de_memcpy(), but once done the code is no longer endian dependent (right now there is no way to ask for cross-endian: a new flag needed or ?). leb128 numbers are endian-independent, so nothing need be done with those for cross-endian support (the storage of leb128 on disk is always little-endian). The .ps files are postscript. So those who cannot deal with mm format files but do have a postscript printer (or have ghostscript) can print the documents. This form was chosen before pdf format existed... libdwarf2.1.pdf documents a way for a debugger to read dwarf information. libdwarf2p.1.pdf documents a way for a compiler to generate dwarf information. mips_extensions.ps documents the mips/sgi extensions to dwarf. See the Makefile for the commands used to build pdf files libdwarf.2.1.pdf and libdwarf1p.1.pdf. pic is a picture processing tool (ATT command). tbl is a table-processing tool. (part of Documentor's Work Bench on ATT-like systems). tbl and pic are available on linux. psroff is a name for a troff-like processor, part of Documentor's Work Bench on IRIX. Substitute a troff-like or nroff-like processor (GNU groff works fine). To use dwarf or libdwarf, you may want to install dwarf.h and libdwarf.h somewhere convenient. You will also need libelf (libelf.a and/or libelf.so) and libelf.h installed. These are available from GNU repositories and from the normal Linux repositories for Linux releases. On Ubuntu Linux for example: sudo apt-get install libelf-dev libelf1 Compiler warnings: A few Warnings like: dwarf_frame.c:715:29: warning: cast from pointer to integer of different size [- Wpointer-to-int-cast] dwarf_arange.c:113:13: warning: variable ‘local_extension_size’ set but not used [-Wunused-but-set-variable] are considered normal. As of January 2013 the code compiles with gcc without problems with -Wall and -Wsign-compare aside from the warnings hinted at above. The following gcc/clang options have not all been tried as of January 2013, but will be as time permits. -Wsystem-headers -Wall -Wsign-compare -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wold-style-definition -Wno-pointer-sign $Source: /home/davea/dwarf/dwarf-working/trunk/libdwarf/README,v $ $Revision: 1.1 $ $Date: 2009/11/23 17:15:37 $ dwarfutils-20200114/libdwarf/baseline.ltp000066400000000000000000000023351361531463500202400ustar00rootroot00000000000000originalfullpath : /fake/dir/path/a/b linkstring full path: /fake/dir/path/a/de Paths: [ 0] "/usr/lib/debug/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 1] "/fake/lib/debug/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 2] "/fake/dir/path/a/de" [ 3] "/fake/dir/path/a/.debug/de" [ 4] "/usr/lib/debug/fake/dir/path/a/de" [ 5] "/fake/lib/debug/fake/dir/path/a/de" originalfullpath : /fake/dir/path/ge linkstring full path: /fake/dir/path/h/i Paths: [ 0] "/usr/lib/debug/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 1] "/fake/lib/debug/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 2] "/fake/dir/path/h/i" [ 3] "/fake/dir/path/.debug/h/i" [ 4] "/usr/lib/debug/fake/dir/path/h/i" [ 5] "/fake/lib/debug/fake/dir/path/h/i" originalfullpath : /somewherespecial/a/b/ge linkstring full path: /somewherespecial/a/b/h/i Paths: [ 0] "/usr/lib/debug/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 1] "/fake/lib/debug/11/22334421222344a1a2a3a4b1b2b3b4c1c2c3c4.debug" [ 2] "/somewherespecial/a/b/h/i" [ 3] "/somewherespecial/a/b/.debug/h/i" [ 4] "/usr/lib/debug/somewherespecial/a/b/h/i" [ 5] "/fake/lib/debug/somewherespecial/a/b/h/i" dwarfutils-20200114/libdwarf/dwarf.h000066400000000000000000002115111361531463500172070ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2007-2017 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef __DWARF_H #define __DWARF_H #ifdef __cplusplus extern "C" { #endif /* dwarf.h DWARF debugging information values $Revision: 1.41 $ $Date: 2006/04/17 00:09:56 $ The comment "DWARF3" appears where there are new entries from DWARF3 as of 2004, "DWARF3f" where there are new entries as of the November 2005 public review document and other comments apply where extension entries appear. Extensions part of DWARF4 are marked DWARF4. A few extension names have omitted the 'vendor id' (See chapter 7, "Vendor Extensibility"). Please always use a 'vendor id' string in extension names. Vendors should use a vendor string in names and whereever possible avoid duplicating values used by other vendor extensions The DWARF1 comments indicate values unused in DWARF2 and later but used or reserved in DWARF1. */ #define DW_TAG_array_type 0x01 #define DW_TAG_class_type 0x02 #define DW_TAG_entry_point 0x03 #define DW_TAG_enumeration_type 0x04 #define DW_TAG_formal_parameter 0x05 /* TAG_global_subroutine 0x06 DWARF1 only */ /* TAG_global_variable 0x07 DWARF1 only */ #define DW_TAG_imported_declaration 0x08 /* reserved by DWARF1 0x09 DWARF1 only */ #define DW_TAG_label 0x0a #define DW_TAG_lexical_block 0x0b /* TAG_local_variable 0x0c DWARF1 only. */ #define DW_TAG_member 0x0d /* reserved by DWARF1 0x0e DWARF1 only */ #define DW_TAG_pointer_type 0x0f #define DW_TAG_reference_type 0x10 #define DW_TAG_compile_unit 0x11 #define DW_TAG_string_type 0x12 #define DW_TAG_structure_type 0x13 /* TAG_subroutine 0x14 DWARF1 only */ #define DW_TAG_subroutine_type 0x15 #define DW_TAG_typedef 0x16 #define DW_TAG_union_type 0x17 #define DW_TAG_unspecified_parameters 0x18 #define DW_TAG_variant 0x19 #define DW_TAG_common_block 0x1a #define DW_TAG_common_inclusion 0x1b #define DW_TAG_inheritance 0x1c #define DW_TAG_inlined_subroutine 0x1d #define DW_TAG_module 0x1e #define DW_TAG_ptr_to_member_type 0x1f #define DW_TAG_set_type 0x20 #define DW_TAG_subrange_type 0x21 #define DW_TAG_with_stmt 0x22 #define DW_TAG_access_declaration 0x23 #define DW_TAG_base_type 0x24 #define DW_TAG_catch_block 0x25 #define DW_TAG_const_type 0x26 #define DW_TAG_constant 0x27 #define DW_TAG_enumerator 0x28 #define DW_TAG_file_type 0x29 #define DW_TAG_friend 0x2a #define DW_TAG_namelist 0x2b /* Early releases of this header had the following misspelled with a trailing 's' */ #define DW_TAG_namelist_item 0x2c /* DWARF3/2 spelling */ #define DW_TAG_namelist_items 0x2c /* SGI misspelling/typo */ #define DW_TAG_packed_type 0x2d #define DW_TAG_subprogram 0x2e /* The DWARF2 document had two spellings of the following two TAGs, DWARF3 specifies the longer spelling. */ #define DW_TAG_template_type_parameter 0x2f /* DWARF3/2 spelling*/ #define DW_TAG_template_type_param 0x2f /* DWARF2 spelling*/ #define DW_TAG_template_value_parameter 0x30 /* DWARF3/2 spelling*/ #define DW_TAG_template_value_param 0x30 /* DWARF2 spelling*/ #define DW_TAG_thrown_type 0x31 #define DW_TAG_try_block 0x32 #define DW_TAG_variant_part 0x33 #define DW_TAG_variable 0x34 #define DW_TAG_volatile_type 0x35 #define DW_TAG_dwarf_procedure 0x36 /* DWARF3 */ #define DW_TAG_restrict_type 0x37 /* DWARF3 */ #define DW_TAG_interface_type 0x38 /* DWARF3 */ #define DW_TAG_namespace 0x39 /* DWARF3 */ #define DW_TAG_imported_module 0x3a /* DWARF3 */ #define DW_TAG_unspecified_type 0x3b /* DWARF3 */ #define DW_TAG_partial_unit 0x3c /* DWARF3 */ #define DW_TAG_imported_unit 0x3d /* DWARF3 */ /* Do not use DW_TAG_mutable_type */ #define DW_TAG_mutable_type 0x3e /* Withdrawn from DWARF3 by DWARF3f. */ #define DW_TAG_condition 0x3f /* DWARF3f */ #define DW_TAG_shared_type 0x40 /* DWARF3f */ #define DW_TAG_type_unit 0x41 /* DWARF4 */ #define DW_TAG_rvalue_reference_type 0x42 /* DWARF4 */ #define DW_TAG_template_alias 0x43 /* DWARF4 */ #define DW_TAG_coarray_type 0x44 /* DWARF5 */ #define DW_TAG_generic_subrange 0x45 /* DWARF5 */ #define DW_TAG_dynamic_type 0x46 /* DWARF5 */ #define DW_TAG_atomic_type 0x47 /* DWARF5 */ #define DW_TAG_call_site 0x48 /* DWARF5 */ #define DW_TAG_call_site_parameter 0x49 /* DWARF5 */ #define DW_TAG_skeleton_unit 0x4a /* DWARF5 */ #define DW_TAG_immutable_type 0x4b /* DWARF5 */ #define DW_TAG_lo_user 0x4080 #define DW_TAG_MIPS_loop 0x4081 /* HP extensions: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz */ #define DW_TAG_HP_array_descriptor 0x4090 /* HP */ /* GNU extensions. The first 3 missing the GNU_. */ #define DW_TAG_format_label 0x4101 /* GNU. Fortran. */ #define DW_TAG_function_template 0x4102 /* GNU. For C++ */ #define DW_TAG_class_template 0x4103 /* GNU. For C++ */ #define DW_TAG_GNU_BINCL 0x4104 /* GNU */ #define DW_TAG_GNU_EINCL 0x4105 /* GNU */ /* GNU extension. http://gcc.gnu.org/wiki/TemplateParmsDwarf */ #define DW_TAG_GNU_template_template_parameter 0x4106 /* GNU */ #define DW_TAG_GNU_template_template_param 0x4106 /* GNU */ #define DW_TAG_GNU_template_parameter_pack 0x4107 /* GNU */ #define DW_TAG_GNU_formal_parameter_pack 0x4108 /* GNU */ #define DW_TAG_GNU_call_site 0x4109 /* GNU */ #define DW_TAG_GNU_call_site_parameter 0x410a /* GNU */ /* ALTIUM extensions */ /* DSP-C/Starcore __circ qualifier */ #define DW_TAG_ALTIUM_circ_type 0x5101 /* ALTIUM */ /* Starcore __mwa_circ qualifier */ #define DW_TAG_ALTIUM_mwa_circ_type 0x5102 /* ALTIUM */ /* Starcore __rev_carry qualifier */ #define DW_TAG_ALTIUM_rev_carry_type 0x5103 /* ALTIUM */ /* M16 __rom qualifier */ #define DW_TAG_ALTIUM_rom 0x5111 /* ALTIUM */ /* The following 3 are extensions to support UPC */ #define DW_TAG_upc_shared_type 0x8765 /* UPC */ #define DW_TAG_upc_strict_type 0x8766 /* UPC */ #define DW_TAG_upc_relaxed_type 0x8767 /* UPC */ /* PGI (STMicroelectronics) extensions. */ #define DW_TAG_PGI_kanji_type 0xa000 /* PGI */ #define DW_TAG_PGI_interface_block 0xa020 /* PGI */ /* The following are SUN extensions */ #define DW_TAG_SUN_function_template 0x4201 /* SUN */ #define DW_TAG_SUN_class_template 0x4202 /* SUN */ #define DW_TAG_SUN_struct_template 0x4203 /* SUN */ #define DW_TAG_SUN_union_template 0x4204 /* SUN */ #define DW_TAG_SUN_indirect_inheritance 0x4205 /* SUN */ #define DW_TAG_SUN_codeflags 0x4206 /* SUN */ #define DW_TAG_SUN_memop_info 0x4207 /* SUN */ #define DW_TAG_SUN_omp_child_func 0x4208 /* SUN */ #define DW_TAG_SUN_rtti_descriptor 0x4209 /* SUN */ #define DW_TAG_SUN_dtor_info 0x420a /* SUN */ #define DW_TAG_SUN_dtor 0x420b /* SUN */ #define DW_TAG_SUN_f90_interface 0x420c /* SUN */ #define DW_TAG_SUN_fortran_vax_structure 0x420d /* SUN */ #define DW_TAG_SUN_hi 0x42ff /* SUN */ #define DW_TAG_hi_user 0xffff /* The following two are non-standard. Use DW_CHILDREN_yes and DW_CHILDREN_no instead. These could probably be deleted, but someone might be using them, so they remain. */ #define DW_children_no 0 #define DW_children_yes 1 #define DW_FORM_addr 0x01 /* FORM_REF 0x02 DWARF1 only */ #define DW_FORM_block2 0x03 #define DW_FORM_block4 0x04 #define DW_FORM_data2 0x05 #define DW_FORM_data4 0x06 #define DW_FORM_data8 0x07 #define DW_FORM_string 0x08 #define DW_FORM_block 0x09 #define DW_FORM_block1 0x0a #define DW_FORM_data1 0x0b #define DW_FORM_flag 0x0c #define DW_FORM_sdata 0x0d #define DW_FORM_strp 0x0e #define DW_FORM_udata 0x0f #define DW_FORM_ref_addr 0x10 #define DW_FORM_ref1 0x11 #define DW_FORM_ref2 0x12 #define DW_FORM_ref4 0x13 #define DW_FORM_ref8 0x14 #define DW_FORM_ref_udata 0x15 #define DW_FORM_indirect 0x16 #define DW_FORM_sec_offset 0x17 /* DWARF4 */ #define DW_FORM_exprloc 0x18 /* DWARF4 */ #define DW_FORM_flag_present 0x19 /* DWARF4 */ #define DW_FORM_strx 0x1a /* DWARF5 */ #define DW_FORM_addrx 0x1b /* DWARF5 */ #define DW_FORM_ref_sup4 0x1c /* DWARF5 */ #define DW_FORM_strp_sup 0x1d /* DWARF5 */ #define DW_FORM_data16 0x1e /* DWARF5 */ #define DW_FORM_line_strp 0x1f /* DWARF5 */ #define DW_FORM_ref_sig8 0x20 /* DWARF4 */ #define DW_FORM_implicit_const 0x21 /* DWARF5 */ #define DW_FORM_loclistx 0x22 /* DWARF5 */ #define DW_FORM_rnglistx 0x23 /* DWARF5 */ #define DW_FORM_ref_sup8 0x24 /* DWARF5 */ #define DW_FORM_strx1 0x25 /* DWARF5 */ #define DW_FORM_strx2 0x26 /* DWARF5 */ #define DW_FORM_strx3 0x27 /* DWARF5 */ #define DW_FORM_strx4 0x28 /* DWARF5 */ #define DW_FORM_addrx1 0x29 /* DWARF5 */ #define DW_FORM_addrx2 0x2a /* DWARF5 */ #define DW_FORM_addrx3 0x2b /* DWARF5 */ #define DW_FORM_addrx4 0x2c /* DWARF5 */ #define DW_FORM_GNU_addr_index 0x1f01 /* GNU extension in debug_info.dwo.*/ #define DW_FORM_GNU_str_index 0x1f02 /* GNU extension, somewhat like DW_FORM_strp */ #define DW_FORM_GNU_ref_alt 0x1f20 /* GNU extension. Offset in .debug_info. */ #define DW_FORM_GNU_strp_alt 0x1f21 /* GNU extension. Offset in .debug_str of another object file. */ #define DW_AT_sibling 0x01 #define DW_AT_location 0x02 #define DW_AT_name 0x03 /* reserved DWARF1 0x04, DWARF1 only */ /* AT_fund_type 0x05, DWARF1 only */ /* AT_mod_fund_type 0x06, DWARF1 only */ /* AT_user_def_type 0x07, DWARF1 only */ /* AT_mod_u_d_type 0x08, DWARF1 only */ #define DW_AT_ordering 0x09 #define DW_AT_subscr_data 0x0a #define DW_AT_byte_size 0x0b #define DW_AT_bit_offset 0x0c #define DW_AT_bit_size 0x0d /* reserved DWARF1 0x0d, DWARF1 only */ #define DW_AT_element_list 0x0f #define DW_AT_stmt_list 0x10 #define DW_AT_low_pc 0x11 #define DW_AT_high_pc 0x12 #define DW_AT_language 0x13 #define DW_AT_member 0x14 #define DW_AT_discr 0x15 #define DW_AT_discr_value 0x16 #define DW_AT_visibility 0x17 #define DW_AT_import 0x18 #define DW_AT_string_length 0x19 #define DW_AT_common_reference 0x1a #define DW_AT_comp_dir 0x1b #define DW_AT_const_value 0x1c #define DW_AT_containing_type 0x1d #define DW_AT_default_value 0x1e /* reserved 0x1f */ #define DW_AT_inline 0x20 #define DW_AT_is_optional 0x21 #define DW_AT_lower_bound 0x22 /* reserved 0x23 */ /* reserved 0x24 */ #define DW_AT_producer 0x25 /* reserved 0x26 */ #define DW_AT_prototyped 0x27 /* reserved 0x28 */ /* reserved 0x29 */ #define DW_AT_return_addr 0x2a /* reserved 0x2b */ #define DW_AT_start_scope 0x2c /* reserved 0x2d */ #define DW_AT_bit_stride 0x2e /* DWARF3 name */ #define DW_AT_stride_size 0x2e /* DWARF2 name */ #define DW_AT_upper_bound 0x2f /* AT_virtual 0x30, DWARF1 only */ #define DW_AT_abstract_origin 0x31 #define DW_AT_accessibility 0x32 #define DW_AT_address_class 0x33 #define DW_AT_artificial 0x34 #define DW_AT_base_types 0x35 #define DW_AT_calling_convention 0x36 #define DW_AT_count 0x37 #define DW_AT_data_member_location 0x38 #define DW_AT_decl_column 0x39 #define DW_AT_decl_file 0x3a #define DW_AT_decl_line 0x3b #define DW_AT_declaration 0x3c #define DW_AT_discr_list 0x3d /* DWARF2 */ #define DW_AT_encoding 0x3e #define DW_AT_external 0x3f #define DW_AT_frame_base 0x40 #define DW_AT_friend 0x41 #define DW_AT_identifier_case 0x42 #define DW_AT_macro_info 0x43 /* DWARF{234} not DWARF5 */ #define DW_AT_namelist_item 0x44 #define DW_AT_priority 0x45 #define DW_AT_segment 0x46 #define DW_AT_specification 0x47 #define DW_AT_static_link 0x48 #define DW_AT_type 0x49 #define DW_AT_use_location 0x4a #define DW_AT_variable_parameter 0x4b #define DW_AT_virtuality 0x4c #define DW_AT_vtable_elem_location 0x4d #define DW_AT_allocated 0x4e /* DWARF3 */ #define DW_AT_associated 0x4f /* DWARF3 */ #define DW_AT_data_location 0x50 /* DWARF3 */ #define DW_AT_byte_stride 0x51 /* DWARF3f */ #define DW_AT_stride 0x51 /* DWARF3 (do not use) */ #define DW_AT_entry_pc 0x52 /* DWARF3 */ #define DW_AT_use_UTF8 0x53 /* DWARF3 */ #define DW_AT_extension 0x54 /* DWARF3 */ #define DW_AT_ranges 0x55 /* DWARF3 */ #define DW_AT_trampoline 0x56 /* DWARF3 */ #define DW_AT_call_column 0x57 /* DWARF3 */ #define DW_AT_call_file 0x58 /* DWARF3 */ #define DW_AT_call_line 0x59 /* DWARF3 */ #define DW_AT_description 0x5a /* DWARF3 */ #define DW_AT_binary_scale 0x5b /* DWARF3f */ #define DW_AT_decimal_scale 0x5c /* DWARF3f */ #define DW_AT_small 0x5d /* DWARF3f */ #define DW_AT_decimal_sign 0x5e /* DWARF3f */ #define DW_AT_digit_count 0x5f /* DWARF3f */ #define DW_AT_picture_string 0x60 /* DWARF3f */ #define DW_AT_mutable 0x61 /* DWARF3f */ #define DW_AT_threads_scaled 0x62 /* DWARF3f */ #define DW_AT_explicit 0x63 /* DWARF3f */ #define DW_AT_object_pointer 0x64 /* DWARF3f */ #define DW_AT_endianity 0x65 /* DWARF3f */ #define DW_AT_elemental 0x66 /* DWARF3f */ #define DW_AT_pure 0x67 /* DWARF3f */ #define DW_AT_recursive 0x68 /* DWARF3f */ #define DW_AT_signature 0x69 /* DWARF4 */ #define DW_AT_main_subprogram 0x6a /* DWARF4 */ #define DW_AT_data_bit_offset 0x6b /* DWARF4 */ #define DW_AT_const_expr 0x6c /* DWARF4 */ #define DW_AT_enum_class 0x6d /* DWARF4 */ #define DW_AT_linkage_name 0x6e /* DWARF4 */ #define DW_AT_string_length_bit_size 0x6f /* DWARF5 */ #define DW_AT_string_length_byte_size 0x70 /* DWARF5 */ #define DW_AT_rank 0x71 /* DWARF5 */ #define DW_AT_str_offsets_base 0x72 /* DWARF5 */ #define DW_AT_addr_base 0x73 /* DWARF5 */ /* Use DW_AT_rnglists_base, DW_AT_ranges_base is obsolete as */ /* it was only used in some DWARF5 drafts, not the final DWARF5. */ #define DW_AT_rnglists_base 0x74 /* DWARF5 */ /* DW_AT_dwo_id, an experiment in some DWARF4+. Not DWARF5! */ #define DW_AT_dwo_id 0x75 /* DWARF4!*/ #define DW_AT_dwo_name 0x76 /* DWARF5 */ #define DW_AT_reference 0x77 /* DWARF5 */ #define DW_AT_rvalue_reference 0x78 /* DWARF5 */ #define DW_AT_macros 0x79 /* DWARF5 */ #define DW_AT_call_all_calls 0x7a /* DWARF5 */ #define DW_AT_call_all_source_calls 0x7b /* DWARF5 */ #define DW_AT_call_all_tail_calls 0x7c /* DWARF5 */ #define DW_AT_call_return_pc 0x7d /* DWARF5 */ #define DW_AT_call_value 0x7e /* DWARF5 */ #define DW_AT_call_origin 0x7f /* DWARF5 */ #define DW_AT_call_parameter 0x80 /* DWARF5 */ #define DW_AT_call_pc 0x81 /* DWARF5 */ #define DW_AT_call_tail_call 0x82 /* DWARF5 */ #define DW_AT_call_target 0x83 /* DWARF5 */ #define DW_AT_call_target_clobbered 0x84 /* DWARF5 */ #define DW_AT_call_data_location 0x85 /* DWARF5 */ #define DW_AT_call_data_value 0x86 /* DWARF5 */ #define DW_AT_noreturn 0x87 /* DWARF5 */ #define DW_AT_alignment 0x88 /* DWARF5 */ #define DW_AT_export_symbols 0x89 /* DWARF5 */ #define DW_AT_deleted 0x8a /* DWARF5 */ #define DW_AT_defaulted 0x8b /* DWARF5 */ #define DW_AT_loclists_base 0x8c /* DWARF5 */ /* In extensions, we attempt to include the vendor extension in the name even when the vendor leaves it out. */ /* HP extensions. */ #define DW_AT_HP_block_index 0x2000 /* HP */ /* Follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_AT_lo_user 0x2000 #define DW_AT_MIPS_fde 0x2001 /* MIPS/SGI */ #define DW_AT_MIPS_loop_begin 0x2002 /* MIPS/SGI */ #define DW_AT_MIPS_tail_loop_begin 0x2003 /* MIPS/SGI */ #define DW_AT_MIPS_epilog_begin 0x2004 /* MIPS/SGI */ #define DW_AT_MIPS_loop_unroll_factor 0x2005 /* MIPS/SGI */ #define DW_AT_MIPS_software_pipeline_depth 0x2006 /* MIPS/SGI */ #define DW_AT_MIPS_linkage_name 0x2007 /* MIPS/SGI, GNU, and others.*/ #define DW_AT_MIPS_stride 0x2008 /* MIPS/SGI */ #define DW_AT_MIPS_abstract_name 0x2009 /* MIPS/SGI */ #define DW_AT_MIPS_clone_origin 0x200a /* MIPS/SGI */ #define DW_AT_MIPS_has_inlines 0x200b /* MIPS/SGI */ #define DW_AT_MIPS_stride_byte 0x200c /* MIPS/SGI */ #define DW_AT_MIPS_stride_elem 0x200d /* MIPS/SGI */ #define DW_AT_MIPS_ptr_dopetype 0x200e /* MIPS/SGI */ #define DW_AT_MIPS_allocatable_dopetype 0x200f /* MIPS/SGI */ #define DW_AT_MIPS_assumed_shape_dopetype 0x2010 /* MIPS/SGI */ #define DW_AT_MIPS_assumed_size 0x2011 /* MIPS/SGI */ /* HP extensions. */ #define DW_AT_HP_unmodifiable 0x2001 /* conflict: MIPS */ #define DW_AT_HP_actuals_stmt_list 0x2010 /* conflict: MIPS */ #define DW_AT_HP_proc_per_section 0x2011 /* conflict: MIPS */ #define DW_AT_HP_raw_data_ptr 0x2012 /* HP */ #define DW_AT_HP_pass_by_reference 0x2013 /* HP */ #define DW_AT_HP_opt_level 0x2014 /* HP */ #define DW_AT_HP_prof_version_id 0x2015 /* HP */ #define DW_AT_HP_opt_flags 0x2016 /* HP */ #define DW_AT_HP_cold_region_low_pc 0x2017 /* HP */ #define DW_AT_HP_cold_region_high_pc 0x2018 /* HP */ #define DW_AT_HP_all_variables_modifiable 0x2019 /* HP */ #define DW_AT_HP_linkage_name 0x201a /* HP */ #define DW_AT_HP_prof_flags 0x201b /* HP */ #define DW_AT_CPQ_discontig_ranges 0x2001 /* COMPAQ/HP */ #define DW_AT_CPQ_semantic_events 0x2002 /* COMPAQ/HP */ #define DW_AT_CPQ_split_lifetimes_var 0x2003 /* COMPAQ/HP */ #define DW_AT_CPQ_split_lifetimes_rtn 0x2004 /* COMPAQ/HP */ #define DW_AT_CPQ_prologue_length 0x2005 /* COMPAQ/HP */ #define DW_AT_INTEL_other_endian 0x2026 /* Intel, 1 if byte swapped. */ /* GNU extensions. */ #define DW_AT_sf_names 0x2101 /* GNU */ #define DW_AT_src_info 0x2102 /* GNU */ #define DW_AT_mac_info 0x2103 /* GNU */ #define DW_AT_src_coords 0x2104 /* GNU */ #define DW_AT_body_begin 0x2105 /* GNU */ #define DW_AT_body_end 0x2106 /* GNU */ #define DW_AT_GNU_vector 0x2107 /* GNU */ /* Thread safety, see http://gcc.gnu.org/wiki/ThreadSafetyAnnotation . */ /* The values here are from gcc-4.6.2 include/dwarf2.h. The values are not given on the web page at all, nor on web pages it refers to. */ #define DW_AT_GNU_guarded_by 0x2108 /* GNU */ #define DW_AT_GNU_pt_guarded_by 0x2109 /* GNU */ #define DW_AT_GNU_guarded 0x210a /* GNU */ #define DW_AT_GNU_pt_guarded 0x210b /* GNU */ #define DW_AT_GNU_locks_excluded 0x210c /* GNU */ #define DW_AT_GNU_exclusive_locks_required 0x210d /* GNU */ #define DW_AT_GNU_shared_locks_required 0x210e /* GNU */ /* See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo */ #define DW_AT_GNU_odr_signature 0x210f /* GNU */ /* See See http://gcc.gnu.org/wiki/TemplateParmsDwarf */ /* The value here is from gcc-4.6.2 include/dwarf2.h. The value is not consistent with the web page as of December 2011. */ #define DW_AT_GNU_template_name 0x2110 /* GNU */ /* The GNU call site extension. See http://www.dwarfstd.org/ShowIssue.php?issue=100909.2&type=open . */ #define DW_AT_GNU_call_site_value 0x2111 /* GNU */ #define DW_AT_GNU_call_site_data_value 0x2112 /* GNU */ #define DW_AT_GNU_call_site_target 0x2113 /* GNU */ #define DW_AT_GNU_call_site_target_clobbered 0x2114 /* GNU */ #define DW_AT_GNU_tail_call 0x2115 /* GNU */ #define DW_AT_GNU_all_tail_call_sites 0x2116 /* GNU */ #define DW_AT_GNU_all_call_sites 0x2117 /* GNU */ #define DW_AT_GNU_all_source_call_sites 0x2118 /* GNU */ /* Section offset to .debug_macro section. */ #define DW_AT_GNU_macros 0x2119 /* GNU */ /* The GNU DebugFission project: http://gcc.gnu.org/wiki/DebugFission */ #define DW_AT_GNU_dwo_name 0x2130 /* GNU */ #define DW_AT_GNU_dwo_id 0x2131 /* GNU */ #define DW_AT_GNU_ranges_base 0x2132 /* GNU */ #define DW_AT_GNU_addr_base 0x2133 /* GNU */ #define DW_AT_GNU_pubnames 0x2134 /* GNU */ #define DW_AT_GNU_pubtypes 0x2135 /* GNU */ /* To distinguish distinct basic blocks in a single source line. */ #define DW_AT_GNU_discriminator 0x2136 /* GNU */ /* Ada GNAT gcc attributes. constant integer forms. */ #define DW_AT_GNU_numerator 0x2303 /* GNU */ #define DW_AT_GNU_denominator 0x2304 /* GNU */ #define DW_AT_GNU_bias 0x2305 /* GNU */ /* ALTIUM extension: ALTIUM Compliant location lists (flag) */ #define DW_AT_ALTIUM_loclist 0x2300 /* ALTIUM */ /* Sun extensions */ #define DW_AT_SUN_template 0x2201 /* SUN */ #define DW_AT_VMS_rtnbeg_pd_address 0x2201 /* VMS */ #define DW_AT_SUN_alignment 0x2202 /* SUN */ #define DW_AT_SUN_vtable 0x2203 /* SUN */ #define DW_AT_SUN_count_guarantee 0x2204 /* SUN */ #define DW_AT_SUN_command_line 0x2205 /* SUN */ #define DW_AT_SUN_vbase 0x2206 /* SUN */ #define DW_AT_SUN_compile_options 0x2207 /* SUN */ #define DW_AT_SUN_language 0x2208 /* SUN */ #define DW_AT_SUN_browser_file 0x2209 /* SUN */ #define DW_AT_SUN_vtable_abi 0x2210 /* SUN */ #define DW_AT_SUN_func_offsets 0x2211 /* SUN */ #define DW_AT_SUN_cf_kind 0x2212 /* SUN */ #define DW_AT_SUN_vtable_index 0x2213 /* SUN */ #define DW_AT_SUN_omp_tpriv_addr 0x2214 /* SUN */ #define DW_AT_SUN_omp_child_func 0x2215 /* SUN */ #define DW_AT_SUN_func_offset 0x2216 /* SUN */ #define DW_AT_SUN_memop_type_ref 0x2217 /* SUN */ #define DW_AT_SUN_profile_id 0x2218 /* SUN */ #define DW_AT_SUN_memop_signature 0x2219 /* SUN */ #define DW_AT_SUN_obj_dir 0x2220 /* SUN */ #define DW_AT_SUN_obj_file 0x2221 /* SUN */ #define DW_AT_SUN_original_name 0x2222 /* SUN */ #define DW_AT_SUN_hwcprof_signature 0x2223 /* SUN */ #define DW_AT_SUN_amd64_parmdump 0x2224 /* SUN */ #define DW_AT_SUN_part_link_name 0x2225 /* SUN */ #define DW_AT_SUN_link_name 0x2226 /* SUN */ #define DW_AT_SUN_pass_with_const 0x2227 /* SUN */ #define DW_AT_SUN_return_with_const 0x2228 /* SUN */ #define DW_AT_SUN_import_by_name 0x2229 /* SUN */ #define DW_AT_SUN_f90_pointer 0x222a /* SUN */ #define DW_AT_SUN_pass_by_ref 0x222b /* SUN */ #define DW_AT_SUN_f90_allocatable 0x222c /* SUN */ #define DW_AT_SUN_f90_assumed_shape_array 0x222d /* SUN */ #define DW_AT_SUN_c_vla 0x222e /* SUN */ #define DW_AT_SUN_return_value_ptr 0x2230 /* SUN */ #define DW_AT_SUN_dtor_start 0x2231 /* SUN */ #define DW_AT_SUN_dtor_length 0x2232 /* SUN */ #define DW_AT_SUN_dtor_state_initial 0x2233 /* SUN */ #define DW_AT_SUN_dtor_state_final 0x2234 /* SUN */ #define DW_AT_SUN_dtor_state_deltas 0x2235 /* SUN */ #define DW_AT_SUN_import_by_lname 0x2236 /* SUN */ #define DW_AT_SUN_f90_use_only 0x2237 /* SUN */ #define DW_AT_SUN_namelist_spec 0x2238 /* SUN */ #define DW_AT_SUN_is_omp_child_func 0x2239 /* SUN */ #define DW_AT_SUN_fortran_main_alias 0x223a /* SUN */ #define DW_AT_SUN_fortran_based 0x223b /* SUN */ /* See http://gcc.gnu.org/wiki/DW_AT_GNAT_descriptive_type . */ #define DW_AT_use_GNAT_descriptive_type 0x2301 /* GNAT */ #define DW_AT_GNAT_descriptive_type 0x2302 /* GNAT */ /* Go-specific type attributes */ #define DW_AT_go_kind 0x2900 #define DW_AT_go_key 0x2901 #define DW_AT_go_elem 0x2902 #define DW_AT_go_embedded_field 0x2903 /* Attribute for DW_TAG_member of a struct type. Nonzero value indicates the struct field is an embedded field. */ #define DW_AT_go_runtime_type 0x2904 /* UPC extension */ #define DW_AT_upc_threads_scaled 0x3210 /* UPC */ /* PGI (STMicroelectronics) extensions. */ #define DW_AT_PGI_lbase 0x3a00 /* PGI. Block, constant, reference. This attribute is an ASTPLAB extension used to describe the array local base. */ #define DW_AT_PGI_soffset 0x3a01 /* PGI. Block, constant, reference. ASTPLAB adds this attribute to describe the section offset, or the offset to the first element in the dimension. */ #define DW_AT_PGI_lstride 0x3a02 /* PGI. Block, constant, reference. ASTPLAB adds this attribute to describe the linear stride or the distance between elements in the dimension. */ /* There are two groups of Apple extensions here, it is unclear what exactly is correct. */ #define DW_AT_APPLE_optimized 0x3fe1 /* Apple */ #define DW_AT_APPLE_flags 0x3fe2 /* Apple */ #define DW_AT_APPLE_isa 0x3fe3 /* Apple */ #define DW_AT_APPLE_block 0x3fe4 /* Apple */ #define DW_AT_APPLE_major_runtime_vers 0x3fe5 /* Apple */ #define DW_AT_APPLE_runtime_class 0x3fe6 /* Apple */ #define DW_AT_APPLE_omit_frame_ptr 0x3fe7 /* Apple */ /* Apple Extensions for closures */ #define DW_AT_APPLE_closure 0x3fe4 /* Apple */ /* Apple Extensions for Objective-C runtime info */ #define DW_AT_APPLE_major_runtime_vers 0x3fe5 /* Apple */ #define DW_AT_APPLE_runtime_class 0x3fe6 /* Apple */ #define DW_AT_hi_user 0x3fff /* OP values 0x01,0x02,0x04,0x05,0x07 are DWARF1 only */ #define DW_OP_addr 0x03 #define DW_OP_deref 0x06 #define DW_OP_const1u 0x08 #define DW_OP_const1s 0x09 #define DW_OP_const2u 0x0a #define DW_OP_const2s 0x0b #define DW_OP_const4u 0x0c #define DW_OP_const4s 0x0d #define DW_OP_const8u 0x0e #define DW_OP_const8s 0x0f #define DW_OP_constu 0x10 #define DW_OP_consts 0x11 #define DW_OP_dup 0x12 #define DW_OP_drop 0x13 #define DW_OP_over 0x14 #define DW_OP_pick 0x15 #define DW_OP_swap 0x16 #define DW_OP_rot 0x17 #define DW_OP_xderef 0x18 #define DW_OP_abs 0x19 #define DW_OP_and 0x1a #define DW_OP_div 0x1b #define DW_OP_minus 0x1c #define DW_OP_mod 0x1d #define DW_OP_mul 0x1e #define DW_OP_neg 0x1f #define DW_OP_not 0x20 #define DW_OP_or 0x21 #define DW_OP_plus 0x22 #define DW_OP_plus_uconst 0x23 #define DW_OP_shl 0x24 #define DW_OP_shr 0x25 #define DW_OP_shra 0x26 #define DW_OP_xor 0x27 #define DW_OP_bra 0x28 #define DW_OP_eq 0x29 #define DW_OP_ge 0x2a #define DW_OP_gt 0x2b #define DW_OP_le 0x2c #define DW_OP_lt 0x2d #define DW_OP_ne 0x2e #define DW_OP_skip 0x2f #define DW_OP_lit0 0x30 #define DW_OP_lit1 0x31 #define DW_OP_lit2 0x32 #define DW_OP_lit3 0x33 #define DW_OP_lit4 0x34 #define DW_OP_lit5 0x35 #define DW_OP_lit6 0x36 #define DW_OP_lit7 0x37 #define DW_OP_lit8 0x38 #define DW_OP_lit9 0x39 #define DW_OP_lit10 0x3a #define DW_OP_lit11 0x3b #define DW_OP_lit12 0x3c #define DW_OP_lit13 0x3d #define DW_OP_lit14 0x3e #define DW_OP_lit15 0x3f #define DW_OP_lit16 0x40 #define DW_OP_lit17 0x41 #define DW_OP_lit18 0x42 #define DW_OP_lit19 0x43 #define DW_OP_lit20 0x44 #define DW_OP_lit21 0x45 #define DW_OP_lit22 0x46 #define DW_OP_lit23 0x47 #define DW_OP_lit24 0x48 #define DW_OP_lit25 0x49 #define DW_OP_lit26 0x4a #define DW_OP_lit27 0x4b #define DW_OP_lit28 0x4c #define DW_OP_lit29 0x4d #define DW_OP_lit30 0x4e #define DW_OP_lit31 0x4f #define DW_OP_reg0 0x50 #define DW_OP_reg1 0x51 #define DW_OP_reg2 0x52 #define DW_OP_reg3 0x53 #define DW_OP_reg4 0x54 #define DW_OP_reg5 0x55 #define DW_OP_reg6 0x56 #define DW_OP_reg7 0x57 #define DW_OP_reg8 0x58 #define DW_OP_reg9 0x59 #define DW_OP_reg10 0x5a #define DW_OP_reg11 0x5b #define DW_OP_reg12 0x5c #define DW_OP_reg13 0x5d #define DW_OP_reg14 0x5e #define DW_OP_reg15 0x5f #define DW_OP_reg16 0x60 #define DW_OP_reg17 0x61 #define DW_OP_reg18 0x62 #define DW_OP_reg19 0x63 #define DW_OP_reg20 0x64 #define DW_OP_reg21 0x65 #define DW_OP_reg22 0x66 #define DW_OP_reg23 0x67 #define DW_OP_reg24 0x68 #define DW_OP_reg25 0x69 #define DW_OP_reg26 0x6a #define DW_OP_reg27 0x6b #define DW_OP_reg28 0x6c #define DW_OP_reg29 0x6d #define DW_OP_reg30 0x6e #define DW_OP_reg31 0x6f #define DW_OP_breg0 0x70 #define DW_OP_breg1 0x71 #define DW_OP_breg2 0x72 #define DW_OP_breg3 0x73 #define DW_OP_breg4 0x74 #define DW_OP_breg5 0x75 #define DW_OP_breg6 0x76 #define DW_OP_breg7 0x77 #define DW_OP_breg8 0x78 #define DW_OP_breg9 0x79 #define DW_OP_breg10 0x7a #define DW_OP_breg11 0x7b #define DW_OP_breg12 0x7c #define DW_OP_breg13 0x7d #define DW_OP_breg14 0x7e #define DW_OP_breg15 0x7f #define DW_OP_breg16 0x80 #define DW_OP_breg17 0x81 #define DW_OP_breg18 0x82 #define DW_OP_breg19 0x83 #define DW_OP_breg20 0x84 #define DW_OP_breg21 0x85 #define DW_OP_breg22 0x86 #define DW_OP_breg23 0x87 #define DW_OP_breg24 0x88 #define DW_OP_breg25 0x89 #define DW_OP_breg26 0x8a #define DW_OP_breg27 0x8b #define DW_OP_breg28 0x8c #define DW_OP_breg29 0x8d #define DW_OP_breg30 0x8e #define DW_OP_breg31 0x8f #define DW_OP_regx 0x90 #define DW_OP_fbreg 0x91 #define DW_OP_bregx 0x92 #define DW_OP_piece 0x93 #define DW_OP_deref_size 0x94 #define DW_OP_xderef_size 0x95 #define DW_OP_nop 0x96 #define DW_OP_push_object_address 0x97 /* DWARF3 */ #define DW_OP_call2 0x98 /* DWARF3 */ #define DW_OP_call4 0x99 /* DWARF3 */ #define DW_OP_call_ref 0x9a /* DWARF3 */ #define DW_OP_form_tls_address 0x9b /* DWARF3f */ #define DW_OP_call_frame_cfa 0x9c /* DWARF3f */ #define DW_OP_bit_piece 0x9d /* DWARF3f */ #define DW_OP_implicit_value 0x9e /* DWARF4 */ #define DW_OP_stack_value 0x9f /* DWARF4 */ #define DW_OP_implicit_pointer 0xa0 /* DWARF5 */ #define DW_OP_addrx 0xa1 /* DWARF5 */ #define DW_OP_constx 0xa2 /* DWARF5 */ #define DW_OP_entry_value 0xa3 /* DWARF5 */ #define DW_OP_const_type 0xa4 /* DWARF5 */ #define DW_OP_regval_type 0xa5 /* DWARF5 */ #define DW_OP_deref_type 0xa6 /* DWARF5 */ #define DW_OP_xderef_type 0xa7 /* DWARF5 */ #define DW_OP_convert 0xa8 /* DWARF5 */ #define DW_OP_reinterpret 0xa9 /* DWARF5 */ /* GNU extensions. */ #define DW_OP_GNU_push_tls_address 0xe0 /* GNU */ /* Follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_OP_lo_user 0xe0 #define DW_OP_GNU_uninit 0xf0 /* GNU */ #define DW_OP_GNU_encoded_addr 0xf1 /* GNU */ #define DW_OP_GNU_implicit_pointer 0xf2 /* GNU */ #define DW_OP_GNU_entry_value 0xf3 /* GNU */ #define DW_OP_GNU_const_type 0xf4 /* GNU */ #define DW_OP_GNU_regval_type 0xf5 /* GNU */ #define DW_OP_GNU_deref_type 0xf6 /* GNU */ #define DW_OP_GNU_convert 0xf7 /* GNU */ #define DW_OP_GNU_reinterpret 0xf9 /* GNU */ #define DW_OP_GNU_parameter_ref 0xfa /* GNU */ #define DW_OP_GNU_addr_index 0xfb /* GNU DebugFission */ #define DW_OP_GNU_const_index 0xfc /* GNU DebugFission */ /* HP extensions. */ #define DW_OP_HP_unknown 0xe0 /* HP conflict: GNU */ #define DW_OP_HP_is_value 0xe1 /* HP */ #define DW_OP_HP_fltconst4 0xe2 /* HP */ #define DW_OP_HP_fltconst8 0xe3 /* HP */ #define DW_OP_HP_mod_range 0xe4 /* HP */ #define DW_OP_HP_unmod_range 0xe5 /* HP */ #define DW_OP_HP_tls 0xe6 /* HP */ #define DW_OP_INTEL_bit_piece 0xe8 /* Intel: made obsolete by DW_OP_bit_piece above. */ /* Apple extension. */ #define DW_OP_APPLE_uninit 0xf0 /* Apple */ #define DW_OP_PGI_omp_thread_num 0xf8 /* PGI (STMicroelectronics) */ #define DW_OP_hi_user 0xff #define DW_ATE_address 0x01 #define DW_ATE_boolean 0x02 #define DW_ATE_complex_float 0x03 #define DW_ATE_float 0x04 #define DW_ATE_signed 0x05 #define DW_ATE_signed_char 0x06 #define DW_ATE_unsigned 0x07 #define DW_ATE_unsigned_char 0x08 #define DW_ATE_imaginary_float 0x09 /* DWARF3 */ #define DW_ATE_packed_decimal 0x0a /* DWARF3f */ #define DW_ATE_numeric_string 0x0b /* DWARF3f */ #define DW_ATE_edited 0x0c /* DWARF3f */ #define DW_ATE_signed_fixed 0x0d /* DWARF3f */ #define DW_ATE_unsigned_fixed 0x0e /* DWARF3f */ #define DW_ATE_decimal_float 0x0f /* DWARF3f */ #define DW_ATE_UTF 0x10 /* DWARF4 */ #define DW_ATE_UCS 0x11 /* DWARF5 */ #define DW_ATE_ASCII 0x12 /* DWARF5 */ /* ALTIUM extensions. x80, x81 */ #define DW_ATE_ALTIUM_fract 0x80 /* ALTIUM __fract type */ /* Follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_ATE_lo_user 0x80 /* Shown here to help dwarfdump build script. */ #define DW_ATE_ALTIUM_accum 0x81 /* ALTIUM __accum type */ /* HP Floating point extensions. */ #define DW_ATE_HP_float80 0x80 /* (80 bit). HP */ #define DW_ATE_HP_complex_float80 0x81 /* Complex (80 bit). HP */ #define DW_ATE_HP_float128 0x82 /* (128 bit). HP */ #define DW_ATE_HP_complex_float128 0x83 /* Complex (128 bit). HP */ #define DW_ATE_HP_floathpintel 0x84 /* (82 bit IA64). HP */ #define DW_ATE_HP_imaginary_float80 0x85 /* HP */ #define DW_ATE_HP_imaginary_float128 0x86 /* HP */ /* Sun extensions */ #define DW_ATE_SUN_interval_float 0x91 #define DW_ATE_SUN_imaginary_float 0x92 /* Obsolete: See DW_ATE_imaginary_float */ #define DW_ATE_hi_user 0xff /* DWARF5 Defaulted Member Encodings. */ #define DW_DEFAULTED_no 0x0 /* DWARF5 */ #define DW_DEFAULTED_in_class 0x1 /* DWARF5 */ #define DW_DEFAULTED_out_of_class 0x2 /* DWARF5 */ #define DW_IDX_compile_unit 0x1 /* DWARF5 */ #define DW_IDX_type_unit 0x2 /* DWARF5 */ #define DW_IDX_die_offset 0x3 /* DWARF5 */ #define DW_IDX_parent 0x4 /* DWARF5 */ #define DW_IDX_type_hash 0x5 /* DWARF5 */ #define DW_IDX_lo_user 0x2000 /* DWARF5 */ #define DW_IDX_hi_user 0x0fff /* DWARF5 */ /* These with not-quite-the-same-names were used in DWARF4 and never official and should not be used by anyone. */ #define DW_LLEX_end_of_list_entry 0x0 /* DWARF4 experimental */ #define DW_LLEX_base_address_selection_entry 0x01 /* DWARF4 experimental */ #define DW_LLEX_start_end_entry 0x02 /* DWARF4 experimental */ #define DW_LLEX_start_length_entry 0x03 /* DWARF4 experimental */ #define DW_LLEX_offset_pair_entry 0x04 /* DWARF4 experimental */ /* DWARF5 Location List Entries in Split Objects */ #define DW_LLE_end_of_list 0x0 /* DWARF5 */ #define DW_LLE_base_addressx 0x01 /* DWARF5 */ #define DW_LLE_startx_endx 0x02 /* DWARF5 */ #define DW_LLE_startx_length 0x03 /* DWARF5 */ #define DW_LLE_offset_pair 0x04 /* DWARF5 */ #define DW_LLE_default_location 0x05 /* DWARF5 */ #define DW_LLE_base_address 0x06 /* DWARF5 */ #define DW_LLE_start_end 0x07 /* DWARF5 */ #define DW_LLE_start_length 0x08 /* DWARF5 */ /* DWARF5 Range List Entries */ #define DW_RLE_end_of_list 0x00 /* DWARF5 */ #define DW_RLE_base_addressx 0x01 /* DWARF5 */ #define DW_RLE_startx_endx 0x02 /* DWARF5 */ #define DW_RLE_startx_length 0x03 /* DWARF5 */ #define DW_RLE_offset_pair 0x04 /* DWARF5 */ #define DW_RLE_base_address 0x05 /* DWARF5 */ #define DW_RLE_start_end 0x06 /* DWARF5 */ #define DW_RLE_start_length 0x07 /* DWARF5 */ /* DWARF5 Unit header unit type encodings */ #define DW_UT_compile 0x01 /* DWARF5 */ #define DW_UT_type 0x02 /* DWARF5 */ #define DW_UT_partial 0x03 /* DWARF5 */ #define DW_UT_skeleton 0x04 /* DWARF5 */ #define DW_UT_split_compile 0x05 /* DWARF5 */ #define DW_UT_split_type 0x06 /* DWARF5 */ #define DW_UT_lo_user 0x80 /* DWARF5 */ #define DW_UT_hi_user 0xff /* DWARF5 */ /* DWARF5 DebugFission object section id values for .dwp object section offsets hash table. 0 is reserved, not used. 2 is actually reserved, not used in DWARF5. But 2 may be seen in some DWARF4 objects. */ #define DW_SECT_INFO 1 /* .debug_info.dwo DWARF5 */ #define DW_SECT_TYPES 2 /* .debug_types.dwo pre-DWARF5 */ #define DW_SECT_ABBREV 3 /* .debug_abbrev.dwo DWARF5 */ #define DW_SECT_LINE 4 /* .debug_line.dwo DWARF5 */ #define DW_SECT_LOCLISTS 5 /* .debug_loclists.dwo DWARF5 */ #define DW_SECT_STR_OFFSETS 6 /* .debug_str_offsets.dwo DWARF5 */ #define DW_SECT_MACRO 7 /* .debug_macro.dwo DWARF5 */ #define DW_SECT_RNGLISTS 8 /* .debug_rnglists.dwo DWARF5 */ /* Decimal Sign codes. */ #define DW_DS_unsigned 0x01 /* DWARF3f */ #define DW_DS_leading_overpunch 0x02 /* DWARF3f */ #define DW_DS_trailing_overpunch 0x03 /* DWARF3f */ #define DW_DS_leading_separate 0x04 /* DWARF3f */ #define DW_DS_trailing_separate 0x05 /* DWARF3f */ /* Endian code name. */ #define DW_END_default 0x00 /* DWARF3f */ #define DW_END_big 0x01 /* DWARF3f */ #define DW_END_little 0x02 /* DWARF3f */ #define DW_END_lo_user 0x40 /* DWARF3f */ #define DW_END_hi_user 0xff /* DWARF3f */ /* For use with DW_TAG_SUN_codeflags If DW_TAG_SUN_codeflags is accepted as a dwarf standard, then standard dwarf ATCF entries start at 0x01 */ #define DW_ATCF_lo_user 0x40 /* SUN */ #define DW_ATCF_SUN_mop_bitfield 0x41 /* SUN */ #define DW_ATCF_SUN_mop_spill 0x42 /* SUN */ #define DW_ATCF_SUN_mop_scopy 0x43 /* SUN */ #define DW_ATCF_SUN_func_start 0x44 /* SUN */ #define DW_ATCF_SUN_end_ctors 0x45 /* SUN */ #define DW_ATCF_SUN_branch_target 0x46 /* SUN */ #define DW_ATCF_SUN_mop_stack_probe 0x47 /* SUN */ #define DW_ATCF_SUN_func_epilog 0x48 /* SUN */ #define DW_ATCF_hi_user 0xff /* SUN */ /* Accessibility code name. */ #define DW_ACCESS_public 0x01 #define DW_ACCESS_protected 0x02 #define DW_ACCESS_private 0x03 /* Visibility code name. */ #define DW_VIS_local 0x01 #define DW_VIS_exported 0x02 #define DW_VIS_qualified 0x03 /* Virtuality code name. */ #define DW_VIRTUALITY_none 0x00 #define DW_VIRTUALITY_virtual 0x01 #define DW_VIRTUALITY_pure_virtual 0x02 #define DW_LANG_C89 0x0001 #define DW_LANG_C 0x0002 #define DW_LANG_Ada83 0x0003 #define DW_LANG_C_plus_plus 0x0004 #define DW_LANG_Cobol74 0x0005 #define DW_LANG_Cobol85 0x0006 #define DW_LANG_Fortran77 0x0007 #define DW_LANG_Fortran90 0x0008 #define DW_LANG_Pascal83 0x0009 #define DW_LANG_Modula2 0x000a #define DW_LANG_Java 0x000b /* DWARF3 */ #define DW_LANG_C99 0x000c /* DWARF3 */ #define DW_LANG_Ada95 0x000d /* DWARF3 */ #define DW_LANG_Fortran95 0x000e /* DWARF3 */ #define DW_LANG_PLI 0x000f /* DWARF3 */ #define DW_LANG_ObjC 0x0010 /* DWARF3f */ #define DW_LANG_ObjC_plus_plus 0x0011 /* DWARF3f */ #define DW_LANG_UPC 0x0012 /* DWARF3f */ #define DW_LANG_D 0x0013 /* DWARF3f */ #define DW_LANG_Python 0x0014 /* DWARF4 */ /* The following 2 are not yet formally approved October 2010, but it seems extremely likely they will be approved as the committee chair agrees these should be ok and no one on the committee has objected. */ #define DW_LANG_OpenCL 0x0015 /* DWARF5 */ #define DW_LANG_Go 0x0016 /* DWARF5 */ #define DW_LANG_Modula3 0x0017 /* DWARF5 */ #define DW_LANG_Haskel 0x0018 /* DWARF5 */ #define DW_LANG_C_plus_plus_03 0x0019 /* DWARF5 */ #define DW_LANG_C_plus_plus_11 0x001a /* DWARF5 */ #define DW_LANG_OCaml 0x001b /* DWARF5 */ #define DW_LANG_Rust 0x001c /* DWARF5 */ #define DW_LANG_C11 0x001d /* DWARF5 */ #define DW_LANG_Swift 0x001e /* DWARF5 */ #define DW_LANG_Julia 0x001f /* DWARF5 */ #define DW_LANG_Dylan 0x0020 /* DWARF5 */ #define DW_LANG_C_plus_plus_14 0x0021 /* DWARF5 */ #define DW_LANG_Fortran03 0x0022 /* DWARF5 */ #define DW_LANG_Fortran08 0x0023 /* DWARF5 */ #define DW_LANG_RenderScript 0x0024 /* DWARF5 */ #define DW_LANG_BLISS 0x0025 /* DWARF5 */ #define DW_LANG_lo_user 0x8000 #define DW_LANG_Mips_Assembler 0x8001 /* MIPS */ #define DW_LANG_Upc 0x8765 /* UPC, use DW_LANG_UPC instead. */ /* ALTIUM extension */ #define DW_LANG_ALTIUM_Assembler 0x9101 /* ALTIUM */ /* Sun extensions */ #define DW_LANG_SUN_Assembler 0x9001 /* SUN */ #define DW_LANG_hi_user 0xffff /* Identifier case name. */ #define DW_ID_case_sensitive 0x00 #define DW_ID_up_case 0x01 #define DW_ID_down_case 0x02 #define DW_ID_case_insensitive 0x03 /* Calling Convention Name. */ #define DW_CC_normal 0x01 #define DW_CC_program 0x02 #define DW_CC_nocall 0x03 #define DW_CC_pass_by_reference 0x04 /* DWARF5 */ #define DW_CC_pass_by_value 0x05 /* DWARF5 */ #define DW_CC_lo_user 0x40 #define DW_CC_GNU_renesas_sh 0x40 /* GNU */ #define DW_CC_GNU_borland_fastcall_i386 0x41 /* GNU */ /* ALTIUM extensions. */ /* Function is an interrupt handler, return address on system stack. */ #define DW_CC_ALTIUM_interrupt 0x65 /* ALTIUM*/ /* Near function model, return address on system stack. */ #define DW_CC_ALTIUM_near_system_stack 0x66 /*ALTIUM */ /* Near function model, return address on user stack. */ #define DW_CC_ALTIUM_near_user_stack 0x67 /* ALTIUM */ /* Huge function model, return address on user stack. */ #define DW_CC_ALTIUM_huge_user_stack 0x68 /* ALTIUM */ #define DW_CC_hi_user 0xff /* Inline Code Name. */ #define DW_INL_not_inlined 0x00 #define DW_INL_inlined 0x01 #define DW_INL_declared_not_inlined 0x02 #define DW_INL_declared_inlined 0x03 /* Ordering Name. */ #define DW_ORD_row_major 0x00 #define DW_ORD_col_major 0x01 /* Discriminant Descriptor Name. */ #define DW_DSC_label 0x00 #define DW_DSC_range 0x01 /* Line number header entry format encodings. DWARF5 */ #define DW_LNCT_path 0x1 /* DWARF5 */ #define DW_LNCT_directory_index 0x2 /* DWARF5 */ #define DW_LNCT_timestamp 0x3 /* DWARF5 */ #define DW_LNCT_size 0x4 /* DWARF5 */ #define DW_LNCT_MD5 0x5 /* DWARF5 */ /* Experimental two-level line tables. Non standard */ #define DW_LNCT_GNU_subprogram_name 0x6 #define DW_LNCT_GNU_decl_file 0x7 #define DW_LNCT_GNU_decl_line 0x8 #define DW_LNCT_lo_user 0x2000 /* DWARF5 */ #define DW_LNCT_hi_user 0x3fff /* DWARF5 */ /* Line number standard opcode name. */ #define DW_LNS_copy 0x01 #define DW_LNS_advance_pc 0x02 #define DW_LNS_advance_line 0x03 #define DW_LNS_set_file 0x04 #define DW_LNS_set_column 0x05 #define DW_LNS_negate_stmt 0x06 #define DW_LNS_set_basic_block 0x07 #define DW_LNS_const_add_pc 0x08 #define DW_LNS_fixed_advance_pc 0x09 #define DW_LNS_set_prologue_end 0x0a /* DWARF3 */ #define DW_LNS_set_epilogue_begin 0x0b /* DWARF3 */ #define DW_LNS_set_isa 0x0c /* DWARF3 */ /* Experimental two-level line tables. NOT STD DWARF5 */ /* Not saying GNU or anything. There are no DW_LNS_lo_user or DW_LNS_hi_user values though. DW_LNS_set_address_from_logical and DW_LNS_set_subprogram being both 0xd to avoid using up more space in the special opcode table. EXPERIMENTAL DW_LNS follow. */ #define DW_LNS_set_address_from_logical 0x0d /* Actuals table only */ #define DW_LNS_set_subprogram 0x0d /* Logicals table only */ #define DW_LNS_inlined_call 0x0e /* Logicals table only */ #define DW_LNS_pop_context 0x0f /* Logicals table only */ /* Line number extended opcode name. */ #define DW_LNE_end_sequence 0x01 #define DW_LNE_set_address 0x02 #define DW_LNE_define_file 0x03 /* DWARF4 and earlier only */ #define DW_LNE_set_discriminator 0x04 /* DWARF4 */ /* HP extensions. */ #define DW_LNE_HP_negate_is_UV_update 0x11 /* 17 HP */ #define DW_LNE_HP_push_context 0x12 /* 18 HP */ #define DW_LNE_HP_pop_context 0x13 /* 19 HP */ #define DW_LNE_HP_set_file_line_column 0x14 /* 20 HP */ #define DW_LNE_HP_set_routine_name 0x15 /* 21 HP */ #define DW_LNE_HP_set_sequence 0x16 /* 22 HP */ #define DW_LNE_HP_negate_post_semantics 0x17 /* 23 HP */ #define DW_LNE_HP_negate_function_exit 0x18 /* 24 HP */ #define DW_LNE_HP_negate_front_end_logical 0x19 /* 25 HP */ #define DW_LNE_HP_define_proc 0x20 /* 32 HP */ #define DW_LNE_HP_source_file_correlation 0x80 /* HP */ #define DW_LNE_lo_user 0x80 /* DWARF3 */ #define DW_LNE_hi_user 0xff /* DWARF3 */ /* These are known values for DW_LNS_set_isa. */ /* These identifiers are not defined by any DWARFn standard. */ #define DW_ISA_UNKNOWN 0 /* The following two are ARM specific. */ #define DW_ISA_ARM_thumb 1 /* ARM ISA */ #define DW_ISA_ARM_arm 2 /* ARM ISA */ /* Macro information, DWARF5 */ #define DW_MACRO_define 0x01 /* DWARF5 */ #define DW_MACRO_undef 0x02 /* DWARF5 */ #define DW_MACRO_start_file 0x03 /* DWARF5 */ #define DW_MACRO_end_file 0x04 /* DWARF5 */ #define DW_MACRO_define_strp 0x05 /* DWARF5 */ #define DW_MACRO_undef_strp 0x06 /* DWARF5 */ #define DW_MACRO_import 0x07 /* DWARF5 */ #define DW_MACRO_define_sup 0x08 /* DWARF5 */ #define DW_MACRO_undef_sup 0x09 /* DWARF5 */ #define DW_MACRO_import_sup 0x0a /* DWARF5 */ #define DW_MACRO_define_strx 0x0b /* DWARF5 */ #define DW_MACRO_undef_strx 0x0c /* DWARF5 */ #define DW_MACRO_lo_user 0xe0 #define DW_MACRO_hi_user 0xff /* Macro information, DWARF2-DWARF4. */ #define DW_MACINFO_define 0x01 #define DW_MACINFO_undef 0x02 #define DW_MACINFO_start_file 0x03 #define DW_MACINFO_end_file 0x04 #define DW_MACINFO_vendor_ext 0xff /* CFA operator compaction (a space saving measure, see the DWARF standard) means DW_CFA_extended and DW_CFA_nop have the same value here. */ #define DW_CFA_advance_loc 0x40 #define DW_CFA_offset 0x80 #define DW_CFA_restore 0xc0 #define DW_CFA_extended 0 #define DW_CFA_nop 0x00 #define DW_CFA_set_loc 0x01 #define DW_CFA_advance_loc1 0x02 #define DW_CFA_advance_loc2 0x03 #define DW_CFA_advance_loc4 0x04 #define DW_CFA_offset_extended 0x05 #define DW_CFA_restore_extended 0x06 #define DW_CFA_undefined 0x07 #define DW_CFA_same_value 0x08 #define DW_CFA_register 0x09 #define DW_CFA_remember_state 0x0a #define DW_CFA_restore_state 0x0b #define DW_CFA_def_cfa 0x0c #define DW_CFA_def_cfa_register 0x0d #define DW_CFA_def_cfa_offset 0x0e #define DW_CFA_def_cfa_expression 0x0f /* DWARF3 */ #define DW_CFA_expression 0x10 /* DWARF3 */ #define DW_CFA_offset_extended_sf 0x11 /* DWARF3 */ #define DW_CFA_def_cfa_sf 0x12 /* DWARF3 */ #define DW_CFA_def_cfa_offset_sf 0x13 /* DWARF3 */ #define DW_CFA_val_offset 0x14 /* DWARF3f */ #define DW_CFA_val_offset_sf 0x15 /* DWARF3f */ #define DW_CFA_val_expression 0x16 /* DWARF3f */ #define DW_CFA_lo_user 0x1c #define DW_CFA_low_user 0x1c /* Incorrect spelling, do not use. */ /* SGI/MIPS extension. */ #define DW_CFA_MIPS_advance_loc8 0x1d /* MIPS */ /* GNU extensions. */ #define DW_CFA_GNU_window_save 0x2d /* GNU */ #define DW_CFA_GNU_args_size 0x2e /* GNU */ #define DW_CFA_GNU_negative_offset_extended 0x2f /* GNU */ /* Metaware if HC is augmentation, apparently meaning High C and the op has a single uleb operand. See http://sourceforge.net/p/elftoolchain/tickets/397/ */ #define DW_CFA_METAWARE_info 0x34 #define DW_CFA_high_user 0x3f /* GNU exception header encoding. See the Generic Elf Specification of the Linux Standard Base (LSB). http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html The upper 4 bits indicate how the value is to be applied. The lower 4 bits indicate the format of the data. These identifiers are not defined by any DWARFn standard. */ #define DW_EH_PE_absptr 0x00 /* GNU */ #define DW_EH_PE_uleb128 0x01 /* GNU */ #define DW_EH_PE_udata2 0x02 /* GNU */ #define DW_EH_PE_udata4 0x03 /* GNU */ #define DW_EH_PE_udata8 0x04 /* GNU */ #define DW_EH_PE_sleb128 0x09 /* GNU */ #define DW_EH_PE_sdata2 0x0A /* GNU */ #define DW_EH_PE_sdata4 0x0B /* GNU */ #define DW_EH_PE_sdata8 0x0C /* GNU */ #define DW_EH_PE_pcrel 0x10 /* GNU */ #define DW_EH_PE_textrel 0x20 /* GNU */ #define DW_EH_PE_datarel 0x30 /* GNU */ #define DW_EH_PE_funcrel 0x40 /* GNU */ #define DW_EH_PE_aligned 0x50 /* GNU */ #define DW_EH_PE_omit 0xff /* GNU. Means no value present. */ /* Mapping from machine registers and pseudo-regs into the .debug_frame table. DW_FRAME entries are machine specific. These describe MIPS/SGI R3000, R4K, R4400 and all later MIPS/SGI IRIX machines. They describe a mapping from hardware register number to the number used in the table to identify that register. The CFA (Canonical Frame Address) described in DWARF is called the Virtual Frame Pointer on MIPS/SGI machines. The DW_FRAME* names here are MIPS/SGI specific. Libdwarf interfaces defined in 2008 make the frame definitions here (and the fixed table sizes they imply) obsolete. They are left here for compatibility. */ /* Default column used for CFA in the libdwarf reader client. Assumes reg 0 never appears as a register in DWARF information. Usable for MIPS, but never a good idea, really. */ /* These identifiers are not defined by any DWARFn standard. */ #define DW_FRAME_CFA_COL 0 #define DW_FRAME_REG1 1 /* integer reg 1 */ #define DW_FRAME_REG2 2 /* integer reg 2 */ #define DW_FRAME_REG3 3 /* integer reg 3 */ #define DW_FRAME_REG4 4 /* integer reg 4 */ #define DW_FRAME_REG5 5 /* integer reg 5 */ #define DW_FRAME_REG6 6 /* integer reg 6 */ #define DW_FRAME_REG7 7 /* integer reg 7 */ #define DW_FRAME_REG8 8 /* integer reg 8 */ #define DW_FRAME_REG9 9 /* integer reg 9 */ #define DW_FRAME_REG10 10 /* integer reg 10 */ #define DW_FRAME_REG11 11 /* integer reg 11 */ #define DW_FRAME_REG12 12 /* integer reg 12 */ #define DW_FRAME_REG13 13 /* integer reg 13 */ #define DW_FRAME_REG14 14 /* integer reg 14 */ #define DW_FRAME_REG15 15 /* integer reg 15 */ #define DW_FRAME_REG16 16 /* integer reg 16 */ #define DW_FRAME_REG17 17 /* integer reg 17 */ #define DW_FRAME_REG18 18 /* integer reg 18 */ #define DW_FRAME_REG19 19 /* integer reg 19 */ #define DW_FRAME_REG20 20 /* integer reg 20 */ #define DW_FRAME_REG21 21 /* integer reg 21 */ #define DW_FRAME_REG22 22 /* integer reg 22 */ #define DW_FRAME_REG23 23 /* integer reg 23 */ #define DW_FRAME_REG24 24 /* integer reg 24 */ #define DW_FRAME_REG25 25 /* integer reg 25 */ #define DW_FRAME_REG26 26 /* integer reg 26 */ #define DW_FRAME_REG27 27 /* integer reg 27 */ #define DW_FRAME_REG28 28 /* integer reg 28 */ #define DW_FRAME_REG29 29 /* integer reg 29 */ #define DW_FRAME_REG30 30 /* integer reg 30 */ #define DW_FRAME_REG31 31 /* integer reg 31, aka ra */ /* MIPS1, 2 have only some of these 64-bit registers. ** MIPS1 save/restore takes 2 instructions per 64-bit reg, and ** in that case, the register is considered stored after the second ** swc1. */ #define DW_FRAME_FREG0 32 /* 64-bit floating point reg 0 */ #define DW_FRAME_FREG1 33 /* 64-bit floating point reg 1 */ #define DW_FRAME_FREG2 34 /* 64-bit floating point reg 2 */ #define DW_FRAME_FREG3 35 /* 64-bit floating point reg 3 */ #define DW_FRAME_FREG4 36 /* 64-bit floating point reg 4 */ #define DW_FRAME_FREG5 37 /* 64-bit floating point reg 5 */ #define DW_FRAME_FREG6 38 /* 64-bit floating point reg 6 */ #define DW_FRAME_FREG7 39 /* 64-bit floating point reg 7 */ #define DW_FRAME_FREG8 40 /* 64-bit floating point reg 8 */ #define DW_FRAME_FREG9 41 /* 64-bit floating point reg 9 */ #define DW_FRAME_FREG10 42 /* 64-bit floating point reg 10 */ #define DW_FRAME_FREG11 43 /* 64-bit floating point reg 11 */ #define DW_FRAME_FREG12 44 /* 64-bit floating point reg 12 */ #define DW_FRAME_FREG13 45 /* 64-bit floating point reg 13 */ #define DW_FRAME_FREG14 46 /* 64-bit floating point reg 14 */ #define DW_FRAME_FREG15 47 /* 64-bit floating point reg 15 */ #define DW_FRAME_FREG16 48 /* 64-bit floating point reg 16 */ #define DW_FRAME_FREG17 49 /* 64-bit floating point reg 17 */ #define DW_FRAME_FREG18 50 /* 64-bit floating point reg 18 */ #define DW_FRAME_FREG19 51 /* 64-bit floating point reg 19 */ #define DW_FRAME_FREG20 52 /* 64-bit floating point reg 20 */ #define DW_FRAME_FREG21 53 /* 64-bit floating point reg 21 */ #define DW_FRAME_FREG22 54 /* 64-bit floating point reg 22 */ #define DW_FRAME_FREG23 55 /* 64-bit floating point reg 23 */ #define DW_FRAME_FREG24 56 /* 64-bit floating point reg 24 */ #define DW_FRAME_FREG25 57 /* 64-bit floating point reg 25 */ #define DW_FRAME_FREG26 58 /* 64-bit floating point reg 26 */ #define DW_FRAME_FREG27 59 /* 64-bit floating point reg 27 */ #define DW_FRAME_FREG28 60 /* 64-bit floating point reg 28 */ #define DW_FRAME_FREG29 61 /* 64-bit floating point reg 29 */ #define DW_FRAME_FREG30 62 /* 64-bit floating point reg 30 */ #define DW_FRAME_FREG31 63 /* 64-bit floating point reg 31 */ #define DW_FRAME_FREG32 64 /* 64-bit floating point reg 32 */ #define DW_FRAME_FREG33 65 /* 64-bit floating point reg 33 */ #define DW_FRAME_FREG34 66 /* 64-bit floating point reg 34 */ #define DW_FRAME_FREG35 67 /* 64-bit floating point reg 35 */ #define DW_FRAME_FREG36 68 /* 64-bit floating point reg 36 */ #define DW_FRAME_FREG37 69 /* 64-bit floating point reg 37 */ #define DW_FRAME_FREG38 70 /* 64-bit floating point reg 38 */ #define DW_FRAME_FREG39 71 /* 64-bit floating point reg 39 */ #define DW_FRAME_FREG40 72 /* 64-bit floating point reg 40 */ #define DW_FRAME_FREG41 73 /* 64-bit floating point reg 41 */ #define DW_FRAME_FREG42 74 /* 64-bit floating point reg 42 */ #define DW_FRAME_FREG43 75 /* 64-bit floating point reg 43 */ #define DW_FRAME_FREG44 76 /* 64-bit floating point reg 44 */ #define DW_FRAME_FREG45 77 /* 64-bit floating point reg 45 */ #define DW_FRAME_FREG46 78 /* 64-bit floating point reg 46 */ #define DW_FRAME_FREG47 79 /* 64-bit floating point reg 47 */ #define DW_FRAME_FREG48 80 /* 64-bit floating point reg 48 */ #define DW_FRAME_FREG49 81 /* 64-bit floating point reg 49 */ #define DW_FRAME_FREG50 82 /* 64-bit floating point reg 50 */ #define DW_FRAME_FREG51 83 /* 64-bit floating point reg 51 */ #define DW_FRAME_FREG52 84 /* 64-bit floating point reg 52 */ #define DW_FRAME_FREG53 85 /* 64-bit floating point reg 53 */ #define DW_FRAME_FREG54 86 /* 64-bit floating point reg 54 */ #define DW_FRAME_FREG55 87 /* 64-bit floating point reg 55 */ #define DW_FRAME_FREG56 88 /* 64-bit floating point reg 56 */ #define DW_FRAME_FREG57 89 /* 64-bit floating point reg 57 */ #define DW_FRAME_FREG58 90 /* 64-bit floating point reg 58 */ #define DW_FRAME_FREG59 91 /* 64-bit floating point reg 59 */ #define DW_FRAME_FREG60 92 /* 64-bit floating point reg 60 */ #define DW_FRAME_FREG61 93 /* 64-bit floating point reg 61 */ #define DW_FRAME_FREG62 94 /* 64-bit floating point reg 62 */ #define DW_FRAME_FREG63 95 /* 64-bit floating point reg 63 */ #define DW_FRAME_FREG64 96 /* 64-bit floating point reg 64 */ #define DW_FRAME_FREG65 97 /* 64-bit floating point reg 65 */ #define DW_FRAME_FREG66 98 /* 64-bit floating point reg 66 */ #define DW_FRAME_FREG67 99 /* 64-bit floating point reg 67 */ #define DW_FRAME_FREG68 100 /* 64-bit floating point reg 68 */ #define DW_FRAME_FREG69 101 /* 64-bit floating point reg 69 */ #define DW_FRAME_FREG70 102 /* 64-bit floating point reg 70 */ #define DW_FRAME_FREG71 103 /* 64-bit floating point reg 71 */ #define DW_FRAME_FREG72 104 /* 64-bit floating point reg 72 */ #define DW_FRAME_FREG73 105 /* 64-bit floating point reg 73 */ #define DW_FRAME_FREG74 106 /* 64-bit floating point reg 74 */ #define DW_FRAME_FREG75 107 /* 64-bit floating point reg 75 */ #define DW_FRAME_FREG76 108 /* 64-bit floating point reg 76 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** The following 4 #defines are dependent on the target cpu(s) that you apply libdwarf to. Ensure that DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL do not conflict with the range [0-DW_FRAME_STATIC_LINK]. The value 63 works for MIPS cpus at least up to the R16000. For a cpu with more than 63 real registers DW_FRAME_HIGHEST_NORMAL_REGISTER must be increased for things to work properly! Also ensure that DW_FRAME_UNDEFINED_VAL DW_FRAME_SAME_VAL are not in the range [0-DW_FRAME_STATIC_LINK] Having DW_FRAME_HIGHEST_NORMAL_REGISTER be higher than is strictly needed is safe. */ #ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER #define DW_FRAME_HIGHEST_NORMAL_REGISTER 188 #endif /* This is the number of columns in the Frame Table. This constant should be kept in sync with DW_REG_TABLE_SIZE defined in libdwarf.h It must also be large enough to be beyond the highest compiler-defined-register (meaning DW_FRAME_RA_COL DW_FRAME_STATIC_LINK in the MIPS/IRIX case */ #ifndef DW_FRAME_LAST_REG_NUM #define DW_FRAME_LAST_REG_NUM (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3) #endif /* Column recording ra (return address from a function call). This is common to many architectures, but as a 'simple register' is not necessarily adequate for all architectures. For MIPS/IRIX this register number is actually recorded on disk in the .debug_frame section. */ #define DW_FRAME_RA_COL (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1) /* Column recording static link applicable to up-level addressing, as in IRIX mp code, pascal, etc. This is common to many architectures but is not necessarily adequate for all architectures. For MIPS/IRIX this register number is actually recorded on disk in the .debug_frame section. */ #define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2) /* DW_FRAME_UNDEFINED_VAL and DW_FRAME_SAME_VAL are never on disk, just generated by libdwarf. See libdwarf.h for their values. */ #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 #define DW_ADDR_none 0 #ifdef __cplusplus } #endif #endif /* __DWARF_H */ dwarfutils-20200114/libdwarf/dwarf_abbrev.c000066400000000000000000000324051361531463500205260ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_abbrev.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #define TRUE 1 #define FALSE 0 /* This is used to print a .debug_abbrev section without knowing about the DIEs that use the abbrevs. dwarf_get_abbrev() and, in dwarf_util.c, _dwarf_get_abbrev_for_code() When we have a simple .o there is at least a hope of iterating through the abbrevs meaningfully without knowing a CU context. This often fails or gets incorrect info because there is no guarantee the .debug_abbrev section is free of garbage bytes. In an object with multiple CU/TUs the output is difficult/impossible to usefully interpret. In a dwp (Package File) it is really impossible to associate abbrevs with a CU. */ int _dwarf_count_abbrev_entries(Dwarf_Debug dbg, Dwarf_Byte_Ptr abbrev_ptr, Dwarf_Byte_Ptr abbrev_section_end, Dwarf_Unsigned *abbrev_count_out, Dwarf_Byte_Ptr *abbrev_ptr_out, Dwarf_Error *error) { Dwarf_Unsigned abbrev_count = 0; Dwarf_Unsigned attr_name = 0; Dwarf_Unsigned attr_form = 0; UNUSEDARG Dwarf_Unsigned implicit_const = 0; /* The abbreviations table ends with an entry with a single byte of zero for the abbreviation code. Padding bytes following that zero are allowed, but here we simply stop looking past that zero abbrev. We also stop looking if the block/section ends, though the DWARF2 and later standards do not specifically allow section/block end to terminate an abbreviations list. */ do { DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_name, dbg,error,abbrev_section_end); if (attr_name > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_form, dbg,error,abbrev_section_end); if (!_dwarf_valid_form_we_know(attr_form,attr_name)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return (DW_DLV_ERROR); } if (attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, dbg,error,abbrev_section_end); } abbrev_count++; } while ((abbrev_ptr < abbrev_section_end) && (attr_name != 0 || attr_form != 0)); /* We counted one too high,we included the 0,0 */ *abbrev_count_out = abbrev_count-1; *abbrev_ptr_out = abbrev_ptr; return DW_DLV_OK; } int dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Abbrev * returned_abbrev, Dwarf_Unsigned * length, Dwarf_Unsigned * abbr_count, Dwarf_Error * error) { Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_ptr_out = 0; Dwarf_Byte_Ptr abbrev_section_end = 0; Dwarf_Abbrev ret_abbrev = 0; Dwarf_Unsigned labbr_count = 0; Dwarf_Unsigned utmp = 0; int res = 0; if (!dbg) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (dbg->de_debug_abbrev.dss_data == 0) { /* Loads abbrev section (and .debug_info as we do those together). */ res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } if (offset >= dbg->de_debug_abbrev.dss_size) { return DW_DLV_NO_ENTRY; } ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1); if (ret_abbrev == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } ret_abbrev->dab_dbg = dbg; if (returned_abbrev == 0 || abbr_count == 0) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *abbr_count = 0; if (length) { *length = 1; } abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset; abbrev_section_end = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, dbg,error,abbrev_section_end); ret_abbrev->dab_code = utmp; if (ret_abbrev->dab_code == 0) { *returned_abbrev = ret_abbrev; *abbr_count = 0; if (length) { *length = 1; } return DW_DLV_OK; } DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, dbg,error,abbrev_section_end); if (utmp > DW_TAG_hi_user) { _dwarf_error(dbg, error,DW_DLE_TAG_CORRUPT); return DW_DLV_ERROR; } ret_abbrev->dab_tag = utmp; if (abbrev_ptr >= abbrev_section_end) { _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return DW_DLV_ERROR; } ret_abbrev->dab_has_child = *(abbrev_ptr++); ret_abbrev->dab_abbrev_ptr = abbrev_ptr; ret_abbrev->dab_next_ptr = abbrev_ptr; ret_abbrev->dab_next_index = 0; res = _dwarf_count_abbrev_entries(dbg,abbrev_ptr, abbrev_section_end,&labbr_count,&abbrev_ptr_out,error); if (res == DW_DLV_ERROR) { return res; } abbrev_ptr = abbrev_ptr_out; /* Global section offset. */ ret_abbrev->dab_goffset = offset; ret_abbrev->dab_count = labbr_count; if (abbrev_ptr > abbrev_section_end) { dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return DW_DLV_ERROR; } if (length) { *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset; } *returned_abbrev = ret_abbrev; *abbr_count = labbr_count; return DW_DLV_OK; } int dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned * returned_code, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } *returned_code = abbrev->dab_code; return (DW_DLV_OK); } /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be over 16 bits. */ int dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half * returned_tag, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } *returned_tag = abbrev->dab_tag; return (DW_DLV_OK); } int dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed * returned_flag, Dwarf_Error * error) { if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } *returned_flag = abbrev->dab_has_child; return (DW_DLV_OK); } /* This does not return the implicit const, nor does it return all bits of the uleb attribute nor does it return all bits of the uleb form value. Ugh. FIXME by providing a better function. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed indx, Dwarf_Half * returned_attr_num, Dwarf_Signed * returned_form, Dwarf_Off * returned_offset, Dwarf_Error * error) { int res; Dwarf_Unsigned attr = 0; Dwarf_Unsigned form = 0; Dwarf_Signed implicitconst = 0; Dwarf_Unsigned uindex = (Dwarf_Unsigned)indx; Dwarf_Bool filter_outliers = TRUE; res = dwarf_get_abbrev_entry_b(abbrev, uindex, filter_outliers, &attr, &form, &implicitconst, returned_offset, error); if (res != DW_DLV_OK) { return res; } /* returned_offset already set by dwarf_get_abbrev_entry_b; */ if (returned_attr_num) { *returned_attr_num = (Dwarf_Half)attr; } if (returned_form) { *returned_form = (Dwarf_Signed)form; } return DW_DLV_OK; } /* If filter_outliers is non-zero then the routine will return DW_DLV_ERROR if the leb reading generates a number that is so large it cannot be correct. If filter_outliers is 0 the uleb/sleb values read are returned, even if the values are unreasonable. This is a useful option if one wishes to have callers examine the return values in greater detail than the checking here provides. */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned indx, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implicitconst, Dwarf_Off * offset, Dwarf_Error * error) { Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Byte_Ptr mark_abbrev_ptr = 0; Dwarf_Unsigned attr = 0; Dwarf_Unsigned form = 0; Dwarf_Unsigned implicitconst = 0; Dwarf_Debug dbg = 0; Dwarf_Signed local_indx = (Dwarf_Signed)indx; if (abbrev == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); return (DW_DLV_ERROR); } if (abbrev->dab_code == 0) { return (DW_DLV_NO_ENTRY); } if (abbrev->dab_dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } dbg = abbrev->dab_dbg; abbrev_ptr = abbrev->dab_abbrev_ptr; abbrev_end = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; if ((Dwarf_Unsigned)local_indx >= abbrev->dab_next_index) { /* We want a part not yet scanned , so we can start closer to the desired value. */ abbrev_ptr = abbrev->dab_next_ptr; local_indx -= abbrev->dab_next_index; } for (attr = 1, form = 1; local_indx >= 0 && abbrev_ptr < abbrev_end && (attr != 0 || form != 0); local_indx--) { mark_abbrev_ptr = abbrev_ptr; DECODE_LEB128_UWORD_CK(abbrev_ptr, attr,dbg, error,abbrev_end); if (filter_outliers && attr > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(abbrev_ptr, form,dbg, error,abbrev_end); if (filter_outliers && !_dwarf_valid_form_we_know(form,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return (DW_DLV_ERROR); } if (form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK( abbrev_ptr, implicitconst, dbg,error,abbrev_end); } else { implicitconst = 0; } } if (abbrev_ptr >= abbrev_end) { _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return DW_DLV_ERROR; } if (local_indx >= 0) { return DW_DLV_NO_ENTRY; } if (returned_form != NULL) { *returned_form = form; } if (offset != NULL) { *offset = mark_abbrev_ptr - dbg->de_debug_abbrev.dss_data; } if (returned_attr_num) { *returned_attr_num = attr; } if (returned_implicitconst) { /* Callers should only examine implict const value if the form is DW_FORM_implicit_const. */ *returned_implicitconst = implicitconst; } abbrev->dab_next_ptr = abbrev_ptr; abbrev->dab_next_index = (Dwarf_Unsigned)local_indx ; return DW_DLV_OK; } /* This function is not entirely safe to call. The problem is that the DWARF[234] specification does not insist that bytes in .debug_abbrev that are not referenced by .debug_info or .debug_types need to be initialized to anything specific. Any garbage bytes may cause trouble. Not all compilers/linkers leave unreferenced garbage bytes in .debug_abbrev, so this may work for most objects. In case of error could return a bogus value, there is no documented way to detect error. */ int dwarf_get_abbrev_count(Dwarf_Debug dbg) { Dwarf_Abbrev ab; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned attr_count = 0; Dwarf_Unsigned abbrev_count = 0; int abres = DW_DLV_OK; Dwarf_Error err = 0; while ((abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &attr_count, &err)) == DW_DLV_OK) { ++abbrev_count; offset += length; dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); } if (err) { dwarf_dealloc(dbg,err,DW_DLA_ERROR); err = 0; } return abbrev_count; } dwarfutils-20200114/libdwarf/dwarf_abbrev.h000066400000000000000000000047211361531463500205330ustar00rootroot00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* In a given CU, one of these is (eventually) set up for every abbreviation we need to find (and for all. those ealier in the abbreviations for that CU). So we don't want elements needlessly big. */ struct Dwarf_Abbrev_s { /* No TAG should exceed DW_TAG_hi_user, 0xffff, but we do allow a larger value here. */ Dwarf_Unsigned dab_tag; /* Abbreviations are numbered (normally sequentially from 1 and so 16 bits is not enough! */ Dwarf_Unsigned dab_code; Dwarf_Small dab_has_child; /* dab_abbrev_ptr points to the abbreviations themselves in memory, the list of attr/form integers terminated by 0,0. */ Dwarf_Byte_Ptr dab_abbrev_ptr; Dwarf_Debug dab_dbg; /* Section global offset of the abbrev. */ Dwarf_Off dab_goffset; /* dab_count is the number of attr/form uleb pairs */ Dwarf_Off dab_count; /* When the caller cycles through attr/form pairs by index from zero this lets the code read just one pair to work. */ Dwarf_Byte_Ptr dab_next_ptr; Dwarf_Unsigned dab_next_index; }; int _dwarf_count_abbrev_entries(Dwarf_Debug dbg, Dwarf_Byte_Ptr abbrev_ptr, Dwarf_Byte_Ptr abbrev_section_end, Dwarf_Unsigned *abbrev_count_out, Dwarf_Byte_Ptr *abbrev_ptr_out, Dwarf_Error *error); dwarfutils-20200114/libdwarf/dwarf_alloc.c000066400000000000000000000615231361531463500203620ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #undef DEBUG #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_alloc.h" /* These files are included to get the sizes of structs for malloc. */ #include "dwarf_util.h" #include "dwarf_line.h" #include "dwarf_global.h" #include "dwarf_arange.h" #include "dwarf_abbrev.h" #include "dwarf_die_deliv.h" #include "dwarf_frame.h" #include "dwarf_loc.h" #include "dwarf_funcs.h" #include "dwarf_types.h" #include "dwarf_vars.h" #include "dwarf_weaks.h" #include "dwarf_harmless.h" #include "dwarf_tsearch.h" #include "dwarf_gdbindex.h" #include "dwarf_xu_index.h" #include "dwarf_macro5.h" #include "dwarf_dnames.h" #include "dwarf_dsc.h" #include "dwarfstring.h" #include "dwarf_str_offsets.h" #define TRUE 1 #define FALSE 0 /* Some allocations are simple some not. These reduce the issue of determining which sort of thing to a simple test. See ia_multiply_count Usually when MULTIPLY_NO is set the count is 1, so MULTIPY_CT would work as well. */ #define MULTIPLY_NO 0 #define MULTIPLY_CT 1 #define MULTIPLY_SP 2 /* This translates into de_alloc_hdr into a per-instance size and allows room for a constructor/destructor pointer. Rearranging the DW_DLA values would break binary compatibility so that is not an option. */ struct ial_s { /* In bytes, one struct instance. */ short ia_struct_size; /* Not a count, but a MULTIPLY{_NO,_CT,_SP} value. */ short ia_multiply_count; /* When we really need a constructor/destructor these make applying such quite simple. */ int (*specialconstructor) (Dwarf_Debug, void *); void (*specialdestructor) (void *); }; /* Used as a way to return meaningful errors when the malloc arena is exhausted (when malloc returns NULL). Not normally used. New in December 2014.*/ struct Dwarf_Error_s _dwarf_failsafe_error = { DW_DLE_FAILSAFE_ERRVAL, 0, 1 }; void _dwarf_error_destructor(void *m) { Dwarf_Error er = (Dwarf_Error)m; dwarfstring *erm = (dwarfstring *)er->er_msg; if (! erm) { return; } dwarfstring_destructor(erm); free(erm); er->er_msg = 0; return; } /* To do destructors we need some extra data in every _dwarf_get_alloc situation. */ /* Here is the extra we malloc for a prefix. */ struct reserve_size_s { void *dummy_rsv1; void *dummy_rsv2; }; /* Here is how we use the extra prefix area. */ struct reserve_data_s { void *rd_dbg; unsigned short rd_length; unsigned short rd_type; }; #define DW_RESERVE sizeof(struct reserve_size_s) static const struct ial_s alloc_instance_basics[ALLOC_AREA_INDEX_TABLE_MAX] = { { 1,MULTIPLY_NO, 0, 0}, /* 0 none */ { 1,MULTIPLY_CT, 0, 0}, /* 1 DW_DLA_STRING */ { sizeof(Dwarf_Loc),MULTIPLY_NO, 0, 0} ,/* 2 DW_DLA_LOC */ { sizeof(Dwarf_Locdesc),MULTIPLY_NO, 0, 0} , /* 3 DW_DLA_LOCDESC */ { 1,MULTIPLY_NO, 0, 0} , /* not used *//* 4 DW_DLA_ELLIST */ { 1,MULTIPLY_NO, 0, 0} , /* not used *//* 5 DW_DLA_BOUNDS */ { sizeof(Dwarf_Block),MULTIPLY_NO, 0, 0} , /* 6 DW_DLA_BLOCK */ /* the actual dwarf_debug structure */ /* 7 DW_DLA_DEBUG */ { 1,MULTIPLY_NO, 0, 0} , {sizeof(struct Dwarf_Die_s),MULTIPLY_NO, 0, 0},/* 8 DW_DLA_DIE */ {sizeof(struct Dwarf_Line_s),MULTIPLY_NO, 0, 0},/* 9 DW_DLA_LINE */ /* 10 DW_DLA_ATTR */ {sizeof(struct Dwarf_Attribute_s),MULTIPLY_NO, 0, 0}, {1,MULTIPLY_NO, 0, 0}, /* not used */ /* 11 DW_DLA_TYPE */ {1,MULTIPLY_NO, 0, 0}, /* not used */ /* 12 DW_DLA_SUBSCR */ /* 13 DW_DLA_GLOBAL */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 14 DW_DLA_ERROR */ {sizeof(struct Dwarf_Error_s),MULTIPLY_NO, 0, _dwarf_error_destructor}, {sizeof(Dwarf_Ptr),MULTIPLY_CT, 0, 0}, /* 15 DW_DLA_LIST */ {1,MULTIPLY_NO, 0, 0}, /* not used *//* 16 DW_DLA_LINEBUF */ /* 17 DW_DLA_ARANGE */ {sizeof(struct Dwarf_Arange_s),MULTIPLY_NO, 0, 0}, /* 18 DW_DLA_ABBREV */ {sizeof(struct Dwarf_Abbrev_s),MULTIPLY_NO, 0, 0}, /* 19 DW_DLA_FRAME_OP */ {sizeof(Dwarf_Frame_Op),MULTIPLY_NO, 0, 0} , /* 20 DW_DLA_CIE */ {sizeof(struct Dwarf_Cie_s),MULTIPLY_NO, 0, 0}, {sizeof(struct Dwarf_Fde_s),MULTIPLY_NO, 0, _dwarf_fde_destructor},/* 21 DW_DLA_FDE */ {sizeof(Dwarf_Loc),MULTIPLY_CT, 0, 0}, /* 22 DW_DLA_LOC_BLOCK */ {sizeof(Dwarf_Frame_Op),MULTIPLY_CT, 0, 0}, /* 23 DW_DLA_FRAME_BLOCK */ /* 24 DW_DLA_FUNC UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 25 DW_DLA_TYPENAME UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 26 DW_DLA_VAR UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, /* 27 DW_DLA_WEAK UNUSED */ {sizeof(struct Dwarf_Global_s),MULTIPLY_NO, 0, 0}, {1,MULTIPLY_SP, 0, 0}, /* 28 DW_DLA_ADDR */ {sizeof(Dwarf_Ranges),MULTIPLY_CT, 0,0 }, /* 29 DW_DLA_RANGES */ /* The following DW_DLA data types are known only inside libdwarf. */ /* 30 DW_DLA_ABBREV_LIST */ { sizeof(struct Dwarf_Abbrev_List_s),MULTIPLY_NO, 0, 0}, /* 31 DW_DLA_CHAIN */ {sizeof(struct Dwarf_Chain_s),MULTIPLY_NO, 0, 0}, /* 32 DW_DLA_CU_CONTEXT */ {sizeof(struct Dwarf_CU_Context_s),MULTIPLY_NO, 0, 0}, {sizeof(struct Dwarf_Frame_s),MULTIPLY_NO, _dwarf_frame_constructor, _dwarf_frame_destructor}, /* 33 DW_DLA_FRAME */ /* 34 DW_DLA_GLOBAL_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 35 DW_DLA_FILE_ENTRY */ {sizeof(struct Dwarf_File_Entry_s),MULTIPLY_NO, 0, 0}, /* 36 DW_DLA_LINE_CONTEXT */ {sizeof(struct Dwarf_Line_Context_s),MULTIPLY_NO, _dwarf_line_context_constructor, _dwarf_line_context_destructor}, /* 37 DW_DLA_LOC_CHAIN */ {sizeof(struct Dwarf_Loc_Chain_s),MULTIPLY_NO, 0, 0}, /* 38 0x26 DW_DLA_HASH_TABLE */ {sizeof(struct Dwarf_Hash_Table_s),MULTIPLY_NO, 0, 0}, /* The following really use Global struct: used to be unique struct per type, but now merged (11/99). The opaque types are visible in the interface. The types for DW_DLA_FUNC, DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use the global types. */ /* 39 0x27 DW_DLA_FUNC_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 40 0x28 DW_DLA_TYPENAME_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 41 0x29 DW_DLA_VAR_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 42 0x2a DW_DLA_WEAK_CONTEXT */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 43 0x2b DW_DLA_PUBTYPES_CONTEXT DWARF3 */ {sizeof(struct Dwarf_Global_Context_s),MULTIPLY_NO, 0, 0}, /* 44 0x2c DW_DLA_HASH_TABLE_ENTRY */ {sizeof(struct Dwarf_Hash_Table_Entry_s),MULTIPLY_CT,0,0 }, /* 45 0x2d reserved for future use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* 46 0x2e reserved for future use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ /* 47 0x2f reserved for future use */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ /* 0x30-0x36 reserved for future internal use. */ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ {sizeof(int),MULTIPLY_NO, 0, 0}, /* reserved for future internal types*/ /* now, we have types that are public. */ /* 0x37 55. New in June 2014. Gdb. */ {sizeof(struct Dwarf_Gdbindex_s),MULTIPLY_NO, 0, 0}, /* 0x38 56. New in July 2014. DWARF5 DebugFission dwp file sections .debug_cu_index and .debug_tu_index . */ {sizeof(struct Dwarf_Xu_Index_Header_s),MULTIPLY_NO, 0, 0}, /* These required by new features in DWARF5. Also usable for DWARF2,3,4. */ /* 57 DW_DLA_LOC_BLOCK_C */ {sizeof(struct Dwarf_Loc_c_s),MULTIPLY_CT, 0, 0}, /* 58 DW_DLA_LOCDESC_C */ {sizeof(struct Dwarf_Locdesc_c_s),MULTIPLY_CT, 0, 0}, /* 59 DW_DLA_LOC_HEAD_C */ {sizeof(struct Dwarf_Loc_Head_c_s),MULTIPLY_NO, 0, 0}, /* 60 DW_DLA_MACRO_CONTEXT */ {sizeof(struct Dwarf_Macro_Context_s),MULTIPLY_NO, _dwarf_macro_constructor, _dwarf_macro_destructor}, /* 61 DW_DLA_CHAIN_2 */ {sizeof(struct Dwarf_Chain_o),MULTIPLY_NO, 0, 0}, /* 62 DW_DLA_DSC_HEAD 0x3e */ {sizeof(struct Dwarf_Dsc_Head_s),MULTIPLY_NO, 0, _dwarf_dsc_destructor}, /* 63 DW_DLA_DNAMES_HEAD 0x3f */ {sizeof(struct Dwarf_Dnames_Head_s),MULTIPLY_NO, 0, _dwarf_debugnames_destructor}, /* 64 DW_DLA_STR_OFFSETS 0x40 */ {sizeof(struct Dwarf_Str_Offsets_Table_s),MULTIPLY_NO, 0,0}, }; /* We are simply using the incoming pointer as the key-pointer. */ static DW_TSHASHTYPE simple_value_hashfunc(const void *keyp) { DW_TSHASHTYPE up = (DW_TSHASHTYPE)(uintptr_t)keyp; return up; } /* We did alloc something but not a fixed-length thing. Instead, it starts with some special data we noted. The incoming pointer is to the caller data, we destruct based on caller, but find the special extra data in a prefix area. */ static void tdestroy_free_node(void *nodep) { char * m = (char *)nodep; char * malloc_addr = m - DW_RESERVE; struct reserve_data_s * reserve =(struct reserve_data_s *)malloc_addr; unsigned type = reserve->rd_type; if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* Internal error, corrupted data. */ return; } if(!reserve->rd_dbg) { /* Unused (corrupted?) node in the tree. Should never happen. */ return; } if(!reserve->rd_type) { /* Unused (corrupted?) node in the tree. Should never happen. */ return; } if (alloc_instance_basics[type].specialdestructor) { alloc_instance_basics[type].specialdestructor(m); } free(malloc_addr); } /* The sort of hash table entries result in very simple helper functions. */ static int simple_compare_function(const void *l, const void *r) { DW_TSHASHTYPE lp = (DW_TSHASHTYPE)(uintptr_t)l; DW_TSHASHTYPE rp = (DW_TSHASHTYPE)(uintptr_t)r; if(lp < rp) { return -1; } if(lp > rp) { return 1; } return 0; } /* This function returns a pointer to a region of memory. For alloc_types that are not strings or lists of pointers, only 1 struct can be requested at a time. This is indicated by an input count of 1. For strings, count equals the length of the string it will contain, i.e it the length of the string plus 1 for the terminating null. For lists of pointers, count is equal to the number of pointers. For DW_DLA_FRAME_BLOCK, DW_DLA_RANGES, and DW_DLA_LOC_BLOCK allocation types also, count is the count of the number of structs needed. This function cannot be used to allocate a Dwarf_Debug_s struct. */ char * _dwarf_get_alloc(Dwarf_Debug dbg, Dwarf_Small alloc_type, Dwarf_Unsigned count) { char * alloc_mem = 0; Dwarf_Signed basesize = 0; Dwarf_Signed size = 0; unsigned int type = alloc_type; short action = 0; if (dbg == NULL) { return NULL; } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* internal error */ return NULL; } basesize = alloc_instance_basics[alloc_type].ia_struct_size; action = alloc_instance_basics[alloc_type].ia_multiply_count; if(action == MULTIPLY_NO) { /* Usually count is 1, but do not assume it. */ size = basesize; } else if (action == MULTIPLY_CT) { size = basesize * count; } else { /* MULTIPLY_SP */ /* DW_DLA_ADDR.. count * largest size */ size = count * (sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ? sizeof(Dwarf_Addr) : sizeof(Dwarf_Off)); } size += DW_RESERVE; alloc_mem = malloc(size); if (!alloc_mem) { return NULL; } { char * ret_mem = alloc_mem + DW_RESERVE; void *key = ret_mem; struct reserve_data_s *r = (struct reserve_data_s*)alloc_mem; void *result = 0; memset(alloc_mem, 0, size); /* We are not actually using rd_dbg, we are using rd_type. */ r->rd_dbg = dbg; r->rd_type = alloc_type; r->rd_length = size; if (alloc_instance_basics[type].specialconstructor) { int res = alloc_instance_basics[type].specialconstructor(dbg, ret_mem); if (res != DW_DLV_OK) { /* We leak what we allocated in _dwarf_find_memory when constructor fails. */ return NULL; } } result = dwarf_tsearch((void *)key, &dbg->de_alloc_tree,simple_compare_function); if(!result) { /* Something badly wrong. Out of memory. pretend all is well. */ } return (ret_mem); } } /* This was once a long list of tests using dss_data and dss_size to see if 'space' was inside a debug section. This tfind approach removes that maintenance headache. */ static int string_is_in_debug_section(Dwarf_Debug dbg,void * space) { /* See dwarf_line.c dwarf_srcfiles() for one way we can wind up with a DW_DLA_STRING string that may or may not be malloc-ed by _dwarf_get_alloc(). dwarf_formstring(), for example, returns strings which point into .debug_info or .debug_types but dwarf_dealloc is never supposed to be applied to strings dwarf_formstring() returns! Lots of calls returning strings have always been documented as requiring dwarf_dealloc(...DW_DLA_STRING) when the code just returns a pointer to a portion of a loaded section! It is too late to change the documentation. */ void *result = 0; result = dwarf_tfind((void *)space, &dbg->de_alloc_tree,simple_compare_function); if(!result) { /* Not in the tree, so not malloc-ed Nothing to delete. */ return TRUE; } /* We found the address in the tree, so it is NOT part of .debug_info or any other dwarf section, but is space malloc-d in _dwarf_get_alloc(). */ return FALSE; } /* This function is used to deallocate a region of memory that was obtained by a call to _dwarf_get_alloc. Note that though dwarf_dealloc() is a public function, _dwarf_get_alloc() isn't. For lists, typically arrays of pointers, it is assumed that the space was allocated by a direct call to malloc, and so a straight free() is done. This is also the case for variable length blocks such as DW_DLA_FRAME_BLOCK and DW_DLA_LOC_BLOCK and DW_DLA_RANGES. For strings, the pointer might point to a string in .debug_info or .debug_string. After this is checked, and if found not to be the case, a free() is done, again on the assumption that a malloc was used to obtain the space. This function does not return anything. */ void dwarf_dealloc(Dwarf_Debug dbg, Dwarf_Ptr space, Dwarf_Unsigned alloc_type) { unsigned int type = 0; char * malloc_addr = 0; struct reserve_data_s * r = 0; if (space == NULL) { return; } if (dbg) { /* If it's a string in debug_info etc doing (char *)space - DW_RESERVE is totally bogus. */ if (alloc_type == DW_DLA_STRING && string_is_in_debug_section(dbg,space)) { /* A string pointer may point into .debug_info or .debug_string etc. So must not be freed. And strings have no need of a specialdestructor(). Mostly a historical mistake here. */ return; } /* Otherwise it might be allocated string so it is ok do the (char *)space - DW_RESERVE */ } else { /* App error, or an app that failed to succeed in a dwarf_init() call. */ return; } if (alloc_type == DW_DLA_ERROR) { Dwarf_Error ep = (Dwarf_Error)space; if (ep->er_static_alloc == DE_STATIC) { /* This is special, malloc arena was exhausted or a NULL dbg was used for the error because the real dbg was unavailable. There is nothing to delete, really. Set er_errval to signal that the space was dealloc'd. */ _dwarf_failsafe_error.er_errval = DW_DLE_FAILSAFE_ERRVAL; return; } if (ep->er_static_alloc == DE_MALLOC) { /* This is special, we had no arena so just malloc'd a Dwarf_Error_s. */ free(space); return; } /* Was normal alloc, use normal dealloc. */ } type = alloc_type; malloc_addr = (char *)space - DW_RESERVE; r =(struct reserve_data_s *)malloc_addr; if(dbg != r->rd_dbg) { /* Something is badly wrong. Better to leak than to crash. */ return; } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { /* internal or user app error */ return; } if (alloc_instance_basics[type].specialdestructor) { alloc_instance_basics[type].specialdestructor(space); } { /* The 'space' pointer we get points after the reserve space. The key and address to free are just a few bytes before 'space'. */ void *key = space; dwarf_tdelete(key,&dbg->de_alloc_tree,simple_compare_function); /* If dwarf_tdelete returns NULL it might mean a) tree is empty. b) If hashsearch, then a single chain might now be empty, so we do not know of a 'parent node'. c) We did not find that key, we did nothing. In any case, we simply don't worry about it. Not Supposed To Happen. */ free(malloc_addr); return; } } /* Allocates space for a Dwarf_Debug_s struct, since one does not exist. */ Dwarf_Debug _dwarf_get_debug(void) { Dwarf_Debug dbg; dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); if (dbg == NULL) { return (NULL); } memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); /* Set up for a dwarf_tsearch hash table */ dwarf_initialize_search_hash(&dbg->de_alloc_tree,simple_value_hashfunc,0); return (dbg); } /* This function prints out the statistics collected on allocation of memory chunks. No longer used. */ void dwarf_print_memory_stats(UNUSEDARG Dwarf_Debug dbg) { } /* In the 'rela' relocation case we might have malloc'd space to ensure it is read-write. In that case, free the space. */ static void rela_free(struct Dwarf_Section_s * sec) { if (sec->dss_data_was_malloc) { free(sec->dss_data); } sec->dss_data = 0; sec->dss_data_was_malloc = 0; } static void freecontextlist(Dwarf_Debug dbg, Dwarf_Debug_InfoTypes dis) { Dwarf_CU_Context context = 0; Dwarf_CU_Context nextcontext = 0; for (context = dis->de_cu_context_list; context; context = nextcontext) { Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table; _dwarf_free_abbrev_hash_table_contents(dbg,hash_table); nextcontext = context->cc_next; dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE); context->cc_abbrev_hash_table = 0; dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT); } dis->de_cu_context_list = 0; } /* Used to free all space allocated for this Dwarf_Debug. The caller should assume that the Dwarf_Debug pointer itself is no longer valid upon return from this function. In case of difficulty, this function simply returns quietly. */ int _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) { unsigned g = 0; if (dbg == NULL) { return (DW_DLV_ERROR); } /* To do complete validation that we have no surprising missing or erroneous deallocs it is advisable to do the dwarf_deallocs here that are not things the user can otherwise request. Housecleaning. */ if (dbg->de_cu_hashindex_data) { dwarf_xu_header_free(dbg->de_cu_hashindex_data); dbg->de_cu_hashindex_data = 0; } if (dbg->de_tu_hashindex_data) { dwarf_xu_header_free(dbg->de_tu_hashindex_data); dbg->de_tu_hashindex_data = 0; } if( dbg->de_printf_callback_null_device_handle) { fclose(dbg->de_printf_callback_null_device_handle); dbg->de_printf_callback_null_device_handle = 0; } freecontextlist(dbg,&dbg->de_info_reading); freecontextlist(dbg,&dbg->de_types_reading); /* Housecleaning done. Now really free all the space. */ rela_free(&dbg->de_debug_info); rela_free(&dbg->de_debug_types); rela_free(&dbg->de_debug_abbrev); rela_free(&dbg->de_debug_line); rela_free(&dbg->de_debug_line_str); rela_free(&dbg->de_debug_loc); rela_free(&dbg->de_debug_aranges); rela_free(&dbg->de_debug_macinfo); rela_free(&dbg->de_debug_macro); rela_free(&dbg->de_debug_names); rela_free(&dbg->de_debug_pubnames); rela_free(&dbg->de_debug_str); rela_free(&dbg->de_debug_sup); rela_free(&dbg->de_debug_frame); rela_free(&dbg->de_debug_frame_eh_gnu); rela_free(&dbg->de_debug_pubtypes); rela_free(&dbg->de_debug_funcnames); rela_free(&dbg->de_debug_typenames); rela_free(&dbg->de_debug_varnames); rela_free(&dbg->de_debug_weaknames); rela_free(&dbg->de_debug_ranges); rela_free(&dbg->de_debug_str_offsets); rela_free(&dbg->de_debug_addr); rela_free(&dbg->de_debug_gdbindex); rela_free(&dbg->de_debug_cu_index); rela_free(&dbg->de_debug_tu_index); dwarf_harmless_cleanout(&dbg->de_harmless_errors); if (dbg->de_printf_callback.dp_buffer && !dbg->de_printf_callback.dp_buffer_user_provided ) { free(dbg->de_printf_callback.dp_buffer); } _dwarf_destroy_group_map(dbg); dwarf_tdestroy(dbg->de_alloc_tree,tdestroy_free_node); dbg->de_alloc_tree = 0; if (dbg->de_tied_data.td_tied_search) { dwarf_tdestroy(dbg->de_tied_data.td_tied_search, _dwarf_tied_destroy_free_node); dbg->de_tied_data.td_tied_search = 0; } free((void *)dbg->de_path); dbg->de_path = 0; for (g = 0; g < dbg->de_gnu_global_path_count; ++g) { free((char *)dbg->de_gnu_global_paths[g]); dbg->de_gnu_global_paths[g] = 0; } free((void*)dbg->de_gnu_global_paths); dbg->de_gnu_global_paths = 0; dbg->de_gnu_global_path_count = 0; memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */ free(dbg); return (DW_DLV_OK); } /* A special case: we have no dbg, no alloc header etc. So create something out of thin air that we can recognize in dwarf_dealloc. Something with the prefix (prefix space hidden from caller). Only applies to DW_DLA_ERROR, and making up an error record. The allocated space simply leaks. */ struct Dwarf_Error_s * _dwarf_special_no_dbg_error_malloc(void) { Dwarf_Error e = 0; /* The union unused things are to guarantee proper alignment */ Dwarf_Unsigned len = sizeof(struct Dwarf_Error_s); char *mem = (char *)malloc(len); if (mem == 0) { return 0; } memset(mem, 0, len); e = (Dwarf_Error)mem; e->er_static_alloc = DE_MALLOC; return e; } dwarfutils-20200114/libdwarf/dwarf_alloc.h000066400000000000000000000031251361531463500203610ustar00rootroot00000000000000/* Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* #define DWARF_SIMPLE_MALLOC 1 */ char * _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned); Dwarf_Debug _dwarf_get_debug(void); int _dwarf_free_all_of_one_debug(Dwarf_Debug); struct Dwarf_Error_s * _dwarf_special_no_dbg_error_malloc(void); void _dwarf_error_destructor(void *); /* ALLOC_AREA_INDEX_TABLE_MAX is the size of the struct ial_s index_into_allocated array in dwarf_alloc.c */ #define ALLOC_AREA_INDEX_TABLE_MAX 65 dwarfutils-20200114/libdwarf/dwarf_arange.c000066400000000000000000000542421361531463500205250ustar00rootroot00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_arange.h" #include "dwarf_global.h" /* for _dwarf_fixup_* */ /* Common code for two user-visible routines to share. Errors here result in memory leaks, but errors here are serious (making aranges unusable) so we assume callers will not repeat the error often or mind the leaks. */ static int dwarf_get_aranges_list(Dwarf_Debug dbg, Dwarf_Chain * chain_out, Dwarf_Signed * chain_count_out, Dwarf_Error * error) { /* Sweeps through the arange. */ Dwarf_Small *arange_ptr = 0; Dwarf_Small *arange_ptr_start = 0; /* Start of arange header. Used for rounding offset of arange_ptr to twice the tuple size. Libdwarf requirement. */ Dwarf_Small *header_ptr = 0; /* Version of .debug_aranges header. */ Dwarf_Half version = 0; /* Offset of current set of aranges into .debug_info. */ Dwarf_Off info_offset = 0; /* Size in bytes of addresses in target. */ Dwarf_Small address_size = 0; /* Size in bytes of segment offsets in target. */ Dwarf_Small segment_size = 0; /* Count of total number of aranges. */ Dwarf_Signed arange_count = 0; Dwarf_Arange arange = 0; Dwarf_Unsigned section_size = 0; Dwarf_Byte_Ptr arange_end_section = 0; /* Used to chain Dwarf_Aranges structs. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; if (!dbg->de_debug_aranges.dss_size) { return (DW_DLV_NO_ENTRY); } arange_ptr = dbg->de_debug_aranges.dss_data; arange_ptr_start = arange_ptr; section_size = dbg->de_debug_aranges.dss_size; arange_end_section = arange_ptr + section_size; do { /* Length of current set of aranges. This is local length, which begins just after the length field itself. */ Dwarf_Unsigned area_length = 0; Dwarf_Small remainder = 0; Dwarf_Unsigned range_entry_size = 0; int local_length_size; int local_extension_size = 0; Dwarf_Small *end_this_arange = 0; header_ptr = arange_ptr; if (header_ptr >= arange_end_section) { _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned, arange_ptr, local_length_size, local_extension_size,error, section_size, arange_end_section); /* arange_ptr has been incremented appropriately past the length field by READ_AREA_LENGTH. */ if (area_length > dbg->de_debug_aranges.dss_size) { _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } if ((area_length + local_length_size + local_extension_size) > dbg->de_debug_aranges.dss_size) { _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } end_this_arange = arange_ptr + area_length; if (end_this_arange > arange_end_section) { _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } if (!area_length) { /* We read 4 bytes of zero, so area-length zero. Keep scanning. First seen Nov 27, 2018 in GNU-cc in windows dll. */ continue; } READ_UNALIGNED_CK(dbg, version, Dwarf_Half, arange_ptr, DWARF_HALF_SIZE, error,end_this_arange); arange_ptr += DWARF_HALF_SIZE; if (arange_ptr >= end_this_arange) { _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } if (version != DW_ARANGES_VERSION2) { _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg, info_offset, Dwarf_Off, arange_ptr, local_length_size, error,end_this_arange); arange_ptr += local_length_size; if (arange_ptr >= end_this_arange) { _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); return DW_DLV_ERROR; } /* This applies to debug_info only, not to debug_types. */ if (info_offset >= dbg->de_debug_info.dss_size) { FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, "arange info offset.a"); if (info_offset >= dbg->de_debug_info.dss_size) { _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); return (DW_DLV_ERROR); } } address_size = *(Dwarf_Small *) arange_ptr; if (address_size > sizeof(Dwarf_Addr)) { _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR); return DW_DLV_ERROR; } if (address_size == 0) { _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO); return DW_DLV_ERROR; } /* It is not an error if the sizes differ. Unusual, but not an error. */ arange_ptr = arange_ptr + sizeof(Dwarf_Small); /* The following deref means we better check the pointer for off-end. */ if (arange_ptr >= end_this_arange) { _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); return DW_DLV_ERROR; } /* Even DWARF2 had a segment_size field here, meaning size in bytes of a segment descriptor on the target system. */ segment_size = *(Dwarf_Small *) arange_ptr; if (segment_size > sizeof(Dwarf_Addr)) { _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); return (DW_DLV_ERROR); } arange_ptr = arange_ptr + sizeof(Dwarf_Small); /* Code below will check for == end_this_arange as appropriate. */ if (arange_ptr > end_this_arange) { _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); return (DW_DLV_ERROR); } range_entry_size = 2*address_size + segment_size; /* Round arange_ptr offset to next multiple of address_size. */ remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % (range_entry_size); if (remainder != 0) { arange_ptr = arange_ptr + (2 * address_size) - remainder; } do { Dwarf_Addr range_address = 0; Dwarf_Unsigned segment_selector = 0; Dwarf_Unsigned range_length = 0; /* For segmented address spaces, the first field to read is a segment selector (new in DWARF4). The version number DID NOT CHANGE from 2, which is quite surprising. Also surprising since the segment_size was always there in the table header! */ /* We want to test cu_version here but currently with no way to do that. So we just hope no one using segment_selectors, really. FIXME */ if (segment_size) { /* Only applies if cu_version >= 4. */ READ_UNALIGNED_CK(dbg, segment_selector, Dwarf_Unsigned, arange_ptr, segment_size, error,end_this_arange); arange_ptr += address_size; } READ_UNALIGNED_CK(dbg, range_address, Dwarf_Addr, arange_ptr, address_size, error,end_this_arange); arange_ptr += address_size; READ_UNALIGNED_CK(dbg, range_length, Dwarf_Unsigned, arange_ptr, address_size, error,end_this_arange); arange_ptr += address_size; { /* We used to suppress all-zero entries, but now we return all aranges entries so we show the entire content. March 31, 2010. */ arange = (Dwarf_Arange) _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); if (arange == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } arange->ar_segment_selector = segment_selector; arange->ar_segment_selector_size = segment_size; arange->ar_address = range_address; arange->ar_length = range_length; arange->ar_info_offset = info_offset; arange->ar_dbg = dbg; arange_count++; curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_chain->ch_item = arange; if (head_chain == NULL) head_chain = prev_chain = curr_chain; else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } } /* The current set of ranges is terminated by range_address 0 and range_length 0, but that does not necessarily terminate the ranges for this CU! There can be multiple sets in that DWARF does not explicitly forbid multiple sets. DWARF2,3,4 section 7.20 We stop short to avoid overrun of the end of the CU. */ } while (end_this_arange >= (arange_ptr + range_entry_size)); /* A compiler could emit some padding bytes here. dwarf2/3 (dwarf4 sec 7.20) does not clearly make extra padding bytes illegal. */ if (end_this_arange < arange_ptr) { char buf[200]; Dwarf_Unsigned pad_count = arange_ptr - end_this_arange; Dwarf_Unsigned offset = arange_ptr - arange_ptr_start; /* Safe. Length strictly limited. */ sprintf(buf, "DW_DLE_ARANGE_LENGTH_BAD." " 0x%" DW_PR_XZEROS DW_PR_DUx " pad bytes at offset 0x%" DW_PR_XZEROS DW_PR_DUx " in .debug_aranges", pad_count, offset); dwarf_insert_harmless_error(dbg,buf); } /* For most compilers, arange_ptr == end_this_arange at this point. But not if there were padding bytes */ arange_ptr = end_this_arange; } while (arange_ptr < arange_end_section); if (arange_ptr != arange_end_section) { _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); return (DW_DLV_ERROR); } *chain_out = head_chain; *chain_count_out = arange_count; return DW_DLV_OK; } /* This function returns the count of the number of aranges in the .debug_aranges section. It sets aranges to point to a block of Dwarf_Arange's describing the arange's. It returns DW_DLV_ERROR on error. Must be identical in most aspects to dwarf_get_aranges_addr_offsets! */ int dwarf_get_aranges(Dwarf_Debug dbg, Dwarf_Arange ** aranges, Dwarf_Signed * returned_count, Dwarf_Error * error) { /* Count of total number of aranges. */ Dwarf_Signed arange_count = 0; Dwarf_Arange *arange_block = 0; /* Used to chain Dwarf_Aranges structs. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Signed i = 0; int res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error); if (res != DW_DLV_OK) { return res; } /* aranges points in to info, so if info needs expanding we have to load it. */ res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); if (res != DW_DLV_OK) { return res; } arange_block = (Dwarf_Arange *) _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count); if (arange_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_chain = head_chain; for (i = 0; i < arange_count; i++) { *(arange_block + i) = curr_chain->ch_item; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } *aranges = arange_block; *returned_count = (arange_count); return DW_DLV_OK; } /* This function returns DW_DLV_OK if it succeeds and DW_DLV_ERR or DW_DLV_OK otherwise. count is set to the number of addresses in the .debug_aranges section. For each address, the corresponding element in an array is set to the address itself(aranges) and the section offset (offsets). Must be identical in most aspects to dwarf_get_aranges! */ int _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrs, Dwarf_Off ** offsets, Dwarf_Signed * count, Dwarf_Error * error) { Dwarf_Signed i = 0; /* Used to chain Dwarf_Aranges structs. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Signed arange_count = 0; Dwarf_Addr *arange_addrs = 0; Dwarf_Off *arange_offsets = 0; int res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ if (error != NULL) *error = NULL; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error); if (res != DW_DLV_OK) { return res; } /* aranges points in to info, so if info needs expanding we have to load it. */ res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); if (res != DW_DLV_OK) { return res; } arange_addrs = (Dwarf_Addr *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); if (arange_addrs == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } arange_offsets = (Dwarf_Off *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); if (arange_offsets == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_chain = head_chain; for (i = 0; i < arange_count; i++) { Dwarf_Arange ar = curr_chain->ch_item; arange_addrs[i] = ar->ar_address; arange_offsets[i] = ar->ar_info_offset; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } *count = arange_count; *offsets = arange_offsets; *addrs = arange_addrs; return (DW_DLV_OK); } /* This function takes a pointer to a block of Dwarf_Arange's, and a count of the length of the block. It checks if the given address is within the range of an address range in the block. If yes, it returns the appropriate Dwarf_Arange. Otherwise, it returns DW_DLV_ERROR. */ int dwarf_get_arange(Dwarf_Arange * aranges, Dwarf_Unsigned arange_count, Dwarf_Addr address, Dwarf_Arange * returned_arange, Dwarf_Error * error) { Dwarf_Arange curr_arange = 0; Dwarf_Unsigned i = 0; if (aranges == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL); return (DW_DLV_ERROR); } for (i = 0; i < arange_count; i++) { curr_arange = *(aranges + i); if (address >= curr_arange->ar_address && address < curr_arange->ar_address + curr_arange->ar_length) { *returned_arange = curr_arange; return (DW_DLV_OK); } } return (DW_DLV_NO_ENTRY); } /* This function takes an Dwarf_Arange, and returns the offset of the first die in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. For an arange, the cu_die can only be from debug_info, not debug_types, it seems. */ int dwarf_get_cu_die_offset(Dwarf_Arange arange, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Off offset = 0; Dwarf_Unsigned headerlen = 0; int cres = 0; if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } dbg = arange->ar_dbg; offset = arange->ar_info_offset; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } cres = _dwarf_length_of_cu_header(dbg, offset, true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *returned_offset = headerlen + offset; return DW_DLV_OK; } /* This function takes an Dwarf_Arange, and returns the offset of the CU header in the compilation-unit that the arange belongs to. Returns DW_DLV_ERROR on error. Ensures .debug_info loaded so the cu_offset is meaningful. */ int dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, Dwarf_Off * cu_header_offset_returned, Dwarf_Error * error) { Dwarf_Debug dbg = 0; if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } dbg = arange->ar_dbg; /* This applies to debug_info only, not to debug_types. */ /* Like dwarf_get_arange_info this ensures debug_info loaded: the cu_header is in debug_info and will be used else we would not call dwarf_get_arange_cu_header_offset. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } *cu_header_offset_returned = arange->ar_info_offset; return DW_DLV_OK; } /* This function takes a Dwarf_Arange, and returns true if it is not NULL. It also stores the start address of the range in *start, the length of the range in *length, and the offset of the first die in the compilation-unit in *cu_die_offset. It returns false on error. If cu_die_offset returned ensures .debug_info loaded so the cu_die_offset is meaningful. */ int dwarf_get_arange_info(Dwarf_Arange arange, Dwarf_Addr * start, Dwarf_Unsigned * length, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } if (start != NULL) *start = arange->ar_address; if (length != NULL) *length = arange->ar_length; if (cu_die_offset != NULL) { Dwarf_Debug dbg = arange->ar_dbg; Dwarf_Off headerlen = 0; Dwarf_Off offset = arange->ar_info_offset; int cres = 0; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } cres = _dwarf_length_of_cu_header(dbg, offset, true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *cu_die_offset = headerlen + offset; } return (DW_DLV_OK); } /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b(Dwarf_Arange arange, Dwarf_Unsigned* segment, Dwarf_Unsigned* segment_entry_size, Dwarf_Addr * start, Dwarf_Unsigned* length, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { if (arange == NULL) { _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); return (DW_DLV_ERROR); } if (segment != NULL) { *segment = arange->ar_segment_selector; } if (segment_entry_size != NULL) { *segment_entry_size = arange->ar_segment_selector_size; } if (start != NULL) *start = arange->ar_address; if (length != NULL) *length = arange->ar_length; if (cu_die_offset != NULL) { Dwarf_Debug dbg = arange->ar_dbg; Dwarf_Off offset = arange->ar_info_offset; Dwarf_Unsigned headerlen = 0; int cres = 0; /* This applies to debug_info only, not to debug_types. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } cres = _dwarf_length_of_cu_header(dbg, offset, true, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } *cu_die_offset = offset + headerlen; } return (DW_DLV_OK); } dwarfutils-20200114/libdwarf/dwarf_arange.h000066400000000000000000000037411361531463500205300ustar00rootroot00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This structure is used to read an arange into. */ struct Dwarf_Arange_s { /* The segment selector. Only non-zero if Dwarf4, only meaningful if ar_segment_selector_size non-zero */ Dwarf_Unsigned ar_segment_selector; /* Starting address of the arange, ie low-pc. */ Dwarf_Addr ar_address; /* Length of the arange. */ Dwarf_Unsigned ar_length; /* Offset into .debug_info of the start of the compilation-unit containing this set of aranges. Applies only to .debug_info, not .debug_types. */ Dwarf_Off ar_info_offset; /* Corresponding Dwarf_Debug. */ Dwarf_Debug ar_dbg; Dwarf_Half ar_segment_selector_size; }; int _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrs, Dwarf_Off ** offsets, Dwarf_Signed * count, Dwarf_Error * error); dwarfutils-20200114/libdwarf/dwarf_base_types.h000066400000000000000000000103651361531463500214310ustar00rootroot00000000000000/* Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2012 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define true 1 #define false 0 /* .debug_addr new in DWARF5 */ #define DW_ADDR_VERSION5 5 /* To identify a cie. That is, for .debug_frame */ #define DW_CIE_ID ~(0x0) #define DW_CIE_VERSION 1 /* DWARF2 */ #define DW_CIE_VERSION3 3 /* DWARF3 */ #define DW_CIE_VERSION4 4 /* DWARF4 */ #define DW_CIE_VERSION5 5 /* DWARF5 */ /* For .debug_info DWARF2,3,4,5. .debug_types in DWARF4 only, and gets DW_CU_VERSION4. */ #define DW_CU_VERSION2 2 #define DW_CU_VERSION3 3 #define DW_CU_VERSION4 4 #define DW_CU_VERSION5 5 /* DWARF2,3, 4 and 5.*/ #define DW_ARANGES_VERSION2 2 #define DW_LINE_VERSION2 2 #define DW_LINE_VERSION3 3 #define DW_LINE_VERSION4 4 #define DW_LINE_VERSION5 5 /* .debug_line_str (and .dwo) new in DWARF5. */ #define DW_LINE_STR_VERSION5 5 #define EXPERIMENTAL_LINE_TABLES_VERSION 0xf006 /* Experimental two-level line tables */ /* .debug_loc (and .dwo) First header version number is DWARF5. */ #define DW_LOC_VERSION5 5 /* .debug_macro (and .dwo) new in DWARF5. */ #define DW_MACRO_VERSION5 5 /* .debug_names new in DWARF5. */ #define DW_NAMES_VERSION5 5 /* .debug_pubnames in DWARF2,3,4. */ #define DW_PUBNAMES_VERSION2 2 /* .debug_pubnames in DWARF3,4. */ #define DW_PUBTYPES_VERSION2 2 /* .debug_ranges gets a version number in header in DWARF5. */ #define DW_RANGES_VERSION5 5 /* .debug_str_offsets (and .dwo) new in DWARF5. */ #define DW_STR_OFFSETS_VERSION5 5 /* .debug_sup new in DWARF5. */ #define DW_SUP_VERSION5 5 /* .debug_cu_index new in DWARF5. */ #define DW_CU_INDEX_VERSION5 5 /* .debug_tu_index new in DWARF5. */ #define DW_TU_INDEX_VERSION5 5 /* These are allocation type codes for structs that are internal to the Libdwarf Consumer library. */ #define DW_DLA_ABBREV_LIST 0x1e #define DW_DLA_CHAIN 0x1f #define DW_DLA_CU_CONTEXT 0x20 #define DW_DLA_FRAME 0x21 #define DW_DLA_GLOBAL_CONTEXT 0x22 #define DW_DLA_FILE_ENTRY 0x23 #define DW_DLA_LINE_CONTEXT 0x24 #define DW_DLA_LOC_CHAIN 0x25 #define DW_DLA_HASH_TABLE 0x26 #define DW_DLA_FUNC_CONTEXT 0x27 #define DW_DLA_TYPENAME_CONTEXT 0x28 #define DW_DLA_VAR_CONTEXT 0x29 #define DW_DLA_WEAK_CONTEXT 0x2a #define DW_DLA_PUBTYPES_CONTEXT 0x2b /* DWARF3 */ #define DW_DLA_HASH_TABLE_ENTRY 0x2c #define DW_DLA_FISSION_PERCU 0x2d #define DW_DLA_CHAIN_2 0x3d /* Thru 0x36 reserved for internal future use. */ /* Maximum number of allocation types for allocation routines. Only used with malloc_check.c and that is basically obsolete. */ #define MAX_DW_DLA 0x3a typedef signed char Dwarf_Sbyte; typedef unsigned char Dwarf_Ubyte; typedef signed short Dwarf_Shalf; typedef Dwarf_Small *Dwarf_Byte_Ptr; #define DWARF_HALF_SIZE 2 #define DWARF_32BIT_SIZE 4 #define DWARF_64BIT_SIZE 8 typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List; typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry; typedef struct Dwarf_CU_Context_s *Dwarf_CU_Context; typedef struct Dwarf_Hash_Table_s *Dwarf_Hash_Table; typedef struct Dwarf_Hash_Table_Entry_s *Dwarf_Hash_Table_Entry; typedef struct Dwarf_Alloc_Hdr_s *Dwarf_Alloc_Hdr; dwarfutils-20200114/libdwarf/dwarf_debuglink.c000066400000000000000000000675131361531463500212410ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_MALLOC_H #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDDEF_H #include /* ptrdiff_t */ #endif /* HAVE_STDDEF_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ #ifdef HAVE_UNISTD_H #include /* getcwd */ #endif /* HAVE_UNISTD_H */ #if 0 #include /* for open() */ #include /* for open() */ #include /* for open() */ #include #endif #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_debuglink.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #define MINBUFLEN 1000 #define TRUE 1 #define FALSE 0 #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #if _WIN32 #define NULL_DEVICE_NAME "NUL" #else #define NULL_DEVICE_NAME "/dev/null" #endif /* _WIN32 */ #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ static int extract_buildid(Dwarf_Debug dbg, struct Dwarf_Section_s * pbuildid, unsigned *type_returned, char **owner_name_returned, unsigned char **build_id_returned, unsigned *build_id_length_returned, Dwarf_Error *error); struct joins_s { char * js_fullpath; dwarfstring js_dirname; dwarfstring js_basepath; dwarfstring js_basename; dwarfstring js_cwd; dwarfstring js_originalfullpath; dwarfstring js_tmp; dwarfstring js_tmp2; dwarfstring js_tmpdeb; dwarfstring js_tmp3; dwarfstring js_buildid; dwarfstring js_buildid_filename; }; #if 0 int _dwarf_check_string_valid( void *areaptr, void *strptr, void *areaendptr, int suggested_error, int *errcode) { Dwarf_Small *start = areaptr; Dwarf_Small *p = strptr; Dwarf_Small *end = areaendptr; ptrdiff_t diff = 0; if (p < start) { diff = start - p; #ifdef TESTING printf("Error string start pointer error: loc %" DW_PR_DSs " bytes before available area \n",(Dwarf_Signed)diff); #endif /* TESTING */ *errcode = suggested_error; return DW_DLV_ERROR; } if (p >= end) { diff = p - start; #ifdef TESTING printf("Error string end pointer error, not terminated %" " before end of area. Length: " DW_PR_DSs "\n",(Dwarf_Signed)diff); #endif /* TESTING */ *errcode = suggested_error; return DW_DLV_ERROR; } while (p < end) { if (*p == 0) { return DW_DLV_OK; } ++p; } diff = p - start; #ifdef TESTING printf("Error string not terminated error: not ended after %" DW_PR_DSs " bytes (past end of available bytes)\n", (Dwarf_Signed)diff); #endif /* TESTING */ *errcode = DW_DLE_STRING_NOT_TERMINATED; return DW_DLV_ERROR; } #endif #if 0 static int does_file_exist(char *f) { int fd = 0; fd = open(f,O_RDONLY|O_BINARY); if (fd < 0) { return DW_DLV_NO_ENTRY; } /* Here we could derive the crc to validate the file. */ close(fd); return DW_DLV_OK; } #endif static void construct_js(struct joins_s * js) { memset(js,0,sizeof(struct joins_s)); dwarfstring_constructor(&js->js_basename); dwarfstring_constructor(&js->js_dirname); dwarfstring_constructor(&js->js_basepath); dwarfstring_constructor(&js->js_cwd); dwarfstring_constructor(&js->js_originalfullpath); dwarfstring_constructor(&js->js_tmp); dwarfstring_constructor(&js->js_tmp2); dwarfstring_constructor(&js->js_tmpdeb); dwarfstring_constructor(&js->js_tmp3); dwarfstring_constructor(&js->js_buildid); dwarfstring_constructor(&js->js_buildid_filename); } static void destruct_js(struct joins_s * js) { dwarfstring_destructor(&js->js_dirname); dwarfstring_destructor(&js->js_basepath); dwarfstring_destructor(&js->js_basename); dwarfstring_destructor(&js->js_cwd); dwarfstring_destructor(&js->js_originalfullpath); dwarfstring_destructor(&js->js_tmp); dwarfstring_destructor(&js->js_tmp2); dwarfstring_destructor(&js->js_tmpdeb); dwarfstring_destructor(&js->js_tmp3); dwarfstring_destructor(&js->js_buildid); dwarfstring_destructor(&js->js_buildid_filename); } static char joinchar = '/'; static char* joinstr = "/"; int _dwarf_pathjoinl(dwarfstring *target,dwarfstring * input) { char *inputs = dwarfstring_string(input); char *targ = dwarfstring_string(target); size_t targlen = 0; if (!dwarfstring_strlen(target)) { dwarfstring_append(target,dwarfstring_string(input)); return DW_DLV_OK; } targlen = dwarfstring_strlen(target); targ = dwarfstring_string(target); if (targ[targlen-1] != joinchar) { if (*inputs != joinchar) { dwarfstring_append(target,joinstr); dwarfstring_append(target,inputs); } else { dwarfstring_append(target,inputs); } } else { if (*inputs != joinchar) { dwarfstring_append(target,inputs); } else { dwarfstring_append(target,inputs+1); } } return DW_DLV_OK; } /* ASSERT: the last character in s is not a / */ static size_t mydirlen(char *s) { char *cp = 0; char *lastjoinchar = 0; size_t count =0; for(cp = s ; *cp ; ++cp,++count) { if (*cp == joinchar) { lastjoinchar = cp; } } if (lastjoinchar) { /* we know diff is postive in all cases */ ptrdiff_t diff = lastjoinchar - s; /* count the last join as mydirlen. */ return (size_t)(diff+1); } return 0; } struct dwarfstring_list_s { dwarfstring dl_string; struct dwarfstring_list_s *dl_next; }; static void dwarfstring_list_constructor(struct dwarfstring_list_s *l) { dwarfstring_constructor(&l->dl_string); l->dl_next = 0; } static int dwarfstring_list_add_new(struct dwarfstring_list_s * base_entry, struct dwarfstring_list_s *prev, dwarfstring * input, struct dwarfstring_list_s ** new_out, int *errcode) { struct dwarfstring_list_s *next = 0; if(prev) { next = ( struct dwarfstring_list_s *) malloc(sizeof(struct dwarfstring_list_s)); if (!next) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } dwarfstring_list_constructor(next); } else { next = base_entry; } dwarfstring_append(&next->dl_string, dwarfstring_string(input)); if (prev) { prev->dl_next = next; } *new_out = next; return DW_DLV_OK; } /* destructs passed in entry (does not free it) and all those on the dl_next list (those are freed). */ static void dwarfstring_list_destructor(struct dwarfstring_list_s *l) { struct dwarfstring_list_s *curl = l; struct dwarfstring_list_s *nextl = l; nextl = curl->dl_next; dwarfstring_destructor(&curl->dl_string); curl->dl_next = 0; curl = nextl; for( ; curl ; curl = nextl) { nextl = curl->dl_next; dwarfstring_destructor(&curl->dl_string); curl->dl_next = 0; free(curl); } } static void build_buildid_filename(dwarfstring *target, unsigned buildid_length, unsigned char *buildid) { dwarfstring tmp; unsigned bu = 0; unsigned char *cp = 0; char lbuf[10]; dwarfstring_constructor(&tmp); cp = buildid; for (bu = 0; bu < buildid_length; ++bu ,++cp) { sprintf(lbuf,"%02x",*cp); dwarfstring_append(&tmp,lbuf); if (bu == 0) { dwarfstring_append(&tmp,"/"); } } dwarfstring_append(&tmp,".debug"); _dwarf_pathjoinl(target,&tmp); dwarfstring_destructor(&tmp); return; } #if 0 static void dump_bytes(const char *msg,unsigned char * start, unsigned len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* New September 2019. Access to the GNU section named .gnu_debuglink See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html */ int _dwarf_construct_linkedto_path( char **global_prefixes_in, unsigned length_global_prefixes_in, char *pathname_in, char *link_string_in, /* from debug link */ dwarfstring * link_string_fullpath_out, UNUSEDARG unsigned char *crc_in, /* from debug_link, 4 bytes */ unsigned char *buildid, /* from gnu buildid */ unsigned buildid_length, /* from gnu buildid */ char ***paths_out, unsigned *paths_out_length, int *errcode) { char * depath = pathname_in; int res = 0; struct joins_s joind; size_t dirnamelen = 0; struct dwarfstring_list_s base_dwlist; struct dwarfstring_list_s *last_entry = 0; unsigned global_prefix_number = 0; dwarfstring_list_constructor(&base_dwlist); construct_js(&joind); build_buildid_filename(&joind.js_buildid_filename, buildid_length, buildid); dirnamelen = mydirlen(depath); if (dirnamelen) { dwarfstring_append_length(&joind.js_dirname, depath,dirnamelen); } dwarfstring_append(&joind.js_basepath,depath+dirnamelen); dwarfstring_append(&joind.js_basename,link_string_in); if (depath[0] != joinchar) { char buffer[2000]; #ifdef TESTING buffer[0] = 0; /* For testing lets use a fake (consistent) base dir. */ strcpy(buffer,"/fake/dir/path"); #else unsigned buflen= sizeof(buffer); char *wdret = 0; buffer[0] = 0; wdret = getcwd(buffer,buflen); if (!wdret) { printf("getcwd() issue. Do nothing. " " line %d %s\n",__LINE__,__FILE__); dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } #endif /* TESTING */ dwarfstring_append(&joind.js_cwd,buffer); buffer[0] = 0; } { /* Builds the full path to the original executable, but absent executable name. */ dwarfstring_append(&joind.js_originalfullpath, dwarfstring_string(&joind.js_cwd)); _dwarf_pathjoinl(&joind.js_originalfullpath, &joind.js_dirname); _dwarf_pathjoinl(&joind.js_originalfullpath, &joind.js_basepath); #ifdef TESTING printf("originalfullpath : %s\n", dwarfstring_string(&joind.js_originalfullpath)); #endif } { /* There is perhaps a directory prefix in the incoming pathname. So we add that to js_cwd. */ res = _dwarf_pathjoinl(&joind.js_cwd, &joind.js_dirname); /* This is used in a couple search paths. */ } for (global_prefix_number = 0; buildid_length && (global_prefix_number < length_global_prefixes_in); ++global_prefix_number) { char * prefix = 0; prefix = global_prefixes_in[global_prefix_number]; dwarfstring_reset(&joind.js_buildid); dwarfstring_append(&joind.js_buildid,prefix); _dwarf_pathjoinl(&joind.js_buildid, &joind.js_buildid_filename); if (!strcmp(dwarfstring_string(&joind.js_originalfullpath), dwarfstring_string(&joind.js_buildid))) { #ifdef TESTING printf("duplicated output string %s\n", dwarfstring_string(&joind.js_buildid)); #endif /* TESTING */ /* duplicated name. spurious match. */ } else { struct dwarfstring_list_s *now_last = 0; res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_buildid, &now_last,errcode); if(res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } } if (link_string_in) { /* js_cwd is a leading / directory name. */ { dwarfstring_reset(&joind.js_tmp); dwarfstring_append(&joind.js_tmp, dwarfstring_string(&joind.js_cwd)); /* If we add basename do we find what we look for? */ res = _dwarf_pathjoinl(&joind.js_tmp,&joind.js_basename); /* We return the original link as full path this way. */ dwarfstring_append(link_string_fullpath_out, dwarfstring_string(&joind.js_tmp)); if (!strcmp(dwarfstring_string(&joind.js_originalfullpath), dwarfstring_string(&joind.js_tmp))) { #ifdef TESTING printf("duplicated output string %s\n", dwarfstring_string(&joind.js_tmp)); #endif /* TESTING */ /* duplicated name. spurious match. */ } else if (res == DW_DLV_OK) { struct dwarfstring_list_s *now_last = 0; res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_tmp, &now_last,errcode); if(res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } } { dwarfstring_reset(&joind.js_tmp2); dwarfstring_reset(&joind.js_tmpdeb); dwarfstring_append(&joind.js_tmp2, dwarfstring_string(&joind.js_cwd)); dwarfstring_append(&joind.js_tmpdeb,".debug"); res = _dwarf_pathjoinl(&joind.js_tmp2,&joind.js_tmpdeb); if (res == DW_DLV_OK) { res = _dwarf_pathjoinl(&joind.js_tmp2, &joind.js_basename); /* this the second search path after global directories search for nn/nnnnn....debug. */ if (!strcmp(dwarfstring_string( &joind.js_originalfullpath), dwarfstring_string(&joind.js_tmp2))) { #ifdef TESTING printf("duplicated output string %s\n", dwarfstring_string(&joind.js_tmp2)); #endif /* TESTING */ /* duplicated name. spurious match. */ } else if(res == DW_DLV_OK) { struct dwarfstring_list_s *now_last = 0; res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_tmp2, &now_last,errcode); if(res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } } } /* Not found above, now look in the global locations. */ for (global_prefix_number = 0; global_prefix_number < length_global_prefixes_in; ++global_prefix_number) { char * prefix = global_prefixes_in[global_prefix_number]; dwarfstring_reset(&joind.js_tmp3); dwarfstring_append(&joind.js_tmp3, prefix); res = _dwarf_pathjoinl(&joind.js_tmp3, &joind.js_cwd); if (res == DW_DLV_OK) { res = _dwarf_pathjoinl(&joind.js_tmp3, &joind.js_basename); if (!strcmp(dwarfstring_string( &joind.js_originalfullpath), dwarfstring_string(&joind.js_tmp3))) { /* duplicated name. spurious match. */ #ifdef TESTING printf("duplicated output string %s\n", dwarfstring_string(&joind.js_tmp3)); #endif /* TESTING */ } else if (res == DW_DLV_OK) { struct dwarfstring_list_s *now_last = 0; res = dwarfstring_list_add_new( &base_dwlist, last_entry,&joind.js_tmp3, &now_last,errcode); if(res != DW_DLV_OK) { dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return res; } last_entry = now_last; } } } } { struct dwarfstring_list_s *cur = 0; char **resultfullstring = 0; unsigned long count = 0; unsigned long pointerarraysize = 0; unsigned long sumstringlengths = 0; unsigned long totalareasize = 0; unsigned long setptrindex = 0; unsigned long setstrindex = 0; cur = &base_dwlist; for ( ; cur ; cur = cur->dl_next) { ++count; pointerarraysize += sizeof(void *); sumstringlengths += dwarfstring_strlen(&cur->dl_string) +1; } /* Make a final null pointer in the pointer array. */ pointerarraysize += sizeof(void *); totalareasize = pointerarraysize + sumstringlengths +8; resultfullstring = (char **)malloc(totalareasize); setstrindex = pointerarraysize; if(!resultfullstring) { #ifdef TESTING printf("Malloc fail making final paths. Length %lu" " bytes.\n",totalareasize); #endif /* TESTING */ dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(resultfullstring,0,totalareasize); cur = &base_dwlist; for ( ; cur ; cur = cur->dl_next,++setptrindex) { char **iptr = (char **)((char *)resultfullstring + setptrindex*sizeof(void *)); char *sptr = (char*)resultfullstring + setstrindex; strcpy(sptr,dwarfstring_string(&cur->dl_string)); setstrindex += dwarfstring_strlen(&cur->dl_string)+1; *iptr = sptr; } *paths_out = resultfullstring; *paths_out_length = count; } dwarfstring_list_destructor(&base_dwlist); destruct_js(&joind); return DW_DLV_OK; } static int extract_debuglink(Dwarf_Debug dbg, struct Dwarf_Section_s * pdebuglink, char ** name_returned, /* static storage, do not free */ unsigned char ** crc_returned, /* 32bit crc , do not free */ Dwarf_Error *error) { Dwarf_Small *ptr = 0; Dwarf_Small *endptr = 0; unsigned namelen = 0; unsigned m = 0; unsigned incr = 0; Dwarf_Small *crcptr = 0; int res = DW_DLV_ERROR; Dwarf_Unsigned secsize = 0; if (!pdebuglink->dss_data) { res = _dwarf_load_section(dbg, pdebuglink,error); if (res != DW_DLV_OK) { return res; } } secsize = pdebuglink->dss_size; ptr = pdebuglink->dss_data; endptr = ptr + secsize; res = _dwarf_check_string_valid(dbg,ptr, ptr, endptr, DW_DLE_FORM_STRING_BAD_STRING, error); if ( res != DW_DLV_OK) { return res; } namelen = (unsigned)strlen((const char*)ptr); m = (namelen+1) %4; if (m) { incr = 4 - m; } crcptr = (unsigned char *)ptr +namelen +1 +incr; if ((crcptr +4) != (unsigned char*)endptr) { _dwarf_error(dbg,error,DW_DLE_CORRUPT_GNU_DEBUGLINK); return DW_DLV_ERROR; } *name_returned = (char *)ptr; *crc_returned = crcptr; return DW_DLV_OK; } /* The definition of .note.gnu.buildid contents (also used for other GNU .note.gnu. sections too. */ struct buildid_s { char bu_ownernamesize[4]; char bu_buildidsize[4]; char bu_type[4]; char bu_owner[1]; }; static int extract_buildid(Dwarf_Debug dbg, struct Dwarf_Section_s * pbuildid, unsigned * type_returned, char **owner_name_returned, unsigned char **build_id_returned, unsigned * build_id_length_returned, Dwarf_Error *error) { Dwarf_Small * ptr = 0; Dwarf_Small * endptr = 0; int res = DW_DLV_ERROR; struct buildid_s *bu = 0; Dwarf_Unsigned namesize = 0; Dwarf_Unsigned descrsize = 0; Dwarf_Unsigned type = 0; Dwarf_Unsigned finalsize; Dwarf_Unsigned secsize = 0; if (!pbuildid->dss_data) { res = _dwarf_load_section(dbg, pbuildid,error); if (res != DW_DLV_OK) { return res; } } secsize = pbuildid->dss_size; ptr = pbuildid->dss_data; if (secsize < sizeof(struct buildid_s)) { #ifdef TESTING printf("ERROR section .note.gnu.build-id too small: " " section length: 0x%" DW_PR_DUx " minimum struct size 0x%" DW_PR_DUx "\n", secsize,(Dwarf_Unsigned) sizeof(struct buildid_s)); #endif /* TESTING */ _dwarf_error(dbg,error,DW_DLE_CORRUPT_NOTE_GNU_DEBUGID); return DW_DLV_ERROR; } endptr = ptr + secsize; /* We hold gh_content till all is closed as we return pointers into it if all goes well. */ bu = (struct buildid_s *)ptr; ASNAR(dbg->de_copy_word,namesize, bu->bu_ownernamesize); ASNAR(dbg->de_copy_word,descrsize,bu->bu_buildidsize); ASNAR(dbg->de_copy_word,type, bu->bu_type); if (descrsize != 20) { _dwarf_error(dbg,error,DW_DLE_CORRUPT_NOTE_GNU_DEBUGID); return DW_DLV_ERROR; } res = _dwarf_check_string_valid(dbg, (Dwarf_Small *)&bu->bu_owner[0], (Dwarf_Small *)&bu->bu_owner[0], endptr, DW_DLE_CORRUPT_GNU_DEBUGID_STRING, error); if ( res != DW_DLV_OK) { return res; } if ((strlen(bu->bu_owner) +1) != namesize) { _dwarf_error(dbg,error, DW_DLE_CORRUPT_GNU_DEBUGID_STRING); return res; } finalsize = sizeof(struct buildid_s)-1 + namesize + descrsize; if (finalsize > secsize) { _dwarf_error(dbg,error, DW_DLE_CORRUPT_GNU_DEBUGID_SIZE); return DW_DLV_ERROR; } *type_returned = type; *owner_name_returned = &bu->bu_owner[0]; *build_id_length_returned = descrsize; *build_id_returned = (unsigned char *)ptr + sizeof(struct buildid_s)-1 + namesize; return DW_DLV_OK; } /* */ int dwarf_gnu_debuglink(Dwarf_Debug dbg, char ** debuglink_path_returned, unsigned char ** crc_returned, char ** debuglink_fullpath_returned, unsigned * debuglink_fullpath_length_returned, unsigned * buildid_type_returned , char ** buildid_owner_name_returned, unsigned char ** buildid_returned, unsigned * buildid_length_returned, char *** paths_returned, unsigned * paths_count_returned, Dwarf_Error* error) { dwarfstring debuglink_fullpath; int linkres = DW_DLV_ERROR; int res = DW_DLV_ERROR; char * pathname = 0; int buildidres = 0; int errcode = 0; struct Dwarf_Section_s * pdebuglink = 0; struct Dwarf_Section_s * pbuildid = 0; if(!dbg) { _dwarf_error(dbg,error,DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (dbg->de_gnu_debuglink.dss_size) { pdebuglink = &dbg->de_gnu_debuglink; } if (dbg->de_note_gnu_buildid.dss_size) { pbuildid = &dbg->de_note_gnu_buildid; } if (!pdebuglink && !pbuildid) { return DW_DLV_NO_ENTRY; } if (pdebuglink) { linkres = extract_debuglink(dbg, pdebuglink, debuglink_path_returned, crc_returned, error); if (linkres == DW_DLV_ERROR) { return linkres; } } if (pbuildid) { buildidres = extract_buildid(dbg, pbuildid, buildid_type_returned, buildid_owner_name_returned, buildid_returned, buildid_length_returned, error); if (buildidres == DW_DLV_ERROR) { return buildidres; } } dwarfstring_constructor(&debuglink_fullpath); pathname = (char *)dbg->de_path; if (pathname && paths_returned) { res = _dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, pathname, *debuglink_path_returned, &debuglink_fullpath, *crc_returned, *buildid_returned, *buildid_length_returned, paths_returned, paths_count_returned, &errcode); if(res != DW_DLV_OK) { dwarfstring_destructor(&debuglink_fullpath); return res; } if (dwarfstring_strlen(&debuglink_fullpath)) { *debuglink_fullpath_returned = strdup(dwarfstring_string(&debuglink_fullpath)); *debuglink_fullpath_length_returned = dwarfstring_strlen(&debuglink_fullpath); } } else if (paths_count_returned) { *paths_count_returned = 0; } dwarfstring_destructor(&debuglink_fullpath); return DW_DLV_OK; } /* This should be rarely called and most likely only once (at dbg init time from dwarf_generic_init.c, see set_global_paths_init()). Maybe once or twice later. */ int dwarf_add_debuglink_global_path(Dwarf_Debug dbg, const char *pathname, Dwarf_Error *error) { unsigned glpath_count_in = 0; unsigned glpath_count_out = 0; const char **glpaths = 0; const char * path1 = 0; glpath_count_in = dbg->de_gnu_global_path_count; glpath_count_out = glpath_count_in+1; glpaths = (const char **)malloc(sizeof(char *)* glpath_count_out); if (!glpaths) { _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (glpath_count_in) { memcpy(glpaths, dbg->de_gnu_global_paths, sizeof(char *)*glpath_count_in); } path1 = strdup(pathname); if (!path1) { free(glpaths); _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } free((char *)dbg->de_gnu_global_paths); glpaths[glpath_count_in] = path1; dbg->de_gnu_global_paths = (const char **)glpaths; dbg->de_gnu_global_path_count = glpath_count_out; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_debuglink.h000066400000000000000000000040231361531463500212310ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_DEBUGLINK_H #define DWARF_DEBUGLINK_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int _dwarf_pathjoinl(dwarfstring *target,dwarfstring * input); int _dwarf_construct_linkedto_path( char **global_prefixes_in, unsigned length_global_prefixes_in, char *pathname_in, char *link_string_in, /* from debug link */ dwarfstring *link_string_fullpath, unsigned char *crc_in, /* from debug_link, 4 bytes */ unsigned char *buildid, /* from gnu buildid */ unsigned buildid_length, /* from gnu buildid */ char ***paths_out, unsigned *paths_out_length, int *errcode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_DEBUGLINK_H */ dwarfutils-20200114/libdwarf/dwarf_die_deliv.c000066400000000000000000002523571361531463500212230ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_die_deliv.h" #define FALSE 0 #define TRUE 1 /* These are sanity checks, not 'rules'. */ #define MINIMUM_ADDRESS_SIZE 2 #define MAXIMUM_ADDRESS_SIZE 8 static void assign_correct_unit_type(Dwarf_CU_Context cu_context); static int find_cu_die_base_fields(Dwarf_Debug dbg, Dwarf_Die cudie, Dwarf_Sig8 * dwoid_return, Dwarf_Bool * dwoid_present_return, Dwarf_Unsigned *str_offsets_base_return, Dwarf_Bool * str_offsets_base_present_return, Dwarf_Unsigned *addr_base_return, Dwarf_Bool * addr_base_present_return, Dwarf_Unsigned *ranges_base_return, /* rnglists_base */ Dwarf_Bool * ranges_base_present_return, Dwarf_Unsigned *loclists_base_return, /* rnglists_base */ Dwarf_Bool * loclists_base_present_return, char ** dwo_name_return, /* rnglists_base */ Dwarf_Bool * dwo_name_present_return, Dwarf_Bool * has_children_return, Dwarf_Error* error); /* see cuandunit.txt for an overview of the DWARF5 split dwarf sections and values and the DWARF4 GNU cc version of a draft version of DWARF5 (quite different from the final DWARF5). */ /* New October 2011. Enables client code to know if it is a debug_info or debug_types context. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die die) { return die->di_is_info; } #if 0 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 /* For a given Dwarf_Debug dbg, this function checks if a CU that includes the given offset has been read or not. If yes, it returns the Dwarf_CU_Context for the CU. Otherwise it returns NULL. Being an internal routine, it is assumed that a valid dbg is passed. **This is a sequential search. May be too slow. If debug_info and debug_abbrev not loaded, this will wind up returning NULL. So no need to load before calling this. */ static Dwarf_CU_Context _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,Dwarf_Bool is_info) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; if (offset >= dis->de_last_offset) return (NULL); if (dis->de_cu_context != NULL && dis->de_cu_context->cc_next != NULL && dis->de_cu_context->cc_next->cc_debug_offset == offset) { return (dis->de_cu_context->cc_next); } if (dis->de_cu_context != NULL && dis->de_cu_context->cc_debug_offset <= offset) { for (cu_context = dis->de_cu_context; cu_context != NULL; cu_context = cu_context->cc_next) { if (offset >= cu_context->cc_debug_offset && offset < cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { return (cu_context); } } } for (cu_context = dis->de_cu_context_list; cu_context != NULL; cu_context = cu_context->cc_next) { if (offset >= cu_context->cc_debug_offset && offset < cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { return (cu_context); } } return (NULL); } /* This routine checks the dwarf_offdie() list of CU contexts for the right CU context. */ static Dwarf_CU_Context _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; for (cu_context = dis->de_offdie_cu_context; cu_context != NULL; cu_context = cu_context->cc_next) if (offset >= cu_context->cc_debug_offset && offset < cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) return (cu_context); return (NULL); } int dwarf_get_debugfission_for_die(Dwarf_Die die, struct Dwarf_Debug_Fission_Per_CU_s *fission_out, Dwarf_Error *error) { Dwarf_CU_Context context = 0; Dwarf_Debug dbg = 0; struct Dwarf_Debug_Fission_Per_CU_s * percu = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; if (!_dwarf_file_has_debug_fission_index(dbg)) { return DW_DLV_NO_ENTRY; } /* Logic should work for DW4 and DW5. */ if (context->cc_unit_type == DW_UT_type|| context->cc_unit_type == DW_UT_split_type ) { if (!_dwarf_file_has_debug_fission_tu_index(dbg)) { return DW_DLV_NO_ENTRY; } } else if (context->cc_unit_type == DW_UT_split_compile) { if (!_dwarf_file_has_debug_fission_cu_index(dbg)) { return DW_DLV_NO_ENTRY; } } percu = &context->cc_dwp_offsets; if (!percu->pcu_type) { return DW_DLV_NO_ENTRY; } *fission_out = *percu; return DW_DLV_OK; } static Dwarf_Bool is_unknown_UT_value(int ut) { switch(ut) { case DW_UT_compile: case DW_UT_type: case DW_UT_partial: return FALSE; case DW_UT_skeleton: case DW_UT_split_compile: case DW_UT_split_type: return FALSE; } return TRUE; } /* ASSERT: whichone is a DW_SECT* macro value. */ Dwarf_Unsigned _dwarf_get_dwp_extra_offset(struct Dwarf_Debug_Fission_Per_CU_s* dwp, unsigned whichone, Dwarf_Unsigned * size) { Dwarf_Unsigned sectoff = 0; if (!dwp->pcu_type) { return 0; } sectoff = dwp->pcu_offset[whichone]; *size = dwp->pcu_size[whichone]; return sectoff; } /* _dwarf_get_fission_addition_die returns DW_DLV_OK etc. */ int _dwarf_get_fission_addition_die(Dwarf_Die die, int dw_sect_index, Dwarf_Unsigned *offset, Dwarf_Unsigned *size, Dwarf_Error *error) { /* We do not yet know the DIE hash, so we cannot use it to identify the offset. */ Dwarf_CU_Context context = 0; Dwarf_Unsigned dwpadd = 0; Dwarf_Unsigned dwpsize = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dwpadd = _dwarf_get_dwp_extra_offset( &context->cc_dwp_offsets, dw_sect_index,&dwpsize); *offset = dwpadd; *size = dwpsize; return DW_DLV_OK; } /* Not sure if this is the only way to be sure early on in reading a compile unit. */ static int section_name_ends_with_dwo(const char *name) { int lenstr = 0; int dotpos = 0; if (!name) { return FALSE; } lenstr = strlen(name); if (lenstr < 5) { return FALSE; } dotpos = lenstr - 4; if(strcmp(name+dotpos,".dwo")) { return FALSE; } return TRUE; } /* New January 2017 */ static int _dwarf_read_cu_version_and_abbrev_offset(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Bool is_info, UNUSEDARG unsigned group_number, unsigned offset_size, /* 4 or 8 */ Dwarf_CU_Context cu_context, /* end_data used for sanity checking */ Dwarf_Small * end_data, Dwarf_Unsigned * bytes_read_out, Dwarf_Error * error) { Dwarf_Small * data_start = data; Dwarf_Small * dataptr = data; int unit_type = 0; Dwarf_Ubyte addrsize = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version = 0; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, dataptr,DWARF_HALF_SIZE,error,end_data); dataptr += DWARF_HALF_SIZE; if (version == DW_CU_VERSION5) { Dwarf_Ubyte unit_typeb = 0; READ_UNALIGNED_CK(dbg, unit_typeb, Dwarf_Ubyte, dataptr, sizeof(unit_typeb),error,end_data); dataptr += sizeof(unit_typeb); unit_type = unit_typeb; /* We do not need is_info flag in DWARF5 */ if (is_unknown_UT_value(unit_type)) { /* DWARF5 object file is corrupt. Invalid value */ _dwarf_error(dbg, error, DW_DLE_CU_UT_TYPE_ERROR); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, addrsize, unsigned char, dataptr, sizeof(addrsize),error,end_data); dataptr += sizeof(char); READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, dataptr, offset_size,error,end_data); dataptr += offset_size; } else if (version == DW_CU_VERSION2 || version == DW_CU_VERSION3 || version == DW_CU_VERSION4) { /* DWARF2,3,4 */ READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, dataptr, offset_size,error,end_data); dataptr += offset_size; READ_UNALIGNED_CK(dbg, addrsize, Dwarf_Ubyte, dataptr, sizeof(addrsize),error,end_data); dataptr += sizeof(addrsize); /* This is an initial approximation of unit_type. For DW4 we will refine this after we have built the CU header (by reading CU_die) */ unit_type = is_info?DW_UT_compile:DW_UT_type; } else { _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } cu_context->cc_version_stamp = version; cu_context->cc_unit_type = unit_type; cu_context->cc_address_size = addrsize; cu_context->cc_abbrev_offset = abbrev_offset; if (!addrsize) { _dwarf_error(dbg,error,DW_DLE_ADDRESS_SIZE_ZERO); return DW_DLV_ERROR; } if (addrsize < MINIMUM_ADDRESS_SIZE || addrsize > MAXIMUM_ADDRESS_SIZE ) { _dwarf_error(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR); return DW_DLV_ERROR; } if (addrsize > sizeof(Dwarf_Addr)) { _dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD); return DW_DLV_ERROR; } /* We are ignoring this. Can get it from DWARF5. */ cu_context->cc_segment_selector_size = 0; *bytes_read_out = (dataptr - data_start); return DW_DLV_OK; } /* .debug_info[.dwo] .debug_types[.dwo] the latter only DWARF4. */ static int read_info_area_length_and_check(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Unsigned offset, Dwarf_Byte_Ptr *cu_ptr_io, Dwarf_Unsigned section_size, Dwarf_Byte_Ptr section_end_ptr, Dwarf_Unsigned *max_cu_global_offset_out, Dwarf_Error *error) { Dwarf_Byte_Ptr cu_ptr = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Unsigned max_cu_global_offset = 0; Dwarf_Unsigned length = 0; cu_ptr = *cu_ptr_io; /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, cu_ptr, local_length_size, local_extension_size, error,section_size,section_end_ptr); if (!length) { return DW_DLV_NO_ENTRY; } cu_context->cc_length_size = local_length_size; cu_context->cc_extension_size = local_extension_size; cu_context->cc_length = length; /* This is a bare minimum, not the real max offset. A preliminary sanity check. */ max_cu_global_offset = offset + length + local_extension_size + local_length_size; if(length > section_size) { _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } if(max_cu_global_offset > section_size) { _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } *cu_ptr_io = cu_ptr; *max_cu_global_offset_out = max_cu_global_offset; return DW_DLV_OK; } /* In DWARF4 GNU dwp there is a problem. We cannot read the CU die and it's DW_AT_GNU_dwo_id until we know the section offsets from the index files. Hence we do not know how to search the index files by key. So search by offset. There is no such problem in DWARF5. We have not yet corrected the unit_type so, for DWARF4, we check for simpler unit types. */ static int fill_in_dwp_offsets_if_present(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Sig8 * signaturedata, Dwarf_Off offset, Dwarf_Error *error) { Dwarf_Half unit_type = cu_context->cc_unit_type; const char * typename = 0; Dwarf_Half ver = cu_context->cc_version_stamp; if (unit_type == DW_UT_split_type || (ver == DW_CU_VERSION4 && unit_type == DW_UT_type)){ typename = "tu"; if (!_dwarf_file_has_debug_fission_tu_index(dbg) ){ /* nothing to do. */ return DW_DLV_OK; } } else if (unit_type == DW_UT_split_compile || (ver == DW_CU_VERSION4 && unit_type == DW_UT_compile)){ typename = "cu"; if (!_dwarf_file_has_debug_fission_cu_index(dbg) ){ /* nothing to do. */ return DW_DLV_OK; } } else { /* nothing to do. */ return DW_DLV_OK; } if (cu_context->cc_signature_present) { int resdf = 0; resdf = dwarf_get_debugfission_for_key(dbg, signaturedata, typename, &cu_context->cc_dwp_offsets, error); if (resdf == DW_DLV_ERROR) { return resdf; } else if (resdf == DW_DLV_NO_ENTRY) { _dwarf_error(dbg, error, DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH); return DW_DLV_ERROR; } } else { int resdf = 0; resdf = _dwarf_get_debugfission_for_offset(dbg, offset, typename, &cu_context->cc_dwp_offsets, error); if (resdf == DW_DLV_ERROR) { return resdf; } else if (resdf == DW_DLV_NO_ENTRY) { _dwarf_error(dbg, error, DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH); return DW_DLV_ERROR; } cu_context->cc_signature = cu_context->cc_dwp_offsets.pcu_hash; cu_context->cc_signature_present = TRUE; } return DW_DLV_OK; } static Dwarf_Bool _dwarf_may_have_base_fields(Dwarf_CU_Context cu_context) { if (cu_context->cc_version_stamp < DW_CU_VERSION4) { return FALSE; } return TRUE; } static int finish_cu_context_via_cudie_inner( Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Error *error) { if (_dwarf_may_have_base_fields(cu_context)) { /* DW4: Look for DW_AT_dwo_id and if there is one pick up the hash DW5: hash in skeleton CU die Also pick up cc_str_offset_base and any other base values. */ Dwarf_Die cudie = 0; int resdwo = 0; /* Must call the internal siblingof so we do not depend on the dbg...de_cu_context used by and for dwarf_cu_header_* calls. */ resdwo = _dwarf_siblingof_internal(dbg,NULL, cu_context, cu_context->cc_is_info, &cudie, error); if (resdwo == DW_DLV_OK) { Dwarf_Sig8 dwosignature; Dwarf_Bool dwoid_present = FALSE; Dwarf_Unsigned str_offsets_base = 0; Dwarf_Unsigned addr_base = 0; Dwarf_Unsigned ranges_base = 0; Dwarf_Unsigned loclists_base = 0; char * dwo_name = 0; Dwarf_Bool str_offsets_base_present = FALSE; Dwarf_Bool addr_base_present = FALSE; Dwarf_Bool ranges_base_present = FALSE; Dwarf_Bool loclists_base_present = FALSE; Dwarf_Bool dwo_name_present = FALSE; Dwarf_Bool has_children = TRUE; Dwarf_Half cutag = 0; int resdwob = 0; memset(&dwosignature,0,sizeof(dwosignature)); resdwob = find_cu_die_base_fields(dbg, cudie,&dwosignature,&dwoid_present, &str_offsets_base,&str_offsets_base_present, &addr_base,&addr_base_present, &ranges_base,&ranges_base_present, &loclists_base,&loclists_base_present, &dwo_name,&dwo_name_present, &has_children, error); if (resdwob == DW_DLV_OK) { if(dwoid_present) { if(!cu_context->cc_signature_present) { /* this can be in executable or ordinary .o or .dwo or .dwp. Non-standard DWARF4. */ cu_context->cc_signature = dwosignature; cu_context->cc_signature_present = TRUE; } else { /* VERIFY signatures match. It's not clear if we ever get here except in case of a corrupted object file (so bad DWARF). */ /* FIXME how report? Or just let it go for the consumer to find? */ #if 0 if (memcmp(&cu_context->cc_signature, &dwosignature,sizeof(Dwarf_Sig8))) { _dwarf_error(NULL, error, DW_DLE_DWP_SIGNATURE_MISMATCH); return DW_DLV_ERROR; } #endif } } cu_context->cc_cu_die_has_children = has_children; if (addr_base_present) { cu_context->cc_addr_base = addr_base; cu_context->cc_addr_base_present = TRUE; } if(str_offsets_base_present) { cu_context->cc_str_offsets_base = str_offsets_base; cu_context->cc_str_offsets_base_present = TRUE; } if(ranges_base_present) { cu_context->cc_ranges_base = ranges_base; cu_context->cc_ranges_base_present = TRUE; } if(loclists_base_present) { cu_context->cc_loclists_base = ranges_base; cu_context->cc_loclists_base_present = TRUE; } if (dwo_name_present ) { cu_context->cc_dwo_name = dwo_name; } } else if (resdwob == DW_DLV_NO_ENTRY) { /* The CU die has no children */ dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return DW_DLV_OK; } else { /* Not applicable or an error */ dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return resdwob; } resdwob = dwarf_tag(cudie,&cutag,error); if (resdwob == DW_DLV_OK) { cu_context->cc_cu_die_tag = cutag; } dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return resdwob; } else if (resdwo == DW_DLV_NO_ENTRY) { /* no die. Empty CU */ return DW_DLV_OK; } else { return resdwo; } } return DW_DLV_OK; } /* This function is used to create a CU Context for a compilation-unit that begins at offset in .debug_info. The CU Context is attached to the list of CU Contexts for this dbg. It is assumed that the CU at offset has not been read before, and so do not call this routine before making sure of this with _dwarf_find_CU_Context(). Returns NULL on error. As always, being an internal routine, assumes a good dbg. The offset argument is global offset, the offset in the section, irrespective of CUs. The offset has the DWP Package File offset built in as it comes from the actual section. max_cu_local_offset is a local offset in this CU. So zero of this field is immediately following the length field of the CU header. so max_cu_local_offset is identical to the CU length field. max_cu_global_offset is the offset one-past the end of this entire CU. */ static int _dwarf_make_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,Dwarf_Bool is_info, Dwarf_CU_Context * context_out,Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned typeoffset = 0; Dwarf_Sig8 signaturedata; Dwarf_Unsigned types_extra_len = 0; Dwarf_Unsigned max_cu_local_offset = 0; Dwarf_Unsigned max_cu_global_offset = 0; Dwarf_Byte_Ptr cu_ptr = 0; Dwarf_Byte_Ptr section_end_ptr = 0; int local_length_size = 0; Dwarf_Unsigned bytes_read = 0; const char * secname = is_info?dbg->de_debug_info.dss_name: dbg->de_debug_types.dss_name; Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size: dbg->de_debug_types.dss_size; int unit_type = 0; int version = 0; Dwarf_Small * dataptr = 0; int res = 0; cu_context = (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1); if (cu_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } cu_context->cc_dbg = dbg; cu_context->cc_is_info = is_info; dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; /* Preliminary sanity checking. */ if (!dataptr) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } if (offset >= section_size) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } if ((offset+4) > section_size) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } section_end_ptr = dataptr+section_size; cu_ptr = (Dwarf_Byte_Ptr) (dataptr+offset); if (section_name_ends_with_dwo(secname)) { cu_context->cc_is_dwo = TRUE; } res = read_info_area_length_and_check(dbg, cu_context, offset, &cu_ptr, section_size, section_end_ptr, &max_cu_global_offset, error); if (res != DW_DLV_OK) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); return res; } local_length_size = cu_context->cc_length_size; length = cu_context->cc_length; max_cu_local_offset = length; res = _dwarf_read_cu_version_and_abbrev_offset(dbg, cu_ptr, is_info, dbg->de_groupnumber, local_length_size, cu_context, section_end_ptr, &bytes_read,error); if (res != DW_DLV_OK) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); return res; } version = cu_context->cc_version_stamp; cu_ptr += bytes_read; unit_type = cu_context->cc_unit_type; if (cu_ptr > section_end_ptr) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } /* In a dwp context, the abbrev_offset is still incomplete. We need to add in the base from the .debug_cu_index or .debug_tu_index . Done below */ /* At this point, for DW4, the unit_type is not fully correct as we don't know if it is a skeleton or a split_compile or split_type */ if (version == DW_CU_VERSION5 || version == DW_CU_VERSION4) { /* DW4/DW5 header fields, depending on UT type. See DW5 section 7.5.1.x, DW4 data is a GNU extension of DW4. */ switch(unit_type) { case DW_UT_split_type: case DW_UT_type: { types_extra_len = sizeof(Dwarf_Sig8) /* 8 */ + local_length_size /*type_offset size*/; break; } case DW_UT_skeleton: case DW_UT_split_compile: { types_extra_len = sizeof(Dwarf_Sig8) /* 8 */; break; } case DW_UT_compile: /* No additional fields */ case DW_UT_partial: /* No additional fields */ break; default: /* Data corruption in libdwarf? */ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg,error,DW_DLE_CU_UT_TYPE_VALUE); return DW_DLV_ERROR; } } /* Compare the space following the length field to the bytes in the CU header. */ if (length < (CU_VERSION_STAMP_SIZE /* is 2 */ + local_length_size /*for debug_abbrev offset */ + CU_ADDRESS_SIZE_SIZE /* is 1 */ + /* and finally size of the rest of the header: */ types_extra_len)) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } /* Now we can read the fields with some confidence, we know the fields of the header are inside the section. */ cu_context->cc_unit_type = unit_type; switch(unit_type) { case DW_UT_split_type: case DW_UT_type: { /* ASSERT: DW_CU_VERSION4 or DW_CU_VERSION5, determined by logic above. Now read the debug_types extra header fields of the signature (8 bytes) and the typeoffset. This can be in executable, ordinary object (as in Type Unit), there was no dwo in DWARF4 */ memcpy(&signaturedata,cu_ptr,sizeof(signaturedata)); cu_ptr += sizeof(signaturedata); READ_UNALIGNED_CK(dbg, typeoffset, Dwarf_Unsigned, cu_ptr, local_length_size,error,section_end_ptr); cu_context->cc_signature = signaturedata; cu_context->cc_signature_offset = typeoffset; cu_context->cc_signature_present = TRUE; if (typeoffset >= max_cu_local_offset) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPEOFFSET_BAD); return DW_DLV_ERROR; } } break; case DW_UT_skeleton: case DW_UT_split_compile: { /* These unit types make a pair and paired units have identical signature.*/ memcpy(&signaturedata,cu_ptr,sizeof(signaturedata)); cu_context->cc_signature = signaturedata; cu_context->cc_signature_present = TRUE; break; } /* The following with no additional fields */ case DW_UT_compile: case DW_UT_partial: break; default: /* Data corruption in libdwarf? */ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg,error,DW_DLE_CU_UT_TYPE_VALUE); return DW_DLV_ERROR; } cu_context->cc_abbrev_hash_table = (Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1); if (cu_context->cc_abbrev_hash_table == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } cu_context->cc_debug_offset = offset; /* This is recording an overall section value for later sanity checking. */ dis->de_last_offset = max_cu_global_offset; *context_out = cu_context; return DW_DLV_OK; } static int reloc_incomplete(int res,Dwarf_Error err) { int e = 0; if (res == DW_DLV_OK) { return FALSE; } if (res == DW_DLV_NO_ENTRY) { return FALSE; } e = dwarf_errno(err); if (e == DW_DLE_RELOC_MISMATCH_INDEX || e == DW_DLE_RELOC_MISMATCH_RELOC_INDEX || e == DW_DLE_RELOC_MISMATCH_STRTAB_INDEX || e == DW_DLE_RELOC_SECTION_MISMATCH || e == DW_DLE_RELOC_SECTION_MISSING_INDEX || e == DW_DLE_RELOC_SECTION_LENGTH_ODD || e == DW_DLE_RELOC_SECTION_PTR_NULL || e == DW_DLE_RELOC_SECTION_MALLOC_FAIL || e == DW_DLE_SEEK_OFF_END || e == DW_DLE_RELOC_INVALID || e == DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD ) { return TRUE; } return FALSE; } /* Returns offset of next compilation-unit thru next_cu_offset pointer. It sequentially moves from one cu to the next. The current cu is recorded internally by libdwarf. The _b form is new for DWARF4 adding new returned fields. */ int dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, Dwarf_Half * address_size, Dwarf_Unsigned * next_cu_offset, Dwarf_Error * error) { Dwarf_Bool is_info = true; Dwarf_Half header_type = 0; return _dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, 0,0,0,0,0, next_cu_offset, &header_type, error); } int dwarf_next_cu_header_b(Dwarf_Debug dbg, 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_Unsigned * next_cu_offset, Dwarf_Error * error) { Dwarf_Bool is_info = true; Dwarf_Half header_type = 0; return _dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, offset_size,extension_size, 0,0,0, next_cu_offset, &header_type, error); } int dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info, 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_Error * error) { Dwarf_Half header_type = 0; int res =_dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, abbrev_offset, address_size, offset_size, extension_size, signature, 0, typeoffset, next_cu_offset, &header_type, error); return res; } int dwarf_next_cu_header_d(Dwarf_Debug dbg, Dwarf_Bool is_info, 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) { /* Faking has_signature to do nothing. */ Dwarf_Bool* has_signature = 0; int res = 0; res = _dwarf_next_cu_header_internal(dbg, is_info, 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; } /* A DWO/DWP CU has different base fields than a normal object/executable, but this finds the base fields for both types. */ static int find_cu_die_base_fields(Dwarf_Debug dbg, Dwarf_Die cudie, Dwarf_Sig8 * dwoid_return, Dwarf_Bool * dwoid_present_return, Dwarf_Unsigned *str_offsets_base_return, Dwarf_Bool * str_offsets_base_present_return, Dwarf_Unsigned *addr_base_return, Dwarf_Bool * addr_base_present_return, Dwarf_Unsigned *ranges_base_return, /* rnglists_base */ Dwarf_Bool * ranges_base_present_return, Dwarf_Unsigned *loclists_base_return, /* rnglists_base */ Dwarf_Bool * loclists_base_present_return, char ** dwo_name_return, /* rnglists_base */ Dwarf_Bool * dwo_name_present_return, Dwarf_Bool * has_children_return, Dwarf_Error* error) { Dwarf_Sig8 signature; Dwarf_Bool dwoid_sig_present = FALSE; Dwarf_Off str_offsets_base = 0; Dwarf_Off ranges_base = 0; Dwarf_Off addr_base = 0; Dwarf_Bool str_offsets_base_present = FALSE; Dwarf_Bool addr_base_present = FALSE; Dwarf_Bool ranges_base_present = FALSE; Dwarf_Off loclists_base = 0; Dwarf_Bool loclists_base_present = 0; char * dwo_name = 0; Dwarf_Bool dwo_name_present = 0; Dwarf_Half version_stamp = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Attribute * alist = 0; Dwarf_Signed atcount = 0; int alres = 0; Dwarf_Half has_children = TRUE; int chres = 0; cu_context = cudie->di_cu_context; version_stamp = cu_context->cc_version_stamp; alres = dwarf_attrlist(cudie, &alist, &atcount,error); if(alres == DW_DLV_OK) { /* DW_AT_dwo_id and/or DW_AT_GNU_dwo_id are only found in some experimental DWARF4. DWARF5 changed CU header contents to make this attribute unnecessary. DW_AT_GNU_odr_signature is the same format, but is in a different namespace so not appropriate here.. */ Dwarf_Signed i = 0; for(i = 0; i < atcount; ++i) { Dwarf_Half attrnum; int ares = 0; Dwarf_Attribute attr = alist[i]; ares = dwarf_whatattr(attr,&attrnum,error); if (ares == DW_DLV_OK) { switch(attrnum) { case DW_AT_dwo_id: case DW_AT_GNU_dwo_id: { /* This is for DWARF4 with an early non-standard version of split dwarf. Not DWARF5. */ int sres = 0; if (version_stamp < DW_CU_VERSION4) { /* Not supposed to happen. */ _dwarf_error(dbg,error, DW_DLE_IMPROPER_DWO_ID); return DW_DLV_ERROR; } sres = dwarf_formsig8_const(attr, &signature,error); if(sres == DW_DLV_OK) { dwoid_sig_present = TRUE; } else { /* Something is badly wrong. */ dwarf_dealloc(dbg,attr,DW_DLA_ATTR); dwarf_dealloc(dbg,alist,DW_DLA_LIST); return sres; } break; } case DW_AT_str_offsets_base:{ int udres = 0; udres = dwarf_global_formref(attr,&str_offsets_base, error); if(udres == DW_DLV_OK) { str_offsets_base_present = TRUE; } else { dwarf_dealloc(dbg,attr,DW_DLA_ATTR); dwarf_dealloc(dbg,alist,DW_DLA_LIST); /* Something is badly wrong. */ return udres; } break; } case DW_AT_addr_base: case DW_AT_GNU_addr_base: { int udres = 0; udres = dwarf_global_formref(attr,&addr_base, error); if(udres == DW_DLV_OK) { addr_base_present = TRUE; } else { dwarf_dealloc(dbg,attr,DW_DLA_ATTR); dwarf_dealloc(dbg,alist,DW_DLA_LIST); /* Something is badly wrong. */ return udres; } break; } case DW_AT_GNU_ranges_base: /* The DW4 ranges base was never used in GNU but did get emitted in skeletons. http://llvm.1065342.n5.nabble.com/DebugInfo-DW-AT-GNU-ranges-base-in-non-fission-td64194.html We therefore ignore it. */ break; case DW_AT_rnglists_base: { int udres = 0; udres = dwarf_global_formref(attr,&ranges_base, error); if(udres == DW_DLV_OK) { ranges_base_present = TRUE; } else { dwarf_dealloc(dbg,attr,DW_DLA_ATTR); dwarf_dealloc(dbg,alist,DW_DLA_LIST); /* Something is badly wrong. */ return udres; } break; } case DW_AT_GNU_dwo_name: case DW_AT_dwo_name: { int dnres = 0; dwo_name_present = TRUE; dnres = dwarf_formstring(attr, &dwo_name,error); if (dnres != DW_DLV_OK) { return dnres; } break; } case DW_AT_loclists_base: { int udres = 0; udres = dwarf_global_formref(attr,&loclists_base, error); if(udres == DW_DLV_OK) { loclists_base_present = TRUE; } else { dwarf_dealloc(dbg,attr,DW_DLA_ATTR); dwarf_dealloc(dbg,alist,DW_DLA_LIST); /* Something is badly wrong. */ return udres; } break; } default: /* do nothing, not an attribute we need to deal with here. */ break; } } dwarf_dealloc(dbg,attr,DW_DLA_ATTR); } dwarf_dealloc(dbg,alist,DW_DLA_LIST); } else { /* Something is badly wrong. No attrlist! */ return alres; } *dwoid_present_return = dwoid_sig_present; *dwoid_return = signature; *str_offsets_base_present_return = str_offsets_base_present; *str_offsets_base_return = str_offsets_base; *addr_base_present_return = addr_base_present; *addr_base_return = addr_base; *ranges_base_present_return = ranges_base_present; *ranges_base_return = ranges_base; *loclists_base_present_return = loclists_base_present; *loclists_base_return = loclists_base; *dwo_name_present_return = dwo_name_present; *dwo_name_return = dwo_name; chres = dwarf_die_abbrev_children_flag(cudie, &has_children); *has_children_return = TRUE; if (chres == DW_DLV_OK) { if (!has_children) { *has_children_return = FALSE; } } else { /* Nothing we do here makes much sense. Pretend has children. */ } return DW_DLV_OK; } /* Called only for DWARF4 */ static void assign_correct_unit_type(Dwarf_CU_Context cu_context) { Dwarf_Half tag = cu_context->cc_cu_die_tag; if(!cu_context->cc_cu_die_has_children) { if(cu_context->cc_signature_present) { if (tag == DW_TAG_compile_unit || tag == DW_TAG_type_unit ) { cu_context->cc_unit_type = DW_UT_skeleton; } } } else { if(cu_context->cc_signature_present) { if (tag == DW_TAG_compile_unit) { cu_context->cc_unit_type = DW_UT_split_compile; } else if (tag == DW_TAG_type_unit) { cu_context->cc_unit_type = DW_UT_split_type; } } } } static int finish_up_cu_context_from_cudie(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_CU_Context cu_context, Dwarf_Error *error) { int version = cu_context->cc_version_stamp; Dwarf_Sig8 signaturedata; int res = 0; signaturedata = cu_context->cc_signature; res = fill_in_dwp_offsets_if_present(dbg, cu_context, &signaturedata, offset, error); if (res == DW_DLV_ERROR) { return res; } if (res != DW_DLV_OK) { return res; } if (cu_context->cc_dwp_offsets.pcu_type) { Dwarf_Unsigned absize = 0; Dwarf_Unsigned aboff = 0; aboff = _dwarf_get_dwp_extra_offset( &cu_context->cc_dwp_offsets, DW_SECT_ABBREV, &absize); cu_context->cc_abbrev_offset += aboff; } if (cu_context->cc_abbrev_offset >= dbg->de_debug_abbrev.dss_size) { _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR); return DW_DLV_ERROR; } /* Now we can read the CU die and determine the correct DW_UT_ type for DWARF4 and some offset base fields for DW4-fission and DW5 */ if (version == DW_CU_VERSION4 || version == DW_CU_VERSION5) { res = finish_cu_context_via_cudie_inner(dbg, cu_context, error); if(res == DW_DLV_ERROR) { return res; } if(res != DW_DLV_OK) { return res; } if (version == DW_CU_VERSION4) { assign_correct_unit_type(cu_context); } } return DW_DLV_OK; } int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool is_info, 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_out, Dwarf_Bool * has_signature, Dwarf_Unsigned *typeoffset, Dwarf_Unsigned * next_cu_offset, /* header_type: DW_UT_compile, DW_UT_partial, DW_UT_type, returned through the pointer. A new item in DWARF5, synthesized for earlier DWARF CUs (& TUs). */ Dwarf_Half * header_type, Dwarf_Error * error) { /* Offset for current and new CU. */ Dwarf_Unsigned new_offset = 0; /* CU Context for current CU. */ Dwarf_CU_Context cu_context = 0; Dwarf_Debug_InfoTypes dis = 0; Dwarf_Unsigned section_size = 0; int res = 0; /* ***** BEGIN CODE ***** */ if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; /* 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*/ strcpy(msg_buf,"Error:corrupted dwarf message table!"); } else { strcpy(msg_buf,msgprefix); strcpy(msg_buf+prefixlen,dwerrmsg); } dwarf_insert_harmless_error(dbg,msg_buf); /* Fall thru to use the newly loaded section. even though it might not be adequately relocated. */ } else { if (error) { *error = err2; err2 = 0; } /* There is nothing here, or what is here is damaged. */ return resd; } } } /* We are leaving new_offset zero. We are at the start of a section. */ } else { /* We already have is_info cu_context. */ new_offset = dis->de_cu_context->cc_debug_offset + dis->de_cu_context->cc_length + dis->de_cu_context->cc_length_size + dis->de_cu_context->cc_extension_size; } /* Check that there is room in .debug_info beyond the new offset for at least a new cu header. If not, return -1 (DW_DLV_NO_ENTRY) to indicate end of debug_info section, and reset de_cu_debug_info_offset to enable looping back through the cu's. */ section_size = is_info? dbg->de_debug_info.dss_size: dbg->de_debug_types.dss_size; if ((new_offset + _dwarf_length_of_cu_header_simple(dbg,is_info)) >= section_size) { dis->de_cu_context = NULL; return DW_DLV_NO_ENTRY; } /* Check if this CU has been read before. */ cu_context = _dwarf_find_CU_Context(dbg, new_offset,is_info); /* If not, make CU Context for it. */ if (cu_context == NULL) { res = _dwarf_make_CU_Context(dbg, new_offset,is_info, &cu_context,error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } res = finish_up_cu_context_from_cudie(dbg,new_offset, cu_context,error); if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); return res; } if (res == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); return res; } dis->de_cu_context = cu_context; if (dis->de_cu_context_list == NULL) { dis->de_cu_context_list = cu_context; dis->de_cu_context_list_end = cu_context; } else { dis->de_cu_context_list_end->cc_next = cu_context; dis->de_cu_context_list_end = cu_context; } } else { dis->de_cu_context = cu_context; } if (cu_header_length != NULL) { *cu_header_length = cu_context->cc_length; } if (version_stamp != NULL) { *version_stamp = cu_context->cc_version_stamp; } if (abbrev_offset != NULL) { *abbrev_offset = cu_context->cc_abbrev_offset; } if (address_size != NULL) { *address_size = cu_context->cc_address_size; } if (offset_size != NULL) { *offset_size = cu_context->cc_length_size; } if (extension_size != NULL) { *extension_size = cu_context->cc_extension_size; } if (header_type) { *header_type = cu_context->cc_unit_type; } if (typeoffset) { *typeoffset = cu_context->cc_signature_offset; } if (signature_out) { *signature_out = cu_context->cc_signature; } if (has_signature) { *has_signature = cu_context->cc_signature_present; } /* Determine the offset of the next CU. */ new_offset = new_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; /* Allowing null argument starting 22 April 2019. */ if (next_cu_offset) { *next_cu_offset = new_offset; } return DW_DLV_OK; } /* This involves data in a split dwarf or package file. Given hash signature, return the CU_die of the applicable CU. The hash is assumed to be from 'somewhere'. For DWARF 4: From a skeleton DIE DW_AT_GNU_dwo_id ("cu" case) or From a DW_FORM_ref_sig8 ("tu" case). For DWARF5: From dwo_id in a skeleton CU header (DW_UT_skeleton). From a DW_FORM_ref_sig8 ("tu" case). If "tu" request, the CU_die of of the type unit. Works on either a dwp package file or a dwo object. If "cu" request, the CU_die of the compilation unit. Works on either a dwp package file or a dwo object. If the hash passed is not present, returns DW_DLV_NO_ENTRY (but read the next two paragraphs for more detail). If a dwp package file with the hash signature is present in the applicable index but no matching compilation unit can be found, it returns DW_DLV_ERROR. If a .dwo object there is no index and we look at the compilation units (possibly all of them). If not present then we return DW_DLV_NO_ENTRY. The returned_die is a CU DIE if the sig_type is "cu". The returned_die is a type DIE if the sig_type is "tu". Perhaps both should return CU die. New 27 April, 2015 */ int dwarf_die_from_hash_signature(Dwarf_Debug dbg, Dwarf_Sig8 * hash_sig, const char * sig_type /* "tu" or "cu"*/, Dwarf_Die * returned_die, Dwarf_Error* error) { Dwarf_Bool is_type_unit = FALSE; int sres = 0; sres = _dwarf_load_debug_info(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } sres = _dwarf_load_debug_types(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } if (!strcmp(sig_type,"tu")) { is_type_unit = TRUE; } else if (!strcmp(sig_type,"cu")) { is_type_unit = FALSE; } else { _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING); return DW_DLV_ERROR; } if (_dwarf_file_has_debug_fission_index(dbg)) { /* This is a dwp package file. */ int fisres = 0; Dwarf_Bool is_info2 = 0; Dwarf_Off cu_header_off = 0; Dwarf_Off cu_size = 0; Dwarf_Off cu_die_off = 0; Dwarf_Off typeoffset = 0; Dwarf_Die cudie = 0; Dwarf_Die typedie = 0; Dwarf_CU_Context context = 0; Dwarf_Debug_Fission_Per_CU fiss; memset(&fiss,0,sizeof(fiss)); fisres = dwarf_get_debugfission_for_key(dbg,hash_sig, sig_type,&fiss,error); if (fisres != DW_DLV_OK) { return fisres; } /* Found it */ if(is_type_unit) { /* DW4 has debug_types, so look in .debug_types Else look in .debug_info. */ is_info2 = dbg->de_debug_types.dss_size?FALSE:TRUE; } else { is_info2 = TRUE; } cu_header_off = _dwarf_get_dwp_extra_offset(&fiss, is_info2?DW_SECT_INFO:DW_SECT_TYPES, &cu_size); fisres = dwarf_get_cu_die_offset_given_cu_header_offset_b( dbg,cu_header_off, is_info2, &cu_die_off,error); if (fisres != DW_DLV_OK) { return fisres; } fisres = dwarf_offdie_b(dbg,cu_die_off,is_info2, &cudie,error); if (fisres != DW_DLV_OK) { return fisres; } if (!is_type_unit) { *returned_die = cudie; return DW_DLV_OK; } context = cudie->di_cu_context; typeoffset = context->cc_signature_offset; typeoffset += cu_header_off; fisres = dwarf_offdie_b(dbg,typeoffset,is_info2, &typedie,error); if (fisres != DW_DLV_OK) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return fisres; } *returned_die = typedie; dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return DW_DLV_OK; } /* Look thru all the CUs, there is no DWP tu/cu index. There will be COMDAT sections for the type TUs (DW_UT_type). A single non-comdat for the DW_UT_compile. */ /* FIXME: DW_DLE_DEBUG_FISSION_INCOMPLETE */ _dwarf_error(dbg,error,DW_DLE_DEBUG_FISSION_INCOMPLETE); return DW_DLV_ERROR; } static int dwarf_ptr_CU_offset(Dwarf_CU_Context cu_context, Dwarf_Byte_Ptr di_ptr, Dwarf_Bool is_info, Dwarf_Off * cu_off) { Dwarf_Debug dbg = cu_context->cc_dbg; Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; *cu_off = (di_ptr - dataptr); return DW_DLV_OK; } #if 0 /* FOR DEBUGGING */ /* Just for debug purposes */ void print_sib_offset(Dwarf_Die sibling) { Dwarf_Off sib_off; Dwarf_Error error; dwarf_dieoffset(sibling,&sib_off,&error); fprintf(stderr," SIB OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,sib_off); } void print_ptr_offset(Dwarf_CU_Context cu_context,Dwarf_Byte_Ptr di_ptr) { Dwarf_Off ptr_off; dwarf_ptr_CU_offset(cu_context,di_ptr,&ptr_off); fprintf(stderr," PTR OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,ptr_off); } #endif /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child() called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset It is essentially guaranteed that dbg->de_last_die is a stale DIE pointer of a deallocated DIE when we get here. It must not be used as a DIE pointer here, just as a sort of anonymous pointer that we just check against NULL. There is a (subtle?) dependence on the fact that when we call this the last dwarf_child() call would have been for this sibling. Meaning that this works in a depth-first traversal even though there is no stack of 'de_last_die' values. The check for dbg->de_last_die just ensures sanity. If one is switching between normal debug_frame and eh_frame (traversing them in tandem, let us say) in a single Dwarf_Debug this validator makes no sense. It works if one processes a .debug_frame (entirely) and then an eh_frame (or vice versa) though. Use caution. */ int dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off *offset) { Dwarf_Debug dbg = 0; Dwarf_Error *error = 0; Dwarf_Debug_InfoTypes dis = 0; CHECK_DIE(sibling, DW_DLV_ERROR); dbg = sibling->di_cu_context->cc_dbg; dis = sibling->di_is_info? &dbg->de_info_reading: &dbg->de_types_reading; *offset = 0; if (dis->de_last_die && dis->de_last_di_ptr) { if (sibling->di_debug_ptr == dis->de_last_di_ptr) { return (DW_DLV_OK); } } /* Calculate global offset used for error reporting */ dwarf_ptr_CU_offset(sibling->di_cu_context, dis->de_last_di_ptr,sibling->di_is_info,offset); return (DW_DLV_ERROR); } /* This function does two slightly different things depending on the input flag want_AT_sibling. If this flag is true, it checks if the input die has a DW_AT_sibling attribute. If it does it returns a pointer to the start of the sibling die in the .debug_info section. Otherwise it behaves the same as the want_AT_sibling false case. If the want_AT_sibling flag is false, it returns a pointer to the immediately adjacent die in the .debug_info section. Die_info_end points to the end of the .debug_info portion for the cu the die belongs to. It is used to check that the search for the next die does not cross the end of the current cu. Cu_info_start points to the start of the .debug_info portion for the current cu, and is used to add to the offset for DW_AT_sibling attributes. Finally, has_die_child is a pointer to a Dwarf_Bool that is set true if the present die has children, false otherwise. However, in case want_AT_child is true and the die has a DW_AT_sibling attribute *has_die_child is set false to indicate that the children are being skipped. die_info_end points to the last byte+1 of the cu. */ static int _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, Dwarf_CU_Context cu_context, Dwarf_Byte_Ptr die_info_end, Dwarf_Byte_Ptr cu_info_start, Dwarf_Bool want_AT_sibling, Dwarf_Bool * has_die_child, Dwarf_Byte_Ptr *next_die_ptr_out, Dwarf_Error *error) { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Abbrev_List abbrev_list = 0; Dwarf_Half attr = 0; Dwarf_Half attr_form = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned utmp = 0; Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr abbrev_end = 0; int lres = 0; info_ptr = die_info_ptr; DECODE_LEB128_UWORD_CK(info_ptr, utmp,dbg,error,die_info_end); abbrev_code = (Dwarf_Unsigned) utmp; if (abbrev_code == 0) { /* Should never happen. Tested before we got here. */ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); return DW_DLV_ERROR; } lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code, &abbrev_list,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_NO_ABBREV_LIST); return DW_DLV_ERROR; } dbg = cu_context->cc_dbg; *has_die_child = abbrev_list->abl_has_child; abbrev_ptr = abbrev_list->abl_abbrev_ptr; abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(cu_context); do { Dwarf_Unsigned utmp2; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error, abbrev_end); if (utmp2 > DW_AT_hi_user) { _dwarf_error(dbg, error, DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } attr = (Dwarf_Half) utmp2; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error, abbrev_end); if (!_dwarf_valid_form_we_know(utmp2,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } attr_form = (Dwarf_Half) utmp2; if (attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; /* DECODE_LEB128_UWORD updates info_ptr */ DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error, die_info_end); attr_form = (Dwarf_Half) utmp6; } if (attr_form == DW_FORM_implicit_const) { UNUSEDARG Dwarf_Signed cval = 0; DECODE_LEB128_SWORD_CK(abbrev_ptr, cval,dbg,error, abbrev_end); } if (want_AT_sibling && attr == DW_AT_sibling) { switch (attr_form) { case DW_FORM_ref1: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr, sizeof(Dwarf_Small), error,die_info_end); break; case DW_FORM_ref2: /* READ_UNALIGNED does not update info_ptr */ READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr,DWARF_HALF_SIZE, error,die_info_end); break; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr, DWARF_32BIT_SIZE, error,die_info_end); break; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, info_ptr, DWARF_64BIT_SIZE, error,die_info_end); break; case DW_FORM_ref_udata: DECODE_LEB128_UWORD_CK(info_ptr, offset, dbg,error,die_info_end); break; case DW_FORM_ref_addr: /* Very unusual. The FORM is intended to refer to a different CU, but a different CU cannot be a sibling, can it? We could ignore this and treat as if no DW_AT_sibling present. Or derive the offset from it and if it is in the same CU use it directly. The offset here is *supposed* to be a global offset, so adding cu_info_start is wrong to any offset we find here unless cu_info_start is zero! Lets pretend there is no DW_AT_sibling attribute. */ goto no_sibling_attr; default: _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_WRONG_FORM); return DW_DLV_ERROR; } /* Reset *has_die_child to indicate children skipped. */ *has_die_child = false; /* A value beyond die_info_end indicates an error. Exactly at die_info_end means 1-past-cu-end and simply means we are at the end, do not return error. Higher level will detect that we are at the end. */ { /* Care required here. Offset can be garbage. */ ptrdiff_t plen = die_info_end - cu_info_start; ptrdiff_t signdoffset = (ptrdiff_t)offset; if (signdoffset > plen || signdoffset < 0) { /* Error case, bad DWARF. */ _dwarf_error(dbg, error,DW_DLE_SIBLING_OFFSET_WRONG); return DW_DLV_ERROR; } } /* At or before end-of-cu */ *next_die_ptr_out = cu_info_start + offset; return DW_DLV_OK; } no_sibling_attr: if (attr_form != 0 && attr_form != DW_FORM_implicit_const) { int res = 0; Dwarf_Unsigned sizeofval = 0; ptrdiff_t sizeb = 0; res = _dwarf_get_size_of_val(cu_context->cc_dbg, attr_form, cu_context->cc_version_stamp, cu_context->cc_address_size, info_ptr, cu_context->cc_length_size, &sizeofval, die_info_end, error); if(res != DW_DLV_OK) { return res; } /* It is ok for info_ptr == die_info_end, as we will test later before using a too-large info_ptr */ sizeb = (ptrdiff_t)sizeofval; if (sizeb > (die_info_end - info_ptr) || sizeb < 0) { _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END); return DW_DLV_ERROR; } info_ptr += sizeofval; if (info_ptr > die_info_end) { /* More than one-past-end indicates a bug somewhere, likely bad dwarf generation. */ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END); return DW_DLV_ERROR; } } } while (attr != 0 || attr_form != 0); *next_die_ptr_out = info_ptr; return DW_DLV_OK; } /* Multiple TAGs are in fact compile units. Allow them all. Return non-zero if a CU tag. Else return 0. */ static int is_cu_tag(int t) { if (t == DW_TAG_compile_unit || t == DW_TAG_partial_unit || t == DW_TAG_skeleton_unit || t == DW_TAG_type_unit) { return 1; } return 0; } /* Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns a Dwarf_Die for the sibling of die. In case die is NULL, it returns (thru ptr) a Dwarf_Die for the first die in the current cu in dbg. Returns DW_DLV_ERROR on error. It is assumed that every sibling chain including those with only one element is terminated with a NULL die, except a chain with only a NULL die. The algorithm moves from one die to the adjacent one. It returns when the depth of children it sees equals the number of sibling chain terminations. A single count, child_depth is used to track the depth of children and sibling terminations encountered. Child_depth is incremented when a die has the Has-Child flag set unless the child happens to be a NULL die. Child_depth is decremented when a die has Has-Child false, and the adjacent die is NULL. Algorithm returns when child_depth is 0. **NOTE: Do not modify input die, since it is used at the end. */ int dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { int res = 0; Dwarf_Bool is_info = TRUE; Dwarf_Debug_InfoTypes dis = 0; dis = &dbg->de_info_reading; res = _dwarf_siblingof_internal(dbg,die, die?die->di_cu_context:dis->de_cu_context, is_info,caller_ret_die,error); return res; } /* This is the new form, October 2011. On calling with 'die' NULL, we cannot tell if this is debug_info or debug_types, so we must be informed!. */ int dwarf_siblingof_b(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Bool is_info, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { int res; Dwarf_Debug_InfoTypes dis = 0; dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; res = _dwarf_siblingof_internal(dbg,die, die?die->di_cu_context:dis->de_cu_context, is_info,caller_ret_die,error); return res; } int _dwarf_siblingof_internal(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_CU_Context context, Dwarf_Bool is_info, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { Dwarf_Die ret_die = 0; Dwarf_Byte_Ptr die_info_ptr = 0; Dwarf_Byte_Ptr cu_info_start = 0; /* die_info_end points 1-past end of die (once set) */ Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; int lres = 0; /* Since die may be NULL, we rely on the input argument. */ Dwarf_Small *dataptr = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; 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) { _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT); 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; } else { /* Find sibling die. */ Dwarf_Bool has_child = false; Dwarf_Signed child_depth = 0; /* We cannot have a legal die unless debug_info was loaded, so no need to load debug_info here. */ CHECK_DIE(die, DW_DLV_ERROR); die_info_ptr = die->di_debug_ptr; if (*die_info_ptr == 0) { return (DW_DLV_NO_ENTRY); } context = die->di_cu_context; cu_info_start = dataptr+ context->cc_debug_offset; die_info_end = _dwarf_calculate_info_section_end_ptr(context); if ((*die_info_ptr) == 0) { return (DW_DLV_NO_ENTRY); } child_depth = 0; do { int res2 = 0; Dwarf_Byte_Ptr die_info_ptr2 = 0; res2 = _dwarf_next_die_info_ptr(die_info_ptr, context, die_info_end, cu_info_start, true, &has_child, &die_info_ptr2, error); if(res2 != DW_DLV_OK) { return res2; } if (die_info_ptr2 < die_info_ptr) { /* There is something very wrong, our die value decreased. Bad DWARF. */ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_LOW_ERROR); return (DW_DLV_ERROR); } if (die_info_ptr2 > die_info_end) { _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END); return (DW_DLV_ERROR); } die_info_ptr = die_info_ptr2; /* die_info_end is one past end. Do not read it! A test for ``!= die_info_end'' would work as well, but perhaps < reads more like the meaning. */ if (die_info_ptr < die_info_end) { if ((*die_info_ptr) == 0 && has_child) { die_info_ptr++; has_child = false; } } /* die_info_ptr can be one-past-end. */ if ((die_info_ptr == die_info_end) || ((*die_info_ptr) == 0)) { /* We are at the end of a sibling list. get back to the next containing sibling list (looking for a libling list with more on it). */ for (;;) { if (child_depth == 0) { /* Meaning there is no outer list, so stop. */ break; } if (die_info_ptr == die_info_end) { /* September 2016: do not deref if we are past end. If we are at end at this point it means the sibling list inside this CU is not properly terminated. August 2019: We used to declare an error, DW_DLE_SIBLING_LIST_IMPROPER but now we just silently declare this is the end of the list. Each level of a sibling nest should have a single NUL byte, but here things are wrong, the DWARF is corrupt. */ return DW_DLV_NO_ENTRY; } if (*die_info_ptr) { /* We have a real sibling. */ break; } /* Move out one DIE level. Move past NUL byte marking end of this sibling list. */ child_depth--; die_info_ptr++; } } else { child_depth = has_child ? child_depth + 1 : child_depth; } } while (child_depth != 0); } /* die_info_ptr > die_info_end is really a bug (possibly in dwarf generation)(but we are past end, no more DIEs here), whereas die_info_ptr == die_info_end means 'one past end, no more DIEs here'. */ if (die_info_ptr >= die_info_end) { return (DW_DLV_NO_ENTRY); } if ((*die_info_ptr) == 0) { return (DW_DLV_NO_ENTRY); } ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (ret_die == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } ret_die->di_is_info = is_info; ret_die->di_debug_ptr = die_info_ptr; ret_die->di_cu_context = die == NULL ? context : die->di_cu_context; DECODE_LEB128_UWORD_CK(die_info_ptr, utmp,dbg,error,die_info_end); if (die_info_ptr > die_info_end) { /* We managed to go past the end of the CU!. Something is badly wrong. */ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return (DW_DLV_ERROR); } abbrev_code = (Dwarf_Unsigned) utmp; if (abbrev_code == 0) { /* Zero means a null DIE */ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return (DW_DLV_NO_ENTRY); } ret_die->di_abbrev_code = abbrev_code; lres = _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code, &ret_die->di_abbrev_list,error); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL); return DW_DLV_ERROR; } if (die == NULL && !is_cu_tag(ret_die->di_abbrev_list->abl_tag)) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU); return DW_DLV_ERROR; } *caller_ret_die = ret_die; return (DW_DLV_OK); } int dwarf_child(Dwarf_Die die, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { Dwarf_Byte_Ptr die_info_ptr = 0; Dwarf_Byte_Ptr die_info_ptr2 = 0; /* die_info_end points one-past-end of die area. */ Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Die ret_die = 0; Dwarf_Bool has_die_child = 0; Dwarf_Debug dbg; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; Dwarf_Debug_InfoTypes dis = 0; int res = 0; Dwarf_CU_Context context = 0; int lres = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dis = die->di_is_info? &dbg->de_info_reading: &dbg->de_types_reading; die_info_ptr = die->di_debug_ptr; /* We are saving a DIE pointer here, but the pointer will not be presumed live later, when it is tested. */ dis->de_last_die = die; dis->de_last_di_ptr = die_info_ptr; /* NULL die has no child. */ if ((*die_info_ptr) == 0) { return DW_DLV_NO_ENTRY; } context = die->di_cu_context; die_info_end = _dwarf_calculate_info_section_end_ptr(context); res = _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context, die_info_end, NULL, false, &has_die_child, &die_info_ptr2, error); if(res != DW_DLV_OK) { return res; } if (die_info_ptr == die_info_end) { return DW_DLV_NO_ENTRY; } die_info_ptr = die_info_ptr2; dis->de_last_di_ptr = die_info_ptr; if (!has_die_child) { /* Look for end of sibling chain. */ while (dis->de_last_di_ptr < die_info_end) { if (*dis->de_last_di_ptr) { break; } ++dis->de_last_di_ptr; } return DW_DLV_NO_ENTRY; } ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (ret_die == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } ret_die->di_debug_ptr = die_info_ptr; ret_die->di_cu_context = die->di_cu_context; ret_die->di_is_info = die->di_is_info; DECODE_LEB128_UWORD_CK(die_info_ptr, utmp, dbg,error,die_info_end); abbrev_code = (Dwarf_Unsigned) utmp; dis->de_last_di_ptr = die_info_ptr; if (abbrev_code == 0) { /* Look for end of sibling chain */ while (dis->de_last_di_ptr < die_info_end) { if (*dis->de_last_di_ptr) { break; } ++dis->de_last_di_ptr; } /* We have arrived at a null DIE, at the end of a CU or the end of a list of siblings. */ *caller_ret_die = 0; dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return DW_DLV_NO_ENTRY; } ret_die->di_abbrev_code = abbrev_code; lres = _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code, &ret_die->di_abbrev_list,error); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_ABBREV_MISSING); return DW_DLV_ERROR; } *caller_ret_die = ret_die; return (DW_DLV_OK); } /* Given a (global, not cu_relative) die offset, this returns a pointer to a DIE thru *new_die. It is up to the caller to do a dwarf_dealloc(dbg,*new_die,DW_DLE_DIE); The old form only works with debug_info. The new _b form works with debug_info or debug_types. */ int dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error) { Dwarf_Bool is_info = true; return dwarf_offdie_b(dbg,offset,is_info,new_die,error); } int dwarf_offdie_b(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Die * new_die, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Off new_cu_offset = 0; Dwarf_Die die = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; int lres = 0; Dwarf_Debug_InfoTypes dis = 0; Dwarf_Byte_Ptr die_info_end = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; cu_context = _dwarf_find_CU_Context(dbg, offset,is_info); if (cu_context == NULL) { cu_context = _dwarf_find_offdie_CU_Context(dbg, offset,is_info); } if (cu_context == NULL) { Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size: dbg->de_debug_types.dss_size; int res = is_info?_dwarf_load_debug_info(dbg, error): _dwarf_load_debug_types(dbg,error); if (res != DW_DLV_OK) { return res; } if (dis->de_offdie_cu_context_end != NULL) { Dwarf_CU_Context lcu_context = dis->de_offdie_cu_context_end; new_cu_offset = lcu_context->cc_debug_offset + lcu_context->cc_length + lcu_context->cc_length_size + lcu_context->cc_extension_size; } do { if ((new_cu_offset + _dwarf_length_of_cu_header_simple(dbg,is_info)) >= section_size) { _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD); return (DW_DLV_ERROR); } res = _dwarf_make_CU_Context(dbg, new_cu_offset,is_info, &cu_context,error); if (res != DW_DLV_OK) { return res; } res = finish_up_cu_context_from_cudie(dbg,new_cu_offset, cu_context,error); if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); return res; } if (res == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); return res; } if (dis->de_offdie_cu_context == NULL) { dis->de_offdie_cu_context = cu_context; dis->de_offdie_cu_context_end = cu_context; } else { dis->de_offdie_cu_context_end->cc_next = cu_context; dis->de_offdie_cu_context_end = cu_context; } new_cu_offset = new_cu_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; } while (offset >= new_cu_offset); } die_info_end = _dwarf_calculate_info_section_end_ptr(cu_context); die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (die == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } die->di_cu_context = cu_context; die->di_is_info = is_info; { Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; info_ptr = dataptr + offset; } die->di_debug_ptr = info_ptr; DECODE_LEB128_UWORD_CK(info_ptr, utmp,dbg,error,die_info_end); abbrev_code = utmp; if (abbrev_code == 0) { /* we are at a null DIE (or there is a bug). */ *new_die = 0; dwarf_dealloc(dbg, die, DW_DLA_DIE); return DW_DLV_NO_ENTRY; } die->di_abbrev_code = abbrev_code; lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code, &die->di_abbrev_list,error); if (lres == DW_DLV_ERROR) { dwarf_dealloc(dbg, die, DW_DLA_DIE); return lres; } if (lres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, die, DW_DLA_DIE); _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL); return DW_DLV_ERROR; } *new_die = die; return DW_DLV_OK; } /* New March 2016. Lets one cross check the abbreviations section and the DIE information presented by dwarfdump -i -G -v. */ int dwarf_die_abbrev_global_offset(Dwarf_Die die, Dwarf_Off * abbrev_goffset, Dwarf_Unsigned * abbrev_count, Dwarf_Error* error) { Dwarf_Abbrev_List dal = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dal = die->di_abbrev_list; if(!dal) { _dwarf_error(dbg,error,DW_DLE_DWARF_ABBREV_NULL); return DW_DLV_ERROR; } *abbrev_goffset = dal->abl_goffset; *abbrev_count = dal->abl_count; return DW_DLV_OK; } /* New August 2018. Because some real compressed sections have .zdebug instead of .debug as the leading characters. actual_sec_name_out points to a static string so so not free it. */ int dwarf_get_real_section_name(Dwarf_Debug dbg, const char *std_section_name, const char **actual_sec_name_out, Dwarf_Small *marked_zcompressed, /* zdebug */ Dwarf_Small *marked_zlib_compressed, /* ZLIB string */ Dwarf_Small *marked_shf_compressed, /* SHF_COMPRESSED */ Dwarf_Unsigned *compressed_length, Dwarf_Unsigned *uncompressed_length, Dwarf_Error *error) { unsigned i = 0; char tbuf[50]; unsigned std_sec_name_len = strlen(std_section_name); tbuf[0] = 0; /* 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)) { strcpy(tbuf,std_section_name); strcpy(tbuf+std_sec_name_len,".dwo"); } 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; const char *std = section->dss_standard_name; if (!strcmp(std,std_section_name) || !strcmp(std,tbuf)) { const char *used = section->dss_name; *actual_sec_name_out = used; if (sdata->ds_have_zdebug) { *marked_zcompressed = TRUE; } if (section->dss_ZLIB_compressed) { *marked_zlib_compressed = TRUE; if (uncompressed_length) { *uncompressed_length = section->dss_uncompressed_length; } if (compressed_length) { *compressed_length = section->dss_compressed_length; } } if (section->dss_shf_compressed) { *marked_shf_compressed = TRUE; if (uncompressed_length) { *uncompressed_length = section->dss_uncompressed_length; } if (compressed_length) { *compressed_length = section->dss_compressed_length; } } return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* This is useful when printing DIE data. The string pointer returned must not be freed. With non-elf objects it is possible the string returned might be empty or NULL, so callers should be prepared for that kind of return. */ int dwarf_get_die_section_name(Dwarf_Debug dbg, Dwarf_Bool is_info, const char ** sec_name, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } if (is_info) { sec = &dbg->de_debug_info; } else { sec = &dbg->de_debug_types; } if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name = sec->dss_name; return DW_DLV_OK; } /* This one assumes is_info not known to caller but a DIE is known. */ int dwarf_get_die_section_name_b(Dwarf_Die die, const char ** sec_name, Dwarf_Error * error) { Dwarf_CU_Context context = 0; Dwarf_Bool is_info = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; is_info = context->cc_is_info; return dwarf_get_die_section_name(dbg,is_info,sec_name,error); } dwarfutils-20200114/libdwarf/dwarf_die_deliv.h000066400000000000000000000035051361531463500212150ustar00rootroot00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This struct holds information about an abbreviation. It is put in the hash table for abbreviations for a compile-unit. */ struct Dwarf_Abbrev_List_s { Dwarf_Unsigned abl_code; Dwarf_Half abl_tag; Dwarf_Half abl_has_child; /* Section global offset of this abbrev entry. */ Dwarf_Off abl_goffset; /* Singly linked synonym list in case of duplicate hash. */ struct Dwarf_Abbrev_List_s *abl_next; /* Points to start of attribute/form pairs in the .debug_abbrev section for the abbrev. */ Dwarf_Byte_Ptr abl_abbrev_ptr; /* The number of at/form[/implicitvalue] pairs in this abbrev. */ Dwarf_Unsigned abl_count; }; dwarfutils-20200114/libdwarf/dwarf_dnames.c000066400000000000000000001171771361531463500205460ustar00rootroot00000000000000/* Portions Copyright (C) 2017-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This provides access to the DWARF5 .debug_names section. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_global.h" #include "dwarf_dnames.h" #define FALSE 0 #define TRUE 1 /* freedabs attempts to do some cleanup in the face of an error. */ static void freedabs(struct Dwarf_D_Abbrev_s *dab) { struct Dwarf_D_Abbrev_s *tmp = 0; for(; dab; dab = tmp) { tmp = dab->da_next; free(dab); } } /* Encapsulates DECODE_LEB128_UWORD_CK so the caller can free resources in case of problems. */ static int read_uword_ab(Dwarf_Small **lp, Dwarf_Unsigned *out_p, Dwarf_Debug dbg, Dwarf_Error *err, Dwarf_Small *lpend) { Dwarf_Small *inptr = *lp; Dwarf_Unsigned out = 0; /* The macro updates inptr */ DECODE_LEB128_UWORD_CK(inptr, out, dbg,err,lpend); *lp = inptr; *out_p = out; return DW_DLV_OK; } static int fill_in_abbrevs_table(struct Dwarf_Dnames_index_header_s * dn, Dwarf_Error * error) { Dwarf_Small *abdata = dn->din_abbreviations; Dwarf_Unsigned ablen = dn->din_abbrev_table_size; Dwarf_Small *tabend = abdata+ablen; Dwarf_Small *abcur = 0; Dwarf_Unsigned code = 0; Dwarf_Unsigned tag = 0; int foundabend = FALSE; unsigned abcount = 0; struct Dwarf_D_Abbrev_s *firstdab = 0; struct Dwarf_D_Abbrev_s *lastdab = 0; struct Dwarf_D_Abbrev_s *curdab = 0; Dwarf_Debug dbg = dn->din_dbg; for (abcur = abdata; abcur < tabend; ) { Dwarf_Unsigned idx = 0; Dwarf_Unsigned form = 0; Dwarf_Small *inner = 0; unsigned idxcount = 0; int res = 0; res = read_uword_ab(&abcur,&code,dbg,error,tabend); if (res != DW_DLV_OK) { freedabs(firstdab); return res; } if (code == 0) { foundabend = TRUE; break; } res = read_uword_ab(&abcur,&tag,dbg,error,tabend); if (res != DW_DLV_OK) { freedabs(firstdab); return res; } inner = abcur; curdab = (struct Dwarf_D_Abbrev_s *)calloc(1, sizeof(struct Dwarf_D_Abbrev_s)); if(!curdab) { freedabs(firstdab); firstdab = 0; _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curdab->da_tag = tag; curdab->da_abbrev_code = code; abcount++; for(;;) { res = read_uword_ab(&inner,&idx,dbg,error,tabend); if (res != DW_DLV_OK) { free(curdab); freedabs(firstdab); firstdab = 0; return res; } res = read_uword_ab(&inner,&form,dbg,error,tabend); if (res != DW_DLV_OK) { free(curdab); freedabs(firstdab); firstdab = 0; return res; } if (!idx && !form) { break; } if (idxcount >= ABB_PAIRS_MAX) { free(curdab); freedabs(firstdab); firstdab = 0; _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW); return DW_DLV_ERROR; } curdab->da_pairs[idxcount].ap_index = idx; curdab->da_pairs[idxcount].ap_form = form; idxcount++; } curdab->da_pairs_count = idxcount; abcur = inner +1; if (!firstdab) { firstdab = curdab; lastdab = curdab; } else { /* Add new on the end, last */ lastdab->da_next = curdab; } } if (!foundabend) { freedabs(firstdab); _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION); return DW_DLV_OK; } { unsigned ct = 0; struct Dwarf_D_Abbrev_s *tmpa = 0; dn->din_abbrev_list = (struct Dwarf_D_Abbrev_s *)calloc( abcount,sizeof(struct Dwarf_D_Abbrev_s)); if(!dn->din_abbrev_list) { freedabs(firstdab); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dn->din_abbrev_list_count = abcount; tmpa = firstdab; for(ct = 0; tmpa && ct < abcount; ++ct) { struct Dwarf_D_Abbrev_s *tmpb =tmpa->da_next; /* da_next no longer means anything */ dn->din_abbrev_list[ct] = *tmpa; dn->din_abbrev_list[ct].da_next = 0; tmpa = tmpb; } freedabs(firstdab); tmpa = 0; firstdab = 0; lastdab = 0; /* Now the list has turned into an array. We can ignore the list aspect. */ } return DW_DLV_OK; } static int get_inhdr_cur(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, struct Dwarf_Dnames_index_header_s **cur, Dwarf_Error *error) { Dwarf_Debug dbg = 0; if (!dn) { _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_NULL_POINTER); return DW_DLV_ERROR; } dbg = dn->dn_dbg; if (index_number >= dn->dn_inhdr_count) { _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } *cur = dn->dn_inhdr_first + index_number; return DW_DLV_OK; } static int read_uword_val(Dwarf_Debug dbg, Dwarf_Small **ptr_in, Dwarf_Small *endptr, int errcode, Dwarf_Unsigned *val_out, Dwarf_Unsigned area_length, Dwarf_Error *error) { Dwarf_Unsigned val = 0; Dwarf_Small *ptr = *ptr_in; READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); ptr += DWARF_32BIT_SIZE; if (ptr >= endptr) { _dwarf_error(dbg, error,errcode); return DW_DLV_ERROR; } /* Some of the fields are not length fields, but if non-zero the size will be longer than the value, so we do the following overall sanity check to avoid overflows. */ if (val > area_length) { _dwarf_error(dbg, error,errcode); return DW_DLV_ERROR; } *val_out = val; *ptr_in = ptr; return DW_DLV_OK; } /* We do not alter the dn data here. */ static int read_a_name_index(Dwarf_Dnames_Head dn, Dwarf_Unsigned section_offset, Dwarf_Small **curptr_in, Dwarf_Small *end_section, Dwarf_Unsigned remaining_section_size, struct Dwarf_Dnames_index_header_s ** index_header_out, Dwarf_Error *error) { Dwarf_Unsigned area_length = 0; int local_length_size; int local_extension_size = 0; Dwarf_Small *past_length = 0; Dwarf_Small *end_dnames = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; Dwarf_Unsigned comp_unit_count = 0; Dwarf_Unsigned local_type_unit_count = 0; Dwarf_Unsigned foreign_type_unit_count = 0; Dwarf_Unsigned bucket_count = 0; Dwarf_Unsigned name_count = 0; Dwarf_Unsigned abbrev_table_size = 0; /* bytes */ Dwarf_Unsigned augmentation_string_size = 0; /* bytes */ int res = 0; const char *str_utf8 = 0; Dwarf_Small *curptr = *curptr_in; struct Dwarf_Dnames_index_header_s *di_header = 0; Dwarf_Debug dbg = dn->dn_dbg; READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned, curptr, local_length_size, local_extension_size,error, remaining_section_size,end_section); /* curptr now points past the length field */ past_length = curptr; /* Two stage length test so overflow is caught. */ if (area_length > remaining_section_size) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } if ((area_length + local_length_size + local_extension_size) > remaining_section_size) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } end_dnames = curptr + area_length; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, curptr, DWARF_HALF_SIZE, error,end_dnames); curptr += DWARF_HALF_SIZE; if (curptr >= end_dnames) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } if (version != DWARF_DNAMES_VERSION5) { _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg, padding, Dwarf_Half, curptr, DWARF_HALF_SIZE, error,end_dnames); curptr += DWARF_HALF_SIZE; if (curptr >= end_dnames) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } if (padding) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return (DW_DLV_ERROR); } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &comp_unit_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &local_type_unit_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &foreign_type_unit_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &bucket_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &name_count,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &abbrev_table_size,area_length,error); if (res != DW_DLV_OK) { return res; } res = read_uword_val(dbg, &curptr, end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, &augmentation_string_size,area_length,error); if (res != DW_DLV_OK) { return res; } str_utf8 = (const char *) curptr; curptr+= augmentation_string_size; if (curptr >= end_dnames) { _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header = (struct Dwarf_Dnames_index_header_s *) calloc(1,sizeof(*di_header)); if(!di_header) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } di_header->din_dbg = dbg; di_header->din_section_offset = section_offset; di_header->din_indextable_data = past_length; di_header->din_indextable_length = area_length; di_header->din_version = version; di_header->din_comp_unit_count = comp_unit_count; di_header->din_local_type_unit_count = local_type_unit_count ; di_header->din_foreign_type_unit_count = foreign_type_unit_count ; di_header->din_bucket_count = bucket_count ; di_header->din_name_count = name_count ; di_header->din_abbrev_table_size = abbrev_table_size; di_header->din_augmentation_string_size = augmentation_string_size; di_header->din_augmentation_string = calloc(1, augmentation_string_size +1); strncpy(di_header->din_augmentation_string,str_utf8, augmentation_string_size); { /* This deals with a zero length string too. */ Dwarf_Unsigned len = augmentation_string_size; char *cp = 0; char *cpend = 0; Dwarf_Bool foundnull = FALSE; cp = di_header->din_augmentation_string; cpend = cp + len; for( ; cpdin_cu_list = curptr; curptr += dbg->de_length_size * comp_unit_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_local_tu_list = curptr; curptr += dbg->de_length_size * local_type_unit_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_foreign_tu_list = curptr; curptr += sizeof(Dwarf_Sig8) * foreign_type_unit_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_buckets = curptr; curptr += DWARF_32BIT_SIZE * bucket_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_hash_table = curptr; curptr += sizeof(Dwarf_Sig8) * name_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_string_offsets = curptr; curptr += DWARF_32BIT_SIZE * name_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_entry_offsets = curptr; curptr += DWARF_32BIT_SIZE * name_count; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_abbreviations = curptr; curptr += abbrev_table_size; if(curptr > end_dnames) { free(di_header->din_augmentation_string); free(di_header); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); return DW_DLV_ERROR; } di_header->din_entry_pool = curptr; di_header->din_offset_size = local_length_size; di_header->din_entry_pool_size = end_dnames - curptr; *curptr_in = curptr; *index_header_out = di_header; res = fill_in_abbrevs_table(di_header,error); if (res != DW_DLV_OK) { free(di_header->din_augmentation_string); free(di_header); return res; } return DW_DLV_OK; } #define FAKE_LAST_USED 0xffffffff static void free_inhdr_content(struct Dwarf_Dnames_index_header_s *f) { free(f->din_augmentation_string); free(f->din_abbrev_list); } static void free_inhdr_list(struct Dwarf_Dnames_index_header_s *f) { struct Dwarf_Dnames_index_header_s *tmp = 0; for( ; f ; f = tmp) { tmp = f->din_next; free_inhdr_content(f); free(f); } } /* There may be one debug index for an entire object file, for multiple CUs or there can be individual indexes for some CUs. see DWARF5 6.1.1.3 Per_CU versus Per-Module Indexes. */ int dwarf_debugnames_header(Dwarf_Debug dbg, Dwarf_Dnames_Head * dn_out, Dwarf_Unsigned * dn_count_out, Dwarf_Error *error) { Dwarf_Unsigned remaining = 0; Dwarf_Dnames_Head dn_header = 0; Dwarf_Unsigned section_size; Dwarf_Small *start_section = 0; Dwarf_Small *end_section = 0; Dwarf_Small *curptr = 0; struct Dwarf_Dnames_index_header_s *inhdr_last = 0; struct Dwarf_Dnames_index_header_s *inhdr_first = 0; unsigned inhdr_count = 0; int res = 0; if(!dbg) { _dwarf_error(dbg, error,DW_DLE_DBG_NULL); return DW_DLV_ERROR; } res = _dwarf_load_section(dbg, &dbg->de_debug_names, error); if (res != DW_DLV_OK) { return res; } section_size = dbg->de_debug_names.dss_size; if(!section_size){ return DW_DLV_NO_ENTRY; } start_section = dbg->de_debug_names.dss_data; curptr = start_section; end_section = start_section + section_size; remaining = section_size; dn_header = (Dwarf_Dnames_Head)_dwarf_get_alloc(dbg, DW_DLA_DNAMES_HEAD, 1); if(!dn_header) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dn_header->dn_section_data = start_section; dn_header->dn_section_size = section_size; dn_header->dn_section_end = start_section + section_size; dn_header->dn_dbg = dbg; for( ; curptr < end_section; ) { struct Dwarf_Dnames_index_header_s * index_header = 0; Dwarf_Small *curptr_start = curptr; Dwarf_Unsigned usedspace = 0; Dwarf_Unsigned section_offset = curptr - start_section; res = read_a_name_index(dn_header, section_offset, &curptr, end_section, remaining, &index_header, error); if (res == DW_DLV_ERROR) { free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); return res; } if (res == DW_DLV_NO_ENTRY) { /* Impossible. A bug. Or possibly a bunch of zero pad? */ free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); break; } /* Add the new one to the list. */ if(!inhdr_first) { inhdr_count = 1; inhdr_first = index_header; inhdr_last = index_header; } else { struct Dwarf_Dnames_index_header_s *tmp = inhdr_last; inhdr_last = index_header; tmp->din_next = index_header; inhdr_count++; } usedspace = curptr - curptr_start; remaining -= - usedspace; if (remaining < 5) { /* No more in here, just padding. Check for zero in padding. */ if ((curptr +remaining) < end_section) { free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_OFF_END); return DW_DLV_ERROR; } for ( ; curptr < end_section; ++curptr) { if(*curptr) { /* One could argue this is a harmless error, but for now assume it is real corruption. */ free_inhdr_list(inhdr_first); dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_PAD_NON_ZERO); return DW_DLV_ERROR; } } } } { struct Dwarf_Dnames_index_header_s *cur = 0; int n = 0; dn_header->dn_inhdr_first = (struct Dwarf_Dnames_index_header_s *) calloc(inhdr_count,sizeof(struct Dwarf_Dnames_index_header_s)); for(n = 0,cur = inhdr_first; cur; ++n ) { /* We are copying these structs so do not free them at this time. */ struct Dwarf_Dnames_index_header_s *tmp = cur->din_next; dn_header->dn_inhdr_first[n] = *cur; cur = tmp; } } *dn_out = dn_header; *dn_count_out = inhdr_count; return DW_DLV_OK; } int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned * section_offset, Dwarf_Unsigned * version, /* 5 */ Dwarf_Unsigned * offset_size, /* 4 or 8 */ /* The counts are entry counts, not bye sizes. */ Dwarf_Unsigned * comp_unit_count, Dwarf_Unsigned * local_type_unit_count, Dwarf_Unsigned * foreign_type_unit_count, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * name_count, /* The following are counted in bytes */ Dwarf_Unsigned * indextable_overall_length, Dwarf_Unsigned * abbrev_table_size, Dwarf_Unsigned * entry_pool_size, Dwarf_Unsigned * augmentation_string_size, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; int res = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if(res != DW_DLV_OK) { return res; } if (section_offset) { *section_offset = cur->din_section_offset; } if (version) { *version = cur->din_version; } if (offset_size) { *offset_size = cur->din_offset_size; } if (comp_unit_count) { *comp_unit_count = cur->din_comp_unit_count; } if (local_type_unit_count) { *local_type_unit_count = cur->din_local_type_unit_count; } if (foreign_type_unit_count) { *foreign_type_unit_count = cur->din_foreign_type_unit_count; } if (bucket_count) { *bucket_count = cur->din_bucket_count; } if (name_count) { *name_count = cur->din_name_count; } if (abbrev_table_size) { *abbrev_table_size = cur->din_abbrev_table_size; } if (entry_pool_size) { *entry_pool_size = cur->din_entry_pool_size; } if (augmentation_string_size) { *augmentation_string_size = cur->din_augmentation_string_size; } if (indextable_overall_length) { *indextable_overall_length = cur->din_indextable_length; } return DW_DLV_OK; } int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (offset_number >= cur->din_comp_unit_count) { if (offset_count) { *offset_count = cur->din_comp_unit_count; } return DW_DLV_NO_ENTRY; } if (offset) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_cu_list + offset_number *cur->din_offset_size; Dwarf_Small *endptr = cur->din_local_tu_list; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, cur->din_offset_size, error,endptr); *offset = offsetval; } if (offset_count) { *offset_count = cur->din_comp_unit_count; } return DW_DLV_OK; } int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (offset_number >= cur->din_local_type_unit_count) { if (offset_count) { *offset_count = cur->din_local_type_unit_count; } return DW_DLV_NO_ENTRY; } if (offset) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_local_tu_list + offset_number *cur->din_offset_size; Dwarf_Small *endptr = cur->din_foreign_tu_list; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, cur->din_offset_size, error,endptr); *offset = offsetval; } if (offset_count) { *offset_count = cur->din_local_type_unit_count; } return DW_DLV_OK; } /* Here the sig_number ranges from local_type_unit_count to local_type_unit_count+foreign_type_unit_count-1 because the foreign indices are a continuation of the local tu indices. */ int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned sig_number, /* these index starting at local_type_unit_count */ Dwarf_Unsigned * sig_minimum, Dwarf_Unsigned * sig_count, Dwarf_Sig8 * signature, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; unsigned legal_low = 0; unsigned legal_high = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; legal_low = cur->din_local_type_unit_count; legal_high = legal_low + cur->din_foreign_type_unit_count; if (sig_number < legal_low) { _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } if (sig_number >= legal_high) { if (sig_minimum) { *sig_minimum = legal_low; } if (sig_count) { *sig_count = cur->din_foreign_type_unit_count; } return DW_DLV_NO_ENTRY; } if (signature) { Dwarf_Small *ptr = cur->din_foreign_tu_list + sig_number *cur->din_offset_size; Dwarf_Small *endptr = cur->din_hash_table; if((ptr +sizeof(Dwarf_Sig8)) > endptr) { _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } memcpy(signature,ptr,sizeof(Dwarf_Sig8)); } if (sig_minimum) { *sig_minimum = legal_low; } if (sig_count) { *sig_count = cur->din_foreign_type_unit_count; } return DW_DLV_OK; } /* The hash table is composed of the buckets table and the hashes table. If there is no buckets table (bucket_count == 0) the hashes part still exists. */ int dwarf_debugnames_bucket(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned bucket_number, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * index_of_name_entry, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (bucket_number >= cur->din_bucket_count) { if (bucket_count) { *bucket_count = cur->din_bucket_count; } return DW_DLV_NO_ENTRY; } if (index_of_name_entry) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_buckets + bucket_number * DWARF_32BIT_SIZE; Dwarf_Small *endptr = cur->din_hash_table; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); *index_of_name_entry = offsetval; } if (bucket_count) { *bucket_count = cur->din_bucket_count; } return DW_DLV_OK; } /* Access to the .debug_names name table. */ int dwarf_debugnames_name(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned name_entry, Dwarf_Unsigned * names_count, Dwarf_Sig8 * signature, Dwarf_Unsigned * offset_to_debug_str, Dwarf_Unsigned * offset_in_entrypool, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (name_entry >= cur->din_name_count) { if (names_count) { *names_count = cur->din_bucket_count; } return DW_DLV_NO_ENTRY; } if (signature) { Dwarf_Small *ptr = cur->din_hash_table + name_entry *sizeof(Dwarf_Sig8); Dwarf_Small *endptr = cur->din_string_offsets; if ((ptr + sizeof(Dwarf_Sig8)) > endptr) { _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); return DW_DLV_ERROR; } memcpy(signature,ptr,sizeof(Dwarf_Sig8)); } if (offset_to_debug_str) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_string_offsets + name_entry * DWARF_32BIT_SIZE; Dwarf_Small *endptr = cur->din_abbreviations; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); *offset_to_debug_str = offsetval; } if (offset_in_entrypool) { Dwarf_Unsigned offsetval = 0; Dwarf_Small *ptr = cur->din_entry_offsets + name_entry * DWARF_32BIT_SIZE; Dwarf_Small *endptr = cur->din_abbreviations; READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, ptr, DWARF_32BIT_SIZE, error,endptr); *offset_in_entrypool = offsetval; } if (names_count) { *names_count = cur->din_name_count; } return DW_DLV_OK; } /* If abbrev_code returned is zero there is no tag returned and we are at the end of the entry pool set for this name entry. abbrev code, tag nameindexattr,form ... 0,0 ... repeat like the above 0 */ /* This provides a way to print the abbrev table by indexing from 0. */ int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * number_of_abbrev, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error *error) { struct Dwarf_Dnames_index_header_s *cur = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; int res = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } if (abbrev_entry >= cur->din_abbrev_list_count) { if (number_of_abbrev) { *number_of_abbrev = cur->din_abbrev_list_count; } return DW_DLV_NO_ENTRY; } abbrev = cur->din_abbrev_list + abbrev_entry; if(abbrev_code) { *abbrev_code = abbrev->da_abbrev_code; } if(tag) { *tag = abbrev->da_tag; } if(number_of_abbrev) { *number_of_abbrev = cur->din_abbrev_list_count; } if(number_of_attr_form_entries) { *number_of_attr_form_entries = abbrev->da_pairs_count; } return DW_DLV_OK; } static int _dwarf_internal_abbrev_by_code(struct Dwarf_Dnames_index_header_s *cur, Dwarf_Unsigned abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * number_of_attr_form_entries) { unsigned n = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; abbrev = cur->din_abbrev_list; for(n = 0; n < cur->din_abbrev_list_count; ++n,++abbrev) { if (abbrev_code == abbrev->da_abbrev_code) { if (tag) { *tag = abbrev->da_tag; } if (index_of_abbrev) { *index_of_abbrev = n; } if (number_of_attr_form_entries) { *number_of_attr_form_entries = abbrev->da_pairs_count; } return DW_DLV_OK; } } /* Something is wrong, not found! */ return DW_DLV_NO_ENTRY; } /* Access the abbrev by abbrev code (instead of index). */ int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_code, Dwarf_Unsigned * tag, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * index_of_abbrev, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_internal_abbrev_by_code(cur, abbrev_code, tag, index_of_abbrev, number_of_attr_form_entries); return res; } int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry_index, Dwarf_Unsigned abbrev_form_index, Dwarf_Unsigned * name_index_attr, Dwarf_Unsigned * form, Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; struct abbrev_pair_s *ap = 0; int res; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } if (abbrev_entry_index >= cur->din_abbrev_list_count) { if (number_of_attr_form_entries) { *number_of_attr_form_entries = cur->din_bucket_count; } return DW_DLV_NO_ENTRY; } abbrev = cur->din_abbrev_list + abbrev_entry_index; if (abbrev_form_index >= abbrev->da_pairs_count) { return DW_DLV_NO_ENTRY; } ap = abbrev->da_pairs + abbrev_entry_index; if(name_index_attr) { *name_index_attr = ap->ap_index; } if(form) { *form = ap->ap_form; } if(number_of_attr_form_entries) { *number_of_attr_form_entries = abbrev->da_pairs_count; } return DW_DLV_OK; } /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_in_entrypool, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * value_count, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * offset_of_initial_value, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Small *entrypool = 0; Dwarf_Small *endentrypool = 0; Dwarf_Unsigned abcode = 0; Dwarf_Unsigned leblen = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; if (offset_in_entrypool >= cur->din_entry_pool_size) { _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET); return DW_DLV_ERROR; } endentrypool = cur->din_entry_pool +cur->din_entry_pool_size; entrypool = cur->din_entry_pool + offset_in_entrypool; DECODE_LEB128_UWORD_LEN_CK(entrypool,abcode,leblen, dbg,error,endentrypool); res = _dwarf_internal_abbrev_by_code(cur, abcode, tag, index_of_abbrev, value_count); if (res != DW_DLV_OK) { /* Never DW_DLV_ERROR (so far) */ return res; } *offset_of_initial_value = offset_in_entrypool + leblen; *abbrev_code = abcode; return DW_DLV_OK; } /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. While an array of structs would be easier for the caller to allocate than parallel arrays, public structs have turned out to be difficult to work with as interfaces (as formats change over time). */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned index_of_abbrev, Dwarf_Unsigned offset_in_entrypool_of_values, Dwarf_Unsigned * array_dw_idx_number, Dwarf_Unsigned * array_form, Dwarf_Unsigned * array_of_offsets, Dwarf_Sig8 * array_of_signatures, /* offset of the next entrypool entry. */ Dwarf_Unsigned * offset_of_next_entrypool, Dwarf_Error * error) { struct Dwarf_Dnames_index_header_s *cur = 0; struct Dwarf_D_Abbrev_s * abbrev = 0; Dwarf_Debug dbg = 0; unsigned n = 0; int res = 0; Dwarf_Unsigned abcount = 0; Dwarf_Unsigned pooloffset = offset_in_entrypool_of_values; Dwarf_Small * endpool = 0; Dwarf_Small * poolptr = 0; res = get_inhdr_cur(dn,index_number,&cur,error); if (res != DW_DLV_OK) { return res; } dbg = dn->dn_dbg; endpool = cur->din_entry_pool + cur->din_entry_pool_size; if (index_of_abbrev >= cur->din_abbrev_list_count) { _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION); return DW_DLV_ERROR; } poolptr = cur->din_entry_pool + offset_in_entrypool_of_values; abbrev = cur->din_abbrev_list + index_of_abbrev; abcount = cur->din_abbrev_list_count; for(n = 0; n < abcount ; ++n) { struct abbrev_pair_s *abp = abbrev->da_pairs +n; unsigned idxtype = abp->ap_index; unsigned form = abp->ap_form; array_dw_idx_number[n] = idxtype; array_form[n] = form; if(form == DW_FORM_data8 && idxtype == DW_IDX_type_hash) { if ((poolptr + sizeof(Dwarf_Sig8)) > endpool){ _dwarf_error(dbg,error, DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET); return DW_DLV_ERROR; } memcpy(array_of_signatures+n, poolptr,sizeof(Dwarf_Sig8)); poolptr += sizeof(Dwarf_Sig8); pooloffset += sizeof(Dwarf_Sig8); continue; } else if (_dwarf_allow_formudata(form)) { Dwarf_Unsigned val = 0; Dwarf_Unsigned bytesread = 0; res = _dwarf_formudata_internal(dbg,form,poolptr, endpool,&val,&bytesread,error); if(res != DW_DLV_OK) { return res; } poolptr += bytesread; pooloffset += bytesread; array_of_offsets[n] = val; continue; } /* There is some mistake/omission in our code here or in the data. */ _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_UNHANDLED_FORM); return DW_DLV_ERROR; } *offset_of_next_entrypool = pooloffset; return DW_DLV_OK; } /* Frees any Dwarf_Dnames_Head_s data that is directly mallocd. */ void _dwarf_debugnames_destructor(void *m) { struct Dwarf_Dnames_Head_s *h = (struct Dwarf_Dnames_Head_s *)m; struct Dwarf_Dnames_index_header_s *cur = 0; unsigned n = 0; cur = h->dn_inhdr_first; for( ;n < h->dn_inhdr_count ; ++n,++cur) { free_inhdr_content(cur); } free(h->dn_inhdr_first); h->dn_inhdr_first = 0; h->dn_inhdr_count = 0; } dwarfutils-20200114/libdwarf/dwarf_dnames.h000066400000000000000000000067031361531463500205430ustar00rootroot00000000000000/* Copyright (C) 2017-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Only 5 abbrev DW_IDX defined, we allow three user defined (arbitrarily) */ #define ABB_PAIRS_MAX 8 struct abbrev_pair_s { unsigned ap_index; unsigned ap_form; }; struct Dwarf_D_Abbrev_s { struct Dwarf_D_Abbrev_s * da_next; unsigned da_abbrev_code; unsigned da_tag; unsigned da_pairs_count; struct abbrev_pair_s da_pairs[ABB_PAIRS_MAX]; }; #define DWARF_DNAMES_VERSION5 5 struct Dwarf_Dnames_index_header_s { Dwarf_Debug din_dbg; struct Dwarf_Dnames_index_header_s *din_next; /* The .debug_names section offset of 1st byte of a header record. */ Dwarf_Unsigned din_section_offset; /* For offset and pointer sanity calculations. */ Dwarf_Small * din_indextable_data; Dwarf_Unsigned din_indextable_length; unsigned din_offset_size; Dwarf_Unsigned din_version; Dwarf_Unsigned din_comp_unit_count; Dwarf_Unsigned din_local_type_unit_count; Dwarf_Unsigned din_foreign_type_unit_count; Dwarf_Unsigned din_bucket_count; Dwarf_Unsigned din_name_count; Dwarf_Unsigned din_abbrev_table_size; /* bytes */ Dwarf_Unsigned din_entry_pool_size; /* bytes */ Dwarf_Unsigned din_augmentation_string_size; /* Since we cannot assume the string is NUL terminated we allocate a sufficient string space and NUL terminate the string. The DWARF5 standard does not specify it as null-terminated. We copy it into calloc area so not 'const' */ char * din_augmentation_string; Dwarf_Small * din_cu_list; Dwarf_Small * din_local_tu_list; Dwarf_Small * din_foreign_tu_list; Dwarf_Small * din_buckets; Dwarf_Small * din_hash_table; Dwarf_Small * din_string_offsets; Dwarf_Small * din_entry_offsets; Dwarf_Small * din_abbreviations; Dwarf_Small * din_entry_pool; unsigned din_abbrev_list_count; /* An array of size din_abbrev_list_count. */ struct Dwarf_D_Abbrev_s * din_abbrev_list; }; struct Dwarf_Dnames_Head_s { Dwarf_Debug dn_dbg; Dwarf_Small * dn_section_data; Dwarf_Small * dn_section_end; Dwarf_Unsigned dn_section_size; unsigned dn_inhdr_count; /* Becomes an array of these structs, dn_inhdr_count of them. */ struct Dwarf_Dnames_index_header_s * dn_inhdr_first; }; void _dwarf_debugnames_destructor(void *m); dwarfutils-20200114/libdwarf/dwarf_dsc.c000066400000000000000000000231521361531463500200350ustar00rootroot00000000000000/* Copyright (C) 2016-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_dsc.h" #define FALSE 0 #define TRUE 1 /* When called with ary and *arraycount 0 this just counts the elements found. Otherwise it records the values in ary and recounts. The arraycount pointer must be passed-in non-null always. */ static int get_dsc_leb_entries(Dwarf_Debug dbg, Dwarf_Small * blockpointer, Dwarf_Unsigned blocklen, int dounsigned, struct Dwarf_Dsc_Entry_s *ary, size_t * arraycount, Dwarf_Error * error) { Dwarf_Small *p = blockpointer; Dwarf_Small *endp = blockpointer + blocklen; size_t larraycount = 0; size_t iarraycount = *arraycount; if (!ary) { if (iarraycount) { /* Internal botch calling this static function. */ _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } } else { if (!iarraycount) { /* Internal botch calling this static function. */ _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } } if (dounsigned) { while (p < endp) { Dwarf_Unsigned dsc = 0; Dwarf_Unsigned low = 0; Dwarf_Unsigned high = 0; UNUSEDARG Dwarf_Unsigned leblen = 0; if (ary && (larraycount >= iarraycount)) { _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_LEN_CK(p,dsc, leblen,dbg,error,endp); if (!dsc) { DECODE_LEB128_UWORD_LEN_CK(p,low, leblen, dbg,error,endp); } else { DECODE_LEB128_UWORD_LEN_CK(p,low, leblen, dbg,error,endp); DECODE_LEB128_UWORD_LEN_CK(p,high, leblen, dbg,error,endp); } if(ary) { struct Dwarf_Dsc_Entry_s *arye = ary+larraycount; /* type reads the same as uleb and leb because it is only zero or one. */ arye->dsc_type = dsc; arye->dsc_low_u = low; arye->dsc_high_u = high; } larraycount++; } } else { while (p < endp) { Dwarf_Signed dsc = 0; Dwarf_Signed low = 0; Dwarf_Signed high = 0; UNUSEDARG Dwarf_Unsigned leblen = 0; if (ary && (larraycount >= iarraycount)) { _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } DECODE_LEB128_SWORD_LEN_CK(p,dsc, leblen,dbg,error,endp); if (!dsc) { DECODE_LEB128_SWORD_LEN_CK(p,low, leblen,dbg,error,endp); } else { DECODE_LEB128_SWORD_LEN_CK(p,low, leblen,dbg,error,endp); DECODE_LEB128_SWORD_LEN_CK(p,high, leblen,dbg,error,endp); } if(ary) { struct Dwarf_Dsc_Entry_s *arye = ary+larraycount; /* type reads the same as uleb and leb because it is only zero or one. */ arye->dsc_type = (Dwarf_Unsigned)dsc; arye->dsc_low_s = low; arye->dsc_high_s = high; } larraycount++; } } if (ary) { /* Just verify this recount matches original */ if(iarraycount != larraycount) { _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } } else { /* This matters for first call with ary 0 and iarraycount 0 as we are generating the count. */ *arraycount = larraycount; } return DW_DLV_OK; } int dwarf_discr_list(Dwarf_Debug dbg, Dwarf_Small * blockpointer, Dwarf_Unsigned blocklen, Dwarf_Dsc_Head * dsc_head_out, Dwarf_Unsigned * dsc_array_length_out, Dwarf_Error * error) { Dwarf_Dsc_Head h = 0; int res = 0; size_t arraycount = 0; struct Dwarf_Dsc_Entry_s *ary = 0; Dwarf_Small * dscblockp = 0; Dwarf_Unsigned dscblocklen = 0; if (!dbg){ _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ return DW_DLV_ERROR; } if (blocklen == 0) { return DW_DLV_NO_ENTRY; } dscblockp = (Dwarf_Small *)calloc(blocklen,sizeof(Dwarf_Small)); if(!dscblockp) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dscblocklen = blocklen; memcpy(dscblockp,blockpointer,blocklen); res = get_dsc_leb_entries(dbg,dscblockp,dscblocklen, /* TRUE or FALSE here is not important, the arraycount returned to us will be identical either way. */ FALSE, 0, &arraycount,error); if (res != DW_DLV_OK) { free(dscblockp); return res; } h = (Dwarf_Dsc_Head)_dwarf_get_alloc(dbg,DW_DLA_DSC_HEAD,1); if(!h) { free(dscblockp); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } h->dsh_block = dscblockp; h->dsh_block_len = dscblocklen; h->dsh_debug = dbg; /* Now the destructor for h will deal with block malloc space. */ ary = (struct Dwarf_Dsc_Entry_s *)calloc(arraycount, sizeof(struct Dwarf_Dsc_Entry_s)); if(!ary) { dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } h->dsh_count = arraycount; h->dsh_array = ary; h->dsh_set_unsigned = 0; h->dsh_set_signed = 0; *dsc_head_out = h; *dsc_array_length_out = arraycount; return DW_DLV_OK; } /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head dsh , Dwarf_Unsigned entrynum, Dwarf_Half * out_type, Dwarf_Unsigned * out_discr_low, Dwarf_Unsigned * out_discr_high, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Dsc_Entry_s *dse = 0; if (entrynum >= dsh->dsh_count) { return DW_DLV_NO_ENTRY; } if (!dsh->dsh_set_unsigned) { int res =0; int dounsigned = 1; size_t count = dsh->dsh_count; res = get_dsc_leb_entries(dsh->dsh_debug, dsh->dsh_block, dsh->dsh_block_len, dounsigned, dsh->dsh_array, &count, error); if (res != DW_DLV_OK) { return res; } dsh->dsh_set_unsigned = TRUE; } if (!dsh->dsh_array) { _dwarf_error(dsh->dsh_debug, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } dse = dsh->dsh_array + entrynum; *out_type = dse->dsc_type; *out_discr_low = dse->dsc_low_u; *out_discr_high = dse->dsc_high_u; return DW_DLV_OK; } /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head dsh, Dwarf_Unsigned entrynum, Dwarf_Half * out_type, Dwarf_Signed * out_discr_low, Dwarf_Signed * out_discr_high, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Dsc_Entry_s *dse = 0; if (entrynum >= dsh->dsh_count) { return DW_DLV_NO_ENTRY; } if (!dsh->dsh_set_signed) { int res =0; int dounsigned = 0; size_t count = dsh->dsh_count; res = get_dsc_leb_entries(dsh->dsh_debug, dsh->dsh_block, dsh->dsh_block_len, dounsigned, dsh->dsh_array, &count, error); if (res != DW_DLV_OK) { return res; } dsh->dsh_set_signed = TRUE; } if (!dsh->dsh_array) { _dwarf_error(dsh->dsh_debug, error, DW_DLE_DISCR_ARRAY_ERROR); return DW_DLV_ERROR; } dse = dsh->dsh_array + entrynum; *out_type = dse->dsc_type; *out_discr_low = dse->dsc_low_s; *out_discr_high = dse->dsc_high_s; return DW_DLV_OK; } void _dwarf_dsc_destructor(void *m) { Dwarf_Dsc_Head h = (Dwarf_Dsc_Head) m; free(h->dsh_array); h->dsh_array = 0; free(h->dsh_block); h->dsh_block = 0; h->dsh_count = 0; } dwarfutils-20200114/libdwarf/dwarf_dsc.h000066400000000000000000000040661361531463500200450ustar00rootroot00000000000000/* Copyright (C) 2016-2016 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* dsc_type: if 0, then dsc_low is a single discriminant value and dsc_high is zero.. If 1, then dsc_low, dsc_high are a discriminant range All the messy complexity here is so we can have both a set of values read as uleb and as sleb. We make our own copy of the block for the same reason. */ struct Dwarf_Dsc_Entry_s { /* Type is a 1 byte leb that reads the same as sleb or uleb because its value can only be zero or one. */ Dwarf_Half dsc_type; Dwarf_Unsigned dsc_low_u; Dwarf_Unsigned dsc_high_u; Dwarf_Signed dsc_low_s; Dwarf_Signed dsc_high_s; }; struct Dwarf_Dsc_Head_s { Dwarf_Debug dsh_debug; Dwarf_Unsigned dsh_count; Dwarf_Small *dsh_block; Dwarf_Unsigned dsh_block_len; /* Following two are flags to tell us whether lebs already read in a given signedness. */ Dwarf_Bool dsh_set_unsigned; Dwarf_Bool dsh_set_signed; struct Dwarf_Dsc_Entry_s *dsh_array; }; void _dwarf_dsc_destructor(void *m); dwarfutils-20200114/libdwarf/dwarf_elf_access.c000066400000000000000000001016351361531463500213560ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved. Portions Copyright 2009-2019 David Anderson. All rights reserved. Portions Copyright 2009-2010 Novell Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This file is ONLY used for libelf and with libelf For */ #include "config.h" #ifdef DWARF_WITH_LIBELF #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_elf_access.h" #include "dwarf_elf_rel_detector.h" /* Include the ELF definitions depending on system headers if any. */ #include "dwarf_elf_defines.h" #include #include #include #ifdef HAVE_UNISTD_H #include /* for close */ #endif /* HAVE_UNISTD_H */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #define FALSE 0 #define TRUE 1 #ifdef HAVE_ELF64_GETEHDR extern Elf64_Ehdr *elf64_getehdr(Elf *); #endif #ifdef HAVE_ELF64_GETSHDR extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); #endif #ifdef WORDS_BIGENDIAN #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word(dest, \ ((char *)source) +srclength-len_out, \ len_out) ; \ } #else /* LITTLE ENDIAN */ #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((char *)source) , \ len_out) ; \ } #endif /* *-ENDIAN */ /* ident[0] == 'E' for elf when using libelf. ident[1] = 1 */ typedef struct { char ident[8]; const char * path; int is_64bit; Dwarf_Small length_size; Dwarf_Small pointer_size; Dwarf_Unsigned section_count; Dwarf_Endianness endianness; Dwarf_Small machine; char libdwarf_owns_elf; dwarf_elf_handle elf; Elf32_Ehdr *ehdr32; #ifdef HAVE_ELF64_GETEHDR Elf64_Ehdr *ehdr64; #endif /* Elf symtab and its strtab. Initialized at first call to do relocations, the actual data is in the Dwarf_Debug struct, not allocated locally here. */ struct Dwarf_Section_s *symtab; struct Dwarf_Section_s *strtab; } dwarf_elf_object_access_internals_t; struct Dwarf_Elf_Rela { Dwarf_Unsigned r_offset; /*Dwarf_Unsigned r_info; */ Dwarf_Unsigned r_type; Dwarf_Unsigned r_symidx; Dwarf_Unsigned r_addend; }; static int dwarf_elf_object_access_load_section(void* obj_in, Dwarf_Half section_index, Dwarf_Small** section_data, int* error); /* dwarf_elf_object_access_internals_init() On error, set *error with libdwarf error code. */ static int dwarf_elf_object_access_internals_init(void* obj_in, dwarf_elf_handle elf, int* error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; char *ehdr_ident = 0; Dwarf_Half machine = 0; obj->elf = elf; if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) { *error = DW_DLE_ELF_GETIDENT_ERROR; return DW_DLV_ERROR; } obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64); if (ehdr_ident[EI_DATA] == ELFDATA2LSB){ obj->endianness = DW_OBJECT_LSB; } else if (ehdr_ident[EI_DATA] == ELFDATA2MSB){ obj->endianness = DW_OBJECT_MSB; } if (obj->is_64bit) { #ifdef HAVE_ELF64_GETEHDR obj->ehdr64 = elf64_getehdr(elf); if (obj->ehdr64 == NULL) { *error = DW_DLE_ELF_GETEHDR_ERROR; return DW_DLV_ERROR; } obj->section_count = obj->ehdr64->e_shnum; machine = obj->ehdr64->e_machine; obj->machine = machine; #else *error = DW_DLE_NO_ELF64_SUPPORT; return DW_DLV_ERROR; #endif } else { obj->ehdr32 = elf32_getehdr(elf); if (obj->ehdr32 == NULL) { *error = DW_DLE_ELF_GETEHDR_ERROR; return DW_DLV_ERROR; } obj->section_count = obj->ehdr32->e_shnum; machine = obj->ehdr32->e_machine; obj->machine = machine; } /* The following length_size is Not Too Significant. Only used one calculation, and an approximate one at that. */ obj->length_size = obj->is_64bit ? 8 : 4; obj->pointer_size = obj->is_64bit ? 8 : 4; obj->ident[0] = 'E'; obj->ident[1] = 1; #ifdef _WIN32 if (obj->is_64bit && machine == EM_PPC64) { /* The SNC compiler generates the EM_PPC64 machine type for the PS3 platform, but is a 32 bits pointer size in user mode. */ obj->pointer_size = 4; } #endif /* _WIN32 */ if (obj->is_64bit && machine != EM_MIPS) { /* MIPS/IRIX makes pointer size and length size 8 for -64. Other platforms make length 4 always. */ /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus tools, and the dwarfv2.1 64bit extension setting. This is not the same as the size-of-an-offset, which is 4 in 32bit dwarf and 8 in 64bit dwarf. */ obj->length_size = 4; } return DW_DLV_OK; } /* dwarf_elf_object_access_get_byte_order */ static Dwarf_Endianness dwarf_elf_object_access_get_byte_order(void* obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->endianness; } /* dwarf_elf_object_access_get_section_count() */ static Dwarf_Unsigned dwarf_elf_object_access_get_section_count(void * obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->section_count; } static int _dwarf_get_elf_flags_func( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; Elf32_Shdr *shdr32 = 0; #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr *shdr64 = 0; #endif Elf_Scn *scn = 0; scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { *error = DW_DLE_MDE; return DW_DLV_ERROR; } if (obj->is_64bit) { #ifdef HAVE_ELF64_GETSHDR shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also section 'sh_type' and sh_info' fields, so the caller can use it for additional tasks that require that info. */ *flags_out = shdr64->sh_flags; *addralign_out = shdr64->sh_addralign; return DW_DLV_OK; #else *error = DW_DLE_MISSING_ELF64_SUPPORT; return DW_DLV_ERROR; #endif /* HAVE_ELF64_GETSHDR */ } if ((shdr32 = elf32_getshdr(scn)) == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also the section type, so the caller can use it for additional tasks that require to know the section type. */ *flags_out = shdr32->sh_flags; *addralign_out = shdr32->sh_addralign; return DW_DLV_OK; } /* dwarf_elf_object_access_get_section() If writing a function vaguely like this for a non-elf object, be sure that when section-index is passed in as zero that you set the fields in *ret_scn_doas to reflect an empty section with an empty string as the section name. Adjust your section indexes of your non-elf-reading-code for all the necessary functions in Dwarf_Obj_Access_Methods_s accordingly. Should have gotten sh_flags, sh_addralign too. But Dwarf_Obj_Access_Section is publically defined so changing it is quite painful for everyone. */ static int dwarf_elf_object_access_get_section_info( void* obj_in, Dwarf_Half section_index, Dwarf_Obj_Access_Section* ret_scn_doas, int* error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; Elf32_Shdr *shdr32 = 0; #ifdef HAVE_ELF64_GETSHDR Elf64_Shdr *shdr64 = 0; #endif Elf_Scn *scn = 0; scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { *error = DW_DLE_MDE; return DW_DLV_ERROR; } if (obj->is_64bit) { #ifdef HAVE_ELF64_GETSHDR shdr64 = elf64_getshdr(scn); if (shdr64 == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also section 'sh_type' and sh_info' fields, so the caller can use it for additional tasks that require that info. */ ret_scn_doas->type = shdr64->sh_type; ret_scn_doas->size = shdr64->sh_size; ret_scn_doas->addr = shdr64->sh_addr; ret_scn_doas->link = shdr64->sh_link; ret_scn_doas->info = shdr64->sh_info; ret_scn_doas->entrysize = shdr64->sh_entsize; ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx, shdr64->sh_name); if (ret_scn_doas->name == NULL) { *error = DW_DLE_ELF_STRPTR_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; #else *error = DW_DLE_MISSING_ELF64_SUPPORT; return DW_DLV_ERROR; #endif /* HAVE_ELF64_GETSHDR */ } if ((shdr32 = elf32_getshdr(scn)) == NULL) { *error = DW_DLE_ELF_GETSHDR_ERROR; return DW_DLV_ERROR; } /* Get also the section type, so the caller can use it for additional tasks that require to know the section type. */ ret_scn_doas->type = shdr32->sh_type; ret_scn_doas->size = shdr32->sh_size; ret_scn_doas->addr = shdr32->sh_addr; ret_scn_doas->link = shdr32->sh_link; ret_scn_doas->info = shdr32->sh_info; ret_scn_doas->entrysize = shdr32->sh_entsize; ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx, shdr32->sh_name); if (ret_scn_doas->name == NULL) { *error = DW_DLE_ELF_STRPTR_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; } /* dwarf_elf_object_access_get_length_size */ static Dwarf_Small dwarf_elf_object_access_get_length_size(void* obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->length_size; } /* dwarf_elf_object_access_get_pointer_size */ static Dwarf_Small dwarf_elf_object_access_get_pointer_size(void* obj_in) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; return obj->pointer_size; } #define MATCH_REL_SEC(i_,s_,r_) \ if (i_ == s_.dss_index) { \ *r_ = &s_; \ return DW_DLV_OK; \ } static int find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, struct Dwarf_Section_s **relocatablesec, int *error) { MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec); /* dbg-> de_debug_tu_index,reloctablesec); */ /* dbg-> de_debug_cu_index,reloctablesec); */ /* dbg-> de_debug_gdbindex,reloctablesec); */ /* dbg-> de_debug_str,syms); */ /* de_elf_symtab,syms); */ /* de_elf_strtab,syms); */ *error = DW_DLE_RELOC_SECTION_MISMATCH; return DW_DLV_ERROR; } #undef MATCH_REL_SEC static void get_rela_elf32(Dwarf_Small *data, unsigned int i, UNUSEDARG int endianness, UNUSEDARG int machine, struct Dwarf_Elf_Rela *relap) { Elf32_Rela *relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela))); relap->r_offset = relp->r_offset; /* relap->r_info = relp->r_info; */ relap->r_type = ELF32_R_TYPE(relp->r_info); relap->r_symidx = ELF32_R_SYM(relp->r_info); relap->r_addend = relp->r_addend; } static void get_rela_elf64(Dwarf_Small *data, unsigned int i, int endianness, int machine, struct Dwarf_Elf_Rela *relap) { #ifdef HAVE_ELF64_RELA Elf64_Rela * relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela))); relap->r_offset = relp->r_offset; /* relap->r_info = relp->r_info; */ #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff) #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff) if (machine == EM_MIPS && endianness == DW_OBJECT_LSB ){ /* This is really wierd. Treat this very specially. The Elf64 LE MIPS object used for testing (that has rela) wants the values as sym ssym type3 type2 type, treating each value as independent value. But libelf xlate treats it as something else so we fudge here. It is unclear how to precisely characterize where these relocations were used. SGI MIPS on IRIX never used .rela relocations. The BE 64bit elf MIPS test object with rela uses traditional elf relocation layouts, not this special case. */ /* We ignore the special TYPE2 and TYPE3, they should be value R_MIPS_NONE in rela. */ relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info); relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info); #undef MIPS64SYM #undef MIPS64TYPE } else { relap->r_type = ELF64_R_TYPE(relp->r_info); relap->r_symidx = ELF64_R_SYM(relp->r_info); } relap->r_addend = relp->r_addend; #endif } static void get_relocations_array(Dwarf_Bool is_64bit, int endianness, int machine, Dwarf_Small *data, unsigned int num_relocations, struct Dwarf_Elf_Rela *relap) { unsigned int i = 0; void (*get_relocations)(Dwarf_Small *data, unsigned int i, int endianness, int machine, struct Dwarf_Elf_Rela *relap); /* Handle 32/64 bit issue */ if (is_64bit) { get_relocations = get_rela_elf64; } else { get_relocations = get_rela_elf32; } for (i=0; i < num_relocations; i++) { get_relocations(data, i,endianness,machine, &(relap[i])); } } static int get_relocation_entries(Dwarf_Bool is_64bit, int endianness, int machine, Dwarf_Small *relocation_section, Dwarf_Unsigned relocation_section_size, Dwarf_Unsigned relocation_section_entrysize, struct Dwarf_Elf_Rela **relas, unsigned int *nrelas, int *error) { unsigned int relocation_size = 0; if (is_64bit) { #ifdef HAVE_ELF64_RELA relocation_size = sizeof(Elf64_Rela); #else *error = DW_DLE_MISSING_ELF64_SUPPORT; return DW_DLV_ERROR; #endif } else { relocation_size = sizeof(Elf32_Rela); } if (relocation_size != relocation_section_entrysize) { /* Means our struct definition does not match the real object. */ *error = DW_DLE_RELOC_SECTION_LENGTH_ODD; return DW_DLV_ERROR; } if (relocation_section == NULL) { *error = DW_DLE_RELOC_SECTION_PTR_NULL; return(DW_DLV_ERROR); } if ((relocation_section_size != 0)) { size_t bytescount = 0; if (relocation_section_size%relocation_size) { *error = DW_DLE_RELOC_SECTION_LENGTH_ODD; return DW_DLV_ERROR; } *nrelas = relocation_section_size/relocation_size; bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela); *relas = malloc(bytescount); if (!*relas) { *error = DW_DLE_MAF; return(DW_DLV_ERROR); } memset(*relas,0,bytescount); get_relocations_array(is_64bit,endianness,machine, relocation_section, *nrelas, *relas); } return(DW_DLV_OK); } /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. The caller may decide to ignore the errors or report them. */ static int update_entry(Dwarf_Debug dbg, Dwarf_Bool is_64bit, UNUSEDARG Dwarf_Endianness endianess, UNUSEDARG Dwarf_Half machine, struct Dwarf_Elf_Rela *rela, Dwarf_Small *target_section, Dwarf_Unsigned target_section_size, Dwarf_Small *symtab_section_data, Dwarf_Unsigned symtab_section_size, Dwarf_Unsigned symtab_section_entrysize, int *error) { unsigned int type = 0; unsigned int sym_idx = 0; #ifdef HAVE_ELF64_SYM Elf64_Sym sym_buf; Elf64_Sym *sym = 0; #else Elf32_Sym sym_buf; Elf32_Sym *sym = 0; #endif Elf32_Sym *sym32 = 0; Dwarf_Unsigned offset = 0; Dwarf_Signed addend = 0; Dwarf_Unsigned reloc_size = 0; Dwarf_Unsigned symtab_entry_count = 0; if (symtab_section_entrysize == 0) { *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO; return DW_DLV_ERROR; } symtab_entry_count = symtab_section_size/symtab_section_entrysize; /* Dwarf_Elf_Rela dereferencing */ offset = rela->r_offset; addend = rela->r_addend; type = rela->r_type; sym_idx = rela->r_symidx; if (sym_idx >= symtab_entry_count) { *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD; return DW_DLV_ERROR; } if (offset >= target_section_size) { /* If offset really big, any add will overflow. So lets stop early if offset is corrupt. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } if (is_64bit) { #ifdef HAVE_ELF64_SYM sym = &((Elf64_Sym*)symtab_section_data)[sym_idx]; #else /* We cannot handle this object without 64_SYMs. */ *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; return DW_DLV_ERROR; #endif } else { sym32 = &((Elf32_Sym*)symtab_section_data)[sym_idx]; /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at an Elf64_Sym local variable (sym_buf) to allow us to use the same pointer (sym) for both 32-bit and 64-bit instances. */ sym = &sym_buf; sym->st_name = sym32->st_name; sym->st_info = sym32->st_info; sym->st_other = sym32->st_other; sym->st_shndx = sym32->st_shndx; sym->st_value = sym32->st_value; sym->st_size = sym32->st_size; } /* Determine relocation size */ if (_dwarf_is_32bit_abs_reloc(type, machine)) { reloc_size = 4; } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { reloc_size = 8; } else { *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; return DW_DLV_ERROR; } if ( (offset + reloc_size) < offset) { /* Another check for overflow. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } if ( (offset + reloc_size) > target_section_size) { *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } { /* Assuming we do not need to do a READ_UNALIGNED here at target_section + offset and add its value to outval. Some ABIs say no read (for example MIPS), but if some do then which ones? */ Dwarf_Unsigned outval = sym->st_value + addend; /* The 0th byte goes at offset. */ WRITE_UNALIGNED(dbg,target_section + offset, &outval,sizeof(outval),reloc_size); } return DW_DLV_OK; } /* Somewhat arbitrarily, we attempt to apply all the relocations we can and still notify the caller of at least one error if we found any errors. */ static int apply_rela_entries(Dwarf_Debug dbg, Dwarf_Bool is_64bit, Dwarf_Endianness endianess, Dwarf_Half machine, Dwarf_Small *target_section, Dwarf_Unsigned target_section_size, Dwarf_Small *symtab_section, Dwarf_Unsigned symtab_section_size, Dwarf_Unsigned symtab_section_entrysize, struct Dwarf_Elf_Rela *relas, unsigned int nrelas, int *error) { int return_res = DW_DLV_OK; if ((target_section != NULL) && (relas != NULL)) { unsigned int i; if (symtab_section_entrysize == 0) { *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO; return DW_DLV_ERROR; } if (symtab_section_size%symtab_section_entrysize) { *error = DW_DLE_SYMTAB_SECTION_LENGTH_ODD; return DW_DLV_ERROR; } for (i = 0; i < nrelas; i++) { int res = update_entry(dbg, is_64bit, endianess, machine, &(relas)[i], target_section, target_section_size, symtab_section, symtab_section_size, symtab_section_entrysize, error); if (res != DW_DLV_OK) { return_res = res; } } } return return_res; } static int loop_through_relocations( Dwarf_Debug dbg, dwarf_elf_object_access_internals_t* obj, struct Dwarf_Section_s *relocatablesec, int *error) { Dwarf_Small *target_section = 0; Dwarf_Small *symtab_section = obj->symtab->dss_data; Dwarf_Unsigned symtab_section_entrysize = obj->symtab->dss_entrysize; Dwarf_Unsigned symtab_section_size = obj->symtab->dss_size; Dwarf_Small *relocation_section = relocatablesec->dss_reloc_data; Dwarf_Unsigned relocation_section_size = relocatablesec->dss_reloc_size; Dwarf_Unsigned relocation_section_entrysize = relocatablesec->dss_reloc_entrysize; int ret = DW_DLV_ERROR; struct Dwarf_Elf_Rela *relas = 0; unsigned int nrelas = 0; Dwarf_Small *mspace = 0; ret = get_relocation_entries(obj->is_64bit, obj->endianness, obj->machine, relocation_section, relocation_section_size, relocation_section_entrysize, &relas, &nrelas, error); if (ret != DW_DLV_OK) { free(relas); return ret; } if(!relocatablesec->dss_data_was_malloc) { /* Some systems read Elf in read-only memory via mmap or the like. So the only safe thing is to copy the current data into malloc space and refer to the malloc space instead of the space returned by the elf library */ mspace = malloc(relocatablesec->dss_size); if (!mspace) { free(relas); *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL; return DW_DLV_ERROR; } memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size); relocatablesec->dss_data = mspace; relocatablesec->dss_data_was_malloc = TRUE; } target_section = relocatablesec->dss_data; ret = apply_rela_entries( dbg, obj->is_64bit, obj->endianness, obj->machine, target_section, relocatablesec->dss_size, symtab_section, symtab_section_size, symtab_section_entrysize, relas, nrelas, error); free(relas); return ret; } /* Find the section data in dbg and find all the relevant sections. Then do relocations. */ static int dwarf_elf_object_relocate_a_section(void* obj_in, Dwarf_Half section_index, Dwarf_Debug dbg, int* error) { int res = DW_DLV_ERROR; dwarf_elf_object_access_internals_t*obj = 0; struct Dwarf_Section_s * relocatablesec = 0; if (section_index == 0) { return DW_DLV_NO_ENTRY; } obj = (dwarf_elf_object_access_internals_t*)obj_in; /* The section to relocate must already be loaded into memory. */ res = find_section_to_relocate(dbg, section_index,&relocatablesec,error); if (res != DW_DLV_OK) { return res; } /* Sun and possibly others do not always set sh_link in .debug_* sections. So we cannot do full consistency checks. */ if (relocatablesec->dss_reloc_index == 0 ) { /* Something is wrong. */ *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; return DW_DLV_ERROR; } /* Now load the relocations themselves. */ res = dwarf_elf_object_access_load_section(obj_in, relocatablesec->dss_reloc_index, &relocatablesec->dss_reloc_data, error); if (res != DW_DLV_OK) { return res; } /* Now get the symtab. */ if (!obj->symtab) { obj->symtab = &dbg->de_elf_symtab; obj->strtab = &dbg->de_elf_strtab; } if (obj->symtab->dss_index != relocatablesec->dss_reloc_link) { /* Something is wrong. */ *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; return DW_DLV_ERROR; } if (obj->strtab->dss_index != obj->symtab->dss_link) { /* Something is wrong. */ *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX; return DW_DLV_ERROR; } if (!obj->symtab->dss_data) { /* Now load the symtab */ res = dwarf_elf_object_access_load_section(obj_in, obj->symtab->dss_index, &obj->symtab->dss_data, error); if (res != DW_DLV_OK) { return res; } } if (!obj->strtab->dss_data) { /* Now load the strtab */ res = dwarf_elf_object_access_load_section(obj_in, obj->strtab->dss_index, &obj->strtab->dss_data,error); if (res != DW_DLV_OK){ return res; } } /* We have all the data we need in memory. */ res = loop_through_relocations(dbg,obj,relocatablesec,error); return res; } /* dwarf_elf_object_access_load_section() We are only asked to load sections that libdwarf really needs. It would be much better if a 'user data pointer' were passed through these interfaces so one part of libdwarf could pass through to this. Or even just if a Dwarf_Debug were passed in. Sigh. */ static int dwarf_elf_object_access_load_section(void* obj_in, Dwarf_Half section_index, Dwarf_Small** section_data, int* error) { dwarf_elf_object_access_internals_t*obj = (dwarf_elf_object_access_internals_t*)obj_in; if (section_index == 0) { return DW_DLV_NO_ENTRY; } { Elf_Scn *scn = 0; Elf_Data *data = 0; scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { /* The section_index does not exist or obj->elf is NULL. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } /* When using libelf as a producer, section data may be stored in multiple buffers. In libdwarf however, we only use libelf as a consumer (there is a dwarf producer API, but it doesn't use libelf). Because of this, this single call to elf_getdata will retrieve the entire section in a single contiguous buffer. */ data = elf_getdata(scn, NULL); if (data == NULL) { /* Most likely means that the Elf section header is damaged/corrupt and the data is impossible to read into memory. The size specified in the Elf section is too large to allocate memory for so the data could not be loaded. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } if (!data->d_buf) { /* If NULL it means 'the section has no data' according to libelf documentation. No DWARF-related section should ever have 'no data'. Happens if a section type is SHT_NOBITS and no section libdwarf wants to look at should be SHT_NOBITS. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } *section_data = data->d_buf; } return DW_DLV_OK; } /* dwarf_elf_access method table. */ static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods = { dwarf_elf_object_access_get_section_info, dwarf_elf_object_access_get_byte_order, dwarf_elf_object_access_get_length_size, dwarf_elf_object_access_get_pointer_size, dwarf_elf_object_access_get_section_count, dwarf_elf_object_access_load_section, dwarf_elf_object_relocate_a_section }; /* Interface for the ELF object file implementation. On error this should set *err with the libdwarf error code. */ int dwarf_elf_object_access_init(dwarf_elf_handle elf, int libdwarf_owns_elf, Dwarf_Obj_Access_Interface** ret_obj, int *err) { int res = 0; dwarf_elf_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); if (!internals) { *err = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = dwarf_elf_object_access_internals_init(internals, elf, err); if (res != DW_DLV_OK){ /* *err is already set. */ free(internals); return DW_DLV_ERROR; } internals->libdwarf_owns_elf = libdwarf_owns_elf; intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ *err = DW_DLE_ALLOC_FAIL; free(internals); return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &dwarf_elf_object_access_methods; /* An access method hidden from non-elf. Needed to handle new-ish SHF_COMPRESSED flag in elf. */ _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func; *ret_obj = intfc; return DW_DLV_OK; } /* Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init. */ void dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj) { if (!obj) { return; } if (obj->object) { dwarf_elf_object_access_internals_t *internals = (dwarf_elf_object_access_internals_t *)obj->object; if (internals->libdwarf_owns_elf){ /* Happens with dwarf_init_path(), dwarf_init(), or dwarf_init_b() interfaces. */ elf_end(internals->elf); } } free(obj->object); free(obj); } /* This function returns the Elf * pointer associated with a Dwarf_Debug. This function only makes sense if ELF is implied and there actually is an Elf * pointer available. */ int dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, Dwarf_Error * error) { struct Dwarf_Obj_Access_Interface_s * obj = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } obj = dbg->de_obj_file; if (obj && obj->object) { dwarf_elf_object_access_internals_t *internals = 0; char typeletter = *(char *)(obj->object); if (typeletter != 'E') { /* Not libelf Elf */ return DW_DLV_NO_ENTRY; } internals = (dwarf_elf_object_access_internals_t*)obj->object; if (internals->elf == NULL) { _dwarf_error(dbg, error, DW_DLE_FNO); return (DW_DLV_ERROR); } *elf = internals->elf; return DW_DLV_OK; } _dwarf_error(dbg, error, DW_DLE_FNO); return DW_DLV_ERROR; } #else int dwarf_elf_access_dummy_var_avoid_warn = 0; #endif /* DWARF_WITH_LIBELF */ dwarfutils-20200114/libdwarf/dwarf_elf_access.h000066400000000000000000000030551361531463500213600ustar00rootroot00000000000000#ifndef _DWARF_ELF_PORT_H #define _DWARF_ELF_PORT_H /* Copyright (C) 2008-2011 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* ELF (usually libelf) object access for the generic object file interface */ int dwarf_elf_object_access_init(dwarf_elf_handle elf , int libdwarf_owns_elf, Dwarf_Obj_Access_Interface** ret_obj, int *err ); void dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj ); /* End ELF object access for the generic object file interface */ #endif dwarfutils-20200114/libdwarf/dwarf_elf_defines.h000066400000000000000000000525231361531463500215400ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_ELF_DEFINES_H #define DWARF_ELF_DEFINES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Use the system headers if they are available. */ #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ /* Relocation definitions are in sys/elf_{mach}.h on Solaris. */ #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif /* HAVE_LIBELF_LIBELF_H */ #endif /* HAVE_LIBELF_H */ /* Standard Elf section types. */ #ifndef SHT_NULL #define SHT_NULL 0 #endif #ifndef SHT_PROGBITS #define SHT_PROGBITS 1 #endif #ifndef SHT_SYMTAB #define SHT_SYMTAB 2 #endif #ifndef SHT_STRTAB #define SHT_STRTAB 3 #endif #ifndef SHT_RELA #define SHT_RELA 4 #endif #ifndef DW_GROUPNUMBER_BASE #define DW_GROUPNUMBER_BASE 1 #endif #ifndef DW_GROUPNUMBER_DWO #define DW_GROUPNUMBER_DWO 2 #endif #ifndef SHF_GROUP #define SHF_GROUP (1 << 9) #endif /* SHF_GROUP */ #ifndef STN_UNDEF #define STN_UNDEF 0 #endif /* STN_UNDEF */ #ifndef SHT_HASH #define SHT_HASH 5 #endif #ifndef SHT_DYNAMIC #define SHT_DYNAMIC 6 #endif #ifndef SHT_NOTE #define SHT_NOTE 7 #endif #ifndef SHT_NOBITS #define SHT_NOBITS 8 #endif #ifndef SHT_REL #define SHT_REL 9 #endif #ifndef SHT_SHLIB #define SHT_SHLIB 10 #endif #ifndef SHT_DYNSYM #define SHT_DYNSYM 11 #endif #ifndef SHT_GROUP #define SHT_GROUP 17 #endif /* SHT_GROUP */ /* Symbol Types, Elf standard. */ #define STT_NOTYPE 0 #define STT_OBJECT 1 #define STT_FUNC 2 #define STT_SECTION 3 #define STT_FILE 4 #ifndef PT_NULL #define PT_NULL 0 #endif #ifndef PT_LOAD #define PT_LOAD 1 #endif #ifndef PT_DYNAMIC #define PT_DYNAMIC 2 #endif #ifndef PT_INTERP #define PT_INTERP 3 #endif #ifndef PT_NOTE #define PT_NOTE 4 #endif #ifndef PT_SHLIB #define PT_SHLIB 5 #endif #ifndef PT_PHDR #define PT_PHDR 6 #endif #ifndef PT_LOPROC #define PT_LOPROC 0x70000000 #endif #ifndef PT_HIPROC #define PT_HIPROC 0x7fffffff #endif #ifndef PF_X #define PF_X (1 << 0) #endif #ifndef PF_W #define PF_W (1 << 1) #endif #ifndef PF_R #define PF_R (1 << 2) #endif #ifndef PF_MASKOS #define PF_MASKOS 0x0ff00000 #endif #ifndef PF_MASKPROC #define PF_MASKPROC 0xf0000000 #endif #ifndef ET_NONE #define ET_NONE 0 #endif #ifndef ET_REL #define ET_REL 1 #endif #ifndef ET_EXEC #define ET_EXEC 2 #endif #ifndef ET_DYN #define ET_DYN 3 #endif #ifndef ET_CORE #define ET_CORE 4 #endif #ifndef ET_NUM #define ET_NUM 5 #endif #ifndef ET_LOOS #define ET_LOOS 0xfe00 #endif #ifndef ET_HIOS #define ET_HIOS 0xfeff #endif #ifndef ET_LOPROC #define ET_LOPROC 0xff00 #endif #ifndef ET_HIPROC #define ET_HIPROC 0xffff #endif #ifndef EM_NONE #define EM_NONE 0 #endif #ifndef EM_M32 #define EM_M32 1 #endif #ifndef EM_SPARC #define EM_SPARC 2 #endif #ifndef EM_386 #define EM_386 3 #endif #ifndef EM_68K #define EM_68K 4 #endif #ifndef EM_88K #define EM_88K 5 #endif #ifndef EM_IAMCU #define EM_IAMCU 6 #endif #ifndef EM_860 #define EM_860 7 #endif #ifndef EM_MIPS #define EM_MIPS 8 #endif #ifndef EM_S370 #define EM_S370 9 #endif #ifndef EM_MIPS_RS3_LE #define EM_MIPS_RS3_LE 10 #endif #ifndef EM_PARISC #define EM_PARISC 15 #endif #ifndef EM_VPP500 #define EM_VPP500 17 #endif #ifndef EM_SPARC32PLUS #define EM_SPARC32PLUS 18 #endif #ifndef EM_960 #define EM_960 19 #endif #ifndef EM_PPC #define EM_PPC 20 #endif #ifndef EM_PPC64 #define EM_PPC64 21 #endif #ifndef EM_S390 #define EM_S390 22 #endif #ifndef EM_SPU #define EM_SPU 23 #endif #ifndef EM_V800 #define EM_V800 36 #endif #ifndef EM_FR20 #define EM_FR20 37 #endif #ifndef EM_RH32 #define EM_RH32 38 #endif #ifndef EM_RCE #define EM_RCE 39 #endif #ifndef EM_ARM #define EM_ARM 40 #endif #ifndef EM_FAKE_ALPHA #define EM_FAKE_ALPHA 41 #endif #ifndef EM_SH #define EM_SH 42 #endif #ifndef EM_SPARCV9 #define EM_SPARCV9 43 #endif #ifndef EM_TRICORE #define EM_TRICORE 44 #endif #ifndef EM_ARC #define EM_ARC 45 #endif #ifndef EM_H8_300 #define EM_H8_300 46 #endif #ifndef EM_H8_300H #define EM_H8_300H 47 #endif #ifndef EM_H8S #define EM_H8S 48 #endif #ifndef EM_H8_500 #define EM_H8_500 49 #endif #ifndef EM_IA_64 #define EM_IA_64 50 #endif #ifndef EM_MIPS_X #define EM_MIPS_X 51 #endif #ifndef EM_COLDFIRE #define EM_COLDFIRE 52 #endif #ifndef EM_68HC12 #define EM_68HC12 53 #endif #ifndef EM_MMA #define EM_MMA 54 #endif #ifndef EM_PCP #define EM_PCP 55 #endif #ifndef EM_NCPU #define EM_NCPU 56 #endif #ifndef EM_NDR1 #define EM_NDR1 57 #endif #ifndef EM_STARCORE #define EM_STARCORE 58 #endif #ifndef EM_ME16 #define EM_ME16 59 #endif #ifndef EM_ST100 #define EM_ST100 60 #endif #ifndef EM_TINYJ #define EM_TINYJ 61 #endif #ifndef EM_X86_64 #define EM_X86_64 62 #endif #ifndef EM_PDSP #define EM_PDSP 63 #endif #ifndef EM_PDP10 #define EM_PDP10 64 #endif #ifndef EM_PDP11 #define EM_PDP11 65 #endif #ifndef EM_FX66 #define EM_FX66 66 #endif #ifndef EM_ST9PLUS #define EM_ST9PLUS 67 #endif #ifndef EM_ST7 #define EM_ST7 68 #endif #ifndef EM_68HC16 #define EM_68HC16 69 #endif #ifndef EM_68HC11 #define EM_68HC11 70 #endif #ifndef EM_68HC08 #define EM_68HC08 71 #endif #ifndef EM_68HC05 #define EM_68HC05 72 #endif #ifndef EM_SVX #define EM_SVX 73 #endif #ifndef EM_ST19 #define EM_ST19 74 #endif #ifndef EM_VAX #define EM_VAX 75 #endif #ifndef EM_CRIS #define EM_CRIS 76 #endif #ifndef EM_JAVELIN #define EM_JAVELIN 77 #endif #ifndef EM_FIREPATH #define EM_FIREPATH 78 #endif #ifndef EM_ZSP #define EM_ZSP 79 #endif #ifndef EM_MMIX #define EM_MMIX 80 #endif #ifndef EM_HUANY #define EM_HUANY 81 #endif #ifndef EM_PRISM #define EM_PRISM 82 #endif #ifndef EM_AVR #define EM_AVR 83 #endif #ifndef EM_FR30 #define EM_FR30 84 #endif #ifndef EM_D10V #define EM_D10V 85 #endif #ifndef EM_D30V #define EM_D30V 86 #endif #ifndef EM_V850 #define EM_V850 87 #endif #ifndef EM_M32R #define EM_M32R 88 #endif #ifndef EM_MN10300 #define EM_MN10300 89 #endif #ifndef EM_MN10200 #define EM_MN10200 90 #endif #ifndef EM_PJ #define EM_PJ 91 #endif #ifndef EM_OPENRISC #define EM_OPENRISC 92 #endif #ifndef EM_ARC_COMPACT #define EM_ARC_COMPACT 93 #endif #ifndef EM_XTENSA #define EM_XTENSA 94 #endif #ifndef EM_VIDEOCORE #define EM_VIDEOCORE 95 #endif #ifndef EM_TMM_GPP #define EM_TMM_GPP 96 #endif #ifndef EM_NS32K #define EM_NS32K 97 #endif #ifndef EM_TPC #define EM_TPC 98 #endif #ifndef EM_SNP1K #define EM_SNP1K 99 #endif #ifndef EM_ST200 #define EM_ST200 100 #endif #ifndef EM_IP2K #define EM_IP2K 101 #endif #ifndef EM_MAX #define EM_MAX 102 #endif #ifndef EM_CR #define EM_CR 103 #endif #ifndef EM_F2MC16 #define EM_F2MC16 104 #endif #ifndef EM_MSP430 #define EM_MSP430 105 #endif #ifndef EM_BLACKFIN #define EM_BLACKFIN 106 #endif #ifndef EM_SE_C33 #define EM_SE_C33 107 #endif #ifndef EM_SEP #define EM_SEP 108 #endif #ifndef EM_ARCA #define EM_ARCA 109 #endif #ifndef EM_UNICORE #define EM_UNICORE 110 #endif #ifndef EM_EXCESS #define EM_EXCESS 111 #endif #ifndef EM_DXP #define EM_DXP 112 #endif #ifndef EM_ALTERA_NIOS2 #define EM_ALTERA_NIOS2 113 #endif #ifndef EM_CRX #define EM_CRX 114 #endif #ifndef EM_XGATE #define EM_XGATE 115 #endif #ifndef EM_C166 #define EM_C166 116 #endif #ifndef EM_M16C #define EM_M16C 117 #endif #ifndef EM_DSPIC30F #define EM_DSPIC30F 118 #endif #ifndef EM_CE #define EM_CE 119 #endif #ifndef EM_M32C #define EM_M32C 120 #endif #ifndef EM_TSK3000 #define EM_TSK3000 131 #endif #ifndef EM_RS08 #define EM_RS08 132 #endif #ifndef EM_SHARC #define EM_SHARC 133 #endif #ifndef EM_ECOG2 #define EM_ECOG2 134 #endif #ifndef EM_SCORE7 #define EM_SCORE7 135 #endif #ifndef EM_DSP24 #define EM_DSP24 136 #endif #ifndef EM_VIDEOCORE3 #define EM_VIDEOCORE3 137 #endif #ifndef EM_LATTICEMICO32 #define EM_LATTICEMICO32 138 #endif #ifndef EM_SE_C17 #define EM_SE_C17 139 #endif #ifndef EM_TI_C6000 #define EM_TI_C6000 140 #endif #ifndef EM_TI_C2000 #define EM_TI_C2000 141 #endif #ifndef EM_TI_C5500 #define EM_TI_C5500 142 #endif #ifndef EM_TI_ARP32 #define EM_TI_ARP32 143 #endif #ifndef EM_TI_PRU #define EM_TI_PRU 144 #endif #ifndef EM_MMDSP_PLUS #define EM_MMDSP_PLUS 160 #endif #ifndef EM_CYPRESS_M8C #define EM_CYPRESS_M8C 161 #endif #ifndef EM_R32C #define EM_R32C 162 #endif #ifndef EM_TRIMEDIA #define EM_TRIMEDIA 163 #endif #ifndef EM_QDSP6 #define EM_QDSP6 164 #endif #ifndef EM_QUALCOMM_DSP6 #define EM_QUALCOMM_DSP6 164 #endif #ifndef EM_8051 #define EM_8051 165 #endif #ifndef EM_STXP7X #define EM_STXP7X 166 #endif #ifndef EM_NDS32 #define EM_NDS32 167 #endif #ifndef EM_ECOG1X #define EM_ECOG1X 168 #endif #ifndef EM_MAXQ30 #define EM_MAXQ30 169 #endif #ifndef EM_XIMO16 #define EM_XIMO16 170 #endif #ifndef EM_MANIK #define EM_MANIK 171 #endif #ifndef EM_CRAYNV2 #define EM_CRAYNV2 172 #endif #ifndef EM_RX #define EM_RX 173 #endif #ifndef EM_METAG #define EM_METAG 174 #endif #ifndef EM_MCST_ELBRUS #define EM_MCST_ELBRUS 175 #endif #ifndef EM_ECOG16 #define EM_ECOG16 176 #endif #ifndef EM_CR16 #define EM_CR16 177 #endif #ifndef EM_ETPU #define EM_ETPU 178 #endif #ifndef EM_SLE9X #define EM_SLE9X 179 #endif #ifndef EM_L10M #define EM_L10M 180 #endif #ifndef EM_K10M #define EM_K10M 181 #endif #ifndef EM_AARCH64 #define EM_AARCH64 183 #endif #ifndef EM_AVR32 #define EM_AVR32 185 #endif #ifndef EM_STM8 #define EM_STM8 186 #endif #ifndef EM_TILE64 #define EM_TILE64 187 #endif #ifndef EM_TILEPRO #define EM_TILEPRO 188 #endif #ifndef EM_MICROBLAZE #define EM_MICROBLAZE 189 #endif #ifndef EM_CUDA #define EM_CUDA 190 #endif #ifndef EM_TILEGX #define EM_TILEGX 191 #endif #ifndef EM_CLOUDSHIELD #define EM_CLOUDSHIELD 192 #endif #ifndef EM_COREA_1ST #define EM_COREA_1ST 193 #endif #ifndef EM_COREA_2ND #define EM_COREA_2ND 194 #endif #ifndef EM_ARC_COMPACT2 #define EM_ARC_COMPACT2 195 #endif #ifndef EM_OPEN8 #define EM_OPEN8 196 #endif #ifndef EM_RL78 #define EM_RL78 197 #endif #ifndef EM_VIDEOCORE5 #define EM_VIDEOCORE5 198 #endif #ifndef EM_78KOR #define EM_78KOR 199 #endif #ifndef EM_56800EX #define EM_56800EX 200 #endif #ifndef EM_BA1 #define EM_BA1 201 #endif #ifndef EM_BA2 #define EM_BA2 202 #endif #ifndef EM_XCORE #define EM_XCORE 203 #endif #ifndef EM_MCHP_PIC #define EM_MCHP_PIC 204 #endif #ifndef EM_KM32 #define EM_KM32 210 #endif #ifndef EM_KMX32 #define EM_KMX32 211 #endif #ifndef EM_EMX16 #define EM_EMX16 212 #endif #ifndef EM_EMX8 #define EM_EMX8 213 #endif #ifndef EM_KVARC #define EM_KVARC 214 #endif #ifndef EM_CDP #define EM_CDP 215 #endif #ifndef EM_COGE #define EM_COGE 216 #endif #ifndef EM_COOL #define EM_COOL 217 #endif #ifndef EM_NORC #define EM_NORC 218 #endif #ifndef EM_CSR_KALIMBA #define EM_CSR_KALIMBA 219 #endif #ifndef EM_Z80 #define EM_Z80 220 #endif #ifndef EM_VISIUM #define EM_VISIUM 221 #endif #ifndef EM_FT32 #define EM_FT32 222 #endif #ifndef EM_MOXIE #define EM_MOXIE 223 #endif #ifndef EM_AMDGPU #define EM_AMDGPU 224 #endif #ifndef EM_RISCV #define EM_RISCV 243 #endif #ifndef EM_BPF #define EM_BPF 247 #endif /* Standard Elf dynamic tags. */ #ifndef DT_NULL #define DT_NULL 0 #endif #ifndef DT_NEEDED #define DT_NEEDED 1 #endif #ifndef DT_PLTRELSZ #define DT_PLTRELSZ 2 #endif #ifndef DT_PLTGOT #define DT_PLTGOT 3 #endif #ifndef DT_HASH #define DT_HASH 4 #endif #ifndef DT_STRTAB #define DT_STRTAB 5 #endif #ifndef DT_SYMTAB #define DT_SYMTAB 6 #endif #ifndef DT_RELA #define DT_RELA 7 #endif #ifndef DT_RELASZ #define DT_RELASZ 8 #endif #ifndef DT_RELAENT #define DT_RELAENT 9 #endif #ifndef DT_STRSZ #define DT_STRSZ 10 #endif #ifndef DT_SYMENT #define DT_SYMENT 11 #endif #ifndef DT_INIT #define DT_INIT 12 #endif #ifndef DT_FINI #define DT_FINI 13 #endif #ifndef DT_SONAME #define DT_SONAME 14 #endif #ifndef DT_RPATH #define DT_RPATH 15 #endif #ifndef DT_SYMBOLIC #define DT_SYMBOLIC 16 #endif #ifndef DT_REL #define DT_REL 17 #endif #ifndef DT_RELSZ #define DT_RELSZ 18 #endif #ifndef DT_RELENT #define DT_RELENT 19 #endif #ifndef DT_PLTREL #define DT_PLTREL 20 #endif #ifndef DT_DEBUG #define DT_DEBUG 21 #endif #ifndef DT_TEXTREL #define DT_TEXTREL 22 #endif #ifndef DT_JMPREL #define DT_JMPREL 23 #endif #ifndef SHN_UNDEF #define SHN_UNDEF 0 #endif #ifndef SHN_LORESERVE #define SHN_LORESERVE 0xff00 #endif #ifndef SHN_LOPROC #define SHN_LOPROC 0xff00 #endif #ifndef SHN_HIPROC #define SHN_HIPROC 0xff1f #endif #ifndef SHN_ABS #define SHN_ABS 0xfff1 #endif #ifndef SHN_COMMON #define SHN_COMMON 0xfff2 #endif #ifndef SHN_HIRESERVE #define SHN_HIRESERVE 0xffff #endif #ifndef EV_CURRENT #define EV_CURRENT 1 #endif #ifndef EV_NONE #define EV_NONE 0 #endif #ifndef EI_MAG0 #define EI_MAG0 0 #endif #ifndef EI_MAG1 #define EI_MAG1 1 #endif #ifndef EI_MAG2 #define EI_MAG2 2 #endif #ifndef EI_MAG3 #define EI_MAG3 3 #endif #ifndef EI_CLASS #define EI_CLASS 4 #endif #ifndef EI_DATA #define EI_DATA 5 #endif #ifndef EI_VERSION #define EI_VERSION 6 #endif #ifndef EI_PAD #define EI_PAD 7 #endif #ifndef EI_OSABI #define EI_OSABI 7 #endif #ifndef EI_NIDENT #define EI_NIDENT 16 #endif #ifndef EI_ABIVERSION #define EI_ABIVERSION 8 #endif #ifndef ELFMAG0 #define ELFMAG0 0x7f #endif #ifndef ELFMAG1 #define ELFMAG1 'E' #endif #ifndef ELFMAG2 #define ELFMAG2 'L' #endif #ifndef ELFMAG3 #define ELFMAG3 'F' #endif #ifndef ELFCLASSNONE #define ELFCLASSNONE 0 #endif #ifndef ELFCLASS32 #define ELFCLASS32 1 #endif #ifndef ELFCLASS64 #define ELFCLASS64 2 #endif #ifndef ELFDATANONE #define ELFDATANONE 0 #endif #ifndef ELFDATA2LSB #define ELFDATA2LSB 1 #endif #ifndef ELFDATA2MSB #define ELFDATA2MSB 2 #endif #ifndef ELFOSABI_NONE #define ELFOSABI_NONE 0 #endif #ifndef ELFOSABI_SYSV #define ELFOSABI_SYSV 0 #endif #ifndef ELFOSABI_HPUX #define ELFOSABI_HPUX 1 #endif #ifndef ELFOSABI_NETBSD #define ELFOSABI_NETBSD 2 #endif #ifndef ELFOSABI_GNU #define ELFOSABI_GNU 3 #endif #ifndef ELFOSABI_LINUX #define ELFOSABI_LINUX ELFOSABI_GNU #endif #ifndef ELFOSABI_SOLARIS #define ELFOSABI_SOLARIS 6 #endif #ifndef ELFOSABI_AIX #define ELFOSABI_AIX 7 #endif #ifndef ELFOSABI_IRIX #define ELFOSABI_IRIX 8 #endif #ifndef ELFOSABI_FREEBSD #define ELFOSABI_FREEBSD 9 #endif #ifndef ELFOSABI_TRU64 #define ELFOSABI_TRU64 10 #endif #ifndef ELFOSABI_MODESTO #define ELFOSABI_MODESTO 11 #endif #ifndef ELFOSABI_OPENBSD #define ELFOSABI_OPENBSD 12 #endif #ifndef ELFOSABI_ARM_AEABI #define ELFOSABI_ARM_AEABI 64 #endif #ifndef ELFOSABI_ARM #define ELFOSABI_ARM 97 #endif #ifndef ELFOSABI_STANDALONE #define ELFOSABI_STANDALONE 255 #endif /* for the producer code. */ #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif #ifndef R_QUALCOMM_REL32 #define R_QUALCOMM_REL32 6 #endif /* For Freebsd: */ #ifndef R_PPC64_ADDR32 #define R_PPC64_ADDR32 1 #endif #ifndef R_PPC64_DTPREL32 #define R_PPC64_DTPREL32 110 #endif #ifndef R_PPC64_DTPREL64 #define R_PPC64_DTPREL64 78 #endif #ifndef R_PPC_DTPREL32 #define R_PPC_DTPREL32 78 #endif /* The following two probably useless. */ #ifndef R_X86_64_PC32_BND #define R_X86_64_PC32_BND 39 #endif #ifndef R_X86_64_PLT32_BND #define R_X86_64_PLT32_BND 40 #endif #ifndef R_386_32 #define R_386_32 1 #endif /* R_386_32 */ #ifndef R_386_TLS_DTPOFF32 #define R_386_TLS_DTPOFF32 36 #endif /* R_386_TLS_DTPOFF32 */ #ifndef R_386_TLS_LDO_32 #define R_386_TLS_LDO_32 32 #endif /* R_386_TLS_LDO_32 */ #ifndef R_390_32 #define R_390_32 4 #endif /* R_390_32 */ #ifndef R_390_64 #define R_390_64 22 #endif /* R_390_64 */ #ifndef R_390_TLS_LDO32 #define R_390_TLS_LDO32 52 #endif /* R_390_TLS_LDO32 */ #ifndef R_390_TLS_LDO64 #define R_390_TLS_LDO64 53 #endif /* R_390_TLS_LDO64 */ #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 258 #endif /* R_AARCH64_ABS32 */ #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 257 #endif /* R_AARCH64_ABS64 */ #ifndef R_ARM_ABS32 #define R_ARM_ABS32 2 #endif /* R_ARM_ABS32 */ #ifndef R_ARM_TLS_LDO32 #define R_ARM_TLS_LDO32 106 #endif /* R_ARM_TLS_LDO32 */ #ifndef R_IA64_DIR32LSB #define R_IA64_DIR32LSB 0x25 #endif /* R_IA64_DIR32LSB */ #ifndef R_IA64_DIR64LSB #define R_IA64_DIR64LSB 0x27 #endif /* R_IA64_DIR64LSB */ #ifndef R_IA64_DTPREL32LSB #define R_IA64_DTPREL32LSB 0xb5 #endif /* R_IA64_DTPREL32LSB */ #ifndef R_IA64_DTPREL64LSB #define R_IA64_DTPREL64LSB 0xb7 #endif /* R_IA64_DTPREL64LSB */ #ifndef R_IA64_REL32LSB #define R_IA64_REL32LSB 0x6d #endif /* R_IA64_REL32LSB */ #ifndef R_IA64_SECREL32LSB #define R_IA64_SECREL32LSB 0x65 #endif /* R_IA64_SECREL32LSB */ #ifndef R_IA64_SECREL64LSB #define R_IA64_SECREL64LSB 0x67 #endif /* R_IA64_SECREL64LSB */ #ifndef R_MIPS_32 #define R_MIPS_32 2 #endif /* R_MIPS_32 */ #ifndef R_MIPS_64 #define R_MIPS_64 18 #endif /* R_MIPS_64 */ #ifndef R_MIPS_TLS_DTPREL32 #define R_MIPS_TLS_DTPREL32 39 #endif /* R_MIPS_TLS_DTPREL32 */ #ifndef R_MIPS_TLS_DTPREL64 #define R_MIPS_TLS_DTPREL64 41 #endif /* R_MIPS_TLS_DTPREL64 */ #ifndef R_PPC64_ADDR64 #define R_PPC64_ADDR64 38 #endif /* R_PPC64_ADDR64 */ #ifndef R_PPC64_DTPREL32 #define R_PPC64_DTPREL32 110 #endif /* R_PPC64_DTPREL32 */ #ifndef R_PPC64_DTPREL64 #define R_PPC64_DTPREL64 78 #endif /* R_PPC64_DTPREL64 */ #ifndef R_PPC_ADDR32 #define R_PPC_ADDR32 1 #endif /* R_PPC_ADDR32 */ #ifndef R_PPC_DTPREL32 #define R_PPC_DTPREL32 78 #endif /* R_PPC_DTPREL32 */ #ifndef R_QUALCOMM_REL32 #define R_QUALCOMM_REL32 6 #endif /* R_QUALCOMM_REL32 */ #ifndef R_SH_DIR32 #define R_SH_DIR32 1 #endif /* R_SH_DIR32 */ #ifndef R_SH_TLS_DTPOFF32 #define R_SH_TLS_DTPOFF32 150 #endif /* R_SH_TLS_DTPOFF32 */ #ifndef R_SPARC_TLS_DTPOFF32 #define R_SPARC_TLS_DTPOFF32 76 #endif /* R_SPARC_TLS_DTPOFF32 */ #ifndef R_SPARC_TLS_DTPOFF64 #define R_SPARC_TLS_DTPOFF64 77 #endif /* R_SPARC_TLS_DTPOFF64 */ #ifndef R_SPARC_UA32 #define R_SPARC_UA32 23 #endif /* R_SPARC_UA32 */ #ifndef R_SPARC_UA64 #define R_SPARC_UA64 54 #endif /* R_SPARC_UA64 */ #ifndef R_X86_64_32 #define R_X86_64_32 10 #endif /* R_X86_64_32 */ #ifndef R_X86_64_64 #define R_X86_64_64 1 #endif /* R_X86_64_64 */ #ifndef R_X86_64_DTPOFF32 #define R_X86_64_DTPOFF32 21 #endif /* R_X86_64_DTPOFF32 */ #ifndef R_X86_64_DTPOFF64 #define R_X86_64_DTPOFF64 17 #endif /* R_X86_64_DTPOFF64 */ #ifndef R_X86_64_PC32 #define R_X86_64_PC32 2 #endif /* R_X86_64_PC32 */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_ELF_DEFINES_H */ dwarfutils-20200114/libdwarf/dwarf_elf_load_headers.c000066400000000000000000001703261361531463500225320ustar00rootroot00000000000000/* Copyright 2018 David Anderson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This reads elf headers and creates generic-elf structures containing the Elf headers. */ #include "config.h" #include #include /* For memcpy etc */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #include /* for open() */ #include /* for open() */ #include /* for open() */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarfdefs.h" #include "dwarf.h" #include "libdwarf.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "memcpy_swap.h" #include "dwarf_elfstructs.h" #include "dwarf_reading.h" #include "dwarf_elf_defines.h" #include "dwarf_elfread.h" #include "dwarf_object_detector.h" #include "dwarf_object_read_common.h" #include "dwarf_util.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #define TRUE 1 #define FALSE 0 #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ static int _dwarf_load_elf_section_is_dwarf(const char *sname) { if (!strncmp(sname,".rel",4)) { return FALSE; } if (!strncmp(sname,".debug_",7)) { return TRUE; } if (!strncmp(sname,".zdebug_",8)) { return TRUE; } if (!strcmp(sname,".eh_frame")) { return TRUE; } if (!strncmp(sname,".gdb_index",10)) { return TRUE; } return FALSE; } static int is_empty_section(Dwarf_Unsigned type) { if (type == SHT_NOBITS) { return TRUE; } if (type == SHT_NULL) { return TRUE; } return FALSE; } #if 0 int dwarf_construct_elf_access_path(const char *path, dwarf_elf_object_access_internals_t **mp,int *errcode) { int fd = -1; int res = 0; dwarf_elf_object_access_internals_t *mymp = 0; fd = open(path, O_RDONLY|O_BINARY); if (fd < 0) { *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; return DW_DLV_ERROR; } res = dwarf_construct_elf_access(fd, path,&mymp,errcode); if (res != DW_DLV_OK) { close(fd); return res; } mymp->f_destruct_close_fd = TRUE; *mp = mymp; return res; } #endif /* 0 */ /* Here path is not essential. Pass in with "" if unknown. */ int dwarf_construct_elf_access(int fd, const char *path, dwarf_elf_object_access_internals_t **mp,int *errcode) { unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; dwarf_elf_object_access_internals_t *mfp = 0; int res = 0; res = dwarf_object_detector_fd(fd, &ftype,&endian,&offsetsize, &filesize, errcode); if (res != DW_DLV_OK) { return res; } mfp = calloc(1,sizeof(dwarf_elf_object_access_internals_t)); if (!mfp) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* For non-libelf Elf, call it 'F'. Libelf Elf uses 'E' */ mfp->f_ident[0] = 'F'; mfp->f_ident[1] = 1; mfp->f_fd = fd; mfp->f_destruct_close_fd = FALSE; mfp->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); mfp->f_filesize = filesize; mfp->f_offsetsize = offsetsize; mfp->f_pointersize = offsetsize; mfp->f_endian = endian; mfp->f_ftype = ftype; mfp->f_path = strdup(path); *mp = mfp; return DW_DLV_OK; } /* Caller must zero the passed in pointer after this returns to remind the caller to avoid use of the pointer. */ int dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t* ep, UNUSEDARG int *errcode) { struct generic_shdr *shp = 0; Dwarf_Unsigned shcount = 0; Dwarf_Unsigned i = 0; free(ep->f_ehdr); shp = ep->f_shdr; shcount = ep->f_loc_shdr.g_count; for(i = 0; i < shcount; ++i,++shp) { free(shp->gh_rels); shp->gh_rels = 0; free(shp->gh_content); shp->gh_content = 0; free(shp->gh_sht_group_array); shp->gh_sht_group_array = 0; shp->gh_sht_group_array_count = 0; } free(ep->f_shdr); free(ep->f_phdr); free(ep->f_elf_shstrings_data); free(ep->f_dynamic); free(ep->f_symtab_sect_strings); free(ep->f_dynsym_sect_strings); free(ep->f_symtab); free(ep->f_dynsym); /* if TRUE close f_fd on destruct.*/ if (ep->f_destruct_close_fd) { close(ep->f_fd); } ep->f_ident[0] = 'X'; free(ep->f_path); free(ep); return DW_DLV_OK; } static int generic_ehdr_from_32(dwarf_elf_object_access_internals_t *ep, struct generic_ehdr *ehdr, dw_elf32_ehdr *e, UNUSEDARG int *errcode) { int i = 0; for (i = 0; i < EI_NIDENT; ++i) { ehdr->ge_ident[i] = e->e_ident[i]; } ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type); ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine); ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version); ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry); ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff); ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff); ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags); ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize); ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize); ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum); ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize); ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum); ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx); ep->f_machine = ehdr->ge_machine; ep->f_ehdr = ehdr; ep->f_loc_ehdr.g_name = "Elf File Header"; ep->f_loc_ehdr.g_offset = 0; ep->f_loc_ehdr.g_count = 1; ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf32_ehdr); ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf32_ehdr); return DW_DLV_OK; } static int generic_ehdr_from_64(dwarf_elf_object_access_internals_t* ep, struct generic_ehdr *ehdr, dw_elf64_ehdr *e, UNUSEDARG int *errcode) { int i = 0; for (i = 0; i < EI_NIDENT; ++i) { ehdr->ge_ident[i] = e->e_ident[i]; } ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type); ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine); ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version); ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry); ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff); ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff); ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags); ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize); ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize); ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum); ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize); ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum); ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx); ep->f_machine = ehdr->ge_machine; ep->f_ehdr = ehdr; ep->f_loc_ehdr.g_name = "Elf File Header"; ep->f_loc_ehdr.g_offset = 0; ep->f_loc_ehdr.g_count = 1; ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf64_ehdr); ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf64_ehdr); return DW_DLV_OK; } #if 0 /* not used */ static int generic_phdr_from_phdr32(dwarf_elf_object_access_internals_t* ep, struct generic_phdr **phdr_out, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf32_phdr *pph =0; dw_elf32_phdr *orig_pph =0; struct generic_phdr *gphdr =0; struct generic_phdr *orig_gphdr =0; Dwarf_Unsigned i = 0; int res = 0; *count_out = 0; pph = (dw_elf32_phdr *)calloc(count , entsize); if(pph == 0) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr)); if(gphdr == 0) { free(pph); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_pph = pph; orig_gphdr = gphdr; res = RRMOA(ep->f_fd,pph,offset,count*entsize, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(pph); free(gphdr); return res; } for( i = 0; i < count; ++i, pph++,gphdr++) { ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type); ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset); ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr); ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr); ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz); ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz); ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags); ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align); } free(orig_pph); *phdr_out = orig_gphdr; *count_out = count; ep->f_phdr = orig_gphdr; ep->f_loc_phdr.g_name = "Program Header"; ep->f_loc_phdr.g_offset = offset; ep->f_loc_phdr.g_count = count; ep->f_loc_phdr.g_entrysize = sizeof(dw_elf32_phdr); ep->f_loc_phdr.g_totalsize = sizeof(dw_elf32_phdr)*count; return DW_DLV_OK; } static int generic_phdr_from_phdr64(dwarf_elf_object_access_internals_t* ep, struct generic_phdr **phdr_out, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf64_phdr *pph =0; dw_elf64_phdr *orig_pph =0; struct generic_phdr *gphdr =0; struct generic_phdr *orig_gphdr =0; int res = 0; Dwarf_Unsigned i = 0; *count_out = 0; pph = (dw_elf64_phdr *)calloc(count , entsize); if(pph == 0) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr)); if(gphdr == 0) { free(pph); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_pph = pph; orig_gphdr = gphdr; res = RRMOA(ep->f_fd,pph,offset,count*entsize, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(pph); free(gphdr); return res; } for( i = 0; i < count; ++i, pph++,gphdr++) { ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type); ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset); ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr); ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr); ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz); ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz); ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags); ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align); } free(orig_pph); *phdr_out = orig_gphdr; *count_out = count; ep->f_phdr = orig_gphdr; ep->f_loc_phdr.g_name = "Program Header"; ep->f_loc_phdr.g_offset = offset; ep->f_loc_phdr.g_count = count; ep->f_loc_phdr.g_entrysize = sizeof(dw_elf64_phdr); ep->f_loc_phdr.g_totalsize = sizeof(dw_elf64_phdr)*count; return DW_DLV_OK; } #endif /* not used */ static int generic_shdr_from_shdr32(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf32_shdr *psh =0; dw_elf32_shdr *orig_psh =0; struct generic_shdr *gshdr =0; struct generic_shdr *orig_gshdr =0; Dwarf_Unsigned i = 0; int res = 0; *count_out = 0; psh = (dw_elf32_shdr *)calloc(count , entsize); if(!psh) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr)); if(!gshdr) { free(psh); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_psh = psh; orig_gshdr = gshdr; res = RRMOA(ep->f_fd,psh,offset,count*entsize, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(psh); free(gshdr); return res; } for(i = 0; i < count; ++i, psh++,gshdr++) { gshdr->gh_secnum = i; ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name); ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type); ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags); ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr); ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset); ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size); ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link); ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info); ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign); ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize); if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){ gshdr->gh_reloc_target_secnum = gshdr->gh_info; } } free(orig_psh); *count_out = count; ep->f_shdr = orig_gshdr; ep->f_loc_shdr.g_name = "Section Header"; ep->f_loc_shdr.g_count = count; ep->f_loc_shdr.g_offset = offset; ep->f_loc_shdr.g_entrysize = sizeof(dw_elf32_shdr); ep->f_loc_shdr.g_totalsize = sizeof(dw_elf32_shdr)*count; return DW_DLV_OK; } static int generic_shdr_from_shdr64(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned * count_out, Dwarf_Unsigned offset, Dwarf_Unsigned entsize, Dwarf_Unsigned count, int *errcode) { dw_elf64_shdr *psh =0; dw_elf64_shdr *orig_psh =0; struct generic_shdr *gshdr =0; struct generic_shdr *orig_gshdr =0; Dwarf_Unsigned i = 0; int res = 0; *count_out = 0; psh = (dw_elf64_shdr *)calloc(count , entsize); if(!psh) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr)); if(gshdr == 0) { free(psh); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } orig_psh = psh; orig_gshdr = gshdr; res = RRMOA(ep->f_fd,psh,offset,count*entsize, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(psh); free(gshdr); return res; } for( i = 0; i < count; ++i, psh++,gshdr++) { gshdr->gh_secnum = i; ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name); ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type); ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags); ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr); ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset); ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size); ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link); ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info); ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign); ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize); if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){ gshdr->gh_reloc_target_secnum = gshdr->gh_info; } } free(orig_psh); *count_out = count; ep->f_shdr = orig_gshdr; ep->f_loc_shdr.g_name = "Section Header"; ep->f_loc_shdr.g_count = count; ep->f_loc_shdr.g_offset = offset; ep->f_loc_shdr.g_entrysize = sizeof(dw_elf64_shdr); ep->f_loc_shdr.g_totalsize = sizeof(dw_elf64_shdr)*count; return DW_DLV_OK; } static int dwarf_generic_elf_load_symbols32( dwarf_elf_object_access_internals_t *ep, struct generic_symentry **gsym_out, Dwarf_Unsigned offset,Dwarf_Unsigned size, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; dw_elf32_sym *psym = 0; dw_elf32_sym *orig_psym = 0; struct generic_symentry * gsym = 0; struct generic_symentry * orig_gsym = 0; int res = 0; ecount = (long)(size/sizeof(dw_elf32_sym)); size2 = ecount * sizeof(dw_elf32_sym); if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } psym = calloc(ecount,sizeof(dw_elf32_sym)); if (!psym) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gsym = calloc(ecount,sizeof(struct generic_symentry)); if (!gsym) { free(psym); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,psym,offset,size, ep->f_filesize,errcode); if(res!= DW_DLV_OK) { free(psym); free(gsym); return res; } orig_psym = psym; orig_gsym = gsym; for ( i = 0; i < ecount; ++i,++psym,++gsym) { Dwarf_Unsigned bind = 0; Dwarf_Unsigned type = 0; ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name); ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value); ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size); ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info); ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other); ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx); bind = gsym->gs_info >> 4; type = gsym->gs_info & 0xf; gsym->gs_bind = bind; gsym->gs_type = type; } *count_out = ecount; *gsym_out = orig_gsym; free(orig_psym); return DW_DLV_OK; } static int dwarf_generic_elf_load_symbols64( dwarf_elf_object_access_internals_t *ep, struct generic_symentry **gsym_out, Dwarf_Unsigned offset,Dwarf_Unsigned size, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; dw_elf64_sym *psym = 0; dw_elf64_sym *orig_psym = 0; struct generic_symentry * gsym = 0; struct generic_symentry * orig_gsym = 0; int res = 0; ecount = (long)(size/sizeof(dw_elf64_sym)); size2 = ecount * sizeof(dw_elf64_sym); if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } psym = calloc(ecount,sizeof(dw_elf64_sym)); if (!psym) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } gsym = calloc(ecount,sizeof(struct generic_symentry)); if (!gsym) { free(psym); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,psym,offset,size, ep->f_filesize,errcode); if(res!= DW_DLV_OK) { free(psym); free(gsym); *errcode = DW_DLE_ALLOC_FAIL; return res; } orig_psym = psym; orig_gsym = gsym; for ( i = 0; i < ecount; ++i,++psym,++gsym) { Dwarf_Unsigned bind = 0; Dwarf_Unsigned type = 0; ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name); ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value); ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size); ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info); ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other); ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx); bind = gsym->gs_info >> 4; type = gsym->gs_info & 0xf; gsym->gs_bind = bind; gsym->gs_type = type; } *count_out = ecount; *gsym_out = orig_gsym; free(orig_psym); return DW_DLV_OK; } static int dwarf_generic_elf_load_symbols( dwarf_elf_object_access_internals_t *ep, int secnum, struct generic_shdr *psh, struct generic_symentry **gsym_out, Dwarf_Unsigned *count_out,int *errcode) { int res = 0; struct generic_symentry *gsym = 0; Dwarf_Unsigned count = 0; if(!secnum) { return DW_DLV_NO_ENTRY; } if (ep->f_offsetsize == 32) { res = dwarf_generic_elf_load_symbols32(ep, &gsym, psh->gh_offset,psh->gh_size, &count,errcode); } else if (ep->f_offsetsize == 64) { res = dwarf_generic_elf_load_symbols64(ep, &gsym, psh->gh_offset,psh->gh_size, &count,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res == DW_DLV_OK) { *gsym_out = gsym; *count_out = count; } return res; } #if 0 int dwarf_load_elf_dynsym_symbols( dwarf_elf_object_access_internals_t *ep, int*errcode) { int res = 0; struct generic_symentry *gsym = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned secnum = ep->f_dynsym_sect_index; struct generic_shdr * psh = 0; if(!secnum) { return DW_DLV_NO_ENTRY; } psh = ep->f_shdr + secnum; res = dwarf_generic_elf_load_symbols(ep, secnum, psh, &gsym, &count,errcode); if (res == DW_DLV_OK) { ep->f_dynsym = gsym; ep->f_loc_dynsym.g_count = count; } return res; } #endif /* 0 */ int _dwarf_load_elf_symtab_symbols( dwarf_elf_object_access_internals_t *ep, int*errcode) { int res = 0; struct generic_symentry *gsym = 0; Dwarf_Unsigned count = 0; Dwarf_Unsigned secnum = ep->f_symtab_sect_index; struct generic_shdr * psh = 0; if(!secnum) { return DW_DLV_NO_ENTRY; } psh = ep->f_shdr + secnum; res = dwarf_generic_elf_load_symbols(ep, secnum, psh, &gsym, &count,errcode); if (res == DW_DLV_OK) { ep->f_symtab = gsym; ep->f_loc_symtab.g_count = count; } return res; } static int generic_rel_from_rela32( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf32_rela *relp, struct generic_rela *grel, int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; ecount = size/sizeof(dw_elf32_rela); size2 = ecount * sizeof(dw_elf32_rela); if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); /* addend signed */ ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend); SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend)); grel->gr_isrela = TRUE; grel->gr_sym = grel->gr_info>>8; /* ELF32_R_SYM */ grel->gr_type = grel->gr_info & 0xff; } return DW_DLV_OK; } static int generic_rel_from_rela64( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf64_rela *relp, struct generic_rela *grel, int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; int objlittleendian = (ep->f_endian == DW_OBJECT_LSB); int ismips64 = (ep->f_machine == EM_MIPS); int issparcv9 = (ep->f_machine == EM_SPARCV9); ecount = size/sizeof(dw_elf64_rela); size2 = ecount * sizeof(dw_elf64_rela); if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend); SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend)); if (ismips64 && objlittleendian ) { char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; grel->gr_type2 = relp->r_info[6]; grel->gr_type3 = relp->r_info[5]; } else if (issparcv9) { /* Always Big Endian? */ char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; } else { grel->gr_sym = grel->gr_info >> 32; grel->gr_type = grel->gr_info & 0xffffffff; } grel->gr_isrela = TRUE; } return DW_DLV_OK; } #if 0 static int generic_rel_from_rel32( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf32_rel *relp, struct generic_rela *grel,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; ecount = size/sizeof(dw_elf32_rel); size2 = ecount * sizeof(dw_elf32_rel); if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { grel->gr_isrela = 0; ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); grel->gr_addend = 0; /* Unused for plain .rel */ grel->gr_sym = grel->gr_info >>8; /* ELF32_R_SYM */ grel->gr_isrela = FALSE; grel->gr_type = grel->gr_info & 0xff; } return DW_DLV_OK; } #endif /* 0 */ #if 0 static int generic_rel_from_rel64( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, dw_elf64_rel *relp, struct generic_rela *grel,int *errcode) { Dwarf_Unsigned ecount = 0; Dwarf_Unsigned size = gsh->gh_size; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned i = 0; int objlittleendian = (ep->f_endian == DW_OBJECT_LSB); int ismips64 = (ep->f_machine == EM_MIPS); int issparcv9 = (ep->f_machine == EM_SPARCV9); ecount = size/sizeof(dw_elf64_rel); size2 = ecount * sizeof(dw_elf64_rel); if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } for ( i = 0; i < ecount; ++i,++relp,++grel) { grel->gr_isrela = 0; ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); grel->gr_addend = 0; /* Unused for plain .rel */ if (ismips64 && objlittleendian ) { char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; grel->gr_type2 = relp->r_info[6]; grel->gr_type3 = relp->r_info[5]; } else if (issparcv9) { /* Always Big Endian? */ char realsym[4]; memcpy(realsym,&relp->r_info,sizeof(realsym)); ASNAR(ep->f_copy_word,grel->gr_sym,realsym); grel->gr_type = relp->r_info[7]; } else { grel->gr_sym = grel->gr_info >>32; grel->gr_type = grel->gr_info & 0xffffffff; } grel->gr_isrela = FALSE; } return DW_DLV_OK; } #endif /* 0 */ #if 0 int dwarf_load_elf_dynstr( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr *strpsh = 0; int res = 0; Dwarf_Unsigned strsectindex =0; Dwarf_Unsigned strsectlength = 0; if (!ep->f_dynsym_sect_strings_sect_index) { return DW_DLV_NO_ENTRY; } strsectindex = ep->f_dynsym_sect_strings_sect_index; strsectlength = ep->f_dynsym_sect_strings_max; strpsh = ep->f_shdr + strsectindex; /* Alloc an extra byte as a guaranteed NUL byte at the end of the strings in case the section is corrupted and lacks a NUL at end. */ ep->f_dynsym_sect_strings = calloc(1,strsectlength+1); if(!ep->f_dynsym_sect_strings) { ep->f_dynsym_sect_strings = 0; ep->f_dynsym_sect_strings_max = 0; ep->f_dynsym_sect_strings_sect_index = 0; *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,ep->f_dynsym_sect_strings, strpsh->gh_offset, strsectlength, ep->f_filesize,errcode); if(res != DW_DLV_OK) { ep->f_dynsym_sect_strings = 0; ep->f_dynsym_sect_strings_max = 0; ep->f_dynsym_sect_strings_sect_index = 0; return res; } return DW_DLV_OK; } #endif /* 0 */ int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr *strpsh = 0; int res = 0; Dwarf_Unsigned strsectindex =0; Dwarf_Unsigned strsectlength = 0; if (!ep->f_symtab_sect_strings_sect_index) { return DW_DLV_NO_ENTRY; } strsectindex = ep->f_symtab_sect_strings_sect_index; strsectlength = ep->f_symtab_sect_strings_max; strpsh = ep->f_shdr + strsectindex; /* Alloc an extra byte as a guaranteed NUL byte at the end of the strings in case the section is corrupted and lacks a NUL at end. */ ep->f_symtab_sect_strings = calloc(1,strsectlength+1); if(!ep->f_symtab_sect_strings) { ep->f_symtab_sect_strings = 0; ep->f_symtab_sect_strings_max = 0; ep->f_symtab_sect_strings_sect_index = 0; *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,ep->f_symtab_sect_strings, strpsh->gh_offset, strsectlength, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(ep->f_symtab_sect_strings); ep->f_symtab_sect_strings = 0; ep->f_symtab_sect_strings_max = 0; ep->f_symtab_sect_strings_sect_index = 0; return res; } return DW_DLV_OK; } static int _dwarf_elf_load_sectstrings( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned stringsection, int *errcode) { int res = 0; struct generic_shdr *psh = 0; Dwarf_Unsigned secoffset = 0; ep->f_elf_shstrings_length = 0; if (stringsection >= ep->f_ehdr->ge_shnum) { *errcode = DW_DLE_SECTION_INDEX_BAD; return DW_DLV_ERROR; } psh = ep->f_shdr + stringsection; secoffset = psh->gh_offset; if(is_empty_section(psh->gh_type)) { *errcode = DW_DLE_ELF_STRING_SECTION_MISSING; return DW_DLV_ERROR; } if(psh->gh_size > ep->f_elf_shstrings_max) { free(ep->f_elf_shstrings_data); ep->f_elf_shstrings_data = (char *)malloc(psh->gh_size); ep->f_elf_shstrings_max = psh->gh_size; if(!ep->f_elf_shstrings_data) { ep->f_elf_shstrings_max = 0; *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } } ep->f_elf_shstrings_length = psh->gh_size; res = RRMOA(ep->f_fd,ep->f_elf_shstrings_data,secoffset, psh->gh_size, ep->f_filesize,errcode); return res; } static int elf_load_sectheaders32( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned offset,Dwarf_Unsigned entsize, Dwarf_Unsigned count,int *errcode) { Dwarf_Unsigned generic_count = 0; int res = 0; if(count == 0) { return DW_DLV_NO_ENTRY; } if(entsize < sizeof(dw_elf32_shdr)) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if ((offset > ep->f_filesize)|| (entsize > 200)|| (count > ep->f_filesize) || ((count *entsize +offset) > ep->f_filesize)) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } res = generic_shdr_from_shdr32(ep,&generic_count, offset,entsize,count,errcode); if (res != DW_DLV_OK) { return res; } if (generic_count != count) { *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH; return DW_DLV_ERROR; } return DW_DLV_OK; } static int elf_load_sectheaders64( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned offset,Dwarf_Unsigned entsize, Dwarf_Unsigned count,int*errcode) { Dwarf_Unsigned generic_count = 0; int res = 0; if(count == 0) { return DW_DLV_NO_ENTRY; } if(entsize < sizeof(dw_elf64_shdr)) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if ((offset > ep->f_filesize)|| (entsize > 200)|| (count > ep->f_filesize) || ((count *entsize +offset) > ep->f_filesize)) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } res = generic_shdr_from_shdr64(ep,&generic_count, offset,entsize,count,errcode); if (res != DW_DLV_OK) { return res; } if (generic_count != count) { *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH; return DW_DLV_ERROR; } return DW_DLV_OK; } static int _dwarf_elf_load_rela_32( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, struct generic_rela ** grel_out, Dwarf_Unsigned *count_out, int *errcode) { Dwarf_Unsigned count = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned sizeg = 0; Dwarf_Unsigned offset = 0; int res = 0; dw_elf32_rela *relp = 0; Dwarf_Unsigned object_reclen = sizeof(dw_elf32_rela); struct generic_rela *grel = 0; offset = gsh->gh_offset; size = gsh->gh_size; if(size == 0) { return DW_DLV_NO_ENTRY; } if ((offset > ep->f_filesize)|| (size > ep->f_filesize) || ((size +offset) > ep->f_filesize)) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } count = (long)(size/object_reclen); size2 = count * object_reclen; if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } relp = (dw_elf32_rela *)malloc(size); if(!relp) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(relp); return res; } sizeg = count*sizeof(struct generic_rela); grel = (struct generic_rela *)malloc(sizeg); if (!grel) { free(relp); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_rel_from_rela32(ep,gsh,relp,grel,errcode); free(relp); if (res == DW_DLV_OK) { gsh->gh_relcount = count; gsh->gh_rels = grel; *count_out = count; *grel_out = grel; return res; } /* Some sort of issue */ count_out = 0; free(grel); return res; } #if 0 static int _dwarf_elf_load_rel_32( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh,struct generic_rela ** grel_out, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned count = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned sizeg = 0; Dwarf_Unsigned offset = 0; int res = 0; dw_elf32_rel* relp = 0; Dwarf_Unsigned object_reclen = sizeof(dw_elf32_rel); struct generic_rela *grel = 0; offset = gsh->gh_offset; size = gsh->gh_size; if(size == 0) { return DW_DLV_NO_ENTRY; } if ((offset > ep->f_filesize)|| (size > ep->f_filesize) || ((size +offset) > ep->f_filesize)) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } count = size/object_reclen; size2 = count * object_reclen; if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } relp = (dw_elf32_rel *)malloc(size); if(!relp) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(relp); return res; } sizeg = count *sizeof(struct generic_rela); grel = (struct generic_rela *)malloc(sizeg); if (!grel) { free(relp); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_rel_from_rel32(ep,gsh,relp,grel,errcode); free(relp); if (res == DW_DLV_OK) { *count_out = count; *grel_out = grel; return res; } /* Some sort of error */ count_out = 0; free (grel); return res; } #endif /* 0 */ #if 0 static int _dwarf_elf_load_rel_64( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh,struct generic_rela ** grel_out, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned count = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned sizeg = 0; Dwarf_Unsigned offset = 0; int res = 0; dw_elf64_rel* relp = 0; Dwarf_Unsigned object_reclen = sizeof(dw_elf64_rel); struct generic_rela *grel = 0; offset = gsh->gh_offset; size = gsh->gh_size; if(size == 0) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if ((offset > ep->f_filesize)|| (size > ep->f_filesize) || ((size +offset) > ep->f_filesize)) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } count = size/object_reclen; size2 = count * object_reclen; if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } relp = (dw_elf64_rel *)malloc(size); if(!relp) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(relp); return res; } sizeg = count*sizeof(struct generic_rela); grel = (struct generic_rela *)malloc(sizeg); if (!grel) { free(relp); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_rel_from_rel64(ep,gsh,relp,grel,errcode); free(relp); if (res == DW_DLV_OK) { *count_out = count; *grel_out = grel; return res; } /* Some sort of error */ count_out = 0; free (grel); return res; } #endif /* 0 */ static int _dwarf_elf_load_rela_64( dwarf_elf_object_access_internals_t *ep, struct generic_shdr * gsh, struct generic_rela ** grel_out, Dwarf_Unsigned *count_out,int *errcode) { Dwarf_Unsigned count = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned size2 = 0; Dwarf_Unsigned sizeg = 0; Dwarf_Unsigned offset = 0; int res = 0; dw_elf64_rela *relp = 0; Dwarf_Unsigned object_reclen = sizeof(dw_elf64_rela); struct generic_rela *grel = 0; offset = gsh->gh_offset; size = gsh->gh_size; if(size == 0) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } if ((offset > ep->f_filesize)|| (size > ep->f_filesize) || ((size +offset) > ep->f_filesize)) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } count = (long)(size/object_reclen); size2 = count * object_reclen; if(size != size2) { *errcode = DW_DLE_SECTION_SIZE_ERROR; return DW_DLV_ERROR; } /* Here want native rela size from the file */ relp = (dw_elf64_rela *)malloc(size); if(!relp) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,relp,offset,size, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(relp); return res; } sizeg = count*sizeof(struct generic_rela); /* Here want generic-record size from the file */ grel = (struct generic_rela *)malloc(sizeg); if (!grel) { free(relp); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_rel_from_rela64(ep,gsh,relp,grel,errcode); free(relp); if (res == DW_DLV_OK) { *count_out = count; *grel_out = grel; return res; } /* Some sort of error */ count_out = 0; free (grel); return res; } /* Is this rela section related to dwarf at all? set oksecnum zero if not. Else set targ secnum. Never returns DW_DLV_NO_ENTRY. */ static int this_is_a_section_dwarf_related( dwarf_elf_object_access_internals_t *ep, struct generic_shdr *gshdr, unsigned *oksecnum_out, int *errcode) { unsigned oksecnum = 0; struct generic_shdr *gstarg = 0; if (gshdr->gh_type != SHT_RELA ) { *oksecnum_out = 0; return DW_DLV_OK; } oksecnum = gshdr->gh_reloc_target_secnum; if (oksecnum >= ep->f_loc_shdr.g_count) { *oksecnum_out = 0; *errcode = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } gstarg = ep->f_shdr+oksecnum; if (!gstarg->gh_is_dwarf) { *oksecnum_out = 0; /* no reloc needed. */ return DW_DLV_OK; } *oksecnum_out = oksecnum; return DW_DLV_OK; } /* Secnum here is the secnum of rela. Not the target of the relocations. */ int _dwarf_load_elf_rela( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned secnum, int *errcode) { struct generic_shdr *gshdr = 0; Dwarf_Unsigned seccount = 0; unsigned offsetsize = 0; struct generic_rela *grp = 0; Dwarf_Unsigned count_read = 0; int res = 0; unsigned oksec = 0; if (!ep) { *errcode = DW_DLE_INTERNAL_NULL_POINTER; return DW_DLV_ERROR; } offsetsize = ep->f_offsetsize; seccount = ep->f_loc_shdr.g_count; if (secnum >= seccount) { *errcode = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } gshdr = ep->f_shdr +secnum; if (is_empty_section(gshdr->gh_type)) { return DW_DLV_NO_ENTRY; } res = this_is_a_section_dwarf_related(ep,gshdr,&oksec,errcode); if (res == DW_DLV_ERROR) { return res; } if (!oksec) { return DW_DLV_OK; } /* We will actually read these relocations. Others get ignored. */ if (offsetsize == 32) { res = _dwarf_elf_load_rela_32(ep, gshdr,&grp,&count_read,errcode); } else if (offsetsize == 64) { res = _dwarf_elf_load_rela_64(ep, gshdr,&grp,&count_read,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } gshdr->gh_rels = grp; gshdr->gh_relcount = count_read; return DW_DLV_OK; } #if 0 int _dwarf_load_elf_rel( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned secnum, int *errcode) { struct generic_shdr *gshdr = 0; Dwarf_Unsigned generic_count = 0; unsigned offsetsize = 0; struct generic_rela *grp = 0; Dwarf_Unsigned count_read = 0; int res = 0; if (!ep) { *errcode = DW_DLE_INTERNAL_NULL_POINTER; return DW_DLV_ERROR; } offsetsize = ep->f_offsetsize; generic_count = ep->f_loc_shdr.g_count; if (secnum >= generic_count) { *errcode = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } gshdr = ep->f_shdr +secnum; if (is_empty_section(gshdr->gh_type)) { return DW_DLV_NO_ENTRY; } if (offsetsize == 32) { res = _dwarf_elf_load_rel_32(ep, gshdr,&grp,&count_read,errcode); } else if (offsetsize == 64) { res = _dwarf_elf_load_rel_64(ep, gshdr,&grp,&count_read,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } gshdr->gh_rels = grp; gshdr->gh_relcount = count_read; return DW_DLV_OK; } #endif /* 0 */ static int validate_section_name_string(Dwarf_Unsigned section_length, Dwarf_Unsigned string_loc_index, const char * strings_start, int * errcode) { const char *endpoint = strings_start + section_length; const char *cur = 0; if (section_length <= string_loc_index) { *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD; return DW_DLV_ERROR; } cur = string_loc_index+strings_start; for( ; cur < endpoint;++cur) { if (!*cur) { return DW_DLV_OK; } } *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD; return DW_DLV_ERROR; } static int _dwarf_elf_load_sect_namestring( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr *gshdr = 0; Dwarf_Unsigned generic_count = 0; Dwarf_Unsigned i = 1; const char *stringsecbase = 0; stringsecbase = ep->f_elf_shstrings_data; gshdr = ep->f_shdr; generic_count = ep->f_loc_shdr.g_count; for(i = 0; i < generic_count; i++, ++gshdr) { const char *namestr = ""; int res = 0; res = validate_section_name_string(ep->f_elf_shstrings_length, gshdr->gh_name, stringsecbase, errcode); if (res != DW_DLV_OK) { gshdr->gh_namestring = namestr; return res; } gshdr->gh_namestring = stringsecbase + gshdr->gh_name; } return DW_DLV_OK; } static int elf_load_elf_header32( dwarf_elf_object_access_internals_t *ep,int *errcode) { int res = 0; dw_elf32_ehdr ehdr32; struct generic_ehdr *ehdr = 0; res = RRMOA(ep->f_fd,&ehdr32,0,sizeof(ehdr32), ep->f_filesize,errcode); if(res != DW_DLV_OK) { return res; } ehdr = (struct generic_ehdr *)calloc(1, sizeof(struct generic_ehdr)); if (!ehdr) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_ehdr_from_32(ep,ehdr,&ehdr32,errcode); return res; } static int elf_load_elf_header64( dwarf_elf_object_access_internals_t *ep,int *errcode) { int res = 0; dw_elf64_ehdr ehdr64; struct generic_ehdr *ehdr = 0; res = RRMOA(ep->f_fd,&ehdr64,0,sizeof(ehdr64), ep->f_filesize,errcode); if(res != DW_DLV_OK) { return res; } ehdr = (struct generic_ehdr *)calloc(1, sizeof(struct generic_ehdr)); if (!ehdr) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = generic_ehdr_from_64(ep,ehdr,&ehdr64,errcode); return res; } static int validate_struct_sizes( #ifdef HAVE_ELF_H int*errcode #else UNUSEDARG int*errcode #endif ) { #ifdef HAVE_ELF_H /* This is a sanity check when we have an elf.h to check against. */ if (sizeof(Elf32_Ehdr) != sizeof(dw_elf32_ehdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Ehdr) != sizeof(dw_elf64_ehdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Shdr) != sizeof(dw_elf32_shdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Shdr) != sizeof(dw_elf64_shdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Phdr) != sizeof(dw_elf32_phdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Phdr) != sizeof(dw_elf64_phdr)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Rel) != sizeof(dw_elf32_rel)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Rel) != sizeof(dw_elf64_rel)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Rela) != sizeof(dw_elf32_rela)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Rela) != sizeof(dw_elf64_rela)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf32_Sym) != sizeof(dw_elf32_sym)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } if (sizeof(Elf64_Sym) != sizeof(dw_elf64_sym)) { *errcode = DW_DLE_BAD_TYPE_SIZE; return DW_DLV_ERROR; } #endif /* HAVE_ELF_H */ return DW_DLV_OK; } int _dwarf_load_elf_header( dwarf_elf_object_access_internals_t *ep,int*errcode) { unsigned offsetsize = ep->f_offsetsize; int res = 0; res = validate_struct_sizes(errcode); if (res != DW_DLV_OK) { return res; } if (offsetsize == 32) { res = elf_load_elf_header32(ep,errcode); } else if (offsetsize == 64) { if (sizeof(Dwarf_Unsigned) < 8) { *errcode = DW_DLE_INTEGER_TOO_SMALL; return DW_DLV_ERROR; } res = elf_load_elf_header64(ep,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } return res; } static int validate_links( dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned knownsect, Dwarf_Unsigned string_sect, int *errcode) { struct generic_shdr* pshk = 0; if (!knownsect) { return DW_DLV_OK; } if (!string_sect) { *errcode = DW_DLE_ELF_STRING_SECTION_ERROR; return DW_DLV_ERROR; } pshk = ep->f_shdr + knownsect; if (string_sect != pshk->gh_link) { *errcode = DW_DLE_ELF_SECTION_LINK_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; } static int string_endswith(const char *n,const char *q) { unsigned long len = strlen(n); unsigned long qlen = strlen(q); const char *startpt = 0; if ( len < qlen) { return FALSE; } startpt = n + (len-qlen); if (strcmp(startpt,q)) { return FALSE; } return TRUE; } /* We are allowing either SHT_GROUP or .group to indicate a group section, but really one should have both or neither! */ static int elf_sht_groupsec(Dwarf_Unsigned type, const char *sname) { /* ARM compilers name SHT group "__ARM_grp" not .group */ if ((type == SHT_GROUP) || (!strcmp(sname,".group"))){ return TRUE; } return FALSE; } static int elf_flagmatches(Dwarf_Unsigned flagsword,Dwarf_Unsigned flag) { if ((flagsword&flag) == flag) { return TRUE; } return FALSE; } /* For SHT_GROUP sections. */ static int read_gs_section_group( dwarf_elf_object_access_internals_t *ep, struct generic_shdr* psh, int *errcode) { Dwarf_Unsigned i = 0; int res = 0; if (!psh->gh_sht_group_array) { Dwarf_Unsigned seclen = psh->gh_size; char *data = 0; char *dp = 0; Dwarf_Unsigned* grouparray = 0; char dblock[4]; Dwarf_Unsigned va = 0; Dwarf_Unsigned count = 0; int foundone = 0; if (seclen < DWARF_32BIT_SIZE) { *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } data = malloc(seclen); if (!data) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } dp = data; if (psh->gh_entsize != DWARF_32BIT_SIZE) { *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; free(data); return DW_DLV_ERROR; } count = seclen/psh->gh_entsize; if (count > ep->f_loc_shdr.g_count) { /* Impossible */ free(data); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } res = RRMOA(ep->f_fd,data,psh->gh_offset,seclen, ep->f_filesize,errcode); if(res != DW_DLV_OK) { free(data); return res; } grouparray = malloc(count * sizeof(Dwarf_Unsigned)); if (!grouparray) { free(data); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memcpy(dblock,dp,DWARF_32BIT_SIZE); ASNAR(memcpy,va,dblock); /* There is ambiguity on the endianness of this stuff. */ if (va != 1 && va != 0x1000000) { /* Could be corrupted elf object. */ *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; free(data); free(grouparray); return DW_DLV_ERROR; } grouparray[0] = 1; dp = dp + DWARF_32BIT_SIZE; for( i = 1; i < count; ++i,dp += DWARF_32BIT_SIZE) { Dwarf_Unsigned gseca = 0; Dwarf_Unsigned gsecb = 0; struct generic_shdr* targpsh = 0; memcpy(dblock,dp,DWARF_32BIT_SIZE); ASNAR(memcpy,gseca,dblock); ASNAR(_dwarf_memcpy_swap_bytes,gsecb,dblock); if (!gseca) { free(data); free(grouparray); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } grouparray[i] = gseca; if (gseca > ep->f_loc_shdr.g_count) { /* Might be confused endianness by the compiler generating the SHT_GROUP. This is pretty horrible. */ if (gsecb > ep->f_loc_shdr.g_count) { *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; free(data); free(grouparray); return DW_DLV_ERROR; } /* Ok. Yes, ugly. */ gseca = gsecb; grouparray[i] = gseca; } targpsh = ep->f_shdr + gseca; if (targpsh->gh_section_group_number) { /* multi-assignment to groups. Oops. */ free(data); free(grouparray); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } targpsh->gh_section_group_number = ep->f_sg_next_group_number; foundone = 1; } if (foundone) { ++ep->f_sg_next_group_number; ++ep->f_sht_group_type_section_count; } free(data); psh->gh_sht_group_array = grouparray; psh->gh_sht_group_array_count = count; } return DW_DLV_OK; } /* Does related things. A) Counts the number of SHT_GROUP and for each builds an array of the sections in the group (which we expect are all DWARF-related) and sets the group number in each mentioned section. B) Counts the number of SHF_GROUP flags. C) If gnu groups: ensure all the DWARF sections marked with right group based on A(we will mark unmarked as group 1, DW_GROUPNUMBER_BASE). D) If arm groups (SHT_GROUP zero, SHF_GROUP non-zero): Check the relocations of all SHF_GROUP section FIXME: algorithm needed. If SHT_GROUP and SHF_GROUP this is GNU groups. If no SHT_GROUP and have SHF_GROUP this is arm cc groups and we must use relocation information to identify the group members. It seems(?) impossible for an object to have both dwo sections and (SHF_GROUP or SHT_GROUP), but we do not rule that out here. */ static int _dwarf_elf_setup_all_section_groups( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr* psh = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned count = 0; int res = 0; count = ep->f_loc_shdr.g_count; psh = ep->f_shdr; /* Does step A and step B */ for (i = 0; i < count; ++psh,++i) { const char *name = psh->gh_namestring; if (is_empty_section(psh->gh_type)) { /* No data here. */ continue; } if (!elf_sht_groupsec(psh->gh_type,name)) { /* Step B */ if (elf_flagmatches(psh->gh_flags,SHF_GROUP)) { ep->f_shf_group_flag_section_count++; } continue; } /* Looks like a section group. Do Step A. */ res =read_gs_section_group(ep,psh,errcode); if (res != DW_DLV_OK) { return res; } } /* Any sections not marked above or here are in grep DW_GROUPNUMBER_BASE (1). Section C. */ psh = ep->f_shdr; for (i = 0; i < count; ++psh,++i) { const char *name = psh->gh_namestring; if (is_empty_section(psh->gh_type)) { /* No data here. */ continue; } if (elf_sht_groupsec(psh->gh_type,name)) { continue; } /* Not a section group */ if(string_endswith(name,".dwo")) { if (psh->gh_section_group_number) { /* multi-assignment to groups. Oops. */ *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; return DW_DLV_ERROR; } psh->gh_is_dwarf = TRUE; psh->gh_section_group_number = DW_GROUPNUMBER_DWO; ep->f_dwo_group_section_count++; } else if (_dwarf_load_elf_section_is_dwarf(name)) { if(!psh->gh_section_group_number) { psh->gh_section_group_number = DW_GROUPNUMBER_BASE; } psh->gh_is_dwarf = TRUE; } else { /* Do nothing. */ } } if (ep->f_sht_group_type_section_count) { /* Not ARM. Done. */ } if (!ep->f_shf_group_flag_section_count) { /* Nothing more to do. */ return DW_DLV_OK; } return DW_DLV_OK; } static int _dwarf_elf_find_sym_sections( dwarf_elf_object_access_internals_t *ep, int *errcode) { struct generic_shdr* psh = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned count = 0; int res = 0; count = ep->f_loc_shdr.g_count; psh = ep->f_shdr; for (i = 0; i < count; ++psh,++i) { const char *name = psh->gh_namestring; if (is_empty_section(psh->gh_type)) { /* No data here. */ continue; } if (!strcmp(name,".dynsym")) { ep->f_dynsym_sect_index = i; ep->f_loc_dynsym.g_offset = psh->gh_offset; } else if (!strcmp(name,".dynstr")) { ep->f_dynsym_sect_strings_sect_index = i; ep->f_dynsym_sect_strings_max = psh->gh_size; } else if (!strcmp(name,".symtab")) { ep->f_symtab_sect_index = i; ep->f_loc_symtab.g_offset = psh->gh_offset; } else if (!strcmp(name,".strtab")) { ep->f_symtab_sect_strings_sect_index = i; ep->f_symtab_sect_strings_max = psh->gh_size; } else if (!strcmp(name,".dynamic")) { ep->f_dynamic_sect_index = i; ep->f_loc_dynamic.g_offset = psh->gh_offset; } } #if 0 res = validate_links(ep,ep->f_dynsym_sect_index, ep->f_dynsym_sect_strings_sect_index,errcode); if (res!= DW_DLV_OK) { return res; } #endif /* 0 */ res = validate_links(ep,ep->f_symtab_sect_index, ep->f_symtab_sect_strings_sect_index,errcode); if (res!= DW_DLV_OK) { return res; } return DW_DLV_OK; } int _dwarf_load_elf_sectheaders( dwarf_elf_object_access_internals_t *ep,int*errcode) { int res = 0; if (ep->f_offsetsize == 32) { res = elf_load_sectheaders32(ep,ep->f_ehdr->ge_shoff, ep->f_ehdr->ge_shentsize, ep->f_ehdr->ge_shnum,errcode); } else if (ep->f_offsetsize == 64) { res = elf_load_sectheaders64(ep,ep->f_ehdr->ge_shoff, ep->f_ehdr->ge_shentsize, ep->f_ehdr->ge_shnum,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_load_sectstrings(ep, ep->f_ehdr->ge_shstrndx,errcode); if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_load_sect_namestring(ep,errcode); if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_find_sym_sections(ep,errcode); if (res != DW_DLV_OK) { return res; } res = _dwarf_elf_setup_all_section_groups(ep,errcode); return res; } dwarfutils-20200114/libdwarf/dwarf_elf_rel_detector.c000066400000000000000000000206751361531463500225740ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. cc Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #include "dwarf_elf_defines.h" #include "dwarf_elf_rel_detector.h" unsigned _dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine) { unsigned r = 0; switch (machine) { #if defined(EM_MIPS) && defined (R_MIPS_32) case EM_MIPS: r = (0 #if defined (R_MIPS_32) | (type == R_MIPS_32) #endif #if defined (R_MIPS_TLS_DTPREL32) | (type == R_MIPS_TLS_DTPREL32) #endif /* DTPREL32 */ ); break; #endif /* MIPS case */ #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32) case EM_SPARC32PLUS: r = (0 #if defined(R_SPARC_UA32) | (type == R_SPARC_UA32) #endif #if defined(R_SPARC_TLS_DTPOFF32) | (type == R_SPARC_TLS_DTPOFF32) #endif ); break; #endif #if defined(EM_SPARCV9) && defined (R_SPARC_UA32) case EM_SPARCV9: r = (type == R_SPARC_UA32); break; #endif #if defined(EM_SPARC) && defined (R_SPARC_UA32) case EM_SPARC: r = (0 #if defined(R_SPARC_UA32) | (type == R_SPARC_UA32) #endif #if (R_SPARC_TLS_DTPOFF32) | (type == R_SPARC_TLS_DTPOFF32) #endif ); break; #endif /* EM_SPARC */ #if defined(EM_386) && defined (R_386_32) case EM_386: r = (0 #if defined (R_386_32) | (type == R_386_32) #endif #if defined (R_386_TLS_LDO_32) | (type == R_386_TLS_LDO_32) #endif #if defined (R_386_TLS_DTPOFF32) | (type == R_386_TLS_DTPOFF32) #endif ); break; #endif /* EM_386 */ #if defined (EM_SH) && defined (R_SH_DIR32) case EM_SH: r = (0 #if defined (R_SH_DIR32) | (type == R_SH_DIR32) #endif #if defined (R_SH_DTPOFF32) | (type == R_SH_TLS_DTPOFF32) #endif ); break; #endif /* SH */ #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB) case EM_IA_64: /* 32bit? ! */ r = (0 #if defined (R_IA64_SECREL32LSB) | (type == R_IA64_SECREL32LSB) #endif #if defined (R_IA64_DIR32LSB) | (type == R_IA64_DIR32LSB) #endif #if defined (R_IA64_DTPREL32LSB) | (type == R_IA64_DTPREL32LSB) #endif ); break; #endif /* EM_IA_64 */ #if defined(EM_ARM) && defined (R_ARM_ABS32) case EM_ARM: case EM_AARCH64: r = (0 #if defined (R_ARM_ABS32) | ( type == R_ARM_ABS32) #endif #if defined (R_AARCH64_ABS32) | ( type == R_AARCH64_ABS32) #endif #if defined (R_ARM_TLS_LDO32) | ( type == R_ARM_TLS_LDO32) #endif ); break; #endif /* EM_ARM */ /* On FreeBSD xR_PPC64_ADDR32 not defined so we use the xR_PPC_ names which have the proper value. Our headers have: xR_PPC64_ADDR64 38 xR_PPC_ADDR32 1 so we use this one xR_PPC64_ADDR32 R_PPC_ADDR32 xR_PPC64_DTPREL32 110 which may be wrong/unavailable xR_PPC64_DTPREL64 78 xR_PPC_DTPREL32 78 */ #if defined(EM_PPC64) && defined (R_PPC_ADDR32) case EM_PPC64: r = (0 #if defined(R_PPC_ADDR32) | (type == R_PPC_ADDR32) #endif #if defined(R_PPC64_DTPREL32) | (type == R_PPC64_DTPREL32) #endif ); break; #endif /* EM_PPC64 */ #if defined(EM_PPC) && defined (R_PPC_ADDR32) case EM_PPC: r = (0 #if defined (R_PPC_ADDR32) | (type == R_PPC_ADDR32) #endif #if defined (R_PPC_DTPREL32) | (type == R_PPC_DTPREL32) #endif ); break; #endif /* EM_PPC */ #if defined(EM_S390) && defined (R_390_32) case EM_S390: r = (0 #if defined (R_390_32) | (type == R_390_32) #endif #if defined (R_390_TLS_LDO32) | (type == R_390_TLS_LDO32) #endif ); break; #endif /* EM_S390 */ #if defined(EM_X86_64) && ( defined(R_X86_64_32) || defined(R_X86_64_PC32) || defined(R_X86_64_DTPOFF32) ) #if defined(EM_K10M) case EM_K10M: #endif #if defined(EM_L10M) case EM_L10M: #endif case EM_X86_64: r = (0 #if defined (R_X86_64_PC32) | (type == R_X86_64_PC32) #endif #if defined (R_X86_64_32) | (type == R_X86_64_32) #endif #if defined (R_X86_64_DTPOFF32) | (type == R_X86_64_DTPOFF32) #endif ); break; #endif /* EM_X86_64 */ case EM_QUALCOMM_DSP6: r = (type == R_QUALCOMM_REL32); break; } return r; } unsigned _dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine) { unsigned r = 0; switch (machine) { #if defined(EM_MIPS) && defined (R_MIPS_64) case EM_MIPS: r = (0 #if defined (R_MIPS_64) | (type == R_MIPS_64) #endif #if defined (R_MIPS_32) | (type == R_MIPS_32) #endif #if defined(R_MIPS_TLS_DTPREL64) | (type == R_MIPS_TLS_DTPREL64) #endif ); break; #endif /* EM_MIPS */ #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64) case EM_SPARC32PLUS: r = (type == R_SPARC_UA64); break; #endif #if defined(EM_SPARCV9) && defined (R_SPARC_UA64) case EM_SPARCV9: r = (0 #if defined (R_SPARC_UA64) | (type == R_SPARC_UA64) #endif #if defined (R_SPARC_TLS_DTPOFF64) | (type == R_SPARC_TLS_DTPOFF64) #endif ); break; #endif #if defined(EM_SPARC) && defined (R_SPARC_UA64) case EM_SPARC: r = (0 #if defined(R_SPARC_UA64) | (type == R_SPARC_UA64) #endif #if defined (R_SPARC_TLS_DTPOFF64) | (type == R_SPARC_TLS_DTPOFF64) #endif ); break; #endif /* EM_SPARC */ #if defined(EM_IA_64) && defined (R_IA64_SECREL64LSB) case EM_IA_64: /* 64bit */ r = (0 #if defined (R_IA64_SECREL64LSB) | (type == R_IA64_SECREL64LSB) #endif #if defined (R_IA64_SECREL32LSB) | (type == R_IA64_SECREL32LSB) #endif #if defined (R_IA64_DIR64LSB) | (type == R_IA64_DIR64LSB) #endif #if defined (R_IA64_DTPREL64LSB) | (type == R_IA64_DTPREL64LSB) #endif #if defined (R_IA64_REL32LSB) | (type == R_IA64_REL32LSB) #endif ); break; #endif /* EM_IA_64 */ #if defined(EM_PPC64) && defined (R_PPC64_ADDR64) case EM_PPC64: r = (0 #if defined(R_PPC64_ADDR64) | (type == R_PPC64_ADDR64) #endif #if defined(R_PPC64_DTPREL64) | (type == R_PPC64_DTPREL64) #endif ); break; #endif /* EM_PPC64 */ #if defined(EM_S390) && defined (R_390_64) case EM_S390: r = (0 #if defined(R_390_64) | (type == R_390_64) #endif #if defined(R_390_TLS_LDO64) | (type == R_390_TLS_LDO64) #endif ); break; #endif /* EM_390 */ #if defined(EM_X86_64) && defined (R_X86_64_64) #if defined(EM_K10M) case EM_K10M: #endif #if defined(EM_L10M) case EM_L10M: #endif case EM_X86_64: r = (0 #if defined (R_X86_64_64) | (type == R_X86_64_64) #endif #if defined (R_X86_64_DTPOFF32) | (type == R_X86_64_DTPOFF64) #endif ); break; #endif /* EM_X86_64 */ #if defined(EM_AARCH64) && defined (R_AARCH64_ABS64) case EM_AARCH64: r = (0 #if defined (R_AARCH64_ABS64) | ( type == R_AARCH64_ABS64) #endif ); break; #endif /* EM_AARCH64 */ } return r; } dwarfutils-20200114/libdwarf/dwarf_elf_rel_detector.h000066400000000000000000000032201361531463500225640ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_ELF_REL_DETECTOR_H #define DWARF_ELF_REL_DETECTOR_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ unsigned _dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine); unsigned _dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_ELF_REL_DETECTOR_H */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_386.h000066400000000000000000000065361361531463500216320ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_386(unsigned long); #ifndef R_386_NONE #define R_386_NONE 0 #endif /* R_386_NONE */ #ifndef R_386_32 #define R_386_32 1 #endif /* R_386_32 */ #ifndef R_386_PC32 #define R_386_PC32 2 #endif /* R_386_PC32 */ #ifndef R_386_GOT32 #define R_386_GOT32 3 #endif /* R_386_GOT32 */ #ifndef R_386_PLT32 #define R_386_PLT32 4 #endif /* R_386_PLT32 */ #ifndef R_386_COPY #define R_386_COPY 5 #endif /* R_386_COPY */ #ifndef R_386_GLOB_DAT #define R_386_GLOB_DAT 6 #endif /* R_386_GLOB_DAT */ #ifndef R_386_JMP_SLOT #define R_386_JMP_SLOT 7 #endif /* R_386_JMP_SLOT */ #ifndef R_386_RELATIVE #define R_386_RELATIVE 8 #endif /* R_386_RELATIVE */ #ifndef R_386_GOTOFF #define R_386_GOTOFF 9 #endif /* R_386_GOTOFF */ #ifndef R_386_GOTPC #define R_386_GOTPC 10 #endif /* R_386_GOTPC */ #ifndef R_386_32PLT #define R_386_32PLT 11 #endif /* R_386_32PLT */ #ifndef R_386_TLS_TPOFF #define R_386_TLS_TPOFF 14 #endif /* R_386_TLS_TPOFF */ #ifndef R_386_TLS_IE #define R_386_TLS_IE 15 #endif /* R_386_TLS_IE */ #ifndef R_386_TLS_GOTIE #define R_386_TLS_GOTIE 16 #endif /* R_386_TLS_GOTIE */ #ifndef R_386_TLS_LE #define R_386_TLS_LE 17 #endif /* R_386_TLS_LE */ #ifndef R_386_TLS_LDM #define R_386_TLS_LDM 19 #endif /* R_386_TLS_LDM */ #ifndef R_386_16 #define R_386_16 20 #endif /* R_386_16 */ #ifndef R_386_PC16 #define R_386_PC16 21 #endif /* R_386_PC16 */ #ifndef R_386_8 #define R_386_8 22 #endif /* R_386_8 */ #ifndef R_386_PC8 #define R_386_PC8 23 #endif /* R_386_PC8 */ #ifndef R_386_TLS_GD_32 #define R_386_TLS_GD_32 24 #endif /* R_386_TLS_GD_32 */ #ifndef R_386_TLS_GD_PUSH #define R_386_TLS_GD_PUSH 25 #endif /* R_386_TLS_GD_PUSH */ #ifndef R_386_TLS_GD_CALL #define R_386_TLS_GD_CALL 26 #endif /* R_386_TLS_GD_CALL */ #ifndef R_386_TLS_GD_POP #define R_386_TLS_GD_POP 27 #endif /* R_386_TLS_GD_POP */ #ifndef R_386_TLS_LDM_32 #define R_386_TLS_LDM_32 28 #endif /* R_386_TLS_LDM_32 */ #ifndef R_386_TLS_LDM_PUSH #define R_386_TLS_LDM_PUSH 29 #endif /* R_386_TLS_LDM_PUSH */ #ifndef R_386_TLS_LDM_CALL #define R_386_TLS_LDM_CALL 30 #endif /* R_386_TLS_LDM_CALL */ #ifndef R_386_TLS_LDM_POP #define R_386_TLS_LDM_POP 31 #endif /* R_386_TLS_LDM_POP */ #ifndef R_386_TLS_LDO_32 #define R_386_TLS_LDO_32 32 #endif /* R_386_TLS_LDO_32 */ #ifndef R_386_TLS_IE_32 #define R_386_TLS_IE_32 33 #endif /* R_386_TLS_IE_32 */ #ifndef R_386_TLS_LE_32 #define R_386_TLS_LE_32 34 #endif /* R_386_TLS_LE_32 */ #ifndef R_386_TLS_DTPMOD32 #define R_386_TLS_DTPMOD32 35 #endif /* R_386_TLS_DTPMOD32 */ #ifndef R_386_TLS_DTPOFF32 #define R_386_TLS_DTPOFF32 36 #endif /* R_386_TLS_DTPOFF32 */ #ifndef R_386_TLS_TPOFF32 #define R_386_TLS_TPOFF32 37 #endif /* R_386_TLS_TPOFF32 */ #ifndef R_386_SIZE32 #define R_386_SIZE32 38 #endif /* R_386_SIZE32 */ #ifndef R_386_TLS_GOTDESC #define R_386_TLS_GOTDESC 39 #endif /* R_386_TLS_GOTDESC */ #ifndef R_386_TLS_DESC_CALL #define R_386_TLS_DESC_CALL 40 #endif /* R_386_TLS_DESC_CALL */ #ifndef R_386_TLS_DESC #define R_386_TLS_DESC 41 #endif /* R_386_TLS_DESC */ #ifndef R_386_IRELATIVE #define R_386_IRELATIVE 42 #endif /* R_386_IRELATIVE */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_aarch64.h000066400000000000000000000360001361531463500225270ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_aarch64(unsigned long); #ifndef R_AARCH64_NONE #define R_AARCH64_NONE 0 #endif /* R_AARCH64_NONE */ #ifndef R_AARCH64_P32_ABS32 #define R_AARCH64_P32_ABS32 1 #endif /* R_AARCH64_P32_ABS32 */ #ifndef R_AARCH64_P32_COPY #define R_AARCH64_P32_COPY 180 #endif /* R_AARCH64_P32_COPY */ #ifndef R_AARCH64_P32_GLOB_DAT #define R_AARCH64_P32_GLOB_DAT 181 #endif /* R_AARCH64_P32_GLOB_DAT */ #ifndef R_AARCH64_P32_JUMP_SLOT #define R_AARCH64_P32_JUMP_SLOT 182 #endif /* R_AARCH64_P32_JUMP_SLOT */ #ifndef R_AARCH64_P32_RELATIVE #define R_AARCH64_P32_RELATIVE 183 #endif /* R_AARCH64_P32_RELATIVE */ #ifndef R_AARCH64_P32_TLS_DTPMOD #define R_AARCH64_P32_TLS_DTPMOD 184 #endif /* R_AARCH64_P32_TLS_DTPMOD */ #ifndef R_AARCH64_P32_TLS_DTPREL #define R_AARCH64_P32_TLS_DTPREL 185 #endif /* R_AARCH64_P32_TLS_DTPREL */ #ifndef R_AARCH64_P32_TLS_TPREL #define R_AARCH64_P32_TLS_TPREL 186 #endif /* R_AARCH64_P32_TLS_TPREL */ #ifndef R_AARCH64_P32_TLSDESC #define R_AARCH64_P32_TLSDESC 187 #endif /* R_AARCH64_P32_TLSDESC */ #ifndef R_AARCH64_P32_IRELATIVE #define R_AARCH64_P32_IRELATIVE 188 #endif /* R_AARCH64_P32_IRELATIVE */ #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 257 #endif /* R_AARCH64_ABS64 */ #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 258 #endif /* R_AARCH64_ABS32 */ #ifndef R_AARCH64_ABS16 #define R_AARCH64_ABS16 259 #endif /* R_AARCH64_ABS16 */ #ifndef R_AARCH64_PREL64 #define R_AARCH64_PREL64 260 #endif /* R_AARCH64_PREL64 */ #ifndef R_AARCH64_PREL32 #define R_AARCH64_PREL32 261 #endif /* R_AARCH64_PREL32 */ #ifndef R_AARCH64_PREL16 #define R_AARCH64_PREL16 262 #endif /* R_AARCH64_PREL16 */ #ifndef R_AARCH64_MOVW_UABS_G0 #define R_AARCH64_MOVW_UABS_G0 263 #endif /* R_AARCH64_MOVW_UABS_G0 */ #ifndef R_AARCH64_MOVW_UABS_G0_NC #define R_AARCH64_MOVW_UABS_G0_NC 264 #endif /* R_AARCH64_MOVW_UABS_G0_NC */ #ifndef R_AARCH64_MOVW_UABS_G1 #define R_AARCH64_MOVW_UABS_G1 265 #endif /* R_AARCH64_MOVW_UABS_G1 */ #ifndef R_AARCH64_MOVW_UABS_G1_NC #define R_AARCH64_MOVW_UABS_G1_NC 266 #endif /* R_AARCH64_MOVW_UABS_G1_NC */ #ifndef R_AARCH64_MOVW_UABS_G2 #define R_AARCH64_MOVW_UABS_G2 267 #endif /* R_AARCH64_MOVW_UABS_G2 */ #ifndef R_AARCH64_MOVW_UABS_G2_NC #define R_AARCH64_MOVW_UABS_G2_NC 268 #endif /* R_AARCH64_MOVW_UABS_G2_NC */ #ifndef R_AARCH64_MOVW_UABS_G3 #define R_AARCH64_MOVW_UABS_G3 269 #endif /* R_AARCH64_MOVW_UABS_G3 */ #ifndef R_AARCH64_MOVW_SABS_G0 #define R_AARCH64_MOVW_SABS_G0 270 #endif /* R_AARCH64_MOVW_SABS_G0 */ #ifndef R_AARCH64_MOVW_SABS_G1 #define R_AARCH64_MOVW_SABS_G1 271 #endif /* R_AARCH64_MOVW_SABS_G1 */ #ifndef R_AARCH64_MOVW_SABS_G2 #define R_AARCH64_MOVW_SABS_G2 272 #endif /* R_AARCH64_MOVW_SABS_G2 */ #ifndef R_AARCH64_LD_PREL_LO19 #define R_AARCH64_LD_PREL_LO19 273 #endif /* R_AARCH64_LD_PREL_LO19 */ #ifndef R_AARCH64_ADR_PREL_LO21 #define R_AARCH64_ADR_PREL_LO21 274 #endif /* R_AARCH64_ADR_PREL_LO21 */ #ifndef R_AARCH64_ADR_PREL_PG_HI21 #define R_AARCH64_ADR_PREL_PG_HI21 275 #endif /* R_AARCH64_ADR_PREL_PG_HI21 */ #ifndef R_AARCH64_ADR_PREL_PG_HI21_NC #define R_AARCH64_ADR_PREL_PG_HI21_NC 276 #endif /* R_AARCH64_ADR_PREL_PG_HI21_NC */ #ifndef R_AARCH64_ADD_ABS_LO12_NC #define R_AARCH64_ADD_ABS_LO12_NC 277 #endif /* R_AARCH64_ADD_ABS_LO12_NC */ #ifndef R_AARCH64_LDST8_ABS_LO12_NC #define R_AARCH64_LDST8_ABS_LO12_NC 278 #endif /* R_AARCH64_LDST8_ABS_LO12_NC */ #ifndef R_AARCH64_TSTBR14 #define R_AARCH64_TSTBR14 279 #endif /* R_AARCH64_TSTBR14 */ #ifndef R_AARCH64_CONDBR19 #define R_AARCH64_CONDBR19 280 #endif /* R_AARCH64_CONDBR19 */ #ifndef R_AARCH64_JUMP26 #define R_AARCH64_JUMP26 282 #endif /* R_AARCH64_JUMP26 */ #ifndef R_AARCH64_CALL26 #define R_AARCH64_CALL26 283 #endif /* R_AARCH64_CALL26 */ #ifndef R_AARCH64_LDST16_ABS_LO12_NC #define R_AARCH64_LDST16_ABS_LO12_NC 284 #endif /* R_AARCH64_LDST16_ABS_LO12_NC */ #ifndef R_AARCH64_LDST32_ABS_LO12_NC #define R_AARCH64_LDST32_ABS_LO12_NC 285 #endif /* R_AARCH64_LDST32_ABS_LO12_NC */ #ifndef R_AARCH64_LDST64_ABS_LO12_NC #define R_AARCH64_LDST64_ABS_LO12_NC 286 #endif /* R_AARCH64_LDST64_ABS_LO12_NC */ #ifndef R_AARCH64_MOVW_PREL_G0 #define R_AARCH64_MOVW_PREL_G0 287 #endif /* R_AARCH64_MOVW_PREL_G0 */ #ifndef R_AARCH64_MOVW_PREL_G0_NC #define R_AARCH64_MOVW_PREL_G0_NC 288 #endif /* R_AARCH64_MOVW_PREL_G0_NC */ #ifndef R_AARCH64_MOVW_PREL_G1 #define R_AARCH64_MOVW_PREL_G1 289 #endif /* R_AARCH64_MOVW_PREL_G1 */ #ifndef R_AARCH64_MOVW_PREL_G1_NC #define R_AARCH64_MOVW_PREL_G1_NC 290 #endif /* R_AARCH64_MOVW_PREL_G1_NC */ #ifndef R_AARCH64_MOVW_PREL_G2 #define R_AARCH64_MOVW_PREL_G2 291 #endif /* R_AARCH64_MOVW_PREL_G2 */ #ifndef R_AARCH64_MOVW_PREL_G2_NC #define R_AARCH64_MOVW_PREL_G2_NC 292 #endif /* R_AARCH64_MOVW_PREL_G2_NC */ #ifndef R_AARCH64_MOVW_PREL_G3 #define R_AARCH64_MOVW_PREL_G3 293 #endif /* R_AARCH64_MOVW_PREL_G3 */ #ifndef R_AARCH64_LDST128_ABS_LO12_NC #define R_AARCH64_LDST128_ABS_LO12_NC 299 #endif /* R_AARCH64_LDST128_ABS_LO12_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G0 #define R_AARCH64_MOVW_GOTOFF_G0 300 #endif /* R_AARCH64_MOVW_GOTOFF_G0 */ #ifndef R_AARCH64_MOVW_GOTOFF_G0_NC #define R_AARCH64_MOVW_GOTOFF_G0_NC 301 #endif /* R_AARCH64_MOVW_GOTOFF_G0_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G1 #define R_AARCH64_MOVW_GOTOFF_G1 302 #endif /* R_AARCH64_MOVW_GOTOFF_G1 */ #ifndef R_AARCH64_MOVW_GOTOFF_G1_NC #define R_AARCH64_MOVW_GOTOFF_G1_NC 303 #endif /* R_AARCH64_MOVW_GOTOFF_G1_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G2 #define R_AARCH64_MOVW_GOTOFF_G2 304 #endif /* R_AARCH64_MOVW_GOTOFF_G2 */ #ifndef R_AARCH64_MOVW_GOTOFF_G2_NC #define R_AARCH64_MOVW_GOTOFF_G2_NC 305 #endif /* R_AARCH64_MOVW_GOTOFF_G2_NC */ #ifndef R_AARCH64_MOVW_GOTOFF_G3 #define R_AARCH64_MOVW_GOTOFF_G3 306 #endif /* R_AARCH64_MOVW_GOTOFF_G3 */ #ifndef R_AARCH64_GOTREL64 #define R_AARCH64_GOTREL64 307 #endif /* R_AARCH64_GOTREL64 */ #ifndef R_AARCH64_GOTREL32 #define R_AARCH64_GOTREL32 308 #endif /* R_AARCH64_GOTREL32 */ #ifndef R_AARCH64_GOT_LD_PREL19 #define R_AARCH64_GOT_LD_PREL19 309 #endif /* R_AARCH64_GOT_LD_PREL19 */ #ifndef R_AARCH64_LD64_GOTOFF_LO15 #define R_AARCH64_LD64_GOTOFF_LO15 310 #endif /* R_AARCH64_LD64_GOTOFF_LO15 */ #ifndef R_AARCH64_ADR_GOT_PAGE #define R_AARCH64_ADR_GOT_PAGE 311 #endif /* R_AARCH64_ADR_GOT_PAGE */ #ifndef R_AARCH64_LD64_GOT_LO12_NC #define R_AARCH64_LD64_GOT_LO12_NC 312 #endif /* R_AARCH64_LD64_GOT_LO12_NC */ #ifndef R_AARCH64_LD64_GOTPAGE_LO15 #define R_AARCH64_LD64_GOTPAGE_LO15 313 #endif /* R_AARCH64_LD64_GOTPAGE_LO15 */ #ifndef R_AARCH64_TLSGD_ADR_PREL21 #define R_AARCH64_TLSGD_ADR_PREL21 512 #endif /* R_AARCH64_TLSGD_ADR_PREL21 */ #ifndef R_AARCH64_TLSGD_ADR_PAGE21 #define R_AARCH64_TLSGD_ADR_PAGE21 513 #endif /* R_AARCH64_TLSGD_ADR_PAGE21 */ #ifndef R_AARCH64_TLSGD_ADD_LO12_NC #define R_AARCH64_TLSGD_ADD_LO12_NC 514 #endif /* R_AARCH64_TLSGD_ADD_LO12_NC */ #ifndef R_AARCH64_TLSGD_MOVW_G1 #define R_AARCH64_TLSGD_MOVW_G1 515 #endif /* R_AARCH64_TLSGD_MOVW_G1 */ #ifndef R_AARCH64_TLSGD_MOVW_G0_NC #define R_AARCH64_TLSGD_MOVW_G0_NC 516 #endif /* R_AARCH64_TLSGD_MOVW_G0_NC */ #ifndef R_AARCH64_TLSLD_ADR_PREL21 #define R_AARCH64_TLSLD_ADR_PREL21 517 #endif /* R_AARCH64_TLSLD_ADR_PREL21 */ #ifndef R_AARCH64_TLSLD_ADR_PAGE21 #define R_AARCH64_TLSLD_ADR_PAGE21 518 #endif /* R_AARCH64_TLSLD_ADR_PAGE21 */ #ifndef R_AARCH64_TLSLD_ADD_LO12_NC #define R_AARCH64_TLSLD_ADD_LO12_NC 519 #endif /* R_AARCH64_TLSLD_ADD_LO12_NC */ #ifndef R_AARCH64_TLSLD_MOVW_G1 #define R_AARCH64_TLSLD_MOVW_G1 520 #endif /* R_AARCH64_TLSLD_MOVW_G1 */ #ifndef R_AARCH64_TLSLD_MOVW_G0_NC #define R_AARCH64_TLSLD_MOVW_G0_NC 521 #endif /* R_AARCH64_TLSLD_MOVW_G0_NC */ #ifndef R_AARCH64_TLSLD_LD_PREL19 #define R_AARCH64_TLSLD_LD_PREL19 522 #endif /* R_AARCH64_TLSLD_LD_PREL19 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G2 #define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G2 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G1 #define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G1 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC #define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G0 #define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G0 */ #ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC #define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 #endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC */ #ifndef R_AARCH64_TLSLD_ADD_DTPREL_HI12 #define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 #endif /* R_AARCH64_TLSLD_ADD_DTPREL_HI12 */ #ifndef R_AARCH64_TLSLD_ADD_DTPREL_LO12 #define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 #endif /* R_AARCH64_TLSLD_ADD_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC #define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 #endif /* R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST8_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 #endif /* R_AARCH64_TLSLD_LDST8_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 #endif /* R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST16_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 #endif /* R_AARCH64_TLSLD_LDST16_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 #endif /* R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST32_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 #endif /* R_AARCH64_TLSLD_LDST32_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 #endif /* R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST64_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 #endif /* R_AARCH64_TLSLD_LDST64_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 #endif /* R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC */ #ifndef R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 #define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 #endif /* R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 */ #ifndef R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC #define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 #endif /* R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC */ #ifndef R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 #define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 #endif /* R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 */ #ifndef R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC #define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 #endif /* R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC */ #ifndef R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 #define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 #endif /* R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G2 #define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G2 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G1 #define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G1 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G1_NC #define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G1_NC */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G0 #define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G0 */ #ifndef R_AARCH64_TLSLE_MOVW_TPREL_G0_NC #define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 #endif /* R_AARCH64_TLSLE_MOVW_TPREL_G0_NC */ #ifndef R_AARCH64_TLSLE_ADD_TPREL_HI12 #define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 #endif /* R_AARCH64_TLSLE_ADD_TPREL_HI12 */ #ifndef R_AARCH64_TLSLE_ADD_TPREL_LO12 #define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 #endif /* R_AARCH64_TLSLE_ADD_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_ADD_TPREL_LO12_NC #define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 #endif /* R_AARCH64_TLSLE_ADD_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST8_TPREL_LO12 #define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 #endif /* R_AARCH64_TLSLE_LDST8_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 #endif /* R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST16_TPREL_LO12 #define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 #endif /* R_AARCH64_TLSLE_LDST16_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 #endif /* R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST32_TPREL_LO12 #define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 #endif /* R_AARCH64_TLSLE_LDST32_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 #endif /* R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLE_LDST64_TPREL_LO12 #define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 #endif /* R_AARCH64_TLSLE_LDST64_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 #endif /* R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSDESC_LD_PREL19 #define R_AARCH64_TLSDESC_LD_PREL19 560 #endif /* R_AARCH64_TLSDESC_LD_PREL19 */ #ifndef R_AARCH64_TLSDESC_ADR_PREL21 #define R_AARCH64_TLSDESC_ADR_PREL21 561 #endif /* R_AARCH64_TLSDESC_ADR_PREL21 */ #ifndef R_AARCH64_TLSDESC_ADR_PAGE21 #define R_AARCH64_TLSDESC_ADR_PAGE21 562 #endif /* R_AARCH64_TLSDESC_ADR_PAGE21 */ #ifndef R_AARCH64_TLSDESC_LD64_LO12 #define R_AARCH64_TLSDESC_LD64_LO12 563 #endif /* R_AARCH64_TLSDESC_LD64_LO12 */ #ifndef R_AARCH64_TLSDESC_ADD_LO12 #define R_AARCH64_TLSDESC_ADD_LO12 564 #endif /* R_AARCH64_TLSDESC_ADD_LO12 */ #ifndef R_AARCH64_TLSDESC_OFF_G1 #define R_AARCH64_TLSDESC_OFF_G1 565 #endif /* R_AARCH64_TLSDESC_OFF_G1 */ #ifndef R_AARCH64_TLSDESC_OFF_G0_NC #define R_AARCH64_TLSDESC_OFF_G0_NC 566 #endif /* R_AARCH64_TLSDESC_OFF_G0_NC */ #ifndef R_AARCH64_TLSDESC_LDR #define R_AARCH64_TLSDESC_LDR 567 #endif /* R_AARCH64_TLSDESC_LDR */ #ifndef R_AARCH64_TLSDESC_ADD #define R_AARCH64_TLSDESC_ADD 568 #endif /* R_AARCH64_TLSDESC_ADD */ #ifndef R_AARCH64_TLSDESC_CALL #define R_AARCH64_TLSDESC_CALL 569 #endif /* R_AARCH64_TLSDESC_CALL */ #ifndef R_AARCH64_TLSLE_LDST128_TPREL_LO12 #define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 #endif /* R_AARCH64_TLSLE_LDST128_TPREL_LO12 */ #ifndef R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC #define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 #endif /* R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC */ #ifndef R_AARCH64_TLSLD_LDST128_DTPREL_LO12 #define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 #endif /* R_AARCH64_TLSLD_LDST128_DTPREL_LO12 */ #ifndef R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC #define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 #endif /* R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC */ #ifndef R_AARCH64_COPY #define R_AARCH64_COPY 1024 #endif /* R_AARCH64_COPY */ #ifndef R_AARCH64_GLOB_DAT #define R_AARCH64_GLOB_DAT 1025 #endif /* R_AARCH64_GLOB_DAT */ #ifndef R_AARCH64_JUMP_SLOT #define R_AARCH64_JUMP_SLOT 1026 #endif /* R_AARCH64_JUMP_SLOT */ #ifndef R_AARCH64_RELATIVE #define R_AARCH64_RELATIVE 1027 #endif /* R_AARCH64_RELATIVE */ #ifndef R_AARCH64_TLS_DTPMOD #define R_AARCH64_TLS_DTPMOD 1028 #endif /* R_AARCH64_TLS_DTPMOD */ #ifndef R_AARCH64_TLS_DTPREL #define R_AARCH64_TLS_DTPREL 1029 #endif /* R_AARCH64_TLS_DTPREL */ #ifndef R_AARCH64_TLS_TPREL #define R_AARCH64_TLS_TPREL 1030 #endif /* R_AARCH64_TLS_TPREL */ #ifndef R_AARCH64_TLSDESC #define R_AARCH64_TLSDESC 1031 #endif /* R_AARCH64_TLSDESC */ #ifndef R_AARCH64_IRELATIVE #define R_AARCH64_IRELATIVE 1032 #endif /* R_AARCH64_IRELATIVE */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_arm.h000066400000000000000000000251721361531463500220660ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_arm(unsigned long); #ifndef R_ARM_NONE #define R_ARM_NONE 0 #endif /* R_ARM_NONE */ #ifndef R_ARM_PC24 #define R_ARM_PC24 1 #endif /* R_ARM_PC24 */ #ifndef R_ARM_ABS32 #define R_ARM_ABS32 2 #endif /* R_ARM_ABS32 */ #ifndef R_ARM_REL32 #define R_ARM_REL32 3 #endif /* R_ARM_REL32 */ #ifndef R_ARM_LDR_PC_G0 #define R_ARM_LDR_PC_G0 4 #endif /* R_ARM_LDR_PC_G0 */ #ifndef R_ARM_ABS16 #define R_ARM_ABS16 5 #endif /* R_ARM_ABS16 */ #ifndef R_ARM_ABS12 #define R_ARM_ABS12 6 #endif /* R_ARM_ABS12 */ #ifndef R_ARM_THM_ABS5 #define R_ARM_THM_ABS5 7 #endif /* R_ARM_THM_ABS5 */ #ifndef R_ARM_ABS8 #define R_ARM_ABS8 8 #endif /* R_ARM_ABS8 */ #ifndef R_ARM_SBREL32 #define R_ARM_SBREL32 9 #endif /* R_ARM_SBREL32 */ #ifndef R_ARM_THM_CALL #define R_ARM_THM_CALL 10 #endif /* R_ARM_THM_CALL */ #ifndef R_ARM_THM_PC8 #define R_ARM_THM_PC8 11 #endif /* R_ARM_THM_PC8 */ #ifndef R_ARM_BREL_ADJ #define R_ARM_BREL_ADJ 12 #endif /* R_ARM_BREL_ADJ */ #ifndef R_ARM_TLS_DESC #define R_ARM_TLS_DESC 13 #endif /* R_ARM_TLS_DESC */ #ifndef R_ARM_THM_SWI8 #define R_ARM_THM_SWI8 14 #endif /* R_ARM_THM_SWI8 */ #ifndef R_ARM_XPC25 #define R_ARM_XPC25 15 #endif /* R_ARM_XPC25 */ #ifndef R_ARM_THM_XPC22 #define R_ARM_THM_XPC22 16 #endif /* R_ARM_THM_XPC22 */ #ifndef R_ARM_TLS_DTPMOD32 #define R_ARM_TLS_DTPMOD32 17 #endif /* R_ARM_TLS_DTPMOD32 */ #ifndef R_ARM_TLS_DTPOFF32 #define R_ARM_TLS_DTPOFF32 18 #endif /* R_ARM_TLS_DTPOFF32 */ #ifndef R_ARM_TLS_TPOFF32 #define R_ARM_TLS_TPOFF32 19 #endif /* R_ARM_TLS_TPOFF32 */ #ifndef R_ARM_COPY #define R_ARM_COPY 20 #endif /* R_ARM_COPY */ #ifndef R_ARM_GLOB_DAT #define R_ARM_GLOB_DAT 21 #endif /* R_ARM_GLOB_DAT */ #ifndef R_ARM_JUMP_SLOT #define R_ARM_JUMP_SLOT 22 #endif /* R_ARM_JUMP_SLOT */ #ifndef R_ARM_RELATIVE #define R_ARM_RELATIVE 23 #endif /* R_ARM_RELATIVE */ #ifndef R_ARM_GOTOFF32 #define R_ARM_GOTOFF32 24 #endif /* R_ARM_GOTOFF32 */ #ifndef R_ARM_BASE_PREL #define R_ARM_BASE_PREL 25 #endif /* R_ARM_BASE_PREL */ #ifndef R_ARM_GOT_BREL #define R_ARM_GOT_BREL 26 #endif /* R_ARM_GOT_BREL */ #ifndef R_ARM_PLT32 #define R_ARM_PLT32 27 #endif /* R_ARM_PLT32 */ #ifndef R_ARM_CALL #define R_ARM_CALL 28 #endif /* R_ARM_CALL */ #ifndef R_ARM_JUMP24 #define R_ARM_JUMP24 29 #endif /* R_ARM_JUMP24 */ #ifndef R_ARM_THM_JUMP24 #define R_ARM_THM_JUMP24 30 #endif /* R_ARM_THM_JUMP24 */ #ifndef R_ARM_BASE_ABS #define R_ARM_BASE_ABS 31 #endif /* R_ARM_BASE_ABS */ #ifndef R_ARM_ALU_PCREL_7_0 #define R_ARM_ALU_PCREL_7_0 32 #endif /* R_ARM_ALU_PCREL_7_0 */ #ifndef R_ARM_ALU_PCREL_15_8 #define R_ARM_ALU_PCREL_15_8 33 #endif /* R_ARM_ALU_PCREL_15_8 */ #ifndef R_ARM_ALU_PCREL_23_15 #define R_ARM_ALU_PCREL_23_15 34 #endif /* R_ARM_ALU_PCREL_23_15 */ #ifndef R_ARM_LDR_SBREL_11_0_NC #define R_ARM_LDR_SBREL_11_0_NC 35 #endif /* R_ARM_LDR_SBREL_11_0_NC */ #ifndef R_ARM_ALU_SBREL_19_12_NC #define R_ARM_ALU_SBREL_19_12_NC 36 #endif /* R_ARM_ALU_SBREL_19_12_NC */ #ifndef R_ARM_ALU_SBREL_27_20_CK #define R_ARM_ALU_SBREL_27_20_CK 37 #endif /* R_ARM_ALU_SBREL_27_20_CK */ #ifndef R_ARM_TARGET1 #define R_ARM_TARGET1 38 #endif /* R_ARM_TARGET1 */ #ifndef R_ARM_SBREL31 #define R_ARM_SBREL31 39 #endif /* R_ARM_SBREL31 */ #ifndef R_ARM_V4BX #define R_ARM_V4BX 40 #endif /* R_ARM_V4BX */ #ifndef R_ARM_TARGET2 #define R_ARM_TARGET2 41 #endif /* R_ARM_TARGET2 */ #ifndef R_ARM_PREL31 #define R_ARM_PREL31 42 #endif /* R_ARM_PREL31 */ #ifndef R_ARM_MOVW_ABS_NC #define R_ARM_MOVW_ABS_NC 43 #endif /* R_ARM_MOVW_ABS_NC */ #ifndef R_ARM_MOVT_ABS #define R_ARM_MOVT_ABS 44 #endif /* R_ARM_MOVT_ABS */ #ifndef R_ARM_MOVW_PREL_NC #define R_ARM_MOVW_PREL_NC 45 #endif /* R_ARM_MOVW_PREL_NC */ #ifndef R_ARM_MOVT_PREL #define R_ARM_MOVT_PREL 46 #endif /* R_ARM_MOVT_PREL */ #ifndef R_ARM_THM_MOVW_ABS_NC #define R_ARM_THM_MOVW_ABS_NC 47 #endif /* R_ARM_THM_MOVW_ABS_NC */ #ifndef R_ARM_THM_MOVT_ABS #define R_ARM_THM_MOVT_ABS 48 #endif /* R_ARM_THM_MOVT_ABS */ #ifndef R_ARM_THM_MOVW_PREL_NC #define R_ARM_THM_MOVW_PREL_NC 49 #endif /* R_ARM_THM_MOVW_PREL_NC */ #ifndef R_ARM_THM_MOVT_PREL #define R_ARM_THM_MOVT_PREL 50 #endif /* R_ARM_THM_MOVT_PREL */ #ifndef R_ARM_THM_JUMP19 #define R_ARM_THM_JUMP19 51 #endif /* R_ARM_THM_JUMP19 */ #ifndef R_ARM_THM_JUMP6 #define R_ARM_THM_JUMP6 52 #endif /* R_ARM_THM_JUMP6 */ #ifndef R_ARM_THM_ALU_PREL_11_0 #define R_ARM_THM_ALU_PREL_11_0 53 #endif /* R_ARM_THM_ALU_PREL_11_0 */ #ifndef R_ARM_THM_PC12 #define R_ARM_THM_PC12 54 #endif /* R_ARM_THM_PC12 */ #ifndef R_ARM_ABS32_NOI #define R_ARM_ABS32_NOI 55 #endif /* R_ARM_ABS32_NOI */ #ifndef R_ARM_REL32_NOI #define R_ARM_REL32_NOI 56 #endif /* R_ARM_REL32_NOI */ #ifndef R_ARM_ALU_PC_G0_NC #define R_ARM_ALU_PC_G0_NC 57 #endif /* R_ARM_ALU_PC_G0_NC */ #ifndef R_ARM_ALU_PC_G0 #define R_ARM_ALU_PC_G0 58 #endif /* R_ARM_ALU_PC_G0 */ #ifndef R_ARM_ALU_PC_G1_NC #define R_ARM_ALU_PC_G1_NC 59 #endif /* R_ARM_ALU_PC_G1_NC */ #ifndef R_ARM_ALU_PC_G1 #define R_ARM_ALU_PC_G1 60 #endif /* R_ARM_ALU_PC_G1 */ #ifndef R_ARM_ALU_PC_G2 #define R_ARM_ALU_PC_G2 61 #endif /* R_ARM_ALU_PC_G2 */ #ifndef R_ARM_LDR_PC_G1 #define R_ARM_LDR_PC_G1 62 #endif /* R_ARM_LDR_PC_G1 */ #ifndef R_ARM_LDR_PC_G2 #define R_ARM_LDR_PC_G2 63 #endif /* R_ARM_LDR_PC_G2 */ #ifndef R_ARM_LDRS_PC_G0 #define R_ARM_LDRS_PC_G0 64 #endif /* R_ARM_LDRS_PC_G0 */ #ifndef R_ARM_LDRS_PC_G1 #define R_ARM_LDRS_PC_G1 65 #endif /* R_ARM_LDRS_PC_G1 */ #ifndef R_ARM_LDRS_PC_G2 #define R_ARM_LDRS_PC_G2 66 #endif /* R_ARM_LDRS_PC_G2 */ #ifndef R_ARM_LDC_PC_G0 #define R_ARM_LDC_PC_G0 67 #endif /* R_ARM_LDC_PC_G0 */ #ifndef R_ARM_LDC_PC_G1 #define R_ARM_LDC_PC_G1 68 #endif /* R_ARM_LDC_PC_G1 */ #ifndef R_ARM_LDC_PC_G2 #define R_ARM_LDC_PC_G2 69 #endif /* R_ARM_LDC_PC_G2 */ #ifndef R_ARM_ALU_SB_G0_NC #define R_ARM_ALU_SB_G0_NC 70 #endif /* R_ARM_ALU_SB_G0_NC */ #ifndef R_ARM_ALU_SB_G0 #define R_ARM_ALU_SB_G0 71 #endif /* R_ARM_ALU_SB_G0 */ #ifndef R_ARM_ALU_SB_G1_NC #define R_ARM_ALU_SB_G1_NC 72 #endif /* R_ARM_ALU_SB_G1_NC */ #ifndef R_ARM_ALU_SB_G1 #define R_ARM_ALU_SB_G1 73 #endif /* R_ARM_ALU_SB_G1 */ #ifndef R_ARM_ALU_SB_G2 #define R_ARM_ALU_SB_G2 74 #endif /* R_ARM_ALU_SB_G2 */ #ifndef R_ARM_LDR_SB_G0 #define R_ARM_LDR_SB_G0 75 #endif /* R_ARM_LDR_SB_G0 */ #ifndef R_ARM_LDR_SB_G1 #define R_ARM_LDR_SB_G1 76 #endif /* R_ARM_LDR_SB_G1 */ #ifndef R_ARM_LDR_SB_G2 #define R_ARM_LDR_SB_G2 77 #endif /* R_ARM_LDR_SB_G2 */ #ifndef R_ARM_LDRS_SB_G0 #define R_ARM_LDRS_SB_G0 78 #endif /* R_ARM_LDRS_SB_G0 */ #ifndef R_ARM_LDRS_SB_G1 #define R_ARM_LDRS_SB_G1 79 #endif /* R_ARM_LDRS_SB_G1 */ #ifndef R_ARM_LDRS_SB_G2 #define R_ARM_LDRS_SB_G2 80 #endif /* R_ARM_LDRS_SB_G2 */ #ifndef R_ARM_LDC_SB_G0 #define R_ARM_LDC_SB_G0 81 #endif /* R_ARM_LDC_SB_G0 */ #ifndef R_ARM_LDC_SB_G1 #define R_ARM_LDC_SB_G1 82 #endif /* R_ARM_LDC_SB_G1 */ #ifndef R_ARM_LDC_SB_G2 #define R_ARM_LDC_SB_G2 83 #endif /* R_ARM_LDC_SB_G2 */ #ifndef R_ARM_MOVW_BREL_NC #define R_ARM_MOVW_BREL_NC 84 #endif /* R_ARM_MOVW_BREL_NC */ #ifndef R_ARM_MOVT_BREL #define R_ARM_MOVT_BREL 85 #endif /* R_ARM_MOVT_BREL */ #ifndef R_ARM_MOVW_BREL #define R_ARM_MOVW_BREL 86 #endif /* R_ARM_MOVW_BREL */ #ifndef R_ARM_THM_MOVW_BREL_NC #define R_ARM_THM_MOVW_BREL_NC 87 #endif /* R_ARM_THM_MOVW_BREL_NC */ #ifndef R_ARM_THM_MOVT_BREL #define R_ARM_THM_MOVT_BREL 88 #endif /* R_ARM_THM_MOVT_BREL */ #ifndef R_ARM_THM_MOVW_BREL #define R_ARM_THM_MOVW_BREL 89 #endif /* R_ARM_THM_MOVW_BREL */ #ifndef R_ARM_TLS_GOTDESC #define R_ARM_TLS_GOTDESC 90 #endif /* R_ARM_TLS_GOTDESC */ #ifndef R_ARM_TLS_CALL #define R_ARM_TLS_CALL 91 #endif /* R_ARM_TLS_CALL */ #ifndef R_ARM_TLS_DESCSEQ #define R_ARM_TLS_DESCSEQ 92 #endif /* R_ARM_TLS_DESCSEQ */ #ifndef R_ARM_THM_TLS_CALL #define R_ARM_THM_TLS_CALL 93 #endif /* R_ARM_THM_TLS_CALL */ #ifndef R_ARM_PLT32_ABS #define R_ARM_PLT32_ABS 94 #endif /* R_ARM_PLT32_ABS */ #ifndef R_ARM_GOT_ABS #define R_ARM_GOT_ABS 95 #endif /* R_ARM_GOT_ABS */ #ifndef R_ARM_GOT_PREL #define R_ARM_GOT_PREL 96 #endif /* R_ARM_GOT_PREL */ #ifndef R_ARM_GOT_BREL12 #define R_ARM_GOT_BREL12 97 #endif /* R_ARM_GOT_BREL12 */ #ifndef R_ARM_GOTOFF12 #define R_ARM_GOTOFF12 98 #endif /* R_ARM_GOTOFF12 */ #ifndef R_ARM_GOTRELAX #define R_ARM_GOTRELAX 99 #endif /* R_ARM_GOTRELAX */ #ifndef R_ARM_GNU_VTENTRY #define R_ARM_GNU_VTENTRY 100 #endif /* R_ARM_GNU_VTENTRY */ #ifndef R_ARM_GNU_VTINHERIT #define R_ARM_GNU_VTINHERIT 101 #endif /* R_ARM_GNU_VTINHERIT */ #ifndef R_ARM_THM_JUMP11 #define R_ARM_THM_JUMP11 102 #endif /* R_ARM_THM_JUMP11 */ #ifndef R_ARM_THM_JUMP8 #define R_ARM_THM_JUMP8 103 #endif /* R_ARM_THM_JUMP8 */ #ifndef R_ARM_TLS_GD32 #define R_ARM_TLS_GD32 104 #endif /* R_ARM_TLS_GD32 */ #ifndef R_ARM_TLS_LDM32 #define R_ARM_TLS_LDM32 105 #endif /* R_ARM_TLS_LDM32 */ #ifndef R_ARM_TLS_LDO32 #define R_ARM_TLS_LDO32 106 #endif /* R_ARM_TLS_LDO32 */ #ifndef R_ARM_TLS_IE32 #define R_ARM_TLS_IE32 107 #endif /* R_ARM_TLS_IE32 */ #ifndef R_ARM_TLS_LE32 #define R_ARM_TLS_LE32 108 #endif /* R_ARM_TLS_LE32 */ #ifndef R_ARM_TLS_LDO12 #define R_ARM_TLS_LDO12 109 #endif /* R_ARM_TLS_LDO12 */ #ifndef R_ARM_TLS_LE12 #define R_ARM_TLS_LE12 110 #endif /* R_ARM_TLS_LE12 */ #ifndef R_ARM_TLS_IE12GP #define R_ARM_TLS_IE12GP 111 #endif /* R_ARM_TLS_IE12GP */ #ifndef R_ARM_ME_TOO #define R_ARM_ME_TOO 128 #endif /* R_ARM_ME_TOO */ #ifndef R_ARM_THM_TLS_DESCSEQ16 #define R_ARM_THM_TLS_DESCSEQ16 129 #endif /* R_ARM_THM_TLS_DESCSEQ16 */ #ifndef R_ARM_THM_TLS_DESCSEQ32 #define R_ARM_THM_TLS_DESCSEQ32 130 #endif /* R_ARM_THM_TLS_DESCSEQ32 */ #ifndef R_ARM_RXPC25 #define R_ARM_RXPC25 249 #endif /* R_ARM_RXPC25 */ #ifndef R_ARM_RSBREL32 #define R_ARM_RSBREL32 250 #endif /* R_ARM_RSBREL32 */ #ifndef R_ARM_THM_RPC22 #define R_ARM_THM_RPC22 251 #endif /* R_ARM_THM_RPC22 */ #ifndef R_ARM_RREL32 #define R_ARM_RREL32 252 #endif /* R_ARM_RREL32 */ #ifndef R_ARM_RABS32 #define R_ARM_RABS32 253 #endif /* R_ARM_RABS32 */ #ifndef R_ARM_RPC24 #define R_ARM_RPC24 254 #endif /* R_ARM_RPC24 */ #ifndef R_ARM_RBASE #define R_ARM_RBASE 255 #endif /* R_ARM_RBASE */ #ifndef R_ARM_NUM #define R_ARM_NUM 256 #endif /* R_ARM_NUM */ #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 0x101 #endif /* R_AARCH64_ABS64 */ #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 0x102 #endif /* R_AARCH64_ABS32 */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_mips.h000066400000000000000000000110421361531463500222460ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_mips(unsigned long); #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif /* R_MIPS_NONE */ #ifndef R_MIPS_16 #define R_MIPS_16 1 #endif /* R_MIPS_16 */ #ifndef R_MIPS_32 #define R_MIPS_32 2 #endif /* R_MIPS_32 */ #ifndef R_MIPS_REL #define R_MIPS_REL 3 #endif /* R_MIPS_REL */ #ifndef R_MIPS_26 #define R_MIPS_26 4 #endif /* R_MIPS_26 */ #ifndef R_MIPS_HI16 #define R_MIPS_HI16 5 #endif /* R_MIPS_HI16 */ #ifndef R_MIPS_LO16 #define R_MIPS_LO16 6 #endif /* R_MIPS_LO16 */ #ifndef R_MIPS_GPREL #define R_MIPS_GPREL 7 #endif /* R_MIPS_GPREL */ #ifndef R_MIPS_LITERAL #define R_MIPS_LITERAL 8 #endif /* R_MIPS_LITERAL */ #ifndef R_MIPS_GOT #define R_MIPS_GOT 9 #endif /* R_MIPS_GOT */ #ifndef R_MIPS_PC16 #define R_MIPS_PC16 10 #endif /* R_MIPS_PC16 */ #ifndef R_MIPS_CALL #define R_MIPS_CALL 11 #endif /* R_MIPS_CALL */ #ifndef R_MIPS_GPREL32 #define R_MIPS_GPREL32 12 #endif /* R_MIPS_GPREL32 */ #ifndef R_MIPS_UNUSED1 #define R_MIPS_UNUSED1 13 #endif /* R_MIPS_UNUSED1 */ #ifndef R_MIPS_UNUSED2 #define R_MIPS_UNUSED2 14 #endif /* R_MIPS_UNUSED2 */ #ifndef R_MIPS_UNUSED3 #define R_MIPS_UNUSED3 15 #endif /* R_MIPS_UNUSED3 */ #ifndef R_MIPS_SHIFT5 #define R_MIPS_SHIFT5 16 #endif /* R_MIPS_SHIFT5 */ #ifndef R_MIPS_SHIFT6 #define R_MIPS_SHIFT6 17 #endif /* R_MIPS_SHIFT6 */ #ifndef R_MIPS_64 #define R_MIPS_64 18 #endif /* R_MIPS_64 */ #ifndef R_MIPS_GOT_DISP #define R_MIPS_GOT_DISP 19 #endif /* R_MIPS_GOT_DISP */ #ifndef R_MIPS_GOT_PAGE #define R_MIPS_GOT_PAGE 20 #endif /* R_MIPS_GOT_PAGE */ #ifndef R_MIPS_GOT_OFST #define R_MIPS_GOT_OFST 21 #endif /* R_MIPS_GOT_OFST */ #ifndef R_MIPS_GOT_HI16 #define R_MIPS_GOT_HI16 22 #endif /* R_MIPS_GOT_HI16 */ #ifndef R_MIPS_GOT_LO16 #define R_MIPS_GOT_LO16 23 #endif /* R_MIPS_GOT_LO16 */ #ifndef R_MIPS_SUB #define R_MIPS_SUB 24 #endif /* R_MIPS_SUB */ #ifndef R_MIPS_INSERT_A #define R_MIPS_INSERT_A 25 #endif /* R_MIPS_INSERT_A */ #ifndef R_MIPS_INSERT_B #define R_MIPS_INSERT_B 26 #endif /* R_MIPS_INSERT_B */ #ifndef R_MIPS_DELETE #define R_MIPS_DELETE 27 #endif /* R_MIPS_DELETE */ #ifndef R_MIPS_HIGHER #define R_MIPS_HIGHER 28 #endif /* R_MIPS_HIGHER */ #ifndef R_MIPS_HIGHEST #define R_MIPS_HIGHEST 29 #endif /* R_MIPS_HIGHEST */ #ifndef R_MIPS_CALL_HI16 #define R_MIPS_CALL_HI16 30 #endif /* R_MIPS_CALL_HI16 */ #ifndef R_MIPS_CALL_LO16 #define R_MIPS_CALL_LO16 31 #endif /* R_MIPS_CALL_LO16 */ #ifndef R_MIPS_SCN_DISP #define R_MIPS_SCN_DISP 32 #endif /* R_MIPS_SCN_DISP */ #ifndef R_MIPS_REL16 #define R_MIPS_REL16 33 #endif /* R_MIPS_REL16 */ #ifndef R_MIPS_ADD_IMMEDIATE #define R_MIPS_ADD_IMMEDIATE 34 #endif /* R_MIPS_ADD_IMMEDIATE */ #ifndef R_MIPS_PJUMP #define R_MIPS_PJUMP 35 #endif /* R_MIPS_PJUMP */ #ifndef R_MIPS_RELGOT #define R_MIPS_RELGOT 36 #endif /* R_MIPS_RELGOT */ #ifndef R_MIPS_JALR #define R_MIPS_JALR 37 #endif /* R_MIPS_JALR */ #ifndef R_MIPS_TLS_DTPMOD32 #define R_MIPS_TLS_DTPMOD32 38 #endif /* R_MIPS_TLS_DTPMOD32 */ #ifndef R_MIPS_TLS_DTPREL32 #define R_MIPS_TLS_DTPREL32 39 #endif /* R_MIPS_TLS_DTPREL32 */ #ifndef R_MIPS_TLS_DTPMOD64 #define R_MIPS_TLS_DTPMOD64 40 #endif /* R_MIPS_TLS_DTPMOD64 */ #ifndef R_MIPS_TLS_DTPREL64 #define R_MIPS_TLS_DTPREL64 41 #endif /* R_MIPS_TLS_DTPREL64 */ #ifndef R_MIPS_TLS_GD #define R_MIPS_TLS_GD 42 #endif /* R_MIPS_TLS_GD */ #ifndef R_MIPS_TLS_LDM #define R_MIPS_TLS_LDM 43 #endif /* R_MIPS_TLS_LDM */ #ifndef R_MIPS_TLS_DTPREL_HI16 #define R_MIPS_TLS_DTPREL_HI16 44 #endif /* R_MIPS_TLS_DTPREL_HI16 */ #ifndef R_MIPS_TLS_DTPREL_LO16 #define R_MIPS_TLS_DTPREL_LO16 45 #endif /* R_MIPS_TLS_DTPREL_LO16 */ #ifndef R_MIPS_TLS_GOTTPREL #define R_MIPS_TLS_GOTTPREL 46 #endif /* R_MIPS_TLS_GOTTPREL */ #ifndef R_MIPS_TLS_TPREL32 #define R_MIPS_TLS_TPREL32 47 #endif /* R_MIPS_TLS_TPREL32 */ #ifndef R_MIPS_TLS_TPREL_HI16 #define R_MIPS_TLS_TPREL_HI16 49 #endif /* R_MIPS_TLS_TPREL_HI16 */ #ifndef R_MIPS_TLS_TPREL_LO16 #define R_MIPS_TLS_TPREL_LO16 50 #endif /* R_MIPS_TLS_TPREL_LO16 */ #ifndef R_MIPS_GLOB_DAT #define R_MIPS_GLOB_DAT 51 #endif /* R_MIPS_GLOB_DAT */ #ifndef R_MIPS_COPY #define R_MIPS_COPY 126 #endif /* R_MIPS_COPY */ #ifndef R_MIPS_JUMP_SLOT #define R_MIPS_JUMP_SLOT 127 #endif /* R_MIPS_JUMP_SLOT */ #ifndef R_MIPS_NUM #define R_MIPS_NUM 128 #endif /* R_MIPS_NUM */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_ppc.h000066400000000000000000000243151361531463500220670ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_ppc(unsigned long); #ifndef R_PPC_NONE #define R_PPC_NONE 0 #endif /* R_PPC_NONE */ #ifndef R_PPC_ADDR32 #define R_PPC_ADDR32 1 #endif /* R_PPC_ADDR32 */ #ifndef R_PPC_ADDR24 #define R_PPC_ADDR24 2 #endif /* R_PPC_ADDR24 */ #ifndef R_PPC_ADDR16 #define R_PPC_ADDR16 3 #endif /* R_PPC_ADDR16 */ #ifndef R_PPC_ADDR16_LO #define R_PPC_ADDR16_LO 4 #endif /* R_PPC_ADDR16_LO */ #ifndef R_PPC_ADDR16_HI #define R_PPC_ADDR16_HI 5 #endif /* R_PPC_ADDR16_HI */ #ifndef R_PPC_ADDR16_HA #define R_PPC_ADDR16_HA 6 #endif /* R_PPC_ADDR16_HA */ #ifndef R_PPC_ADDR14 #define R_PPC_ADDR14 7 #endif /* R_PPC_ADDR14 */ #ifndef R_PPC_ADDR14_BRTAKEN #define R_PPC_ADDR14_BRTAKEN 8 #endif /* R_PPC_ADDR14_BRTAKEN */ #ifndef R_PPC_ADDR14_BRNTAKEN #define R_PPC_ADDR14_BRNTAKEN 9 #endif /* R_PPC_ADDR14_BRNTAKEN */ #ifndef R_PPC_REL24 #define R_PPC_REL24 10 #endif /* R_PPC_REL24 */ #ifndef R_PPC_REL14 #define R_PPC_REL14 11 #endif /* R_PPC_REL14 */ #ifndef R_PPC_REL14_BRTAKEN #define R_PPC_REL14_BRTAKEN 12 #endif /* R_PPC_REL14_BRTAKEN */ #ifndef R_PPC_REL14_BRNTAKEN #define R_PPC_REL14_BRNTAKEN 13 #endif /* R_PPC_REL14_BRNTAKEN */ #ifndef R_PPC_GOT16 #define R_PPC_GOT16 14 #endif /* R_PPC_GOT16 */ #ifndef R_PPC_GOT16_LO #define R_PPC_GOT16_LO 15 #endif /* R_PPC_GOT16_LO */ #ifndef R_PPC_GOT16_HI #define R_PPC_GOT16_HI 16 #endif /* R_PPC_GOT16_HI */ #ifndef R_PPC_GOT16_HA #define R_PPC_GOT16_HA 17 #endif /* R_PPC_GOT16_HA */ #ifndef R_PPC_PLTREL24 #define R_PPC_PLTREL24 18 #endif /* R_PPC_PLTREL24 */ #ifndef R_PPC_COPY #define R_PPC_COPY 19 #endif /* R_PPC_COPY */ #ifndef R_PPC_GLOB_DAT #define R_PPC_GLOB_DAT 20 #endif /* R_PPC_GLOB_DAT */ #ifndef R_PPC_JMP_SLOT #define R_PPC_JMP_SLOT 21 #endif /* R_PPC_JMP_SLOT */ #ifndef R_PPC_RELATIVE #define R_PPC_RELATIVE 22 #endif /* R_PPC_RELATIVE */ #ifndef R_PPC_LOCAL24PC #define R_PPC_LOCAL24PC 23 #endif /* R_PPC_LOCAL24PC */ #ifndef R_PPC_UADDR32 #define R_PPC_UADDR32 24 #endif /* R_PPC_UADDR32 */ #ifndef R_PPC_UADDR16 #define R_PPC_UADDR16 25 #endif /* R_PPC_UADDR16 */ #ifndef R_PPC_REL32 #define R_PPC_REL32 26 #endif /* R_PPC_REL32 */ #ifndef R_PPC_PLT32 #define R_PPC_PLT32 27 #endif /* R_PPC_PLT32 */ #ifndef R_PPC_PLTREL32 #define R_PPC_PLTREL32 28 #endif /* R_PPC_PLTREL32 */ #ifndef R_PPC_PLT16_LO #define R_PPC_PLT16_LO 29 #endif /* R_PPC_PLT16_LO */ #ifndef R_PPC_PLT16_HI #define R_PPC_PLT16_HI 30 #endif /* R_PPC_PLT16_HI */ #ifndef R_PPC_PLT16_HA #define R_PPC_PLT16_HA 31 #endif /* R_PPC_PLT16_HA */ #ifndef R_PPC_SDAREL16 #define R_PPC_SDAREL16 32 #endif /* R_PPC_SDAREL16 */ #ifndef R_PPC_SECTOFF #define R_PPC_SECTOFF 33 #endif /* R_PPC_SECTOFF */ #ifndef R_PPC_SECTOFF_LO #define R_PPC_SECTOFF_LO 34 #endif /* R_PPC_SECTOFF_LO */ #ifndef R_PPC_SECTOFF_HI #define R_PPC_SECTOFF_HI 35 #endif /* R_PPC_SECTOFF_HI */ #ifndef R_PPC_SECTOFF_HA #define R_PPC_SECTOFF_HA 36 #endif /* R_PPC_SECTOFF_HA */ #ifndef R_PPC_37 #define R_PPC_37 37 #endif /* R_PPC_37 */ #ifndef R_PPC_38 #define R_PPC_38 38 #endif /* R_PPC_38 */ #ifndef R_PPC_39 #define R_PPC_39 39 #endif /* R_PPC_39 */ #ifndef R_PPC_40 #define R_PPC_40 40 #endif /* R_PPC_40 */ #ifndef R_PPC_41 #define R_PPC_41 41 #endif /* R_PPC_41 */ #ifndef R_PPC_42 #define R_PPC_42 42 #endif /* R_PPC_42 */ #ifndef R_PPC_43 #define R_PPC_43 43 #endif /* R_PPC_43 */ #ifndef R_PPC_44 #define R_PPC_44 44 #endif /* R_PPC_44 */ #ifndef R_PPC_45 #define R_PPC_45 45 #endif /* R_PPC_45 */ #ifndef R_PPC_46 #define R_PPC_46 46 #endif /* R_PPC_46 */ #ifndef R_PPC_47 #define R_PPC_47 47 #endif /* R_PPC_47 */ #ifndef R_PPC_48 #define R_PPC_48 48 #endif /* R_PPC_48 */ #ifndef R_PPC_49 #define R_PPC_49 49 #endif /* R_PPC_49 */ #ifndef R_PPC_50 #define R_PPC_50 50 #endif /* R_PPC_50 */ #ifndef R_PPC_51 #define R_PPC_51 51 #endif /* R_PPC_51 */ #ifndef R_PPC_52 #define R_PPC_52 52 #endif /* R_PPC_52 */ #ifndef R_PPC_53 #define R_PPC_53 53 #endif /* R_PPC_53 */ #ifndef R_PPC_54 #define R_PPC_54 54 #endif /* R_PPC_54 */ #ifndef R_PPC_55 #define R_PPC_55 55 #endif /* R_PPC_55 */ #ifndef R_PPC_56 #define R_PPC_56 56 #endif /* R_PPC_56 */ #ifndef R_PPC_57 #define R_PPC_57 57 #endif /* R_PPC_57 */ #ifndef R_PPC_58 #define R_PPC_58 58 #endif /* R_PPC_58 */ #ifndef R_PPC_59 #define R_PPC_59 59 #endif /* R_PPC_59 */ #ifndef R_PPC_60 #define R_PPC_60 60 #endif /* R_PPC_60 */ #ifndef R_PPC_61 #define R_PPC_61 61 #endif /* R_PPC_61 */ #ifndef R_PPC_62 #define R_PPC_62 62 #endif /* R_PPC_62 */ #ifndef R_PPC_63 #define R_PPC_63 63 #endif /* R_PPC_63 */ #ifndef R_PPC_64 #define R_PPC_64 64 #endif /* R_PPC_64 */ #ifndef R_PPC_65 #define R_PPC_65 65 #endif /* R_PPC_65 */ #ifndef R_PPC_66 #define R_PPC_66 66 #endif /* R_PPC_66 */ #ifndef R_PPC_TLS #define R_PPC_TLS 67 #endif /* R_PPC_TLS */ #ifndef R_PPC_DTPMOD32 #define R_PPC_DTPMOD32 68 #endif /* R_PPC_DTPMOD32 */ #ifndef R_PPC_TPREL16 #define R_PPC_TPREL16 69 #endif /* R_PPC_TPREL16 */ #ifndef R_PPC_TPREL16_LO #define R_PPC_TPREL16_LO 70 #endif /* R_PPC_TPREL16_LO */ #ifndef R_PPC_TPREL16_HI #define R_PPC_TPREL16_HI 71 #endif /* R_PPC_TPREL16_HI */ #ifndef R_PPC_TPREL16_HA #define R_PPC_TPREL16_HA 72 #endif /* R_PPC_TPREL16_HA */ #ifndef R_PPC_TPREL32 #define R_PPC_TPREL32 73 #endif /* R_PPC_TPREL32 */ #ifndef R_PPC_DTPREL16 #define R_PPC_DTPREL16 74 #endif /* R_PPC_DTPREL16 */ #ifndef R_PPC_DTPREL16_LO #define R_PPC_DTPREL16_LO 75 #endif /* R_PPC_DTPREL16_LO */ #ifndef R_PPC_DTPREL16_HI #define R_PPC_DTPREL16_HI 76 #endif /* R_PPC_DTPREL16_HI */ #ifndef R_PPC_DTPREL16_HA #define R_PPC_DTPREL16_HA 77 #endif /* R_PPC_DTPREL16_HA */ #ifndef R_PPC_DTPREL32 #define R_PPC_DTPREL32 78 #endif /* R_PPC_DTPREL32 */ #ifndef R_PPC_GOT_TLSGD16 #define R_PPC_GOT_TLSGD16 79 #endif /* R_PPC_GOT_TLSGD16 */ #ifndef R_PPC_GOT_TLSGD16_LO #define R_PPC_GOT_TLSGD16_LO 80 #endif /* R_PPC_GOT_TLSGD16_LO */ #ifndef R_PPC_GOT_TLSGD16_HI #define R_PPC_GOT_TLSGD16_HI 81 #endif /* R_PPC_GOT_TLSGD16_HI */ #ifndef R_PPC_GOT_TLSGD16_HA #define R_PPC_GOT_TLSGD16_HA 82 #endif /* R_PPC_GOT_TLSGD16_HA */ #ifndef R_PPC_GOT_TLSLD16 #define R_PPC_GOT_TLSLD16 83 #endif /* R_PPC_GOT_TLSLD16 */ #ifndef R_PPC_GOT_TLSLD16_LO #define R_PPC_GOT_TLSLD16_LO 84 #endif /* R_PPC_GOT_TLSLD16_LO */ #ifndef R_PPC_GOT_TLSLD16_HI #define R_PPC_GOT_TLSLD16_HI 85 #endif /* R_PPC_GOT_TLSLD16_HI */ #ifndef R_PPC_GOT_TLSLD16_HA #define R_PPC_GOT_TLSLD16_HA 86 #endif /* R_PPC_GOT_TLSLD16_HA */ #ifndef R_PPC_GOT_TPREL16 #define R_PPC_GOT_TPREL16 87 #endif /* R_PPC_GOT_TPREL16 */ #ifndef R_PPC_GOT_TPREL16_LO #define R_PPC_GOT_TPREL16_LO 88 #endif /* R_PPC_GOT_TPREL16_LO */ #ifndef R_PPC_GOT_TPREL16_HI #define R_PPC_GOT_TPREL16_HI 89 #endif /* R_PPC_GOT_TPREL16_HI */ #ifndef R_PPC_GOT_TPREL16_HA #define R_PPC_GOT_TPREL16_HA 90 #endif /* R_PPC_GOT_TPREL16_HA */ #ifndef R_PPC_GOT_DTPREL16 #define R_PPC_GOT_DTPREL16 91 #endif /* R_PPC_GOT_DTPREL16 */ #ifndef R_PPC_GOT_DTPREL16_LO #define R_PPC_GOT_DTPREL16_LO 92 #endif /* R_PPC_GOT_DTPREL16_LO */ #ifndef R_PPC_GOT_DTPREL16_HI #define R_PPC_GOT_DTPREL16_HI 93 #endif /* R_PPC_GOT_DTPREL16_HI */ #ifndef R_PPC_GOT_DTPREL16_HA #define R_PPC_GOT_DTPREL16_HA 94 #endif /* R_PPC_GOT_DTPREL16_HA */ #ifndef R_PPC_TLSGD #define R_PPC_TLSGD 95 #endif /* R_PPC_TLSGD */ #ifndef R_PPC_TLSLD #define R_PPC_TLSLD 96 #endif /* R_PPC_TLSLD */ #ifndef R_PPC_EMB_NADDR32 #define R_PPC_EMB_NADDR32 101 #endif /* R_PPC_EMB_NADDR32 */ #ifndef R_PPC_EMB_NADDR16 #define R_PPC_EMB_NADDR16 102 #endif /* R_PPC_EMB_NADDR16 */ #ifndef R_PPC_EMB_NADDR16_LO #define R_PPC_EMB_NADDR16_LO 103 #endif /* R_PPC_EMB_NADDR16_LO */ #ifndef R_PPC_EMB_NADDR16_HI #define R_PPC_EMB_NADDR16_HI 104 #endif /* R_PPC_EMB_NADDR16_HI */ #ifndef R_PPC_EMB_NADDR16_HA #define R_PPC_EMB_NADDR16_HA 105 #endif /* R_PPC_EMB_NADDR16_HA */ #ifndef R_PPC_EMB_SDAI16 #define R_PPC_EMB_SDAI16 106 #endif /* R_PPC_EMB_SDAI16 */ #ifndef R_PPC_EMB_SDA2I16 #define R_PPC_EMB_SDA2I16 107 #endif /* R_PPC_EMB_SDA2I16 */ #ifndef R_PPC_EMB_SDA2REL #define R_PPC_EMB_SDA2REL 108 #endif /* R_PPC_EMB_SDA2REL */ #ifndef R_PPC_EMB_SDA21 #define R_PPC_EMB_SDA21 109 #endif /* R_PPC_EMB_SDA21 */ #ifndef R_PPC_EMB_MRKREF #define R_PPC_EMB_MRKREF 110 #endif /* R_PPC_EMB_MRKREF */ #ifndef R_PPC_EMB_RELSEC16 #define R_PPC_EMB_RELSEC16 111 #endif /* R_PPC_EMB_RELSEC16 */ #ifndef R_PPC_EMB_RELST_LO #define R_PPC_EMB_RELST_LO 112 #endif /* R_PPC_EMB_RELST_LO */ #ifndef R_PPC_EMB_RELST_HI #define R_PPC_EMB_RELST_HI 113 #endif /* R_PPC_EMB_RELST_HI */ #ifndef R_PPC_EMB_RELST_HA #define R_PPC_EMB_RELST_HA 114 #endif /* R_PPC_EMB_RELST_HA */ #ifndef R_PPC_EMB_BIT_FLD #define R_PPC_EMB_BIT_FLD 115 #endif /* R_PPC_EMB_BIT_FLD */ #ifndef R_PPC_EMB_RELSDA #define R_PPC_EMB_RELSDA 116 #endif /* R_PPC_EMB_RELSDA */ #ifndef R_PPC_DIAB_SDA21_LO #define R_PPC_DIAB_SDA21_LO 180 #endif /* R_PPC_DIAB_SDA21_LO */ #ifndef R_PPC_DIAB_SDA21_HI #define R_PPC_DIAB_SDA21_HI 181 #endif /* R_PPC_DIAB_SDA21_HI */ #ifndef R_PPC_DIAB_SDA21_HA #define R_PPC_DIAB_SDA21_HA 182 #endif /* R_PPC_DIAB_SDA21_HA */ #ifndef R_PPC_DIAB_RELSDA_LO #define R_PPC_DIAB_RELSDA_LO 183 #endif /* R_PPC_DIAB_RELSDA_LO */ #ifndef R_PPC_DIAB_RELSDA_HI #define R_PPC_DIAB_RELSDA_HI 184 #endif /* R_PPC_DIAB_RELSDA_HI */ #ifndef R_PPC_DIAB_RELSDA_HA #define R_PPC_DIAB_RELSDA_HA 185 #endif /* R_PPC_DIAB_RELSDA_HA */ #ifndef R_PPC_IRELATIVE #define R_PPC_IRELATIVE 248 #endif /* R_PPC_IRELATIVE */ #ifndef R_PPC_REL16 #define R_PPC_REL16 249 #endif /* R_PPC_REL16 */ #ifndef R_PPC_REL16_LO #define R_PPC_REL16_LO 250 #endif /* R_PPC_REL16_LO */ #ifndef R_PPC_REL16_HI #define R_PPC_REL16_HI 251 #endif /* R_PPC_REL16_HI */ #ifndef R_PPC_REL16_HA #define R_PPC_REL16_HA 252 #endif /* R_PPC_REL16_HA */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_ppc64.h000066400000000000000000000177051361531463500222460ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_ppc64(unsigned long); #ifndef R_PPC64_ADDR30 #define R_PPC64_ADDR30 37 #endif /* R_PPC64_ADDR30 */ #ifndef R_PPC64_ADDR64 #define R_PPC64_ADDR64 38 #endif /* R_PPC64_ADDR64 */ #ifndef R_PPC64_ADDR16_HIGHER #define R_PPC64_ADDR16_HIGHER 39 #endif /* R_PPC64_ADDR16_HIGHER */ #ifndef R_PPC64_ADDR16_HIGHERA #define R_PPC64_ADDR16_HIGHERA 40 #endif /* R_PPC64_ADDR16_HIGHERA */ #ifndef R_PPC64_ADDR16_HIGHEST #define R_PPC64_ADDR16_HIGHEST 41 #endif /* R_PPC64_ADDR16_HIGHEST */ #ifndef R_PPC64_ADDR16_HIGHESTA #define R_PPC64_ADDR16_HIGHESTA 42 #endif /* R_PPC64_ADDR16_HIGHESTA */ #ifndef R_PPC64_UADDR64 #define R_PPC64_UADDR64 43 #endif /* R_PPC64_UADDR64 */ #ifndef R_PPC64_REL64 #define R_PPC64_REL64 44 #endif /* R_PPC64_REL64 */ #ifndef R_PPC64_PLT64 #define R_PPC64_PLT64 45 #endif /* R_PPC64_PLT64 */ #ifndef R_PPC64_PLTREL64 #define R_PPC64_PLTREL64 46 #endif /* R_PPC64_PLTREL64 */ #ifndef R_PPC64_TOC16 #define R_PPC64_TOC16 47 #endif /* R_PPC64_TOC16 */ #ifndef R_PPC64_TOC16_LO #define R_PPC64_TOC16_LO 48 #endif /* R_PPC64_TOC16_LO */ #ifndef R_PPC64_TOC16_HI #define R_PPC64_TOC16_HI 49 #endif /* R_PPC64_TOC16_HI */ #ifndef R_PPC64_TOC16_HA #define R_PPC64_TOC16_HA 50 #endif /* R_PPC64_TOC16_HA */ #ifndef R_PPC64_TOC #define R_PPC64_TOC 51 #endif /* R_PPC64_TOC */ #ifndef R_PPC64_PLTGOT16 #define R_PPC64_PLTGOT16 52 #endif /* R_PPC64_PLTGOT16 */ #ifndef R_PPC64_PLTGOT16_LO #define R_PPC64_PLTGOT16_LO 53 #endif /* R_PPC64_PLTGOT16_LO */ #ifndef R_PPC64_PLTGOT16_HI #define R_PPC64_PLTGOT16_HI 54 #endif /* R_PPC64_PLTGOT16_HI */ #ifndef R_PPC64_PLTGOT16_HA #define R_PPC64_PLTGOT16_HA 55 #endif /* R_PPC64_PLTGOT16_HA */ #ifndef R_PPC64_ADDR16_DS #define R_PPC64_ADDR16_DS 56 #endif /* R_PPC64_ADDR16_DS */ #ifndef R_PPC64_ADDR16_LO_DS #define R_PPC64_ADDR16_LO_DS 57 #endif /* R_PPC64_ADDR16_LO_DS */ #ifndef R_PPC64_GOT16_DS #define R_PPC64_GOT16_DS 58 #endif /* R_PPC64_GOT16_DS */ #ifndef R_PPC64_GOT16_LO_DS #define R_PPC64_GOT16_LO_DS 59 #endif /* R_PPC64_GOT16_LO_DS */ #ifndef R_PPC64_PLT16_LO_DS #define R_PPC64_PLT16_LO_DS 60 #endif /* R_PPC64_PLT16_LO_DS */ #ifndef R_PPC64_SECTOFF_DS #define R_PPC64_SECTOFF_DS 61 #endif /* R_PPC64_SECTOFF_DS */ #ifndef R_PPC64_SECTOFF_LO_DS #define R_PPC64_SECTOFF_LO_DS 62 #endif /* R_PPC64_SECTOFF_LO_DS */ #ifndef R_PPC64_TOC16_DS #define R_PPC64_TOC16_DS 63 #endif /* R_PPC64_TOC16_DS */ #ifndef R_PPC64_TOC16_LO_DS #define R_PPC64_TOC16_LO_DS 64 #endif /* R_PPC64_TOC16_LO_DS */ #ifndef R_PPC64_PLTGOT16_DS #define R_PPC64_PLTGOT16_DS 65 #endif /* R_PPC64_PLTGOT16_DS */ #ifndef R_PPC64_PLTGOT16_LO_DS #define R_PPC64_PLTGOT16_LO_DS 66 #endif /* R_PPC64_PLTGOT16_LO_DS */ #ifndef R_PPC64_TLS #define R_PPC64_TLS 67 #endif /* R_PPC64_TLS */ #ifndef R_PPC64_DTPMOD64 #define R_PPC64_DTPMOD64 68 #endif /* R_PPC64_DTPMOD64 */ #ifndef R_PPC64_TPREL16 #define R_PPC64_TPREL16 69 #endif /* R_PPC64_TPREL16 */ #ifndef R_PPC64_TPREL16_LO #define R_PPC64_TPREL16_LO 70 #endif /* R_PPC64_TPREL16_LO */ #ifndef R_PPC64_TPREL16_HI #define R_PPC64_TPREL16_HI 71 #endif /* R_PPC64_TPREL16_HI */ #ifndef R_PPC64_TPREL16_HA #define R_PPC64_TPREL16_HA 72 #endif /* R_PPC64_TPREL16_HA */ #ifndef R_PPC64_TPREL64 #define R_PPC64_TPREL64 73 #endif /* R_PPC64_TPREL64 */ #ifndef R_PPC64_DTPREL16 #define R_PPC64_DTPREL16 74 #endif /* R_PPC64_DTPREL16 */ #ifndef R_PPC64_DTPREL16_LO #define R_PPC64_DTPREL16_LO 75 #endif /* R_PPC64_DTPREL16_LO */ #ifndef R_PPC64_DTPREL16_HI #define R_PPC64_DTPREL16_HI 76 #endif /* R_PPC64_DTPREL16_HI */ #ifndef R_PPC64_DTPREL16_HA #define R_PPC64_DTPREL16_HA 77 #endif /* R_PPC64_DTPREL16_HA */ #ifndef R_PPC64_DTPREL64 #define R_PPC64_DTPREL64 78 #endif /* R_PPC64_DTPREL64 */ #ifndef R_PPC64_GOT_TLSGD16 #define R_PPC64_GOT_TLSGD16 79 #endif /* R_PPC64_GOT_TLSGD16 */ #ifndef R_PPC64_GOT_TLSGD16_LO #define R_PPC64_GOT_TLSGD16_LO 80 #endif /* R_PPC64_GOT_TLSGD16_LO */ #ifndef R_PPC64_GOT_TLSGD16_HI #define R_PPC64_GOT_TLSGD16_HI 81 #endif /* R_PPC64_GOT_TLSGD16_HI */ #ifndef R_PPC64_GOT_TLSGD16_HA #define R_PPC64_GOT_TLSGD16_HA 82 #endif /* R_PPC64_GOT_TLSGD16_HA */ #ifndef R_PPC64_GOT_TLSLD16 #define R_PPC64_GOT_TLSLD16 83 #endif /* R_PPC64_GOT_TLSLD16 */ #ifndef R_PPC64_GOT_TLSLD16_LO #define R_PPC64_GOT_TLSLD16_LO 84 #endif /* R_PPC64_GOT_TLSLD16_LO */ #ifndef R_PPC64_GOT_TLSLD16_HI #define R_PPC64_GOT_TLSLD16_HI 85 #endif /* R_PPC64_GOT_TLSLD16_HI */ #ifndef R_PPC64_GOT_TLSLD16_HA #define R_PPC64_GOT_TLSLD16_HA 86 #endif /* R_PPC64_GOT_TLSLD16_HA */ #ifndef R_PPC64_GOT_TPREL16_DS #define R_PPC64_GOT_TPREL16_DS 87 #endif /* R_PPC64_GOT_TPREL16_DS */ #ifndef R_PPC64_GOT_TPREL16_LO_DS #define R_PPC64_GOT_TPREL16_LO_DS 88 #endif /* R_PPC64_GOT_TPREL16_LO_DS */ #ifndef R_PPC64_GOT_TPREL16_HI #define R_PPC64_GOT_TPREL16_HI 89 #endif /* R_PPC64_GOT_TPREL16_HI */ #ifndef R_PPC64_GOT_TPREL16_HA #define R_PPC64_GOT_TPREL16_HA 90 #endif /* R_PPC64_GOT_TPREL16_HA */ #ifndef R_PPC64_GOT_DTPREL16_DS #define R_PPC64_GOT_DTPREL16_DS 91 #endif /* R_PPC64_GOT_DTPREL16_DS */ #ifndef R_PPC64_GOT_DTPREL16_LO_DS #define R_PPC64_GOT_DTPREL16_LO_DS 92 #endif /* R_PPC64_GOT_DTPREL16_LO_DS */ #ifndef R_PPC64_GOT_DTPREL16_HI #define R_PPC64_GOT_DTPREL16_HI 93 #endif /* R_PPC64_GOT_DTPREL16_HI */ #ifndef R_PPC64_GOT_DTPREL16_HA #define R_PPC64_GOT_DTPREL16_HA 94 #endif /* R_PPC64_GOT_DTPREL16_HA */ #ifndef R_PPC64_TPREL16_DS #define R_PPC64_TPREL16_DS 95 #endif /* R_PPC64_TPREL16_DS */ #ifndef R_PPC64_TPREL16_LO_DS #define R_PPC64_TPREL16_LO_DS 96 #endif /* R_PPC64_TPREL16_LO_DS */ #ifndef R_PPC64_TPREL16_HIGHER #define R_PPC64_TPREL16_HIGHER 97 #endif /* R_PPC64_TPREL16_HIGHER */ #ifndef R_PPC64_TPREL16_HIGHERA #define R_PPC64_TPREL16_HIGHERA 98 #endif /* R_PPC64_TPREL16_HIGHERA */ #ifndef R_PPC64_TPREL16_HIGHEST #define R_PPC64_TPREL16_HIGHEST 99 #endif /* R_PPC64_TPREL16_HIGHEST */ #ifndef R_PPC64_TPREL16_HIGHESTA #define R_PPC64_TPREL16_HIGHESTA 100 #endif /* R_PPC64_TPREL16_HIGHESTA */ #ifndef R_PPC64_DTPREL16_DS #define R_PPC64_DTPREL16_DS 101 #endif /* R_PPC64_DTPREL16_DS */ #ifndef R_PPC64_DTPREL16_LO_DS #define R_PPC64_DTPREL16_LO_DS 102 #endif /* R_PPC64_DTPREL16_LO_DS */ #ifndef R_PPC64_DTPREL16_HIGHER #define R_PPC64_DTPREL16_HIGHER 103 #endif /* R_PPC64_DTPREL16_HIGHER */ #ifndef R_PPC64_DTPREL16_HIGHERA #define R_PPC64_DTPREL16_HIGHERA 104 #endif /* R_PPC64_DTPREL16_HIGHERA */ #ifndef R_PPC64_DTPREL16_HIGHEST #define R_PPC64_DTPREL16_HIGHEST 105 #endif /* R_PPC64_DTPREL16_HIGHEST */ #ifndef R_PPC64_DTPREL16_HIGHESTA #define R_PPC64_DTPREL16_HIGHESTA 106 #endif /* R_PPC64_DTPREL16_HIGHESTA */ #ifndef R_PPC64_TOC32 #define R_PPC64_TOC32 107 #endif /* R_PPC64_TOC32 */ #ifndef R_PPC64_DTPMOD32 #define R_PPC64_DTPMOD32 108 #endif /* R_PPC64_DTPMOD32 */ #ifndef R_PPC64_TPREL32 #define R_PPC64_TPREL32 109 #endif /* R_PPC64_TPREL32 */ #ifndef R_PPC64_DTPREL32 #define R_PPC64_DTPREL32 110 #endif /* R_PPC64_DTPREL32 */ #ifndef R_PPC64_ADDR16_HIGHA #define R_PPC64_ADDR16_HIGHA 111 #endif /* R_PPC64_ADDR16_HIGHA */ #ifndef R_PPC64_TPREL16_HIGH #define R_PPC64_TPREL16_HIGH 112 #endif /* R_PPC64_TPREL16_HIGH */ #ifndef R_PPC64_TPREL16_HIGHA #define R_PPC64_TPREL16_HIGHA 113 #endif /* R_PPC64_TPREL16_HIGHA */ #ifndef R_PPC64_DTPREL16_HIGH #define R_PPC64_DTPREL16_HIGH 114 #endif /* R_PPC64_DTPREL16_HIGH */ #ifndef R_PPC64_DTPREL16_HIGHA #define R_PPC64_DTPREL16_HIGHA 115 #endif /* R_PPC64_DTPREL16_HIGHA */ #ifndef R_PPC64_JMP_IREL #define R_PPC64_JMP_IREL 247 #endif /* R_PPC64_JMP_IREL */ #ifndef R_PPC64_IRELATIVE #define R_PPC64_IRELATIVE 248 #endif /* R_PPC64_IRELATIVE */ #ifndef R_PPC64_REL16 #define R_PPC64_REL16 249 #endif /* R_PPC64_REL16 */ #ifndef R_PPC64_REL16_LO #define R_PPC64_REL16_LO 250 #endif /* R_PPC64_REL16_LO */ #ifndef R_PPC64_REL16_HI #define R_PPC64_REL16_HI 251 #endif /* R_PPC64_REL16_HI */ #ifndef R_PPC64_REL16_HA #define R_PPC64_REL16_HA 252 #endif /* R_PPC64_REL16_HA */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_sparc.h000066400000000000000000000177561361531463500224300ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_sparc(unsigned long); #ifndef R_SPARC_NONE #define R_SPARC_NONE 0 #endif /* R_SPARC_NONE */ #ifndef R_SPARC_8 #define R_SPARC_8 1 #endif /* R_SPARC_8 */ #ifndef R_SPARC_16 #define R_SPARC_16 2 #endif /* R_SPARC_16 */ #ifndef R_SPARC_32 #define R_SPARC_32 3 #endif /* R_SPARC_32 */ #ifndef R_SPARC_DISP8 #define R_SPARC_DISP8 4 #endif /* R_SPARC_DISP8 */ #ifndef R_SPARC_DISP16 #define R_SPARC_DISP16 5 #endif /* R_SPARC_DISP16 */ #ifndef R_SPARC_DISP32 #define R_SPARC_DISP32 6 #endif /* R_SPARC_DISP32 */ #ifndef R_SPARC_WDISP30 #define R_SPARC_WDISP30 7 #endif /* R_SPARC_WDISP30 */ #ifndef R_SPARC_WDISP22 #define R_SPARC_WDISP22 8 #endif /* R_SPARC_WDISP22 */ #ifndef R_SPARC_HI22 #define R_SPARC_HI22 9 #endif /* R_SPARC_HI22 */ #ifndef R_SPARC_22 #define R_SPARC_22 10 #endif /* R_SPARC_22 */ #ifndef R_SPARC_13 #define R_SPARC_13 11 #endif /* R_SPARC_13 */ #ifndef R_SPARC_LO10 #define R_SPARC_LO10 12 #endif /* R_SPARC_LO10 */ #ifndef R_SPARC_GOT10 #define R_SPARC_GOT10 13 #endif /* R_SPARC_GOT10 */ #ifndef R_SPARC_GOT13 #define R_SPARC_GOT13 14 #endif /* R_SPARC_GOT13 */ #ifndef R_SPARC_GOT22 #define R_SPARC_GOT22 15 #endif /* R_SPARC_GOT22 */ #ifndef R_SPARC_PC10 #define R_SPARC_PC10 16 #endif /* R_SPARC_PC10 */ #ifndef R_SPARC_PC22 #define R_SPARC_PC22 17 #endif /* R_SPARC_PC22 */ #ifndef R_SPARC_WPLT30 #define R_SPARC_WPLT30 18 #endif /* R_SPARC_WPLT30 */ #ifndef R_SPARC_COPY #define R_SPARC_COPY 19 #endif /* R_SPARC_COPY */ #ifndef R_SPARC_GLOB_DAT #define R_SPARC_GLOB_DAT 20 #endif /* R_SPARC_GLOB_DAT */ #ifndef R_SPARC_JMP_SLOT #define R_SPARC_JMP_SLOT 21 #endif /* R_SPARC_JMP_SLOT */ #ifndef R_SPARC_RELATIVE #define R_SPARC_RELATIVE 22 #endif /* R_SPARC_RELATIVE */ #ifndef R_SPARC_UA32 #define R_SPARC_UA32 23 #endif /* R_SPARC_UA32 */ #ifndef R_SPARC_PLT32 #define R_SPARC_PLT32 24 #endif /* R_SPARC_PLT32 */ #ifndef R_SPARC_HIPLT22 #define R_SPARC_HIPLT22 25 #endif /* R_SPARC_HIPLT22 */ #ifndef R_SPARC_LOPLT10 #define R_SPARC_LOPLT10 26 #endif /* R_SPARC_LOPLT10 */ #ifndef R_SPARC_PCPLT32 #define R_SPARC_PCPLT32 27 #endif /* R_SPARC_PCPLT32 */ #ifndef R_SPARC_PCPLT22 #define R_SPARC_PCPLT22 28 #endif /* R_SPARC_PCPLT22 */ #ifndef R_SPARC_PCPLT10 #define R_SPARC_PCPLT10 29 #endif /* R_SPARC_PCPLT10 */ #ifndef R_SPARC_10 #define R_SPARC_10 30 #endif /* R_SPARC_10 */ #ifndef R_SPARC_11 #define R_SPARC_11 31 #endif /* R_SPARC_11 */ #ifndef R_SPARC_64 #define R_SPARC_64 32 #endif /* R_SPARC_64 */ #ifndef R_SPARC_OLO10 #define R_SPARC_OLO10 33 #endif /* R_SPARC_OLO10 */ #ifndef R_SPARC_HH22 #define R_SPARC_HH22 34 #endif /* R_SPARC_HH22 */ #ifndef R_SPARC_HM10 #define R_SPARC_HM10 35 #endif /* R_SPARC_HM10 */ #ifndef R_SPARC_LM22 #define R_SPARC_LM22 36 #endif /* R_SPARC_LM22 */ #ifndef R_SPARC_PC_HH22 #define R_SPARC_PC_HH22 37 #endif /* R_SPARC_PC_HH22 */ #ifndef R_SPARC_PC_HM10 #define R_SPARC_PC_HM10 38 #endif /* R_SPARC_PC_HM10 */ #ifndef R_SPARC_PC_LM22 #define R_SPARC_PC_LM22 39 #endif /* R_SPARC_PC_LM22 */ #ifndef R_SPARC_WDISP16 #define R_SPARC_WDISP16 40 #endif /* R_SPARC_WDISP16 */ #ifndef R_SPARC_WDISP19 #define R_SPARC_WDISP19 41 #endif /* R_SPARC_WDISP19 */ #ifndef R_SPARC_GLOB_JMP #define R_SPARC_GLOB_JMP 42 #endif /* R_SPARC_GLOB_JMP */ #ifndef R_SPARC_7 #define R_SPARC_7 43 #endif /* R_SPARC_7 */ #ifndef R_SPARC_5 #define R_SPARC_5 44 #endif /* R_SPARC_5 */ #ifndef R_SPARC_6 #define R_SPARC_6 45 #endif /* R_SPARC_6 */ #ifndef R_SPARC_DISP64 #define R_SPARC_DISP64 46 #endif /* R_SPARC_DISP64 */ #ifndef R_SPARC_PLT64 #define R_SPARC_PLT64 47 #endif /* R_SPARC_PLT64 */ #ifndef R_SPARC_HIX22 #define R_SPARC_HIX22 48 #endif /* R_SPARC_HIX22 */ #ifndef R_SPARC_LOX10 #define R_SPARC_LOX10 49 #endif /* R_SPARC_LOX10 */ #ifndef R_SPARC_H44 #define R_SPARC_H44 50 #endif /* R_SPARC_H44 */ #ifndef R_SPARC_M44 #define R_SPARC_M44 51 #endif /* R_SPARC_M44 */ #ifndef R_SPARC_L44 #define R_SPARC_L44 52 #endif /* R_SPARC_L44 */ #ifndef R_SPARC_REGISTER #define R_SPARC_REGISTER 53 #endif /* R_SPARC_REGISTER */ #ifndef R_SPARC_UA64 #define R_SPARC_UA64 54 #endif /* R_SPARC_UA64 */ #ifndef R_SPARC_UA16 #define R_SPARC_UA16 55 #endif /* R_SPARC_UA16 */ #ifndef R_SPARC_TLS_GD_HI22 #define R_SPARC_TLS_GD_HI22 56 #endif /* R_SPARC_TLS_GD_HI22 */ #ifndef R_SPARC_TLS_GD_LO10 #define R_SPARC_TLS_GD_LO10 57 #endif /* R_SPARC_TLS_GD_LO10 */ #ifndef R_SPARC_TLS_GD_ADD #define R_SPARC_TLS_GD_ADD 58 #endif /* R_SPARC_TLS_GD_ADD */ #ifndef R_SPARC_TLS_GD_CALL #define R_SPARC_TLS_GD_CALL 59 #endif /* R_SPARC_TLS_GD_CALL */ #ifndef R_SPARC_TLS_LDM_HI22 #define R_SPARC_TLS_LDM_HI22 60 #endif /* R_SPARC_TLS_LDM_HI22 */ #ifndef R_SPARC_TLS_LDM_LO10 #define R_SPARC_TLS_LDM_LO10 61 #endif /* R_SPARC_TLS_LDM_LO10 */ #ifndef R_SPARC_TLS_LDM_ADD #define R_SPARC_TLS_LDM_ADD 62 #endif /* R_SPARC_TLS_LDM_ADD */ #ifndef R_SPARC_TLS_LDM_CALL #define R_SPARC_TLS_LDM_CALL 63 #endif /* R_SPARC_TLS_LDM_CALL */ #ifndef R_SPARC_TLS_LDO_HIX22 #define R_SPARC_TLS_LDO_HIX22 64 #endif /* R_SPARC_TLS_LDO_HIX22 */ #ifndef R_SPARC_TLS_LDO_LOX10 #define R_SPARC_TLS_LDO_LOX10 65 #endif /* R_SPARC_TLS_LDO_LOX10 */ #ifndef R_SPARC_TLS_LDO_ADD #define R_SPARC_TLS_LDO_ADD 66 #endif /* R_SPARC_TLS_LDO_ADD */ #ifndef R_SPARC_TLS_IE_HI22 #define R_SPARC_TLS_IE_HI22 67 #endif /* R_SPARC_TLS_IE_HI22 */ #ifndef R_SPARC_TLS_IE_LO10 #define R_SPARC_TLS_IE_LO10 68 #endif /* R_SPARC_TLS_IE_LO10 */ #ifndef R_SPARC_TLS_IE_LD #define R_SPARC_TLS_IE_LD 69 #endif /* R_SPARC_TLS_IE_LD */ #ifndef R_SPARC_TLS_IE_LDX #define R_SPARC_TLS_IE_LDX 70 #endif /* R_SPARC_TLS_IE_LDX */ #ifndef R_SPARC_TLS_IE_ADD #define R_SPARC_TLS_IE_ADD 71 #endif /* R_SPARC_TLS_IE_ADD */ #ifndef R_SPARC_TLS_LE_HIX22 #define R_SPARC_TLS_LE_HIX22 72 #endif /* R_SPARC_TLS_LE_HIX22 */ #ifndef R_SPARC_TLS_LE_LOX10 #define R_SPARC_TLS_LE_LOX10 73 #endif /* R_SPARC_TLS_LE_LOX10 */ #ifndef R_SPARC_TLS_DTPMOD32 #define R_SPARC_TLS_DTPMOD32 74 #endif /* R_SPARC_TLS_DTPMOD32 */ #ifndef R_SPARC_TLS_DTPMOD64 #define R_SPARC_TLS_DTPMOD64 75 #endif /* R_SPARC_TLS_DTPMOD64 */ #ifndef R_SPARC_TLS_DTPOFF32 #define R_SPARC_TLS_DTPOFF32 76 #endif /* R_SPARC_TLS_DTPOFF32 */ #ifndef R_SPARC_TLS_DTPOFF64 #define R_SPARC_TLS_DTPOFF64 77 #endif /* R_SPARC_TLS_DTPOFF64 */ #ifndef R_SPARC_TLS_TPOFF32 #define R_SPARC_TLS_TPOFF32 78 #endif /* R_SPARC_TLS_TPOFF32 */ #ifndef R_SPARC_TLS_TPOFF64 #define R_SPARC_TLS_TPOFF64 79 #endif /* R_SPARC_TLS_TPOFF64 */ #ifndef R_SPARC_GOTDATA_HIX22 #define R_SPARC_GOTDATA_HIX22 80 #endif /* R_SPARC_GOTDATA_HIX22 */ #ifndef R_SPARC_GOTDATA_LOX10 #define R_SPARC_GOTDATA_LOX10 81 #endif /* R_SPARC_GOTDATA_LOX10 */ #ifndef R_SPARC_GOTDATA_OP_HIX22 #define R_SPARC_GOTDATA_OP_HIX22 82 #endif /* R_SPARC_GOTDATA_OP_HIX22 */ #ifndef R_SPARC_GOTDATA_OP_LOX10 #define R_SPARC_GOTDATA_OP_LOX10 83 #endif /* R_SPARC_GOTDATA_OP_LOX10 */ #ifndef R_SPARC_GOTDATA_OP #define R_SPARC_GOTDATA_OP 84 #endif /* R_SPARC_GOTDATA_OP */ #ifndef R_SPARC_H34 #define R_SPARC_H34 85 #endif /* R_SPARC_H34 */ #ifndef R_SPARC_SIZE32 #define R_SPARC_SIZE32 86 #endif /* R_SPARC_SIZE32 */ #ifndef R_SPARC_SIZE64 #define R_SPARC_SIZE64 87 #endif /* R_SPARC_SIZE64 */ #ifndef R_SPARC_WDISP10 #define R_SPARC_WDISP10 88 #endif /* R_SPARC_WDISP10 */ #ifndef R_SPARC_JMP_IREL #define R_SPARC_JMP_IREL 248 #endif /* R_SPARC_JMP_IREL */ #ifndef R_SPARC_IRELATIVE #define R_SPARC_IRELATIVE 249 #endif /* R_SPARC_IRELATIVE */ #ifndef R_SPARC_GNU_VTINHERIT #define R_SPARC_GNU_VTINHERIT 250 #endif /* R_SPARC_GNU_VTINHERIT */ #ifndef R_SPARC_GNU_VTENTRY #define R_SPARC_GNU_VTENTRY 251 #endif /* R_SPARC_GNU_VTENTRY */ #ifndef R_SPARC_REV32 #define R_SPARC_REV32 252 #endif /* R_SPARC_REV32 */ dwarfutils-20200114/libdwarf/dwarf_elf_reloc_x86_64.h000066400000000000000000000071331361531463500222420ustar00rootroot00000000000000/* Created by build_access.py */ /* returns string of length 0 if invalid arg */ const char * dwarf_get_elf_relocname_x86_64(unsigned long); #ifndef R_X86_64_NONE #define R_X86_64_NONE 0 #endif /* R_X86_64_NONE */ #ifndef R_X86_64_64 #define R_X86_64_64 1 #endif /* R_X86_64_64 */ #ifndef R_X86_64_PC32 #define R_X86_64_PC32 2 #endif /* R_X86_64_PC32 */ #ifndef R_X86_64_GOT32 #define R_X86_64_GOT32 3 #endif /* R_X86_64_GOT32 */ #ifndef R_X86_64_PLT32 #define R_X86_64_PLT32 4 #endif /* R_X86_64_PLT32 */ #ifndef R_X86_64_COPY #define R_X86_64_COPY 5 #endif /* R_X86_64_COPY */ #ifndef R_X86_64_GLOB_DAT #define R_X86_64_GLOB_DAT 6 #endif /* R_X86_64_GLOB_DAT */ #ifndef R_X86_64_JUMP_SLOT #define R_X86_64_JUMP_SLOT 7 #endif /* R_X86_64_JUMP_SLOT */ #ifndef R_X86_64_RELATIVE #define R_X86_64_RELATIVE 8 #endif /* R_X86_64_RELATIVE */ #ifndef R_X86_64_GOTPCREL #define R_X86_64_GOTPCREL 9 #endif /* R_X86_64_GOTPCREL */ #ifndef R_X86_64_32 #define R_X86_64_32 10 #endif /* R_X86_64_32 */ #ifndef R_X86_64_32S #define R_X86_64_32S 11 #endif /* R_X86_64_32S */ #ifndef R_X86_64_16 #define R_X86_64_16 12 #endif /* R_X86_64_16 */ #ifndef R_X86_64_PC16 #define R_X86_64_PC16 13 #endif /* R_X86_64_PC16 */ #ifndef R_X86_64_8 #define R_X86_64_8 14 #endif /* R_X86_64_8 */ #ifndef R_X86_64_PC8 #define R_X86_64_PC8 15 #endif /* R_X86_64_PC8 */ #ifndef R_X86_64_DTPMOD64 #define R_X86_64_DTPMOD64 16 #endif /* R_X86_64_DTPMOD64 */ #ifndef R_X86_64_DTPOFF64 #define R_X86_64_DTPOFF64 17 #endif /* R_X86_64_DTPOFF64 */ #ifndef R_X86_64_TPOFF64 #define R_X86_64_TPOFF64 18 #endif /* R_X86_64_TPOFF64 */ #ifndef R_X86_64_TLSGD #define R_X86_64_TLSGD 19 #endif /* R_X86_64_TLSGD */ #ifndef R_X86_64_TLSLD #define R_X86_64_TLSLD 20 #endif /* R_X86_64_TLSLD */ #ifndef R_X86_64_DTPOFF32 #define R_X86_64_DTPOFF32 21 #endif /* R_X86_64_DTPOFF32 */ #ifndef R_X86_64_GOTTPOFF #define R_X86_64_GOTTPOFF 22 #endif /* R_X86_64_GOTTPOFF */ #ifndef R_X86_64_TPOFF32 #define R_X86_64_TPOFF32 23 #endif /* R_X86_64_TPOFF32 */ #ifndef R_X86_64_PC64 #define R_X86_64_PC64 24 #endif /* R_X86_64_PC64 */ #ifndef R_X86_64_GOTOFF64 #define R_X86_64_GOTOFF64 25 #endif /* R_X86_64_GOTOFF64 */ #ifndef R_X86_64_GOTPC32 #define R_X86_64_GOTPC32 26 #endif /* R_X86_64_GOTPC32 */ #ifndef R_X86_64_GOT64 #define R_X86_64_GOT64 27 #endif /* R_X86_64_GOT64 */ #ifndef R_X86_64_GOTPCREL64 #define R_X86_64_GOTPCREL64 28 #endif /* R_X86_64_GOTPCREL64 */ #ifndef R_X86_64_GOTPC64 #define R_X86_64_GOTPC64 29 #endif /* R_X86_64_GOTPC64 */ #ifndef R_X86_64_GOTPLT64 #define R_X86_64_GOTPLT64 30 #endif /* R_X86_64_GOTPLT64 */ #ifndef R_X86_64_PLTOFF64 #define R_X86_64_PLTOFF64 31 #endif /* R_X86_64_PLTOFF64 */ #ifndef R_X86_64_SIZE32 #define R_X86_64_SIZE32 32 #endif /* R_X86_64_SIZE32 */ #ifndef R_X86_64_SIZE64 #define R_X86_64_SIZE64 33 #endif /* R_X86_64_SIZE64 */ #ifndef R_X86_64_GOTPC32_TLSDESC #define R_X86_64_GOTPC32_TLSDESC 34 #endif /* R_X86_64_GOTPC32_TLSDESC */ #ifndef R_X86_64_TLSDESC_CALL #define R_X86_64_TLSDESC_CALL 35 #endif /* R_X86_64_TLSDESC_CALL */ #ifndef R_X86_64_TLSDESC #define R_X86_64_TLSDESC 36 #endif /* R_X86_64_TLSDESC */ #ifndef R_X86_64_IRELATIVE #define R_X86_64_IRELATIVE 37 #endif /* R_X86_64_IRELATIVE */ #ifndef R_X86_64_RELATIVE64 #define R_X86_64_RELATIVE64 38 #endif /* R_X86_64_RELATIVE64 */ #ifndef R_X86_64_GOTPCRELX #define R_X86_64_GOTPCRELX 41 #endif /* R_X86_64_GOTPCRELX */ #ifndef R_X86_64_REX_GOTPCRELX #define R_X86_64_REX_GOTPCRELX 42 #endif /* R_X86_64_REX_GOTPCRELX */ dwarfutils-20200114/libdwarf/dwarf_elfread.c000066400000000000000000000602061361531463500206670ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. cc Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file reads the parts of an Elf file appropriate to reading DWARF debugging data. Overview: _dwarf_elf_nlsetup() Does all elf setup. calls _dwarf_elf_access_init() calls _dwarf_elf_object_access_internals_init() Creates internals record 'M', dwarf_elf_object_access_internals_t Sets flags/data in internals record Loads elf object data needed later. Sets methods struct to access elf object. calls _dwarf_object_init_b() Creates Dwarf_Debug, independent of any elf code. Sets internals record into dbg. ---------------------- _dwarf_destruct_elf_nlaccess(). This frees the elf internals record created in _dwarf_elf_object_access_internals_init() in case of errors during setup or when dwarf_finish() is called. Works safely for partially or fully set-up elf internals record. Other than in _dwarf_elf_nlsetup() the elf code knows nothing about Dwarf_Debug, and the rest of libdwarf knows nothing about the content of the object-type-specific (for Elf here) internals record. */ #include "config.h" #include #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include #include #include /* open() */ #include /* open() */ #include /* open() */ #include #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "libdwarfdefs.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "dwarf_error.h" /* for _dwarf_error() declaration */ #include "dwarf_reading.h" #include "memcpy_swap.h" #include "dwarf_object_read_common.h" #include "dwarf_object_detector.h" #include "dwarf_elfstructs.h" #include "dwarf_elf_defines.h" #include "dwarf_elf_rel_detector.h" #include "dwarf_elfread.h" #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYPE */ #ifdef WORDS_BIGENDIAN #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word(dest, \ ((char *)source) +srclength-len_out, \ len_out) ; \ } #else /* LITTLE ENDIAN */ #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((char *)source) , \ len_out) ; \ } #endif /* end LITTLE- BIG-ENDIAN */ #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ static int _dwarf_elf_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum); static Dwarf_Endianness elf_get_nolibelf_byte_order (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_endian; } static Dwarf_Small elf_get_nolibelf_length_size (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_offsetsize/8; } static Dwarf_Small elf_get_nolibelf_pointer_size (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_pointersize/8; } static Dwarf_Unsigned elf_get_nolibelf_section_count (void *obj) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); return elf->f_loc_shdr.g_count; } static int elf_get_nolibelf_section_info (void *obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section *return_section, UNUSEDARG int *error) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); if (section_index < elf->f_loc_shdr.g_count) { struct generic_shdr *sp = 0; sp = elf->f_shdr + section_index; return_section->addr = sp->gh_addr; return_section->type = sp->gh_type; return_section->size = sp->gh_size; return_section->name = sp->gh_namestring; return_section->link = sp->gh_link; return_section->info = sp->gh_info; return_section->entrysize = sp->gh_entsize; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int elf_load_nolibelf_section (void *obj, Dwarf_Half section_index, Dwarf_Small **return_data, int *error) { dwarf_elf_object_access_internals_t *elf = (dwarf_elf_object_access_internals_t*)(obj); if (0 < section_index && section_index < elf->f_loc_shdr.g_count) { int res = 0; struct generic_shdr *sp = elf->f_shdr + section_index; if (sp->gh_content) { *return_data = (Dwarf_Small *)sp->gh_content; return DW_DLV_OK; } if (!sp->gh_size) { return DW_DLV_NO_ENTRY; } if ((sp->gh_size + sp->gh_offset) > elf->f_filesize) { *error = DW_DLE_ELF_SECTION_ERROR; return DW_DLV_ERROR; } sp->gh_content = malloc((size_t)sp->gh_size); if(!sp->gh_content) { *error = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(elf->f_fd, sp->gh_content, (off_t)sp->gh_offset, (size_t)sp->gh_size, (off_t)elf->f_filesize, error); if (res != DW_DLV_OK) { free(sp->gh_content); sp->gh_content = 0; return res; } *return_data = (Dwarf_Small *)sp->gh_content; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int _dwarf_get_elf_flags_func_nl( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error) { dwarf_elf_object_access_internals_t *ep = 0; struct generic_shdr *shp = 0; ep = (dwarf_elf_object_access_internals_t *)obj_in; if (section_index == 0) { /* Nothing to do. Empty section */ return DW_DLV_OK; } if (section_index >= ep->f_loc_shdr.g_count) { *error = DW_DLE_SECTION_INDEX_BAD; return DW_DLV_ERROR; } shp = ep->f_shdr + section_index; *flags_out = shp->gh_flags; *addralign_out = shp->gh_addralign; return DW_DLV_OK; } #define MATCH_REL_SEC(i_,s_,r_) \ if (i_ == s_.dss_index) { \ *r_ = &s_; \ return DW_DLV_OK; \ } static int find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, struct Dwarf_Section_s **relocatablesec, int *error) { MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec); /* dbg-> de_debug_tu_index,reloctablesec); */ /* dbg-> de_debug_cu_index,reloctablesec); */ /* dbg-> de_debug_gdbindex,reloctablesec); */ /* dbg-> de_debug_str,syms); */ /* de_elf_symtab,syms); */ /* de_elf_strtab,syms); */ *error = DW_DLE_RELOC_SECTION_MISMATCH; return DW_DLV_ERROR; } /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. The caller may decide to ignore the errors or report them. */ static int update_entry(Dwarf_Debug dbg, dwarf_elf_object_access_internals_t*obj, struct generic_rela *rela, Dwarf_Small *target_section, Dwarf_Unsigned target_section_size, int *error) { unsigned int type = 0; unsigned int sym_idx = 0; Dwarf_Unsigned offset = 0; Dwarf_Signed addend = 0; Dwarf_Unsigned reloc_size = 0; Dwarf_Half machine = obj->f_machine; struct generic_symentry *symp = 0; offset = rela->gr_offset; addend = rela->gr_addend; type = (unsigned int)rela->gr_type; sym_idx = (unsigned int)rela->gr_sym; if (sym_idx >= obj->f_loc_symtab.g_count) { *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD; return DW_DLV_ERROR; } symp = obj->f_symtab + sym_idx; if (offset >= target_section_size) { /* If offset really big, any add will overflow. So lets stop early if offset is corrupt. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } /* Determine relocation size */ if (_dwarf_is_32bit_abs_reloc(type, machine)) { reloc_size = 4; } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { reloc_size = 8; } else { *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; return DW_DLV_ERROR; } if ( (offset + reloc_size) < offset) { /* Another check for overflow. */ *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } if ( (offset + reloc_size) > target_section_size) { *error = DW_DLE_RELOC_INVALID; return DW_DLV_ERROR; } { /* Assuming we do not need to do a READ_UNALIGNED here at target_section + offset and add its value to outval. Some ABIs say no read (for example MIPS), but if some do then which ones? */ Dwarf_Unsigned outval = symp->gs_value + addend; /* The 0th byte goes at offset. */ WRITE_UNALIGNED(dbg, target_section + offset, &outval, sizeof(outval), (unsigned long)reloc_size); } return DW_DLV_OK; } /* Somewhat arbitrarily, we attempt to apply all the relocations we can and still notify the caller of at least one error if we found any errors. */ static int apply_rela_entries( Dwarf_Debug dbg, /* Section_index of the relocation section, .rela entries */ Dwarf_Half r_section_index, dwarf_elf_object_access_internals_t*obj, /* relocatablesec is the .debug_info(etc) in Dwarf_Debug */ struct Dwarf_Section_s * relocatablesec, int *error) { int return_res = DW_DLV_OK; struct generic_shdr * rels_shp = 0; Dwarf_Unsigned relcount; Dwarf_Unsigned i = 0; if (r_section_index >= obj->f_loc_shdr.g_count) { *error = DW_DLE_SECTION_INDEX_BAD; return DW_DLV_ERROR; } rels_shp = obj->f_shdr + r_section_index; relcount = rels_shp->gh_relcount; if (!relcount) { /* Nothing to do. */ return DW_DLV_OK; } if (!rels_shp->gh_rels) { /* something wrong. */ *error = DW_DLE_RELOCS_ERROR; return DW_DLV_ERROR; } for (i = 0; i < relcount; i++) { int res = update_entry(dbg,obj, rels_shp->gh_rels+i, relocatablesec->dss_data, relocatablesec->dss_size, error); if (res != DW_DLV_OK) { /* We try to keep going, not stop. */ return_res = res; } } return return_res; } /* Find the section data in dbg and find all the relevant sections. Then do relocations. section_index is the index of a .debug_info (for example) so we have to find the section(s) with relocations targeting section_index. Normally there is exactly one such, though. */ static int elf_relocations_nolibelf(void* obj_in, Dwarf_Half section_index, Dwarf_Debug dbg, int* error) { int res = DW_DLV_ERROR; dwarf_elf_object_access_internals_t*obj = 0; struct Dwarf_Section_s * relocatablesec = 0; unsigned section_with_reloc_records = 0; if (section_index == 0) { return DW_DLV_NO_ENTRY; } obj = (dwarf_elf_object_access_internals_t*)obj_in; /* The section to relocate must already be loaded into memory. This just turns section_index into a pointer to a de_debug_info or other section record in Dwarf_Debug. */ res = find_section_to_relocate(dbg, section_index, &relocatablesec, error); if (res != DW_DLV_OK) { return res; } /* Now we know the Dwarf_Section_s section we need to relocate. So lets find the rela section(s) targeting this. */ /* Sun and possibly others do not always set sh_link in .debug_* sections. So we cannot do full consistency checks. FIXME: This approach assumes there is only one relocation section applying to section section_index! */ section_with_reloc_records = relocatablesec->dss_reloc_index; if (!section_with_reloc_records) { /* Something is wrong. */ *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; return DW_DLV_ERROR; } /* The relocations, if they exist, have been loaded. */ /* The symtab was already loaded. */ if (!obj->f_symtab || !obj->f_symtab_sect_strings) { *error = DW_DLE_DEBUG_SYMTAB_ERR; return DW_DLV_ERROR; } if (obj->f_symtab_sect_index != relocatablesec->dss_reloc_link) { /* Something is wrong. */ *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; return DW_DLV_ERROR; } /* We have all the data we need in memory. */ /* Now we apply the relocs in section_with_reloc_records to the target, relocablesec */ res = apply_rela_entries(dbg,section_with_reloc_records, obj, relocatablesec,error); return res; } void _dwarf_destruct_elf_nlaccess( struct Dwarf_Obj_Access_Interface_s *aip) { dwarf_elf_object_access_internals_t *ep = 0; struct generic_shdr *shp = 0; Dwarf_Unsigned shcount = 0; Dwarf_Unsigned i = 0; ep = (dwarf_elf_object_access_internals_t *)aip->object; free(ep->f_ehdr); shp = ep->f_shdr; shcount = ep->f_loc_shdr.g_count; for(i = 0; i < shcount; ++i,++shp) { free(shp->gh_rels); shp->gh_rels = 0; free(shp->gh_content); shp->gh_content = 0; free(shp->gh_sht_group_array); shp->gh_sht_group_array = 0; shp->gh_sht_group_array_count = 0; } free(ep->f_shdr); ep->f_loc_shdr.g_count = 0; free(ep->f_phdr); free(ep->f_elf_shstrings_data); free(ep->f_dynamic); free(ep->f_symtab_sect_strings); free(ep->f_dynsym_sect_strings); free(ep->f_symtab); free(ep->f_dynsym); /* if TRUE close f_fd on destruct.*/ if (ep->f_destruct_close_fd) { close(ep->f_fd); } ep->f_ident[0] = 'X'; free(ep->f_path); free(ep); free(aip); } int _dwarf_elf_nlsetup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error) { Dwarf_Obj_Access_Interface *binary_interface = 0; dwarf_elf_object_access_internals_t *intfc = 0; int res = DW_DLV_OK; int localerrnum = 0; res = _dwarf_elf_object_access_init( fd, ftype,endian,offsetsize,filesize,access, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } _dwarf_error(NULL, error, localerrnum); return DW_DLV_ERROR; } /* allocates and initializes Dwarf_Debug, generic code */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ _dwarf_destruct_elf_nlaccess(binary_interface); return res; } intfc = binary_interface->object; intfc->f_path = strdup(true_path); return res; } static Dwarf_Obj_Access_Methods const elf_nlmethods = { elf_get_nolibelf_section_info, elf_get_nolibelf_byte_order, elf_get_nolibelf_length_size, elf_get_nolibelf_pointer_size, elf_get_nolibelf_section_count, elf_load_nolibelf_section, elf_relocations_nolibelf }; /* On any error this frees internals argument. */ static int _dwarf_elf_object_access_internals_init( dwarf_elf_object_access_internals_t * internals, int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, int *errcode) { dwarf_elf_object_access_internals_t * intfc = internals; Dwarf_Unsigned i = 0; struct Dwarf_Obj_Access_Interface_s *localdoas; int res = 0; /* Must malloc as _dwarf_destruct_elf_access() forces that due to other uses. */ localdoas = (struct Dwarf_Obj_Access_Interface_s *) malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); if (!localdoas) { free(internals); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); /* E is used with libelf. F with this elf reader. */ intfc->f_ident[0] = 'F'; intfc->f_ident[1] = '1'; intfc->f_fd = fd; intfc->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); intfc->f_offsetsize = offsetsize; intfc->f_pointersize = offsetsize; intfc->f_filesize = filesize; intfc->f_ftype = ftype; intfc->f_destruct_close_fd = FALSE; #ifdef WORDS_BIGENDIAN if (endian == DW_ENDIAN_LITTLE ) { intfc->f_copy_word = _dwarf_memcpy_swap_bytes; intfc->f_endian = DW_OBJECT_LSB; } else { intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; intfc->f_endian = DW_OBJECT_MSB; } #else /* LITTLE ENDIAN */ if (endian == DW_ENDIAN_LITTLE ) { intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; intfc->f_endian = DW_OBJECT_LSB; } else { intfc->f_copy_word = _dwarf_memcpy_swap_bytes; intfc->f_endian = DW_OBJECT_MSB; } #endif /* LITTLE- BIG-ENDIAN */ _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func_nl; /* The following sets f_machine. */ res = _dwarf_load_elf_header(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } /* Not loading progheaders */ res = _dwarf_load_elf_sectheaders(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } /* We are not looking at symbol strings for now. */ res = _dwarf_load_elf_symstr(intfc,errcode); if (res == DW_DLV_ERROR) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } res = _dwarf_load_elf_symtab_symbols(intfc,errcode); if (res == DW_DLV_ERROR) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } for ( i = 1; i < intfc->f_loc_shdr.g_count; ++i) { struct generic_shdr *shp = 0; Dwarf_Unsigned section_type = 0; shp = intfc->f_shdr +i; section_type = shp->gh_type; if (section_type == SHT_RELA) { /* Possibly we should check if the target section is one we care about before loading rela FIXME */ res = _dwarf_load_elf_rela(intfc,i,errcode); if (res == DW_DLV_ERROR) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } } } #if 0 /* Right now we don't need the .rel sections.Maybe later.*/ res = _dwarf_load_elf_rel(intfc,i,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_elf_nlaccess(localdoas); localdoas = 0; return res; } #endif free(localdoas); localdoas = 0; return DW_DLV_OK; } static int _dwarf_elf_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum) { int res = 0; dwarf_elf_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); if (!internals) { *localerrnum = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = _dwarf_elf_object_access_internals_init(internals, fd, ftype, endian, offsetsize, filesize, access, localerrnum); if (res != DW_DLV_OK){ return res; } intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ free(internals); *localerrnum = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &elf_nlmethods; *binary_interface = intfc; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_elfread.h000066400000000000000000000201071361531463500206700ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef READELFOBJ_H #define READELFOBJ_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Use this for rel too. */ struct generic_rela { int gr_isrela; /* 0 means rel, non-zero means rela */ Dwarf_Unsigned gr_offset; Dwarf_Unsigned gr_info; Dwarf_Unsigned gr_sym; /* From info */ Dwarf_Unsigned gr_type; /* From info */ Dwarf_Signed gr_addend; unsigned char gr_type2; /*MIPS64*/ unsigned char gr_type3; /*MIPS64*/ }; /* The following are generic to simplify handling Elf32 and Elf64. Some fields added where the two sizes have different extraction code. */ struct generic_ehdr { unsigned char ge_ident[EI_NIDENT]; Dwarf_Unsigned ge_type; Dwarf_Unsigned ge_machine; Dwarf_Unsigned ge_version; Dwarf_Unsigned ge_entry; Dwarf_Unsigned ge_phoff; Dwarf_Unsigned ge_shoff; Dwarf_Unsigned ge_flags; Dwarf_Unsigned ge_ehsize; Dwarf_Unsigned ge_phentsize; Dwarf_Unsigned ge_phnum; Dwarf_Unsigned ge_shentsize; Dwarf_Unsigned ge_shnum; Dwarf_Unsigned ge_shstrndx; }; struct generic_phdr { Dwarf_Unsigned gp_type; Dwarf_Unsigned gp_flags; Dwarf_Unsigned gp_offset; Dwarf_Unsigned gp_vaddr; Dwarf_Unsigned gp_paddr; Dwarf_Unsigned gp_filesz; Dwarf_Unsigned gp_memsz; Dwarf_Unsigned gp_align; }; struct generic_shdr { Dwarf_Unsigned gh_secnum; Dwarf_Unsigned gh_name; const char * gh_namestring; Dwarf_Unsigned gh_type; Dwarf_Unsigned gh_flags; Dwarf_Unsigned gh_addr; Dwarf_Unsigned gh_offset; Dwarf_Unsigned gh_size; Dwarf_Unsigned gh_link; /* Section index (in an SHT_REL or SHT_RELA section) of the target section from gh_link. Otherwise 0. */ Dwarf_Unsigned gh_reloc_target_secnum; Dwarf_Unsigned gh_info; Dwarf_Unsigned gh_addralign; Dwarf_Unsigned gh_entsize; /* Zero unless content read in. Malloc space of size gh_size, in bytes. For dwarf and strings mainly. free() this if not null*/ char * gh_content; /* If a .rel or .rela section this will point to generic relocation records if such have been loaded. free() this if not null. */ Dwarf_Unsigned gh_relcount; struct generic_rela * gh_rels; /* For SHT_GROUP based grouping, which group is this section in. 0 unknown, 1 DW_GROUP_NUMBER_BASE base DWARF, 2 DW_GROUPNUMBER_DWO dwo sections, 3+ are in an SHT_GROUP. GNU uses this. set with group number (3+) from SHT_GROUP and the flags should have SHF_GROUP set if in SHT_GROUP. Must only be in one group? */ Dwarf_Unsigned gh_section_group_number; /* Content of an SHT_GROUP section as an array of integers. [0] is the version, which can only be one(1) . */ Dwarf_Unsigned * gh_sht_group_array; /* Number of elements in the gh_sht_group_array. */ Dwarf_Unsigned gh_sht_group_array_count; /* TRUE if .debug_info .eh_frame etc. */ char gh_is_dwarf; }; struct generic_dynentry { Dwarf_Unsigned gd_tag; /* gd_val stands in for d_ptr and d_val union, the union adds nothing in practice since we expect ptrsize <= ulongest. */ Dwarf_Unsigned gd_val; Dwarf_Unsigned gd_dyn_file_offset; }; struct generic_symentry { Dwarf_Unsigned gs_name; Dwarf_Unsigned gs_value; Dwarf_Unsigned gs_size; Dwarf_Unsigned gs_info; Dwarf_Unsigned gs_other; Dwarf_Unsigned gs_shndx; /* derived */ Dwarf_Unsigned gs_bind; Dwarf_Unsigned gs_type; }; struct location { const char *g_name; Dwarf_Unsigned g_offset; Dwarf_Unsigned g_count; Dwarf_Unsigned g_entrysize; Dwarf_Unsigned g_totalsize; }; typedef struct elf_filedata_s { /* f_ident[0] == 'E' means it is elf and elf_filedata_s is the struct involved. Other means error/corruption of some kind. f_ident[1] is a version number. Only version 1 is defined. */ char f_ident[8]; char * f_path; /* non-null if known. Must be freed */ int f_fd; int f_machine; /* EM_* */ int f_destruct_close_fd; int f_is_64bit; unsigned f_endian; Dwarf_Unsigned f_filesize; /* Elf size, not DWARF. 32 or 64 */ Dwarf_Small f_offsetsize; Dwarf_Small f_pointersize; int f_ftype; Dwarf_Unsigned f_max_secdata_offset; Dwarf_Unsigned f_max_progdata_offset; void (*f_copy_word) (void *, const void *, unsigned long); struct location f_loc_ehdr; struct generic_ehdr* f_ehdr; struct location f_loc_shdr; struct generic_shdr* f_shdr; struct location f_loc_phdr; struct generic_phdr* f_phdr; char *f_elf_shstrings_data; /* section name strings */ /* length of currentsection. Might be zero..*/ Dwarf_Unsigned f_elf_shstrings_length; /* size of malloc-d space */ Dwarf_Unsigned f_elf_shstrings_max; /* This is the .dynamic section */ struct location f_loc_dynamic; struct generic_dynentry * f_dynamic; Dwarf_Unsigned f_dynamic_sect_index; /* .dynsym, .dynstr */ struct location f_loc_dynsym; struct generic_symentry* f_dynsym; char *f_dynsym_sect_strings; Dwarf_Unsigned f_dynsym_sect_strings_max; Dwarf_Unsigned f_dynsym_sect_strings_sect_index; Dwarf_Unsigned f_dynsym_sect_index; /* .symtab .strtab */ struct location f_loc_symtab; struct generic_symentry* f_symtab; char * f_symtab_sect_strings; Dwarf_Unsigned f_symtab_sect_strings_max; Dwarf_Unsigned f_symtab_sect_strings_sect_index; Dwarf_Unsigned f_symtab_sect_index; /* Starts at 3. 0,1,2 used specially. */ Dwarf_Unsigned f_sg_next_group_number; /* Both the following will be zero unless there are explicit Elf groups. */ Dwarf_Unsigned f_sht_group_type_section_count; Dwarf_Unsigned f_shf_group_flag_section_count; Dwarf_Unsigned f_dwo_group_section_count; } dwarf_elf_object_access_internals_t; int dwarf_construct_elf_access(int fd, const char *path, dwarf_elf_object_access_internals_t **ep,int *errcode); int dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_header(dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_sectheaders(dwarf_elf_object_access_internals_t* ep,int *errcode); int _dwarf_load_elf_symtab_symbols(dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode); int _dwarf_load_elf_rela(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned secnum, int *errcode); #ifndef EI_NIDENT #define EI_NIDENT 16 #endif /* EI_NIDENT */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* READELFOBJ_H */ dwarfutils-20200114/libdwarf/dwarf_elfstructs.h000066400000000000000000000112611361531463500214650ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Typed in from the SystemV Application Binary Interface but using char arrays instead of variables as for reading we don't need the struct members to be variables. This simplifies configure. https://www.uclibc.org/docs/elf-64-gen.pdf used as source of Elf64 fields. It is expected code including this will have included an official (for various definitions needed) before including this. But that is not strictly necessary given other headers. The structs were all officially defined so files could be mapped in. Fields are arranged so there will not be gaps and we need not deal with alignment-gaps. */ #ifndef DW_ELFSTRUCTS_H #define DW_ELFSTRUCTS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef EI_NIDENT #define EI_NIDENT 16 #endif #ifndef TYP #define TYP(n,l) char n[l] #endif typedef struct { unsigned char e_ident[EI_NIDENT]; TYP(e_type,2); TYP(e_machine,2); TYP(e_version,4); TYP(e_entry,4); TYP(e_phoff,4); TYP(e_shoff,4); TYP(e_flags,4); TYP(e_ehsize,2); TYP(e_phentsize,2); TYP(e_phnum,2); TYP(e_shentsize,2); TYP(e_shnum,2); TYP(e_shstrndx,2); } dw_elf32_ehdr; typedef struct { unsigned char e_ident[EI_NIDENT]; TYP(e_type,2); TYP(e_machine,2); TYP(e_version,4); TYP(e_entry,8); TYP(e_phoff,8); TYP(e_shoff,8); TYP(e_flags,4); TYP(e_ehsize,2); TYP(e_phentsize,2); TYP(e_phnum,2); TYP(e_shentsize,2); TYP(e_shnum,2); TYP(e_shstrndx,2); } dw_elf64_ehdr; typedef struct { TYP(p_type,4); TYP(p_offset,4); TYP(p_vaddr,4); TYP(p_paddr,4); TYP(p_filesz,4); TYP(p_memsz,4); TYP(p_flags,4); TYP(p_align,4); } dw_elf32_phdr; typedef struct { TYP(p_type,4); TYP(p_flags,4); TYP(p_offset,8); TYP(p_vaddr,8); TYP(p_paddr,8); TYP(p_filesz,8); TYP(p_memsz,8); TYP(p_align,8); } dw_elf64_phdr; typedef struct { TYP(sh_name,4); TYP(sh_type,4); TYP(sh_flags,4); TYP(sh_addr,4); TYP(sh_offset,4); TYP(sh_size,4); TYP(sh_link,4); TYP(sh_info,4); TYP(sh_addralign,4); TYP(sh_entsize,4); }dw_elf32_shdr; typedef struct { TYP(sh_name,4); TYP(sh_type,4); TYP(sh_flags,8); TYP(sh_addr,8); TYP(sh_offset,8); TYP(sh_size,8); TYP(sh_link,4); TYP(sh_info,4); TYP(sh_addralign,8); TYP(sh_entsize,8); }dw_elf64_shdr; typedef struct { TYP(r_offset,4); TYP(r_info,4); } dw_elf32_rel; typedef struct { TYP(r_offset,8); TYP(r_info,8); } dw_elf64_rel; typedef struct { TYP(r_offset,4); TYP(r_info,4); TYP(r_addend,4); /* signed */ } dw_elf32_rela; typedef struct { TYP(r_offset,8); TYP(r_info,8); TYP(r_addend,8); /* signed */ } dw_elf64_rela; typedef struct { TYP(st_name,4); TYP(st_value,4); TYP(st_size,4); unsigned char st_info[1]; unsigned char st_other[1]; TYP(st_shndx,2); } dw_elf32_sym; typedef struct { TYP(st_name,4); unsigned char st_info[1]; unsigned char st_other[1]; TYP(st_shndx,2); TYP(st_value,8); TYP(st_size,8); } dw_elf64_sym; typedef struct { TYP(d_tag,4); /* signed */ TYP(d_val,4); /* Union in original */ } dw_elf32_dyn; typedef struct { TYP(d_tag,8); /* signed */ TYP(d_val,8); /* Union in original */ } dw_elf64_dyn; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DW_ELFSTRUCTS_H */ dwarfutils-20200114/libdwarf/dwarf_errmsg_list.h000066400000000000000000000672451361531463500216360ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_ERRMSG_LIST_H #define DWARF_ERRMSG_LIST_H /* Array to hold string representation of errors. Any time a define is added to the list in libdwarf.h, a string should be added to this Array Errors in the list (missing a comma, for example) happen too often. Making this a separate little file simplfies testing for missing-commas/extra-strings. String count should match DW_DLE_LAST+1 */ const char *_dwarf_errmsgs[] = { "No error (0)\n", "DW_DLE_VMM (1) dwarf format/library version mismatch", "DW_DLE_MAP (2) memory map failure", "DW_DLE_LEE (3) libelf error", "DW_DLE_NDS (4) no debug section", "DW_DLE_NLS (5) no line section ", "DW_DLE_ID (6) invalid descriptor for query ", "DW_DLE_IOF (7) I/O failure ", "DW_DLE_MAF (8) memory allocation failure ", "DW_DLE_IA (9) invalid argument ", "DW_DLE_MDE (10) mangled debugging entry:libelf detected error", "DW_DLE_MLE (11) mangled line number entry ", "DW_DLE_FNO (12) file not open ", "DW_DLE_FNR (13) file not a regular file ", "DW_DLE_FWA (14) file open with wrong access ", "DW_DLE_NOB (15) not an object file ", "DW_DLE_MOF (16) mangled object file header ", "DW_DLE_EOLL (17) end of location list entries ", "DW_DLE_NOLL (18) no location list section ", "DW_DLE_BADOFF (19) Invalid offset ", "DW_DLE_EOS (20) end of section ", "DW_DLE_ATRUNC (21) abbreviations section appears truncated", "DW_DLE_BADBITC (22) Address size passed to dwarf bad", "DW_DLE_DBG_ALLOC (23) Unable to malloc a Dwarf_Debug structure", "DW_DLE_FSTAT_ERROR (24) The file fd passed to dwarf_init " "cannot be fstat()ed", "DW_DLE_FSTAT_MODE_ERROR (25) The file mode bits do not " "indicate that the file being opened via " "dwarf_init() is a normal file", "DW_DLE_INIT_ACCESS_WRONG (26) A call to dwarf_init had an " "access of other than DW_DLC_READ", "DW_DLE_ELF_BEGIN_ERROR (27) a call to " "elf_begin(... ELF_C_READ_MMAP... ) failed", "DW_DLE_ELF_GETEHDR_ERROR (28) a call to " "elf32_getehdr() or elf64_getehdr() failed", "DW_DLE_ELF_GETSHDR_ERROR (29) a call to " "elf32_getshdr() or elf64_getshdr() failed", "DW_DLE_ELF_STRPTR_ERROR (30) a call to " "elf_strptr() failed trying to get a section name", "DW_DLE_DEBUG_INFO_DUPLICATE (31) Only one .debug_info " "section is allowed", "DW_DLE_DEBUG_INFO_NULL (32) .debug_info section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_ABBREV_DUPLICATE (33) Only one .debug_abbrev " "section is allowed", "DW_DLE_DEBUG_ABBREV_NULL (34) .debug_abbrev section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_ARANGES_DUPLICATE (35) Only one .debug_aranges " "section is allowed", "DW_DLE_DEBUG_ARANGES_NULL (36) .debug_aranges section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_LINE_DUPLICATE (37) Only one .debug_line " "section is allowed", "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc " "section is allowed", "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo " "section is allowed", "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames " "section is allowed", "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_STR_DUPLICATE (45) Only one .debug_str " "section is allowed", "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_CU_LENGTH_ERROR (47)", "DW_DLE_VERSION_STAMP_ERROR (48)", "DW_DLE_ABBREV_OFFSET_ERROR (49)", "DW_DLE_ADDRESS_SIZE_ERROR (50) size too large", "DW_DLE_DEBUG_INFO_PTR_NULL (51)", "DW_DLE_DIE_NULL (52)", "DW_DLE_STRING_OFFSET_BAD (53)", "DW_DLE_DEBUG_LINE_LENGTH_BAD (54)", "DW_DLE_LINE_PROLOG_LENGTH_BAD (55)", "DW_DLE_LINE_NUM_OPERANDS_BAD (56)", "DW_DLE_LINE_SET_ADDR_ERROR (57)", "DW_DLE_LINE_EXT_OPCODE_BAD (58)", "DW_DLE_DWARF_LINE_NULL (59)", "DW_DLE_INCL_DIR_NUM_BAD (60)", "DW_DLE_LINE_FILE_NUM_BAD (61)", "DW_DLE_ALLOC_FAIL (62)", "DW_DLE_NO_CALLBACK_FUNC (63)", "DW_DLE_SECT_ALLOC (64)", "DW_DLE_FILE_ENTRY_ALLOC (65)", "DW_DLE_LINE_ALLOC (66)", "DW_DLE_FPGM_ALLOC (67)", "DW_DLE_INCDIR_ALLOC (68)", "DW_DLE_STRING_ALLOC (69)", "DW_DLE_CHUNK_ALLOC (70)", "DW_DLE_BYTEOFF_ERR (71)", "DW_DLE_CIE_ALLOC (72)", "DW_DLE_FDE_ALLOC (73)", "DW_DLE_REGNO_OVFL (74)", "DW_DLE_CIE_OFFS_ALLOC (75)", "DW_DLE_WRONG_ADDRESS (76)", "DW_DLE_EXTRA_NEIGHBORS (77)", "DW_DLE_WRONG_TAG (78)", "DW_DLE_DIE_ALLOC (79)", "DW_DLE_PARENT_EXISTS (80)", "DW_DLE_DBG_NULL (81)", "DW_DLE_DEBUGLINE_ERROR (82)", "DW_DLE_DEBUGFRAME_ERROR (83)", "DW_DLE_DEBUGINFO_ERROR (84)", "DW_DLE_ATTR_ALLOC (85)", "DW_DLE_ABBREV_ALLOC (86)", "DW_DLE_OFFSET_UFLW (87)", "DW_DLE_ELF_SECT_ERR (88)", "DW_DLE_DEBUG_FRAME_LENGTH_BAD (89)", "DW_DLE_FRAME_VERSION_BAD (90)", "DW_DLE_CIE_RET_ADDR_REG_ERROR (91)", "DW_DLE_FDE_NULL (92)", "DW_DLE_FDE_DBG_NULL (93)", "DW_DLE_CIE_NULL (94)", "DW_DLE_CIE_DBG_NULL (95)", "DW_DLE_FRAME_TABLE_COL_BAD (96)", "DW_DLE_PC_NOT_IN_FDE_RANGE (97)", "DW_DLE_CIE_INSTR_EXEC_ERROR (98)", "DW_DLE_FRAME_INSTR_EXEC_ERROR (99)", "DW_DLE_FDE_PTR_NULL (100)", "DW_DLE_RET_OP_LIST_NULL (101)", "DW_DLE_LINE_CONTEXT_NULL (102)", "DW_DLE_DBG_NO_CU_CONTEXT (103)", "DW_DLE_DIE_NO_CU_CONTEXT (104)", "DW_DLE_FIRST_DIE_NOT_CU (105)", "DW_DLE_NEXT_DIE_PTR_NULL (106)", "DW_DLE_DEBUG_FRAME_DUPLICATE (107) Only one .debug_frame " "section is allowed", "DW_DLE_DEBUG_FRAME_NULL (108) .debug_frame section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_ABBREV_DECODE_ERROR (109)", "DW_DLE_DWARF_ABBREV_NULL (110)", "DW_DLE_ATTR_NULL (111)", "DW_DLE_DIE_BAD (112)", "DW_DLE_DIE_ABBREV_BAD (113)", "DW_DLE_ATTR_FORM_BAD (114)", "DW_DLE_ATTR_NO_CU_CONTEXT (115)", "DW_DLE_ATTR_FORM_SIZE_BAD (116)", "DW_DLE_ATTR_DBG_NULL (117)", "DW_DLE_BAD_REF_FORM (118)", "DW_DLE_ATTR_FORM_OFFSET_BAD (119)", "DW_DLE_LINE_OFFSET_BAD (120)", "DW_DLE_DEBUG_STR_OFFSET_BAD (121)", "DW_DLE_STRING_PTR_NULL (122)", "DW_DLE_PUBNAMES_VERSION_ERROR (123)", "DW_DLE_PUBNAMES_LENGTH_BAD (124)", "DW_DLE_GLOBAL_NULL (125)", "DW_DLE_GLOBAL_CONTEXT_NULL (126)", "DW_DLE_DIR_INDEX_BAD (127)", "DW_DLE_LOC_EXPR_BAD (128)", "DW_DLE_DIE_LOC_EXPR_BAD (129)", "DW_DLE_ADDR_ALLOC (130)", "DW_DLE_OFFSET_BAD (131)", "DW_DLE_MAKE_CU_CONTEXT_FAIL (132)", "DW_DLE_REL_ALLOC (133)", "DW_DLE_ARANGE_OFFSET_BAD (134)", "DW_DLE_SEGMENT_SIZE_BAD (135) Size of a segment selector should usually be less than 8 (bytes).", "DW_DLE_ARANGE_LENGTH_BAD (136)", "DW_DLE_ARANGE_DECODE_ERROR (137)", "DW_DLE_ARANGES_NULL (138)", "DW_DLE_ARANGE_NULL (139)", "DW_DLE_NO_FILE_NAME (140)", "DW_DLE_NO_COMP_DIR (141)", "DW_DLE_CU_ADDRESS_SIZE_BAD (142)", "DW_DLE_INPUT_ATTR_BAD (143)", "DW_DLE_EXPR_NULL (144)", "DW_DLE_BAD_EXPR_OPCODE (145)", "DW_DLE_EXPR_LENGTH_BAD (146)", "DW_DLE_MULTIPLE_RELOC_IN_EXPR (147)", "DW_DLE_ELF_GETIDENT_ERROR (148)", "DW_DLE_NO_AT_MIPS_FDE (149)", "DW_DLE_NO_CIE_FOR_FDE (150)", "DW_DLE_DIE_ABBREV_LIST_NULL (151) No abbrev exists for the requested abbrev code" , "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE (152)", "DW_DLE_DEBUG_FUNCNAMES_NULL (153) .debug_funcnames section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR (154)", "DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD (155)", "DW_DLE_FUNC_NULL (156)", "DW_DLE_FUNC_CONTEXT_NULL (157)", "DW_DLE_DEBUG_TYPENAMES_DUPLICATE (158)", "DW_DLE_DEBUG_TYPENAMES_NULL (159) .debug_typenames section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR (160)", "DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD (161)", "DW_DLE_TYPE_NULL (162)", "DW_DLE_TYPE_CONTEXT_NULL (163)", "DW_DLE_DEBUG_VARNAMES_DUPLICATE (164)", "DW_DLE_DEBUG_VARNAMES_NULL (165) .debug_varnames section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_VARNAMES_VERSION_ERROR (166)", "DW_DLE_DEBUG_VARNAMES_LENGTH_BAD (167)", "DW_DLE_VAR_NULL (168)", "DW_DLE_VAR_CONTEXT_NULL (169)", "DW_DLE_DEBUG_WEAKNAMES_DUPLICATE (170)", "DW_DLE_DEBUG_WEAKNAMES_NULL (171) .debug_weaknames section present but " "elf_getdata() failed or section is zero-length", "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR (172)", "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD (173)", "DW_DLE_WEAK_NULL (174)", "DW_DLE_WEAK_CONTEXT_NULL (175)", "DW_DLE_LOCDESC_COUNT_WRONG (176)", "DW_DLE_MACINFO_STRING_NULL (177)", "DW_DLE_MACINFO_STRING_EMPTY (178)", "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)", "DW_DLE_MACINFO_MALLOC_FAIL (180)", "DW_DLE_DEBUGMACINFO_ERROR (181)", "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_MAX_BAD (183) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185) in .debug_macinfo", "DW_DLE_DEBUG_MACRO_INCONSISTENT (186) in .debug_macinfo", "DW_DLE_DF_NO_CIE_AUGMENTATION(187)", "DW_DLE_DF_REG_NUM_TOO_HIGH(188)", "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)", "DW_DLE_DF_NEW_LOC_LESS_OLD_LOC(190)", "DW_DLE_DF_POP_EMPTY_STACK(191)", "DW_DLE_DF_ALLOC_FAIL(192)", "DW_DLE_DF_FRAME_DECODING_ERROR(193)", "DW_DLE_DEBUG_LOC_SECTION_SHORT(194)", "DW_DLE_FRAME_AUGMENTATION_UNKNOWN(195)", "DW_DLE_PUBTYPE_CONTEXT(196)", "DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD(197)", "DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR(198)", "DW_DLE_DEBUG_PUBTYPES_DUPLICATE(199)", "DW_DLE_FRAME_CIE_DECODE_ERROR(200)", "DW_DLE_FRAME_REGISTER_UNREPRESENTABLE(201)", "DW_DLE_FRAME_REGISTER_COUNT_MISMATCH(202)", "DW_DLE_LINK_LOOP(203)", "DW_DLE_STRP_OFFSET_BAD(204)", "DW_DLE_DEBUG_RANGES_DUPLICATE(205)", "DW_DLE_DEBUG_RANGES_OFFSET_BAD(206)", "DW_DLE_DEBUG_RANGES_MISSING_END(207)", "DW_DLE_DEBUG_RANGES_OUT_OF_MEM(208)", "DW_DLE_DEBUG_SYMTAB_ERR(209)", "DW_DLE_DEBUG_STRTAB_ERR(210)", "DW_DLE_RELOC_MISMATCH_INDEX(211)", "DW_DLE_RELOC_MISMATCH_RELOC_INDEX(212)", "DW_DLE_RELOC_MISMATCH_STRTAB_INDEX(213)", "DW_DLE_RELOC_SECTION_MISMATCH(214)", "DW_DLE_RELOC_SECTION_MISSING_INDEX(215)", "DW_DLE_RELOC_SECTION_LENGTH_ODD(216)", "DW_DLE_RELOC_SECTION_PTR_NULL(217)", "DW_DLE_RELOC_SECTION_MALLOC_FAIL(218)", "DW_DLE_NO_ELF64_SUPPORT(219)", "DW_DLE_MISSING_ELF64_SUPPORT(220)", "DW_DLE_ORPHAN_FDE(221)", "DW_DLE_DUPLICATE_INST_BLOCK(222)", "DW_DLE_BAD_REF_SIG8_FORM(223)", "DW_DLE_ATTR_EXPRLOC_FORM_BAD(224)", "DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD(225)", "DW_DLE_NOT_REF_FORM(226)", "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE(227)", "DW_DLE_REF_SIG8_NOT_HANDLED (228)", "DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH (229)", "DW_DLE_LOC_BAD_TERMINATION (230) the last location operator in an expression is missing some associated data, an operator ended too soon", "DW_DLE_SYMTAB_SECTION_LENGTH_ODD (231) so doing relocations seems unsafe", "DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD (232) so doing a relocation seems unsafe", "DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN (233) so doing a relocation is unsafe", "DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO(234)", "DW_DLE_LINE_NUMBER_HEADER_ERROR (235), a line number program header seems incomplete (perhaps the header_length is wrong?).", "DW_DLE_DEBUG_TYPES_NULL (236)", "DW_DLE_DEBUG_TYPES_DUPLICATE (237)", "DW_DLE_DEBUG_TYPES_ONLY_DWARF4 (238) DW4 and DW5 have types CUs", "DW_DLE_DEBUG_TYPEOFFSET_BAD (239)", "DW_DLE_GNU_OPCODE_ERROR (240)", "DW_DLE_DEBUGPUBTYPES_ERROR (241), could not create pubtypes section", "DW_DLE_AT_FIXUP_NULL (242)", "DW_DLE_AT_FIXUP_DUP (243)", "DW_DLE_BAD_ABINAME (244)", "DW_DLE_TOO_MANY_DEBUG(245), too many .debug_* sections present somehow", "DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE(246)", "DW_DLE_SECTION_DUPLICATION(247)", "DW_DLE_SECTION_ERROR(248)", "DW_DLE_DEBUG_ADDR_DUPLICATE(249)", "DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM(250)", "DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE(251)", "DW_DLE_NEXT_DIE_PAST_END(252)", "DW_DLE_NEXT_DIE_WRONG_FORM(253)", "DW_DLE_NEXT_DIE_NO_ABBREV_LIST(254)", "DW_DLE_NESTED_FORM_INDIRECT_ERROR(255)", "DW_DLE_CU_DIE_NO_ABBREV_LIST(256)", "DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION(257)", "DW_DLE_ATTR_FORM_NOT_ADDR_INDEX(258)", "DW_DLE_ATTR_FORM_NOT_STR_INDEX(259)", "DW_DLE_DUPLICATE_GDB_INDEX(260)", "DW_DLE_ERRONEOUS_GDB_INDEX_SECTION(261) The section is too small", "DW_DLE_GDB_INDEX_COUNT_ERROR(262)", "DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR(263)", "DW_DLE_GDB_INDEX_CUVEC_ERROR(264)", "DW_DLE_GDB_INDEX_INDEX_ERROR(265)", "DW_DLE_DUPLICATE_CU_INDEX(266)", "DW_DLE_DUPLICATE_TU_INDEX(267)", "DW_DLE_XU_TYPE_ARG_ERROR(268) XU means dwarf_cu_ or tu_ index section", "DW_DLE_XU_IMPOSSIBLE_ERROR(269) XU means dwarf_cu_ or tu_ index section", "DW_DLE_XU_NAME_COL_ERROR(270) XU means dwarf_cu_ or tu_ index section", "DW_DLE_XU_HASH_ROW_ERROR(271) XU means dwarf_cu_ or tu_ index section", "DW_DLE_XU_HASH_INDEX_ERROR(272) XU means dwarf_cu_ or tu_ index section", "DW_DLE_FAILSAFE_ERRVAL(273)", "DW_DLE_ARANGE_ERROR(274) producer problem in object generation", "DW_DLE_PUBNAMES_ERROR(275) producer problem in object generation", "DW_DLE_FUNCNAMES_ERROR(276) producer problem in object generation", "DW_DLE_TYPENAMES_ERROR(277) producer problem in object generation", "DW_DLE_VARNAMES_ERROR(278) producer problem in object generation", "DW_DLE_WEAKNAMES_ERROR(279) producer problem in object generation", "DW_DLE_RELOCS_ERROR(280) producer problem in object generation", "DW_DLE_DW_DLE_ATTR_OUTSIDE_SECTION(281)", "DW_DLE_FISSION_INDEX_WRONG(282)", "DW_DLE_FISSION_VERSION_ERROR(283)", "DW_DLE_NEXT_DIE_LOW_ERROR(284) corrupted DIE tree", "DW_DLE_CU_UT_TYPE_ERROR(285) bad DW_UT_* value, corrupt DWARF5", "DW_DLE_NO_SUCH_SIGNATURE_FOUND(286) CU signature not in the index", "DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG(287) libdwarf software error", "DW_DLE_ATTR_FORM_NOT_DATA8(288) wanted an 8 byte signature", "DW_DLE_SIG_TYPE_WRONG_STRING (289) expected tu or cu", "DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH(290) is a broken dwp package file", "DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH(291) is a broken dwp package file", "DW_DLE_DWP_MISSING_DWO_ID(292)", "DW_DLE_DWP_SIBLING_ERROR(293)", "DW_DLE_DEBUG_FISSION_INCOMPLETE(294)", "DW_DLE_FISSION_SECNUM_ERR(295) internal libdwarf error", "DW_DLE_DEBUG_MACRO_DUPLICATE(296)", "DW_DLE_DEBUG_NAMES_DUPLICATE(297)", "DW_DLE_DEBUG_LINE_STR_DUPLICATE(298)", "DW_DLE_DEBUG_SUP_DUPLICATE(299)", "DW_DLE_NO_SIGNATURE_TO_LOOKUP(300)", "DW_DLE_NO_TIED_ADDR_AVAILABLE(301)", "DW_DLE_NO_TIED_SIG_AVAILABLE(302)", "DW_DLE_STRING_NOT_TERMINATED(303) section data may be corrupted", "DW_DLE_BAD_LINE_TABLE_OPERATION(304) two-level line table botch", "DW_DLE_LINE_CONTEXT_BOTCH(305) call is wrong or memory corruption", "DW_DLE_LINE_CONTEXT_INDEX_WRONG(306)", "DW_DLE_NO_TIED_STRING_AVAILABLE(307) tied file does not have the string", "DW_DLE_NO_TIED_FILE_AVAILABLE(308) see dwarf_set_tied_dbg()", "DW_DLE_CU_TYPE_MISSING(309) libdwarf bug or data corruption", "DW_DLE_LLE_CODE_UNKNOWN (310) libdwarf bug or data corruption", "DW_DLE_LOCLIST_INTERFACE_ERROR (311) interface cannot do location or DW_OP*", "DW_DLE_LOCLIST_INDEX_ERROR (312)", "DW_DLE_INTERFACE_NOT_SUPPORTED (313)", "DW_DLE_ZDEBUG_REQUIRES_ZLIB (314) Unable to decompress .zdebug as zlib missing", "DW_DLE_ZDEBUG_INPUT_FORMAT_ODD(315)", "DW_DLE_ZLIB_BUF_ERROR (316) Z_BUF_ERROR buffer size small", "DW_DLE_ZLIB_DATA_ERROR (317) Z_DATA_ERROR compressed data corrupted", "DW_DLE_MACRO_OFFSET_BAD (318)", "DW_DLE_MACRO_OPCODE_BAD (319)", "DW_DLE_MACRO_OPCODE_FORM_BAD (320)", "DW_DLE_UNKNOWN_FORM (321) Possibly corrupt DWARF data", "DW_DLE_BAD_MACRO_HEADER_POINTER(322)", "DW_DLE_BAD_MACRO_INDEX(323)", "DW_DLE_MACRO_OP_UNHANDLED(324) Possibly an implementation extension", "DW_DLE_MACRO_PAST_END(325)", "DW_DLE_LINE_STRP_OFFSET_BAD(326)", "DW_DLE_STRING_FORM_IMPROPER(327) An internal libdwarf logic error", "DW_DLE_ELF_FLAGS_NOT_AVAILABLE(328) elf/non-elf object confusion?", "DW_DLE_LEB_IMPROPER (329) Runs off end of section or CU", "DW_DLE_DEBUG_LINE_RANGE_ZERO (330) Corrupted line section", "DW_DLE_READ_LITTLEENDIAN_ERROR (331) Corrupted dwarfdata littleendian host", "DW_DLE_READ_BIGENDIAN_ERROR (332) Corrupted dwarf data bigendian host", "DW_DLE_RELOC_INVALID (333) relocation corruption", "DW_DLE_INFO_HEADER_ERROR(334) Corrupt dwarf", "DW_DLE_ARANGES_HEADER_ERROR(335) Corrupt dwarf", "DW_DLE_LINE_OFFSET_WRONG_FORM(336) Corrupt dwarf", "DW_DLE_FORM_BLOCK_LENGTH_ERROR(337) Corrupt dwarf", "DW_DLE_ZLIB_SECTION_SHORT (338) Corrupt dwarf", "DW_DLE_CIE_INSTR_PTR_ERROR (339)", "DW_DLE_FDE_INSTR_PTR_ERROR (340)", "DW_DLE_FISSION_ADDITION_ERROR (341) Corrupt dwarf", "DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE (342) Corrupt dwarf", "DW_DLE_LOCEXPR_OFF_SECTION_END (343) Corrupt dwarf", "DW_DLE_POINTER_SECTION_UNKNOWN (344)", "DW_DLE_ERRONEOUS_XU_INDEX_SECTION(345) XU means cu_ or tu_ index", "DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH(346) Inconsistent line table, corrupted.", "DW_DLE_COMPRESSED_EMPTY_SECTION(347) corrupt section data", "DW_DLE_SIZE_WRAPAROUND(348) Impossible string length", "DW_DLE_ILLOGICAL_TSEARCH(349) Impossible sitauation. Corrupted data?", "DW_DLE_BAD_STRING_FORM(350) Not a currently allowed form", "DW_DLE_DEBUGSTR_ERROR(351) problem generating .debug_str section", "DW_DLE_DEBUGSTR_UNEXPECTED_REL(352) string relocation will be wrong.", "DW_DLE_DISCR_ARRAY_ERROR(353) Internal error in dwarf_discr_list()", "DW_DLE_LEB_OUT_ERROR(354) Insufficient buffer to turn integer to leb", "DW_DLE_SIBLING_LIST_IMPROPER(355) Runs off end of section. Corrupt dwarf", "DW_DLE_LOCLIST_OFFSET_BAD(356) Corrupt dwarf", "DW_DLE_LINE_TABLE_BAD(357) Corrupt line table", "DW_DLE_DEBUG_LOClISTS_DUPLICATE(358)", "DW_DLE_DEBUG_RNGLISTS_DUPLICATE(359)", "DW_DLE_ABBREV_OFF_END(360)", "DW_DLE_FORM_STRING_BAD_STRING(361) string runs off end of data", "DW_DLE_AUGMENTATION_STRING_OFF_END(362) augmenation runs off of its section", "DW_DLE_STRING_OFF_END_PUBNAMES_LIKE(363) one of the global sections, string bad", "DW_DLE_LINE_STRING_BAD(364) runs off end of line data", "DW_DLE_DEFINE_FILE_STRING_BAD(365) runs off end of section", "DW_DLE_MACRO_STRING_BAD(366) DWARF5 macro def/undef string runs off section data", "DW_DLE_MACINFO_STRING_BAD(367) DWARF2..4 macro def/undef string runs off section data", "DW_DLE_ZLIB_UNCOMPRESS_ERROR(368) Surely an invalid uncompress length", "DW_DLE_IMPROPER_DWO_ID(369)", "DW_DLE_GROUPNUMBER_ERROR(370) An error determining default target group number", "DW_DLE_ADDRESS_SIZE_ZERO(371)", "DW_DLE_DEBUG_NAMES_HEADER_ERROR(372)", "DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR(373) corrupt dwarf", "DW_DLE_DEBUG_NAMES_PAD_NON_ZERO(374) corrupt dwarf", "DW_DLE_DEBUG_NAMES_OFF_END(375) corrupt dwarf", "DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW(376) Surprising overrun of fixed size array", "DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION(377)", "DW_DLE_DEBUG_NAMES_NULL_POINTER(378) null argument", "DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG(379) index outside valid range", "DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET(380) offset outside entrypool", "DW_DLE_DEBUG_NAMES_UNHANDLED_FORM(381) Might be corrupt dwarf or incomplete DWARF support", "DW_DLE_LNCT_CODE_UNKNOWN(382)", "DW_DLE_LNCT_FORM_CODE_NOT_HANDLED(383) Might be bad form or just not implemented", "DW_DLE_LINE_HEADER_LENGTH_BOTCH(384) Internal libdwarf error", "DW_DLE_STRING_HASHTAB_IDENTITY_ERROR(385) Internal libdwarf error", "DW_DLE_UNIT_TYPE_NOT_HANDLED(386) Possibly incomplete dwarf5 support", "DW_DLE_GROUP_MAP_ALLOC(387) Out of malloc space", "DW_DLE_GROUP_MAP_DUPLICATE(388) Each section # should appear once", "DW_DLE_GROUP_COUNT_ERROR(389) An inconsistency in map entry count", "DW_DLE_GROUP_INTERNAL_ERROR(390) libdwarf data corruption", "DW_DLE_GROUP_LOAD_ERROR(391) corrupt data?", "DW_DLE_GROUP_LOAD_READ_ERROR(392)", "DW_DLE_AUG_DATA_LENGTH_BAD(393) Data does not fit in section", "DW_DLE_ABBREV_MISSING(394) Unable to find abbrev for DIE", "DW_DLE_NO_TAG_FOR_DIE(395)", "DW_DLE_LOWPC_WRONG_CLASS(396) found in dwarf_lowpc()", "DW_DLE_HIGHPC_WRONG_FORM(397) found in dwarf_highpc()", "DW_DLE_STR_OFFSETS_BASE_WRONG_FORM(398)", "DW_DLE_DATA16_OUTSIDE_SECTION(399)", "DW_DLE_LNCT_MD5_WRONG_FORM(400)", "DW_DLE_LINE_HEADER_CORRUPT(401) possible data corruption", "DW_DLE_STR_OFFSETS_NULLARGUMENT(402) improper call", "DW_DLE_STR_OFFSETS_NULL_DBG(403) improper call", "DW_DLE_STR_OFFSETS_NO_MAGIC(404) improper call", "DW_DLE_STR_OFFSETS_ARRAY_SIZE(405) Not a multiple of entry size", "DW_DLE_STR_OFFSETS_VERSION_WRONG(406) Must be 5 ", "DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG(407) Requested outside bound", "DW_DLE_STR_OFFSETS_EXTRA_BYTES(408) Unused non-zero bytes end section", "DW_DLE_DUP_ATTR_ON_DIE(409) Compiler error, object improper DWARF", "DW_DLE_SECTION_NAME_BIG(410) Caller provided insufficient room for section name", "DW_DLE_FILE_UNAVAILABLE(411). Unable find/read object file", "DW_DLE_FILE_WRONG_TYPE(412). Not an object type we recognize.", "DW_DLE_SIBLING_OFFSET_WRONG(413). Corrupt dwarf.", "DW_DLE_OPEN_FAIL(414) Unable to open, possibly a bad filename", "DW_DLE_OFFSET_SIZE(415) Offset size is neither 32 nor 64", "DW_DLE_MACH_O_SEGOFFSET_BAD(416) corrupt object", "DW_DLE_FILE_OFFSET_BAD(417) corrupt object", "DW_DLE_SEEK_ERROR(418). Seek failed, corrupt object", "DW_DLE_READ_ERROR(419). Read failed, corrupt object", "DW_DLE_ELF_CLASS_BAD(420) Corrupt object.", "DW_DLE_ELF_ENDIAN_BAD(421) Corrupt object.", "DW_DLE_ELF_VERSION_BAD(422) Corrupt object.", "DW_DLE_FILE_TOO_SMALL(423) File is too small to be an object file.", "DW_DLE_PATH_SIZE_TOO_SMALL(424) buffer passed to dwarf_object_detector_path is too small.", "DW_DLE_BAD_TYPE_SIZE(425) At compile time the build configured itself improperly.", "DW_DLE_PE_SIZE_SMALL(426) File too small to be valid PE object.", "DW_DLE_PE_OFFSET_BAD(427) Calculated offset too large. Corrupt object.", "DW_DLE_PE_STRING_TOO_LONG(428) Increase size for call.", "DW_DLE_IMAGE_FILE_UNKNOWN_TYPE(429) a PE object has an unknown machine type, not 0x14c, 0x200 or 0x8664", "DW_DLE_LINE_TABLE_LINENO_ERROR(430) Negative line number impossible. Corrupted line table.", "DW_DLE_PRODUCER_CODE_NOT_AVAILABLE(431) Without elf.h the producer code is not available.", "DW_DLE_NO_ELF_SUPPORT(432) libdwarf was compiled without Elf object support.", "DW_DLE_NO_STREAM_RELOC_SUPPORT(433) no elf.h so cannot generate STREAM relocations", "DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR(434) Flag value passed in not allowed.", "DW_DLE_SECTION_SIZE_ERROR(435) Corrupt Elf. Section size not a multiple of section entry size", "DW_DLE_INTERNAL_NULL_POINTER(436) Internal libdwarf call:null pointer", "DW_DLE_SECTION_STRING_OFFSET_BAD(437) Corrupt Elf, an offset to section name is invalid", "DW_DLE_SECTION_INDEX_BAD(438) Corrupt Elf, a section index is incorrect", "DW_DLE_INTEGER_TOO_SMALL(439) Build does not allow reading Elf64", "DW_DLE_ELF_SECTION_LINK_ERROR(440) Corrupt Elf, section links in error", "DW_DLE_ELF_SECTION_GROUP_ERROR(441) Corrupt Elf, section group information problem", "DW_DLE_ELF_SECTION_COUNT_MISMATCH(442) Corrupt Elf or libdwarf bug.", "DW_DLE_ELF_STRING_SECTION_MISSING(443) Corrupt Elf, string section wrong type", "DW_DLE_SEEK_OFF_END(444) Corrupt Elf. Seek past the end not allowed", "DW_DLE_READ_OFF_END(445) Corrupt Elf. A read would read past end of object", "DW_DLE_ELF_SECTION_ERROR(446) Section offset or size is too large. Corrupt elf object.", "DW_DLE_ELF_STRING_SECTION_ERROR(447) String section missing. Corrupt Elf", "DW_DLE_MIXING_SPLIT_DWARF_VERSIONS(448) DWARF5 header signature and DWARF4 DW_AT_[GNU]_dwo_id present in one CU header/die. Corrupt Dwarf.", "DW_DLE_TAG_CORRUPT(449) DW_TAG outside allowed range. Corrupt DWARF.", "DW_DLE_FORM_CORRUPT(450) DW_FORM unknown, too large a value. Corrupt DWARF?", "DW_DLE_ATTR_CORRUPT(451) DW_AT outside allowed range. Corrupt DWARF.", "DW_DLE_ABBREV_ATTR_DUPLICATION(452) Abbreviation list corruption.", "DW_DLE_DWP_SIGNATURE_MISMATCH(453) Impossible signature mismatch. Corrupted Dwarf?", "DW_DLE_CU_UT_TYPE_VALUE(454) Internal libdwarf data corruption", "DW_DLE_DUPLICATE_GNU_DEBUGLINK(455) Duplicated section .gnu_debuglink", "DW_DLE_CORRUPT_GNU_DEBUGLINK(456) Section length wrong", "DW_DLE_CORRUPT_NOTE_GNU_DEBUGID(457) Data corruption in .note.gnu.debugid section", "DW_DLE_CORRUPT_GNU_DEBUGID_SIZE(458) Section .note.gnu.debugid size incorrect", "DW_DLE_CORRUPT_GNU_DEBUGID_STRING(459) Section .note.gnu.debugid ownder string not terminated properly", "DW_DLE_HEX_STRING_ERROR(460). dwarf_producer_init() extras string has a bad hex string", "DW_DLE_DECIMAL_STRING_ERROR(461) dwarf_producer_init() extras string has a bad decimal string", "DW_DLE_PRO_INIT_EXTRAS_UNKNOWN(462) dwarf_producer_init() extras string has an unknown string", "DW_DLE_PRO_INIT_EXTRAS_ERR(463) dwarf_producer_init() extras string has an unexpected space character", "DW_DLE_NULL_ARGS_DWARF_ADD_PATH(464) either Dwarf_Debug or file_path argument to dwarf_add_file_path is NULL.", "DW_DLE_DWARF_INIT_DBG_NULL(465) a dwarf_init*() call the return-dbg argument is null", }; #endif /* DWARF_ERRMSG_LIST_H */ dwarfutils-20200114/libdwarf/dwarf_error.c000066400000000000000000000121071361531463500204130ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarfstring.h" #include "dwarf_error.h" /* Array to hold string representation of errors. Any time a define is added to the list in libdwarf.h, a string should be added to this Array */ #include "dwarf_errmsg_list.h" /* This function performs error handling as described in the libdwarf consumer document section 3. Dbg is the Dwarf_debug structure being processed. Error is a pointer to the pointer to the error descriptor that will be returned. Errval is an error code listed in dwarf_error.h. If the malloc arena is exhausted we return a pointer to a special static error record. This special singleton is mostly ignored by dwarf_dealloc(). Users should not be storing Dwarf_Error pointers for long so this singleton is only going to cause confusion when callers try to save an out-of-memory Dwarf_Error pointer. The _dwarf_failsafe_error is intended to be an improvement over an abort() call. The failsafe means we will not abort due to a Dwarf_Error struct creation. */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval) { _dwarf_error_string(dbg,error,errval,0); } void _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval,char *msg) { Dwarf_Error errptr; /* Allow NULL dbg on entry, since sometimes that can happen and we want to report the upper-level error, not this one. */ if (error != NULL) { /* If dbg is NULL, use the alternate error struct. However, this will overwrite the earlier error. */ if (dbg != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (!errptr) { errptr = &_dwarf_failsafe_error; errptr->er_static_alloc = DE_STATIC; } else { errptr->er_static_alloc = DE_STANDARD; } } else { /* We have no dbg to work with. dwarf_init failed. We hack up a special area. */ errptr = _dwarf_special_no_dbg_error_malloc(); if (!errptr) { errptr = &_dwarf_failsafe_error; errptr->er_static_alloc = DE_STATIC; } else { errptr->er_static_alloc = DE_MALLOC; } } errptr->er_errval = errval; if (msg) { dwarfstring *em = 0; em = (dwarfstring *)calloc(1,sizeof(dwarfstring)); dwarfstring_constructor(em); dwarfstring_append(em,msg); errptr->er_msg = (void*)em; } *error = errptr; return; } if (dbg != NULL && dbg->de_errhand != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (errptr == NULL) { errptr = &_dwarf_failsafe_error; errptr->er_static_alloc = DE_STATIC; } errptr->er_errval = errval; dbg->de_errhand(errptr, dbg->de_errarg); return; } fflush(stdout); fprintf(stdout, "\nNow abort() in libdwarf. " "No error argument or handler available.\n"); fflush(stdout); abort(); } Dwarf_Unsigned dwarf_errno(Dwarf_Error error) { if (!error) { return (0); } return (error->er_errval); } char* dwarf_errmsg_by_number(Dwarf_Unsigned errornum ) { if (errornum >= (Dwarf_Signed)(sizeof(_dwarf_errmsgs) / sizeof(char *))) { return "Dwarf_Error value out of range"; } return ((char *) _dwarf_errmsgs[errornum]); } /* */ char * dwarf_errmsg(Dwarf_Error error) { if (!error) { return "Dwarf_Error is NULL"; } if (error->er_msg) { return dwarfstring_string(error->er_msg); } return dwarf_errmsg_by_number(error->er_errval); } dwarfutils-20200114/libdwarf/dwarf_error.h000066400000000000000000000044051361531463500204220ustar00rootroot00000000000000/* Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_ERROR_H #define DWARF_ERROR_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval); void _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval, char *msg); #define DE_STANDARD 0 /* Normal alloc attached to dbg. */ #define DE_STATIC 1 /* Using global static var */ #define DE_MALLOC 2 /* Using malloc space */ struct Dwarf_Error_s { Dwarf_Signed er_errval; void * er_msg; /* If non-zero the Dwarf_Error_s struct is not malloc'd. To aid when malloc returns NULL. If zero a normal dwarf_dealloc will work. er_static_alloc only accessed by dwarf_alloc.c. If er_static_alloc is 1 in a Dwarf_Error_s struct (set by libdwarf) and client code accidentally turns that 0 to zero through a wild pointer reference (the field is hidden from clients...) then chaos will eventually follow. */ int er_static_alloc; }; extern struct Dwarf_Error_s _dwarf_failsafe_error; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_ERROR_H */ dwarfutils-20200114/libdwarf/dwarf_form.c000066400000000000000000001546031361531463500202350ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarfstring.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_die_deliv.h" #define TRUE 1 #define FALSE 0 /* This code was repeated many times, now it is all in one place. */ static int get_attr_dbg(Dwarf_Debug *dbg, Dwarf_CU_Context * cu_context, Dwarf_Attribute attr, Dwarf_Error *error) { Dwarf_CU_Context cup; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return (DW_DLV_ERROR); } cup = attr->ar_cu_context; if (cup == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return (DW_DLV_ERROR); } if (cup->cc_dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } *cu_context = cup; *dbg = cup->cc_dbg; return DW_DLV_OK; } int dwarf_hasform(Dwarf_Attribute attr, Dwarf_Half form, Dwarf_Bool * return_bool, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res =get_attr_dbg(&dbg,&cu_context, attr,error); if (res != DW_DLV_OK) { return res; } *return_bool = (attr->ar_attribute_form == form); return DW_DLV_OK; } /* Not often called, we do not worry about efficiency here. The dwarf_whatform() call does the sanity checks for us. */ int dwarf_whatform_direct(Dwarf_Attribute attr, Dwarf_Half * return_form, Dwarf_Error * error) { int res = dwarf_whatform(attr, return_form, error); if (res != DW_DLV_OK) { return res; } *return_form = attr->ar_attribute_form_direct; return (DW_DLV_OK); } /* Pass in the content of a block and the length of that content. On success return DW_DLV_OK and set *value_count to the size of the array returned through value_array. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug dbg, Dwarf_Unsigned input_length_in_bytes, void * input_block, Dwarf_Unsigned * value_count, Dwarf_Signed ** value_array, Dwarf_Error * error) { Dwarf_Unsigned output_length_in_units = 0; Dwarf_Signed * output_block = 0; unsigned i = 0; char * ptr = 0; int remain = 0; Dwarf_Signed * array = 0; Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ input_length_in_bytes; output_length_in_units = 0; remain = input_length_in_bytes; ptr = input_block; while (remain > 0) { Dwarf_Unsigned len = 0; Dwarf_Signed value = 0; int rres = 0; rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &value,endptr); if (rres != DW_DLV_OK) { _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER); return DW_DLV_ERROR; } ptr += len; remain -= len; output_length_in_units++; } if (remain != 0) { _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } output_block = (Dwarf_Signed*) _dwarf_get_alloc(dbg, DW_DLA_STRING, output_length_in_units * sizeof(Dwarf_Signed)); if (!output_block) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } array = output_block; remain = input_length_in_bytes; ptr = input_block; for (i=0; i0; i++) { Dwarf_Signed num; Dwarf_Unsigned len; int sres = 0; sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &num,endptr); if (sres != DW_DLV_OK) { dwarf_dealloc(dbg,output_block,DW_DLA_STRING); _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER); return DW_DLV_ERROR; } ptr += len; remain -= len; array[i] = num; } if (remain != 0) { dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } *value_count = output_length_in_units; *value_array = output_block; return DW_DLV_OK; } /* This code was contributed around 2007 and the return value is in the wrong form. See dwarf_uncompress_integer_block_a() above. As of 2019 it is not clear that Sun Sparc compilers are in current use, nor whether there is a reason to make reads of this data format safe from corrupted object files. */ void * dwarf_uncompress_integer_block( Dwarf_Debug dbg, Dwarf_Bool unit_is_signed, Dwarf_Small unit_length_in_bits, void* input_block, Dwarf_Unsigned input_length_in_bytes, Dwarf_Unsigned* output_length_in_units_ptr, Dwarf_Error* error ) { Dwarf_Unsigned output_length_in_units = 0; void * output_block = 0; unsigned i = 0; char * ptr = 0; int remain = 0; /* This only applies to Sun and there an unsigned is 4 bytes so this works. As with most linux. */ unsigned * array = 0; Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ input_length_in_bytes; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return((void *)DW_DLV_BADADDR); } if (unit_is_signed == false || unit_length_in_bits != 32 || input_block == NULL || input_length_in_bytes == 0 || output_length_in_units_ptr == NULL) { _dwarf_error(NULL, error, DW_DLE_BADBITC); return ((void *) DW_DLV_BADADDR); } /* At this point we assume the format is: signed 32 bit */ /* first uncompress everything to find the total size. */ output_length_in_units = 0; remain = input_length_in_bytes; ptr = input_block; while (remain > 0) { Dwarf_Unsigned len = 0; Dwarf_Signed value = 0; int rres = 0; rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &value,endptr); if (rres != DW_DLV_OK) { return ((void *)DW_DLV_BADADDR); } ptr += len; remain -= len; output_length_in_units++; } if (remain != 0) { _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); return((void *)DW_DLV_BADADDR); } /* then alloc */ output_block = (void *) _dwarf_get_alloc(dbg, DW_DLA_STRING, output_length_in_units * (unit_length_in_bits / 8)); if (output_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return((void*)DW_DLV_BADADDR); } /* then uncompress again and copy into new buffer */ array = (unsigned *) output_block; remain = input_length_in_bytes; ptr = input_block; for (i=0; i0; i++) { Dwarf_Signed num; Dwarf_Unsigned len; int sres = 0; sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, &len, &num,endptr); if (sres != DW_DLV_OK) { dwarf_dealloc(dbg,output_block,DW_DLA_STRING); return ((void *) DW_DLV_BADADDR); } ptr += len; remain -= len; array[i] = num; } if (remain != 0) { dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return((Dwarf_P_Attribute)DW_DLV_BADADDR); } *output_length_in_units_ptr = output_length_in_units; return output_block; } void dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space) { dwarf_dealloc(dbg, space, DW_DLA_STRING); } int dwarf_whatform(Dwarf_Attribute attr, Dwarf_Half * return_form, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res =get_attr_dbg(&dbg,&cu_context, attr,error); if (res != DW_DLV_OK) { return res; } *return_form = attr->ar_attribute_form; return (DW_DLV_OK); } /* This function is analogous to dwarf_whatform. It returns the attribute in attr instead of the form. */ int dwarf_whatattr(Dwarf_Attribute attr, Dwarf_Half * return_attr, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res =get_attr_dbg(&dbg,&cu_context, attr,error); if (res != DW_DLV_OK) { return res; } *return_attr = (attr->ar_attribute); return DW_DLV_OK; } /* Convert an offset within the local CU into a section-relative debug_info (or debug_types) offset. See dwarf_global_formref() and dwarf_formref() for additional information on conversion rules. */ int dwarf_convert_to_global_offset(Dwarf_Attribute attr, Dwarf_Off offset, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } switch (attr->ar_attribute_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: /* It is a cu-local offset. Convert to section-global. */ /* It would be nice to put some code to check legality of the offset */ /* cc_debug_offset always has any DWP Package File offset included (when the cu_context created) so there is no extra work for DWP. Globalize the offset */ offset += cu_context->cc_debug_offset; break; case DW_FORM_ref_addr: /* This offset is defined to be debug_info global already, so use this value unaltered. Since a DWP package file is not relocated there is no way that this reference offset to an address in any other CU can be correct for a DWP Package File offset */ break; default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_BAD_REF_FORM. The form " "code is 0x%x which cannot be converted to a global " " offset by " "dwarf_convert_to_global_offset()", attr->ar_attribute_form); _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } *ret_offset = (offset); return DW_DLV_OK; } /* A global offset cannot be returned by this interface: see dwarf_global_formref(). DW_FORM_ref_addr is considered an incorrect form for this call because DW_FORM_ref_addr is a global-offset into the debug_info section. For the same reason DW_FORM_data4/data8 are not returned from this function. For the same reason DW_FORM_sec_offset is not returned from this function, DW_FORM_sec_offset is a global offset (to various sections, not a CU relative offset. DW_FORM_ref_addr has a value which was documented in DWARF2 as address-size but which was always an offset so should have always been offset size (wording corrected in DWARF3). The dwarfstd.org FAQ "How big is a DW_FORM_ref_addr?" suggested all should use offset-size, but that suggestion seems to have been ignored in favor of doing what the DWARF2 and 3 standards actually say. November, 2010: *ret_offset is always set now. Even in case of error. Set to zero for most errors, but for DW_DLE_ATTR_FORM_OFFSET_BAD *ret_offset is set to the bad offset. DW_FORM_addrx DW_FORM_strx DW_FORM_GNU_addr_index DW_FORM_GNU_str_index are not references to .debug_info/.debug_types, so they are not allowed here. */ int dwarf_formref(Dwarf_Attribute attr, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned offset = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Unsigned maximumoffset = 0; int res = DW_DLV_ERROR; Dwarf_Byte_Ptr section_end = 0; *ret_offset = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); switch (attr->ar_attribute_form) { case DW_FORM_ref1: offset = *(Dwarf_Small *) attr->ar_debug_ptr; break; case DW_FORM_ref2: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); break; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); break; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); break; case DW_FORM_ref_udata: { Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr; Dwarf_Unsigned localoffset = 0; DECODE_LEB128_UWORD_CK(ptr,localoffset, dbg,error,section_end); offset = localoffset; break; } case DW_FORM_ref_sig8: /* We cannot handle this here. The reference is to .debug_types not a .debug_info CU local offset. */ _dwarf_error(dbg, error, DW_DLE_REF_SIG8_NOT_HANDLED); return (DW_DLV_ERROR); default: { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, "DW_DLE_BAD_REF_FORM. The form " "code is 0x%x which does not have an offset " " for " "dwarf_formref() to return.", attr->ar_attribute_form); _dwarf_error_string(dbg, error, DW_DLE_BAD_REF_FORM, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } } /* Check that offset is within current cu portion of .debug_info. */ maximumoffset = cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; if (offset >= maximumoffset) { /* For the DW_TAG_compile_unit is legal to have the DW_AT_sibling attribute outside the current cu portion of .debug_info. In other words, sibling points to the end of the CU. It is used for precompiled headers. The valid condition will be: 'offset == maximumoffset'. */ Dwarf_Half tag = 0; int tres = dwarf_tag(attr->ar_die,&tag,error); if (tres != DW_DLV_OK) { if (tres == DW_DLV_NO_ENTRY) { _dwarf_error(dbg, error, DW_DLE_NO_TAG_FOR_DIE); return DW_DLV_ERROR; } return DW_DLV_ERROR; } if (DW_TAG_compile_unit != tag && DW_AT_sibling != attr->ar_attribute && offset > maximumoffset) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); /* Return the incorrect offset for better error reporting */ *ret_offset = (offset); return DW_DLV_ERROR; } } *ret_offset = (offset); return DW_DLV_OK; } static int _dwarf_formsig8_internal(Dwarf_Attribute attr, int formexpected, int formerrnum, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Byte_Ptr field_end = 0; Dwarf_Byte_Ptr section_end = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (attr->ar_attribute_form != formexpected ) { _dwarf_error(dbg, error, formerrnum); return (DW_DLV_ERROR); } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); field_end = attr->ar_debug_ptr + sizeof(Dwarf_Sig8); if (field_end > section_end) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); return (DW_DLV_ERROR); } memcpy(returned_sig_bytes, attr->ar_debug_ptr, sizeof(Dwarf_Sig8)); return DW_DLV_OK; } int dwarf_formsig8_const(Dwarf_Attribute attr, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { int res =_dwarf_formsig8_internal(attr, DW_FORM_data8, DW_DLE_ATTR_FORM_NOT_DATA8, returned_sig_bytes,error); return res; } /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes directly to the caller). Not a string, an 8 byte MD5 hash. This function is new in DWARF4 libdwarf. */ int dwarf_formsig8(Dwarf_Attribute attr, Dwarf_Sig8 * returned_sig_bytes, Dwarf_Error* error) { int res = _dwarf_formsig8_internal(attr, DW_FORM_ref_sig8, DW_DLE_BAD_REF_SIG8_FORM, returned_sig_bytes,error); return res; } /* Since this returns section-relative debug_info offsets, this can represent all REFERENCE forms correctly and allows all applicable forms. DW_FORM_ref_addr has a value which was documented in DWARF2 as address-size but which was always an offset so should have always been offset size (wording corrected in DWARF3). gcc and Go and libdwarf producer code define the length of the value of DW_FORM_ref_addr per the version. So for V2 it is address-size and V3 and later it is offset-size. See the DWARF4 document for the 3 cases fitting reference forms. The caller must determine which section the reference 'points' to. The function added in November 2009, dwarf_get_form_class(), helps in this regard. */ int dwarf_global_formref(Dwarf_Attribute attr, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned offset = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Half context_version = 0; Dwarf_Byte_Ptr section_end = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); context_version = cu_context->cc_version_stamp; switch (attr->ar_attribute_form) { case DW_FORM_ref1: offset = *(Dwarf_Small *) attr->ar_debug_ptr; goto fixoffset; case DW_FORM_ref2: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref_udata: { Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr; Dwarf_Unsigned localoffset = 0; DECODE_LEB128_UWORD_CK(ptr,localoffset, dbg,error,section_end); offset = localoffset; fixoffset: /* we have a local offset, make it global */ /* check legality of offset */ if (offset >= cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); return (DW_DLV_ERROR); } /* globalize the offset */ offset += cu_context->cc_debug_offset; } break; /* The DWARF2 document did not make clear that DW_FORM_data4( and 8) were references with global offsets to some section. That was first clearly documented in DWARF3. In DWARF4 these two forms are no longer references. */ case DW_FORM_data4: if (context_version >= DW_CU_VERSION4) { _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error, section_end); /* The offset is global. */ break; case DW_FORM_data8: if (context_version >= DW_CU_VERSION4) { _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); /* The offset is global. */ break; case DW_FORM_ref_addr: { /* In Dwarf V2 DW_FORM_ref_addr was defined as address-size even though it is a .debug_info offset. Fixed in Dwarf V3 to be offset-size. */ unsigned length_size = 0; if (context_version == 2) { length_size = cu_context->cc_address_size; } else { length_size = cu_context->cc_length_size; } if (length_size == 4) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); } else if (length_size == 8) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); } else { _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); return (DW_DLV_ERROR); } } break; case DW_FORM_sec_offset: case DW_FORM_GNU_ref_alt: /* 2013 GNU extension */ case DW_FORM_GNU_strp_alt: /* 2013 GNU extension */ case DW_FORM_strp_sup: /* DWARF5, sup string section */ case DW_FORM_line_strp: /* DWARF5, .debug_line_str section */ { /* DW_FORM_sec_offset first exists in DWARF4.*/ /* It is up to the caller to know what the offset of DW_FORM_sec_offset, DW_FORM_strp_sup or DW_FORM_GNU_strp_alt etc refer to, the offset is not going to refer to .debug_info! */ unsigned length_size = cu_context->cc_length_size; if (length_size == 4) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); } else if (length_size == 8) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); } else { _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); return (DW_DLV_ERROR); } } break; case DW_FORM_ref_sig8: /* FIXME */ /* We cannot handle this yet. The reference is to .debug_types, and this function only returns an offset in .debug_info at this point. */ _dwarf_error(dbg, error, DW_DLE_REF_SIG8_NOT_HANDLED); return (DW_DLV_ERROR); default: _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); return (DW_DLV_ERROR); } /* We do not know what section the offset refers to, so we have no way to check it for correctness. */ *ret_offset = offset; return DW_DLV_OK; } /* Part of DebugFission. So a consumer can get the index when the object with the actual debug_addr is elsewhere. New May 2014*/ int _dwarf_get_addr_index_itself(int theform, Dwarf_Small *info_ptr, Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Unsigned *val_out, Dwarf_Error * error) { Dwarf_Unsigned index = 0; Dwarf_Byte_Ptr section_end = 0; section_end = _dwarf_calculate_info_section_end_ptr(cu_context); switch(theform){ case DW_FORM_GNU_addr_index: case DW_FORM_addrx: DECODE_LEB128_UWORD_CK(info_ptr,index, dbg,error,section_end); break; case DW_FORM_addrx1: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 1, error,section_end); break; case DW_FORM_addrx2: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 2, error,section_end); break; case DW_FORM_addrx3: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 3, error,section_end); break; case DW_FORM_addrx4: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 4, error,section_end); break; default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX); return DW_DLV_ERROR; } *val_out = index; return DW_DLV_OK; } int dwarf_get_debug_addr_index(Dwarf_Attribute attr, Dwarf_Unsigned * return_index, Dwarf_Error * error) { int theform = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } theform = attr->ar_attribute_form; if (theform == DW_FORM_GNU_addr_index || theform == DW_FORM_addrx) { Dwarf_Unsigned index = 0; res = _dwarf_get_addr_index_itself(theform, attr->ar_debug_ptr,dbg,cu_context,&index,error); *return_index = index; return res; } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX); return DW_DLV_ERROR; } static int dw_read_index_val_itself(Dwarf_Debug dbg, unsigned theform, Dwarf_Small *info_ptr, Dwarf_Small *section_end, Dwarf_Unsigned *return_index, Dwarf_Error *error) { Dwarf_Unsigned index = 0; switch(theform) { case DW_FORM_strx: case DW_FORM_GNU_str_index: DECODE_LEB128_UWORD_CK(info_ptr,index, dbg,error,section_end); break; case DW_FORM_strx1: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 1, error,section_end); break; case DW_FORM_strx2: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 2, error,section_end); break; case DW_FORM_strx3: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 3, error,section_end); break; case DW_FORM_strx4: READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, info_ptr, 4, error,section_end); break; default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_STR_INDEX); return DW_DLV_ERROR; } *return_index = index; return DW_DLV_OK; } /* Part of DebugFission. So a dwarf dumper application can get the index and print it for the user. A convenience function. New May 2014 Also used with DWARF5 forms. */ int dwarf_get_debug_str_index(Dwarf_Attribute attr, Dwarf_Unsigned *return_index, Dwarf_Error *error) { int theform = attr->ar_attribute_form; Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Byte_Ptr section_end = 0; Dwarf_Unsigned index = 0; Dwarf_Small *info_ptr = 0; int indxres = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); info_ptr = attr->ar_debug_ptr; indxres = dw_read_index_val_itself(dbg, theform, info_ptr, section_end, &index,error); if (indxres == DW_DLV_OK) { *return_index = index; return indxres; } return indxres; } int _dwarf_extract_data16(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Small *section_start, Dwarf_Small *section_end, Dwarf_Form_Data16 * returned_val, Dwarf_Error *error) { Dwarf_Small *data16end = 0; data16end = data + sizeof(Dwarf_Form_Data16); if (data < section_start || section_end < data16end) { _dwarf_error(dbg, error,DW_DLE_DATA16_OUTSIDE_SECTION); return DW_DLV_ERROR; } memcpy(returned_val, data, sizeof(Dwarf_Form_Data16)); return DW_DLV_OK; } int dwarf_formdata16(Dwarf_Attribute attr, Dwarf_Form_Data16 * returned_val, Dwarf_Error* error) { Dwarf_Half attrform = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Small *section_end = 0; Dwarf_Unsigned section_length = 0; Dwarf_Small *section_start = 0; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } if (returned_val == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return DW_DLV_ERROR; } attrform = attr->ar_attribute_form; if (attrform != DW_FORM_data16) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return DW_DLV_ERROR; } res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_start = _dwarf_calculate_info_section_start_ptr( cu_context,§ion_length); section_end = section_start + section_length; res = _dwarf_extract_data16(dbg, attr->ar_debug_ptr, section_start, section_end, returned_val, error); return res; } #if 0 case DW_FORM_GNU_addr_index: case DW_FORM_addrx: case DW_FORM_addrx1 : /* DWARF5 */ case DW_FORM_addrx2 : /* DWARF5 */ case DW_FORM_addrx3 : /* DWARF5 */ case DW_FORM_addrx4 : /* DWARF5 */ #endif int dwarf_formaddr(Dwarf_Attribute attr, Dwarf_Addr * return_addr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Addr ret_addr = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Half attrform = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } attrform = attr->ar_attribute_form; if (attrform == DW_FORM_addrx || attrform == DW_FORM_addrx1 || attrform == DW_FORM_addrx2 || attrform == DW_FORM_addrx3 || attrform == DW_FORM_addrx4 || attrform == DW_FORM_GNU_addr_index) { res = _dwarf_look_in_local_and_tied( attrform, cu_context, attr->ar_debug_ptr, return_addr, error); return res; } if (attrform == DW_FORM_addr /* || attrform == DW_FORM_ref_addr Allowance of DW_FORM_ref_addr was a mistake. The value returned in that case is NOT an address it is a global debug_info offset (ie, not CU-relative offset within the CU in debug_info). The Dwarf document refers to it as an address (misleadingly) in sec 6.5.4 where it describes the reference form. It is address-sized so that the linker can easily update it, but it is a reference inside the debug_info section. No longer allowed. */ ) { Dwarf_Small *section_end = _dwarf_calculate_info_section_end_ptr(cu_context); READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr, attr->ar_debug_ptr, cu_context->cc_address_size, error,section_end); *return_addr = ret_addr; return (DW_DLV_OK); } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } int dwarf_formflag(Dwarf_Attribute attr, Dwarf_Bool * ret_bool, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return (DW_DLV_ERROR); } cu_context = attr->ar_cu_context; if (cu_context == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return (DW_DLV_ERROR); } dbg = cu_context->cc_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } if (attr->ar_attribute_form == DW_FORM_flag_present) { /* Implicit means we don't read any data at all. Just the existence of the Form does it. DWARF4. */ *ret_bool = 1; return (DW_DLV_OK); } if (attr->ar_attribute_form == DW_FORM_flag) { *ret_bool = *(Dwarf_Small *)(attr->ar_debug_ptr); return (DW_DLV_OK); } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } Dwarf_Bool _dwarf_allow_formudata(unsigned form) { switch(form) { case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_udata: case DW_FORM_loclistx: return TRUE; } return FALSE; } /* If the form is DW_FORM_constx and the .debug_addr section is missing, this returns DW_DLV_ERROR and the error number in the Dwarf_Error is DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION. When that arises, a consumer should call dwarf_get_debug_addr_index() and use that on the appropriate .debug_addr section in the executable or another object. */ int _dwarf_formudata_internal(Dwarf_Debug dbg, unsigned form, Dwarf_Byte_Ptr data, Dwarf_Byte_Ptr section_end, Dwarf_Unsigned *return_uval, Dwarf_Unsigned *bytes_read, Dwarf_Error *error) { Dwarf_Unsigned ret_value = 0; switch (form) { case DW_FORM_data1: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, sizeof(Dwarf_Small), error,section_end); *return_uval = ret_value; *bytes_read = 1; return DW_DLV_OK; /* READ_UNALIGNED does the right thing as it reads the right number bits and generates host order. So we can just assign to *return_uval. */ case DW_FORM_data2:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, DWARF_HALF_SIZE, error,section_end); *return_uval = ret_value; *bytes_read = 2; return DW_DLV_OK; } case DW_FORM_data4:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, DWARF_32BIT_SIZE, error,section_end); *return_uval = ret_value; *bytes_read = DWARF_32BIT_SIZE;; return DW_DLV_OK; } case DW_FORM_data8:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, data, DWARF_64BIT_SIZE, error,section_end); *return_uval = ret_value; *bytes_read = DWARF_64BIT_SIZE; return DW_DLV_OK; } break; /* real udata */ case DW_FORM_loclistx: case DW_FORM_udata: { Dwarf_Unsigned leblen = 0; DECODE_LEB128_UWORD_LEN_CK(data, ret_value,leblen, dbg,error,section_end); *return_uval = ret_value; *bytes_read = leblen; return DW_DLV_OK; } /* IRIX bug 583450. We do not allow reading sdata from a udata value. Caller can retry, calling sdata */ default: break; } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } int dwarf_formudata(Dwarf_Attribute attr, Dwarf_Unsigned * return_uval, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Byte_Ptr section_end = 0; Dwarf_Unsigned bytes_read = 0; Dwarf_Byte_Ptr data = attr->ar_debug_ptr; unsigned form = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); form = attr->ar_attribute_form; res = _dwarf_formudata_internal(dbg, form, data, section_end, return_uval, &bytes_read, error); return res; } int dwarf_formsdata(Dwarf_Attribute attr, Dwarf_Signed * return_sval, Dwarf_Error * error) { Dwarf_Signed ret_value = 0; Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Byte_Ptr section_end = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); switch (attr->ar_attribute_form) { case DW_FORM_data1: if ( attr->ar_debug_ptr >= section_end) { _dwarf_error(dbg, error, DW_DLE_DIE_BAD); return DW_DLV_ERROR; } *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_ptr); return DW_DLV_OK; /* READ_UNALIGNED does not sign extend. So we have to use a cast to get the value sign extended in the right way for each case. */ case DW_FORM_data2:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); *return_sval = (Dwarf_Shalf) ret_value; return DW_DLV_OK; } case DW_FORM_data4:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); SIGN_EXTEND(ret_value,DWARF_32BIT_SIZE); *return_sval = (Dwarf_Signed) ret_value; return DW_DLV_OK; } case DW_FORM_data8:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); /* No SIGN_EXTEND needed, we are filling all bytes already.*/ *return_sval = (Dwarf_Signed) ret_value; return DW_DLV_OK; } /* DW_FORM_implicit_const is a value in the abbreviations, not in the DIEs. */ case DW_FORM_implicit_const: *return_sval = attr->ar_implicit_const; return DW_DLV_OK; case DW_FORM_sdata: { Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; DECODE_LEB128_SWORD_CK(tmp, ret_value, dbg,error,section_end); *return_sval = ret_value; return DW_DLV_OK; } /* IRIX bug 583450. We do not allow reading sdata from a udata value. Caller can retry, calling udata */ default: break; } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return DW_DLV_ERROR; } int dwarf_formblock(Dwarf_Attribute attr, Dwarf_Block ** return_block, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; Dwarf_Unsigned length = 0; Dwarf_Small *data = 0; Dwarf_Block *ret_block = 0; Dwarf_Small *section_start = 0; Dwarf_Small *section_end = 0; Dwarf_Unsigned section_length = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); section_start = _dwarf_calculate_info_section_start_ptr(cu_context,§ion_length); switch (attr->ar_attribute_form) { case DW_FORM_block1: length = *(Dwarf_Small *) attr->ar_debug_ptr; data = attr->ar_debug_ptr + sizeof(Dwarf_Small); break; case DW_FORM_block2: READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); data = attr->ar_debug_ptr + DWARF_HALF_SIZE; break; case DW_FORM_block4: READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned, attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); data = attr->ar_debug_ptr + DWARF_32BIT_SIZE; break; case DW_FORM_block: { Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; Dwarf_Unsigned leblen = 0; DECODE_LEB128_UWORD_LEN_CK(tmp, length, leblen, dbg,error,section_end); data = attr->ar_debug_ptr + leblen; break; } default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } if (length >= section_length) { /* Sanity test looking for wraparound: when length actually added in it would not be caught. Test could be just >, but >= ok here too.*/ _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); return (DW_DLV_ERROR); } if ((attr->ar_debug_ptr + length) > section_end) { _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); return (DW_DLV_ERROR); } if (data > section_end) { _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); return (DW_DLV_ERROR); } if ((data + length) > section_end) { _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); return (DW_DLV_ERROR); } ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1); if (ret_block == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } ret_block->bl_len = length; ret_block->bl_data = (Dwarf_Ptr) data; ret_block->bl_from_loclist = 0; ret_block->bl_section_offset = data - section_start; *return_block = ret_block; return (DW_DLV_OK); } int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Small *data_ptr, Dwarf_Small *end_data_ptr, UNUSEDARG Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, Dwarf_Unsigned *str_sect_offset_out, Dwarf_Error *error) { Dwarf_Unsigned offset_base = 0; Dwarf_Unsigned index_to_offset_entry = 0; Dwarf_Unsigned offsetintable = 0; Dwarf_Unsigned end_offsetintable = 0; int res = 0; int idxres = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); if (res != DW_DLV_OK) { return res; } idxres = dw_read_index_val_itself(dbg, attrform,data_ptr,end_data_ptr,&index_to_offset_entry,error); if ( idxres != DW_DLV_OK) { return idxres; } /* DW_FORM_GNU_str_index has no 'base' value. DW_FORM_strx* has a base value for the offset table */ if( attrform != DW_FORM_GNU_str_index) { res = _dwarf_get_string_base_attr_value(dbg,cu_context, &offset_base,error); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY could be acceptable when a producer knows that the base offset will be zero. Hence DW_AT_str_offsets_base missing. DWARF5 draft as of September 2015 allows the attribute to be missing (it's up to the compilation tools to make sure that has the correct effect). */ return res; } } offsetintable = (index_to_offset_entry*cu_context->cc_length_size ) + offset_base; { Dwarf_Unsigned fissoff = 0; Dwarf_Unsigned size = 0; fissoff = _dwarf_get_dwp_extra_offset(&cu_context->cc_dwp_offsets, DW_SECT_STR_OFFSETS, &size); offsetintable += fissoff; } end_offsetintable = offsetintable + cu_context->cc_length_size; /* The offsets table is a series of offset-size entries. The == case in the test applies when we are at the last table entry, so == is not an error, hence only test > */ if (end_offsetintable > dbg->de_debug_str_offsets.dss_size ) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); return (DW_DLV_ERROR); } { Dwarf_Unsigned offsettostr = 0; Dwarf_Small *offsets_start = dbg->de_debug_str_offsets.dss_data; Dwarf_Small *offsets_end = offsets_start + dbg->de_debug_str_offsets.dss_size; /* Now read the string offset from the offset table. */ READ_UNALIGNED_CK(dbg,offsettostr,Dwarf_Unsigned, offsets_start+ offsetintable, cu_context->cc_length_size,error,offsets_end); *str_sect_offset_out = offsettostr; } return DW_DLV_OK; } int _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, unsigned attrform, Dwarf_Unsigned offset, char ** return_str, Dwarf_Error * error) { if (attrform == DW_FORM_strp || attrform == DW_FORM_line_strp || attrform == DW_FORM_GNU_str_index || attrform == DW_FORM_strx1 || attrform == DW_FORM_strx2 || attrform == DW_FORM_strx3 || attrform == DW_FORM_strx4 || attrform == DW_FORM_strx) { /* The 'offset' into .debug_str or .debug_line_str is given, here we turn that into a pointer. */ Dwarf_Small *secend = 0; Dwarf_Small *secbegin = 0; Dwarf_Small *strbegin = 0; Dwarf_Unsigned secsize = 0; int errcode = 0; int res = 0; if(attrform == DW_FORM_line_strp) { res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error); if (res != DW_DLV_OK) { return res; } errcode = DW_DLE_STRP_OFFSET_BAD; secsize = dbg->de_debug_line_str.dss_size; secbegin = dbg->de_debug_line_str.dss_data; strbegin= dbg->de_debug_line_str.dss_data + offset; } else { /* DW_FORM_strp etc */ res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; } errcode = DW_DLE_STRING_OFFSET_BAD; secsize = dbg->de_debug_str.dss_size; secbegin = dbg->de_debug_str.dss_data; strbegin= dbg->de_debug_str.dss_data + offset; secend = dbg->de_debug_str.dss_data + secsize; } if (offset >= secsize) { /* Badly damaged DWARF here. */ _dwarf_error(dbg, error, errcode); return (DW_DLV_ERROR); } res= _dwarf_check_string_valid(dbg,secbegin,strbegin, secend, errcode,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *)strbegin; return DW_DLV_OK; } _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } /* Contrary to pre-2005 documentation, The string pointer returned thru return_str must never have dwarf_dealloc() applied to it. Documentation fixed July 2005. */ int dwarf_formstring(Dwarf_Attribute attr, char **return_str, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Debug dbg = 0; Dwarf_Unsigned offset = 0; int res = DW_DLV_ERROR; Dwarf_Small *secdataptr = 0; Dwarf_Small *secend = 0; Dwarf_Unsigned secdatalen = 0; Dwarf_Small *infoptr = attr->ar_debug_ptr; Dwarf_Small *contextend = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (cu_context->cc_is_info) { secdataptr = (Dwarf_Small *)dbg->de_debug_info.dss_data; secdatalen = dbg->de_debug_info.dss_size; } else { secdataptr = (Dwarf_Small *)dbg->de_debug_types.dss_data; secdatalen = dbg->de_debug_types.dss_size; } contextend = secdataptr + cu_context->cc_debug_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; secend = secdataptr + secdatalen; if (contextend < secend) { secend = contextend; } switch(attr->ar_attribute_form) { case DW_FORM_string: { Dwarf_Small *begin = attr->ar_debug_ptr; res= _dwarf_check_string_valid(dbg,secdataptr,begin, secend, DW_DLE_FORM_STRING_BAD_STRING,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *) (begin); return DW_DLV_OK; } case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: { Dwarf_Error alterr = 0; /* See dwarfstd.org issue 120604.1 This is the offset in the .debug_str section of another object file. The 'tied' file notion should apply. It is not clear whether both a supplementary and a split object might be needed at the same time (hence two 'tied' files simultaneously). */ Dwarf_Off soffset = 0; res = dwarf_global_formref(attr, &soffset,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_get_string_from_tied(dbg, soffset, return_str, &alterr); if (res == DW_DLV_ERROR) { if (dwarf_errno(alterr) == DW_DLE_NO_TIED_FILE_AVAILABLE) { dwarf_dealloc(dbg,alterr,DW_DLA_ERROR); if( attr->ar_attribute_form == DW_FORM_GNU_strp_alt) { *return_str = (char *)""; } else { *return_str = (char *)""; } return DW_DLV_OK; } if (error) { *error = alterr; } return res; } if (res == DW_DLV_NO_ENTRY) { if( attr->ar_attribute_form == DW_FORM_GNU_strp_alt) { *return_str = (char *)""; }else { *return_str = (char *)""; } } return res; } case DW_FORM_GNU_str_index: case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: case DW_FORM_strx3: case DW_FORM_strx4: { Dwarf_Unsigned offsettostr= 0; res = _dwarf_extract_string_offset_via_str_offsets(dbg, infoptr, secend, attr->ar_attribute, attr->ar_attribute_form, cu_context, &offsettostr, error); if (res != DW_DLV_OK) { return res; } offset = offsettostr; break; } case DW_FORM_strp: case DW_FORM_line_strp:{ READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, infoptr, cu_context->cc_length_size,error,secend); break; } default: _dwarf_error(dbg, error, DW_DLE_STRING_FORM_IMPROPER); return DW_DLV_ERROR; } /* Now we have offset so read the string from debug_str or debug_line_str. */ res = _dwarf_extract_local_debug_str_string_given_offset(dbg, attr->ar_attribute_form, offset, return_str, error); return res; } int _dwarf_get_string_from_tied(Dwarf_Debug dbg, Dwarf_Unsigned offset, char **return_str, Dwarf_Error*error) { Dwarf_Debug tieddbg = 0; Dwarf_Small *secend = 0; Dwarf_Small *secbegin = 0; Dwarf_Small *strbegin = 0; int res = DW_DLV_ERROR; Dwarf_Error localerror = 0; /* Attach errors to dbg, not tieddbg. */ tieddbg = dbg->de_tied_data.td_tied_object; if (!tieddbg) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE); return DW_DLV_ERROR; } /* The 'offset' into .debug_str is set. */ res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str,&localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); _dwarf_error(dbg,error,lerrno); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } if (offset >= tieddbg->de_debug_str.dss_size) { /* Badly damaged DWARF here. */ _dwarf_error(dbg, error, DW_DLE_NO_TIED_STRING_AVAILABLE); return (DW_DLV_ERROR); } secbegin = tieddbg->de_debug_str.dss_data; strbegin= tieddbg->de_debug_str.dss_data + offset; secend = tieddbg->de_debug_str.dss_data + tieddbg->de_debug_str.dss_size; /* Ensure the offset lies within the .debug_str */ if (offset >= tieddbg->de_debug_str.dss_size) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_STRING_AVAILABLE); return (DW_DLV_ERROR); } res= _dwarf_check_string_valid(tieddbg,secbegin,strbegin, secend, DW_DLE_NO_TIED_STRING_AVAILABLE, &localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); _dwarf_error(dbg,error,lerrno); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } *return_str = (char *) (tieddbg->de_debug_str.dss_data + offset); return DW_DLV_OK; } int dwarf_formexprloc(Dwarf_Attribute attr, Dwarf_Unsigned * return_exprlen, Dwarf_Ptr * block_ptr, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context cu_context = 0; int res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { return res; } if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } if (attr->ar_attribute_form == DW_FORM_exprloc ) { Dwarf_Die die = 0; Dwarf_Unsigned leb_len = 0; Dwarf_Byte_Ptr section_start = 0; Dwarf_Unsigned section_len = 0; Dwarf_Byte_Ptr section_end = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Unsigned exprlen = 0; Dwarf_Small * addr = attr->ar_debug_ptr; info_ptr = addr; section_start = _dwarf_calculate_info_section_start_ptr(cu_context, §ion_len); section_end = section_start + section_len; DECODE_LEB128_UWORD_LEN_CK(info_ptr, exprlen, leb_len, dbg,error,section_end); if (exprlen > section_len) { /* Corrupted dwarf! */ _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); return DW_DLV_ERROR; } die = attr->ar_die; /* Is the block entirely in the section, or is there bug somewhere? Here the final addr may be 1 past end of section. */ if (_dwarf_reference_outside_section(die, (Dwarf_Small *)addr, ((Dwarf_Small *)addr)+exprlen +leb_len)) { _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); return DW_DLV_ERROR; } *return_exprlen = exprlen; *block_ptr = addr + leb_len; return DW_DLV_OK; } _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD); return (DW_DLV_ERROR); } dwarfutils-20200114/libdwarf/dwarf_frame.c000066400000000000000000002632561361531463500203710ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_arange.h" /* Using Arange as a way to build a list */ #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg ) \ do { \ if ((fde) == NULL) { \ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);\ return (DW_DLV_ERROR); \ } \ (dbg)= (fde)->fd_dbg; \ if ((dbg) == NULL) { \ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\ return (DW_DLV_ERROR); \ } } while (0) #define MIN(a,b) (((a) < (b))? a:b) #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif /* 0 */ static int dwarf_initialize_fde_table(Dwarf_Debug dbg, struct Dwarf_Frame_s *fde_table, unsigned table_real_data_size, Dwarf_Error * error); static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table); static void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base, unsigned first, unsigned last,int initial_value); static void dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base, unsigned first, unsigned last,int initial_value); static void dwarf_init_reg_rules_dw3(struct Dwarf_Regtable_Entry3_s *base, unsigned first, unsigned last,int initial_value); #if 0 /* FOR DEBUGGING */ /* Only used for debugging libdwarf. */ static void dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule); #endif int dwarf_get_frame_section_name(Dwarf_Debug dbg, const char **sec_name, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_frame; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name = sec->dss_name; return DW_DLV_OK; } int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg, const char **sec_name, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_frame_eh_gnu; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name = sec->dss_name; return DW_DLV_OK; } /* This function is the heart of the debug_frame stuff. Don't even think of reading this without reading both the Libdwarf and consumer API carefully first. This function basically executes frame instructions contained in a Cie or an Fde, but does in a number of different ways depending on the information sought. Start_instr_ptr points to the first byte of the frame instruction stream, and final_instr_ptr to the to the first byte after the last. The offsets returned in the frame instructions are factored. That is they need to be multiplied by either the code_alignment_factor or the data_alignment_factor, as appropriate to obtain the actual offset. This makes it possible to expand an instruction stream without the corresponding Cie. However, when an Fde frame instr sequence is being expanded there must be a valid Cie with a pointer to an initial table row. If successful, returns DW_DLV_OK And sets returned_count thru the pointer if make_instr is true. If make_instr is false returned_count should NOT be used by the caller (returned_count is set to 0 thru the pointer by this routine...) If unsuccessful, returns DW_DLV_ERROR and sets returned_error to the error code It does not do a whole lot of input validation being a private function. Please make sure inputs are valid. (1) If make_instr is true, it makes a list of pointers to Dwarf_Frame_Op structures containing the frame instructions executed. A pointer to this list is returned in ret_frame_instr. Make_instr is true only when a list of frame instructions is to be returned. In this case since we are not interested in the contents of the table, the input Cie can be NULL. This is the only case where the inpute Cie can be NULL. (2) If search_pc is true, frame instructions are executed till either a location is reached that is greater than the search_pc_val provided, or all instructions are executed. At this point the last row of the table generated is returned in a structure. A pointer to this structure is supplied in table. (3) This function is also used to create the initial table row defined by a Cie. In this case, the Dwarf_Cie pointer cie, is NULL. For an FDE, however, cie points to the associated Cie. (4) If search_pc is true and (has_more_rows and subsequent_pc are non-null) then: has_more_rows is set true if there are instruction bytes following the detection of search_over. If all the instruction bytes have been seen then *has_more_rows is set false. If *has_more_rows is true then *subsequent_pc is set to the pc value that is the following row in the table. make_instr - make list of frame instr? 0/1 ret_frame_instr - Ptr to list of ptrs to frame instrs search_pc - Search for a pc value? 0/1 search_pc_val - Search for this pc value initial_loc - Initial code location value. start_instr_ptr - Ptr to start of frame instrs. final_instr_ptr - Ptr just past frame instrs. table - Ptr to struct with last row. cie - Ptr to Cie used by the Fde. Different cies may have distinct address-sizes, so the cie is used, not de_pointer_size. */ int _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Frame_Op ** ret_frame_instr, Dwarf_Bool search_pc, Dwarf_Addr search_pc_val, Dwarf_Addr initial_loc, Dwarf_Small * start_instr_ptr, Dwarf_Small * final_instr_ptr, Dwarf_Frame table, Dwarf_Cie cie, Dwarf_Debug dbg, Dwarf_Half reg_num_of_cfa, Dwarf_Signed * returned_count, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error *error) { /* The following macro depends on macreg and machigh_reg both being unsigned to avoid unintended behavior and to avoid compiler warnings when high warning levels are turned on. */ #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg) \ do { \ if ((macreg) >= (machigh_reg)) { \ SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \ } \ } /*CONSTCOND */ while (0) #define SIMPLE_ERROR_RETURN(code) \ free(localregtab); \ _dwarf_error(dbg,error,code); \ return DW_DLV_ERROR /* Sweeps the frame instructions. */ Dwarf_Small *instr_ptr; /* Register numbers not limited to just 255, thus not using Dwarf_Small. */ typedef unsigned reg_num_type; Dwarf_Unsigned factored_N_value; Dwarf_Signed signed_factored_N_value; Dwarf_Addr current_loc = initial_loc; /* code location/ pc-value corresponding to the frame instructions. Starts at zero when the caller has no value to pass in. */ /* Must be min de_pointer_size bytes and must be at least 4 */ Dwarf_Unsigned adv_loc = 0; unsigned reg_count = dbg->de_frame_reg_rules_entry_count; struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count, sizeof(struct Dwarf_Reg_Rule_s)); struct Dwarf_Reg_Rule_s cfa_reg; /* This is used to end executing frame instructions. */ /* Becomes true when search_pc is true and current_loc */ /* is greater than search_pc_val. */ Dwarf_Bool search_over = false; Dwarf_Addr possible_subsequent_pc = 0; /* Used by the DW_FRAME_advance_loc instr */ /* to hold the increment in pc value. */ Dwarf_Addr adv_pc; Dwarf_Half address_size = (cie)? cie->ci_address_size: dbg->de_pointer_size; /* Counts the number of frame instructions executed. */ Dwarf_Unsigned instr_count = 0; /* These contain the current fields of the current frame instruction. */ Dwarf_Small fp_base_op = 0; Dwarf_Small fp_extended_op; reg_num_type fp_register; /* The value in fp_offset may be signed, though we call it unsigned. This works ok for 2-s complement arithmetic. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; /* Stack_table points to the row (Dwarf_Frame ie) being pushed or popped by a remember or restore instruction. Top_stack points to the top of the stack of rows. */ Dwarf_Frame stack_table = NULL; Dwarf_Frame top_stack = NULL; /* These are used only when make_instr is true. Curr_instr is a pointer to the current frame instruction executed. Curr_instr_ptr, head_instr_list, and curr_instr_list are used to form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is used to deallocate the structs used to form the chain. Head_instr_block points to a contiguous list of pointers to the Dwarf_Frame_Op structs executed. */ Dwarf_Frame_Op *curr_instr; Dwarf_Chain curr_instr_item, dealloc_instr_item; Dwarf_Chain head_instr_chain = NULL; Dwarf_Chain tail_instr_chain = NULL; Dwarf_Frame_Op *head_instr_block; /* These are the alignment_factors taken from the Cie provided. When no input Cie is provided they are set to 1, because only factored offsets are required. */ Dwarf_Signed code_alignment_factor = 1; Dwarf_Signed data_alignment_factor = 1; /* This flag indicates when an actual alignment factor is needed. So if a frame instruction that computes an offset using an alignment factor is encountered when this flag is set, an error is returned because the Cie did not have a valid augmentation. */ Dwarf_Bool need_augmentation = false; Dwarf_Unsigned i; /* Initialize first row from associated Cie. Using temp regs explicity */ if (localregtab == 0) { SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL); } { struct Dwarf_Reg_Rule_s *t1reg = localregtab; if (cie != NULL && cie->ci_initial_table != NULL) { unsigned minregcount = 0; unsigned curreg = 0; struct Dwarf_Reg_Rule_s *t2reg = cie->ci_initial_table->fr_reg; if (reg_count != cie->ci_initial_table->fr_reg_count) { /* Should never happen, it makes no sense to have the table sizes change. There is no real allowance for the set of registers to change dynamically in a single Dwarf_Debug (except the size can be set near initial Dwarf_Debug creation time). */ SIMPLE_ERROR_RETURN (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH); } minregcount = MIN(reg_count,cie->ci_initial_table->fr_reg_count); for (; curreg < minregcount ;curreg++, t1reg++, t2reg++) { *t1reg = *t2reg; } cfa_reg = cie->ci_initial_table->fr_cfa_rule; } else { dwarf_init_reg_rules_ru(localregtab,0,reg_count, dbg->de_frame_rule_initial_value); dwarf_init_reg_rules_ru(&cfa_reg,0, 1, dbg->de_frame_rule_initial_value); } } /* The idea here is that the code_alignment_factor and data_alignment_factor which are needed for certain instructions are valid only when the Cie has a proper augmentation string. So if the augmentation is not right, only Frame instruction can be read. */ if (cie != NULL && cie->ci_augmentation != NULL) { code_alignment_factor = cie->ci_code_alignment_factor; data_alignment_factor = cie->ci_data_alignment_factor; } else { need_augmentation = !make_instr; } instr_ptr = start_instr_ptr; while ((instr_ptr < final_instr_ptr) && (!search_over)) { Dwarf_Small instr = 0; Dwarf_Small opcode = 0; reg_num_type reg_no = 0; fp_instr_offset = instr_ptr - start_instr_ptr; instr = *(Dwarf_Small *) instr_ptr; instr_ptr += sizeof(Dwarf_Small); fp_base_op = (instr & 0xc0) >> 6; if ((instr & 0xc0) == 0x00) { opcode = instr; /* is really extended op */ fp_extended_op = (instr & (~(0xc0))) & 0xff; } else { opcode = instr & 0xc0; /* is base op */ fp_extended_op = 0; } fp_register = 0; fp_offset = 0; switch (opcode) { case DW_CFA_advance_loc: { /* base op */ fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_pc = adv_pc * code_alignment_factor; possible_subsequent_pc = current_loc + adv_pc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_offset: { /* base op */ reg_no = (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK); ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value, dbg,error,final_instr_ptr); fp_register = reg_no; fp_offset = factored_N_value; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_offset_or_block_len = factored_N_value * data_alignment_factor; break; } case DW_CFA_restore: { /* base op */ reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK); ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); fp_register = reg_no; if (cie != NULL && cie->ci_initial_table != NULL) localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; else if (!make_instr) { SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT); } break; } case DW_CFA_set_loc: { Dwarf_Addr new_loc = 0; READ_UNALIGNED_CK(dbg, new_loc, Dwarf_Addr, instr_ptr, address_size, error,final_instr_ptr); instr_ptr += address_size; if (new_loc != 0 && current_loc != 0) { /* Pre-relocation or before current_loc is set the test comparing new_loc and current_loc makes no sense. Testing for non-zero (above) is a way (fallible) to check that current_loc, new_loc are already relocated. */ if (new_loc <= current_loc) { /* Within a frame, address must increase. Seemingly it has not. Seems to be an error. */ SIMPLE_ERROR_RETURN (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC); } } search_over = search_pc && (new_loc > search_pc_val); /* If gone past pc needed, retain old pc. */ possible_subsequent_pc = new_loc; if (!search_over) { current_loc = possible_subsequent_pc; } fp_offset = new_loc; break; } case DW_CFA_advance_loc1: { READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, instr_ptr, sizeof(Dwarf_Small), error,final_instr_ptr); instr_ptr += sizeof(Dwarf_Small); fp_offset = adv_loc; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_advance_loc2: { READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, instr_ptr, DWARF_HALF_SIZE, error,final_instr_ptr); instr_ptr += DWARF_HALF_SIZE; fp_offset = adv_loc; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_advance_loc4: { READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, instr_ptr, DWARF_32BIT_SIZE, error,final_instr_ptr); instr_ptr += DWARF_32BIT_SIZE; fp_offset = adv_loc; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_MIPS_advance_loc8: { READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, instr_ptr, DWARF_64BIT_SIZE, error,final_instr_ptr); instr_ptr += DWARF_64BIT_SIZE; fp_offset = adv_loc; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } adv_loc *= code_alignment_factor; possible_subsequent_pc = current_loc + adv_loc; search_over = search_pc && (possible_subsequent_pc > search_pc_val); /* If gone past pc needed, retain old pc. */ if (!search_over) { current_loc = possible_subsequent_pc; } break; } case DW_CFA_offset_extended: { Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_offset_or_block_len = factored_N_value * data_alignment_factor; fp_register = reg_no; fp_offset = factored_N_value; break; } case DW_CFA_restore_extended: { Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); if (cie != NULL && cie->ci_initial_table != NULL) { localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; } else { if (!make_instr) { SIMPLE_ERROR_RETURN (DW_DLE_DF_MAKE_INSTR_NO_INIT); } } fp_register = reg_no; break; } case DW_CFA_undefined: { Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); localregtab[reg_no].ru_is_off = 0; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = dbg->de_frame_undefined_value_number; localregtab[reg_no].ru_offset_or_block_len = 0; fp_register = reg_no; break; } case DW_CFA_same_value: { Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); localregtab[reg_no].ru_is_off = 0; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = dbg->de_frame_same_value_number; localregtab[reg_no].ru_offset_or_block_len = 0; fp_register = reg_no; break; } case DW_CFA_register: { Dwarf_Unsigned lreg; reg_num_type reg_noA = 0; reg_num_type reg_noB = 0; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_noA = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_noB = (reg_num_type) lreg; if (reg_noB > reg_count) { SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); } localregtab[reg_noA].ru_is_off = 0; localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_noA].ru_register = reg_noB; localregtab[reg_noA].ru_offset_or_block_len = 0; fp_register = reg_noA; fp_offset = reg_noB; break; } case DW_CFA_remember_state: { stack_table = (Dwarf_Frame) _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); if (stack_table == NULL) { SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); } for (i = 0; i < reg_count; i++) stack_table->fr_reg[i] = localregtab[i]; stack_table->fr_cfa_rule = cfa_reg; if (top_stack != NULL) stack_table->fr_next = top_stack; top_stack = stack_table; break; } case DW_CFA_restore_state: { if (top_stack == NULL) { SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK); } stack_table = top_stack; top_stack = stack_table->fr_next; for (i = 0; i < reg_count; i++) localregtab[i] = stack_table->fr_reg[i]; cfa_reg = stack_table->fr_cfa_rule; dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); break; } case DW_CFA_def_cfa: { Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_register = reg_no; cfa_reg.ru_offset_or_block_len = factored_N_value; fp_register = reg_no; fp_offset = factored_N_value; break; } case DW_CFA_def_cfa_register: { Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); cfa_reg.ru_register = reg_no; /* Do NOT set ru_offset_or_block_len or ru_is_off here. See dwarf2/3 spec. */ fp_register = reg_no; break; } case DW_CFA_def_cfa_offset: { DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_offset_or_block_len = factored_N_value; fp_offset = factored_N_value; break; } /* This is for Metaware with augmentation string HC We do not really know what to do with it. */ case DW_CFA_METAWARE_info: { DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value, dbg,error,final_instr_ptr); /* Not really known what the value means or is. */ cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_offset_or_block_len = factored_N_value; break; } case DW_CFA_nop: { break; } /* DWARF3 ops begin here. */ case DW_CFA_def_cfa_expression: { /* A single DW_FORM_block representing a dwarf expression. The form block establishes the way to compute the CFA. */ Dwarf_Unsigned block_len = 0; DECODE_LEB128_UWORD_CK(instr_ptr, block_len, dbg,error,final_instr_ptr); cfa_reg.ru_is_off = 0; /* arbitrary */ cfa_reg.ru_value_type = DW_EXPR_EXPRESSION; cfa_reg.ru_offset_or_block_len = block_len; cfa_reg.ru_block = instr_ptr; fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; instr_ptr += block_len; } break; case DW_CFA_expression: { /* An unsigned leb128 value is the first operand (a register number). The second operand is single DW_FORM_block representing a dwarf expression. The evaluator pushes the CFA on the evaluation stack then evaluates the expression to compute the value of the register contents. */ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned block_len = 0; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, block_len, dbg,error,final_instr_ptr); localregtab[lreg].ru_is_off = 0; /* arbitrary */ localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION; localregtab[lreg].ru_offset_or_block_len = block_len; localregtab[lreg].ru_block = instr_ptr; fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; fp_register = reg_no; instr_ptr += block_len; } break; case DW_CFA_offset_extended_sf: { /* The first operand is an unsigned leb128 register number. The second is a signed factored offset. Identical to DW_CFA_offset_extended except the second operand is signed */ Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_register = reg_no; fp_offset = signed_factored_N_value; } break; case DW_CFA_def_cfa_sf: { /* The first operand is an unsigned leb128 register number. The second is a signed leb128 factored offset. Identical to DW_CFA_def_cfa except that the second operand is signed and factored. */ Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_register = reg_no; cfa_reg.ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_register = reg_no; fp_offset = signed_factored_N_value; } break; case DW_CFA_def_cfa_offset_sf: { /* The operand is a signed leb128 operand representing a factored offset. Identical to DW_CFA_def_cfa_offset excep the operand is signed and factored. */ DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ cfa_reg.ru_is_off = 1; cfa_reg.ru_value_type = DW_EXPR_OFFSET; cfa_reg.ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_offset = signed_factored_N_value; } break; case DW_CFA_val_offset: { /* The first operand is an unsigned leb128 register number. The second is a factored unsigned offset. Makes the register be a val_offset(N) rule with N = factored_offset*data_alignment_factor. */ Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_register = reg_num_of_cfa; localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET; localregtab[reg_no].ru_offset_or_block_len = factored_N_value * data_alignment_factor; fp_offset = factored_N_value; break; } case DW_CFA_val_offset_sf: { /* The first operand is an unsigned leb128 register number. The second is a factored signed offset. Makes the register be a val_offset(N) rule with N = factored_offset*data_alignment_factor. */ Dwarf_Unsigned lreg; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_SWORD_CK(instr_ptr, signed_factored_N_value, dbg,error,final_instr_ptr); if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); } /* Do set ru_is_off here, as here factored_N_value counts. */ localregtab[reg_no].ru_is_off = 1; localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET; localregtab[reg_no].ru_offset_or_block_len = signed_factored_N_value * data_alignment_factor; fp_offset = signed_factored_N_value; } break; case DW_CFA_val_expression: { /* The first operand is an unsigned leb128 register number. The second is a DW_FORM_block representing a DWARF expression. The rule for the register number becomes a val_expression(E) rule. */ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned block_len = 0; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); reg_no = (reg_num_type) lreg; ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count); DECODE_LEB128_UWORD_CK(instr_ptr, block_len, dbg,error,final_instr_ptr); localregtab[lreg].ru_is_off = 0; /* arbitrary */ localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION; localregtab[lreg].ru_offset_or_block_len = block_len; localregtab[lreg].ru_block = instr_ptr; fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; instr_ptr += block_len; fp_register = reg_no; } break; /* END DWARF3 new ops. */ #ifdef DW_CFA_GNU_window_save case DW_CFA_GNU_window_save: { /* No information: this just tells unwinder to restore the window registers from the previous frame's window save area */ break; } #endif #ifdef DW_CFA_GNU_args_size /* Single uleb128 is the current arg area size in bytes. No register exists yet to save this in */ case DW_CFA_GNU_args_size: { UNUSEDARG Dwarf_Unsigned lreg = 0; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); /* We have nowhere to store lreg. FIXME This is the total size of arguments pushed on the stack. https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA.junk/dwarfext.html */ break; } #endif default: /* ERROR, we have an opcode we know nothing about. Memory leak here, but an error like this is not supposed to happen so we ignore the leak. These used to be ignored, now we notice and report. */ SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR); } if (make_instr) { instr_count++; curr_instr = (Dwarf_Frame_Op *) _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1); if (curr_instr == NULL) { SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); } curr_instr->fp_base_op = fp_base_op; curr_instr->fp_extended_op = fp_extended_op; curr_instr->fp_register = fp_register; curr_instr->fp_offset = fp_offset; curr_instr->fp_instr_offset = fp_instr_offset; curr_instr_item = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_instr_item == NULL) { SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); } curr_instr_item->ch_item = curr_instr; if (head_instr_chain == NULL) head_instr_chain = tail_instr_chain = curr_instr_item; else { tail_instr_chain->ch_next = curr_instr_item; tail_instr_chain = curr_instr_item; } } } /* If frame instruction decoding was right we would stop exactly at final_instr_ptr. */ if (instr_ptr > final_instr_ptr) { SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR); } /* If search_over is set the last instr was an advance_loc so we are not done with rows. */ if ((instr_ptr == final_instr_ptr) && !search_over) { if (has_more_rows) { *has_more_rows = false; } if (subsequent_pc) { *subsequent_pc = 0; } } else { if (has_more_rows) { *has_more_rows = true; } if (subsequent_pc) { *subsequent_pc = possible_subsequent_pc; } } /* Fill in the actual output table, the space the caller passed in. */ if (table != NULL) { struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg; struct Dwarf_Reg_Rule_s *t3reg = localregtab; unsigned minregcount = MIN(table->fr_reg_count,reg_count); unsigned curreg = 0; table->fr_loc = current_loc; for (; curreg < minregcount ; curreg++, t3reg++, t2reg++) { *t2reg = *t3reg; } /* CONSTCOND */ /* Do not update the main table with the cfa_reg. Just leave cfa_reg as cfa_reg. */ table->fr_cfa_rule = cfa_reg; } /* Dealloc anything remaining on stack. */ for (; top_stack != NULL;) { stack_table = top_stack; top_stack = top_stack->fr_next; dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); } if (make_instr) { /* Allocate array of Dwarf_Frame_Op structs. */ head_instr_block = (Dwarf_Frame_Op *) _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count); if (head_instr_block == NULL) { SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); } /* Store Dwarf_Frame_Op instances in this array and deallocate the structs that chain the Dwarf_Frame_Op's. */ curr_instr_item = head_instr_chain; for (i = 0; i < instr_count; i++) { *(head_instr_block + i) = *(Dwarf_Frame_Op *) curr_instr_item->ch_item; dealloc_instr_item = curr_instr_item; curr_instr_item = curr_instr_item->ch_next; dwarf_dealloc(dbg, dealloc_instr_item->ch_item, DW_DLA_FRAME_OP); dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN); } *ret_frame_instr = head_instr_block; *returned_count = (Dwarf_Signed) instr_count; } else { *returned_count = 0; } free(localregtab); return DW_DLV_OK; #undef ERROR_IF_REG_NUM_TOO_HIGH #undef SIMPLE_ERROR_RETURN } /* Depending on version, either read the return address register as a ubyte or as an leb number. The form of this value changed for DWARF3. */ int _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr, int version, Dwarf_Debug dbg, Dwarf_Byte_Ptr section_end, unsigned long *size, Dwarf_Unsigned *return_address_register, Dwarf_Error *error) { Dwarf_Unsigned uvalue = 0; Dwarf_Unsigned leb128_length = 0; if (version == 1) { if (frame_ptr >= section_end) { _dwarf_error(NULL, error, DW_DLE_DF_FRAME_DECODING_ERROR); return DW_DLV_ERROR; } *size = 1; uvalue = *(unsigned char *) frame_ptr; *return_address_register = uvalue; return DW_DLV_OK; } DECODE_LEB128_UWORD_LEN_CK(frame_ptr,uvalue,leb128_length, dbg,error,section_end); *size = leb128_length; *return_address_register = uvalue; return DW_DLV_OK; } /* Trivial consumer function. */ int dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie * cie_returned, Dwarf_Error * error) { if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return (DW_DLV_ERROR); } *cie_returned = fde->fd_cie; return DW_DLV_OK; } int dwarf_get_cie_index( Dwarf_Cie cie, Dwarf_Signed* indx, Dwarf_Error* error ) { if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return (DW_DLV_ERROR); } *indx = cie->ci_index; return (DW_DLV_OK); } /* For g++ .eh_frame fde and cie. the cie id is different as the definition of the cie_id in an fde is the distance back from the address of the value to the cie. Or 0 if this is a true cie. Non standard dwarf, designed this way to be convenient at run time for an allocated (mapped into memory as part of the running image) section. */ int dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_get_fde_list_internal(dbg, cie_data, cie_element_count, fde_data, fde_element_count, dbg->de_debug_frame_eh_gnu.dss_data, dbg->de_debug_frame_eh_gnu.dss_index, dbg->de_debug_frame_eh_gnu.dss_size, /* cie_id_value */ 0, /* use_gnu_cie_calc= */ 1, error); return res; } /* For standard dwarf .debug_frame cie_id is -1 in a cie, and is the section offset in the .debug_frame section of the cie otherwise. Standard dwarf */ int dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_get_fde_list_internal(dbg, cie_data, cie_element_count, fde_data, fde_element_count, dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_size, DW_CIE_ID, /* use_gnu_cie_calc= */ 0, error); return res; } /* Only works on dwarf sections, not eh_frame because based on DW_AT_MIPS_fde. Given a Dwarf_Die, see if it has a DW_AT_MIPS_fde attribute and if so use that to get an fde offset. Then create a Dwarf_Fde to return thru the ret_fde pointer. Also creates a cie (pointed at from the Dwarf_Fde). */ int dwarf_get_fde_for_die(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Fde * ret_fde, Dwarf_Error * error) { Dwarf_Attribute attr; Dwarf_Unsigned fde_offset = 0; Dwarf_Signed signdval = 0; Dwarf_Fde new_fde = 0; unsigned char *fde_ptr = 0; unsigned char *fde_start_ptr = 0; unsigned char *fde_end_ptr = 0; unsigned char *cie_ptr = 0; Dwarf_Unsigned cie_id = 0; /* Fields for the current Cie being read. */ int res = 0; int resattr = 0; int sdatares = 0; struct cie_fde_prefix_s prefix; struct cie_fde_prefix_s prefix_c; if (die == NULL) { _dwarf_error(NULL, error, DW_DLE_DIE_NULL); return (DW_DLV_ERROR); } resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error); if (resattr != DW_DLV_OK) { return resattr; } /* why is this formsdata? FIX */ sdatares = dwarf_formsdata(attr, &signdval, error); if (sdatares != DW_DLV_OK) { return sdatares; } res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error); if (res != DW_DLV_OK) { return res; } fde_offset = signdval; fde_start_ptr = dbg->de_debug_frame.dss_data; fde_ptr = fde_start_ptr + fde_offset; fde_end_ptr = fde_start_ptr + dbg->de_debug_frame.dss_size; /* First read in the 'common prefix' to figure out what * we are to do with this entry. */ memset(&prefix_c, 0, sizeof(prefix_c)); memset(&prefix, 0, sizeof(prefix)); res = dwarf_read_cie_fde_prefix(dbg, fde_ptr, dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_size, &prefix, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { return res; } fde_ptr = prefix.cf_addr_after_prefix; cie_id = prefix.cf_cie_id; /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame.dss_data has no eh_frame relevance. */ res = dwarf_create_fde_from_after_start(dbg, &prefix, fde_start_ptr, fde_ptr, fde_end_ptr, /* use_gnu_cie_calc= */ 0, /* Dwarf_Cie = */ 0, &new_fde, error); if (res == DW_DLV_ERROR) { return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } /* DW_DLV_OK */ /* now read the cie corresponding to the fde */ cie_ptr = new_fde->fd_section_ptr + cie_id; res = dwarf_read_cie_fde_prefix(dbg, cie_ptr, dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_size, &prefix_c, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) return res; cie_ptr = prefix_c.cf_addr_after_prefix; cie_id = prefix_c.cf_cie_id; if (cie_id == (Dwarf_Unsigned)DW_CIE_ID) { int res2 = 0; Dwarf_Cie new_cie = 0; /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame.dss_data has no eh_frame relevance. */ res2 = dwarf_create_cie_from_after_start(dbg, &prefix_c, fde_start_ptr, cie_ptr, fde_end_ptr, /* cie_count= */ 0, /* use_gnu_cie_calc= */ 0, &new_cie, error); if (res2 == DW_DLV_ERROR) { dwarf_dealloc(dbg, new_fde, DW_DLA_FDE); return res; } else if (res2 == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, new_fde, DW_DLA_FDE); return res; } new_fde->fd_cie = new_cie; } else { _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE); return (DW_DLV_ERROR); } *ret_fde = new_fde; return DW_DLV_OK; } /* A dwarf consumer operation, see the consumer library documentation. */ int dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr * low_pc, Dwarf_Unsigned * func_length, Dwarf_Ptr * fde_bytes, Dwarf_Unsigned * fde_byte_length, Dwarf_Off * cie_offset, Dwarf_Signed * cie_index, Dwarf_Off * fde_offset, Dwarf_Error * error) { Dwarf_Debug dbg; if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return (DW_DLV_ERROR); } dbg = fde->fd_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return (DW_DLV_ERROR); } /* We have always already done the section load here, so no need to load the section. We did the section load in order to create the Dwarf_Fde pointer passed in here. */ if (low_pc != NULL) *low_pc = fde->fd_initial_location; if (func_length != NULL) *func_length = fde->fd_address_range; if (fde_bytes != NULL) *fde_bytes = fde->fd_fde_start; if (fde_byte_length != NULL) *fde_byte_length = fde->fd_length; if (cie_offset != NULL) *cie_offset = fde->fd_cie_offset; if (cie_index != NULL) *cie_index = fde->fd_cie_index; if (fde_offset != NULL) *fde_offset = fde->fd_fde_start - fde->fd_section_ptr; return DW_DLV_OK; } /* IRIX specific function. The exception tables have C++ destructor information and are at present undocumented. */ int dwarf_get_fde_exception_info(Dwarf_Fde fde, Dwarf_Signed * offset_into_exception_tables, Dwarf_Error * error) { Dwarf_Debug dbg; dbg = fde->fd_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return (DW_DLV_ERROR); } *offset_into_exception_tables = fde->fd_offset_into_exception_tables; return DW_DLV_OK; } /* A consumer code function. Given a CIE pointer, return the normal CIE data thru pointers. Special augmentation data is not returned here. */ int dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned * bytes_in_cie, Dwarf_Small * ptr_to_version, char **augmenter, Dwarf_Unsigned * code_alignment_factor, Dwarf_Signed * data_alignment_factor, Dwarf_Half * return_address_register, Dwarf_Ptr * initial_instructions, Dwarf_Unsigned * initial_instructions_length, Dwarf_Error * error) { Dwarf_Half offset_size = 0; return dwarf_get_cie_info_b(cie, bytes_in_cie, ptr_to_version, augmenter, code_alignment_factor, data_alignment_factor, return_address_register, initial_instructions, initial_instructions_length, &offset_size, error); } int dwarf_get_cie_info_b(Dwarf_Cie cie, Dwarf_Unsigned * bytes_in_cie, Dwarf_Small * ptr_to_version, char **augmenter, Dwarf_Unsigned * code_alignment_factor, Dwarf_Signed * data_alignment_factor, Dwarf_Half * return_address_register, Dwarf_Ptr * initial_instructions, Dwarf_Unsigned * initial_instructions_length, Dwarf_Half * offset_size, Dwarf_Error * error) { Dwarf_Debug dbg = 0; if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return (DW_DLV_ERROR); } dbg = cie->ci_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL); return (DW_DLV_ERROR); } if (ptr_to_version != NULL) *ptr_to_version = cie->ci_cie_version_number; if (augmenter != NULL) *augmenter = cie->ci_augmentation; if (code_alignment_factor != NULL) *code_alignment_factor = cie->ci_code_alignment_factor; if (data_alignment_factor != NULL) *data_alignment_factor = cie->ci_data_alignment_factor; if (return_address_register != NULL) *return_address_register = cie->ci_return_address_register; if (initial_instructions != NULL) *initial_instructions = cie->ci_cie_instr_start; if (initial_instructions_length != NULL) { *initial_instructions_length = cie->ci_length + cie->ci_length_size + cie->ci_extension_size - (cie->ci_cie_instr_start - cie->ci_cie_start); } if (offset_size) { *offset_size = cie->ci_length_size; } *bytes_in_cie = (cie->ci_length); return (DW_DLV_OK); } /* Return the register rules for all registers at a given pc. */ static int _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Frame table, Dwarf_Half cfa_reg_col_num, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Cie cie = 0; Dwarf_Signed icount = 0; int res = 0; if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } dbg = fde->fd_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return DW_DLV_ERROR; } if (pc_requested < fde->fd_initial_location || pc_requested >= fde->fd_initial_location + fde->fd_address_range) { _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); return DW_DLV_ERROR; } cie = fde->fd_cie; if (cie->ci_initial_table == NULL) { Dwarf_Small *instrstart = cie->ci_cie_instr_start; Dwarf_Small *instrend = instrstart +cie->ci_length + cie->ci_length_size + cie->ci_extension_size - (cie->ci_cie_instr_start - cie->ci_cie_start); if (instrend > cie->ci_cie_end) { _dwarf_error(dbg, error,DW_DLE_CIE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } cie->ci_initial_table = (Dwarf_Frame)_dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); if (cie->ci_initial_table == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dwarf_init_reg_rules_ru(cie->ci_initial_table->fr_reg, 0, cie->ci_initial_table->fr_reg_count, dbg->de_frame_rule_initial_value); dwarf_init_reg_rules_ru(&cie->ci_initial_table->fr_cfa_rule, 0,1,dbg->de_frame_rule_initial_value); res = _dwarf_exec_frame_instr( /* make_instr= */ false, /* ret_frame_instr= */ NULL, /* search_pc */ false, /* search_pc_val */ 0, /* location */ 0, instrstart, instrend, cie->ci_initial_table, cie, dbg, cfa_reg_col_num, &icount, NULL,NULL, error); if (res != DW_DLV_OK) { return res; } } { Dwarf_Small *instr_end = fde->fd_fde_instr_start + fde->fd_length + fde->fd_length_size + fde->fd_extension_size - (fde->fd_fde_instr_start - fde->fd_fde_start); if (instr_end > fde->fd_fde_end) { _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } res = _dwarf_exec_frame_instr( /* make_instr= */ false, /* ret_frame_instr= */ NULL, /* search_pc */ true, /* search_pc_val */ pc_requested, fde->fd_initial_location, fde->fd_fde_instr_start, instr_end, table, cie, dbg, cfa_reg_col_num, &icount, has_more_rows, subsequent_pc, error); } if (res != DW_DLV_OK) { return res; } return DW_DLV_OK; } /* A consumer call for efficiently getting the register info for all registers in one call. The output table rules array is size DW_REG_TABLE_SIZE. The frame info rules array in fde_table is of size DW_REG_TABLE_SIZE too. This interface really only works well with MIPS/IRIX where DW_FRAME_CFA_COL is zero (in that case it's safe). It is also restricted to the case where DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM == dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX). If this condition is not met calling this routine can result in incorrect output or in memory corruption. It is much better to use dwarf_get_fde_info_for_all_regs3() instead of this interface. */ int dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable * reg_table, Dwarf_Addr * row_pc, Dwarf_Error * error) { /* Table size: DW_REG_TABLE_SIZE */ struct Dwarf_Frame_s fde_table; Dwarf_Signed i = 0; struct Dwarf_Reg_Rule_s *rule = NULL; struct Dwarf_Regtable_Entry_s *out_rule = NULL; int res = 0; Dwarf_Debug dbg = 0; /* For this interface the size is fixed at compile time. */ int output_table_real_data_size = DW_REG_TABLE_SIZE; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); if (res != DW_DLV_OK) return res; /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number,NULL,NULL, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } out_rule = ®_table->rules[0]; rule = &fde_table.fr_reg[0]; for (i = 0; i < output_table_real_data_size; i++, ++out_rule, ++rule) { out_rule->dw_offset_relevant = rule->ru_is_off; out_rule->dw_value_type = rule->ru_value_type; out_rule->dw_regnum = rule->ru_register; out_rule->dw_offset = rule->ru_offset_or_block_len; } dwarf_init_reg_rules_dw(®_table->rules[0],i,DW_REG_TABLE_SIZE, dbg->de_frame_undefined_value_number); /* The test is just in case it's not inside the table. For non-MIPS it could be outside the table and that is just fine, it was really a mistake to put it in the table in 1993. */ /* CONSTCOND */ if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) { out_rule = ®_table->rules[dbg->de_frame_cfa_col_number]; out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off; out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type; out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register; out_rule->dw_offset = fde_table.fr_cfa_rule.ru_offset_or_block_len; } if (row_pc != NULL) *row_pc = fde_table.fr_loc; dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* A consumer call for efficiently getting the register info for all registers in one call. The output table rules array is size output_table_real_data_size. (normally DW_REG_TABLE_SIZE). The frame info rules array in fde_table is normally of size DW_FRAME_LAST_REG_NUM. */ 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) { struct Dwarf_Frame_s fde_table; Dwarf_Signed i = 0; int res = 0; struct Dwarf_Reg_Rule_s *rule = NULL; struct Dwarf_Regtable_Entry3_s *out_rule = NULL; Dwarf_Debug dbg = 0; int output_table_real_data_size = reg_table->rt3_reg_table_size; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); output_table_real_data_size = MIN(output_table_real_data_size, dbg->de_frame_reg_rules_entry_count); res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); if (res != DW_DLV_OK) { return res; } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number, NULL,NULL, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } out_rule = ®_table->rt3_rules[0]; rule = &fde_table.fr_reg[0]; for (i = 0; i < output_table_real_data_size; i++, ++out_rule, ++rule) { out_rule->dw_offset_relevant = rule->ru_is_off; out_rule->dw_value_type = rule->ru_value_type; out_rule->dw_regnum = rule->ru_register; out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len; out_rule->dw_block_ptr = rule->ru_block; } dwarf_init_reg_rules_dw3(®_table->rt3_rules[0],i,reg_table->rt3_reg_table_size, dbg->de_frame_undefined_value_number); reg_table->rt3_cfa_rule.dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off; reg_table->rt3_cfa_rule.dw_value_type = fde_table.fr_cfa_rule.ru_value_type; reg_table->rt3_cfa_rule.dw_regnum = fde_table.fr_cfa_rule.ru_register; reg_table->rt3_cfa_rule.dw_offset_or_block_len = fde_table.fr_cfa_rule.ru_offset_or_block_len; reg_table->rt3_cfa_rule.dw_block_ptr = fde_table.fr_cfa_rule.ru_block; if (row_pc != NULL) *row_pc = fde_table.fr_loc; dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* Obsolete as of 2006. Gets the register info for a single register at a given PC value for the FDE specified. This is the old MIPS interface and should no longer be used. Use dwarf_get_fde_info_for_reg3() instead. It can not handle DWARF3 or later properly as it assumes the CFA is representable as a table column. */ int dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset, Dwarf_Addr * row_pc, Dwarf_Error * error) { struct Dwarf_Frame_s fde_table; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; int output_table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); output_table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); if (res != DW_DLV_OK) return res; if (table_column >= output_table_real_data_size) { dwarf_free_fde_table(&fde_table); _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return (DW_DLV_ERROR); } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number, NULL,NULL,error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) { /* The problem here is that this interface cannot deal with other sorts of (newer) dwarf frame values. Code must use dwarf_get_fde_info_for_reg3() to get these values correctly. We error rather than return misleading incomplete data. */ dwarf_free_fde_table(&fde_table); _dwarf_error(NULL, error, DW_DLE_FRAME_REGISTER_UNREPRESENTABLE); return (DW_DLV_ERROR); } if (table_column == dbg->de_frame_cfa_col_number) { if (register_num != NULL) *register_num = fde_table.fr_cfa_rule.ru_register; if (offset != NULL) *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len; if (row_pc != NULL) *row_pc = fde_table.fr_loc; *offset_relevant = fde_table.fr_cfa_rule.ru_is_off; } else { if (register_num != NULL) *register_num = fde_table.fr_reg[table_column].ru_register; if (offset != NULL) *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len; if (row_pc != NULL) *row_pc = fde_table.fr_loc; *offset_relevant = fde_table.fr_reg[table_column].ru_is_off; } dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* In this interface, table_column of DW_FRAME_CFA_COL is not meaningful. Use dwarf_get_fde_info_for_cfa_reg3() to get the CFA. Call dwarf_set_frame_cfa_value() to set the correct column after calling dwarf_init() (DW_FRAME_CFA_COL3 is a sensible column to use). */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Error * error) { int res = dwarf_get_fde_info_for_reg3_b(fde, table_column, pc_requested, value_type, offset_relevant, register_num, offset_or_block_len, block_ptr, row_pc_out, /* Not looking for the has_more_rows flag nor for the next pc in the frame data. */ NULL,NULL, error); return res; } /* New May 2018. If one is tracking the value of a single table column through a function, this lets us skip to the next pc value easily. if pc_requested is a change from the last pc_requested on this pc, this function returns *has_more_rows and *subsequent_pc (null pointers passed are acceptable, the assignment through the pointer is skipped if the pointer is null). Otherwise *has_more_rows and *subsequent_pc are not set. */ int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { struct Dwarf_Frame_s * fde_table = &(fde->fd_fde_table); int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; int table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); if (!fde->fd_have_fde_tab || /* The test is just in case it's not inside the table. For non-MIPS it could be outside the table and that is just fine, it was really a mistake to put it in the table in 1993. */ fde->fd_fde_pc_requested != pc_requested) { if (fde->fd_have_fde_tab) { dwarf_free_fde_table(fde_table); fde->fd_have_fde_tab = false; } table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = dwarf_initialize_fde_table(dbg, fde_table, table_real_data_size, error); if (res != DW_DLV_OK) { return res; } if (table_column >= table_real_data_size) { dwarf_free_fde_table(fde_table); fde->fd_have_fde_tab = false; _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return (DW_DLV_ERROR); } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, fde_table, dbg->de_frame_cfa_col_number, has_more_rows,subsequent_pc, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(fde_table); fde->fd_have_fde_tab = false; return res; } } if (register_num != NULL) { *register_num = fde_table->fr_reg[table_column].ru_register; } if (offset_or_block_len != NULL) { *offset_or_block_len = fde_table->fr_reg[table_column].ru_offset_or_block_len; } if (row_pc_out != NULL) { *row_pc_out = fde_table->fr_loc; } if (block_ptr) { *block_ptr = fde_table->fr_reg[table_column].ru_block; } /* Without value_type the data cannot be understood, so we insist on it being present, we don't test it. */ *value_type = fde_table->fr_reg[table_column].ru_value_type; *offset_relevant = (fde_table->fr_reg[table_column].ru_is_off); fde->fd_have_fde_tab = true; fde->fd_fde_pc_requested = pc_requested; return DW_DLV_OK; } /* New 2006. For current DWARF, this is a preferred interface. Compared to dwarf_get_fde_info_for_reg() it more correctly deals with the CFA by not making the CFA a column number, which means DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE, a special value, not something one uses as an index. See also dwarf_get_fde_info_for_cfa_reg3_b(), which is slightly preferred. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Error * error) { Dwarf_Bool has_more_rows = 0; Dwarf_Addr next_pc = 0; int res = 0; res = dwarf_get_fde_info_for_cfa_reg3_b(fde, pc_requested, value_type, offset_relevant, register_num, offset_or_block_len, block_ptr, row_pc_out, &has_more_rows, &next_pc, error); return res; } /* New June 11,2016. For current DWARF, this is a preferred interface. Has extra arguments has_more_rows and next_pc (compared to dwarf_get_fde_info_for_cfa_reg3()) which can be used to more efficiently traverse frame data (primarily for dwarfdump and like programs). Like dwarf_get_fde_info_for_cfa_reg3() it deals with the CFA by not making the CFA a column number, which means DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE, a special value, not something one uses as an index. Call dwarf_set_frame_cfa_value() to set the correct column after calling dwarf_init() (DW_FRAME_CFA_COL3 is a sensible column to use, and is the default unless '--enable-oldframecol' is used to configure libdwarf). */ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed * offset_relevant, Dwarf_Signed * register_num, Dwarf_Signed * offset_or_block_len, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { struct Dwarf_Frame_s fde_table; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; int table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = dwarf_initialize_fde_table(dbg, &fde_table, table_real_data_size, error); if (res != DW_DLV_OK) return res; res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number,has_more_rows, subsequent_pc,error); if (res != DW_DLV_OK) { dwarf_free_fde_table(&fde_table); return res; } if (register_num != NULL) *register_num = fde_table.fr_cfa_rule.ru_register; if (offset_or_block_len != NULL) *offset_or_block_len = fde_table.fr_cfa_rule.ru_offset_or_block_len; if (row_pc_out != NULL) { *row_pc_out = fde_table.fr_loc; } if (block_ptr) { *block_ptr = fde_table.fr_cfa_rule.ru_block; } /* Without value_type the data cannot be understood, so we insist on it being present, we don't test it. */ *value_type = fde_table.fr_cfa_rule.ru_value_type; *offset_relevant = fde_table.fr_cfa_rule.ru_is_off; dwarf_free_fde_table(&fde_table); return DW_DLV_OK; } /* Return pointer to the instructions in the dwarf fde. */ int dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr, Dwarf_Unsigned * outaddrlen, Dwarf_Error * error) { Dwarf_Unsigned len = 0; unsigned char *instrs = 0; Dwarf_Debug dbg = 0; if (inFde == NULL) { _dwarf_error(dbg, error, DW_DLE_FDE_NULL); return (DW_DLV_ERROR); } dbg = inFde->fd_dbg; if (dbg == NULL) { _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL); return (DW_DLV_ERROR); } instrs = inFde->fd_fde_instr_start; len = (inFde->fd_fde_start + inFde->fd_length + inFde->fd_length_size + inFde->fd_extension_size) - instrs; *outinstraddr = instrs; *outaddrlen = len; return DW_DLV_OK; } /* Allows getting an fde from its table via an index. With more error checking than simply indexing oneself. */ int dwarf_get_fde_n(Dwarf_Fde * fde_data, Dwarf_Unsigned fde_index, Dwarf_Fde * returned_fde, Dwarf_Error * error) { Dwarf_Debug dbg = 0; Dwarf_Unsigned fdecount = 0; if (fde_data == NULL) { _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL); return (DW_DLV_ERROR); } FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg); /* Assumes fde_data table has at least one entry. */ fdecount = fde_data[0]->fd_is_eh? dbg->de_fde_count_eh:dbg->de_fde_count; if (fde_index >= fdecount) { return (DW_DLV_NO_ENTRY); } *returned_fde = (*(fde_data + fde_index)); return DW_DLV_OK; } /* Lopc and hipc are extensions to the interface to return the range of addresses that are described by the returned fde. */ int dwarf_get_fde_at_pc(Dwarf_Fde * fde_data, Dwarf_Addr pc_of_interest, Dwarf_Fde * returned_fde, Dwarf_Addr * lopc, Dwarf_Addr * hipc, Dwarf_Error * error) { Dwarf_Debug dbg = NULL; Dwarf_Fde fde = NULL; Dwarf_Fde entryfde = NULL; Dwarf_Signed fdecount = 0; if (fde_data == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL); return (DW_DLV_ERROR); } /* Assumes fde_data table has at least one entry. */ entryfde = *fde_data; FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg); fdecount = entryfde->fd_is_eh? dbg->de_fde_count_eh:dbg->de_fde_count; { /* The fdes are sorted by their addresses. Binary search to find correct fde. */ Dwarf_Signed low = 0; Dwarf_Signed high = fdecount - 1L; Dwarf_Signed middle = 0; Dwarf_Fde cur_fde; while (low <= high) { middle = (low + high) / 2; cur_fde = fde_data[middle]; if (pc_of_interest < cur_fde->fd_initial_location) { high = middle - 1; } else if (pc_of_interest >= (cur_fde->fd_initial_location + cur_fde->fd_address_range)) { low = middle + 1; } else { fde = fde_data[middle]; break; } } } if (fde) { if (lopc != NULL) *lopc = fde->fd_initial_location; if (hipc != NULL) *hipc = fde->fd_initial_location + fde->fd_address_range - 1; *returned_fde = fde; return (DW_DLV_OK); } return (DW_DLV_NO_ENTRY); } /* Expands a single frame instruction block from a specific cie into a n array of Dwarf_Frame_Op-s. This depends on having the cfa column set sensibly. Call dwarf_set_frame_cfa_value() to set the correct column after calling dwarf_init() unless you are using the old MIPS frame interfaces (in which case the default will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ). */ int dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, Dwarf_Unsigned i_length, Dwarf_Frame_Op ** returned_op_list, Dwarf_Signed * returned_op_count, Dwarf_Error * error) { Dwarf_Signed instr_count; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; Dwarf_Small * instr_start = instruction; Dwarf_Small * instr_end = (Dwarf_Small *)instruction + i_length;; if (cie == 0) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } dbg = cie->ci_dbg; if (returned_op_list == 0 || returned_op_count == 0) { _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL); return (DW_DLV_ERROR); } if ( instr_end < instr_start) { /* Impossible unless there was wraparond somewhere and we missed it. */ _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } res = _dwarf_exec_frame_instr( /* make_instr= */ true, returned_op_list, /* search_pc */ false, /* search_pc_val */ 0, /* location */ 0, instr_start, instr_end, /* Dwarf_Frame */ NULL, cie, dbg, dbg->de_frame_cfa_col_number, &instr_count, NULL,NULL, error); if (res != DW_DLV_OK) { return (res); } *returned_op_count = instr_count; return DW_DLV_OK; } /* Used by dwarfdump -v to print offsets, for debugging dwarf info. 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, Dwarf_Error * err) { return dwarf_fde_section_offset(dbg,in_fde,fde_off, cie_off,err); } /* ARGSUSED 4 */ int dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, Dwarf_Off * fde_off, Dwarf_Off * cie_off, Dwarf_Error * err) { char *start = 0; char *loc = 0; if(!in_fde) { _dwarf_error(dbg, err, DW_DLE_FDE_NULL); return DW_DLV_ERROR; } start = (char *) in_fde->fd_section_ptr; loc = (char *) in_fde->fd_fde_start; *fde_off = (loc - start); *cie_off = in_fde->fd_cie_offset; return DW_DLV_OK; } /* Used by dwarfdump -v to print offsets, for debugging dwarf info. 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 * err) { return dwarf_cie_section_offset(dbg,in_cie,cie_off,err); } /* ARGSUSED 4 */ int dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, Dwarf_Off * cie_off, Dwarf_Error * err) { char *start = 0; char *loc = 0; if(!in_cie) { _dwarf_error(dbg, err, DW_DLE_CIE_NULL); return DW_DLV_ERROR; } start = (char *) in_cie->ci_section_ptr; loc = (char *) in_cie->ci_cie_start; *cie_off = (loc - start); return DW_DLV_OK; } /* Returns a pointer to target-specific augmentation data thru augdata and returns the length of the data thru augdata_len. It's up to the consumer code to know how to interpret the bytes of target-specific data (endian issues apply too, these are just raw bytes pointed to). See Linux Standard Base Core Specification version 3.0 for the details on .eh_frame info. Returns DW_DLV_ERROR if fde is NULL or some other serious error. Returns DW_DLV_NO_ENTRY if there is no target-specific augmentation data. The bytes pointed to are in the Dwarf_Cie, and as long as that is valid the bytes are there. No 'dealloc' call is needed for the bytes. */ int dwarf_get_cie_augmentation_data(Dwarf_Cie cie, Dwarf_Small ** augdata, Dwarf_Unsigned * augdata_len, Dwarf_Error * error) { if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return (DW_DLV_ERROR); } if (cie->ci_gnu_eh_augmentation_len == 0) { return DW_DLV_NO_ENTRY; } *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes); *augdata_len = cie->ci_gnu_eh_augmentation_len; return DW_DLV_OK; } /* Returns a pointer to target-specific augmentation data thru augdata and returns the length of the data thru augdata_len. It's up to the consumer code to know how to interpret the bytes of target-specific data (endian issues apply too, these are just raw bytes pointed to). See Linux Standard Base Core Specification version 3.0 for the details on .eh_frame info. Returns DW_DLV_ERROR if fde is NULL or some other serious error. Returns DW_DLV_NO_ENTRY if there is no target-specific augmentation data. The bytes pointed to are in the Dwarf_Fde, and as long as that is valid the bytes are there. No 'dealloc' call is needed for the bytes. */ int dwarf_get_fde_augmentation_data(Dwarf_Fde fde, Dwarf_Small * *augdata, Dwarf_Unsigned * augdata_len, Dwarf_Error * error) { Dwarf_Cie cie = 0; if (fde == NULL) { _dwarf_error(NULL, error, DW_DLE_FDE_NULL); return (DW_DLV_ERROR); } if(!fde->fd_gnu_eh_aug_present) { return DW_DLV_NO_ENTRY; } cie = fde->fd_cie; if (cie == NULL) { _dwarf_error(NULL, error, DW_DLE_CIE_NULL); return (DW_DLV_ERROR); } *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes; *augdata_len = fde->fd_gnu_eh_augmentation_len; return DW_DLV_OK; } #if 0 /* FOR DEBUGGING */ /* Used solely for debugging libdwarf. */ static void dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule) { printf ("%s type %s (0x%" DW_PR_XZEROS DW_PR_DUx "), is_off %" DW_PR_DUu " reg %" DW_PR_DUu " offset 0x%" DW_PR_XZEROS DW_PR_DUx " blockp 0x%" DW_PR_XZEROS DW_PR_DUx "\n", msg, (reg_rule->ru_value_type == DW_EXPR_OFFSET) ? "DW_EXPR_OFFSET" : (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ? "DW_EXPR_VAL_OFFSET" : (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ? "DW_EXPR_VAL_EXPRESSION" : (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ? "DW_EXPR_EXPRESSION" : "Unknown", (Dwarf_Unsigned) reg_rule->ru_value_type, (Dwarf_Unsigned) reg_rule->ru_is_off, (Dwarf_Unsigned) reg_rule->ru_register, (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len, (Dwarf_Unsigned) reg_rule->ru_block); return; } #endif /* This allows consumers to set the 'initial value' so that an ISA/ABI specific default can be used, dynamically, at run time. Useful for dwarfdump and non-MIPS architectures.. The value defaults to one of DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE but dwarfdump can dump multiple ISA/ABI objects so we may want to get this set to what the ABI says is correct. Returns the value that was present before we changed it here. */ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_rule_initial_value; dbg->de_frame_rule_initial_value = value; return orig; } /* The following spelling for backwards compatibility. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value) { return dwarf_set_frame_rule_initial_value(dbg,value); } /* This allows consumers to set the array size of the reg rules table so that an ISA/ABI specific value can be used, dynamically, at run time. Useful for non-MIPS archtectures. The value defaults to DW_FRAME_LAST_REG_NUM. but dwarfdump can dump multiple ISA/ABI objects so consumers want to get this set to what the ABI says is correct. Returns the value that was present before we changed it here. */ Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count; dbg->de_frame_reg_rules_entry_count = value; /* Take the caller-specified value, but do not let the value be too small. Keep it at least to DW_FRAME_LAST_REG_NUM. This helps prevent libdwarf (mistakenly) indexing outside of of a register array when the ABI reg count is really small. */ if (value < DW_FRAME_LAST_REG_NUM) { dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; } return orig; } /* This allows consumers to set the CFA register value so that an ISA/ABI specific value can be used, dynamically, at run time. Useful for non-MIPS archtectures. The value defaults to DW_FRAME_CFA_COL3 and should be higher than any real register in the ABI. Dwarfdump can dump multiple ISA/ABI objects so consumers want to get this set to what the ABI says is correct. Returns the value that was present before we changed it here. */ Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_cfa_col_number; dbg->de_frame_cfa_col_number = value; return orig; } /* Similar to above, but for the other crucial fields for frames. */ Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_same_value_number; dbg->de_frame_same_value_number = value; return orig; } Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value) { Dwarf_Half orig = dbg->de_frame_same_value_number; dbg->de_frame_undefined_value_number = value; return orig; } /* Does something only if value passed in is greater than 0 and a size than we can handle (in number of bytes). */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug dbg, Dwarf_Small value ) { Dwarf_Small orig = dbg->de_pointer_size; if (value > 0 && value <= sizeof(Dwarf_Addr)) { dbg->de_pointer_size = value; } return orig; } static int init_reg_rules_alloc(Dwarf_Debug dbg,struct Dwarf_Frame_s *f, unsigned count, Dwarf_Error * error) { f->fr_reg_count = count; f->fr_reg = (struct Dwarf_Reg_Rule_s *) calloc(sizeof(struct Dwarf_Reg_Rule_s), count); if (f->fr_reg == 0) { if (error) { _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL); } return (DW_DLV_ERROR); } dwarf_init_reg_rules_ru(f->fr_reg,0, count, dbg->de_frame_rule_initial_value); return DW_DLV_OK; } static int dwarf_initialize_fde_table(Dwarf_Debug dbg, struct Dwarf_Frame_s *fde_table, unsigned table_real_data_size, Dwarf_Error * error) { unsigned entry_size = sizeof(struct Dwarf_Frame_s); memset(fde_table,0,entry_size); fde_table->fr_loc = 0; fde_table->fr_next = 0; return init_reg_rules_alloc(dbg,fde_table,table_real_data_size,error); } static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table) { free(fde_table->fr_reg); fde_table->fr_reg_count = 0; fde_table->fr_reg = 0; } /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR. */ int _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame) { struct Dwarf_Frame_s *fp = frame; if (!dbg) { return DW_DLV_ERROR; } return init_reg_rules_alloc(dbg,fp,dbg->de_frame_reg_rules_entry_count, 0); } void _dwarf_frame_destructor(void *frame) { struct Dwarf_Frame_s *fp = frame; dwarf_free_fde_table(fp); } void _dwarf_fde_destructor(void *f) { struct Dwarf_Fde_s *fde = f; if (fde->fd_have_fde_tab) { dwarf_free_fde_table(&fde->fd_fde_table); fde->fd_have_fde_tab = false; } } static void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base, unsigned first, unsigned last,int initial_value) { struct Dwarf_Reg_Rule_s *r = base+first; unsigned i = first; for (; i < last; ++i,++r) { r->ru_is_off = 0; r->ru_value_type = DW_EXPR_OFFSET; r->ru_register = initial_value; r->ru_offset_or_block_len = 0; r->ru_block = 0; } } static void dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base, unsigned first, unsigned last,int initial_value) { struct Dwarf_Regtable_Entry_s *r = base+first; unsigned i = first; for (; i < last; ++i,++r) { r->dw_offset_relevant = 0; r->dw_value_type = DW_EXPR_OFFSET; r->dw_regnum = initial_value; r->dw_offset = 0; } } static void dwarf_init_reg_rules_dw3(struct Dwarf_Regtable_Entry3_s *base, unsigned first, unsigned last,int initial_value) { struct Dwarf_Regtable_Entry3_s *r = base+first; unsigned i = first; for (; i < last; ++i,++r) { r->dw_offset_relevant = 0; r->dw_value_type = DW_EXPR_OFFSET; r->dw_regnum = initial_value; r->dw_offset_or_block_len = 0; r->dw_block_ptr = 0; } } dwarfutils-20200114/libdwarf/dwarf_frame.h000066400000000000000000000373551361531463500203750ustar00rootroot00000000000000/* Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The dwarf 2.0 standard dictates that only the following fields can be read when an unexpected augmentation string (in the cie) is encountered: CIE length, CIE_id, version and augmentation; FDE: length, CIE pointer, initial location and address range. Unfortunately, with the above restrictions, it is impossible to read the instruction table from a CIE or a FDE when a new augmentation string is encountered. To fix this problem, the following layout is used, if the augmentation string starts with the string "z". CIE FDE length length CIE_id CIE_pointer version initial_location augmentation address_range - length_of_augmented_fields (*NEW*) code_alignment_factor Any new fields as necessary data_alignment_factor instruction_table return_address length_of_augmented fields Any new fields as necessary initial_instructions The type of all the old data items are the same as what is described in dwarf 2.0 standard. The length_of_augmented_fields is an LEB128 data item that denotes the size (in bytes) of the augmented fields (not including the size of "length_of_augmented_fields" itself). Handling of cie augmentation strings is necessarly a heuristic. See dwarf_frame.c for the currently known augmentation strings. ---START SGI-ONLY COMMENT: SGI-IRIX versions of cie or fde were intended to use "z1", "z2" as the augmenter strings if required for new augmentation. However, that never happened (as of March 2005). The fde's augmented by the string "z" have a new field (signed constant, 4 byte field) called offset_into_exception_tables, following the length_of_augmented field. This field contains an offset into the "_MIPS_eh_region", which describes the IRIX CC exception handling tables. ---END SGI-ONLY COMMENT GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4) The similarity to IRIX 'z' (and proposed but never implemented IRIX z1, z2 etc) was confusing things. If the section is .eh_frame then 'z' means GNU exception information 'Augmentation Data' not IRIX 'z'. See The Linux Standard Base Core Specification version 3.0 */ #define DW_DEBUG_FRAME_VERSION 1 /* DWARF2 */ #define DW_DEBUG_FRAME_VERSION3 3 /* DWARF3 */ #define DW_DEBUG_FRAME_VERSION4 4 /* DWARF4 */ /* The following is SGI/IRIX specific, and probably no longer in use anywhere. */ #define DW_DEBUG_FRAME_AUGMENTER_STRING "mti v1" /* The value of the offset field for Cie's. */ #define DW_CIE_OFFSET ~(0x0) /* The augmentation string may be NULL. */ #define DW_EMPTY_STRING "" #define DW_FRAME_INSTR_OPCODE_SHIFT 6 #define DW_FRAME_INSTR_OFFSET_MASK 0x3f /* This struct denotes the rule for a register in a row of the frame table. In other words, it is one element of the table. */ struct Dwarf_Reg_Rule_s { /* Is a flag indicating whether the rule includes the offset field, ie whether the ru_offset field is valid or not. Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. It is important, since reg+offset (offset of 0) is different from just 'register' since the former means 'read memory at address given by the sum of register contents plus offset to get the value'. whereas the latter means 'the value is in the register'. The 'register' numbers are either real registers (ie, table columns defined as real registers) or defined entries that are not really hardware registers, such as DW_FRAME_SAME_VAL or DW_FRAME_CFA_COL. */ Dwarf_Sbyte ru_is_off; /* DW_EXPR_OFFSET (0, DWARF2) DW_EXPR_VAL_OFFSET 1 (dwarf2/3) DW_EXPR_EXPRESSION 2 (dwarf2/3) DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3) See dwarf_frame.h. */ Dwarf_Sbyte ru_value_type; /* Register involved in this rule. */ Dwarf_Half ru_register; /* Offset to add to register, if indicated by ru_is_offset and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION this is DW_FORM_block block-length, not offset. */ Dwarf_Unsigned ru_offset_or_block_len; /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set, else 0. */ Dwarf_Small *ru_block; }; typedef struct Dwarf_Frame_s *Dwarf_Frame; /* This structure represents a row of the frame table. Fr_loc is the pc value for this row, and Fr_reg contains the rule for each column. Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS way of setting CFA. cfa_rule is the new one. */ struct Dwarf_Frame_s { /* Pc value corresponding to this row of the frame table. */ Dwarf_Addr fr_loc; /* Rules for all the registers in this row. */ struct Dwarf_Reg_Rule_s fr_cfa_rule; /* fr_reg_count is the the number of entries of the fr_reg array. */ unsigned long fr_reg_count; struct Dwarf_Reg_Rule_s *fr_reg; Dwarf_Frame fr_next; }; typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List; /* This is used to chain together Dwarf_Frame_Op structures. */ struct Dwarf_Frame_Op_List_s { Dwarf_Frame_Op *fl_frame_instr; Dwarf_Frame_Op_List fl_next; }; /* See dwarf_frame.c for the heuristics used to set the Dwarf_Cie ci_augmentation_type. This succinctly helps interpret the size and meaning of .debug_frame and (for gcc) .eh_frame. In the case of gcc .eh_frame (gcc 3.3, 3.4) z may be followed by one or more of L R P. */ enum Dwarf_augmentation_type { aug_empty_string, /* Default empty augmentation string. */ aug_irix_exception_table, /* IRIX plain "z", for exception handling, IRIX CC compiler. Proposed z1 z2 ... never implemented. */ aug_gcc_eh_z, /* gcc z augmentation, (including L R P variations). gcc 3.3 3.4 exception handling in eh_frame. */ aug_irix_mti_v1, /* IRIX "mti v1" augmentation string. Probably never in any released SGI-IRIX compiler. */ aug_eh, /* For gcc .eh_frame, "eh" is the string., gcc 1,2, egcs. Older values. */ aug_armcc, /* "armcc+" meaning the cfa calculation is corrected to be standard (output by Arm C RVCT 3.0 SP1 and later). See http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html for details. */ aug_unknown, /* Unknown augmentation, we cannot do much. */ /* HC, From http://sourceforge.net/p/elftoolchain/tickets/397/ */ aug_metaware, aug_past_last }; /* This structure contains all the pertinent info for a Cie. Most of the fields are taken straight from the definition of a Cie. Ci_cie_start points to the address (in .debug_frame) where this Cie begins. Ci_cie_instr_start points to the first byte of the frame instructions for this Cie. Ci_dbg points to the associated Dwarf_Debug structure. Ci_initial_table is a pointer to the table row generated by the instructions for this Cie. */ struct Dwarf_Cie_s { Dwarf_Unsigned ci_length; char *ci_augmentation; Dwarf_Small ci_code_alignment_factor; Dwarf_Sbyte ci_data_alignment_factor; Dwarf_Small ci_return_address_register; Dwarf_Small *ci_cie_start; Dwarf_Small *ci_cie_instr_start; Dwarf_Small *ci_cie_end; Dwarf_Debug ci_dbg; Dwarf_Frame ci_initial_table; Dwarf_Cie ci_next; Dwarf_Small ci_length_size; Dwarf_Small ci_extension_size; Dwarf_Half ci_cie_version_number; enum Dwarf_augmentation_type ci_augmentation_type; /* The following 2 for GNU .eh_frame exception handling Augmentation Data. Set if ci_augmentation_type is aug_gcc_eh_z. Zero if unused. */ Dwarf_Unsigned ci_gnu_eh_augmentation_len; Dwarf_Ptr ci_gnu_eh_augmentation_bytes; /* These are extracted from the gnu eh_frame augmentation if the augmentation begins with 'z'. See Linux LSB documents. Otherwize these are zero. */ unsigned char ci_gnu_personality_handler_encoding; unsigned char ci_gnu_lsda_encoding; unsigned char ci_gnu_fde_begin_encoding; /* If 'P' augmentation present, is handler addr. Else is zero. */ Dwarf_Addr ci_gnu_personality_handler_addr; /* In creating list of cie's (which will become an array) record the position so fde can get it on fde creation. */ Dwarf_Unsigned ci_index; Dwarf_Small * ci_section_ptr; Dwarf_Unsigned ci_section_length; Dwarf_Small * ci_section_end; /* DWARF4 adds address size and segment size to the CIE: the .debug_info section may not always be present to allow libdwarf to find address_size from the compilation-unit. */ Dwarf_Half ci_address_size; Dwarf_Half ci_segment_size; }; /* This structure contains all the pertinent info for a Fde. Most of the fields are taken straight from the definition. fd_cie_index is the index of the Cie associated with this Fde in the list of Cie's for this debug_frame. Fd_cie points to the corresponsing Dwarf_Cie structure. Fd_fde_start points to the start address of the Fde. Fd_fde_instr_start points to the start of the instructions for this Fde. Fd_dbg points to the associated Dwarf_Debug structure. */ struct Dwarf_Fde_s { Dwarf_Unsigned fd_length; Dwarf_Addr fd_cie_offset; Dwarf_Unsigned fd_cie_index; Dwarf_Cie fd_cie; Dwarf_Addr fd_initial_location; Dwarf_Small *fd_initial_loc_pos; Dwarf_Addr fd_address_range; Dwarf_Small *fd_fde_start; Dwarf_Small *fd_fde_instr_start; Dwarf_Small *fd_fde_end; Dwarf_Debug fd_dbg; /* fd_offset_into_exception_tables is SGI/IRIX exception table offset. Unused and zero if not IRIX .debug_frame. */ Dwarf_Signed fd_offset_into_exception_tables; Dwarf_Fde fd_next; Dwarf_Small fd_length_size; Dwarf_Small fd_extension_size; /* So we know from an fde which 'count' of fde-s in Dwarf_Debug applies: eh or standard. */ Dwarf_Small fd_is_eh; /* The following 2 for GNU .eh_frame exception handling Augmentation Data. Set if CIE ci_augmentation_type is aug_gcc_eh_z. Zero if unused. */ Dwarf_Unsigned fd_gnu_eh_augmentation_len; Dwarf_Bool fd_gnu_eh_aug_present; Dwarf_Ptr fd_gnu_eh_augmentation_bytes; Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter present: is address of the Language Specific Data Area (LSDA). If not 'L" is zero. */ /* The following 3 are about the Elf section the FDEs come from. */ Dwarf_Small * fd_section_ptr; Dwarf_Unsigned fd_section_length; Dwarf_Unsigned fd_section_index; Dwarf_Small * fd_section_end; /* If fd_eh_table_value_set is true, then fd_eh_table_value is meaningful. Never meaningful for .debug_frame, is part of .eh_frame. */ Dwarf_Unsigned fd_eh_table_value; Dwarf_Bool fd_eh_table_value_set; /* The following are memoization to save recalculation. */ struct Dwarf_Frame_s fd_fde_table; Dwarf_Addr fd_fde_pc_requested; Dwarf_Bool fd_have_fde_tab; }; int _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, Dwarf_Off ** offsetlist, Dwarf_Signed * returncount, Dwarf_Error * err); int _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Unsigned cie_id_value, int use_gnu_cie_calc, /* If non-zero, this is gcc eh_frame. */ Dwarf_Error * error); enum Dwarf_augmentation_type _dwarf_get_augmentation_type(Dwarf_Debug dbg, Dwarf_Small *augmentation_string, int is_gcc_eh_frame); int _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr, int version, Dwarf_Debug dbg, Dwarf_Byte_Ptr section_end, unsigned long *size, Dwarf_Unsigned *return_address_register, Dwarf_Error *error); /* Temporary recording of crucial cie/fde prefix data. Vastly simplifies some argument lists. */ struct cie_fde_prefix_s { /* cf_start_addr is a pointer to the first byte of this fde/cie (meaning the length field itself) */ Dwarf_Small * cf_start_addr; /* cf_addr_after_prefix is a pointer to the first byte of this fde/cie we are reading now, immediately following the length field read by READ_AREA_LENGTH. */ Dwarf_Small * cf_addr_after_prefix; /* cf_length is the length field value from the cie/fde header. */ Dwarf_Unsigned cf_length; int cf_local_length_size; int cf_local_extension_size; Dwarf_Unsigned cf_cie_id; Dwarf_Small * cf_cie_id_addr; /* used for eh_frame calculations. */ /* Simplifies passing around these values to create fde having these here. */ /* cf_section_ptr is a pointer to the first byte of the object section the prefix is read from. */ Dwarf_Small * cf_section_ptr; Dwarf_Unsigned cf_section_index; Dwarf_Unsigned cf_section_length; }; int _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Frame_Op ** ret_frame_instr, Dwarf_Bool search_pc, Dwarf_Addr search_pc_val, Dwarf_Addr initial_loc, Dwarf_Small * start_instr_ptr, Dwarf_Small * final_instr_ptr, Dwarf_Frame table, Dwarf_Cie cie, Dwarf_Debug dbg, Dwarf_Half reg_num_of_cfa, Dwarf_Signed * returned_count, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error); int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, Dwarf_Small *frame_ptr_in, Dwarf_Small *section_ptr_in, Dwarf_Unsigned section_index_in, Dwarf_Unsigned section_length_in, struct cie_fde_prefix_s *prefix_out, Dwarf_Error *error); int dwarf_create_fde_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s * prefix, Dwarf_Small *section_pointer, Dwarf_Small *frame_ptr, Dwarf_Small *section_ptr_end, int use_gnu_cie_calc, Dwarf_Cie cie_ptr_in, Dwarf_Fde *fde_ptr_out, Dwarf_Error *error); int dwarf_create_cie_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s *prefix, Dwarf_Small* section_pointer, Dwarf_Small* frame_ptr, Dwarf_Small *section_ptr_end, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie *cie_ptr_out, Dwarf_Error *error); int _dwarf_frame_constructor(Dwarf_Debug dbg,void * ); void _dwarf_frame_destructor (void *); void _dwarf_fde_destructor (void *); dwarfutils-20200114/libdwarf/dwarf_frame2.c000066400000000000000000001656011361531463500204460ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 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 and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This implements _dwarf_get_fde_list_internal() and related helper functions for reading cie/fde data. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_arange.h" /* using Arange as a way to build a list */ /* For a little information about .eh_frame see https://stackoverflow.com/questions/14091231/what-do-the-eh-frame-and-eh-frame-hdr-sections-store-exactly http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html The above give information about fields and sizes but very very little about content. .eh_frame_hdr contains data for C++ unwinding. Namely tables for fast access into .eh_frame. */ #define TRUE 1 #define FALSE 0 #if 0 /* FOR DEBUGGING */ /* For debugging only. */ static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); } printf("\n"); } #endif static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, Dwarf_Cie cur_cie_ptr, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Cie head_cie_ptr); static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, Dwarf_Cie head_cie_ptr); static int dwarf_create_cie_from_start(Dwarf_Debug dbg, Dwarf_Small * cie_ptr_val, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Small * section_ptr_end, Dwarf_Unsigned cie_id_value, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Error * error); static int get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, unsigned long *size_of_augmentation_data, enum Dwarf_augmentation_type augtype, Dwarf_Small * section_end_pointer, char *augmentation, Dwarf_Error *error); static int gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, Dwarf_Half address_size, unsigned char *pers_hand_enc_out, unsigned char *lsda_enc_out, unsigned char *fde_begin_enc_out, Dwarf_Addr * gnu_pers_addr_out, Dwarf_Error *error); static int read_encoded_ptr(Dwarf_Debug dbg, Dwarf_Small * section_pointer, Dwarf_Small * input_field, int gnu_encoding, Dwarf_Small * section_ptr_end, Dwarf_Half address_size, Dwarf_Unsigned * addr, Dwarf_Small ** input_field_out, Dwarf_Error *error); /* Called by qsort to compare FDE entries. Consumer code expects the array of FDE pointers to be in address order. */ static int qsort_compare(const void *elem1, const void *elem2) { const Dwarf_Fde fde1 = *(const Dwarf_Fde *) elem1; const Dwarf_Fde fde2 = *(const Dwarf_Fde *) elem2; Dwarf_Addr addr1 = fde1->fd_initial_location; Dwarf_Addr addr2 = fde2->fd_initial_location; if (addr1 < addr2) { return -1; } else if (addr1 > addr2) { return 1; } return 0; } /* Adds 'newone' to the end of the list starting at 'head' and makes the new one 'cur'rent. */ static void chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur) { if (*head == NULL) *head = newone; else { (*cur)->fd_next = newone; } *cur = newone; } /* Adds 'newone' to the end of the list starting at 'head' and makes the new one 'cur'rent. */ static void chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur) { if (*head == NULL) { *head = newone; } else { (*cur)->ci_next = newone; } *cur = newone; } /* The size of the length field plus the value of length must be an integral multiple of the address size. Dwarf4 standard. A constant that gives the number of bytes of the CIE structure, not including the length field itself (where length mod == 0) (see Section 7.2.2). Dwarf3 standard. A uword constant that gives the number of bytes of the CIE structure, not including the length field, itself (length mod == 0). Dwarf2 standard.*/ static void validate_length(Dwarf_Debug dbg, Dwarf_Cie cieptr, Dwarf_Unsigned length, Dwarf_Unsigned length_size, Dwarf_Unsigned extension_size, Dwarf_Small * section_ptr, Dwarf_Small * ciefde_start, const char * cieorfde) { Dwarf_Unsigned address_size = 0; Dwarf_Unsigned length_field_summed = length_size + extension_size; Dwarf_Unsigned total_len = length + length_field_summed; Dwarf_Unsigned mod = 0; if (cieptr) { address_size = cieptr->ci_address_size; } else { address_size = dbg->de_pointer_size; } mod = total_len % address_size; if (mod != 0) { static char msg[DW_HARMLESS_ERROR_MSG_STRING_SIZE]; Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr; if (!cieorfde || (strlen(cieorfde) > 3)) { /* Coding error or memory corruption? */ cieorfde = "ERROR!"; } sprintf(msg, "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE" " len=0x%" DW_PR_XZEROS DW_PR_DUx ", len size=0x%" DW_PR_XZEROS DW_PR_DUx ", extn size=0x%" DW_PR_XZEROS DW_PR_DUx ", totl length=0x%" DW_PR_XZEROS DW_PR_DUx ", addr size=0x%" DW_PR_XZEROS DW_PR_DUx ", mod=0x%" DW_PR_XZEROS DW_PR_DUx " must be zero" " in %s" ", offset 0x%" DW_PR_XZEROS DW_PR_DUx ".", length, length_size, extension_size, total_len,address_size, mod, cieorfde, sectionoffset); dwarf_insert_harmless_error(dbg,msg); } return; } #if 0 /* FOR DEBUGGING */ /* For debugging only. */ static void print_prefix(struct cie_fde_prefix_s *prefix, int line) { printf("prefix-print, prefix at 0x%lx, line %d\n", (unsigned long) prefix, line); printf(" start addr 0x%lx after prefix 0x%lx\n", (unsigned long) prefix->cf_start_addr, (unsigned long) prefix->cf_addr_after_prefix); printf(" length 0x%" DW_PR_DUx ", len size %d ext size %d\n", (Dwarf_Unsigned) prefix->cf_length, prefix->cf_local_length_size, prefix->cf_local_extension_size); printf(" cie_id 0x%" DW_PR_DUx " cie_id cie_id_addr 0x%lx\n", (Dwarf_Unsigned) prefix->cf_cie_id, (long) prefix->cf_cie_id_addr); printf (" sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n", (unsigned long) prefix->cf_section_ptr, (Dwarf_Signed) prefix->cf_section_index, (Dwarf_Unsigned) prefix->cf_section_length, (unsigned long) prefix->cf_section_ptr + (unsigned long)prefix->cf_section_length); } #endif /* Make the 'cieptr' consistent across .debug_frame and .eh_frame. Calculate a pointer into section bytes given a cie_id in an FDE header. In .debug_frame, the CIE_pointer is an offset in .debug_frame. In .eh_frame, the CIE Pointer is, when cie_id_value subtracted from the cie_id_addr, the address in memory of a CIE length field. Since cie_id_addr is the address of an FDE CIE_Pointer field, cie_id_value for .eh_frame has to account for the length-prefix. so that the returned cieptr really points to a CIE length field. Whew! Available documentation on this is just a bit ambiguous, but this calculation is correct. */ static Dwarf_Small * get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, int use_gnu_cie_calc, Dwarf_Small * section_ptr, Dwarf_Small * cie_id_addr) { Dwarf_Small *cieptr = 0; if (use_gnu_cie_calc) { /* cie_id value is offset, in section, of the cie_id itself, to use vm ptr of the value, less the value, to get to the cie header. */ cieptr = cie_id_addr - cie_id_value; } else { /* Traditional dwarf section offset is in cie_id */ cieptr = section_ptr + cie_id_value; } return cieptr; } /* Internal function called from various places to create lists of CIEs and FDEs. Not directly called by consumer code */ int _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Signed * cie_element_count, Dwarf_Fde ** fde_data, Dwarf_Signed * fde_element_count, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Unsigned cie_id_value, int use_gnu_cie_calc, Dwarf_Error * error) { /* Scans the debug_frame section. */ Dwarf_Small *frame_ptr = section_ptr; Dwarf_Small *section_ptr_end = section_ptr + section_length; /* New_cie points to the Cie being read, and head_cie_ptr and cur_cie_ptr are used for chaining them up in sequence. In case cie's are reused aggressively we need tail_cie_ptr to add to the chain. If we re-use an early cie later on, that does not mean we chain a new cie to the early one, we always chain it to the tail. */ Dwarf_Cie head_cie_ptr = NULL; Dwarf_Cie cur_cie_ptr = NULL; Dwarf_Cie tail_cie_ptr = NULL; Dwarf_Unsigned cie_count = 0; /* Points to a list of contiguous pointers to Dwarf_Cie structures. */ Dwarf_Cie *cie_list_ptr = 0; /* New_fde points to the Fde being created, and head_fde_ptr and cur_fde_ptr are used to chain them up. */ Dwarf_Fde head_fde_ptr = NULL; Dwarf_Fde cur_fde_ptr = NULL; Dwarf_Unsigned fde_count = 0; /* Points to a list of contiguous pointers to Dwarf_Fde structures. */ Dwarf_Fde *fde_list_ptr = NULL; Dwarf_Unsigned i = 0; int res = DW_DLV_ERROR; if (frame_ptr == 0) { return DW_DLV_NO_ENTRY; } /* We create the fde and cie arrays. Processing each CIE as we come to it or as an FDE refers to it. We cannot process 'late' CIEs late as GNU .eh_frame complexities mean we need the whole CIE before we can process the FDE correctly. */ while (frame_ptr < section_ptr_end) { struct cie_fde_prefix_s prefix; /* First read in the 'common prefix' to figure out what we are to do with this entry. */ memset(&prefix, 0, sizeof(prefix)); res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr, section_index, section_length, &prefix, error); if (res == DW_DLV_ERROR) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return res; } if (res == DW_DLV_NO_ENTRY) break; frame_ptr = prefix.cf_addr_after_prefix; if (frame_ptr >= section_ptr_end) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } if (prefix.cf_cie_id == cie_id_value) { /* This is a CIE. */ Dwarf_Cie cie_ptr_to_use = 0; int resc = 0; resc = dwarf_find_existing_cie_ptr(prefix.cf_start_addr, cur_cie_ptr, &cie_ptr_to_use, head_cie_ptr); if (resc == DW_DLV_OK) { cur_cie_ptr = cie_ptr_to_use; /* Ok. Seen already. */ } else if (resc == DW_DLV_NO_ENTRY) { /* CIE before its FDE in this case. */ resc = dwarf_create_cie_from_after_start(dbg, &prefix, section_ptr, frame_ptr, section_ptr_end, cie_count, use_gnu_cie_calc, &cie_ptr_to_use, error); if (resc != DW_DLV_OK) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resc; } cie_count++; chain_up_cie(cie_ptr_to_use, &head_cie_ptr, &tail_cie_ptr); cur_cie_ptr = tail_cie_ptr; } else { /* res == DW_DLV_ERROR */ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resc; } frame_ptr = cie_ptr_to_use->ci_cie_start + cie_ptr_to_use->ci_length + cie_ptr_to_use->ci_length_size + cie_ptr_to_use->ci_extension_size; continue; } else { /* This is an FDE, Frame Description Entry, see the Dwarf Spec, (section 6.4.1 in DWARF2, DWARF3, DWARF4, ...) Or see the .eh_frame specification, from the Linux Foundation (or other source). */ int resf = DW_DLV_ERROR; Dwarf_Cie cie_ptr_to_use = 0; Dwarf_Fde fde_ptr_to_use = 0; Dwarf_Small *cieptr_val = 0; cieptr_val = get_cieptr_given_offset(prefix.cf_cie_id, use_gnu_cie_calc, section_ptr, prefix.cf_cie_id_addr); resf = dwarf_find_existing_cie_ptr(cieptr_val, cur_cie_ptr, &cie_ptr_to_use, head_cie_ptr); if (resf == DW_DLV_OK) { cur_cie_ptr = cie_ptr_to_use; /* Ok. Seen CIE already. */ } else if (resf == DW_DLV_NO_ENTRY) { resf = dwarf_create_cie_from_start(dbg, cieptr_val, section_ptr, section_index, section_length, section_ptr_end, cie_id_value, cie_count, use_gnu_cie_calc, &cie_ptr_to_use, error); if (resf == DW_DLV_ERROR) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resf; } else if (resf == DW_DLV_NO_ENTRY) { return resf; } ++cie_count; chain_up_cie(cie_ptr_to_use, &head_cie_ptr, &tail_cie_ptr); cur_cie_ptr = tail_cie_ptr; } else { /* DW_DLV_ERROR */ return resf; } resf = dwarf_create_fde_from_after_start(dbg, &prefix, section_ptr, frame_ptr, section_ptr_end, use_gnu_cie_calc, cie_ptr_to_use, &fde_ptr_to_use, error); if (resf == DW_DLV_ERROR) { return resf; } else if (resf == DW_DLV_NO_ENTRY) { /* impossible. */ return resf; } chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr); fde_count++; /* ASSERT: DW_DLV_OK. */ frame_ptr = cur_fde_ptr->fd_fde_start + cur_fde_ptr->fd_length + cur_fde_ptr->fd_length_size + cur_fde_ptr->fd_extension_size; if (frame_ptr < fde_ptr_to_use->fd_fde_instr_start) { /* Sanity check. With a really short fde instruction set and address_size we think is 8 as it is ELF64 (but is really 4, as in DWARF{2,3} where we have no FDE address_size) we emit an error. This error means things will not go well. */ _dwarf_error(dbg,error, DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH); return DW_DLV_ERROR; } continue; } } /* Now build list of CIEs from the list. If there are no CIEs there should be no FDEs. */ if (cie_count > 0) { cie_list_ptr = (Dwarf_Cie *) _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count); } else { if (fde_count > 0) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg, error, DW_DLE_ORPHAN_FDE); return DW_DLV_ERROR; } dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return DW_DLV_NO_ENTRY; } if (cie_list_ptr == NULL) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (!head_cie_ptr) { /* Should be impossible. */ _dwarf_error(dbg, error,DW_DLE_DEBUGFRAME_ERROR); return DW_DLV_ERROR; } cur_cie_ptr = head_cie_ptr; for (i = 0; i < cie_count; i++) { *(cie_list_ptr + i) = cur_cie_ptr; cur_cie_ptr = cur_cie_ptr->ci_next; } /* Now build array of FDEs from the list. With orphan CIEs (meaning no FDEs) lets not return DW_DLV_NO_ENTRY */ if (fde_count > 0) { fde_list_ptr = (Dwarf_Fde *) _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count); } /* It is ok if fde_list_ptr is NULL, we just have no fdes. */ cur_fde_ptr = head_fde_ptr; for (i = 0; i < fde_count; i++) { *(fde_list_ptr + i) = cur_fde_ptr; cur_fde_ptr = cur_fde_ptr->fd_next; } /* Return arguments. */ *cie_data = cie_list_ptr; *cie_element_count = cie_count; *fde_data = fde_list_ptr; *fde_element_count = fde_count; if (use_gnu_cie_calc) { dbg->de_fde_data_eh = fde_list_ptr; dbg->de_fde_count_eh = fde_count; dbg->de_cie_data_eh = cie_list_ptr; dbg->de_cie_count_eh = cie_count; } else { dbg->de_fde_data = fde_list_ptr; dbg->de_fde_count = fde_count; dbg->de_cie_data = cie_list_ptr; dbg->de_cie_count = cie_count; } /* Sort the list by the address so that dwarf_get_fde_at_pc() can binary search this list. */ if (fde_count > 0) { qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr), qsort_compare); } return (DW_DLV_OK); } /* Internal function, not called by consumer code. 'prefix' has accumulated the info up thru the cie-id and now we consume the rest and build a Dwarf_Cie_s structure. */ int dwarf_create_cie_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s *prefix, Dwarf_Small * section_pointer, Dwarf_Small * frame_ptr, Dwarf_Small * section_ptr_end, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie * cie_ptr_out, Dwarf_Error * error) { Dwarf_Cie new_cie = 0; /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses -1 (in .debug_frame). .eh_frame not quite identical to .debug_frame */ /* We here default the address size as it is not present in DWARF2 or DWARF3 cie data, below we set it right if it is present. */ Dwarf_Half address_size = dbg->de_pointer_size; Dwarf_Small *augmentation = 0; Dwarf_Half segment_size = 0; Dwarf_Signed data_alignment_factor = -1; Dwarf_Unsigned code_alignment_factor = 4; Dwarf_Unsigned return_address_register = 31; int local_length_size = 0; Dwarf_Unsigned leb128_length = 0; Dwarf_Unsigned cie_aug_data_len = 0; Dwarf_Small *cie_aug_data = 0; Dwarf_Addr gnu_personality_handler_addr = 0; unsigned char gnu_personality_handler_encoding = 0; unsigned char gnu_lsda_encoding = 0; unsigned char gnu_fde_begin_encoding = 0; int res = 0; Dwarf_Small version = 0; enum Dwarf_augmentation_type augt = aug_unknown; /* This is a CIE, Common Information Entry: See the dwarf spec, section 6.4.1 */ if (frame_ptr >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } version = *(Dwarf_Small *) frame_ptr; if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } frame_ptr++; if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3 && version != DW_CIE_VERSION4 && version != DW_CIE_VERSION5) { _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); return (DW_DLV_ERROR); } augmentation = frame_ptr; res = _dwarf_check_string_valid(dbg,section_pointer, frame_ptr,section_ptr_end, DW_DLE_AUGMENTATION_STRING_OFF_END,error); if (res != DW_DLV_OK) { return res; } frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1; if (frame_ptr >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } augt = _dwarf_get_augmentation_type(dbg, augmentation, use_gnu_cie_calc); if (augt == aug_eh) { /* REFERENCED *//* Not used in this instance */ UNUSEDARG Dwarf_Unsigned exception_table_addr; if ((frame_ptr+local_length_size) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } /* this is per egcs-1.1.2 as on RH 6.0 */ READ_UNALIGNED_CK(dbg, exception_table_addr, Dwarf_Unsigned, frame_ptr, local_length_size, error,section_ptr_end); frame_ptr += local_length_size; } { Dwarf_Unsigned lreg = 0; unsigned long size = 0; if (version == DW_CIE_VERSION4) { if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } address_size = *((unsigned char *)frame_ptr); if (address_size < 1) { _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO); return (DW_DLV_ERROR); } if (address_size > sizeof(Dwarf_Addr)) { _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR); return (DW_DLV_ERROR); } if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } ++frame_ptr; segment_size = *((unsigned char *)frame_ptr); ++frame_ptr; if (segment_size > sizeof(Dwarf_Addr)) { _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); return (DW_DLV_ERROR); } } /* Not a great test. But the DECODE* do checking so ok. */ if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error,section_ptr_end); code_alignment_factor = (Dwarf_Unsigned) lreg; res = (Dwarf_Signed) _dwarf_decode_s_leb128_chk(frame_ptr, &leb128_length,&data_alignment_factor,section_ptr_end); if(res != DW_DLV_OK) { return res; } frame_ptr = frame_ptr + leb128_length; /* Not a great test. FIXME */ if ((frame_ptr+1) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } res = _dwarf_get_return_address_reg(frame_ptr, version, dbg,section_ptr_end, &size,&return_address_register,error); if(res != DW_DLV_OK) { return res; } if (return_address_register > dbg->de_frame_reg_rules_entry_count) { _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); return (DW_DLV_ERROR); } frame_ptr += size; if ((frame_ptr) > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } } switch (augt) { case aug_empty_string: break; case aug_irix_mti_v1: break; case aug_irix_exception_table:{ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned length_of_augmented_fields; /* Decode the length of augmented fields. */ DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error,section_ptr_end); length_of_augmented_fields = (Dwarf_Unsigned) lreg; /* set the frame_ptr to point at the instruction start. */ frame_ptr += length_of_augmented_fields; } break; case aug_eh:{ int err = 0; unsigned long increment = 0; if (!use_gnu_cie_calc) { /* This should be impossible. */ _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment, augt, section_ptr_end, (char *) augmentation,error); if (err == DW_DLV_ERROR) { _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } frame_ptr += increment; } break; case aug_gcc_eh_z:{ /* Here we have Augmentation Data Length (uleb128) followed by Augmentation Data bytes (not a string). */ int resz = DW_DLV_ERROR; Dwarf_Unsigned adlen = 0; /* Not a great test. FIXME */ if ((frame_ptr+1) > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(frame_ptr, adlen, dbg,error,section_ptr_end); cie_aug_data_len = adlen; cie_aug_data = frame_ptr; if (adlen) { Dwarf_Small *cie_aug_data_end = cie_aug_data+adlen; if (cie_aug_data_end < cie_aug_data || cie_aug_data_end > section_ptr_end) { /* Bad adlen */ _dwarf_error(dbg, error, DW_DLE_AUG_DATA_LENGTH_BAD); return DW_DLV_ERROR; } } resz = gnu_aug_encodings(dbg, (char *) augmentation, cie_aug_data, cie_aug_data_len, address_size, &gnu_personality_handler_encoding, &gnu_lsda_encoding, &gnu_fde_begin_encoding, &gnu_personality_handler_addr, error); if (resz != DW_DLV_OK) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return resz; } frame_ptr += adlen; } break; case aug_armcc: break; default:{ /* We do not understand the augmentation string. No assumption can be made about any fields other than what we have already read. */ frame_ptr = prefix->cf_start_addr + prefix->cf_length + prefix->cf_local_length_size + prefix->cf_local_extension_size; /* FIX -- What are the values of data_alignment_factor, code_alignement_factor, return_address_register and instruction start? They were clearly uninitalized in the previous version and I am leaving them the same way. */ } if ((frame_ptr) > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } break; } /* End switch on augmentation type. */ new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); if (new_cie == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } new_cie->ci_cie_version_number = version; new_cie->ci_initial_table = NULL; new_cie->ci_length = (Dwarf_Unsigned) prefix->cf_length; new_cie->ci_length_size = prefix->cf_local_length_size; new_cie->ci_extension_size = prefix->cf_local_extension_size; new_cie->ci_augmentation = (char *) augmentation; new_cie->ci_data_alignment_factor = (Dwarf_Sbyte) data_alignment_factor; new_cie->ci_code_alignment_factor = (Dwarf_Small) code_alignment_factor; new_cie->ci_return_address_register = return_address_register; new_cie->ci_cie_start = prefix->cf_start_addr; if ( frame_ptr > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return (DW_DLV_ERROR); } new_cie->ci_cie_instr_start = frame_ptr; new_cie->ci_dbg = dbg; new_cie->ci_augmentation_type = augt; new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len; new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data; new_cie->ci_gnu_personality_handler_encoding = gnu_personality_handler_encoding; new_cie->ci_gnu_personality_handler_addr = gnu_personality_handler_addr; new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding; new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding; new_cie->ci_index = cie_count; new_cie->ci_section_ptr = prefix->cf_section_ptr; new_cie->ci_section_end = section_ptr_end; new_cie->ci_cie_end = new_cie->ci_cie_start + new_cie->ci_length + new_cie->ci_length_size+ new_cie->ci_extension_size; if ( new_cie->ci_cie_end > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return (DW_DLV_ERROR); } /* The Following new in DWARF4 */ new_cie->ci_address_size = address_size; new_cie->ci_segment_size = segment_size; validate_length(dbg,new_cie,new_cie->ci_length, new_cie->ci_length_size, new_cie->ci_extension_size, new_cie->ci_section_ptr, new_cie->ci_cie_start,"cie"); *cie_ptr_out = new_cie; return DW_DLV_OK; } /* Internal function, not called by consumer code. 'prefix' has accumulated the info up thru the cie-id and now we consume the rest and build a Dwarf_Fde_s structure. Can be called with cie_ptr_in NULL from dwarf_frame.c */ int dwarf_create_fde_from_after_start(Dwarf_Debug dbg, struct cie_fde_prefix_s *prefix, Dwarf_Small * section_pointer, Dwarf_Small * frame_ptr, Dwarf_Small * section_ptr_end, int use_gnu_cie_calc, Dwarf_Cie cie_ptr_in, Dwarf_Fde * fde_ptr_out, Dwarf_Error * error) { Dwarf_Fde new_fde = 0; Dwarf_Cie cieptr = 0; Dwarf_Small *saved_frame_ptr = 0; Dwarf_Small *initloc = frame_ptr; Dwarf_Signed offset_into_exception_tables = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; Dwarf_Small *fde_aug_data = 0; Dwarf_Unsigned fde_aug_data_len = 0; Dwarf_Addr cie_base_offset = prefix->cf_cie_id; Dwarf_Addr initial_location = 0; /* must be min de_pointer_size bytes in size */ Dwarf_Addr address_range = 0; /* must be min de_pointer_size bytes in size */ Dwarf_Half address_size = 0; Dwarf_Unsigned eh_table_value = 0; Dwarf_Bool eh_table_value_set = FALSE; /* Temporary assumption. */ enum Dwarf_augmentation_type augt = aug_empty_string; if (cie_ptr_in) { cieptr = cie_ptr_in; address_size = cieptr->ci_address_size; augt = cieptr->ci_augmentation_type; } if (augt == aug_gcc_eh_z) { /* If z augmentation this is eh_frame, and initial_location and address_range in the FDE are read according to the CIE augmentation string instructions. */ { Dwarf_Small *fp_updated = 0; int res = read_encoded_ptr(dbg, section_pointer, frame_ptr, cieptr-> ci_gnu_fde_begin_encoding, section_ptr_end, address_size, &initial_location, &fp_updated,error); if (res != DW_DLV_OK) { return res; } frame_ptr = fp_updated; /* For the address-range it makes no sense to be pc-relative, so we turn it off with a section_pointer of NULL. Masking off DW_EH_PE_pcrel from the ci_gnu_fde_begin_encoding in this call would also work to turn off DW_EH_PE_pcrel. */ res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL, frame_ptr, cieptr->ci_gnu_fde_begin_encoding, section_ptr_end, address_size, &address_range, &fp_updated,error); if (res != DW_DLV_OK) { return res; } frame_ptr = fp_updated; } { Dwarf_Unsigned adlen = 0; DECODE_LEB128_UWORD_CK(frame_ptr, adlen, dbg,error,section_ptr_end); fde_aug_data_len = adlen; fde_aug_data = frame_ptr; frame_ptr += adlen; if (adlen) { if (frame_ptr < fde_aug_data || frame_ptr >= section_ptr_end ) { /* Bad adlen */ _dwarf_error(dbg, error, DW_DLE_AUG_DATA_LENGTH_BAD); return DW_DLV_ERROR; } } } } else { if ((frame_ptr + 2*address_size) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, initial_location, Dwarf_Addr, frame_ptr, address_size, error,section_ptr_end); frame_ptr += address_size; READ_UNALIGNED_CK(dbg, address_range, Dwarf_Addr, frame_ptr, address_size, error,section_ptr_end); frame_ptr += address_size; } switch (augt) { case aug_irix_mti_v1: case aug_empty_string: break; case aug_irix_exception_table:{ Dwarf_Unsigned lreg = 0; Dwarf_Unsigned length_of_augmented_fields = 0; DECODE_LEB128_UWORD_CK(frame_ptr, lreg, dbg,error,section_ptr_end); length_of_augmented_fields = (Dwarf_Unsigned) lreg; saved_frame_ptr = frame_ptr; /* The first word is an offset into exception tables. Defined as a 32bit offset even for CC -64. */ if ((frame_ptr + DWARF_32BIT_SIZE) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, offset_into_exception_tables, Dwarf_Addr, frame_ptr, DWARF_32BIT_SIZE, error,section_ptr_end); SIGN_EXTEND(offset_into_exception_tables, DWARF_32BIT_SIZE); frame_ptr = saved_frame_ptr + length_of_augmented_fields; } break; case aug_eh:{ if (!use_gnu_cie_calc) { /* This should be impossible. */ _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* gnu eh fde case. we do not need to do anything */ /*REFERENCED*/ /* Not used in this instance of the macro */ if ((frame_ptr + address_size) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, eh_table_value, Dwarf_Unsigned, frame_ptr, address_size, error,section_ptr_end); eh_table_value_set = TRUE; frame_ptr += address_size; } break; case aug_gcc_eh_z:{ /* The Augmentation Data Length is here, followed by the Augmentation Data bytes themselves. */ } break; case aug_armcc: break; case aug_past_last: break; case aug_metaware: /* No special fields. See dwarf_util.h */ break; case aug_unknown: _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* End switch on augmentation type */ if ( frame_ptr > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return (DW_DLV_ERROR); } new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); if (new_fde == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } new_fde->fd_length = prefix->cf_length; new_fde->fd_length_size = prefix->cf_local_length_size; new_fde->fd_extension_size = prefix->cf_local_extension_size; new_fde->fd_is_eh = use_gnu_cie_calc; new_fde->fd_cie_offset = cie_base_offset; if (cieptr) { new_fde->fd_cie_index = cieptr->ci_index; } new_fde->fd_cie = cieptr; new_fde->fd_initial_location = initial_location; new_fde->fd_initial_loc_pos = initloc; new_fde->fd_address_range = address_range; new_fde->fd_fde_start = prefix->cf_start_addr; new_fde->fd_fde_instr_start = frame_ptr; new_fde->fd_fde_end = prefix->cf_start_addr + prefix->cf_length + prefix->cf_local_length_size + prefix->cf_local_extension_size; if ( new_fde->fd_fde_end > section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); return (DW_DLV_ERROR); } new_fde->fd_dbg = dbg; new_fde->fd_offset_into_exception_tables = offset_into_exception_tables; new_fde->fd_eh_table_value = eh_table_value; new_fde->fd_eh_table_value_set = eh_table_value_set; new_fde->fd_section_ptr = prefix->cf_section_ptr; new_fde->fd_section_index = prefix->cf_section_index; new_fde->fd_section_length = prefix->cf_section_length; new_fde->fd_section_end = section_ptr_end; if (augt == aug_gcc_eh_z) { new_fde->fd_gnu_eh_aug_present = TRUE; } new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data; new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len; validate_length(dbg,cieptr,new_fde->fd_length, new_fde->fd_length_size, new_fde->fd_extension_size, new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde"); *fde_ptr_out = new_fde; return DW_DLV_OK; } /* Read in the common cie/fde prefix, including reading the cie-value which shows which this is: cie or fde. */ int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, Dwarf_Small * frame_ptr_in, Dwarf_Small * section_ptr_in, Dwarf_Unsigned section_index_in, Dwarf_Unsigned section_length_in, struct cie_fde_prefix_s *data_out, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Small *frame_ptr = frame_ptr_in; Dwarf_Small *cie_ptr_addr = 0; Dwarf_Unsigned cie_id = 0; Dwarf_Small *section_end = section_ptr_in + section_length_in; if(section_end < (frame_ptr +4)) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, frame_ptr, local_length_size, local_extension_size,error, section_length_in,section_end); if (length == 0) { /* nul bytes at end of section, seen at end of egcs eh_frame sections (in a.out). Take this as meaning no more CIE/FDE data. We should be very close to end of section. */ return DW_DLV_NO_ENTRY; } if((frame_ptr + local_length_size) >= section_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } cie_ptr_addr = frame_ptr; READ_UNALIGNED_CK(dbg, cie_id, Dwarf_Unsigned, frame_ptr, local_length_size,error,section_end); SIGN_EXTEND(cie_id, local_length_size); frame_ptr += local_length_size; data_out->cf_start_addr = frame_ptr_in; data_out->cf_addr_after_prefix = frame_ptr; data_out->cf_length = length; if (length > section_length_in) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } if (cie_ptr_addr+length > section_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } data_out->cf_local_length_size = local_length_size; data_out->cf_local_extension_size = local_extension_size; /* We do not know if it is a CIE or FDE id yet. How we check and what it means depends whether it is .debug_frame or .eh_frame. */ data_out->cf_cie_id = cie_id; /* The address of the CIE_id or FDE_id value in memory. */ data_out->cf_cie_id_addr = cie_ptr_addr; data_out->cf_section_ptr = section_ptr_in; data_out->cf_section_index = section_index_in; data_out->cf_section_length = section_length_in; return DW_DLV_OK; } /* On various errors previously-allocated CIEs and FDEs must be cleaned up. This helps avoid leaks in case of errors. */ static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, Dwarf_Cie head_cie_ptr) { Dwarf_Fde curfde = 0; Dwarf_Cie curcie = 0; Dwarf_Fde nextfde = 0; Dwarf_Cie nextcie = 0; for (curfde = head_fde_ptr; curfde; curfde = nextfde) { nextfde = curfde->fd_next; dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE); } for (curcie = head_cie_ptr; curcie; curcie = nextcie) { Dwarf_Frame frame = curcie->ci_initial_table; nextcie = curcie->ci_next; if (frame) dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME); dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE); } } /* Find the cie whose id value is given: the id value is, per DWARF2/3, an offset in the section. For .debug_frame, zero is a legal offset. For GNU .eh_frame it is not a legal offset. 'cie_ptr' is a pointer into our section, not an offset. */ static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, Dwarf_Cie cur_cie_ptr, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Cie head_cie_ptr) { Dwarf_Cie next = 0; if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) { /* Usually, we use the same cie again and again. */ *cie_ptr_to_use_out = cur_cie_ptr; return DW_DLV_OK; } for (next = head_cie_ptr; next; next = next->ci_next) { if (cie_ptr == next->ci_cie_start) { *cie_ptr_to_use_out = next; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* We have a valid cie_ptr_val that has not been turned into an internal Cie yet. Do so now. Returns DW_DLV_OK or DW_DLV_ERROR, never DW_DLV_NO_ENTRY. 'section_ptr' - Points to first byte of section data. 'section_length' - Length of the section, in bytes. 'section_ptr_end' - Points 1-past last byte of section data. */ static int dwarf_create_cie_from_start(Dwarf_Debug dbg, Dwarf_Small * cie_ptr_val, Dwarf_Small * section_ptr, Dwarf_Unsigned section_index, Dwarf_Unsigned section_length, Dwarf_Small * section_ptr_end, Dwarf_Unsigned cie_id_value, Dwarf_Unsigned cie_count, int use_gnu_cie_calc, Dwarf_Cie * cie_ptr_to_use_out, Dwarf_Error * error) { struct cie_fde_prefix_s prefix; int res = DW_DLV_ERROR; Dwarf_Small *frame_ptr = cie_ptr_val; if (frame_ptr < section_ptr || frame_ptr >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } /* First read in the 'common prefix' to figure out what * we are to do with this entry. If it is not a cie * we are in big trouble. */ memset(&prefix, 0, sizeof(prefix)); res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr, section_index, section_length, &prefix, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { /* error. */ _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); return DW_DLV_ERROR; } if (prefix.cf_cie_id != cie_id_value) { _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); return DW_DLV_ERROR; } frame_ptr = prefix.cf_addr_after_prefix; res = dwarf_create_cie_from_after_start(dbg, &prefix, section_ptr, frame_ptr, section_ptr_end, cie_count, use_gnu_cie_calc, cie_ptr_to_use_out, error); return res; } /* This is for gnu eh frames, the 'z' case. We find the letter involved Return the augmentation character and, if applicable, the personality routine address. personality_routine_out - if 'P' is augchar, is personality handler addr. Otherwise is not set. aug_data - if 'P' points to data space of the aug_data_len - length of areas aug_data points to. */ /* It is not clear if this is entirely correct. */ static int gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, Dwarf_Half address_size, unsigned char *pers_hand_enc_out, unsigned char *lsda_enc_out, unsigned char *fde_begin_enc_out, Dwarf_Addr * gnu_pers_addr_out, Dwarf_Error * error) { char *nc = 0; Dwarf_Small *cur_aug_p = aug_data; Dwarf_Small *end_aug_p = aug_data + aug_data_len; for (nc = augmentation; *nc; ++nc) { char c = *nc; switch (c) { case 'z': /* Means that the augmentation data is present. */ continue; case 'S': /* Indicates this is a signal stack frame. Debuggers have to do special handling. We don't need to do more than print this flag at the right time, though (see dwarfdump where it prints the augmentation string). A signal stack frame (in some OS's) can only be unwound (backtraced) by knowing it is a signal stack frame (perhaps by noticing the name of the function for the stack frame if the name can be found somehow) and figuring out (or knowing) how the kernel and libc pushed a structure onto the stack and loading registers from that structure. Totally different from normal stack unwinding. This flag gives an unwinder a big leg up by decoupling the 'hint: this is a stack frame' from knowledge like the function name (the name might be unavailable at unwind time). */ break; case 'L': if (cur_aug_p > end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } *lsda_enc_out = *(unsigned char *) cur_aug_p; ++cur_aug_p; break; case 'R': /* Followed by a one byte argument giving the pointer encoding for the address pointers in the fde. */ if (cur_aug_p >= end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } *fde_begin_enc_out = *(unsigned char *) cur_aug_p; ++cur_aug_p; break; case 'P':{ int res = DW_DLV_ERROR; Dwarf_Small *updated_aug_p = 0; unsigned char encoding = 0; if (cur_aug_p >= end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } encoding = *(unsigned char *) cur_aug_p; *pers_hand_enc_out = encoding; ++cur_aug_p; if (cur_aug_p > end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* DW_EH_PE_pcrel makes no sense here, so we turn it off via a section pointer of NULL. */ res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL, cur_aug_p, encoding, end_aug_p, address_size, gnu_pers_addr_out, &updated_aug_p, error); if (res != DW_DLV_OK) { return res; } cur_aug_p = updated_aug_p; if (cur_aug_p > end_aug_p) { _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } } break; default: _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } } return DW_DLV_OK; } /* Given augmentation character (the encoding) giving the address format, read the address from input_field and return an incremented value 1 past the input bytes of the address. Push the address read back thru the *addr pointer. See LSB (Linux Standard Base) exception handling documents. */ static int read_encoded_ptr(Dwarf_Debug dbg, Dwarf_Small * section_pointer, Dwarf_Small * input_field, int gnu_encoding, Dwarf_Small * section_end, Dwarf_Half address_size, Dwarf_Unsigned * addr, Dwarf_Small ** input_field_updated, Dwarf_Error *error) { int value_type = gnu_encoding & 0xf; Dwarf_Small *input_field_original = input_field; if (gnu_encoding == 0xff) { /* There is no data here. */ *addr = 0; *input_field_updated = input_field; /* Should we return DW_DLV_NO_ENTRY? */ return DW_DLV_OK; } switch (value_type) { case DW_EH_PE_absptr:{ /* value_type is zero. Treat as pointer size of the object. */ Dwarf_Unsigned ret_value = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, address_size,error,section_end); *addr = ret_value; *input_field_updated = input_field + address_size; } break; case DW_EH_PE_uleb128:{ Dwarf_Unsigned val = 0; DECODE_LEB128_UWORD_CK(input_field,val,dbg,error,section_end); *addr = val; *input_field_updated = input_field; } break; case DW_EH_PE_udata2:{ Dwarf_Unsigned ret_value = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, 2,error,section_end); *addr = ret_value; *input_field_updated = input_field + 2; } break; case DW_EH_PE_udata4:{ Dwarf_Unsigned ret_value = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, DWARF_32BIT_SIZE,error,section_end); *addr = ret_value; *input_field_updated = input_field + DWARF_32BIT_SIZE; } break; case DW_EH_PE_udata8:{ Dwarf_Unsigned ret_value = 0; /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, input_field, DWARF_64BIT_SIZE,error,section_end); *addr = ret_value; *input_field_updated = input_field + DWARF_64BIT_SIZE; } break; case DW_EH_PE_sleb128:{ Dwarf_Signed val = 0; DECODE_LEB128_SWORD_CK(input_field,val,dbg,error,section_end); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field; } break; case DW_EH_PE_sdata2:{ Dwarf_Unsigned val = 0; READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, 2, error,section_end); SIGN_EXTEND(val, 2); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field + 2; } break; case DW_EH_PE_sdata4:{ Dwarf_Unsigned val = 0; READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, DWARF_32BIT_SIZE,error,section_end); SIGN_EXTEND(val, DWARF_32BIT_SIZE); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field + DWARF_32BIT_SIZE; } break; case DW_EH_PE_sdata8:{ Dwarf_Unsigned val = 0; /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, DWARF_64BIT_SIZE,error,section_end); *addr = (Dwarf_Unsigned) val; *input_field_updated = input_field + DWARF_64BIT_SIZE; } break; default: _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; }; /* The ELF ABI for gnu does not document the meaning of DW_EH_PE_pcrel, which is awkward. It apparently means the value we got above is pc-relative (meaning section-relative), so we adjust the value. Section_pointer may be null if it is known DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an address-range value. */ if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) { /* Address (*addr) above is pc relative with respect to a section. Add to the offset the base address (from elf) of section and the distance of the field we are reading from the section-beginning to get the actual address. */ /* ASSERT: input_field_original >= section_pointer */ Dwarf_Unsigned distance = input_field_original - section_pointer; *addr += dbg->de_debug_frame_eh_gnu.dss_addr + distance; } return DW_DLV_OK; } /* All augmentation string checking done here now. For .eh_frame, gcc from 3.3 uses the z style, earlier used only "eh" as augmentation. We don't yet handle decoding .eh_frame with the z style extensions like L P. gnu_aug_encodings() does handle L P. These are nasty heuristics, but then that's life as augmentations are implementation specific. */ /* ARGSUSED */ enum Dwarf_augmentation_type _dwarf_get_augmentation_type(UNUSEDARG Dwarf_Debug dbg, Dwarf_Small * augmentation_string, int is_gcc_eh_frame) { enum Dwarf_augmentation_type t = aug_unknown; char *ag_string = (char *) augmentation_string; if (ag_string[0] == 0) { /* Empty string. We'll just guess that we know what this means: standard dwarf2/3 with no implementation-defined fields. */ t = aug_empty_string; } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) { /* The string is "mti v1". Used internally at SGI, probably never shipped. Replaced by "z". Treat like 'nothing special'. */ t = aug_irix_mti_v1; } else if (ag_string[0] == 'z') { /* If it's IRIX cc, z means aug_irix_exception_table. z1 z2 were designed as for IRIX CC, but never implemented */ /* If it's gcc, z may be any of several things. "z" or z followed optionally followed by one or more of L R P, each of which means a value may be present. Should be in eh_frame only, I think. */ if (is_gcc_eh_frame) { t = aug_gcc_eh_z; } else if (ag_string[1] == 0) { /* This is the normal IRIX C++ case, where there is an offset into a table in each fde. The table being for IRIX CC exception handling. */ /* DW_CIE_AUGMENTER_STRING_V0 "z" */ t = aug_irix_exception_table; } /* Else unknown. */ } else if (strncmp(ag_string, "eh", 2) == 0) { /* gcc .eh_frame augmentation for egcs and gcc 2.x, at least for x86. */ t = aug_eh; } else if (strcmp(ag_string, "armcc+") == 0) { /* Arm uses this string to mean a bug in in Arm compilers was fixed, changing to the standard calculation of the CFA. See http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html for details. */ t = aug_armcc; } else if (strcmp(ag_string, "HC") == 0) { t = aug_metaware; } else { } return t; } /* Using augmentation, and version read in the augmentation data for GNU eh. Return DW_DLV_OK if we succeeded, DW_DLV_ERR if we fail. On success, update 'size_of_augmentation_data' with the length of the fields that are part of augmentation (so the caller can increment frame_ptr appropriately). 'frame_ptr' points within section. 'section_end' points to end of section area of interest. */ /* ARGSUSED */ static int get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, unsigned long *size_of_augmentation_data, enum Dwarf_augmentation_type augtype, Dwarf_Small * section_ptr_end, char *augmentation, Dwarf_Error *error) { char *suffix = 0; unsigned long augdata_size = 0; if (augtype == aug_gcc_eh_z) { /* Has leading 'z'. */ UNUSEDARG Dwarf_Unsigned val = 0; Dwarf_Unsigned leb128_length = 0; /* Dwarf_Unsigned eh_value = */ DECODE_LEB128_UWORD_LEN_CK(frame_ptr,val,leb128_length, dbg,error,section_ptr_end); augdata_size += leb128_length; suffix = augmentation + 1; } else { /* Prefix is 'eh'. As in gcc 3.2. No suffix present apparently. */ suffix = augmentation + 2; } /* FIXME: This could run too far. */ /* for (; *suffix; ++suffix) if we think we can do something */ if (*suffix) { /* We have no idea what this is as yet. Some extensions beyond dwarf exist which we do not yet handle. */ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } *size_of_augmentation_data = augdata_size; return DW_DLV_OK; } /* To properly release all spaced used. Earlier approaches (before July 15, 2005) letting client do the dealloc directly left some data allocated. This is directly called by consumer code. */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, Dwarf_Cie * cie_data, Dwarf_Signed cie_element_count, Dwarf_Fde * fde_data, Dwarf_Signed fde_element_count) { Dwarf_Signed i = 0; for (i = 0; i < cie_element_count; ++i) { Dwarf_Frame frame = cie_data[i]->ci_initial_table; if (frame) dwarf_dealloc(dbg, frame, DW_DLA_FRAME); dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); } for (i = 0; i < fde_element_count; ++i) { dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); } if (cie_data) dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); if (fde_data) dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); } dwarfutils-20200114/libdwarf/dwarf_funcs.c000066400000000000000000000066701361531463500204100ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_funcs.h" #include "dwarf_global.h" int dwarf_get_funcs(Dwarf_Debug dbg, Dwarf_Func ** funcs, Dwarf_Signed * ret_func_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_funcnames,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_funcnames.dss_size) { return (DW_DLV_NO_ENTRY); } return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_funcnames.dss_data, dbg->de_debug_funcnames.dss_size, (Dwarf_Global **) funcs, /* Type punning for sections with identical format. */ ret_func_count, error, DW_DLA_FUNC_CONTEXT, DW_DLA_FUNC, DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD, DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_funcs_dealloc(Dwarf_Debug dbg, Dwarf_Func * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_FUNC_CONTEXT, DW_DLA_FUNC, DW_DLA_LIST); return; } int dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; if (func == NULL) { _dwarf_error(NULL, error, DW_DLE_FUNC_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (func->gl_name); return DW_DLV_OK; } int dwarf_func_die_offset(Dwarf_Func func_in, Dwarf_Off * return_offset, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; return dwarf_global_die_offset(func, return_offset, error); } int dwarf_func_cu_offset(Dwarf_Func func_in, Dwarf_Off * return_offset, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; return dwarf_global_cu_offset(func, return_offset, error); } int dwarf_func_name_offsets(Dwarf_Func func_in, char **ret_func_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global func = (Dwarf_Global) func_in; return dwarf_global_name_offsets(func, ret_func_name, die_offset, cu_die_offset, error); } dwarfutils-20200114/libdwarf/dwarf_funcs.h000066400000000000000000000022571361531463500204120ustar00rootroot00000000000000/* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Func_Context_s *Dwarf_Func_Context; /* struct never completed: see dwarf_global.h */ dwarfutils-20200114/libdwarf/dwarf_gdbindex.c000066400000000000000000000423661361531463500210600ustar00rootroot00000000000000/* Copyright (C) 2014-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "memcpy_swap.h" #include "dwarf_gdbindex.h" #define TRUE 1 #define FALSE 0 /* The dwarf_util macro READ_UNALIGNED cannot be directly used because gdb defines the section contents of .gdb_index as little-endian always. */ #if WORDS_BIGENDIAN /* meaning on this host */ #define READ_GDBINDEX(dest,desttype, source, length) \ do { \ BIGGEST_UINT _ltmp = 0; \ _dwarf_memcpy_swap_bytes((((char *)(&_ltmp)) + sizeof(_ltmp) - length), \ source, length) ; \ dest = (desttype)_ltmp; \ } while (0) #else /* little-endian on this host */ #define READ_GDBINDEX(dest,desttype, source, length) \ do { \ BIGGEST_UINT _ltmp = 0; \ memcpy(((char *)(&_ltmp)) , \ source, length) ; \ dest = (desttype)_ltmp; \ } while (0) #endif struct gi_fileheader_s { char gfs [4][6]; }; struct dwarf_64bitpair { gdbindex_64 offset; gdbindex_64 length; }; static int set_base(Dwarf_Debug dbg, struct Dwarf_Gdbindex_array_instance_s * hdr, Dwarf_Small *start, Dwarf_Small *end, /* entrylen is the length of a single struct as seen in the object. */ Dwarf_Unsigned entrylen, /* The size of each field in the struct in the object. */ Dwarf_Unsigned fieldlen, enum gdbindex_type_e type, Dwarf_Error * err) { if (type == git_std || type == git_cuvec) { /* cuvec is sort of a fake as a simple section, but a useful one. */ Dwarf_Unsigned count = 0; if( end < start) { _dwarf_error(dbg, err,DW_DLE_GDB_INDEX_COUNT_ERROR); return DW_DLV_ERROR; } count = end - start; count = count / entrylen; hdr->dg_type = type; hdr->dg_base = start; hdr->dg_count = count; hdr->dg_entry_length = entrylen; hdr->dg_fieldlen = fieldlen; } else { /* address area. */ /* 64bit, 64bit, offset. Then 32bit pad. */ Dwarf_Unsigned count = 0; hdr->dg_base = start; if( end < start) { _dwarf_error(dbg, err,DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR); return DW_DLV_ERROR; } /* entry length includes pad. */ hdr->dg_entry_length = 2*sizeof(gdbindex_64) + DWARF_32BIT_SIZE; count = end - start; count = count / hdr->dg_entry_length; hdr->dg_count = count; /* The dg_fieldlen is a fake, the fields are not all the same length. */ hdr->dg_fieldlen = DWARF_32BIT_SIZE; hdr->dg_type = type; } return DW_DLV_OK; } int dwarf_gdbindex_header(Dwarf_Debug dbg, Dwarf_Gdbindex * gdbindexptr, Dwarf_Unsigned * version, Dwarf_Unsigned * cu_list_offset, Dwarf_Unsigned * types_cu_list_offset, Dwarf_Unsigned * address_area_offset, Dwarf_Unsigned * symbol_table_offset, Dwarf_Unsigned * constant_pool_offset, Dwarf_Unsigned * section_size, Dwarf_Unsigned * unused_reserved, const char ** section_name, Dwarf_Error * error) { struct gi_fileheader_s header; Dwarf_Gdbindex indexptr = 0; int res = DW_DLV_ERROR; if (!dbg->de_debug_gdbindex.dss_size) { return DW_DLV_NO_ENTRY; } if (!dbg->de_debug_gdbindex.dss_data) { res = _dwarf_load_section(dbg, &dbg->de_debug_gdbindex,error); if (res != DW_DLV_OK) { return res; } } if (dbg->de_debug_gdbindex.dss_size < sizeof(struct gi_fileheader_s) ) { _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_GDB_INDEX_SECTION); return (DW_DLV_ERROR); } memcpy(&header,dbg->de_debug_gdbindex.dss_data, sizeof(struct gi_fileheader_s)); indexptr = (Dwarf_Gdbindex)_dwarf_get_alloc(dbg,DW_DLA_GDBINDEX,1); if (indexptr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } indexptr->gi_dbg = dbg; indexptr->gi_section_data = dbg->de_debug_gdbindex.dss_data; indexptr->gi_section_length = dbg->de_debug_gdbindex.dss_size; READ_GDBINDEX(indexptr->gi_version ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_cu_list_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_types_cu_list_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 2*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_address_area_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 3*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_symbol_table_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 4*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_constant_pool_offset ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data + 5*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE); res = set_base(dbg,&indexptr->gi_culisthdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_cu_list_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset, 2*sizeof(gdbindex_64), sizeof(gdbindex_64), git_std,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_typesculisthdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset, 3*sizeof(gdbindex_64), sizeof(gdbindex_64), git_std,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_addressareahdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset, 3*sizeof(gdbindex_64), sizeof(gdbindex_64), git_address,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_symboltablehdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset, 2*DWARF_32BIT_SIZE, DWARF_32BIT_SIZE, git_std,error); if (res == DW_DLV_ERROR) { return res; } res = set_base(dbg,&indexptr->gi_cuvectorhdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset, /* There is no real single vector size. but we'll use the entire rest as if there was. */ dbg->de_debug_gdbindex.dss_data + indexptr->gi_section_length, DWARF_32BIT_SIZE, DWARF_32BIT_SIZE, git_cuvec,error); if (res == DW_DLV_ERROR) { return res; } /* Really just pointing to constant pool area. */ indexptr->gi_string_pool = dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset; *gdbindexptr = indexptr; *version = indexptr->gi_version; *cu_list_offset = indexptr->gi_cu_list_offset; *types_cu_list_offset = indexptr->gi_types_cu_list_offset; *address_area_offset = indexptr->gi_address_area_offset; *symbol_table_offset = indexptr->gi_symbol_table_offset; *constant_pool_offset = indexptr->gi_constant_pool_offset; *section_size = indexptr->gi_section_length; *unused_reserved = 0; *section_name = dbg->de_debug_gdbindex.dss_name; return DW_DLV_OK; } int dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_culisthdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * cu_offset, Dwarf_Unsigned * cu_length, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_culisthdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; unsigned fieldlen = gdbindexptr->gi_culisthdr.dg_fieldlen; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_culisthdr.dg_base; base += entryindex*gdbindexptr->gi_culisthdr.dg_entry_length; READ_GDBINDEX(offset ,Dwarf_Unsigned, base, fieldlen); READ_GDBINDEX(length ,Dwarf_Unsigned, base+ fieldlen, fieldlen); *cu_offset = offset; *cu_length = length; return DW_DLV_OK; } int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_typesculisthdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_types_culist_entry(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * t_offset, Dwarf_Unsigned * t_length, Dwarf_Unsigned * t_signature, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_typesculisthdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned signature = 0; unsigned fieldlen = gdbindexptr->gi_typesculisthdr.dg_fieldlen; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_typesculisthdr.dg_base; base += entryindex*gdbindexptr->gi_typesculisthdr.dg_entry_length; READ_GDBINDEX(offset ,Dwarf_Unsigned, base, fieldlen); READ_GDBINDEX(length ,Dwarf_Unsigned, base+ (1*fieldlen), fieldlen); READ_GDBINDEX(signature ,Dwarf_Unsigned, base+ (2*fieldlen), fieldlen); *t_offset = offset; *t_length = length; *t_signature = signature; return DW_DLV_OK; } int dwarf_gdbindex_addressarea(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_addressareahdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * low_address, Dwarf_Unsigned * high_address, Dwarf_Unsigned * cu_index, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_addressareahdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned lowaddr = 0; Dwarf_Unsigned highaddr = 0; Dwarf_Unsigned cuindex = 0; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_addressareahdr.dg_base; base += entryindex*gdbindexptr->gi_addressareahdr.dg_entry_length; READ_GDBINDEX(lowaddr ,Dwarf_Unsigned, base, sizeof(gdbindex_64)); READ_GDBINDEX(highaddr ,Dwarf_Unsigned, base+ (1*sizeof(gdbindex_64)), sizeof(gdbindex_64)); READ_GDBINDEX(cuindex ,Dwarf_Unsigned, base+ (2*sizeof(gdbindex_64)), DWARF_32BIT_SIZE); *low_address = lowaddr; *high_address = highaddr; *cu_index = cuindex; return DW_DLV_OK; } int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, UNUSEDARG Dwarf_Error * error) { *list_length = gdbindexptr->gi_symboltablehdr.dg_count; return DW_DLV_OK; } /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * string_offset, Dwarf_Unsigned * cu_vector_offset, Dwarf_Error * error) { Dwarf_Unsigned max = gdbindexptr->gi_symboltablehdr.dg_count; Dwarf_Small * base = 0; Dwarf_Unsigned symoffset = 0; Dwarf_Unsigned cuoffset = 0; unsigned fieldlen = gdbindexptr->gi_symboltablehdr.dg_fieldlen; if (entryindex >= max) { _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base = gdbindexptr->gi_symboltablehdr.dg_base; base += entryindex*gdbindexptr->gi_symboltablehdr.dg_entry_length; READ_GDBINDEX(symoffset ,Dwarf_Unsigned, base, fieldlen); READ_GDBINDEX(cuoffset ,Dwarf_Unsigned, base + fieldlen, fieldlen); *string_offset = symoffset; *cu_vector_offset = cuoffset; return DW_DLV_OK; } int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex gdbindex, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned * innercount, Dwarf_Error * error) { Dwarf_Small *base = gdbindex->gi_cuvectorhdr.dg_base; Dwarf_Small *end = gdbindex->gi_section_data + gdbindex->gi_section_length; Dwarf_Unsigned val = 0; unsigned fieldlen = gdbindex->gi_cuvectorhdr.dg_entry_length; base += cuvector_offset; if ((base + fieldlen) >= end) { _dwarf_error(gdbindex->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } READ_GDBINDEX(val,Dwarf_Unsigned, base, fieldlen); *innercount = val; return DW_DLV_OK; } int dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned innerindex, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_instance_expand_value() */ Dwarf_Unsigned * attributes, Dwarf_Error * error) { Dwarf_Small *base = gdbindexptr->gi_cuvectorhdr.dg_base; Dwarf_Small *end = gdbindexptr->gi_section_data + gdbindexptr->gi_section_length; Dwarf_Unsigned val = 0; unsigned fieldlen = gdbindexptr->gi_cuvectorhdr.dg_entry_length; base += cuvector_offset; if ((base+fieldlen) >= end) { _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } base += fieldlen; base += innerindex*fieldlen; READ_GDBINDEX(val ,Dwarf_Unsigned, base, fieldlen); *attributes = val; return DW_DLV_OK; } int dwarf_gdbindex_cuvector_instance_expand_value( UNUSEDARG Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned value, Dwarf_Unsigned * cu_index, Dwarf_Unsigned * reserved1, Dwarf_Unsigned * symbol_kind, Dwarf_Unsigned * is_static, UNUSEDARG Dwarf_Error * error) { *cu_index = value & 0xffffff; *reserved1 = (value >> 24) & 0xf; *symbol_kind = (value >> 28) & 0x7; *is_static = (value >> 31) & 1; return DW_DLV_OK; } /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned stringoffsetinpool, const char ** string_ptr, UNUSEDARG Dwarf_Error * error) { Dwarf_Small *pooldata = 0; Dwarf_Small *section_end = 0; Dwarf_Small *stringitself = 0; /* If gdbindexptr NULL or gdbindexptr->gi_dbg is NULL this is not going to go very well. Ugh. FIXME */ pooldata = gdbindexptr->gi_section_data + gdbindexptr->gi_constant_pool_offset; section_end = gdbindexptr->gi_section_data + gdbindexptr->gi_section_length; stringitself = pooldata + stringoffsetinpool; if (stringitself > section_end) { _dwarf_error(gdbindexptr->gi_dbg, error,DW_DLE_GDB_INDEX_INDEX_ERROR); return DW_DLV_ERROR; } *string_ptr = (const char *)stringitself; return DW_DLV_OK; } void dwarf_gdbindex_free(Dwarf_Gdbindex indexptr) { if(indexptr) { Dwarf_Debug dbg = indexptr->gi_dbg; dwarf_dealloc(dbg,indexptr,DW_DLA_GDBINDEX); } } dwarfutils-20200114/libdwarf/dwarf_gdbindex.h000066400000000000000000000055521361531463500210610ustar00rootroot00000000000000/* Copyright (C) 2014-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The following is based on The gdb online documentation at https://sourceware.org/gdb/onlinedocs/gdb/ Appendix J, ".gdb_index section format". */ /* These are the two types .gdb_index uses. the offset_type (32 bits) and other fields defined 64 bits. We use our own Dwarf_Unsigned for all the interfaces, these are just for reading the section data. The section data is defined to be in little-endian regardless of the target machine. We use our host endianness in all interfaces. We simply assume unsigned int is 32 bits FIXME. */ typedef unsigned int gdbindex_offset_type; typedef Dwarf_Unsigned gdbindex_64; enum gdbindex_type_e { git_unknown, git_std, git_address, git_cuvec }; struct Dwarf_Gdbindex_array_instance_s { Dwarf_Small * dg_base; Dwarf_Unsigned dg_count; /* the in_object struct size. */ Dwarf_Unsigned dg_entry_length; /* The size of a single field in the in-object struct */ int dg_fieldlen; /* The address_area type is a bit irregular. */ enum gdbindex_type_e dg_type; }; struct Dwarf_Gdbindex_s { Dwarf_Debug gi_dbg; Dwarf_Small * gi_section_data; Dwarf_Unsigned gi_section_length; Dwarf_Unsigned gi_version; Dwarf_Unsigned gi_cu_list_offset; Dwarf_Unsigned gi_types_cu_list_offset; Dwarf_Unsigned gi_address_area_offset; Dwarf_Unsigned gi_symbol_table_offset; Dwarf_Unsigned gi_constant_pool_offset; struct Dwarf_Gdbindex_array_instance_s gi_culisthdr; struct Dwarf_Gdbindex_array_instance_s gi_typesculisthdr; struct Dwarf_Gdbindex_array_instance_s gi_addressareahdr; struct Dwarf_Gdbindex_array_instance_s gi_symboltablehdr; struct Dwarf_Gdbindex_array_instance_s gi_cuvectorhdr; Dwarf_Small * gi_string_pool; }; dwarfutils-20200114/libdwarf/dwarf_generic_init.c000066400000000000000000000257421361531463500217320ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2011-2019 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif #endif #include #include #include #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_object_detector.h" #include "dwarf_elf_access.h" /* Needed while libelf in use */ #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ /* This is the initialization set intended to handle multiple object formats. Created September 2018 The init functions here cannot process archives. For archives the libelf-only dwarf_elf_init*() functions are used if present, else archives cannot be read. */ #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 /* An original basic dwarf initializer function for consumers. Return a libdwarf error code on error, return DW_DLV_OK if this succeeds. dwarf_init_b() is a better choice where there are section groups in an object file. */ int dwarf_init(int fd, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) { return dwarf_init_b(fd,access, DW_GROUPNUMBER_ANY, errhand,errarg,ret_dbg,error); } static int open_a_file(const char * name) { /* Set to a file number that cannot be legal. */ int fd = -1; #if HAVE_ELF_OPEN /* It is not possible to share file handles between applications or DLLs. Each application has its own file-handle table. For two applications to use the same file using a DLL, they must both open the file individually. Let the 'libelf' dll open and close the file. */ fd = elf_open(name, O_RDONLY | O_BINARY); #else fd = open(name, O_RDONLY | O_BINARY); #endif return fd; } static int set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error) { int res = 0; res = dwarf_add_debuglink_global_path(dbg, "/usr/lib/debug",error); return res; } /* New in December 2018. */ int dwarf_init_path(const char *path, char *true_path_out_buffer, unsigned true_path_bufferlen, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg, UNUSEDARG const char * reserved1, UNUSEDARG Dwarf_Unsigned reserved2, UNUSEDARG Dwarf_Unsigned * reserved3, Dwarf_Error* error) { unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; int res = 0; int errcode = 0; int fd = -1; Dwarf_Debug dbg = 0; char *file_path = 0; if (!ret_dbg) { DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR); } res = dwarf_object_detector_path(path, true_path_out_buffer, true_path_bufferlen, &ftype,&endian,&offsetsize,&filesize,&errcode); if (res == DW_DLV_NO_ENTRY) { return res; } if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(NULL, errcode, DW_DLV_ERROR); } if (true_path_out_buffer) { file_path = true_path_out_buffer; fd = open_a_file(true_path_out_buffer); } else { file_path = (char *)path; fd = open_a_file(path); } if(fd == -1) { DWARF_DBG_ERROR(NULL, DW_DLE_FILE_UNAVAILABLE, DW_DLV_ERROR); } switch(ftype) { case DW_FTYPE_ELF: { res = _dwarf_elf_nlsetup(fd, file_path, ftype,endian,offsetsize,filesize, access,groupnumber,errhand,errarg,&dbg,error); if (res != DW_DLV_OK) { *ret_dbg = dbg; close(fd); return res; } dbg->de_path = strdup(file_path); dbg->de_fd = fd; dbg->de_owns_fd = TRUE; res = set_global_paths_init(dbg,error); *ret_dbg = dbg; return res; } case DW_FTYPE_MACH_O: { res = _dwarf_macho_setup(fd, file_path, ftype,endian,offsetsize,filesize, access,groupnumber,errhand,errarg,&dbg,error); if (res != DW_DLV_OK) { close(fd); *ret_dbg = dbg; return res; } dbg->de_path = strdup(file_path); dbg->de_fd = fd; dbg->de_owns_fd = TRUE; set_global_paths_init(dbg,error); *ret_dbg = dbg; return res; } case DW_FTYPE_PE: { res = _dwarf_pe_setup(fd, file_path, ftype,endian,offsetsize,filesize, access,groupnumber,errhand,errarg,&dbg,error); if (res != DW_DLV_OK) { close(fd); *ret_dbg = dbg; } dbg->de_path = strdup(file_path); dbg->de_fd = fd; dbg->de_owns_fd = TRUE; set_global_paths_init(dbg,error); *ret_dbg = dbg; return res; } default: close(fd); DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); } return DW_DLV_NO_ENTRY; /* placeholder for now */ } /* New March 2017, this provides for reading object files with multiple elf section groups. */ int dwarf_init_b(int fd, Dwarf_Unsigned access, unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) { unsigned ftype = 0; unsigned endian = 0; unsigned offsetsize = 0; Dwarf_Unsigned filesize = 0; int res = 0; int errcode = 0; if (!ret_dbg) { DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR); } res = dwarf_object_detector_fd(fd, &ftype, &endian,&offsetsize,&filesize,&errcode); if (res == DW_DLV_NO_ENTRY) { return res; } else if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); } switch(ftype) { case DW_FTYPE_ELF: { int res2 = 0; res2 = _dwarf_elf_nlsetup(fd,"", ftype,endian,offsetsize,filesize, access,group_number,errhand,errarg,ret_dbg,error); if (res2 != DW_DLV_OK) { return res2; } set_global_paths_init(*ret_dbg,error); return res2; } case DW_FTYPE_MACH_O: { int resm = 0; resm = _dwarf_macho_setup(fd,"", ftype,endian,offsetsize,filesize, access,group_number,errhand,errarg,ret_dbg,error); if (resm != DW_DLV_OK) { return resm; } set_global_paths_init(*ret_dbg,error); return resm; } case DW_FTYPE_PE: { int resp = 0; resp = _dwarf_pe_setup(fd, "", ftype,endian,offsetsize,filesize, access,group_number,errhand,errarg,ret_dbg,error); if (resp != DW_DLV_OK) { return resp; } set_global_paths_init(*ret_dbg,error); return resp; } } DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); return res; } /* Frees all memory that was not previously freed by dwarf_dealloc. Aside from certain categories. Applicable when dwarf_init() or dwarf_elf_init() or the -b() form was used to init 'dbg'. */ int dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) { if(!dbg) { DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); } if (dbg->de_obj_file) { /* The initial character of a valid dbg->de_obj_file->object struct is a letter: E, F, M, or P */ char otype = *(char *)(dbg->de_obj_file->object); switch(otype) { case 'E': #ifdef DWARF_WITH_LIBELF dwarf_elf_object_access_finish(dbg->de_obj_file); #endif /* DWARF_WITH_LIBELF */ break; case 'F': /* Non-libelf elf access */ _dwarf_destruct_elf_nlaccess(dbg->de_obj_file); break; case 'M': _dwarf_destruct_macho_access(dbg->de_obj_file); break; case 'P': _dwarf_destruct_pe_access(dbg->de_obj_file); break; default: /* Do nothing. A serious internal error */ break; } } if (dbg->de_owns_fd) { close(dbg->de_fd); dbg->de_owns_fd = FALSE; } free((void *)dbg->de_path); dbg->de_path = 0; /* dwarf_object_finish() also frees de_path, but that is safe because we set it to zero here so no duplicate free will occur. Not all code uses libdwarf exactly as we do hence the free() there. */ return dwarf_object_finish(dbg, error); } /* tieddbg should be the executable or .o that has the .debug_addr section that the base dbg refers to. See Split Objects in DWARF5. Allows setting to NULL (NULL is the default of de_tied_data.td_tied_object). New September 2015. */ int 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); } dbg->de_tied_data.td_tied_object = tieddbg; if (tieddbg) { tieddbg->de_tied_data.td_is_tied_object = TRUE; } return DW_DLV_OK; } /* Unsure of the use-case of this. New September 2015. */ int dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out, UNUSEDARG Dwarf_Error*error) { *tieddbg_out = dbg->de_tied_data.td_tied_object; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_global.c000066400000000000000000000613741361531463500205340ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_global.h" #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ /* The 'fixup' here intended for IRIX targets only. With a 2+GB Elf64 IRIX executable (under 4GB in size), some DIE offsets wrongly got the 32bit upper bit sign extended. For the cu-header offset in the .debug_pubnames section and in the .debug_aranges section. the 'varp' here is a pointer to an offset into .debug_info. We fix up the offset here if it seems advisable.. As of June 2005 we have identified a series of mistakes in ldx64 that can cause this (64 bit values getting passed thru 32-bit signed knothole). */ void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, Dwarf_Unsigned * varp, char *caller_site_name) { Dwarf_Unsigned var = *varp; #define UPPER33 0xffffffff80000000LL #define LOWER32 0xffffffffLL /* Restrict the hack to the known case. Upper 32 bits erroneously sign extended from lower 32 upper bit. */ if ((var & UPPER33) == UPPER33) { var &= LOWER32; /* Apply the fix. Dreadful hack. */ *varp = var; } #undef UPPER33 #undef LOWER32 return; } #endif /* __sgi */ int dwarf_get_globals(Dwarf_Debug dbg, Dwarf_Global ** globals, Dwarf_Signed * return_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error); if (res != DW_DLV_OK) { return res = 0; } if (!dbg->de_debug_pubnames.dss_size) { return (DW_DLV_NO_ENTRY); } return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_pubnames.dss_data, dbg->de_debug_pubnames.dss_size, globals, return_count, error, DW_DLA_GLOBAL_CONTEXT, DW_DLA_GLOBAL, DW_DLE_PUBNAMES_LENGTH_BAD, DW_DLE_PUBNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, dwgl, count, DW_DLA_GLOBAL_CONTEXT, DW_DLA_GLOBAL, DW_DLA_LIST); return; } void _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, Dwarf_Signed count, int context_code, int global_code, int list_code) { Dwarf_Signed i; struct Dwarf_Global_Context_s *gcp = 0; struct Dwarf_Global_Context_s *lastgcp = 0; for (i = 0; i < count; i++) { Dwarf_Global dgb = dwgl[i]; gcp = dgb->gl_context; if (lastgcp != gcp) { lastgcp = gcp; dwarf_dealloc(dbg, gcp, context_code); } dwarf_dealloc(dbg, dgb, global_code); } dwarf_dealloc(dbg, dwgl, list_code); return; } /* Sweeps the complete section. */ int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, Dwarf_Small * section_data_ptr, Dwarf_Unsigned section_length, Dwarf_Global ** globals, Dwarf_Signed * return_count, Dwarf_Error * error, int context_code, int global_code, int length_err_num, int version_err_num) { Dwarf_Small *pubnames_like_ptr = 0; Dwarf_Off pubnames_section_offset = 0; Dwarf_Small *section_end_ptr = section_data_ptr +section_length; /* Points to the context for the current set of global names, and contains information to identify the compilation-unit that the set refers to. */ Dwarf_Global_Context pubnames_context = 0; Dwarf_Half version = 0; /* Offset from the start of compilation-unit for the current global. */ Dwarf_Off die_offset_in_cu = 0; Dwarf_Unsigned global_count = 0; /* Points to the current global read. */ Dwarf_Global global = 0; /* Used to chain the Dwarf_Global_s structs for creating contiguous list of pointers to the structs. */ Dwarf_Chain curr_chain = 0; Dwarf_Chain prev_chain = 0; Dwarf_Chain head_chain = 0; /* Points to contiguous block of Dwarf_Global's to be returned. */ Dwarf_Global *ret_globals = 0; /* Temporary counter. */ Dwarf_Unsigned i = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } /* We will eventually need the .debug_info data. Load it now. */ if (!dbg->de_debug_info.dss_data) { int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } } if (section_data_ptr == NULL) { return (DW_DLV_NO_ENTRY); } pubnames_like_ptr = section_data_ptr; do { Dwarf_Unsigned length = 0; int local_extension_size = 0; int local_length_size = 0; /* Some compilers emit padding at the end of each cu's area. pubnames_ptr_past_end_cu records the true area end for the pubnames(like) content of a cu. Essentially the length in the header and the 0 terminator of the data are redundant information. The dwarf2/3 spec does not mention what to do if the length is past the 0 terminator. So we take any bytes left after the 0 as padding and ignore them. */ Dwarf_Small *pubnames_ptr_past_end_cu = 0; pubnames_context = (Dwarf_Global_Context) _dwarf_get_alloc(dbg, context_code, 1); if (pubnames_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed bytes. */ READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, pubnames_like_ptr, local_length_size, local_extension_size,error,section_length,section_end_ptr); pubnames_context->pu_length_size = local_length_size; pubnames_context->pu_length = length; pubnames_context->pu_extension_size = local_extension_size; pubnames_context->pu_dbg = dbg; pubnames_context->pu_pub_offset = pubnames_section_offset; pubnames_ptr_past_end_cu = pubnames_like_ptr + length; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, pubnames_like_ptr, DWARF_HALF_SIZE, error,section_end_ptr); pubnames_context->pu_version = version; pubnames_like_ptr += DWARF_HALF_SIZE; /* ASSERT: DW_PUBNAMES_VERSION2 == DW_PUBTYPES_VERSION2 */ if (version != DW_PUBNAMES_VERSION2) { _dwarf_error(dbg, error, version_err_num); return (DW_DLV_ERROR); } /* Offset of CU header in debug section. */ READ_UNALIGNED_CK(dbg, pubnames_context->pu_offset_of_cu_header, Dwarf_Off, pubnames_like_ptr, pubnames_context->pu_length_size, error,section_end_ptr); pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, pubnames_context->pu_offset_of_cu_header, "pubnames cu header offset"); READ_UNALIGNED_CK(dbg, pubnames_context->pu_info_length, Dwarf_Unsigned, pubnames_like_ptr, pubnames_context->pu_length_size, error,section_end_ptr); pubnames_like_ptr += pubnames_context->pu_length_size; if (pubnames_like_ptr > (section_data_ptr + section_length)) { _dwarf_error(dbg, error, length_err_num); return (DW_DLV_ERROR); } /* Read initial offset (of DIE within CU) of a pubname, final entry is not a pair, just a zero offset. */ READ_UNALIGNED_CK(dbg, die_offset_in_cu, Dwarf_Off, pubnames_like_ptr, pubnames_context->pu_length_size, error,section_end_ptr); pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, die_offset_in_cu, "offset of die in cu"); if (pubnames_like_ptr > (section_data_ptr + section_length)) { _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; } /* Loop thru pairs. DIE off with CU followed by string. */ if (dbg->de_return_empty_pubnames && die_offset_in_cu == 0) { /* Here we have a pubnames CU with no actual entries so we fake up an entry to hold the header data. There are no 'pairs' here, just the end of list zero value. We do this only if de_return_empty_pubnames is set so that we by default return exactly the same data this always returned, yet dwarfdump can request the empty-cu records get created to test that feature. see dwarf_get_globals_header() */ global = (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1); if (global == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } global_count++; global->gl_context = pubnames_context; global->gl_named_die_offset_within_cu = 0; global->gl_name = (Dwarf_Small *)""; /* Finish off current entry chain */ curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Put current global on singly_linked list. */ curr_chain->ch_item = (Dwarf_Global) global; if (head_chain == NULL) head_chain = prev_chain = curr_chain; else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } /* There is no next entry, we are at it already */ } while (die_offset_in_cu != 0) { int res; /* Already read offset, pubnames_like_ptr now points to the string. */ global = (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1); if (global == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } global_count++; global->gl_context = pubnames_context; global->gl_named_die_offset_within_cu = die_offset_in_cu; global->gl_name = pubnames_like_ptr; res = _dwarf_check_string_valid(dbg,section_data_ptr, pubnames_like_ptr,section_end_ptr, DW_DLE_STRING_OFF_END_PUBNAMES_LIKE,error); if (res != DW_DLV_OK) { return res; } pubnames_like_ptr = pubnames_like_ptr + strlen((char *) pubnames_like_ptr) + 1; /* Finish off current entry chain */ curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Put current global on singly_linked list. */ curr_chain->ch_item = (Dwarf_Global) global; if (head_chain == NULL) head_chain = prev_chain = curr_chain; else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } /* Read offset for the *next* entry */ READ_UNALIGNED_CK(dbg, die_offset_in_cu, Dwarf_Off, pubnames_like_ptr, pubnames_context->pu_length_size, error,section_end_ptr); pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, die_offset_in_cu, "offset of next die in cu"); if (pubnames_like_ptr > (section_data_ptr + section_length)) { _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; } } /* ASSERT: die_offset_in_cu == 0 */ if (pubnames_like_ptr > pubnames_ptr_past_end_cu) { /* This is some kind of error. This simply cannot happen. The encoding is wrong or the length in the header for this cu's contribution is wrong. */ _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; } /* If there is some kind of padding at the end of the section, as emitted by some compilers, skip over that padding and simply ignore the bytes thus passed-over. With most compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at this point */ { Dwarf_Unsigned increment = pubnames_context->pu_length_size + pubnames_context->pu_length + pubnames_context->pu_extension_size; pubnames_section_offset += increment; } pubnames_like_ptr = pubnames_ptr_past_end_cu; } while (pubnames_like_ptr < section_end_ptr); /* Points to contiguous block of Dwarf_Global's. */ ret_globals = (Dwarf_Global *) _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count); if (ret_globals == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Store pointers to Dwarf_Global_s structs in contiguous block, and deallocate the chain. This ignores the various headers */ curr_chain = head_chain; for (i = 0; i < global_count; i++) { *(ret_globals + i) = curr_chain->ch_item; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } *globals = ret_globals; *return_count = (Dwarf_Signed) global_count; return DW_DLV_OK; } /* Given a pubnames entry (or other like section entry) return thru the ret_name pointer a pointer to the string which is the entry name. */ int dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error) { if (glob == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (glob->gl_name); return DW_DLV_OK; } /* Given a pubnames entry (or other like section entry) return thru the ret_off pointer the global offset of the DIE for this entry. The global offset is the offset within the .debug_info section as a whole. */ int dwarf_global_die_offset(Dwarf_Global global, Dwarf_Off * ret_off, Dwarf_Error * error) { if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return (DW_DLV_ERROR); } if (global->gl_context == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return (DW_DLV_ERROR); } *ret_off = (global->gl_named_die_offset_within_cu + global->gl_context->pu_offset_of_cu_header); return DW_DLV_OK; } /* Given a pubnames entry (or other like section entry) return thru the ret_off pointer the offset of the compilation unit header of the compilation unit the global is part of. In early versions of this, the value returned was the offset of the compilation unit die, and other cu-local die offsets were faked so adding this to such a cu-local offset got a true section offset. Now things do as they say (adding *cu_header_offset to a cu-local offset gets the section offset). */ int dwarf_global_cu_offset(Dwarf_Global global, Dwarf_Off * cu_header_offset, Dwarf_Error * error) { Dwarf_Global_Context con = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return (DW_DLV_ERROR); } con = global->gl_context; if (con == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return (DW_DLV_ERROR); } /* In early libdwarf, this incorrectly returned the offset of the CU DIE. Now correctly returns the header offset. */ *cu_header_offset = con->pu_offset_of_cu_header; return DW_DLV_OK; } /* Give back the pubnames entry (or any other like section) name, symbol DIE offset, and the cu-DIE offset. Various errors are possible. The string pointer returned thru ret_name is not dwarf_get_alloc()ed, so no dwarf_dealloc() DW_DLA_STRING should be applied to it. */ int dwarf_global_name_offsets(Dwarf_Global global, char **ret_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global_Context con = 0; Dwarf_Debug dbg = 0; Dwarf_Off cuhdr_off = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return (DW_DLV_ERROR); } con = global->gl_context; if (con == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return (DW_DLV_ERROR); } cuhdr_off = con->pu_offset_of_cu_header; /* The offset had better not be too close to the end. If it is, _dwarf_length_of_cu_header() will step off the end and therefore must not be used. 10 is a meaningless heuristic, but no CU header is that small so it is safe. An erroneous offset is due to a bug in the tool chain. A bug like this has been seen on IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and with 2 million pubnames entries. */ #define MIN_CU_HDR_SIZE 10 dbg = con->pu_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } /* Cannot refer to debug_types */ if (dbg->de_debug_info.dss_size && ((cuhdr_off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) { _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); return (DW_DLV_ERROR); } #undef MIN_CU_HDR_SIZE /* If global->gl_named_die_offset_within_cu is zero then this is a fake global for a pubnames CU with no pubnames. The offset is from the start of the CU header, so no die can have a zero offset, all valid offsets are positive numbers */ if (die_offset) { if(global->gl_named_die_offset_within_cu) { *die_offset = global->gl_named_die_offset_within_cu + cuhdr_off; } else { *die_offset = 0; } } *ret_name = (char *) global->gl_name; if (cu_die_offset) { /* Globals cannot refer to debug_types */ int cres = 0; Dwarf_Unsigned headerlen = 0; int res = _dwarf_load_debug_info(dbg, error); if (res != DW_DLV_OK) { return res; } /* The offset had better not be too close to the end. If it is, _dwarf_length_of_cu_header() will step off the end and therefore must not be used. 10 is a meaningless heuristic, but no CU header is that small so it is safe. */ /* Globals cannot refer to debug_types */ if ((cuhdr_off + 10) >= dbg->de_debug_info.dss_size) { _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); return (DW_DLV_ERROR); } cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,true, &headerlen,error); if(cres != DW_DLV_OK) { return cres; } *cu_die_offset = cuhdr_off + headerlen; } return DW_DLV_OK; } /* New February 2019 from better dwarfdump printing of debug_pubnames and pubtypes. For ao the Dwarf_Global records in one pubnames CU group exactly the same data will be returned. */ int dwarf_get_globals_header(Dwarf_Global global, Dwarf_Off *pub_section_hdr_offset, Dwarf_Unsigned *pub_offset_size, Dwarf_Unsigned *pub_cu_length, Dwarf_Unsigned *version, Dwarf_Off *info_header_offset, Dwarf_Unsigned *info_length, Dwarf_Error* error) { Dwarf_Global_Context con = 0; Dwarf_Debug dbg = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); return DW_DLV_ERROR; } con = global->gl_context; if (con == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); return DW_DLV_ERROR; } dbg = con->pu_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if(pub_section_hdr_offset) { *pub_section_hdr_offset = con->pu_pub_offset; } if (pub_offset_size) { *pub_offset_size = con->pu_length_size; } if (pub_cu_length) { *pub_cu_length = con->pu_length; } if (version) { *version = con->pu_version; } if(info_header_offset) { *info_header_offset = con->pu_offset_of_cu_header; } if (info_length) { *info_length = con->pu_info_length; } return DW_DLV_OK; } /* We have the offset to a CU header. Return thru outFileOffset the offset of the CU DIE. New June, 2001. Used by SGI IRIX debuggers. No error used to be possible. As of May 2016 an error is possible if the DWARF is corrupted! (IRIX debuggers are no longer built ...) See also dwarf_CU_dieoffset_given_die(). This is assumed to never apply to data in .debug_types, it only refers to .debug_info. */ /* ARGSUSED */ int dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Off * out_cu_die_offset, UNUSEDARG Dwarf_Error * err) { Dwarf_Off headerlen = 0; int cres = 0; cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,true, &headerlen,err); if (cres != DW_DLV_OK) { return cres; } *out_cu_die_offset = in_cu_header_offset + headerlen; return DW_DLV_OK; } /* The following version new in October 2011, does allow finding the offset if one knows whether debug_info or debug_types. However, it is not accurate in DWARF5 because there are two different header lengths (CU and TU) in DWARF5 .debug_info. In that case, pretend that it's .debug_types (here) and pass is_info zero for a TU (as if it was in .debug_types). */ int dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, Dwarf_Off * out_cu_die_offset, UNUSEDARG Dwarf_Error * err) { Dwarf_Off headerlen = 0; int cres = 0; cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,is_info, &headerlen,err); if (cres != DW_DLV_OK) { return cres; } *out_cu_die_offset = in_cu_header_offset + headerlen; return DW_DLV_OK; } /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given (passed-in) die. This information makes it possible for a consumer to find and print context information for any die. Use dwarf_offdie() passing in the offset this returns to get a die pointer to the CU die. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die die, Dwarf_Off* return_offset, Dwarf_Error* error) { Dwarf_Off dieoff = 0; Dwarf_CU_Context cucontext = 0; CHECK_DIE(die, DW_DLV_ERROR); cucontext = die->di_cu_context; dieoff = cucontext->cc_debug_offset; /* The following call cannot fail, so no error check. */ dwarf_get_cu_die_offset_given_cu_header_offset_b( cucontext->cc_dbg, dieoff, die->di_is_info, return_offset,error); return DW_DLV_OK; } int dwarf_return_empty_pubnames(Dwarf_Debug dbg, int flag , Dwarf_Error* error) { if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (flag && flag != 1) { _dwarf_error(NULL, error,DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR); return DW_DLV_ERROR; } dbg->de_return_empty_pubnames = (unsigned char)flag; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_global.h000066400000000000000000000071101361531463500205250ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Global_Context_s *Dwarf_Global_Context; /* This struct contains header information for a set of pubnames. Essentially, they contain the context for a set of pubnames belonging to a compilation-unit. This is also used for the sgi-specific weaknames, typenames, varnames, funcnames data: the structs for those are incomplete and instances of this are used instead. Also used for DWARF3 .debug_pubtypes. These never refer to .debug_types, only to .debug_info. */ struct Dwarf_Global_Context_s { /* For this context, size of a length. 4 or 8 */ unsigned char pu_length_size; /* Size of the pubnames data for the CU */ unsigned char pu_length; /* For this CU, size of the extension 0 except for dwarf2 extension 64bit, in which case is 4. */ unsigned char pu_extension_size; Dwarf_Half pu_version; /* 2,3, or 4 */ /* offset in pubnames of the pu header. */ Dwarf_Off pu_pub_offset; /* Offset into .debug_info of the compilation-unit header (not DIE) for this set of pubnames. */ Dwarf_Off pu_offset_of_cu_header; /* Size of compilation-unit that these pubnames are in. */ Dwarf_Unsigned pu_info_length; Dwarf_Debug pu_dbg; }; /* This struct contains information for a single pubname. */ struct Dwarf_Global_s { /* Offset from the start of the corresponding compilation-unit of the DIE for the given pubname CU. */ Dwarf_Off gl_named_die_offset_within_cu; /* Points to the given pubname. */ Dwarf_Small *gl_name; /* Context for this pubname. */ Dwarf_Global_Context gl_context; }; int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, Dwarf_Small * section_data_ptr, Dwarf_Unsigned section_length, Dwarf_Global ** globals, Dwarf_Signed * return_count, Dwarf_Error * error, int context_code, int global_code, int length_err_num, int version_err_num); void _dwarf_internal_globals_dealloc( Dwarf_Debug dbg, Dwarf_Global *dwgl, Dwarf_Signed count, int context_code, int global_code, int list_code); #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, Dwarf_Unsigned *varp, char *caller_site_name); #define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) _dwarf_fix_up_offset_irix(ldbg,&var,name) #else /* ! __sgi */ #define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) #endif /* __sgi */ dwarfutils-20200114/libdwarf/dwarf_groups.c000066400000000000000000000251641361531463500206100ustar00rootroot00000000000000/* Copyright (C) 2017-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_tsearch.h" #define TRUE 1 #define FALSE 0 #define HASHSEARCH /* It has not escaped our attention that the section-group tsearch hash table could be replaced by a simple array with space for each possible section number, each element being the group number. This would be much simpler than what follows here. */ /* Each section number can appear in at most one record in the hash because each section belongs in only one group. Each group number appears as often as appropriate. */ struct Dwarf_Group_Map_Entry_s { unsigned gm_key; /* section number */ unsigned gm_group_number; /* What group number is. */ /* The name is from static storage or from elf, so there is nothing to free on record delete. */ const char * gm_section_name; }; static void * grp_make_entry(unsigned section, unsigned group,const char *name) { struct Dwarf_Group_Map_Entry_s *e = 0; e = calloc(1,sizeof(struct Dwarf_Group_Map_Entry_s)); if(e) { e->gm_key = section; e->gm_group_number = group; e->gm_section_name = name; } return e; } static DW_TSHASHTYPE grp_data_hashfunc(const void *keyp) { const struct Dwarf_Group_Map_Entry_s * enp = keyp; DW_TSHASHTYPE hashv = 0; hashv = enp->gm_key; return hashv; } static int grp_compare_function(const void *l, const void *r) { const struct Dwarf_Group_Map_Entry_s * lp = l; const struct Dwarf_Group_Map_Entry_s * rp = r; if (lp->gm_key < rp->gm_key) { return -1; } if (lp->gm_key > rp->gm_key) { return 1; } /* match. */ return 0; } static void _dwarf_grp_destroy_free_node(void*nodep) { struct Dwarf_Group_Map_Entry_s * enp = nodep; free(enp); return; } int _dwarf_insert_in_group_map(Dwarf_Debug dbg, unsigned groupnum, unsigned section_index, const char *name, Dwarf_Error * error) { struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; void *entry2 = 0; struct Dwarf_Group_Map_Entry_s * entry3 = 0; if (!grp->gd_map) { /* Number of sections is a kind of decent guess as to how much space would be useful. */ dwarf_initialize_search_hash(&grp->gd_map, grp_data_hashfunc,grp->gd_number_of_sections); if (!grp->gd_map) { /* It's really an error I suppose. */ return DW_DLV_NO_ENTRY; } } entry3 = grp_make_entry(section_index,groupnum,name); if (!entry3) { _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_ALLOC); return DW_DLV_ERROR; } entry2 = dwarf_tsearch(entry3,&grp->gd_map,grp_compare_function); if (!entry2) { free(entry3); _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_ALLOC); return DW_DLV_ERROR; } else { struct Dwarf_Group_Map_Entry_s *re = 0; re = *(struct Dwarf_Group_Map_Entry_s **)entry2; if (re != entry3) { free(entry3); _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_DUPLICATE); return DW_DLV_ERROR; } else { ++grp->gd_map_entry_count; /* OK. Added. Fall thru */ } } return DW_DLV_OK; } int _dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, unsigned obj_section_index, unsigned * groupnumber_out, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Group_Map_Entry_s entry; struct Dwarf_Group_Map_Entry_s *entry2; struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; if (!grp->gd_map) { return DW_DLV_NO_ENTRY; } entry.gm_key = obj_section_index; entry.gm_group_number = 0; /* FAKE */ entry.gm_section_name = ""; /* FAKE */ entry2 = dwarf_tfind(&entry, &grp->gd_map,grp_compare_function); if (entry2) { struct Dwarf_Group_Map_Entry_s *e2 = *(struct Dwarf_Group_Map_Entry_s **)entry2;; *groupnumber_out = e2->gm_group_number; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* 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, Dwarf_Unsigned * section_count_out, Dwarf_Unsigned * group_count_out, Dwarf_Unsigned * selected_group_out, Dwarf_Unsigned * map_entry_count_out, UNUSEDARG Dwarf_Error * error) { struct Dwarf_Group_Data_s *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; *map_entry_count_out = grp->gd_map_entry_count; return DW_DLV_OK; } static Dwarf_Unsigned map_reccount = 0; static struct temp_map_struc_s { Dwarf_Unsigned section; Dwarf_Unsigned group; const char *name; } *temp_map_data; static void grp_walk_map(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { struct Dwarf_Group_Map_Entry_s *re = 0; re = *(struct Dwarf_Group_Map_Entry_s **)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } temp_map_data[map_reccount].group = re->gm_group_number; temp_map_data[map_reccount].section = re->gm_key; temp_map_data[map_reccount].name = re->gm_section_name; map_reccount += 1; } /* Looks better sorted by group then sec num. */ static int map_sort_compar(const void*l, const void*r) { struct temp_map_struc_s *lv = (struct temp_map_struc_s *)l; struct temp_map_struc_s *rv = (struct temp_map_struc_s *)r; if (lv->group < rv->group) { return -1; } if (lv->group > rv->group) { return 1; } if (lv->section < rv->section) { return -1; } if (lv->section > rv->section) { return 1; } /* Should never get here! */ return 0; } /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' 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, Dwarf_Unsigned map_entry_count, Dwarf_Unsigned * group_numbers_array, Dwarf_Unsigned * sec_numbers_array, const char ** sec_names_array, Dwarf_Error * error) { Dwarf_Unsigned i = 0; struct Dwarf_Group_Data_s *grp = 0; if(temp_map_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } map_reccount = 0; grp = &dbg->de_groupnumbers; if (map_entry_count < grp->gd_map_entry_count) { _dwarf_error(dbg,error,DW_DLE_GROUP_COUNT_ERROR); return DW_DLV_ERROR; } temp_map_data = calloc(map_entry_count,sizeof(struct temp_map_struc_s)); if(!temp_map_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_MAP_ALLOC); return DW_DLV_ERROR; } dwarf_twalk(grp->gd_map,grp_walk_map); if (map_reccount != grp->gd_map_entry_count) { /* Impossible. */ _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } qsort(temp_map_data,map_reccount,sizeof(struct temp_map_struc_s), map_sort_compar); for (i =0 ; i < map_reccount; ++i) { sec_numbers_array[i] = temp_map_data[i].section; group_numbers_array[i] = temp_map_data[i].group; sec_names_array[i] = temp_map_data[i].name; } free(temp_map_data); map_reccount = 0; temp_map_data = 0; return DW_DLV_OK; } static const char *dwo_secnames[] = { ".debug_info.dwo", ".debug_types.dwo", ".debug_abbrev.dwo", ".debug_line.dwo", ".debug_loc.dwo", ".debug_str.dwo", ".debug_loclists.dwo", ".debug_rnglists.dwo", ".debug_str_offsets.dwo", ".debug_macro.dwo", ".debug_cu_index", ".debug_tu_index", 0 }; /* Assumption: dwo sections are never in a COMDAT group (groupnumber >2) and by definition here are never group 1. Assumption: the map of COMDAT groups (not necessarily all sections, but at least all COMDAT) is complete. */ int _dwarf_dwo_groupnumber_given_name( const char *name, unsigned *grpnum_out) { const char **s = 0; for (s = dwo_secnames; *s; s++) { if(!strcmp(name,*s)) { *grpnum_out = DW_GROUPNUMBER_DWO; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } static unsigned target_group = 0; static int found_name_in_group = 0; const char *lookfor_name = 0; static void grp_walk_for_name(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth) { struct Dwarf_Group_Map_Entry_s *re = 0; re = *(struct Dwarf_Group_Map_Entry_s **)nodep; if (which == dwarf_postorder || which == dwarf_endorder) { return; } if (re->gm_group_number == target_group) { if(!strcmp(lookfor_name,re->gm_section_name)) { found_name_in_group = TRUE; } } } /* returns TRUE or FALSE */ int _dwarf_section_in_group_by_name(Dwarf_Debug dbg, const char * scn_name, unsigned groupnum) { struct Dwarf_Group_Data_s *grp = 0; grp = &dbg->de_groupnumbers; found_name_in_group = FALSE; target_group = groupnum; lookfor_name = scn_name; dwarf_twalk(grp->gd_map,grp_walk_for_name); return found_name_in_group; } void _dwarf_destroy_group_map(Dwarf_Debug dbg) { dwarf_tdestroy(dbg->de_groupnumbers.gd_map,_dwarf_grp_destroy_free_node); dbg->de_groupnumbers.gd_map = 0; } dwarfutils-20200114/libdwarf/dwarf_harmless.c000066400000000000000000000164771361531463500211160ustar00rootroot00000000000000/* Copyright (C) 2010-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This implements _dwarf_insert_harmless_error and related helper functions for recording compiler errors that need not make the input unusable. Applications can use dwarf_get_harmless_error_list to find (and possibly print) a warning about such errors. The initial error reported here is DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE which was a bug in a specific compiler. It is a fixed length circular list to constrain the space used for errors. The assumption is that these errors are exceedingly rare, and indicate a broken compiler (the one that produced the object getting the error(s)). dh_maxcount is recorded internally as 1 greater than requested. Hiding the fact we always leave one slot unused (at least). So a user request for N slots really gives the user N usable slots. */ #include "config.h" #include "dwarf_incl.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_frame.h" #include "dwarf_harmless.h" /* 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, unsigned count, const char ** errmsg_ptrs_array, unsigned * errs_count) { struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; if (!dhp->dh_errors) { dhp->dh_errs_count = 0; return DW_DLV_NO_ENTRY; } if (dhp->dh_errs_count == 0) { return DW_DLV_NO_ENTRY; } if (errs_count) { *errs_count = dhp->dh_errs_count; } if (count) { /* NULL terminate the array of pointers */ --count; errmsg_ptrs_array[count] = 0; if (dhp->dh_next_to_use != dhp->dh_first) { unsigned i = 0; unsigned cur = dhp->dh_first; for (i = 0; cur != dhp->dh_next_to_use; ++i) { if (i >= count ) { /* All output spaces are used. */ break; } errmsg_ptrs_array[i] = dhp->dh_errors[cur]; cur = (cur +1) % dhp->dh_maxcount; } errmsg_ptrs_array[i] = 0; } } dhp->dh_next_to_use = 0; dhp->dh_first = 0; dhp->dh_errs_count = 0; return DW_DLV_OK; } /* strncpy does not null-terminate, this does it. */ static void safe_strncpy(char *targ, char *src, unsigned spaceavail) { unsigned goodcount = spaceavail-1; if (spaceavail < 1) { return; /* impossible */ } strncpy(targ,src,goodcount); targ[goodcount] = 0; } /* 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, char *newerror) { struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; unsigned next = 0; unsigned cur = dhp->dh_next_to_use; char *msgspace; if (!dhp->dh_errors) { dhp->dh_errs_count++; return; } msgspace = dhp->dh_errors[cur]; safe_strncpy(msgspace, newerror,DW_HARMLESS_ERROR_MSG_STRING_SIZE); next = (cur+1) % dhp->dh_maxcount; dhp->dh_errs_count++; dhp->dh_next_to_use = next; if (dhp->dh_next_to_use == dhp->dh_first) { /* Array is full set full invariant. */ dhp->dh_first = (dhp->dh_first+1) % dhp->dh_maxcount; } } /* The size of the circular list of strings may be set and reset as desired. Returns the previous size of the list. If the list is shortened excess error entries are simply dropped. If the reallocation fails the list size is left unchanged. Do not make this a long list! 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 maxcount ) { struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; unsigned prevcount = dhp->dh_maxcount; if (maxcount != 0) { ++maxcount; if (maxcount != dhp->dh_maxcount) { /* Assign transfers 'ownership' of the malloc areas to oldarray. */ struct Dwarf_Harmless_s oldarray = *dhp; /* Do not double increment the max, the init() func increments it too. */ dwarf_harmless_init(dhp,maxcount-1); if (oldarray.dh_next_to_use != oldarray.dh_first) { unsigned i = 0; for (i = oldarray.dh_first; i != oldarray.dh_next_to_use; i = (i+1)%oldarray.dh_maxcount) { dwarf_insert_harmless_error(dbg,oldarray.dh_errors[i]); } if (oldarray.dh_errs_count > dhp->dh_errs_count) { dhp->dh_errs_count = oldarray.dh_errs_count; } } dwarf_harmless_cleanout(&oldarray); } } return prevcount-1; } /* Only callable from within libdwarf (as a practical matter) */ void dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size) { unsigned i = 0; memset(dhp,0,sizeof(*dhp)); dhp->dh_maxcount = size +1; dhp->dh_errors = (char **)malloc(sizeof( char *) *dhp->dh_maxcount); if (!dhp->dh_errors) { dhp->dh_maxcount = 0; return; } for (i = 0; i < dhp->dh_maxcount; ++i) { char *newstr = (char *)malloc(DW_HARMLESS_ERROR_MSG_STRING_SIZE); dhp->dh_errors[i] = newstr; if (!newstr) { dhp->dh_maxcount = 0; /* Let it leak, the leak is a constrained amount. */ dhp->dh_errors = 0; return; } /* We make the string content well-defined by an initial NUL byte, but this is not really necessary. */ newstr[0] = 0; } } void dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp) { unsigned i = 0; if (!dhp->dh_errors) { return; } for (i = 0; i < dhp->dh_maxcount; ++i) { free(dhp->dh_errors[i]); dhp->dh_errors[i] = 0; } free(dhp->dh_errors); dhp->dh_errors = 0; dhp->dh_maxcount = 0; } dwarfutils-20200114/libdwarf/dwarf_harmless.h000066400000000000000000000022661361531463500211120ustar00rootroot00000000000000/* Copyright (C) 2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ void dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size); void dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp); dwarfutils-20200114/libdwarf/dwarf_incl.h000066400000000000000000000033611361531463500202160ustar00rootroot00000000000000/* Copyright (C) 2000, 2002, 2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2008-2010 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_INCL_H #define DWARF_INCL_H #if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) /* At a certain point libelf.h requires _GNU_SOURCE. here we assume the criteria in configure determined that usefully. */ #define _GNU_SOURCE 1 #endif /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarfdefs.h" #include /* strcpy() strlen() */ #include #include "dwarf.h" #include "libdwarf.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #endif /* DWARF_INCL_H */ dwarfutils-20200114/libdwarf/dwarf_init_finish.c000066400000000000000000002130221361531463500215640ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. Portions Copyright (C) 2009-2019 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 and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "memcpy_swap.h" #include "dwarf_harmless.h" /* For consistency, use the HAVE_LIBELF_H symbol */ #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif #endif #ifdef HAVE_ZLIB #include "zlib.h" #endif #ifndef ELFCOMPRESS_ZLIB #define ELFCOMPRESS_ZLIB 1 #endif /* If your mingw elf.h is missing SHT_RELA and you do not need SHT_RELA support this define should work for you. It is the elf value, hopefully it will not cause trouble. If does not work, try -1 or something else and let us know what works. */ #ifndef SHT_RELA #define SHT_RELA 4 #endif /* For COMDAT GROUPS. Guarantees we can compile. We hope. */ #ifndef SHT_GROUP #define SHT_GROUP 17 #endif #ifndef SHF_COMPRESSED /* This from ubuntu xenial. Is in top of trunk binutils as of February 2016. Elf Section Flag */ #define SHF_COMPRESSED (1 << 11) #endif #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 /* Global definition of the function pointer type, typedef in dwarf_opaque.h */ _dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr; /* This static is copied to the dbg on dbg init so that the static need not be referenced at run time, preserving better locality of reference. Value is 0 means do the string check. Value non-zero means do not do the check. */ static Dwarf_Small _dwarf_assume_string_in_bounds; static Dwarf_Small _dwarf_apply_relocs = 1; /* Call this after calling dwarf_init but before doing anything else. It applies to all objects, not just the current object. */ int dwarf_set_reloc_application(int apply) { int oldval = _dwarf_apply_relocs; _dwarf_apply_relocs = apply; return oldval; } int dwarf_set_stringcheck(int newval) { int oldval = _dwarf_assume_string_in_bounds; _dwarf_assume_string_in_bounds = newval; return oldval; } static int startswith(const char * input, char* ckfor) { size_t cklen = strlen(ckfor); if (! strncmp(input,ckfor,cklen)) { return TRUE; } return FALSE; } #if 0 static int endswith(const char * input, char* ckfor) { size_t inlen = strlen(input); size_t endlen = strlen(ckfor); const char * endck = 0; if (endlen > inlen) { return FALSE; } endck = input+inlen - endlen; if (! strcmp(endck,ckfor) ) { return TRUE; } return FALSE; } #endif /* Unifies the basic duplicate/empty testing and section data setting to one place. */ static int get_basic_section_data(Dwarf_Debug dbg, struct Dwarf_Section_s *secdata, struct Dwarf_Obj_Access_Section_s *doas, Dwarf_Half section_index, unsigned group_number, Dwarf_Error* error, int duperr, int emptyerr ) { /* There is an elf convention that section index 0 is reserved, and that section is always empty. Non-elf object formats must honor that by ensuring that (when they assign numbers to 'sections' or 'section-like-things') they never assign a real section section-number 0 to dss_index. */ if (secdata->dss_index != 0) { DWARF_DBG_ERROR(dbg, duperr, DW_DLV_ERROR); } if (doas->size == 0) { /* As of 2018 it seems impossible to detect (via dwarfdump) whether emptyerr has any practical effect, whether TRUE or FALSE. */ if (emptyerr == 0 ) { /* Allow empty section. */ return DW_DLV_OK; } /* Know no reason to allow section */ DWARF_DBG_ERROR(dbg, emptyerr, DW_DLV_ERROR); } secdata->dss_index = section_index; secdata->dss_size = doas->size; secdata->dss_group_number = group_number; secdata->dss_addr = doas->addr; secdata->dss_link = doas->link; secdata->dss_entrysize = doas->entrysize; if (_dwarf_get_elf_flags_func_ptr) { /* We do this so we do not need to update the public struct Dwarf_Obj_Access_Section_s and thereby cause binary and source incompatibility. */ Dwarf_Unsigned flags = 0; Dwarf_Unsigned addralign = 0; int res = 0; int interr = 0; struct Dwarf_Obj_Access_Interface_s *o = 0; o = dbg->de_obj_file; res = _dwarf_get_elf_flags_func_ptr( o->object, section_index, &flags,&addralign, &interr); if (res == DW_DLV_ERROR) { /* Should never get here. */ DWARF_DBG_ERROR(dbg, interr, DW_DLV_ERROR); } if (res == DW_DLV_NO_ENTRY) { return res; } secdata->dss_flags = flags; secdata->dss_addralign = addralign; if (flags & SHF_COMPRESSED) { secdata->dss_shf_compressed = TRUE; } /* We are not looking at section bytes so we do not know if the first 4 bytes are ZLIB */ } return DW_DLV_OK; } static void add_rela_data_to_secdata( struct Dwarf_Section_s *secdata, struct Dwarf_Obj_Access_Section_s *doas, Dwarf_Half section_index) { secdata->dss_reloc_index = section_index; secdata->dss_reloc_size = doas->size; secdata->dss_reloc_entrysize = doas->entrysize; secdata->dss_reloc_addr = doas->addr; secdata->dss_reloc_symtab = doas->link; secdata->dss_reloc_link = doas->link; } /* Used to add the specific information for a debug related section Called on each section of interest by section name. DWARF_MAX_DEBUG_SECTIONS must be large enough to allow that all sections of interest fit in the table. returns DW_DLV_ERROR or DW_DLV_OK. */ static int add_debug_section_info(Dwarf_Debug dbg, /* Name as seen in object file. */ const char *name, const char *standard_section_name, unsigned obj_sec_num, struct Dwarf_Section_s *secdata, unsigned groupnum, /* The have_dwarf flag is a somewhat imprecise way to determine if there is at least one 'meaningful' DWARF information section present in the object file. If not set on some section we claim (later) that there is no DWARF info present. see 'foundDwarf' in this file */ int duperr,int emptyerr,int have_dwarf, int havezdebug, int *err) { unsigned total_entries = dbg->de_debug_sections_total_entries; if (secdata->dss_is_in_use) { *err = duperr; return DW_DLV_ERROR; } if (total_entries < DWARF_MAX_DEBUG_SECTIONS) { struct Dwarf_dbg_sect_s *debug_section = &dbg->de_debug_sections[total_entries]; secdata->dss_is_in_use = TRUE; debug_section->ds_name = name; debug_section->ds_number = obj_sec_num; debug_section->ds_secdata = secdata; debug_section->ds_groupnumber = groupnum; secdata->dss_name = name; /* Actual name from object file. */ secdata->dss_standard_name = standard_section_name; secdata->dss_number = obj_sec_num; secdata->dss_zdebug_requires_decompress = havezdebug; /* We don't yet know about SHF_COMPRESSED */ debug_section->ds_duperr = duperr; debug_section->ds_emptyerr = emptyerr; debug_section->ds_have_dwarf = have_dwarf; debug_section->ds_have_zdebug = havezdebug; ++dbg->de_debug_sections_total_entries; return DW_DLV_OK; } /* This represents a bug in libdwarf. Mis-setup-DWARF_MAX_DEBUG_SECTIONS. Or possibly a use of section groups that is not supported. */ *err = DW_DLE_TOO_MANY_DEBUG; return DW_DLV_ERROR; } #if 0 static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("dump_bytes: %s ",msg); for (; cur < end; cur++) { printf("%02x",*cur); } printf("\n"); } static int all_sig8_bits_zero(Dwarf_Sig8 *val) { unsigned u = 0; for( ; u < sizeof(*val); ++u) { if (val->signature[u] != 0) { return FALSE; } } return TRUE; } #endif /* Return DW_DLV_OK etc. */ static int set_up_section(Dwarf_Debug dbg, /* Section name from object format. Might start with .zdebug not .debug if compressed section. */ const char *secname, /* Standard section name, such as .debug_info */ const char *sec_standard_name, /* Section number from object format */ unsigned obj_sec_num, /* The name associated with this secdata in libdwarf */ const char *targname, /* DW_GROUPNUMBER_ANY or BASE or DWO or some other group num */ unsigned groupnum_of_sec, struct Dwarf_Section_s *secdata, int duperr,int emptyerr,int have_dwarf, int *err) { /* Here accomodate the .debug or .zdebug version, (and of course non- .debug too, but those never zlib) . SECNAMEMAX should be a little bigger than any section name we care about as possibly compressed, which is to say bigger than any standard section name. */ #define SECNAMEMAX 30 int secnamelen = strlen(secname); /* static const char *dprefix = ".debug_"; */ #define DPREFIXLEN 7 static const char *zprefix = ".zdebug_"; #define ZPREFIXLEN 8 int havezdebug = FALSE; int namesmatch = FALSE; /* For example, if the secname is .zdebug_info we update the finaltargname to .debug_info to match with the particular (known, predefined) object section name. We add one character, so check to see if it will, in the end, fit. See the SET_UP_SECTION macro. */ if(secnamelen >= SECNAMEMAX) { /* This is not the target section. our caller will keep looking. */ return DW_DLV_NO_ENTRY; } if((secnamelen+1) < SECNAMEMAX && !strncmp(secname,zprefix,ZPREFIXLEN) && !strcmp(secname+ZPREFIXLEN,targname+DPREFIXLEN)) { /* zprefix version matches the object section name so the section is compressed and is the section this targname applies to. */ havezdebug = TRUE; namesmatch = TRUE; } else if (!strcmp(secname,targname)) { namesmatch = TRUE; } #undef ZPREFIXLEN #undef DPREFIXLEN #undef SECNAMEMAX if(!namesmatch) { /* This is not the target section. our caller will keep looking. */ return DW_DLV_NO_ENTRY; } /* SETUP_SECTION. See also BUILDING_SECTIONS, BUILDING_MAP */ { /* The section name is a match with targname, or the .zdebug version of targname. */ int sectionerr = 0; sectionerr = add_debug_section_info(dbg,secname, sec_standard_name, obj_sec_num, secdata, groupnum_of_sec, duperr,emptyerr, have_dwarf, havezdebug,err); if (sectionerr != DW_DLV_OK) { /* *err is set already */ return sectionerr; } } return DW_DLV_OK; } #define SET_UP_SECTION(mdbg,mname,mtarg,mgrp,minfo,me1,me2,mdw,mer) \ { \ int lerr = 0; \ lerr = set_up_section(mdbg, \ mname, /* actual section name */ \ mtarg, /* std section name */ \ /* scn_number from macro use context */ \ scn_number,mtarg,mgrp, \ minfo, \ me1,me2,mdw,mer); \ if (lerr != DW_DLV_NO_ENTRY) { \ return lerr; \ } /* else fall through. */ \ } /* If running this long set of tests is slow enough to matter one could set up a local tsearch tree with all this content and search it instead of this set of sequential tests. Or use a switch(){} here with a search tree to to turn name into index for the switch(). */ static int enter_section_in_de_debug_sections_array(Dwarf_Debug dbg, const char *scn_name, /* This is the number of the section in the object file. */ unsigned scn_number, unsigned group_number, int *err) { /* Setup the table that contains the basic information about the sections that are DWARF related. The entries are very unlikely to change very often. */ SET_UP_SECTION(dbg,scn_name,".debug_info", group_number, &dbg->de_debug_info, DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_info.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_info, DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_types", group_number, &dbg->de_debug_types, DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_types.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_types, DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_abbrev", group_number, &dbg->de_debug_abbrev, /*03*/ DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_abbrev.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_abbrev, /*03*/ DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_aranges", group_number, &dbg->de_debug_aranges, DW_DLE_DEBUG_ARANGES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_line", group_number, &dbg->de_debug_line, DW_DLE_DEBUG_LINE_DUPLICATE,0, TRUE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_line_str", group_number, &dbg->de_debug_line_str, DW_DLE_DEBUG_LINE_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_line.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_line, DW_DLE_DEBUG_LINE_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_frame", group_number, &dbg->de_debug_frame, DW_DLE_DEBUG_FRAME_DUPLICATE,0, TRUE,err); /* gnu egcs-1.1.2 data */ SET_UP_SECTION(dbg,scn_name,".eh_frame", group_number, &dbg->de_debug_frame_eh_gnu, DW_DLE_DEBUG_FRAME_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_loc", group_number, &dbg->de_debug_loc, DW_DLE_DEBUG_LOC_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_loc.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_loc, DW_DLE_DEBUG_LOC_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_pubnames", group_number, &dbg->de_debug_pubnames, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_str", group_number, &dbg->de_debug_str, DW_DLE_DEBUG_STR_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_str.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_str, DW_DLE_DEBUG_STR_DUPLICATE,0, FALSE,err); /* Section new in DWARF3. */ SET_UP_SECTION(dbg,scn_name,".debug_pubtypes", group_number, &dbg->de_debug_pubtypes, /*13*/ DW_DLE_DEBUG_PUBTYPES_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_names", group_number, &dbg->de_debug_names, /*13*/ DW_DLE_DEBUG_NAMES_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_loclists", group_number, &dbg->de_debug_loclists, /*13*/ DW_DLE_DEBUG_LOClISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_loclists.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_loclists, /*13*/ DW_DLE_DEBUG_LOClISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_rnglists", group_number, &dbg->de_debug_rnglists, /*13*/ DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_rnglists.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_rnglists, /*13*/ DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_str_offsets", group_number, &dbg->de_debug_str_offsets, DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, FALSE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_str_offsets.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_str_offsets, DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_funcnames", group_number, &dbg->de_debug_funcnames, /*11*/ DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only, created years before DWARF3. Content essentially identical to .debug_pubtypes. */ SET_UP_SECTION(dbg,scn_name,".debug_typenames", group_number, &dbg->de_debug_typenames, /*12*/ DW_DLE_DEBUG_TYPENAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_varnames", group_number, &dbg->de_debug_varnames, DW_DLE_DEBUG_VARNAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_weaknames", group_number, &dbg->de_debug_weaknames, DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_macinfo", group_number, &dbg->de_debug_macinfo, DW_DLE_DEBUG_MACINFO_DUPLICATE,0, TRUE,err); /* ".debug_macinfo.dwo" is not allowed. */ /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_macro", group_number, &dbg->de_debug_macro, DW_DLE_DEBUG_MACRO_DUPLICATE,0, TRUE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_macro.dwo", DW_GROUPNUMBER_DWO, &dbg->de_debug_macro, DW_DLE_DEBUG_MACRO_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_ranges", group_number, &dbg->de_debug_ranges, DW_DLE_DEBUG_RANGES_DUPLICATE,0, TRUE,err); /* No .debug_ranges.dwo allowed. */ /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_sup", group_number, &dbg->de_debug_sup, DW_DLE_DEBUG_SUP_DUPLICATE,0, TRUE,err); /* No .debug_sup.dwo allowed. */ /* .symtab and .strtab have to be in any group. */ SET_UP_SECTION(dbg,scn_name,".symtab", group_number, &dbg->de_elf_symtab, DW_DLE_DEBUG_SYMTAB_ERR,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".strtab", group_number, &dbg->de_elf_strtab, DW_DLE_DEBUG_STRTAB_ERR,0, FALSE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_addr", group_number, &dbg->de_debug_addr, DW_DLE_DEBUG_ADDR_DUPLICATE,0, TRUE,err); /* No .debug_addr.dwo allowed. */ /* gdb added this. */ SET_UP_SECTION(dbg,scn_name,".gdb_index", group_number, &dbg->de_debug_gdbindex, DW_DLE_DUPLICATE_GDB_INDEX,0, FALSE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_names", group_number, &dbg->de_debug_names, DW_DLE_DEBUG_NAMES_DUPLICATE,0, FALSE,err); /* No .debug_names.dwo allowed. */ /* gdb added this in DW4. It is in standard DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_cu_index", DW_GROUPNUMBER_DWO, &dbg->de_debug_cu_index, DW_DLE_DUPLICATE_CU_INDEX,0, FALSE,err); /* gdb added this in DW4. It is in standard DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_tu_index", DW_GROUPNUMBER_DWO, &dbg->de_debug_tu_index, DW_DLE_DUPLICATE_TU_INDEX,0, FALSE,err); /* GNU added this. It is not part of DWARF */ SET_UP_SECTION(dbg,scn_name,".gnu_debuglink", DW_GROUPNUMBER_DWO, &dbg->de_gnu_debuglink, DW_DLE_DUPLICATE_GNU_DEBUGLINK,0, FALSE,err); /* GNU added this. It is not part of DWARF */ SET_UP_SECTION(dbg,scn_name,".note.gnu.build-id", DW_GROUPNUMBER_DWO, &dbg->de_note_gnu_buildid, DW_DLE_DUPLICATE_GNU_DEBUGLINK,0, FALSE,err); return DW_DLV_NO_ENTRY; } static int is_section_name_known_already(Dwarf_Debug dbg, const char *scn_name) { unsigned i = 0; for ( ; i < dbg->de_debug_sections_total_entries; ++i) { struct Dwarf_dbg_sect_s *section = &dbg->de_debug_sections[i]; if (!strcmp(scn_name, section->ds_name)) { /* The caller will declare this a duplicate, an error. */ return DW_DLV_OK; } } /* This is normal, we expect we've not accepted scn_name already. */ return DW_DLV_NO_ENTRY; } /* Given an Elf ptr, set up dbg with pointers to all the Dwarf data sections. Return NULL on error. This function is also responsible for determining whether the given object contains Dwarf information or not. The test currently used is that it contains either a .debug_info or a .debug_frame section. If not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to return DW_DLV_NO_ENTRY. Earlier, we had thought of using only the presence/absence of .debug_info to test, but we added .debug_frame since there could be stripped objects that have only a .debug_frame section for exception processing. DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR This does not allow for section-groups in object files, for which many .debug_info (and other DWARF) sections may exist. We process. .rela (SHT_RELA) but not .rel (SHT_REL) sections because with .rela the referencing section offset value is zero whereas with .rel the referencing section value is already correct for the object itself. In other words, we do it because of the definition of .rela relocations in Elf. */ /* For an object file with an incorrect rela section name, readelf prints correct debug information, as the tool takes the section type instead of the section name. So check the section name but test section type. */ static int is_a_rela_section(const char *scn_name,int type) { if(startswith(scn_name,".rela.")) { return TRUE; } if (type == SHT_RELA) { return TRUE; } return FALSE; } /* ASSERT: names like .debug_ or .zdebug_ never passed in here! */ static int is_a_special_section_semi_dwarf(const char *scn_name) { if (!strcmp(scn_name,".strtab") || !strcmp(scn_name,".symtab")) { return TRUE; } /* It's not one of these special sections referenced in the test. */ return FALSE; } static int this_section_dwarf_relevant(const char *scn_name,int type) { /* A small helper function for _dwarf_setup(). */ if (startswith(scn_name, ".zdebug_") || startswith(scn_name, ".debug_")) { /* standard debug */ return TRUE; } /* Now check if a special section could be in a section_group, but though seems unlikely. */ if (!strcmp(scn_name, ".eh_frame")) { /* This is not really a group related file, but it is harmless to consider it such. */ return TRUE; } if (!strcmp(scn_name, ".gnu_debuglink")) { /* This is not a group or DWARF related file, but it is useful for split dwarf. */ return TRUE; } if (!strcmp(scn_name, ".note.gnu.build-id")) { /* This is not a group or DWARF related file, but it is useful for split dwarf. */ return TRUE; } if(!strcmp(scn_name, ".gdb_index")) { return TRUE; } if(is_a_special_section_semi_dwarf(scn_name)) { return TRUE; } if(is_a_rela_section(scn_name,type)) { return TRUE; } /* All sorts of sections are of no interest: .text .rel. and many others. */ return FALSE; } /* This assumes any non-Elf object files have no SHT_GROUP sections. So this code will not be invoked on non-Elf objects. One supposes this is unlikely to match any non-Elf version of COMDAT. */ static int insert_sht_list_in_group_map(Dwarf_Debug dbg, struct Dwarf_Obj_Access_Section_s *doas, unsigned comdat_group_number, unsigned section_number, Dwarf_Unsigned section_count, struct Dwarf_Obj_Access_Interface_s * obj, unsigned *did_add_map, Dwarf_Error *error) { struct Dwarf_Section_s secdata; Dwarf_Small * data = 0; int res = 0; Dwarf_Small* secend = 0; memset(&secdata,0,sizeof(secdata)); secdata.dss_size = doas->size; secdata.dss_entrysize = doas->entrysize; secdata.dss_group_number = 1; /* arbitrary. */ secdata.dss_index = section_number; secdata.dss_name = ".group"; secdata.dss_standard_name = ".group"; secdata.dss_number = section_number; secdata.dss_ignore_reloc_group_sec = TRUE; res = _dwarf_load_section(dbg,&secdata,error); if (res != DW_DLV_OK) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } return res; } if (!secdata.dss_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } if (doas->entrysize != 4) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } /* So now pick up the data in dss_data. It is an array of 32 bit fields. Entry zero is just a constant 1. Each additional is a section number. */ data = secdata.dss_data; secend = data + secdata.dss_size; { unsigned i = 1; unsigned count = doas->size/doas->entrysize; Dwarf_Unsigned fval = 0; /* The fields treatments with regard to endianness is unclear. In any case a single bit should be on, as 0x01000000 without any endiannes swapping. Or so it seems given limited evidence. We read with length checking and allow the reader to byte swap and then fix things. At least one test case has big-endian data but little-endian SHT_GROUP data. */ if ((data+DWARF_32BIT_SIZE) > secend) { /* Duplicates the check in READ_UNALIGNED_CK so we can free allocated memory bere. */ free(secdata.dss_data); _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,fval,Dwarf_Unsigned, data, DWARF_32BIT_SIZE, error, secend); if (fval != 1 && fval != 0x1000000) { /* Could be corrupted elf object. */ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } data = data + doas->entrysize; for (i = 1 ; i < count ; ++i) { Dwarf_Unsigned val = 0; if ((data+DWARF_32BIT_SIZE) > secend) { /* Duplicates the check in READ_UNALIGNED_CK so we can free allocated memory bere. */ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg,val,Dwarf_Unsigned, data, DWARF_32BIT_SIZE, error, secend); if (val > section_count) { /* Might be confused endianness by the compiler generating the SHT_GROUP. This is pretty horrible. */ Dwarf_Unsigned valr = 0; _dwarf_memcpy_swap_bytes(&valr,&val, DWARF_32BIT_SIZE); if (valr > section_count) { if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; } /* Ok. Yes, ugly. */ val = valr; } { /* Ensure this group entry DWARF relevant before adding to group map */ struct Dwarf_Obj_Access_Section_s doasx; int resx = DW_DLV_ERROR; int err = 0; memset(&doasx,0,sizeof(doasx)); resx = obj->methods->get_section_info(obj->object, val, &doasx, &err); if (resx == DW_DLV_NO_ENTRY){ /* Should we really ignore this? */ continue; } else if (resx == DW_DLV_ERROR){ if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } _dwarf_error(dbg,error,err); return resx; } if (!this_section_dwarf_relevant(doasx.name, doasx.type) ) { continue; } data += DWARF_32BIT_SIZE; *did_add_map = TRUE; res = _dwarf_insert_in_group_map(dbg, comdat_group_number,val, doasx.name, error); if (res != DW_DLV_OK) { free(secdata.dss_data); return res; } } } } if (secdata.dss_data_was_malloc) { free(secdata.dss_data); } return DW_DLV_OK; } /* Split dwarf CUs can be in an object with non-split or split may be in a separate object. If all in one object the default is to deal with group_number and ignore DW_GROUPNUMBER_DWO. If only .dwo the default is DW_GROUPNUMBER_DWO(2). Otherwise use DW_GROUP_NUMBER_BASE(1). If there are COMDAT SHT_GROUP sections, these are assigned group numbers 3-N as needed. At present this makes the assumption that COMDAT group (ie, SHT_GROUP) sections have lower section numbers than the sections COMDAT refers to. It is not clear whether this is guaranteed, COMDAT is not an official Elf thing and documentation is scarce. In the 1990's SGI folks and others formed a committee and attempted to get COMDAT and a feature allowing section numbers greater than 16 bits into Elf, but there was no group that was able to approve such things. This is called once at dbg init time. */ static int determine_target_group(Dwarf_Unsigned section_count, struct Dwarf_Obj_Access_Interface_s * obj, unsigned *group_number_out, Dwarf_Debug dbg, Dwarf_Error *error) { unsigned obj_section_index = 0; int found_group_one = 0; int found_group_two = 0; struct Dwarf_Group_Data_s *grp = 0; unsigned comdat_group_next = 3; unsigned lowest_comdat_groupnum = 0; grp = &dbg->de_groupnumbers; grp->gd_number_of_groups = 0; grp->gd_number_of_sections = section_count; if (grp->gd_map) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_OK; } for (obj_section_index = 0; obj_section_index < section_count; ++obj_section_index) { struct Dwarf_Obj_Access_Section_s doas; int res = DW_DLV_ERROR; int err = 0; const char *scn_name = 0; unsigned groupnumber = 0; unsigned mapgroupnumber = 0; memset(&doas,0,sizeof(doas)); res = obj->methods->get_section_info(obj->object, obj_section_index, &doas, &err); if (res == DW_DLV_NO_ENTRY){ return res; } else if (res == DW_DLV_ERROR){ _dwarf_error(dbg, error,err); return res; } if (doas.type == SHT_GROUP) { /* See assumptions in function comment above. */ unsigned did_add_map = 0; /* Add to our map. Here we are assuming SHT_GROUP records come first. Till proven wrong. */ res = insert_sht_list_in_group_map(dbg,&doas, comdat_group_next, obj_section_index, section_count, obj, &did_add_map,error); if (res != DW_DLV_OK) { return res; } if (!lowest_comdat_groupnum) { lowest_comdat_groupnum = comdat_group_next; } if (did_add_map) { ++grp->gd_number_of_groups; ++comdat_group_next; } continue; } scn_name = doas.name; if (!this_section_dwarf_relevant(scn_name,doas.type) ) { continue; } /* Now at a 'normal' section, though we do not quite know what group it is. */ res = _dwarf_section_get_target_group_from_map(dbg, obj_section_index,&groupnumber,error); if (res == DW_DLV_OK ) { /* groupnumber is set. Fall through. All COMDAT group should get here. */ mapgroupnumber = groupnumber; } else if (res == DW_DLV_ERROR) { return res; } else { /* DW_DLV_NO_ENTRY */ /* Normal non-COMDAT. groupnumber is zero. */ } /* BUILDING_MAP. See also BUILDING_SECTIONS, SETUP_SECTION */ if (!groupnumber) { res =_dwarf_dwo_groupnumber_given_name(scn_name, &groupnumber); /* DW_DLV_ERROR impossible here. */ if (res == DW_DLV_OK) { /* groupnumber set 2 */ } else { /* This is what it has to be. .rela in here too. */ groupnumber = DW_GROUPNUMBER_BASE; } } if (is_a_rela_section(scn_name,doas.type)) { unsigned linkgroup = 0; res = _dwarf_section_get_target_group_from_map(dbg, doas.info, &linkgroup,error); if (res == DW_DLV_OK ) { /* Fall through. linkgroup is in group map already. */ } else if (res == DW_DLV_ERROR) { return res; } else { /* DW_DLV_NO_ENTRY */ res = _dwarf_insert_in_group_map(dbg, linkgroup,obj_section_index, scn_name, error); if (res != DW_DLV_OK ) { return res; } } continue; } /* ASSERT: groupnumber non-zero now */ if (!is_a_special_section_semi_dwarf(scn_name)) { if (mapgroupnumber) { /* Already in group map */ continue; } /* !mapgroupnumber */ res = _dwarf_insert_in_group_map(dbg, groupnumber,obj_section_index, scn_name, error); if (res != DW_DLV_OK) { return res; } if (groupnumber == 1) { found_group_one++; } else if (groupnumber == 2) { found_group_two++; } continue; } } if (found_group_two) { ++grp->gd_number_of_groups; } if (found_group_one) { *group_number_out = DW_GROUPNUMBER_BASE; ++grp->gd_number_of_groups; } else { if (found_group_two) { *group_number_out = DW_GROUPNUMBER_DWO; } else { if (lowest_comdat_groupnum) { *group_number_out = lowest_comdat_groupnum; } else { *group_number_out = DW_GROUPNUMBER_BASE; } } } return DW_DLV_OK; } static int _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) { const char *scn_name = 0; struct Dwarf_Obj_Access_Interface_s * obj = 0; int resn = 0; struct Dwarf_Section_s **sections = 0; Dwarf_Endianness endianness; Dwarf_Unsigned section_count = 0; unsigned default_group_number = 0; unsigned foundDwarf = FALSE; unsigned obj_section_index = 0; 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->methods->get_byte_order(obj->object); /* Then adjust any changes we need. */ #ifdef WORDS_BIGENDIAN dbg->de_big_endian_object = 1; if (endianness == DW_OBJECT_LSB ) { 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_OBJECT_MSB ) { dbg->de_same_endian = 0; dbg->de_big_endian_object = 1; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #endif /* !WORDS_BIGENDIAN */ /* The following de_length_size is Not Too Significant. Only used one calculation, and an approximate one at that. */ dbg->de_length_size = obj->methods->get_length_size(obj->object); dbg->de_pointer_size = obj->methods->get_pointer_size(obj->object); section_count = obj->methods->get_section_count(obj->object); resn = determine_target_group(section_count,obj, &default_group_number,dbg,error); if (resn == DW_DLV_ERROR) { return DW_DLV_ERROR; } if (dbg->de_groupnumber == DW_GROUPNUMBER_ANY) { dbg->de_groupnumber = default_group_number; } /* Allocate space to record references to debug sections, that can be referenced by RELA sections in the 'sh_info' field. */ sections = (struct Dwarf_Section_s **)calloc(section_count + 1, sizeof(struct Dwarf_Section_s *)); if (!sections) { /* Impossible case, we hope. Give up. */ _dwarf_error(dbg, error, DW_DLE_SECTION_ERROR); return DW_DLV_ERROR; } /* We can skip index 0 when considering ELF files, but not other object types. Indeed regardless of the object type we should skip section 0 here. This is a convention. We depend on it. Non-elf object access code should (in itself) understand we will index beginning at 1 and adjust itself to deal with this Elf convention. Without this convention various parts of the code in this file won't work correctly. A dss_index of 0 must not be used, even though we start at 0 here. So the get_section_info() must adapt to the situation (the elf version does automatically as a result of Elf having a section zero with zero length and an empty name). */ /* ASSERT: all group map entries set up. */ for (obj_section_index = 0; obj_section_index < section_count; ++obj_section_index) { struct Dwarf_Obj_Access_Section_s doas; int res = DW_DLV_ERROR; int err = 0; unsigned groupnumber = 0; unsigned mapgroupnumber = 0; res = _dwarf_section_get_target_group_from_map(dbg,obj_section_index, &groupnumber,error); if (res == DW_DLV_OK ) { /* groupnumber is set. Fall through */ mapgroupnumber = groupnumber; } else if (res == DW_DLV_ERROR) { free(sections); return res; } else { /* DW_DLV_NO_ENTRY */ /* fall through, a BASE or DWO group, possibly */ } memset(&doas,0,sizeof(doas)); res = obj->methods->get_section_info(obj->object, obj_section_index, &doas, &err); if (res == DW_DLV_NO_ENTRY){ free(sections); return res; } else if (res == DW_DLV_ERROR){ free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } scn_name = doas.name; if (!groupnumber) { /* This finds dwo sections, group 2 */ res = _dwarf_dwo_groupnumber_given_name(scn_name, &groupnumber); if (res == DW_DLV_NO_ENTRY) { /* No, must be group 1 */ groupnumber = DW_GROUPNUMBER_BASE; } } if (!this_section_dwarf_relevant(scn_name,doas.type) ) { continue; } if (!is_a_rela_section(scn_name,doas.type) && !is_a_special_section_semi_dwarf(scn_name)) { /* We do these actions only for group-related sections. Do for .debug_info etc, never for .strtab or .rela.* We already tested for relevance, so that part is not news. */ if(mapgroupnumber == dbg->de_groupnumber) { /* OK. Mapped. Part of the group.. This will catch the cases where there are versions of a section in multiple COMDATs and in BASE an DWO to get the right one */ } else { /* This section not mapped into this group. */ if (groupnumber == 1 && dbg->de_groupnumber > 2 && !_dwarf_section_in_group_by_name(dbg,scn_name, dbg->de_groupnumber)) { /* Load the section (but as group 1) */ } else { continue; } } } /* BUILDING_SECTIONS. See also BUILDING_MAP, SETUP_SECTION */ { /* Build up the sections table and the de_debug* etc pointers in Dwarf_Debug. */ struct Dwarf_dbg_sect_s *section; int found_match = FALSE; res = is_section_name_known_already(dbg,scn_name); if (res == DW_DLV_OK) { /* DUPLICATE */ free(sections); DWARF_DBG_ERROR(dbg, DW_DLE_SECTION_DUPLICATION, DW_DLV_ERROR); } else if (res == DW_DLV_ERROR) { free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } /* No entry: new-to-us section, the normal case. */ res = enter_section_in_de_debug_sections_array(dbg,scn_name, obj_section_index, groupnumber,&err); if (res == DW_DLV_OK) { section = &dbg->de_debug_sections[ dbg->de_debug_sections_total_entries-1]; res = get_basic_section_data(dbg, section->ds_secdata, &doas, obj_section_index, groupnumber, error, section->ds_duperr, section->ds_emptyerr); if (res != DW_DLV_OK) { free(sections); return res; } sections[obj_section_index] = section->ds_secdata; foundDwarf += section->ds_have_dwarf; found_match = TRUE; /* Normal section set up. Fall through. */ } else if (res == DW_DLV_NO_ENTRY) { /* We get here for relocation sections. Fall through. */ } else { free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } if (!found_match) { /* For an object file with incorrect rela section name, the 'readelf' tool, prints correct debug information, as the tool takes the section type instead of the section name. If the current section is a RELA one and the 'sh_info' refers to a debug section, add the relocation data. */ if (is_a_rela_section(scn_name,doas.type)) { if ( doas.info < section_count) { if (sections[doas.info]) { add_rela_data_to_secdata(sections[doas.info], &doas, obj_section_index); } } else { /* Something is wrong with the ELF file. */ free(sections); DWARF_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } } } /* Fetch next section */ } } /* Free table with section information. */ free(sections); if (foundDwarf) { return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* There is one table per CU and one per TU, and each table refers to the associated other DWARF data for that CU or TU. See DW_SECT_* In DWARF4 the type units are in .debug_types In DWARF5 the type units are in .debug_info. */ static int load_debugfission_tables(Dwarf_Debug dbg,Dwarf_Error *error) { int i = 0; if (dbg->de_debug_cu_index.dss_size ==0 && dbg->de_debug_tu_index.dss_size ==0) { /* This is the normal case. No debug fission. Not a .dwp object. */ return DW_DLV_NO_ENTRY; } for (i = 0; i < 2; ++i) { Dwarf_Xu_Index_Header xuptr = 0; struct Dwarf_Section_s* dwsect = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned number_of_cols /* L */ = 0; Dwarf_Unsigned number_of_CUs /* N */ = 0; Dwarf_Unsigned number_of_slots /* M */ = 0; const char *secname = 0; int res = 0; const char *type = 0; if (i == 0) { dwsect = &dbg->de_debug_cu_index; type = "cu"; } else { dwsect = &dbg->de_debug_tu_index; type = "tu"; } if ( !dwsect->dss_size ) { continue; } res = dwarf_get_xu_index_header(dbg,type, &xuptr,&version,&number_of_cols, &number_of_CUs,&number_of_slots, &secname,error); if (res == DW_DLV_NO_ENTRY) { continue; } if (res != DW_DLV_OK) { return res; } if (i == 0) { dbg->de_cu_hashindex_data = xuptr; } else { dbg->de_tu_hashindex_data = xuptr; } } return DW_DLV_OK; } /* Use a Dwarf_Obj_Access_Interface to kick things off. All other init routines eventually use this one. The returned Dwarf_Debug contains a copy of *obj the callers copy of *obj may be freed whenever the caller wishes. */ int dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg, Dwarf_Error* error) { return dwarf_object_init_b(obj,errhand,errarg, DW_GROUPNUMBER_ANY,ret_dbg,error); } /* New March 2017. Enables dealing with DWARF5 split dwarf more fully. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, unsigned groupnumber, Dwarf_Debug* ret_dbg, Dwarf_Error* error) { Dwarf_Debug dbg = 0; int setup_result = DW_DLV_OK; dbg = _dwarf_get_debug(); if (dbg == NULL) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dbg->de_errhand = errhand; dbg->de_errarg = errarg; dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; #ifdef HAVE_OLD_FRAME_CFA_COL /* DW_FRAME_CFA_COL is really only suitable for old libdwarf frame interfaces and its value of 0 there is only usable where (as in MIPS) register 0 has no value other than 0 so we can use the frame table column 0 for the CFA value (and rely on client software to know when 'register 0' is the cfa and when to just use a value 0 for register 0). */ dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL; #else dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3; #endif dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL; dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL; dbg->de_obj_file = obj; dbg->de_groupnumber = groupnumber; setup_result = _dwarf_setup(dbg, error); if (setup_result == DW_DLV_OK) { int fission_result = load_debugfission_tables(dbg,error); /* In most cases we get setup_result == DW_DLV_NO_ENTRY here as having debugfission (.dwp objects) is fairly rare. */ if (fission_result == DW_DLV_ERROR) { /* Something is very wrong. */ setup_result = fission_result; } } if (setup_result != DW_DLV_OK) { int freeresult = 0; int myerr = 0; /* We cannot use any _dwarf_setup() error here as we are freeing dbg, making that error (setup as part of dbg) stale. Hence we have to make a new error without a dbg. But error might be NULL and the init call error-handler function might be set. */ if ( (setup_result == DW_DLV_ERROR) && error ) { /* Preserve our _dwarf_setup error number, but this does not apply if error NULL. */ myerr = dwarf_errno(*error); /* deallocate the soon-stale error pointer. */ dwarf_dealloc(dbg,*error,DW_DLA_ERROR); *error = 0; } /* The status we want to return here is of _dwarf_setup, not of the _dwarf_free_all_of_one_debug(dbg) call. So use a local status variable for the free. */ freeresult = _dwarf_free_all_of_one_debug(dbg); dbg = 0; /* DW_DLV_NO_ENTRY not possible in freeresult */ if (freeresult == DW_DLV_ERROR) { /* Use the _dwarf_setup error number. If error is NULL the following will issue a message on stderr and abort(), as without dbg there is no error-handler function. */ _dwarf_error(NULL,error,DW_DLE_DBG_ALLOC); return DW_DLV_ERROR; } if (setup_result == DW_DLV_ERROR) { /* Use the _dwarf_setup error number. If error is NULL the following will issue a message on stderr and abort(), as without dbg there is no error-handler function. */ _dwarf_error(NULL,error,myerr); } return setup_result; } dwarf_harmless_init(&dbg->de_harmless_errors, DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE); *ret_dbg = dbg; return DW_DLV_OK; } /* A finish routine that is completely unaware of ELF. Frees all memory that was not previously freed by dwarf_dealloc. Aside from certain categories. */ int dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error) { int res = 0; res = _dwarf_free_all_of_one_debug(dbg); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } return res; } #ifdef HAVE_ZLIB /* case 1: The input stream is assumed to contain the four letters ZLIB Followed by 8 bytes of the size of the uncompressed stream. Presented as a big-endian binary number. Following that is the stream to decompress. case 2: The section flag bit SHF_COMPRESSED (1 << 11) must be set. we then do the eqivalent of reading a Elf32_External_Chdr or Elf64_External_Chdr to get the type (which must be 1) and the decompressed_length. Then what follows the implicit Chdr is decompressed. */ /* ALLOWED_ZLIB_INFLATION is a heuristic, not necessarily right. The test case klingler2/compresseddebug.amd64 actually inflates about 8 times. */ #define ALLOWED_ZLIB_INFLATION 16 static int do_decompress_zlib(Dwarf_Debug dbg, struct Dwarf_Section_s *section, Dwarf_Error * error) { Bytef *basesrc = (Bytef *)section->dss_data; Bytef *src = (Bytef *)basesrc; uLong srclen = section->dss_size; Dwarf_Unsigned flags = section->dss_flags; Dwarf_Small *endsection = 0; int res = 0; Bytef *dest = 0; uLongf destlen = 0; Dwarf_Unsigned uncompressed_len = 0; endsection = basesrc + srclen; if ((src + 12) >endsection) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR); } section->dss_compressed_length = section->dss_size; if(!strncmp("ZLIB",(const char *)src,4)) { unsigned i = 0; unsigned l = 8; unsigned char *c = src+4; for( ; i < l; ++i,c++) { uncompressed_len <<= 8; uncompressed_len += *c; } src = src + 12; srclen -= 12; section->dss_uncompressed_length = uncompressed_len; section->dss_ZLIB_compressed = TRUE; } else if (flags & SHF_COMPRESSED) { /* The prefix is a struct: unsigned int type; followed by pad if following are 64bit! size-of-target-address size size-of-target-address */ Dwarf_Small *ptr = (Dwarf_Small *)src; Dwarf_Unsigned type = 0; Dwarf_Unsigned size = 0; /* Dwarf_Unsigned addralign = 0; */ unsigned fldsize = dbg->de_pointer_size; unsigned structsize = 3* fldsize; READ_UNALIGNED_CK(dbg,type,Dwarf_Unsigned,ptr, DWARF_32BIT_SIZE, error,endsection); ptr += fldsize; READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned,ptr,fldsize, error,endsection); if (type != ELFCOMPRESS_ZLIB) { DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, DW_DLV_ERROR); } uncompressed_len = size; section->dss_uncompressed_length = uncompressed_len; src += structsize; srclen -= structsize; section->dss_shf_compressed = TRUE; } else { DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, DW_DLV_ERROR); } { /* According to zlib.net zlib essentially never expands the data when compressing. There is no statement about any effective limit in the compression factor though we, here, assume such a limit to check for sanity in the object file. These tests are heuristics. */ Dwarf_Unsigned max_inflated_len = srclen*ALLOWED_ZLIB_INFLATION; if (srclen > 50) { /* If srclen not super tiny lets check the following. */ if (uncompressed_len < (srclen/2)) { /* Violates the approximate invariant about compression not actually inflating. */ DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); } } if (max_inflated_len < srclen) { /* The calculation overflowed. */ DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); } if (uncompressed_len > max_inflated_len) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); } } if( (src +srclen) > endsection) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR); } destlen = uncompressed_len; dest = malloc(destlen); if(!dest) { DWARF_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } res = uncompress(dest,&destlen,src,srclen); if (res == Z_BUF_ERROR) { free(dest); DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_BUF_ERROR, DW_DLV_ERROR); } else if (res == Z_MEM_ERROR) { free(dest); DWARF_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } else if (res != Z_OK) { free(dest); /* Probably Z_DATA_ERROR. */ DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_DATA_ERROR, DW_DLV_ERROR); } /* Z_OK */ section->dss_data = dest; section->dss_size = destlen; section->dss_data_was_malloc = TRUE; section->dss_did_decompress = TRUE; return DW_DLV_OK; } #endif /* HAVE_ZLIB */ /* Load the ELF section with the specified index and set its dss_data pointer to the memory where it was loaded. */ int _dwarf_load_section(Dwarf_Debug dbg, struct Dwarf_Section_s *section, Dwarf_Error * error) { int res = DW_DLV_ERROR; int err = 0; struct Dwarf_Obj_Access_Interface_s *o = 0; /* check to see if the section is already loaded */ if (section->dss_data != NULL) { return DW_DLV_OK; } o = dbg->de_obj_file; /* There is an elf convention that section index 0 is reserved, and that section is always empty. Non-elf object formats must honor that by ensuring that (when they assign numbers to 'sections' or 'section-like-things') they never assign a real section section-number 0 to dss_index. There is also a convention for 'bss' that that section and its like sections have no data but do have a size. That is never true of DWARF sections */ res = o->methods->load_section( o->object, section->dss_index, §ion->dss_data, &err); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } /* For PE and mach-o all section data was always malloc'd. We do not need to set dss_data_was_malloc though as the o->object data will eventually free the original section data. The first character of any o->object struct gives the type. */ if (res == DW_DLV_NO_ENTRY) { /* Gets this for section->dss_index 0. Which by ELF definition is a section index which is not used (reserved by Elf to mean no-section-index). Otherwise NULL dss_data gets error. BSS would legitimately have no data, but no DWARF related section could possbly be bss. */ return res; } if (section->dss_ignore_reloc_group_sec) { /* Neither zdebug nor reloc apply to .group sections. */ return res; } if ((section->dss_zdebug_requires_decompress || section->dss_shf_compressed || section->dss_ZLIB_compressed) && !section->dss_did_decompress) { if (!section->dss_data) { /* Impossible. This makes no sense. Corrupt object. */ DWARF_DBG_ERROR(dbg, DW_DLE_COMPRESSED_EMPTY_SECTION, DW_DLV_ERROR); } #ifdef HAVE_ZLIB res = do_decompress_zlib(dbg,section,error); if (res != DW_DLV_OK) { return res; } section->dss_did_decompress = TRUE; #else DWARF_DBG_ERROR(dbg,DW_DLE_ZDEBUG_REQUIRES_ZLIB, DW_DLV_ERROR); #endif } if (_dwarf_apply_relocs == 0) { return res; } if (section->dss_reloc_size == 0) { return res; } if (!o->methods->relocate_a_section) { return res; } /*apply relocations */ res = o->methods->relocate_a_section( o->object, section->dss_index, dbg, &err); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } return res; } /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX -64 executable larger than 2GB using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames offsets were wrong.). */ int dwarf_get_section_max_offsets(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; return DW_DLV_OK; } /* This adds the new types size (new section) to the output data. Oct 27, 2011. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size, Dwarf_Unsigned * debug_types_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; *debug_types_size = dbg->de_debug_types.dss_size; return DW_DLV_OK; } /* Now with sections new to DWARF5 (unofficial list,preliminary) */ int dwarf_get_section_max_offsets_c(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size, Dwarf_Unsigned * debug_types_size, Dwarf_Unsigned * debug_macro_size, Dwarf_Unsigned * debug_str_offsets_size, Dwarf_Unsigned * debug_sup_size, Dwarf_Unsigned * debug_cu_index_size, Dwarf_Unsigned * debug_tu_index_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; *debug_types_size = dbg->de_debug_types.dss_size; *debug_macro_size = dbg->de_debug_macro.dss_size; *debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size; *debug_sup_size = dbg->de_debug_sup.dss_size; *debug_cu_index_size = dbg->de_debug_cu_index.dss_size; *debug_tu_index_size = dbg->de_debug_tu_index.dss_size; return DW_DLV_OK; } /* Now with final sections new to DWARF5 (final) */ int dwarf_get_section_max_offsets_d(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, Dwarf_Unsigned * debug_abbrev_size, Dwarf_Unsigned * debug_line_size, Dwarf_Unsigned * debug_loc_size, Dwarf_Unsigned * debug_aranges_size, Dwarf_Unsigned * debug_macinfo_size, Dwarf_Unsigned * debug_pubnames_size, Dwarf_Unsigned * debug_str_size, Dwarf_Unsigned * debug_frame_size, Dwarf_Unsigned * debug_ranges_size, Dwarf_Unsigned * debug_typenames_size, Dwarf_Unsigned * debug_types_size, Dwarf_Unsigned * debug_macro_size, Dwarf_Unsigned * debug_str_offsets_size, Dwarf_Unsigned * debug_sup_size, Dwarf_Unsigned * debug_cu_index_size, Dwarf_Unsigned * debug_tu_index_size, Dwarf_Unsigned * debug_names_size, Dwarf_Unsigned * debug_loclists_size, Dwarf_Unsigned * debug_rnglists_size) { *debug_info_size = dbg->de_debug_info.dss_size; *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; *debug_line_size = dbg->de_debug_line.dss_size; *debug_loc_size = dbg->de_debug_loc.dss_size; *debug_aranges_size = dbg->de_debug_aranges.dss_size; *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; *debug_str_size = dbg->de_debug_str.dss_size; *debug_frame_size = dbg->de_debug_frame.dss_size; *debug_ranges_size = dbg->de_debug_ranges.dss_size; *debug_typenames_size = dbg->de_debug_typenames.dss_size; *debug_types_size = dbg->de_debug_types.dss_size; *debug_macro_size = dbg->de_debug_macro.dss_size; *debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size; *debug_sup_size = dbg->de_debug_sup.dss_size; *debug_cu_index_size = dbg->de_debug_cu_index.dss_size; *debug_tu_index_size = dbg->de_debug_tu_index.dss_size; *debug_names_size = dbg->de_debug_names.dss_size; *debug_loclists_size = dbg->de_debug_loclists.dss_size; *debug_rnglists_size = dbg->de_debug_rnglists.dss_size; return DW_DLV_OK; } /* Given a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug dbg, const char *section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error * error) { struct Dwarf_Obj_Access_Section_s doas; struct Dwarf_Obj_Access_Interface_s * obj = 0; Dwarf_Unsigned section_count = 0; Dwarf_Half section_index = 0; *section_addr = 0; *section_size = 0; obj = dbg->de_obj_file; if (NULL == obj) { return DW_DLV_NO_ENTRY; } section_count = obj->methods->get_section_count(obj->object); /* We can skip index 0 when considering ELF files, but not other object types. */ for (section_index = 0; section_index < section_count; ++section_index) { int err = 0; int res = obj->methods->get_section_info(obj->object, section_index, &doas, &err); if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } if (!strcmp(section_name,doas.name)) { *section_addr = doas.addr; *section_size = doas.size; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } /* Given a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug dbg, int section_index, const char **section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error * error) { *section_addr = 0; *section_size = 0; *section_name = NULL; /* Check if we have a valid section index */ if (section_index >= 0 && section_index < dwarf_get_section_count(dbg)) { int res = 0; int err = 0; struct Dwarf_Obj_Access_Section_s doas; struct Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file; if (NULL == obj) { return DW_DLV_NO_ENTRY; } res = obj->methods->get_section_info(obj->object, section_index, &doas, &err); if (res == DW_DLV_ERROR){ DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } *section_addr = doas.addr; *section_size = doas.size; *section_name = doas.name; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* Get section count */ int dwarf_get_section_count(Dwarf_Debug dbg) { struct Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file; if (NULL == obj) { /* -1 */ return DW_DLV_NO_ENTRY; } return obj->methods->get_section_count(obj->object); } Dwarf_Cmdline_Options dwarf_cmdline_options = { FALSE /* Use quiet mode by default. */ }; /* Lets libdwarf reflect a command line option, so we can get details of some errors printed using libdwarf-internal information. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options options) { dwarf_cmdline_options = options; } dwarfutils-20200114/libdwarf/dwarf_leb.c000066400000000000000000000134231361531463500200260ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_util.h" /* Note that with 'make check') many of the test items only make sense if Dwarf_Unsigned (and Dwarf_Signed) are 64 bits. The encode/decode logic should be fine whether those types are 64 or 32 bits. See runtests.sh */ /* 10 bytes of leb, 7 bits each part of the number, gives room for a 64bit number. While any number of leading zeroes would be legal, so no max is really truly required here, why would a compiler generate leading zeros? That would be strange. */ #define BYTESLEBMAX 10 #define BITSPERBYTE 8 /* Decode ULEB with checking */ int _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Unsigned *outval, Dwarf_Byte_Ptr endptr) { Dwarf_Unsigned byte = 0; Dwarf_Unsigned word_number = 0; Dwarf_Unsigned number = 0; unsigned shift = 0; /* The byte_length value will be a small non-negative integer. */ unsigned byte_length = 0; if (leb128 >=endptr) { return DW_DLV_ERROR; } /* The following unrolls-the-loop for the first two bytes and unpacks into 32 bits to make this as fast as possible. word_number is assumed big enough that the shift has a defined result. */ if ((*leb128 & 0x80) == 0) { if (leb128_length) { *leb128_length = 1; } *outval = *leb128; return DW_DLV_OK; } else { if ((leb128+1) >=endptr) { return DW_DLV_ERROR; } if ((*(leb128 + 1) & 0x80) == 0) { if (leb128_length) { *leb128_length = 2; } word_number = *leb128 & 0x7f; word_number |= (*(leb128 + 1) & 0x7f) << 7; *outval = word_number; return DW_DLV_OK; } /* Gets messy to hand-inline more byte checking. */ } /* The rest handles long numbers Because the 'number' may be larger than the default int/unsigned, we must cast the 'byte' before the shift for the shift to have a defined result. */ number = 0; shift = 0; byte_length = 1; byte = *leb128; for (;;) { if (shift >= (sizeof(number)*BITSPERBYTE)) { return DW_DLV_ERROR; } number |= (byte & 0x7f) << shift; if ((byte & 0x80) == 0) { if (leb128_length) { *leb128_length = byte_length; } *outval = number; return DW_DLV_OK; } shift += 7; byte_length++; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if( leb128_length) { *leb128_length = BYTESLEBMAX; } break; } ++leb128; if ((leb128) >=endptr) { return DW_DLV_ERROR; } byte = *leb128; } return DW_DLV_ERROR; } #define BITSINBYTE 8 int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Signed *outval,Dwarf_Byte_Ptr endptr) { Dwarf_Unsigned byte = 0; Dwarf_Signed number = 0; Dwarf_Bool sign = 0; Dwarf_Unsigned shift = 0; /* The byte_length value will be a small non-negative integer. */ unsigned byte_length = 1; /* byte_length being the number of bytes of data absorbed so far in turning the leb into a Dwarf_Signed. */ if (!outval) { return DW_DLV_ERROR; } if (leb128 >= endptr) { return DW_DLV_ERROR; } byte = *leb128; for (;;) { sign = byte & 0x40; if (shift >= (sizeof(number)*BITSPERBYTE)) { return DW_DLV_ERROR; } number |= ((Dwarf_Unsigned) ((byte & 0x7f))) << shift; shift += 7; if ((byte & 0x80) == 0) { break; } ++leb128; if (leb128 >= endptr) { return DW_DLV_ERROR; } byte = *leb128; byte_length++; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if (leb128_length) { *leb128_length = BYTESLEBMAX; } return DW_DLV_ERROR; } } if (sign) { /* The following avoids undefined behavior. */ unsigned shiftlim = sizeof(Dwarf_Signed) * BITSINBYTE -1; if (shift < shiftlim) { number |= -(Dwarf_Signed)(((Dwarf_Unsigned)1) << shift); } else if (shift == shiftlim) { number |= (((Dwarf_Unsigned)1) << shift); } } if (leb128_length) { *leb128_length = byte_length; } *outval = number; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_leb_test.c000066400000000000000000000212361361531463500210660ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "pro_encode_nm.h" static void printinteresting(void) { return; } static Dwarf_Signed stest[] = { 0,0xff, 0x800000000000002f, 0x800000000000003f, 0x800000000000004f, 0x8000000000000070, 0x800000000000007f, 0x8000000000000080, 0x8000000000000000, 0x800000ffffffffff, 0x80000000ffffffff, 0x800000ffffffffff, 0x8000ffffffffffff, 0xffffffffffffffff, -1703944 /*18446744073707847672 as signed*/, 562949951588368, -1, -127, -100000, -2000000000, -4000000000, -8000000000, -800000000000, }; static Dwarf_Unsigned utest[] = { 0,0xff,0x7f,0x80, 0x800000000000002f, 0x800000000000003f, 0x800000000000004f, 0x8000000000000070, 0x800000000000007f, 0x8000000000000080, 0x800000ffffffffff, 0x80000000ffffffff, 0x800000ffffffffff, 0x8000ffffffffffff, 9223372036854775808ULL, -1703944 /*18446744073707847672 as signed*/, 562949951588368, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0xffffffffffffffff }; #if 0 /* FOR DEBUGGING */ static void dump_encoded(char *space,int len) { int t; printf("encode len %d: ",len); for ( t = 0; t < len; ++t) { printf("%02x",space[t] & 0xff); } printf("\n"); } #endif #define BUFFERLEN 100 static unsigned signedtest(unsigned len) { unsigned errcnt = 0; unsigned t = 0; char bufferspace[BUFFERLEN]; for ( ; t < len; ++t) { int res = 0; int encodelen = 0; Dwarf_Unsigned decodelen = 0; Dwarf_Signed decodeval = 0; res = _dwarf_pro_encode_signed_leb128_nm( stest[t],&encodelen,bufferspace,BUFFERLEN); if (res != DW_DLV_OK) { printf("FAIL signed encode index %u val 0x%llx\n", t,stest[t]); ++errcnt; } res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)bufferspace, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&bufferspace[BUFFERLEN-1])); if (res != DW_DLV_OK) { printf("FAIL signed decode index %u val 0x%llx\n", t,stest[t]); ++errcnt; } if (stest[t] != decodeval) { printf("FAIL signed decode val index %u val 0x%llx vs 0x%llx\n", t,stest[t],decodeval); ++errcnt; } if ((Dwarf_Unsigned)encodelen != decodelen) { printf("FAIL signed decodelen val index %u val 0x%llx\n", t,stest[t]); ++errcnt; } } return errcnt; } static unsigned unsignedtest(unsigned len) { unsigned errcnt = 0; unsigned t = 0; char bufferspace[BUFFERLEN]; for ( ; t < len; ++t) { int res = 0; int encodelen = 0; Dwarf_Unsigned decodelen = 0; Dwarf_Unsigned decodeval = 0; res = _dwarf_pro_encode_leb128_nm( utest[t],&encodelen,bufferspace,BUFFERLEN); if (res != DW_DLV_OK) { printf("FAIL signed encode index %u val 0x%llx", t,utest[t]); ++errcnt; } res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)bufferspace, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&bufferspace[BUFFERLEN-1])); if (res != DW_DLV_OK) { printf("FAIL signed decode index %u val 0x%llx\n", t,utest[t]); ++errcnt; } if (utest[t] != decodeval) { printf("FAIL signed decode val index %u val 0x%llx vs 0x%llx\n", t,utest[t],decodeval); ++errcnt; } if ((Dwarf_Unsigned)encodelen != decodelen) { printf("FAIL signed decodelen val index %u val 0x%llx\n", t,utest[t]); ++errcnt; } } return errcnt; } static unsigned char v1[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; static unsigned char v2[] = { 0xf4,0xff, 0xff, 0xff, 0x0f, 0x4c, 0x00, 0x00, 0x00}; /* 9223372036854775808 == -9223372036854775808 */ static unsigned char v3[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x41 }; /* This warning with --enable-sanitize is fixed as of November 11, 2016 when decoding test v4. dwarf_leb.c: runtime error: negation of -9223372036854775808 cannot be represented in type 'Dwarf_Signed' (aka 'long long'); cast to an unsigned type to negate this value to itself. The actual value here is -4611686018427387904 0xc000000000000000 */ static unsigned char v4[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40 }; static unsigned specialtests(void) { unsigned errcnt = 0; unsigned vlen = 0; Dwarf_Unsigned decodelen = 0; Dwarf_Signed decodeval = 0; Dwarf_Unsigned udecodeval = 0; int res; vlen = sizeof(v1)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v1, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v1[vlen])); if (res != DW_DLV_ERROR) { printf("FAIL unsigned decode special v1 \n"); ++errcnt; } res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)v1, &decodelen, &udecodeval, (Dwarf_Byte_Ptr)(&v1[vlen])); if (res != DW_DLV_ERROR) { printf("FAIL unsigned decode special v1 \n"); ++errcnt; } vlen = sizeof(v2)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v2, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v2[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v2 \n"); ++errcnt; } /* If you just do (byte & 0x7f) << shift and byte is (or is promoted to) a signed type on the following decode you get the wrong value. Undefined effect in C leads to error. */ res = _dwarf_decode_u_leb128_chk( (Dwarf_Small *)v2, &decodelen, &udecodeval, (Dwarf_Byte_Ptr)(&v2[vlen])); if (res != DW_DLV_OK) { printf("FAIL unsigned decode special v2 \n"); ++errcnt; } vlen = sizeof(v3)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v3, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v3[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v3 \n"); ++errcnt; } if ((Dwarf_Unsigned)decodeval != (Dwarf_Unsigned)0x8000000000000000) { printf("FAIL signed decode special v3 value check %lld vs %lld \n", decodeval,(Dwarf_Signed)0x8000000000000000); ++errcnt; } vlen = sizeof(v4)/sizeof(char); res = _dwarf_decode_s_leb128_chk( (Dwarf_Small *)v4, &decodelen, &decodeval, (Dwarf_Byte_Ptr)(&v4[vlen])); if (res != DW_DLV_OK) { printf("FAIL signed decode special v4 \n"); ++errcnt; } if (decodeval != -4611686018427387904) { printf("FAIL signed decode special v4 value check %lld vs %lld \n", decodeval,-4611686018427387904LL); printf("FAIL signed decode special v4 value check 0x%llx vs 0x%llx \n", decodeval,-4611686018427387904LL); ++errcnt; } return errcnt; return errcnt; } int main(void) { unsigned slen = sizeof(stest)/sizeof(Dwarf_Signed); unsigned ulen = sizeof(utest)/sizeof(Dwarf_Unsigned); int errs = 0; printinteresting(); errs += signedtest(slen); errs += unsignedtest(ulen); errs += specialtests(); if (errs) { printf("FAIL. leb encode/decode errors\n"); return 1; } printf("PASS leb tests\n"); return 0; } dwarfutils-20200114/libdwarf/dwarf_line.c000066400000000000000000001764331361531463500202260ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_line.h" #include "dwarfstring.h" /* Line Register Set initial conditions. */ static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = { /* Dwarf_Addr lr_address */ 0, /* Dwarf_Unsigned lr_file */ 1, /* Dwarf_Unsigned lr_line */ 1, /* Dwarf_Unsigned lr_column */ 0, /* Dwarf_Bool lr_is_stmt */ false, /* Dwarf_Bool lr_basic_block */ false, /* Dwarf_Bool lr_end_sequence */ false, /* Dwarf_Bool lr_prologue_end */ false, /* Dwarf_Bool lr_epilogue_begin */ false, /* Dwarf_Small lr_isa */ 0, /* Dwarf_Unsigned lr_op_index */ 0, /* Dwarf_Unsigned lr_discriminator */ 0, /* Dwarf_Unsigned lr_call_context */ 0, /* Dwarf_Unsigned lr_subprogram */ 0, }; void _dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs, unsigned lineversion, Dwarf_Bool is_stmt) { *regs = _dwarf_line_table_regs_default_values; if (lineversion == DW_LINE_VERSION5) { /* DWARF5 file base is zero. */ regs->lr_file = 0; } regs->lr_is_stmt = is_stmt; } static int is_path_separator(Dwarf_Small s) { if (s == '/') { return 1; } #ifdef HAVE_WINDOWS_PATH if (s == '\\') { return 1; } #endif return 0; } /* Return 0 if false, 1 if true. If HAVE_WINDOWS_PATH is defined we attempt to handle windows full paths: \\something or C:cwdpath.c */ int _dwarf_file_name_is_full_path(Dwarf_Small *fname) { Dwarf_Small firstc = *fname; if (is_path_separator(firstc)) { /* Full path. */ return 1; } if (!firstc) { return 0; } /* This is a windows path test, but we do have a few windows paths in our regression tests... This is extremely unlikely to cause UN*X/POSIX users any problems. */ if ((firstc >= 'A' && firstc <= 'Z') || (firstc >= 'a' && firstc <= 'z')) { Dwarf_Small secondc = fname[1]; if (secondc == ':') { return 1; } } /* End Windows style */ return 0; } #include "dwarf_line_table_reader_common.h" static void special_cat(char *dst,char *src, UNUSEDARG int srclen) { #if defined (HAVE_WINDOWS_PATH) /* Always '/' instead of '\\', this is a Windows -> Unix issue. */ int i1 = 0; int i2 = 0; for ( ; dst[i1] ; ++i1) { } for (; i2 < srclen; ++i2,++i1) { dst[i1] = src[i2]; if (dst[i1] == '\\') { dst[i1] = '/'; } } #else strcat(dst, src); #endif /* HAVE_WINDOWS_PATH */ return; } /* With this routine we ensure the file full path is calculated identically for dwarf_srcfiles() and dwarf_filename() We sometimes return a string pointer that points inside a dwarfsection, yet sometimes we return a _dwarf_get_alloc allocated string. This is safe because dwarf_dealloc (which users should call eventually)will not actually deallocate a string unless _dwarf_get_alloc allocated the pointed-to area. dwarf_finish() will do the dealloc if nothing else does. */ static int create_fullest_file_path(Dwarf_Debug dbg, Dwarf_File_Entry fe, Dwarf_Line_Context line_context, char ** name_ptr_out, Dwarf_Error *error) { Dwarf_Unsigned dirno = 0; char *full_name = 0; char *file_name = 0; dirno = fe->fi_dir_index; file_name = (char *) fe->fi_file_name; if (!file_name) { _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); return (DW_DLV_ERROR); } if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) { #ifdef HAVE_WINDOWS_PATH { unsigned len = strlen(file_name); char *tmp = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING, len+1); if(tmp) { tmp[0] = 0; special_cat(tmp,file_name,len); if (strcmp(tmp,file_name)) { /* We transformed the name. Use the new name. */ *name_ptr_out = tmp; return DW_DLV_OK; } else { dwarf_dealloc(dbg,tmp,DW_DLA_STRING); /* Just fall through. file_name ok. */ } } /* else out of memory, just fall through to keep going. */ } #endif *name_ptr_out = file_name; return DW_DLV_OK; } else { char *comp_dir_name = ""; char *inc_dir_name = ""; Dwarf_Unsigned incdirnamelen = 0; Dwarf_Unsigned filenamelen = strlen(file_name); Dwarf_Unsigned compdirnamelen = 0; if (line_context->lc_compilation_directory) { /* This is safe because dwarf_dealloc is careful to not dealloc strings which dwarf_get_alloc did not allocate. */ comp_dir_name = (char *)line_context->lc_compilation_directory; compdirnamelen = strlen(comp_dir_name); } if (dirno > line_context->lc_include_directories_count) { _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD); return (DW_DLV_ERROR); } if (dirno > 0 && fe->fi_dir_index > 0) { inc_dir_name = (char *) line_context->lc_include_directories[ fe->fi_dir_index - 1]; if (!inc_dir_name) { /* This should never ever happen except in case of a corrupted object file. */ inc_dir_name = ""; } incdirnamelen = strlen(inc_dir_name); } full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING, compdirnamelen + 1 + incdirnamelen + 1 + filenamelen + 1); if (full_name == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } if (fe->fi_dir_index == 0) { /* Just use comp dir name */ if (compdirnamelen > 0) { special_cat(full_name,comp_dir_name,compdirnamelen); strcat(full_name, "/"); } special_cat(full_name,file_name,filenamelen); *name_ptr_out = full_name; return DW_DLV_OK; } if (incdirnamelen > 0 && _dwarf_file_name_is_full_path((Dwarf_Small*)inc_dir_name) ) { /* Just use inc dir. */ special_cat(full_name,inc_dir_name,incdirnamelen); strcat(full_name,"/"); special_cat(full_name,file_name,filenamelen); *name_ptr_out = full_name; return DW_DLV_OK; } /* Concat all three names. */ if (compdirnamelen > 0) { special_cat(full_name,comp_dir_name,compdirnamelen); strcat(full_name, "/"); } if (incdirnamelen > 0) { special_cat(full_name,inc_dir_name,incdirnamelen); strcat(full_name, "/"); } special_cat(full_name,file_name,filenamelen); } *name_ptr_out = full_name; return DW_DLV_OK; } /* Although source files is supposed to return the source files in the compilation-unit, it does not look for any in the statement program. In other words, it ignores those defined using the extended opcode DW_LNE_define_file. We do not know of a producer that uses DW_LNE_define_file. In DWARF2,3,4 the array of sourcefiles is represented differently than DWARF5. DWARF 2,3,4: Take the line number from macro information or lines data and subtract 1 to index into srcfiles. Any with line number zero are taken to refer to DW_AT_comp_dir from the CU DIE DWARF 5: Index (from macro or lines data) directly into srcfiles. Index zero is the base compilation directory name. */ int dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed * srcfilecount, Dwarf_Error * error) { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ Dwarf_Small *line_ptr = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ Dwarf_Attribute stmt_list_attr = 0; const char * const_comp_name = 0; /* Pointer to name of compilation directory. */ const char * const_comp_dir = 0; Dwarf_Small *comp_dir = 0; /* Offset into .debug_line specified by a DW_AT_stmt_list attribute. */ Dwarf_Unsigned line_offset = 0; /* This points to a block of char *'s, each of which points to a file name. */ char **ret_files = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; Dwarf_CU_Context context = 0; Dwarf_Line_Context line_context = 0; /* Used to chain the file names. */ Dwarf_Chain curr_chain = NULL; Dwarf_Chain prev_chain = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Half attrform = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; unsigned i = 0; int res = DW_DLV_ERROR; Dwarf_Small *section_start = 0; /* ***** BEGIN CODE ***** */ /* Reset error. */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { return resattr; } if (dbg->de_debug_line.dss_index == 0) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return res; } if (!dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return (DW_DLV_NO_ENTRY); } section_start = dbg->de_debug_line.dss_data; lres = dwarf_whatform(stmt_list_attr,&attrform,error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 && attrform != DW_FORM_sec_offset && attrform != DW_FORM_GNU_ref_alt) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_WRONG_FORM); return (DW_DLV_ERROR); } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return (DW_DLV_ERROR); } line_ptr = dbg->de_debug_line.dss_data + line_offset; { Dwarf_Unsigned fission_offset = 0; Dwarf_Unsigned fission_size = 0; int resl = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if(resl != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return resl; } line_ptr += fission_offset; if (line_ptr > dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR); return DW_DLV_ERROR; } } dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir, &const_comp_name,error); if (resattr == DW_DLV_ERROR) { return resattr; } /* Horrible cast away const to match historical interfaces. */ comp_dir = (Dwarf_Small *)const_comp_dir; line_context = (Dwarf_Line_Context) _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); if (line_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } line_context->lc_new_style_access = false; /* We are in dwarf_srcfiles() */ { Dwarf_Small *line_ptr_out = 0; int dres = 0; dres = _dwarf_read_line_table_header(dbg, context, section_start, line_ptr, dbg->de_debug_line.dss_size, &line_ptr_out, line_context, NULL, NULL,error, 0); if (dres == DW_DLV_ERROR) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); line_context = 0; return dres; } if (dres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); line_context = 0; return dres; } } /* For DWARF5, use of DW_AT_comp_dir not needed. Line table file names and directories start with comp_dir and name. FIXME DWARF5 */ line_context->lc_compilation_directory = comp_dir; /* We are in dwarf_srcfiles() */ { Dwarf_File_Entry fe = 0; Dwarf_File_Entry fe2 =line_context->lc_file_entries; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; res = dwarf_srclines_files_indexes(line_context, &baseindex, &file_count, &endindex, error); if (res != DW_DLV_OK) { return res; } for (i = baseindex; i < endindex; ++i,fe2 = fe->fi_next ) { int sres = 0; char *name_out = 0; fe = fe2; sres = create_fullest_file_path(dbg,fe,line_context, &name_out,error); if (sres != DW_DLV_OK) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); /* This can leak some strings */ return sres; } curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (curr_chain == NULL) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_chain->ch_item = name_out; if (head_chain == NULL) { head_chain = prev_chain = curr_chain; } else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } } } if (!head_chain) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); *srcfiles = NULL; *srcfilecount = 0; return DW_DLV_NO_ENTRY; } /* We are in dwarf_srcfiles() */ if (line_context->lc_file_entry_count == 0) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); *srcfiles = NULL; *srcfilecount = 0; return DW_DLV_NO_ENTRY; } ret_files = (char **) _dwarf_get_alloc(dbg, DW_DLA_LIST, line_context->lc_file_entry_count); if (ret_files == NULL) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_chain = head_chain; for (i = 0; i < line_context->lc_file_entry_count; i++) { *(ret_files + i) = curr_chain->ch_item; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); } /* Our chain is not recorded in the line_context so the line_context destructor will not destroy our list of strings or our strings. Our caller has to do the deallocations. */ *srcfiles = ret_files; *srcfilecount = line_context->lc_file_entry_count; dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); return (DW_DLV_OK); } /* Return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR doaddrs is true iff this is being called for SGI IRIX rqs processing (ie, not a normal libdwarf dwarf_srclines or two-level user call at all). dolines is true iff this is called by a dwarf_srclines call. In case of error or NO_ENTRY in this code we use the dwarf_srcline_dealloc(line_context) and dealloc of DW_DLA_LINE_CONTEXT from the new interface for uniformity here. */ int _dwarf_internal_srclines(Dwarf_Die die, Dwarf_Bool is_new_interface, Dwarf_Unsigned * version, Dwarf_Small * table_count, /* returns 0,1, or 2 */ Dwarf_Line_Context *line_context_out, Dwarf_Line ** linebuf, Dwarf_Signed * linecount, Dwarf_Line ** linebuf_actuals, Dwarf_Signed * linecount_actuals, Dwarf_Bool doaddrs, Dwarf_Bool dolines, Dwarf_Error * error) { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ Dwarf_Small *line_ptr = 0; /* This points to the last byte of the .debug_line portion for the current cu. */ Dwarf_Small *line_ptr_end = 0; /* For two-level line tables, this points to the first byte of the actuals table (and the end of the logicals table) for the current cu. */ Dwarf_Small *line_ptr_actuals = 0; Dwarf_Small *section_start = 0; Dwarf_Small *section_end = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ Dwarf_Attribute stmt_list_attr = 0; const char * const_comp_name = 0; /* Pointer to name of compilation directory. */ const char * const_comp_dir = NULL; Dwarf_Small *comp_dir = NULL; /* Offset into .debug_line specified by a DW_AT_stmt_list attribute. */ Dwarf_Unsigned line_offset = 0; /* Pointer to a Dwarf_Line_Context_s structure that contains the context such as file names and include directories for the set of lines being generated. This is always recorded on an DW_LNS_end_sequence operator, on all special opcodes, and on DW_LNS_copy. */ Dwarf_Line_Context line_context = 0; Dwarf_CU_Context cu_context = 0; Dwarf_Unsigned fission_offset = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; Dwarf_Half address_size = 0; Dwarf_Small * orig_line_ptr = 0; int res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = cu_context->cc_dbg; res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_line.dss_size) { return (DW_DLV_NO_ENTRY); } address_size = _dwarf_get_address_size(dbg, die); resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { return resattr; } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return (DW_DLV_ERROR); } section_start = dbg->de_debug_line.dss_data; section_end = section_start +dbg->de_debug_line.dss_size; { Dwarf_Unsigned fission_size = 0; int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if(resf != DW_DLV_OK) { dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return resf; } line_ptr += fission_offset; if (line_ptr > section_end) { _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR); return DW_DLV_ERROR; } } section_start = dbg->de_debug_line.dss_data; section_end = section_start +dbg->de_debug_line.dss_size; orig_line_ptr = section_start + line_offset + fission_offset; line_ptr = orig_line_ptr; dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); if ((line_offset + fission_offset) > dbg->de_debug_line.dss_size) { _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); } if (line_ptr > section_end) { _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } /* If die has DW_AT_comp_dir attribute, get the string that names the compilation directory. */ resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir, &const_comp_name,error); if (resattr == DW_DLV_ERROR) { return resattr; } /* Horrible cast to match historic interfaces. */ comp_dir = (Dwarf_Small *)const_comp_dir; line_context = (Dwarf_Line_Context) _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); if (line_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } line_context->lc_new_style_access = is_new_interface; line_context->lc_compilation_directory = comp_dir; /* We are in dwarf_internal_srclines() */ { Dwarf_Small *newlinep = 0; int resp = _dwarf_read_line_table_header(dbg, cu_context, section_start, line_ptr, dbg->de_debug_line.dss_size, &newlinep, line_context, NULL,NULL, error, 0); if (resp == DW_DLV_ERROR) { if(is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return resp; } if (resp == DW_DLV_NO_ENTRY) { if(is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return resp; } line_ptr_end = line_context->lc_line_ptr_end; line_ptr = newlinep; if (line_context->lc_actuals_table_offset > 0) { line_ptr_actuals = line_context->lc_line_prologue_start + line_context->lc_actuals_table_offset; } } if (line_ptr_actuals == 0) { /* ASSERT: lc_table_count == 1 or lc_table_count == 0 */ int err_count_out = 0; /* Normal style (single level) line table. */ Dwarf_Bool is_actuals_table = false; Dwarf_Bool local_is_single_table = true; res = read_line_table_program(dbg, line_ptr, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, local_is_single_table, is_actuals_table, error, &err_count_out); if (res != DW_DLV_OK) { if(is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return res; } if (linebuf) *linebuf = line_context->lc_linebuf_logicals; if (linecount) *linecount = line_context->lc_linecount_logicals; if (linebuf_actuals) { *linebuf_actuals = NULL; } if (linecount_actuals) { *linecount_actuals = 0; } } else { Dwarf_Bool is_actuals_table = false; Dwarf_Bool local2_is_single_table = false; int err_count_out = 0; line_context->lc_is_single_table = false; /* Two-level line table. First read the logicals table. */ res = read_line_table_program(dbg, line_ptr, line_ptr_actuals, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, local2_is_single_table, is_actuals_table, error, &err_count_out); if (res != DW_DLV_OK) { if(is_new_interface) { dwarf_srclines_dealloc_b(line_context); } else { dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT); } return res; } if (linebuf) { *linebuf = line_context->lc_linebuf_logicals; } else { } if (linecount) { *linecount = line_context->lc_linecount_logicals; } if (is_new_interface) { /* ASSERT: linebuf_actuals == NULL */ is_actuals_table = true; /* The call requested an actuals table and one is present. So now read that one. */ res = read_line_table_program(dbg, line_ptr_actuals, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, local2_is_single_table, is_actuals_table, error, &err_count_out); if (res != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return res; } if (linebuf_actuals) { *linebuf_actuals = line_context->lc_linebuf_actuals; } if (linecount_actuals != NULL) { *linecount_actuals = line_context->lc_linecount_actuals; } } } if (!is_new_interface && linecount && (linecount == 0 ||*linecount == 0) && (linecount_actuals == 0 || *linecount_actuals == 0)) { /* Here we have no actual lines of any kind. In other words, it looks like a debugfission line table skeleton or a caller not prepared for skeletons or two-level reading.. In that case there are no line entries so the context had nowhere to be recorded. Hence we have to delete it else we would leak the context. */ dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); line_context = 0; return DW_DLV_OK; } *table_count = line_context->lc_table_count; if (version != NULL) { *version = line_context->lc_version_number; } *line_context_out = line_context; return (DW_DLV_OK); } int dwarf_get_ranges_section_name(Dwarf_Debug dbg, const char **section_name_out, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_ranges; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_get_aranges_section_name(Dwarf_Debug dbg, const char **section_name_out, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; if (error != NULL) { *error = NULL; } sec = &dbg->de_debug_aranges; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_get_line_section_name_from_die(Dwarf_Die die, const char **section_name_out, Dwarf_Error * error) { /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; struct Dwarf_Section_s *sec = 0; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; sec = &dbg->de_debug_line; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_get_string_section_name(Dwarf_Debug dbg, const char **section_name_out, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; /* ***** 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. */ return DW_DLV_NO_ENTRY; } *section_name_out = sec->dss_name; return DW_DLV_OK; } int dwarf_srclines(Dwarf_Die die, Dwarf_Line ** linebuf, Dwarf_Signed * linecount, Dwarf_Error * error) { Dwarf_Unsigned version = 0; Dwarf_Line_Context line_context = 0; Dwarf_Small table_count = 0; Dwarf_Bool is_new_interface = false; int res = _dwarf_internal_srclines(die, is_new_interface, &version, &table_count, &line_context, linebuf, linecount, /* linebuf_actuals */ 0, /*linecount_actuals*/0, /* addrlist= */ false, /* linelist= */ true, error); return res; } int dwarf_srclines_two_level(Dwarf_Die die, Dwarf_Unsigned * version, Dwarf_Line ** linebuf, Dwarf_Signed * linecount, Dwarf_Line ** linebuf_actuals, Dwarf_Signed * linecount_actuals, Dwarf_Error * error) { Dwarf_Line_Context line_context = 0; Dwarf_Small table_count = 0; Dwarf_Bool is_new_interface = false; int res = _dwarf_internal_srclines(die, is_new_interface, version, &table_count, &line_context, linebuf, linecount, linebuf_actuals, linecount_actuals, /* addrlist= */ false, /* linelist= */ true, error); return res; } /* New October 2015. */ int dwarf_srclines_b(Dwarf_Die die, Dwarf_Unsigned * version_out, Dwarf_Small * table_count, Dwarf_Line_Context * line_context, Dwarf_Error * error) { Dwarf_Signed linecount_actuals = 0; Dwarf_Line *linebuf = 0; Dwarf_Line *linebuf_actuals = 0; Dwarf_Signed linecount = 0; Dwarf_Bool is_new_interface = true; int res = 0; Dwarf_Unsigned tcount = 0; res = _dwarf_internal_srclines(die, is_new_interface, version_out, table_count, line_context, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, /* addrlist= */ false, /* linelist= */ true, error); if (res == DW_DLV_OK) { (*line_context)->lc_new_style_access = true; } if(linecount_actuals ) { tcount++; } if(linecount ) { tcount++; } *table_count = tcount; return res; } /* New October 2015. */ int dwarf_srclines_from_linecontext(Dwarf_Line_Context line_context, Dwarf_Line** linebuf, Dwarf_Signed * linecount, Dwarf_Error * error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if (!line_context->lc_new_style_access) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *linebuf = line_context->lc_linebuf_logicals; *linecount = line_context->lc_linecount_logicals; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_two_level_from_linecontext(Dwarf_Line_Context line_context, Dwarf_Line** linebuf, Dwarf_Signed * linecount, Dwarf_Line** linebuf_actuals, Dwarf_Signed * linecount_actuals, Dwarf_Error * error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if (!line_context->lc_new_style_access) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *linebuf = line_context->lc_linebuf_logicals; *linecount = line_context->lc_linecount_logicals; *linebuf_actuals = line_context->lc_linebuf_actuals; *linecount_actuals = line_context->lc_linecount_actuals; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_table_offset(Dwarf_Line_Context line_context, Dwarf_Unsigned * offset, Dwarf_Error * error) { if (!line_context ){ _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if( line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *offset = line_context->lc_section_offset; return DW_DLV_OK; } /* New October 2015. */ /* If the CU DIE has no DW_AT_comp_dir then the pointer pushed back to *compilation_directory will be NULL. Foy DWARF5 the line table header has the compilation directory. FIXME DWARF5. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context, const char ** compilation_directory, Dwarf_Error * error) { if (!line_context ){ _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if( line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *compilation_directory = (const char *)line_context->lc_compilation_directory; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context line_context, Dwarf_Signed * count_out, Dwarf_Error * error) { if (!line_context ){ _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if( line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *count_out = line_context->lc_subprogs_count; return DW_DLV_OK; } /* New October 2015. */ /* Index says which to return. Valid indexes are 1-lc_subprogs_count */ int dwarf_srclines_subprog_data(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned *decl_file, Dwarf_Unsigned *decl_line, Dwarf_Error *error) { /* Negative values not sensible. Leaving traditional signed interfaces. */ Dwarf_Unsigned index = (Dwarf_Unsigned)index_in; Dwarf_Subprog_Entry sub = 0; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if (index < 1 || index > line_context->lc_subprogs_count) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return (DW_DLV_ERROR); } sub = line_context->lc_subprogs + (index-1); *name = (const char *)sub->ds_subprog_name; *decl_file = sub->ds_decl_file; *decl_line = sub->ds_decl_line; return DW_DLV_OK; } /* New October 2015. See also dwarf_srclines_files_indexes() */ int dwarf_srclines_files_count(Dwarf_Line_Context line_context, Dwarf_Signed *count_out, Dwarf_Error *error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } /* Negative values not sensible. Leaving traditional signed interfaces. */ *count_out = (Dwarf_Signed)line_context->lc_file_entry_count; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_files_data(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Error * error) { return dwarf_srclines_files_data_b( line_context,index_in,name,directory_index, last_mod_time,file_length,0,error); } /* New March 2018 making iteration through file names. */ int dwarf_srclines_files_indexes(Dwarf_Line_Context line_context, Dwarf_Signed *baseindex, Dwarf_Signed *file_count, Dwarf_Signed *endindex, Dwarf_Error * error) { if(line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return DW_DLV_ERROR; } *baseindex = line_context->lc_file_entry_baseindex; *file_count = line_context->lc_file_entry_count; *endindex = line_context->lc_file_entry_endindex; return DW_DLV_OK; } /* New March 2018 adding DWARF5 data. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** data16ptr, Dwarf_Error * error) { Dwarf_File_Entry fi = 0; Dwarf_Signed i =0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; /* Negative values not sensible. Leaving traditional signed interfaces. */ Dwarf_Signed index = index_in; int res = 0; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } /* Special accomodation of the special gnu experimental version number (a high number) so we cannot just say '5 or greater'. This is awkward, but at least if there is a version 6 or later it still allows the experimental table. */ res = dwarf_srclines_files_indexes(line_context, &baseindex, &file_count, &endindex, error); if (res != DW_DLV_OK) { return res; } fi = line_context->lc_file_entries; if (index < baseindex || index >= endindex) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return DW_DLV_ERROR; } for ( i = baseindex;i < index; i++) { fi = fi->fi_next; if(!fi) { _dwarf_error(NULL, error, DW_DLE_LINE_HEADER_CORRUPT); return DW_DLV_ERROR; } } if(name) { *name = (const char *)fi->fi_file_name; } if (directory_index) { *directory_index = fi->fi_dir_index; } if (last_mod_time) { *last_mod_time = fi->fi_time_last_mod; } if (file_length) { *file_length = fi->fi_file_length; } if (data16ptr) { if (fi->fi_md5_present) { *data16ptr = &fi->fi_md5_value; } else { *data16ptr = 0; } } return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *count = line_context->lc_include_directories_count; return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Error * error) { /* It never made sense that the srclines used a signed count. But that cannot be fixed in interfaces for compatibility. So we adjust here. */ Dwarf_Unsigned index = index_in; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } if (index < 1 || index > line_context->lc_include_directories_count) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); return (DW_DLV_ERROR); } *name = (const char *)(line_context->lc_include_directories[index-1]); return DW_DLV_OK; } /* New October 2015. */ int dwarf_srclines_version(Dwarf_Line_Context line_context, Dwarf_Unsigned *version_out, Dwarf_Small *table_count_out, Dwarf_Error *error) { if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } *version_out = line_context->lc_version_number; *table_count_out = line_context->lc_table_count; return DW_DLV_OK; } /* Every line table entry (except DW_DLE_end_sequence, which is returned using dwarf_lineendsequence()) potentially has the begin-statement flag marked 'on'. This returns thru *return_bool, the begin-statement flag. */ int dwarf_linebeginstatement(Dwarf_Line line, Dwarf_Bool * return_bool, Dwarf_Error * error) { if (line == NULL || return_bool == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *return_bool = (line->li_addr_line.li_l_data.li_is_stmt); return DW_DLV_OK; } /* At the end of any contiguous line-table there may be a DW_LNE_end_sequence operator. This returns non-zero thru *return_bool if and only if this 'line' entry was a DW_LNE_end_sequence. Within a compilation unit or function there may be multiple line tables, each ending with a DW_LNE_end_sequence. Each table describes a contiguous region. Because compilers may split function code up in arbitrary ways compilers may need to emit multiple contigous regions (ie line tables) for a single function. See the DWARF3 spec section 6.2. */ int dwarf_lineendsequence(Dwarf_Line line, Dwarf_Bool * return_bool, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *return_bool = (line->li_addr_line.li_l_data.li_end_sequence); return DW_DLV_OK; } /* Each 'line' entry has a line-number. If the entry is a DW_LNE_end_sequence the line-number is meaningless (see dwarf_lineendsequence(), just above). */ int dwarf_lineno(Dwarf_Line line, Dwarf_Unsigned * ret_lineno, Dwarf_Error * error) { if (line == NULL || ret_lineno == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *ret_lineno = (line->li_addr_line.li_l_data.li_line); return DW_DLV_OK; } /* Each 'line' entry has a file-number, and index into the file table. If the entry is a DW_LNE_end_sequence the index is meaningless (see dwarf_lineendsequence(), just above). The file number returned is an index into the file table produced by dwarf_srcfiles(), but care is required: the li_file begins with 1 for DWARF2,3,4 files, so that the li_file returned here is 1 greater than its index into the dwarf_srcfiles() output array. And entries from DW_LNE_define_file don't appear in the dwarf_srcfiles() output so file indexes from here may exceed the size of the dwarf_srcfiles() output array size. */ int dwarf_line_srcfileno(Dwarf_Line line, Dwarf_Unsigned * ret_fileno, Dwarf_Error * error) { if (line == NULL || ret_fileno == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } /* li_file must be <= line->li_context->lc_file_entry_count else it is trash. li_file 0 means not attributable to any source file per dwarf2/3 spec. For DWARF5, li_file < lc_file_entry_count */ *ret_fileno = (line->li_addr_line.li_l_data.li_file); return DW_DLV_OK; } /* Each 'line' entry has an is_addr_set attribute. If the entry is a DW_LNE_set_address, return TRUE through the *is_addr_set pointer. */ int dwarf_line_is_addr_set(Dwarf_Line line, Dwarf_Bool *is_addr_set, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *is_addr_set = (line->li_addr_line.li_l_data.li_is_addr_set); return DW_DLV_OK; } /* Each 'line' entry has a line-address. If the entry is a DW_LNE_end_sequence the adddress is one-beyond the last address this contigous region covers, so the address is not inside the region, but is just outside it. */ int dwarf_lineaddr(Dwarf_Line line, Dwarf_Addr * ret_lineaddr, Dwarf_Error * error) { if (line == NULL || ret_lineaddr == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *ret_lineaddr = (line->li_address); return DW_DLV_OK; } /* Obsolete: do not use this function. December 2011: For reasons lost in the mists of history, this returned -1, not zero (through the pointer ret_lineoff), if the column was zero. That was always bogus, even in DWARF2. It is also bogus that the column value is signed, but it is painful to change the argument type in 2011, so leave it. */ int dwarf_lineoff(Dwarf_Line line, Dwarf_Signed * ret_lineoff, Dwarf_Error * error) { if (line == NULL || ret_lineoff == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *ret_lineoff = ( (line->li_addr_line.li_l_data.li_column == 0) ? -1 : line->li_addr_line.li_l_data.li_column); return DW_DLV_OK; } /* Each 'line' entry has a column-within-line (offset within the line) where the source text begins. If the entry is a DW_LNE_end_sequence the line-number is meaningless (see dwarf_lineendsequence(), just above). Lines of text begin at column 1. The value 0 means the line begins at the left edge of the line. (See the DWARF3 spec, section 6.2.2). So 0 and 1 mean essentially the same thing. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line line, Dwarf_Unsigned * ret_lineoff, Dwarf_Error * error) { if (line == NULL || ret_lineoff == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *ret_lineoff = line->li_addr_line.li_l_data.li_column; return DW_DLV_OK; } static int dwarf_filename(Dwarf_Line_Context context, Dwarf_Signed fileno_in, char **ret_filename, Dwarf_Error *error) { Dwarf_Signed i = 0; Dwarf_File_Entry file_entry = 0; Dwarf_Debug dbg = context->lc_dbg; int res = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; /* Negative values not sensible. Leaving traditional signed interfaces in place. */ Dwarf_Signed fileno = fileno_in; res = dwarf_srclines_files_indexes(context, &baseindex, &file_count, &endindex, error); if (res != DW_DLV_OK) { return res; } if (fileno < baseindex || fileno >= endindex) { _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); return (DW_DLV_ERROR); } file_entry = context->lc_file_entries; /* ASSERT: li_file > 0, dwarf correctness issue, see line table definition of dwarf2/3 spec. */ for (i = baseindex; i < fileno ; i++) { file_entry = file_entry->fi_next; } res = create_fullest_file_path(dbg, file_entry,context, ret_filename,error); return res; } int dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } if (line->li_context == NULL) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); return DW_DLV_ERROR; } return dwarf_filename(line->li_context, line->li_addr_line.li_l_data.li_file, ret_linesrc, error); } /* Every line table entry potentially has the basic-block-start flag marked 'on'. This returns thru *return_bool, the basic-block-start flag. */ int dwarf_lineblock(Dwarf_Line line, Dwarf_Bool * return_bool, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *return_bool = (line->li_addr_line.li_l_data.li_basic_block); return DW_DLV_OK; } /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line line, Dwarf_Bool * prologue_end, Dwarf_Bool * epilogue_begin, Dwarf_Unsigned * isa, Dwarf_Unsigned * discriminator, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *prologue_end = (line->li_addr_line.li_l_data.li_prologue_end); *epilogue_begin = (line->li_addr_line.li_l_data.li_epilogue_begin); *isa = (line->li_addr_line.li_l_data.li_isa); *discriminator = (line->li_addr_line.li_l_data.li_discriminator); return DW_DLV_OK; } int dwarf_linelogical(Dwarf_Line line, Dwarf_Unsigned * logical, Dwarf_Error* error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *logical = (line->li_addr_line.li_l_data.li_line); return DW_DLV_OK; } int dwarf_linecontext(Dwarf_Line line, Dwarf_Unsigned * context, Dwarf_Error* error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *context = (line->li_addr_line.li_l_data.li_call_context); return DW_DLV_OK; } int dwarf_line_subprogno(Dwarf_Line line, Dwarf_Unsigned * subprog, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return (DW_DLV_ERROR); } *subprog = (line->li_addr_line.li_l_data.li_subprogram); return DW_DLV_OK; } int dwarf_line_subprog(Dwarf_Line line, char ** subprog_name, char ** decl_filename, Dwarf_Unsigned * decl_line, Dwarf_Error * error) { Dwarf_Unsigned subprog_no; Dwarf_Subprog_Entry subprog; Dwarf_Debug dbg; int res; if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); return DW_DLV_ERROR; } if (line->li_context == NULL) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); return DW_DLV_ERROR; } dbg = line->li_context->lc_dbg; subprog_no = line->li_addr_line.li_l_data.li_subprogram; if (subprog_no == 0) { *subprog_name = NULL; *decl_filename = NULL; *decl_line = 0; return DW_DLV_OK; } if (subprog_no > line->li_context->lc_subprogs_count) { _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); return DW_DLV_ERROR; } subprog = &line->li_context->lc_subprogs[subprog_no - 1]; *subprog_name = (char *)subprog->ds_subprog_name; *decl_line = subprog->ds_decl_line; res = dwarf_filename(line->li_context, subprog->ds_decl_file, decl_filename, error); if (res != DW_DLV_OK) { *decl_filename = NULL; } return DW_DLV_OK; } static void delete_line_context_itself(Dwarf_Line_Context context) { Dwarf_Debug dbg = 0; Dwarf_File_Entry fe = 0; if(context->lc_magic != DW_CONTEXT_MAGIC) { /* Something is wrong. */ return; } dbg = context->lc_dbg; fe = context->lc_file_entries; while (fe) { Dwarf_File_Entry fenext = fe->fi_next; fe->fi_next = 0; free(fe); fe = fenext; } context->lc_file_entries = 0; context->lc_file_entry_count = 0; context->lc_file_entry_baseindex = 0; context->lc_file_entry_endindex = 0; if (context->lc_subprogs) { free(context->lc_subprogs); context->lc_subprogs = 0; } if (context->lc_include_directories) { free(context->lc_include_directories); context->lc_include_directories = 0; } context->lc_magic = 0xdead; dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT); } /* It's impossible for callers of dwarf_srclines() to get to and free all the resources (in particular, the li_context and its lc_file_entries). So this function, new July 2005, does it. As of September 2015 this will now delete either table of a two-level line table. In the two-level case one calls it once each on both the logicals and actuals tables. (in either order, the order is not critical). Once the logicals table is dealloced any use of the actuals table will surely result in chaos. Just do the two calls one after the other. In the standard single-table case (DWARF 2,3,4) one calls it just once on the linebuf. Old style dealloc. Should never be used with dwarf_srclines_b(), but if it is there are no bad consequences.. Those using standard DWARF should use dwarf_srclines_b() and dwarf_srclines_dealloc_b() instead of dwarf_srclines and dwarf_srclines_dealloc() as that gives access to various bits of useful information. */ void dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf, Dwarf_Signed count) { Dwarf_Signed i = 0; /* alternate_data_count is a failsafe to prevent duplicate frees when there is inappropriate mixing of new interface and this old routine */ Dwarf_Bool alternate_data_count = 0; struct Dwarf_Line_Context_s *line_context = 0; if(!linebuf) { return; } if (count > 0) { /* All these entries share a single line_context, and for two-levels tables each table gets it too. Hence we will dealloc ONLY if !is_actuals_table so for single and two-level tables the space is deallocated. */ line_context = linebuf[0]->li_context; if (line_context && line_context->lc_magic != DW_CONTEXT_MAGIC ) { /* Something is very wrong. */ line_context = 0; } else if (line_context) { if (linebuf == line_context->lc_linebuf_logicals) { line_context->lc_linebuf_logicals = 0; line_context->lc_linecount_logicals = 0; alternate_data_count = line_context->lc_linecount_actuals; /* Ok to delete logicals */ } else if (linebuf == line_context->lc_linebuf_actuals) { /* Ok to delete actuals */ line_context->lc_linebuf_actuals = 0; line_context->lc_linecount_actuals = 0; alternate_data_count = line_context->lc_linecount_logicals; } else { /* Something is wrong very wrong. */ return; } } else { /* Else: impossible. Unless the caller passed in a bogus linebuf. */ line_context = 0; } } /* Here we actually delete a set of lines. */ for (i = 0; i < count; ++i) { dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE); } dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); if (line_context && !line_context->lc_new_style_access && !alternate_data_count ) { /* There is nothing left referencing this line_context. */ dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); } return; } /* New October 2015. This should be used to deallocate all lines data that is set up by dwarf_srclines_b(). This and dwarf_srclines_b() are now (October 2015) the preferred routine to use. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context line_context) { Dwarf_Line *linestable = 0; Dwarf_Signed linescount = 0; Dwarf_Signed i = 0; Dwarf_Debug dbg = 0; if(!line_context) { return; } if(line_context->lc_magic != DW_CONTEXT_MAGIC) { /* Something is wrong. */ return; } dbg = line_context->lc_dbg; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { /* Something is badly wrong here.*/ return; } linestable = line_context->lc_linebuf_logicals; linescount = line_context->lc_linecount_logicals; for (i = 0; i < linescount ; ++i) { dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE); } dwarf_dealloc(dbg, linestable, DW_DLA_LIST); line_context->lc_linebuf_logicals = 0; line_context->lc_linecount_logicals = 0; linestable = line_context->lc_linebuf_actuals; linescount = line_context->lc_linecount_actuals; for (i = 0; i lc_linebuf_actuals = 0; line_context->lc_linecount_actuals = 0; delete_line_context_itself(line_context); } /* There is an error, so count it. If we are printing errors by command line option, print the details. */ void _dwarf_print_header_issue(Dwarf_Debug dbg, const char *specific_msg, Dwarf_Small *data_start, Dwarf_Signed value, unsigned index, unsigned tabv, unsigned linetabv, int *err_count_out) { if (!err_count_out) { return; } /* Are we in verbose mode */ if (dwarf_cmdline_options.check_verbose_mode){ dwarf_printf(dbg, "\n*** DWARF CHECK: " ".debug_line: %s %" DW_PR_DSd, specific_msg,value); if (index || tabv || linetabv) { dwarf_printf(dbg,"; Mismatch index %u stdval %u linetabval %u", index,tabv,linetabv); } if (data_start >= dbg->de_debug_line.dss_data && (data_start < (dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size))) { Dwarf_Unsigned off = data_start - dbg->de_debug_line.dss_data; dwarf_printf(dbg, " at offset 0x%" DW_PR_XZEROS DW_PR_DUx " ( %" DW_PR_DUu " ) ", off,off); } else { dwarf_printf(dbg, " (unknown section location) "); } dwarf_printf(dbg,"***\n"); } *err_count_out += 1; } int _dwarf_decode_line_string_form(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Unsigned offset_size, Dwarf_Small **line_ptr, Dwarf_Small *line_ptr_end, char **return_str, Dwarf_Error * error) { int res = 0; switch (form) { case DW_FORM_line_strp: { Dwarf_Small *secstart = 0; Dwarf_Small *secend = 0; Dwarf_Small *strptr = 0; Dwarf_Unsigned offset = 0; Dwarf_Small *offsetptr = *line_ptr; res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error); if (res != DW_DLV_OK) { return res; } secstart = dbg->de_debug_line_str.dss_data; secend = secstart + dbg->de_debug_line_str.dss_size; READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,offsetptr, offset_size, error,line_ptr_end); *line_ptr += offset_size; strptr = secstart + offset; res = _dwarf_check_string_valid(dbg, secstart,strptr,secend, DW_DLE_LINE_STRP_OFFSET_BAD,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *) strptr; return DW_DLV_OK; } case DW_FORM_string: { Dwarf_Small *secend = line_ptr_end; Dwarf_Small *strptr = *line_ptr; res = _dwarf_check_string_valid(dbg, strptr ,strptr,secend,DW_DLE_LINE_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } *return_str = (char *)strptr; *line_ptr += strlen((const char *)strptr) + 1; return DW_DLV_OK; } default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return DW_DLV_ERROR; } } int _dwarf_decode_line_udata_form(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Small **line_ptr, Dwarf_Unsigned *return_val, Dwarf_Small *line_end_ptr, Dwarf_Error * error) { Dwarf_Unsigned val = 0; Dwarf_Small * lp = *line_ptr; switch (form) { case DW_FORM_udata: DECODE_LEB128_UWORD_CK(lp, val,dbg,error,line_end_ptr); *return_val = val; *line_ptr = lp; return DW_DLV_OK; default: _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return DW_DLV_ERROR; } } void _dwarf_update_chain_list( Dwarf_Chain chain_line, Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain) { if (*head_chain == NULL) { *head_chain = chain_line; } else { (*curr_chain)->ch_next = chain_line; } *curr_chain = chain_line; } void _dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count) { int i = 0; Dwarf_Chain curr_chain = head; for (i = 0; i < count; i++) { Dwarf_Chain t = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, t, DW_DLA_CHAIN); } } int _dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe) { if (!context->lc_file_entries) { context->lc_file_entries = fe; } else { context->lc_last_entry->fi_next = fe; } context->lc_last_entry = fe; context->lc_file_entry_count++; /* Here we attempt to write code to make it easy to interate though source file names without having to code specially for DWARF2,3,4 vs DWARF5 */ if (context->lc_version_number >= DW_LINE_VERSION5 && context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) { context->lc_file_entry_baseindex = 0; context->lc_file_entry_endindex = context->lc_file_entry_count; } else { /* DWARF2,3,4 and the EXPERIMENTAL_LINE_TABLES_VERSION. */ context->lc_file_entry_baseindex = 1; context->lc_file_entry_endindex = context->lc_file_entry_count+1; } return DW_DLV_OK; } int _dwarf_line_context_constructor(Dwarf_Debug dbg, void *m) { Dwarf_Line_Context line_context = (Dwarf_Line_Context)m; /* dwarf_get_alloc ensures the bytes are all zero when m is passed to us. */ line_context->lc_magic = DW_CONTEXT_MAGIC; line_context->lc_dbg = dbg; return DW_DLV_OK; } /* This cleans up a contex record. The lines tables (actuals and logicals) are themselves items that will be dealloc'd either manually or, at closing the libdwarf dbg, automatically. So we DO NOT touch the lines tables here */ void _dwarf_line_context_destructor(void *m) { Dwarf_Line_Context line_context = (Dwarf_Line_Context)m; if (line_context->lc_magic != DW_CONTEXT_MAGIC) { /* Nothing is safe, do nothing. */ return; } if (line_context->lc_include_directories) { free(line_context->lc_include_directories); line_context->lc_include_directories = 0; line_context->lc_include_directories_count = 0; } if (line_context->lc_file_entries) { Dwarf_File_Entry fe = line_context->lc_file_entries; while(fe) { Dwarf_File_Entry t = fe; fe = t->fi_next; t->fi_next = 0; free(t); } line_context->lc_file_entries = 0; line_context->lc_last_entry = 0; line_context->lc_file_entry_count = 0; line_context->lc_file_entry_baseindex = 0; line_context->lc_file_entry_endindex = 0; } if (line_context->lc_subprogs) { free(line_context->lc_subprogs); line_context->lc_subprogs = 0; line_context->lc_subprogs_count = 0; } line_context->lc_magic = 0; return; } dwarfutils-20200114/libdwarf/dwarf_line.h000066400000000000000000000376331361531463500202310ustar00rootroot00000000000000/* Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2015 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 and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define DW_EXTENDED_OPCODE 0 /* This is used as the starting value for an algorithm to get the minimum difference between 2 values. UINT_MAX is used as our approximation to infinity. */ #define MAX_LINE_DIFF UINT_MAX /* This is for a sanity check on line table extended opcodes. It is entirely arbitrary, and 100 is surely too small if someone was inserting strings in the opcode. */ #define DW_LNE_LEN_MAX 100 /* This structure is used to build a list of all the files that are used in the current compilation unit. All of the fields execpt fi_next have meanings that are obvious from section 6.2.4 of the Libdwarf Doc. Because of DW_LNE_define_file we make this a list, not an array. */ struct Dwarf_File_Entry_s { struct Dwarf_File_Entry_s *fi_next; /* Points to string naming the file. */ Dwarf_Small *fi_file_name; /* Index into the list of directories of the directory in which this file exits. */ Dwarf_Unsigned fi_dir_index; /* Time of last modification of the file. */ Dwarf_Unsigned fi_time_last_mod; /* Length in bytes of the file. */ Dwarf_Unsigned fi_file_length; Dwarf_Form_Data16 fi_md5_value; char fi_md5_present; }; /* Part of two-level line tables support. */ struct Dwarf_Subprog_Entry_s { Dwarf_Small *ds_subprog_name; Dwarf_Unsigned ds_decl_file; Dwarf_Unsigned ds_decl_line; }; typedef struct Dwarf_Subprog_Entry_s *Dwarf_Subprog_Entry; /* This structure provides the context in which the fields of a Dwarf_Line structure are interpreted. They come from the statement program prologue. **Updated by dwarf_srclines in dwarf_line.c. lc_magic will be DW_CONTEXT_MAGIC unless there is a serious programming error somewhere. It's set zero when a Line_Context is deallocated. Any other value indicates there is bug somewhere. */ #define DW_CONTEXT_MAGIC 0xd00d1111 struct Dwarf_Line_Context_s { unsigned lc_magic; /* lc_new_style_access is non-zero if this was allocated via a dwarf_srclines_b() call or equivalent. Otherwise this is 0. */ unsigned char lc_new_style_access; /* The section offset (in .debug_line or .debug_line.dwo of the line table */ Dwarf_Unsigned lc_section_offset; /* 2 for DWARF2, 3 for DWARF3, 4 for DWARF4, 5 for DWARF5. 0xf006 for experimental two-level line tables. */ Dwarf_Half lc_version_number; /* Total length of the line data for this CU */ Dwarf_Unsigned lc_total_length; /* Length of the initial length field itself. */ Dwarf_Half lc_length_field_length; /* address size and segment sizefields new in DWARF5 header. */ Dwarf_Small lc_address_size; Dwarf_Small lc_segment_selector_size; Dwarf_Unsigned lc_prologue_length; Dwarf_Unsigned lc_actuals_table_offset; Dwarf_Unsigned lc_logicals_table_offset; Dwarf_Small lc_minimum_instruction_length; /* Start and end of this CU line area. pf_line_ptr_start + pf_total_length + pf_length_field_length == pf_line_ptr_end. Meaning lc_line_ptr_start is before the length info. */ Dwarf_Small *lc_line_ptr_start; Dwarf_Small *lc_line_ptr_end; /* Start of the lines themselves. */ Dwarf_Small *lc_line_ptr_lines; /* Used to check that decoding of the line prologue is done right. */ Dwarf_Small *lc_line_prologue_start; Dwarf_Small lc_default_is_stmt; Dwarf_Ubyte lc_maximum_ops_per_instruction; /*DWARF5*/ Dwarf_Sbyte lc_line_base; Dwarf_Small lc_line_range; /* Highest std opcode (+1). */ Dwarf_Small lc_opcode_base; /* pf_opcode_base -1 entries (each a count, normally the value of each entry is 0 or 1). */ Dwarf_Small *lc_opcode_length_table; /* The number to treat as standard ops. This is a special accomodation of gcc using the new standard opcodes but not updating the version number. It's legal dwarf2, but much better for the user to understand as dwarf3 when 'it looks ok'. */ Dwarf_Small lc_std_op_count; /* Points to a singly-linked list of entries providing info about source files for the current set of Dwarf_Line structures. The initial entry on the list is 'file 1' per DWARF rules. And so on. lc_last_entry points at the last entry in the list (so we can easily expand the list). It's a list (not a table) since we may encounter DW_LNE_define_file entries. */ Dwarf_File_Entry lc_file_entries; Dwarf_File_Entry lc_last_entry; /* Count of number of source files for this set of Dwarf_Line structures. */ Dwarf_Unsigned lc_file_entry_count; /* Values Easing the process of indexing through lc_file_entries. */ Dwarf_Unsigned lc_file_entry_baseindex; Dwarf_Unsigned lc_file_entry_endindex; /* Points to the portion of .debug_line section that contains a list of strings naming the included directories. Do not free(). An array of pointers to strings. */ Dwarf_Small **lc_include_directories; /* Count of the number of included directories. */ Dwarf_Unsigned lc_include_directories_count; /* Points to an array of subprogram entries. With Two level line tables this may be non-zero. An array of Dwarf_Subprogram_Entry_s structs. */ Dwarf_Subprog_Entry lc_subprogs; /* Count of the number of subprogram entries With Two level line tables this may be non-zero. */ Dwarf_Unsigned lc_subprogs_count; /* Count of the number of lines for this cu. */ Dwarf_Unsigned lc_line_count; /* Points to name of compilation directory. That string is in a .debug section so do not free this. */ Dwarf_Small *lc_compilation_directory; Dwarf_Debug lc_dbg; /* zero table count is skeleton, or just missing names. 1 is standard table. 2 means two-level table (experimantal) Other is a bug somewhere. */ Dwarf_Small lc_table_count; Dwarf_Bool lc_is_single_table; /* For standard line tables the logicals are the only tables and linecount_actuals is 0. */ Dwarf_Line *lc_linebuf_logicals; Dwarf_Unsigned lc_linecount_logicals; /* Non-zero only if two-level table with actuals */ Dwarf_Line *lc_linebuf_actuals; Dwarf_Unsigned lc_linecount_actuals; }; /* The line table set of registers. The state machine state variables. Using names from the DWARF documentation but preceded by lr_. */ struct Dwarf_Line_Registers_s { Dwarf_Addr lr_address; /* DWARF2 */ Dwarf_Unsigned lr_file ; /* DWARF2 */ Dwarf_Unsigned lr_line ; /* DWARF2 */ Dwarf_Unsigned lr_column ; /* DWARF2 */ Dwarf_Bool lr_is_stmt; /* DWARF2 */ Dwarf_Bool lr_basic_block; /* DWARF2 */ Dwarf_Bool lr_end_sequence; /* DWARF2 */ Dwarf_Bool lr_prologue_end; /* DWARF3 */ Dwarf_Bool lr_epilogue_begin; /* DWARF3 */ Dwarf_Small lr_isa; /* DWARF3 */ Dwarf_Unsigned lr_op_index; /* DWARF4, operation within VLIW instruction. */ Dwarf_Unsigned lr_discriminator; /* DWARF4 */ Dwarf_Unsigned lr_call_context; /* EXPERIMENTAL */ Dwarf_Unsigned lr_subprogram; /* EXPERIMENTAL */ }; typedef struct Dwarf_Line_Registers_s *Dwarf_Line_Registers; void _dwarf_set_line_table_regs_default_values( Dwarf_Line_Registers regs, unsigned lineversion, Dwarf_Bool is_stmt); /* This structure defines a row of the line table. All of the fields except li_offset have the exact same meaning that is defined in Section 6.2.2 of the Libdwarf Document. li_offset is used by _dwarf_addr_finder() which is called by rqs(1), an sgi utility for 'moving' shared libraries as if the static linker (ld) had linked the shared library at the newly-specified address. Most libdwarf-using apps will ignore li_offset and _dwarf_addr_finder(). */ struct Dwarf_Line_s { Dwarf_Addr li_address; /* pc value of machine instr */ union addr_or_line_s { struct li_inner_s { /* New as of DWARF4 */ Dwarf_Unsigned li_discriminator; /* int identifying src file li_file is a number 1-N, indexing into a conceptual source file table as described in dwarf2/3 spec line table doc. (see Dwarf_File_Entry lc_file_entries; and Dwarf_Unsigned lc_file_entry_count;) */ Dwarf_Unsigned li_file; /* In single-level table is line number in source file. 1-N In logicals table is not used. In actuals table is index into logicals table. 1-N*/ Dwarf_Unsigned li_line; Dwarf_Half li_column; /* source file column number 1-N */ Dwarf_Small li_isa; /* New as of DWARF4. */ /* Two-level line tables. Is index from logicals table into logicals table. 1-N */ Dwarf_Unsigned li_call_context; /* Two-level line tables. is index into subprograms table. 1-N */ Dwarf_Unsigned li_subprogram; /* To save space, use bit flags. */ /* indicate start of stmt */ unsigned li_is_stmt:1; /* indicate start basic block */ unsigned li_basic_block:1; /* first post sequence instr */ unsigned li_end_sequence:1; unsigned li_prologue_end:1; unsigned li_epilogue_begin:1; /* Mark a line record as being DW_LNS_set_address. */ unsigned li_is_addr_set:1; } li_l_data; #ifdef __sgi /* SGI IRIX ONLY */ Dwarf_Off li_offset; /* for SGI IRIX rqs only*/ #endif /* __sgi */ } li_addr_line; Dwarf_Line_Context li_context; /* assoc Dwarf_Line_Context_s */ /* Set only on the actuals table of a two-level line table. Assists in the dealloc code. */ Dwarf_Bool li_is_actuals_table; }; int _dwarf_line_address_offsets(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr ** addrs, Dwarf_Off ** offs, Dwarf_Unsigned * returncount, Dwarf_Error * err); int _dwarf_internal_srclines(Dwarf_Die die, Dwarf_Bool old_interface, Dwarf_Unsigned * version, Dwarf_Small * table_count, Dwarf_Line_Context *line_context, Dwarf_Line ** linebuf, Dwarf_Signed * count, Dwarf_Line ** linebuf_actuals, Dwarf_Signed * count_actuals, Dwarf_Bool doaddrs, Dwarf_Bool dolines, Dwarf_Error * error); /* The LOP, WHAT_IS_OPCODE stuff is here so it can be reused in 3 places. Seemed hard to keep the 3 places the same without an inline func or a macro. Handling the line section where the header and the file being processed do not match (unusual, but planned for in the design of .debug_line) is too tricky to recode this several times and keep it right. As it is the code starting up line-reading is duplicated and that is just wrong to do. FIXME! */ #define LOP_EXTENDED 1 #define LOP_DISCARD 2 #define LOP_STANDARD 3 #define LOP_SPECIAL 4 #define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr,highest_std) \ if ((opcode) < (base)) { \ /* we know we must treat as a standard op \ or a special case. */ \ if ((opcode) == DW_EXTENDED_OPCODE) { \ type = LOP_EXTENDED; \ } else if ((highest_std+1) >= (base)) { \ /* == Standard case: compile of \ dwarf_line.c and object \ have same standard op codes set. \ == Special case: compile of dwarf_line.c \ has things in standard op codes list \ in dwarf.h header not \ in the object: handle this as a standard \ op code in switch below. \ The header special ops overlap the \ object standard ops. \ The new standard op codes will not \ appear in the object. */ \ type = LOP_STANDARD; \ } else { \ /* These are standard opcodes in the object \ ** that were not defined in the header \ ** at the time dwarf_line.c \ ** was compiled. Provides the ability of \ ** out-of-date dwarf reader to read newer \ ** line table data transparently. \ */ \ type = LOP_DISCARD; \ } \ } else { \ /* Is a special op code. */ \ type = LOP_SPECIAL; \ } /* The following is from the dwarf definition of 'ubyte' and is specifically mentioned in section 6.2.5.1, page 54 of the Rev 2.0.0 dwarf specification. */ #define MAX_LINE_OP_CODE 255 /* Operand counts per standard operand. The initial zero is for DW_LNS_copy. This is an economical way to verify we understand the table of standard-opcode-lengths in the line table prologue. */ #define STANDARD_OPERAND_COUNT_DWARF2 9 #define STANDARD_OPERAND_COUNT_DWARF3 12 /* For two-level line tables, we have three additional standard opcodes. */ #define STANDARD_OPERAND_COUNT_TWO_LEVEL 15 void _dwarf_print_header_issue(Dwarf_Debug dbg, const char *specific_msg, Dwarf_Small *data_start, Dwarf_Signed value, unsigned index, unsigned tabv, unsigned linetabv, int *err_count_out); int _dwarf_decode_line_string_form(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Unsigned offset_size, Dwarf_Small **line_ptr, Dwarf_Small *line_ptr_end, char **return_str, Dwarf_Error * error); int _dwarf_decode_line_udata_form(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Small **line_ptr, Dwarf_Unsigned *return_val, Dwarf_Small *line_end_ptr, Dwarf_Error * error); 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); int _dwarf_line_context_constructor(Dwarf_Debug dbg, void *m); void _dwarf_line_context_destructor(void *m); void _dwarf_print_line_context_record(Dwarf_Debug dbg, Dwarf_Line_Context line_context); void _dwarf_context_src_files_destroy(Dwarf_Line_Context context); int _dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe); dwarfutils-20200114/libdwarf/dwarf_line_table_reader_common.h000066400000000000000000002372241361531463500242700ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This is #included twice. Once for libdwarf callers and one for dwarfdump which prints the internals. This way we have just one blob of code that reads the table operations. */ #define TRUE 1 #define FALSE 0 static unsigned char dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_TWO_LEVEL] = { /* DWARF2 */ 0, 1, 1, 1, 1, 0, 0, 0, 1, /* Following are new for DWARF3. */ 0, 0, 1, /* Experimental opcodes. */ 1, 2, 0, }; /* We have a normal standard opcode base, but an arm compiler emitted a non-standard table! This could lead to problems... ARM C/C++ Compiler, RVCT4.0 [Build 4 00] seems to get the table wrong . */ static unsigned char dwarf_arm_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = { /* DWARF2 */ 0, 1, 1, 1, 1, 0, 0, 0, 0, /* <<< --- this is wrong */ /* Following are new for DWARF3. */ 0, 0, 1 }; /* Rather like memcmp but identifies which value pair mismatches (the return value is non-zero if mismatch, zero if match).. mismatch_entry returns the table index that mismatches. tabval returns the table byte value. lineval returns the value from the line table header. */ static int operandmismatch(unsigned char * table,unsigned table_length, unsigned char *linetable, unsigned check_count, unsigned * mismatch_entry, unsigned * tabval,unsigned *lineval) { unsigned i = 0; /* check_count better be <= table_length */ for (i = 0; i table_length) { *mismatch_entry = i; *lineval = linetable[i]; *tabval = 0; /* No entry present. */ /* A kind of mismatch */ return TRUE; } if (table[i] == linetable[i]) { continue; } *mismatch_entry = i; *tabval = table[i]; *lineval = linetable[i]; return TRUE; } /* Matches. */ return FALSE; } /* Encapsulates DECODE_LEB128_UWORD_CK so the caller can free resources in case of problems. */ static int read_uword_de(Dwarf_Small **lp, Dwarf_Unsigned *out_p, Dwarf_Debug dbg, Dwarf_Error *err, Dwarf_Small *lpend) { Dwarf_Small *inptr = *lp; Dwarf_Unsigned out = 0; DECODE_LEB128_UWORD_CK(inptr, out, dbg,err,lpend); *lp = inptr; *out_p = out; return DW_DLV_OK; } /* Common line table header reading code. Returns DW_DLV_OK, DW_DLV_ERROR. DW_DLV_NO_ENTRY cannot be returned, but callers should assume it is possible. The line_context area must be initialized properly before calling this. Has the side effect of allocating arrays which must be freed (see the Line_Table_Context which holds the pointers to space we allocate here). bogus_bytes_ptr and bogus_bytes are output values which let a print-program notify the user of some surprising bytes after a line table header and before the line table instructions. These can be ignored unless one is printing. And are ignored if NULL passed as the pointer. err_count_out may be NULL, in which case we make no attempt to count checking-type errors. Checking-type errors do not stop us, we just report them. See dw-linetableheader.txt for the ordering of text fields across the various dwarf versions. The code follows this ordering closely. Some of the arguments remaining are in line_context so can be deleted from the argument list (after a close look for correctness). */ static int _dwarf_read_line_table_header(Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Small * section_start, Dwarf_Small * data_start, Dwarf_Unsigned section_length, Dwarf_Small ** updated_data_start_out, Dwarf_Line_Context line_context, Dwarf_Small ** bogus_bytes_ptr, Dwarf_Unsigned *bogus_bytes, Dwarf_Error * err, int *err_count_out) { Dwarf_Small *line_ptr = data_start; Dwarf_Small *starting_line_ptr = data_start; Dwarf_Unsigned total_length = 0; int local_length_size = 0; int local_extension_size = 0; Dwarf_Unsigned prologue_length = 0; Dwarf_Half version = 0; Dwarf_Small *section_end = section_start + section_length; Dwarf_Small *line_ptr_end = 0; Dwarf_Small *lp_begin = 0; int res = 0; if (bogus_bytes_ptr) *bogus_bytes_ptr = 0; if (bogus_bytes) *bogus_bytes= 0; line_context->lc_line_ptr_start = starting_line_ptr; /* READ_AREA_LENGTH updates line_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, total_length, Dwarf_Unsigned, line_ptr, local_length_size, local_extension_size, err, section_length,section_end); line_ptr_end = line_ptr + total_length; line_context->lc_line_ptr_end = line_ptr_end; line_context->lc_length_field_length = local_length_size + local_extension_size; line_context->lc_section_offset = starting_line_ptr - dbg->de_debug_line.dss_data; /* ASSERT: line_context->lc_length_field_length == line_ptr -line_context->lc_line_ptr_start; */ if (line_ptr_end > section_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_total_length = total_length; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, line_ptr, DWARF_HALF_SIZE, err,line_ptr_end); line_context->lc_version_number = version; line_ptr += DWARF_HALF_SIZE; if (version != DW_LINE_VERSION2 && version != DW_LINE_VERSION3 && version != DW_LINE_VERSION4 && version != DW_LINE_VERSION5 && version != EXPERIMENTAL_LINE_TABLES_VERSION) { _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR); return (DW_DLV_ERROR); } if (version == DW_LINE_VERSION5) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_address_size = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_segment_selector_size = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); } else { line_context->lc_address_size = cu_context->cc_address_size; line_context->lc_segment_selector_size = cu_context->cc_segment_selector_size; } READ_UNALIGNED_CK(dbg, prologue_length, Dwarf_Unsigned, line_ptr, local_length_size, err,line_ptr_end); line_context->lc_prologue_length = prologue_length; line_ptr += local_length_size; line_context->lc_line_prologue_start = line_ptr; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_minimum_instruction_length = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (version == DW_LINE_VERSION4 || version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_maximum_ops_per_instruction = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); } if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_default_is_stmt = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLV_ERROR); } line_context->lc_line_base = *(signed char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Sbyte); if(line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } line_context->lc_line_range = *(unsigned char *) line_ptr; if (!line_context->lc_line_range) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_RANGE_ZERO); return DW_DLV_ERROR; } line_ptr = line_ptr + sizeof(Dwarf_Small); if(line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } line_context->lc_opcode_base = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); /* Set up the array of standard opcode lengths. */ /* We think this works ok even for cross-endian processing of objects. It might be wrong, we might need to specially process the array of ubyte into host order. */ line_context->lc_opcode_length_table = line_ptr; /* lc_opcode_base is one greater than the size of the array. */ line_ptr += line_context->lc_opcode_base - 1; line_context->lc_std_op_count = line_context->lc_opcode_base -1; if(line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } { /* Determine (as best we can) whether the lc_opcode_length_table holds 9 or 12 standard-conforming entries. gcc4 upped to DWARF3's 12 without updating the version number. EXPERIMENTAL_LINE_TABLES_VERSION upped to 15. */ unsigned check_count = line_context->lc_std_op_count; unsigned tab_count = sizeof(dwarf_standard_opcode_operand_count); int operand_ck_fail = true; if (line_context->lc_std_op_count > tab_count) { _dwarf_print_header_issue(dbg, "Too many standard operands in linetable header: ", data_start, line_context->lc_std_op_count, 0,0,0, err_count_out); check_count = tab_count; } { unsigned entrynum = 0; unsigned tabv = 0; unsigned linetabv = 0; int mismatch = operandmismatch( dwarf_standard_opcode_operand_count, tab_count, line_context->lc_opcode_length_table, check_count,&entrynum,&tabv,&linetabv); if (mismatch) { if (err_count_out) { _dwarf_print_header_issue(dbg, "standard-operands did not match, checked", data_start, check_count, entrynum,tabv,linetabv,err_count_out); } if (check_count > sizeof(dwarf_arm_standard_opcode_operand_count)) { check_count = sizeof(dwarf_arm_standard_opcode_operand_count); } mismatch = operandmismatch( dwarf_arm_standard_opcode_operand_count, sizeof(dwarf_arm_standard_opcode_operand_count), line_context->lc_opcode_length_table, check_count,&entrynum,&tabv,&linetabv); if (!mismatch && err_count_out) { _dwarf_print_header_issue(dbg, "arm (incorrect) operands in use: ", data_start, check_count, entrynum,tabv,linetabv,err_count_out); } } if (!mismatch) { if (version == 2) { if (line_context->lc_std_op_count == STANDARD_OPERAND_COUNT_DWARF3) { _dwarf_print_header_issue(dbg, "standard DWARF3 operands matched," " but is DWARF2 linetable: count", data_start, check_count, 0,0,0, err_count_out); } } operand_ck_fail = false; } } if (operand_ck_fail) { /* Here we are not sure what the lc_std_op_count is. */ _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD); return (DW_DLV_ERROR); } } /* At this point we no longer need to check operand counts. */ if(line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (version < DW_LINE_VERSION5){ Dwarf_Unsigned directories_count = 0; Dwarf_Unsigned directories_malloc = 5; line_context->lc_include_directories = malloc(sizeof(Dwarf_Small *) * directories_malloc); if (line_context->lc_include_directories == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(line_context->lc_include_directories, 0, sizeof(Dwarf_Small *) * directories_malloc); if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } while ((*(char *) line_ptr) != '\0') { if (directories_count >= directories_malloc) { Dwarf_Unsigned expand = 2 * directories_malloc; Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand; Dwarf_Small **newdirs = realloc(line_context->lc_include_directories, bytesalloc); if (!newdirs) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Doubled size, zero out second half. */ memset(newdirs + directories_malloc, 0, sizeof(Dwarf_Small *) * directories_malloc); directories_malloc = expand; line_context->lc_include_directories = newdirs; } line_context->lc_include_directories[directories_count] = line_ptr; res = _dwarf_check_string_valid(dbg, data_start,line_ptr,line_ptr_end, DW_DLE_LINE_STRING_BAD,err); if (res != DW_DLV_OK) { return res; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; directories_count++; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } line_ptr++; line_context->lc_include_directories_count = directories_count; } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* Empty old style dir entry list. */ line_ptr++; } else if (version == 5) { /* handled below */ } else { /* No old style directory entries. */ } if(line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (version < DW_LINE_VERSION5) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } while (*(char *) line_ptr != '\0') { Dwarf_Unsigned utmp; Dwarf_Unsigned dir_index = 0; Dwarf_Unsigned lastmod = 0; Dwarf_Unsigned file_length = 0; int resl = 0; Dwarf_File_Entry currfile = 0; currfile = (Dwarf_File_Entry) malloc(sizeof(struct Dwarf_File_Entry_s)); if (currfile == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(currfile,0,sizeof(struct Dwarf_File_Entry_s)); /* Insert early so in case of error we can find and free the record. */ _dwarf_add_to_files_list(line_context,currfile); currfile->fi_file_name = line_ptr; resl = _dwarf_check_string_valid(dbg, data_start,line_ptr,line_ptr_end, DW_DLE_LINE_STRING_BAD,err); if (resl != DW_DLV_OK) { return resl; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; DECODE_LEB128_UWORD_CK(line_ptr, utmp,dbg,err,line_ptr_end); dir_index = (Dwarf_Unsigned) utmp; if (dir_index > line_context->lc_include_directories_count) { _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD); return (DW_DLV_ERROR); } currfile->fi_dir_index = dir_index; DECODE_LEB128_UWORD_CK(line_ptr,lastmod, dbg,err, line_ptr_end); currfile->fi_time_last_mod = lastmod; /* Skip over file length. */ DECODE_LEB128_UWORD_CK(line_ptr,file_length, dbg,err, line_ptr_end); currfile->fi_file_length = file_length; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } /* Skip trailing nul byte */ ++line_ptr; } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (*line_ptr != 0) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } line_ptr++; } else if (version == 5) { /* handled below */ } else { /* No old style filenames entries. */ } if(line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { static unsigned char expbytes[5] = {0,0xff,0xff,0x7f, 0x7f }; Dwarf_Unsigned logicals_table_offset = 0; Dwarf_Unsigned actuals_table_offset = 0; unsigned i = 0; for ( ; i < 5; ++i) { if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (*line_ptr != expbytes[i]) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } line_ptr++; } READ_UNALIGNED_CK(dbg, logicals_table_offset, Dwarf_Unsigned, line_ptr, local_length_size,err,line_ptr_end); line_context->lc_logicals_table_offset = logicals_table_offset; line_ptr += local_length_size; READ_UNALIGNED_CK(dbg, actuals_table_offset, Dwarf_Unsigned, line_ptr, local_length_size,err,line_ptr_end); line_context->lc_actuals_table_offset = actuals_table_offset; line_ptr += local_length_size; if(line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } } if (version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* DWARF 5. directory names.*/ Dwarf_Unsigned directory_format_count = 0; Dwarf_Unsigned *directory_entry_types = 0; Dwarf_Unsigned *directory_entry_forms = 0; Dwarf_Unsigned directories_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; int dres = 0; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } directory_format_count = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (directory_format_count > 0) { directory_entry_types = malloc(sizeof(Dwarf_Unsigned) * directory_format_count); if (directory_entry_types == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } directory_entry_forms = malloc(sizeof(Dwarf_Unsigned) * directory_format_count); if (directory_entry_forms == NULL) { free(directory_entry_types); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (i = 0; i < directory_format_count; i++) { dres=read_uword_de(&line_ptr,directory_entry_types+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(directory_entry_types); free(directory_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, directory_entry_types[i], dbg,err,line_ptr_end); */ dres=read_uword_de(&line_ptr,directory_entry_forms+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(directory_entry_types); free(directory_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, directory_entry_forms[i], dbg,err,line_ptr_end); */ } } dres = read_uword_de(&line_ptr,&directories_count, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(directory_entry_types); free(directory_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, directories_count, dbg,err,line_ptr_end); */ line_context->lc_include_directories = malloc(sizeof(Dwarf_Small *) * directories_count); if (line_context->lc_include_directories == NULL) { free(directory_entry_types); free(directory_entry_forms); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } if (directory_format_count ==0 && directories_count > 0) { free(directory_entry_types); free(directory_entry_forms); _dwarf_error(dbg, err, DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH); return (DW_DLV_ERROR); } memset(line_context->lc_include_directories, 0, sizeof(Dwarf_Small *) * directories_count); for(i = 0; i < directories_count; i++) { for (j = 0; j < directory_format_count; j++) { switch (directory_entry_types[j]) { case DW_LNCT_path: { char *inc_dir_ptr = 0; res = _dwarf_decode_line_string_form(dbg, directory_entry_forms[j], local_length_size, &line_ptr, line_ptr_end, &inc_dir_ptr, err); if (res != DW_DLV_OK) { free(directory_entry_types); free(directory_entry_forms); return res; } line_context->lc_include_directories[i] = (unsigned char *)inc_dir_ptr; break; } default: free(directory_entry_types); free(directory_entry_forms); _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } if (line_ptr > line_ptr_end) { free(directory_entry_types); free(directory_entry_forms); _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } free(directory_entry_types); free(directory_entry_forms); line_context->lc_include_directories_count = directories_count; } if (version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* DWARF 5. file names.*/ Dwarf_Unsigned filename_format_count = 0; Dwarf_Unsigned *filename_entry_types = 0; Dwarf_Unsigned *filename_entry_forms = 0; Dwarf_Unsigned files_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; int dres = 0; if (line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } filename_format_count = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); filename_entry_types = malloc(sizeof(Dwarf_Unsigned) * filename_format_count); if (filename_entry_types == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } filename_entry_forms = malloc(sizeof(Dwarf_Unsigned) * filename_format_count); if (filename_entry_forms == NULL) { free(filename_entry_types); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (i = 0; i < filename_format_count; i++) { dres=read_uword_de(&line_ptr,filename_entry_types+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_types[i] dbg,err,line_ptr_end); */ dres=read_uword_de(&line_ptr,filename_entry_forms+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_forms[i], dbg,err,line_ptr_end); */ } dres=read_uword_de(&line_ptr,&files_count, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, files_count, dbg,err,line_ptr_end); */ for (i = 0; i < files_count; i++) { Dwarf_File_Entry curline = 0; curline = (Dwarf_File_Entry) malloc(sizeof(struct Dwarf_File_Entry_s)); if (curline == NULL) { free(filename_entry_types); free(filename_entry_forms); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(curline,0,sizeof(*curline)); _dwarf_add_to_files_list(line_context,curline); for(j = 0; j < filename_format_count; j++) { Dwarf_Unsigned dirindex = 0; switch (filename_entry_types[j]) { case DW_LNCT_path: res = _dwarf_decode_line_string_form(dbg, filename_entry_forms[j], local_length_size, &line_ptr, line_ptr_end, (char **)&curline->fi_file_name, err); if (res != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return res; } break; case DW_LNCT_directory_index: res = _dwarf_decode_line_udata_form(dbg, filename_entry_forms[j], &line_ptr, &dirindex, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return res; } curline->fi_dir_index = dirindex; break; case DW_LNCT_timestamp: res = _dwarf_decode_line_udata_form(dbg, filename_entry_forms[j], &line_ptr, &curline->fi_time_last_mod, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return res; } break; case DW_LNCT_size: res = _dwarf_decode_line_udata_form(dbg, filename_entry_forms[j], &line_ptr, &curline->fi_file_length, line_ptr_end, err); if (res != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return res; } break; case DW_LNCT_MD5: { /* form DW_FORM_data16 */ if (filename_entry_forms[j] != DW_FORM_data16) { free(filename_entry_types); free(filename_entry_forms); _dwarf_error(dbg, err,DW_DLE_LNCT_MD5_WRONG_FORM); return DW_DLV_ERROR; } res = _dwarf_extract_data16(dbg, line_ptr, line_ptr, line_ptr_end, &curline->fi_md5_value, err); if (res != DW_DLV_OK) { free(filename_entry_types); free(filename_entry_forms); return res; } curline->fi_md5_present = TRUE; line_ptr = line_ptr + sizeof(curline->fi_md5_value); } break; default: free(filename_entry_types); free(filename_entry_forms); _dwarf_error(dbg, err,DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (line_ptr > line_ptr_end) { free(filename_entry_types); free(filename_entry_forms); _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } } free(filename_entry_types); free(filename_entry_forms); } /* For two-level line tables, read the subprograms table. */ if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { Dwarf_Unsigned subprog_format_count = 0; Dwarf_Unsigned *subprog_entry_types = 0; Dwarf_Unsigned *subprog_entry_forms = 0; Dwarf_Unsigned subprogs_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; int dres = 0; if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } subprog_format_count = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); subprog_entry_types = malloc(sizeof(Dwarf_Unsigned) * subprog_format_count); if (subprog_entry_types == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } subprog_entry_forms = malloc(sizeof(Dwarf_Unsigned) * subprog_format_count); if (subprog_entry_forms == NULL) { free(subprog_entry_types); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (i = 0; i < subprog_format_count; i++) { dres=read_uword_de(&line_ptr,subprog_entry_types+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_types[i], dbg,err,line_ptr_end); */ dres=read_uword_de(&line_ptr,subprog_entry_forms+i, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_forms[i], dbg,err,line_ptr_end); */ } dres=read_uword_de(&line_ptr,&subprogs_count, dbg,err,line_ptr_end); if (dres != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return dres; } /* DECODE_LEB128_UWORD_CK(line_ptr, subprogs_count, dbg,err,line_ptr_end); */ line_context->lc_subprogs = malloc(sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count); if (line_context->lc_subprogs == NULL) { free(subprog_entry_types); free(subprog_entry_forms); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(line_context->lc_subprogs, 0, sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count); for (i = 0; i < subprogs_count; i++) { struct Dwarf_Subprog_Entry_s *curline = line_context->lc_subprogs + i; for (j = 0; j < subprog_format_count; j++) { switch (subprog_entry_types[j]) { case DW_LNCT_GNU_subprogram_name: res = _dwarf_decode_line_string_form(dbg, subprog_entry_forms[j], local_length_size, &line_ptr, line_ptr_end, (char **)&curline->ds_subprog_name, err); if (res != DW_DLV_OK) { free(subprog_entry_types); free(subprog_entry_forms); return res; } break; case DW_LNCT_GNU_decl_file: res = _dwarf_decode_line_udata_form(dbg, subprog_entry_forms[j], &line_ptr, &curline->ds_decl_file, line_ptr_end, err); if (res != DW_DLV_OK) { free(subprog_entry_forms); free(subprog_entry_types); return res; } break; case DW_LNCT_GNU_decl_line: res = _dwarf_decode_line_udata_form(dbg, subprog_entry_forms[j], &line_ptr, &curline->ds_decl_line, line_ptr_end, err); if (res != DW_DLV_OK) { free(subprog_entry_forms); free(subprog_entry_types); return res; } break; default: free(subprog_entry_forms); free(subprog_entry_types); _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (line_ptr >= line_ptr_end) { free(subprog_entry_types); free(subprog_entry_forms); _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } } } free(subprog_entry_types); free(subprog_entry_forms); line_context->lc_subprogs_count = subprogs_count; } if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { lp_begin = line_context->lc_line_prologue_start + line_context->lc_logicals_table_offset; } else { lp_begin = line_context->lc_line_prologue_start + line_context->lc_prologue_length; } if(line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } if (line_ptr != lp_begin) { if (line_ptr > lp_begin) { _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD); return (DW_DLV_ERROR); } else { /* Bug in compiler. These bytes are really part of the instruction stream. The line_context->lc_prologue_length is wrong (12 too high). */ if (bogus_bytes_ptr) { *bogus_bytes_ptr = line_ptr; } if (bogus_bytes) { /* How far off things are. We expect the value 12 ! */ *bogus_bytes = (lp_begin - line_ptr); } } /* Ignore the lp_begin calc. Assume line_ptr right. Making up for compiler bug. */ lp_begin = line_ptr; } line_context->lc_line_ptr_start = lp_begin; if (line_context->lc_actuals_table_offset) { /* This means two tables. */ line_context->lc_table_count = 2; } else { if (line_context->lc_line_ptr_end > lp_begin) { line_context->lc_table_count = 1; } else { line_context->lc_table_count = 0; } } *updated_data_start_out = lp_begin; return DW_DLV_OK; } /* Read one line table program. For two-level line tables, this function is called once for each table. */ static int read_line_table_program(Dwarf_Debug dbg, Dwarf_Small *line_ptr, Dwarf_Small *line_ptr_end, UNUSEDARG Dwarf_Small *orig_line_ptr, Dwarf_Small *section_start, Dwarf_Line_Context line_context, Dwarf_Half address_size, Dwarf_Bool doaddrs, /* Only true if SGI IRIX rqs calling. */ Dwarf_Bool dolines, Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table, Dwarf_Error *error, UNUSEDARG int *err_count_out) { Dwarf_Unsigned i = 0; Dwarf_File_Entry cur_file_entry = 0; Dwarf_Line *logicals = line_context->lc_linebuf_logicals; Dwarf_Unsigned logicals_count = line_context->lc_linecount_logicals; struct Dwarf_Line_Registers_s regs; /* This is a pointer to the current line being added to the line matrix. */ Dwarf_Line curr_line = 0; /* These variables are used to decode leb128 numbers. Leb128_num holds the decoded number, and leb128_length is its length in bytes. */ Dwarf_Unsigned leb128_num = 0; Dwarf_Signed advance_line = 0; /* This is the operand of the latest fixed_advance_pc extended opcode. */ Dwarf_Half fixed_advance_pc = 0; /* Counts the number of lines in the line matrix. */ Dwarf_Unsigned line_count = 0; /* This is the length of an extended opcode instr. */ Dwarf_Unsigned instr_length = 0; /* Used to chain together pointers to line table entries that are later used to create a block of Dwarf_Line entries. */ Dwarf_Chain chain_line = NULL; Dwarf_Chain head_chain = NULL; Dwarf_Chain curr_chain = NULL; /* This points to a block of Dwarf_Lines, a pointer to which is returned in linebuf. */ Dwarf_Line *block_line = 0; /* Mark a line record as being DW_LNS_set_address */ Dwarf_Bool is_addr_set = false; /* Initialize the one state machine variable that depends on the prefix. */ _dwarf_set_line_table_regs_default_values(®s, line_context->lc_version_number, line_context->lc_default_is_stmt); /* Start of statement program. */ while (line_ptr < line_ptr_end) { int type = 0; Dwarf_Small opcode = 0; #ifdef PRINTING_DETAILS dwarf_printf(dbg, " [0x%06" DW_PR_DSx "] ", (Dwarf_Signed) (line_ptr - section_start)); #endif /* PRINTING_DETAILS */ opcode = *(Dwarf_Small *) line_ptr; line_ptr++; /* 'type' is the output */ WHAT_IS_OPCODE(type, opcode, line_context->lc_opcode_base, line_context->lc_opcode_length_table, line_ptr, line_context->lc_std_op_count); if (type == LOP_DISCARD) { int oc = 0; int opcnt = line_context->lc_opcode_length_table[opcode]; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "*** DWARF CHECK: DISCARD standard opcode %d " "with %d operands: " "not understood.", opcode, opcnt); *err_count_out += 1; #endif /* PRINTING_DETAILS */ for (oc = 0; oc < opcnt; oc++) { /* Read and discard operands we don't understand. arbitrary choice of unsigned read. signed read would work as well. */ UNUSEDARG Dwarf_Unsigned utmp2 = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); #ifdef PRINTING_DETAILS dwarf_printf(dbg, " %" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ")", (Dwarf_Unsigned) utmp2, (Dwarf_Unsigned) utmp2); #endif /* PRINTING_DETAILS */ } #ifdef PRINTING_DETAILS dwarf_printf(dbg,"***\n"); #endif /* PRINTING_DETAILS */ } else if (type == LOP_SPECIAL) { /* This op code is a special op in the object, no matter that it might fall into the standard op range in this compile. That is, these are special opcodes between opcode_base and MAX_LINE_OP_CODE. (including opcode_base and MAX_LINE_OP_CODE) */ #ifdef PRINTING_DETAILS char special[50]; unsigned origop = opcode; #endif /* PRINTING_DETAILS */ Dwarf_Unsigned operation_advance = 0; opcode = opcode - line_context->lc_opcode_base; operation_advance = (opcode / line_context->lc_line_range); if (line_context->lc_maximum_ops_per_instruction < 2) { regs.lr_address = regs.lr_address + (operation_advance * line_context->lc_minimum_instruction_length); } else { regs.lr_address = regs.lr_address + (line_context->lc_minimum_instruction_length * ((regs.lr_op_index + operation_advance)/ line_context->lc_maximum_ops_per_instruction)); regs.lr_op_index = (regs.lr_op_index +operation_advance)% line_context->lc_maximum_ops_per_instruction; } regs.lr_line = regs.lr_line + line_context->lc_line_base + opcode % line_context->lc_line_range; if ((Dwarf_Signed)regs.lr_line < 0) { /* Something is badly wrong */ regs.lr_line = 0; _dwarf_error(dbg, error, DW_DLE_LINE_TABLE_LINENO_ERROR); return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS sprintf(special, "Specialop %3u", origop); print_line_detail(dbg,special, opcode,line_count+1, ®s,is_single_table, is_actuals_table); #endif /* PRINTING_DETAILS */ if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (curr_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Mark a line record as being DW_LNS_set_address */ curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set; is_addr_set = false; curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = regs.lr_is_stmt; curr_line->li_addr_line.li_l_data.li_basic_block = regs.lr_basic_block; curr_line->li_addr_line.li_l_data.li_end_sequence = curr_line->li_addr_line.li_l_data. li_epilogue_begin = regs.lr_epilogue_begin; curr_line->li_addr_line.li_l_data.li_prologue_end = regs.lr_prologue_end; curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa; curr_line->li_addr_line.li_l_data.li_discriminator = regs.lr_discriminator; curr_line->li_addr_line.li_l_data.li_call_context = regs.lr_call_context; curr_line->li_addr_line.li_l_data.li_subprogram = regs.lr_subprogram; curr_line->li_context = line_context; curr_line->li_is_actuals_table = is_actuals_table; line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain); } regs.lr_basic_block = false; regs.lr_prologue_end = false; regs.lr_epilogue_begin = false; regs.lr_discriminator = 0; } else if (type == LOP_STANDARD) { switch (opcode) { case DW_LNS_copy:{ #ifdef PRINTING_DETAILS print_line_detail(dbg,"DW_LNS_copy", opcode,line_count+1, ®s,is_single_table, is_actuals_table); #endif /* PRINTING_DETAILS */ if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (curr_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Mark a line record as being DW_LNS_set_address */ curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set; is_addr_set = false; curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = regs.lr_is_stmt; curr_line->li_addr_line.li_l_data. li_basic_block = regs.lr_basic_block; curr_line->li_addr_line.li_l_data. li_end_sequence = regs.lr_end_sequence; curr_line->li_context = line_context; curr_line->li_is_actuals_table = is_actuals_table; curr_line->li_addr_line.li_l_data. li_epilogue_begin = regs.lr_epilogue_begin; curr_line->li_addr_line.li_l_data. li_prologue_end = regs.lr_prologue_end; curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa; curr_line->li_addr_line.li_l_data.li_discriminator = regs.lr_discriminator; curr_line->li_addr_line.li_l_data.li_call_context = regs.lr_call_context; curr_line->li_addr_line.li_l_data.li_subprogram = regs.lr_subprogram; line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain); } regs.lr_basic_block = false; regs.lr_prologue_end = false; regs.lr_epilogue_begin = false; regs.lr_discriminator = 0; } break; case DW_LNS_advance_pc:{ Dwarf_Unsigned utmp2 = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_advance_pc val %" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Signed) utmp2, (Dwarf_Unsigned)utmp2); #endif /* PRINTING_DETAILS */ leb128_num = utmp2; regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * leb128_num; } break; case DW_LNS_advance_line:{ Dwarf_Signed stmp = 0; DECODE_LEB128_SWORD_CK(line_ptr, stmp, dbg,error,line_ptr_end); advance_line = (Dwarf_Signed) stmp; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_advance_line val %" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", (Dwarf_Signed) advance_line, (Dwarf_Signed) advance_line); #endif /* PRINTING_DETAILS */ regs.lr_line = regs.lr_line + advance_line; if ((Dwarf_Signed)regs.lr_line < 0) { /* Something is badly wrong */ regs.lr_line = 0; _dwarf_error(dbg, error, DW_DLE_LINE_TABLE_LINENO_ERROR); return DW_DLV_ERROR; } } break; case DW_LNS_set_file:{ Dwarf_Unsigned utmp2 = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); regs.lr_file = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_file %ld\n", (long) regs.lr_file); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_set_column:{ Dwarf_Unsigned utmp2 = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); regs.lr_column = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_column val %" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", (Dwarf_Signed) regs.lr_column, (Dwarf_Signed) regs.lr_column); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_negate_stmt:{ regs.lr_is_stmt = !regs.lr_is_stmt; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_negate_stmt\n"); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_set_basic_block:{ regs.lr_basic_block = true; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_basic_block\n"); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_const_add_pc:{ opcode = MAX_LINE_OP_CODE - line_context->lc_opcode_base; if (line_context->lc_maximum_ops_per_instruction < 2) { Dwarf_Unsigned operation_advance = (opcode / line_context->lc_line_range); regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * operation_advance; } else { Dwarf_Unsigned operation_advance = (opcode / line_context->lc_line_range); regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * ((regs.lr_op_index + operation_advance)/ line_context->lc_maximum_ops_per_instruction); regs.lr_op_index = (regs.lr_op_index +operation_advance)% line_context->lc_maximum_ops_per_instruction; } #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_const_add_pc new address 0x%" DW_PR_XZEROS DW_PR_DSx "\n", (Dwarf_Signed) regs.lr_address); #endif /* PRINTING_DETAILS */ } break; case DW_LNS_fixed_advance_pc:{ READ_UNALIGNED_CK(dbg, fixed_advance_pc, Dwarf_Half, line_ptr, DWARF_HALF_SIZE,error,line_ptr_end); line_ptr += DWARF_HALF_SIZE; if (line_ptr > line_ptr_end) { dwarfstring g; ptrdiff_t d = 0; d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNS_fixed_advance_pc we are " "off this line table at section " "offset. 0x%x .", d); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } regs.lr_address = regs.lr_address + fixed_advance_pc; regs.lr_op_index = 0; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_fixed_advance_pc val %" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx " new address 0x%" DW_PR_XZEROS DW_PR_DSx "\n", (Dwarf_Signed) fixed_advance_pc, (Dwarf_Signed) fixed_advance_pc, (Dwarf_Signed) regs.lr_address); #endif /* PRINTING_DETAILS */ } break; /* New in DWARF3 */ case DW_LNS_set_prologue_end:{ regs.lr_prologue_end = true; } break; /* New in DWARF3 */ case DW_LNS_set_epilogue_begin:{ regs.lr_epilogue_begin = true; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_prologue_end set true.\n"); #endif /* PRINTING_DETAILS */ } break; /* New in DWARF3 */ case DW_LNS_set_isa:{ Dwarf_Unsigned utmp2 = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); regs.lr_isa = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_isa new value 0x%" DW_PR_XZEROS DW_PR_DUx ".\n", (Dwarf_Unsigned) utmp2); #endif /* PRINTING_DETAILS */ if (regs.lr_isa != utmp2) { /* The value of the isa did not fit in our local so we record it wrong. declare an error. */ _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_LINE_NUM_OPERANDS_BAD); return (DW_DLV_ERROR); } } break; /* Experimental two-level line tables */ /* DW_LNS_set_address_from_logical and DW_LNS_set_subprogram share the same opcode. Disambiguate by checking is_actuals_table. */ case DW_LNS_set_subprogram: if (is_actuals_table) { /* DW_LNS_set_address_from_logical */ Dwarf_Signed stmp = 0; DECODE_LEB128_SWORD_CK(line_ptr, stmp, dbg,error,line_ptr_end); advance_line = (Dwarf_Signed) stmp; regs.lr_line = regs.lr_line + advance_line; if ((Dwarf_Signed)regs.lr_line < 0) { /* Something is badly wrong */ regs.lr_line = 0; _dwarf_error(dbg, error, DW_DLE_LINE_TABLE_LINENO_ERROR); return DW_DLV_ERROR; } if (regs.lr_line >= 1 && regs.lr_line - 1 < logicals_count) { regs.lr_address = logicals[regs.lr_line - 1]->li_address; regs.lr_op_index = 0; #ifdef PRINTING_DETAILS dwarf_printf(dbg,"DW_LNS_set_address_from_logical " "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx, stmp,stmp); dwarf_printf(dbg," newaddr=" " 0x%" DW_PR_XZEROS DW_PR_DUx ".\n", regs.lr_address); #endif /* PRINTING_DETAILS */ } else { #ifdef PRINTING_DETAILS dwarf_printf(dbg,"DW_LNS_set_address_from_logical line is " "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx ".\n", (Dwarf_Signed)regs.lr_line, (Dwarf_Signed)regs.lr_line); #endif /* PRINTING_DETAILS */ } } else { /* DW_LNS_set_subprogram, building logicals table. */ Dwarf_Unsigned utmp2 = 0; regs.lr_call_context = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); regs.lr_subprogram = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg,"DW_LNS_set_subprogram " "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", (Dwarf_Signed)utmp2,(Dwarf_Signed)utmp2); #endif /* PRINTING_DETAILS */ } break; /* Experimental two-level line tables */ case DW_LNS_inlined_call: { Dwarf_Signed stmp = 0; DECODE_LEB128_SWORD_CK(line_ptr, stmp, dbg,error,line_ptr_end); regs.lr_call_context = line_count + stmp; DECODE_LEB128_UWORD_CK(line_ptr, regs.lr_subprogram, dbg,error,line_ptr_end); #ifdef PRINTING_DETAILS dwarf_printf(dbg,"DW_LNS_inlined_call " "%" DW_PR_DSd " (0x%" DW_PR_XZEROS DW_PR_DSx ")," "%" DW_PR_DSd " (0x%" DW_PR_XZEROS DW_PR_DSx ")", stmp,stmp, (Dwarf_Signed)regs.lr_subprogram, (Dwarf_Signed)regs.lr_subprogram); dwarf_printf(dbg," callcontext=" "%" DW_PR_DSd " (0x%" DW_PR_XZEROS DW_PR_DSx ")\n", (Dwarf_Signed)regs.lr_call_context, (Dwarf_Signed)regs.lr_call_context); #endif /* PRINTING_DETAILS */ } break; /* Experimental two-level line tables */ case DW_LNS_pop_context: { Dwarf_Unsigned logical_num = regs.lr_call_context; Dwarf_Chain logical_chain = head_chain; Dwarf_Line logical_line = 0; if (logical_num > 0 && logical_num <= line_count) { for (i = 1; i < logical_num; i++) { logical_chain = logical_chain->ch_next; } logical_line = (Dwarf_Line) logical_chain->ch_item; regs.lr_file = logical_line->li_addr_line.li_l_data.li_file; regs.lr_line = logical_line->li_addr_line.li_l_data.li_line; regs.lr_column = logical_line->li_addr_line.li_l_data.li_column; regs.lr_discriminator = logical_line->li_addr_line.li_l_data.li_discriminator; regs.lr_is_stmt = logical_line->li_addr_line.li_l_data.li_is_stmt; regs.lr_call_context = logical_line->li_addr_line.li_l_data.li_call_context; regs.lr_subprogram = logical_line->li_addr_line.li_l_data.li_subprogram; #ifdef PRINTING_DETAILS dwarf_printf(dbg,"DW_LNS_pop_context set from logical " "%" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", logical_num,logical_num); } else { dwarf_printf(dbg,"DW_LNS_pop_context does nothing, logical" "%" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n", logical_num,logical_num); #endif /* PRINTING_DETAILS */ } } break; } /* End switch (opcode) */ } else if (type == LOP_EXTENDED) { Dwarf_Unsigned utmp3 = 0; Dwarf_Small ext_opcode = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp3, dbg,error,line_ptr_end); instr_length = utmp3; /* Dwarf_Small is a ubyte and the extended opcode is a ubyte, though not stated as clearly in the 2.0.0 spec as one might hope. */ if (line_ptr >= line_ptr_end) { dwarfstring g; ptrdiff_t d = 0; d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "extended op we are " "off this line table at section " "offset 0x%x .", d); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } ext_opcode = *(Dwarf_Small *) line_ptr; line_ptr++; if (line_ptr > line_ptr_end) { dwarfstring g; ptrdiff_t d = 0; d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "extended op opcode we are " "off this line table at section " "offset 0x%x .", d); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } switch (ext_opcode) { case DW_LNE_end_sequence:{ regs.lr_end_sequence = true; if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (curr_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain, line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } #ifdef PRINTING_DETAILS print_line_detail(dbg, "DW_LNE_end_sequence extended", ext_opcode, line_count+1,®s, is_single_table, is_actuals_table); #endif /* PRINTING_DETAILS */ curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = regs.lr_is_stmt; curr_line->li_addr_line.li_l_data. li_basic_block = regs.lr_basic_block; curr_line->li_addr_line.li_l_data. li_end_sequence = regs.lr_end_sequence; curr_line->li_context = line_context; curr_line->li_is_actuals_table = is_actuals_table; curr_line->li_addr_line.li_l_data. li_epilogue_begin = regs.lr_epilogue_begin; curr_line->li_addr_line.li_l_data. li_prologue_end = regs.lr_prologue_end; curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa; curr_line->li_addr_line.li_l_data.li_discriminator = regs.lr_discriminator; curr_line->li_addr_line.li_l_data.li_call_context = regs.lr_call_context; curr_line->li_addr_line.li_l_data.li_subprogram = regs.lr_subprogram; line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain); } _dwarf_set_line_table_regs_default_values(®s, line_context->lc_version_number, line_context->lc_default_is_stmt); } break; case DW_LNE_set_address:{ READ_UNALIGNED_CK(dbg, regs.lr_address, Dwarf_Addr, line_ptr, address_size,error,line_ptr_end); /* Mark a line record as being DW_LNS_set_address */ is_addr_set = true; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNE_set_address address 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned) regs.lr_address); #endif /* PRINTING_DETAILS */ if (doaddrs) { /* SGI IRIX rqs processing only. */ curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); if (curr_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Mark a line record as being DW_LNS_set_address */ curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set; is_addr_set = false; curr_line->li_address = regs.lr_address; #ifdef __sgi /* SGI IRIX ONLY */ curr_line->li_addr_line.li_offset = line_ptr - dbg->de_debug_line.dss_data; #endif /* __sgi */ line_count++; chain_line = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); if (chain_line == NULL) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } chain_line->ch_item = curr_line; _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain); } regs.lr_op_index = 0; line_ptr += address_size; if (line_ptr > line_ptr_end) { dwarfstring g; ptrdiff_t d = 0; d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNE_set_address we are " "off this line table at section " "offset 0x%x .", d); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } } break; case DW_LNE_define_file: if (dolines) { int res = 0; Dwarf_Unsigned value = 0; cur_file_entry = (Dwarf_File_Entry) malloc(sizeof(struct Dwarf_File_Entry_s)); if (cur_file_entry == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(cur_file_entry,0,sizeof(struct Dwarf_File_Entry_s)); _dwarf_add_to_files_list(line_context,cur_file_entry); cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr; res = _dwarf_check_string_valid(dbg, line_ptr,line_ptr,line_ptr_end, DW_DLE_DEFINE_FILE_STRING_BAD,error); if (res != DW_DLV_OK) { _dwarf_free_chain_entries(dbg,head_chain,line_count); return res; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; DECODE_LEB128_UWORD_CK(line_ptr,value, dbg,error,line_ptr_end); cur_file_entry->fi_dir_index = (Dwarf_Signed)value; DECODE_LEB128_UWORD_CK(line_ptr,value, dbg,error,line_ptr_end); cur_file_entry->fi_time_last_mod = value; DECODE_LEB128_UWORD_CK(line_ptr,value, dbg,error,line_ptr_end); cur_file_entry->fi_file_length = value; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNE_define_file %s \n", cur_file_entry->fi_file_name); dwarf_printf(dbg, " dir index %d\n", (int) cur_file_entry->fi_dir_index); { time_t tt3 = (time_t) cur_file_entry->fi_time_last_mod; /* ctime supplies newline */ dwarf_printf(dbg, " last time 0x%x %s", (unsigned)tt3, ctime(&tt3)); } dwarf_printf(dbg, " file length %ld 0x%lx\n", (long) cur_file_entry->fi_file_length, (unsigned long) cur_file_entry->fi_file_length); #endif /* PRINTING_DETAILS */ } break; case DW_LNE_set_discriminator:{ /* New in DWARF4 */ Dwarf_Unsigned utmp2 = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); regs.lr_discriminator = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNE_set_discriminator 0x%" DW_PR_XZEROS DW_PR_DUx "\n",utmp2); #endif /* PRINTING_DETAILS */ } break; default:{ /* This is an extended op code we do not know about, other than we know now many bytes it is and the op code and the bytes of operand. */ Dwarf_Unsigned remaining_bytes = instr_length -1; if (instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) { dwarfstring g; ptrdiff_t d = 0; _dwarf_free_chain_entries(dbg,head_chain, line_count); d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "unknown DW_LNE_extended op opcode 0x%x ", ext_opcode); dwarfstring_append_printf_u(&g, "we are " "off this line table at section " "offset 0x%x and ", d); dwarfstring_append_printf_u(&g,"instruction length" "%u.",instr_length); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNE extended op 0x%x ",ext_opcode); dwarf_printf(dbg, "Bytecount: %" DW_PR_DUu , (Dwarf_Unsigned)instr_length); if (remaining_bytes > 0) { dwarf_printf(dbg, " linedata: 0x"); while (remaining_bytes > 0) { dwarf_printf(dbg, "%02x",(unsigned char)(*(line_ptr))); line_ptr++; if (line_ptr > line_ptr_end) { dwarfstring g; ptrdiff_t d = 0; d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNE extended op remaining bytes " "we are " "off this line table at section " "offset 0x%x .", d); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } remaining_bytes--; } } #else /* ! PRINTING_DETAILS */ line_ptr += remaining_bytes; if (line_ptr > line_ptr_end) { dwarfstring g; ptrdiff_t d = 0; d = line_ptr - section_start; dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g, "DW_DLE_LINE_TABLE_BAD reading " "DW_LNE extended op remaining bytes " "we are " "off this line table at section " "offset 0x%x .", d); _dwarf_error_string(dbg, error, DW_DLE_LINE_TABLE_BAD, dwarfstring_string(&g)); dwarfstring_destructor(&g); return DW_DLV_ERROR; } #endif /* PRINTING_DETAILS */ dwarf_printf(dbg,"\n"); } break; } /* End switch. */ } } block_line = (Dwarf_Line *) _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count); if (block_line == NULL) { curr_chain = head_chain; /* FIXME: chain cleanup should be a function and called at more places in this function. */ _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_chain = head_chain; for (i = 0; i < line_count; i++) { Dwarf_Chain t = 0; *(block_line + i) = curr_chain->ch_item; t = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, t, DW_DLA_CHAIN); } if (is_single_table || !is_actuals_table) { line_context->lc_linebuf_logicals = block_line; line_context->lc_linecount_logicals = line_count; } else { line_context->lc_linebuf_actuals = block_line; line_context->lc_linecount_actuals = line_count; } #ifdef PRINTING_DETAILS if (is_single_table) { if(!line_count) { dwarf_printf(dbg," Line table is present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no lines present\n", line_context->lc_section_offset); } } else if (is_actuals_table) { if(!line_count) { dwarf_printf(dbg," Line table present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no actuals lines present\n", line_context->lc_section_offset); } } else { if(!line_count) { dwarf_printf(dbg," Line table present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no logicals lines present\n", line_context->lc_section_offset); } } #endif /* PRINTING_DETAILS */ return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_loc.c000066400000000000000000001477211361531463500200520ustar00rootroot00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 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 and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include /* for debugging only. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_loc.h" #define TRUE 1 #define FALSE 0 /* Richard Henderson, on DW_OP_GNU_encoded_addr: The operand is an absolute address. The first byte of the value is an encoding length: 0 2 4 or 8. If zero it means the following is address-size. The address then follows immediately for that number of bytes. */ static int read_encoded_addr(Dwarf_Small *loc_ptr, Dwarf_Debug dbg, Dwarf_Small *section_end_ptr, Dwarf_Unsigned * val_out, int * len_out, Dwarf_Error *error) { int len = 0; Dwarf_Small op = *loc_ptr; Dwarf_Unsigned operand = 0; len++; if (op == 0) { /* FIXME: should be CU specific. */ op = dbg->de_pointer_size; } switch (op) { case 1: *val_out = *loc_ptr; len++; break; case 2: READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 2, error,section_end_ptr); *val_out = operand; len +=2; break; case 4: READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 4, error,section_end_ptr); *val_out = operand; len +=4; break; case 8: READ_UNALIGNED_CK(dbg, operand, Dwarf_Unsigned, loc_ptr, 8, error,section_end_ptr); *val_out = operand; len +=8; break; default: /* We do not know how much to read. */ _dwarf_error(dbg, error, DW_DLE_GNU_OPCODE_ERROR); return DW_DLV_ERROR; }; *len_out = len; return DW_DLV_OK; } /* Return DW_DLV_NO_ENTRY when at the end of the ops for this block (a single Dwarf_Loccesc and multiple Dwarf_Locs will eventually result from calling this till DW_DLV_NO_ENTRY). All op reader code should call this to extract operator fields. For any DWARF version. */ static int _dwarf_read_loc_expr_op(Dwarf_Debug dbg, Dwarf_Block_c * loc_block, /* Caller: Start numbering at 0. */ Dwarf_Signed opnumber, /* 2 for DWARF 2 etc. */ Dwarf_Half version_stamp, Dwarf_Half offset_size, /* 4 or 8 */ Dwarf_Half address_size, /* 2,4, 8 */ Dwarf_Signed startoffset_in, /* offset in block, not section offset */ Dwarf_Small *section_end, /* nextoffset_out so caller knows next entry startoffset */ Dwarf_Unsigned *nextoffset_out, /* The values picked up. */ Dwarf_Loc_c curr_loc, Dwarf_Error * error) { Dwarf_Small *loc_ptr = 0; Dwarf_Unsigned loc_len = 0; Dwarf_Unsigned offset = startoffset_in; Dwarf_Unsigned operand1 = 0; Dwarf_Unsigned operand2 = 0; Dwarf_Unsigned operand3 = 0; Dwarf_Small atom = 0; Dwarf_Unsigned leb128_length = 0; if (offset > loc_block->bl_len) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } loc_len = loc_block->bl_len; if (offset == loc_len) { return DW_DLV_NO_ENTRY; } loc_ptr = (Dwarf_Small*)loc_block->bl_data + offset; if ((loc_ptr+1) > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } memset(curr_loc,0,sizeof(*curr_loc)); curr_loc->lr_opnumber = opnumber; curr_loc->lr_offset = offset; /* loc_ptr is ok to deref, see loc_ptr+1 test just above. */ atom = *(Dwarf_Small *) loc_ptr; loc_ptr++; offset++; curr_loc->lr_atom = atom; switch (atom) { case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: break; case DW_OP_regx: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: operand1 = atom - DW_OP_lit0; break; case DW_OP_addr: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, address_size, error,section_end); loc_ptr += address_size; offset += address_size; break; case DW_OP_const1u: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_const1s: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Sbyte *) loc_ptr; SIGN_EXTEND(operand1,1); loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_const2u: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error,section_end); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_const2s: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error, section_end); SIGN_EXTEND(operand1,2); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_const4u: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error, section_end); loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_const4s: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error, section_end); SIGN_EXTEND(operand1,4); loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_const8u: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8, error, section_end); loc_ptr = loc_ptr + 8; offset = offset + 8; break; case DW_OP_const8s: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8, error, section_end); loc_ptr = loc_ptr + 8; offset = offset + 8; break; case DW_OP_constu: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_consts: DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_fbreg: DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_bregx: /* uleb reg num followed by sleb offset */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_dup: case DW_OP_drop: break; case DW_OP_pick: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_over: case DW_OP_swap: case DW_OP_rot: case DW_OP_deref: break; case DW_OP_deref_size: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_xderef: break; case DW_OP_xderef_type: /* DWARF5 */ if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_xderef_size: if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; break; case DW_OP_abs: case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_neg: case DW_OP_not: case DW_OP_or: case DW_OP_plus: break; case DW_OP_plus_uconst: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: break; case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: break; case DW_OP_skip: case DW_OP_bra: READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error,section_end); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_piece: DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_nop: break; case DW_OP_push_object_address: /* DWARF3 */ break; case DW_OP_call2: /* DWARF3 */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2, error,section_end); loc_ptr = loc_ptr + 2; offset = offset + 2; break; case DW_OP_call4: /* DWARF3 */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error,section_end); loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_call_ref: /* DWARF3 */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, offset_size, error,section_end); loc_ptr = loc_ptr + offset_size; offset = offset + offset_size; break; case DW_OP_form_tls_address: /* DWARF3f */ break; case DW_OP_call_frame_cfa: /* DWARF3f */ break; case DW_OP_bit_piece: /* DWARF3f */ /* uleb size in bits followed by uleb offset in bits */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; /* The operator means: push the currently computed (by the operations encountered so far in this expression) onto the expression stack as the offset in thread-local-storage of the variable. */ case DW_OP_GNU_push_tls_address: /* 0xe0 */ /* Believed to have no operands. */ /* Unimplemented in gdb 7.5.1 ? */ break; case DW_OP_deref_type: /* DWARF5 */ case DW_OP_GNU_deref_type: /* 0xf6 */ if (loc_ptr >= section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + 1; /* die offset (uleb128). */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_implicit_value: /* DWARF4 0xa0 */ /* uleb length of value bytes followed by that number of bytes of the value. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* Second operand is block of 'operand1' bytes of stuff. */ /* This using the second operand as a pointer is quite ugly. */ /* This gets an ugly compiler warning. Sorry. */ operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; offset = offset + operand1; loc_ptr = loc_ptr + operand1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } break; case DW_OP_stack_value: /* DWARF4 */ break; case DW_OP_GNU_uninit: /* 0xf0 */ /* Unimplemented in gdb 7.5.1 */ /* Carolyn Tice: Follws a DW_OP_reg or DW_OP_regx and marks the reg as being uninitialized. */ break; case DW_OP_GNU_encoded_addr: { /* 0xf1 */ /* Richard Henderson: The operand is an absolute address. The first byte of the value is an encoding length: 0 2 4 or 8. If zero it means the following is address-size. The address then follows immediately for that number of bytes. */ int length = 0; int reares = read_encoded_addr(loc_ptr,dbg, section_end, &operand1, &length,error); if (reares != DW_DLV_OK) { return reares; } loc_ptr += length; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset += length; } break; case DW_OP_implicit_pointer: /* DWARF5 */ case DW_OP_GNU_implicit_pointer:{ /* 0xf2 */ /* Jakub Jelinek: The value is an optimized-out pointer value. Represented as an offset_size DIE offset (a simple unsigned integer) in DWARF3,4 followed by a signed leb128 offset. For DWARF2, it is actually pointer size (address size). http://www.dwarfstd.org/ShowIssue.php?issue=100831.1 */ Dwarf_Small iplen = offset_size; if (version_stamp == DW_CU_VERSION2 /* 2 */ ) { iplen = address_size; } READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, iplen,error,section_end); loc_ptr = loc_ptr + iplen; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + iplen; DECODE_LEB128_SWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; } break; case DW_OP_entry_value: /* DWARF5 */ case DW_OP_GNU_entry_value: /* 0xf3 */ /* Jakub Jelinek: A register reused really soon, but the value is unchanged. So to represent that value we have a uleb128 size followed by a DWARF expression block that size. http://www.dwarfstd.org/ShowIssue.php?issue=100909.1 */ /* uleb length of value bytes followed by that number of bytes of the value. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* Second operand is block of 'operand1' bytes of stuff. */ /* This using the second operand as a pointer is quite ugly. */ /* This gets an ugly compiler warning. Sorry. */ operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; offset = offset + operand1; loc_ptr = loc_ptr + operand1; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } break; case DW_OP_const_type: /* DWARF5 */ case DW_OP_GNU_const_type: /* 0xf4 */ { /* die offset as uleb. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* Next byte is size of following data block. */ operand2 = *loc_ptr; loc_ptr = loc_ptr + 1; offset = offset + 1; /* Operand 3 points to a value in the block of size just gotten as operand2. */ /* This gets an ugly compiler warning. Sorry. */ operand3 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; loc_ptr = loc_ptr + operand2; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } offset = offset + operand2; } break; case DW_OP_regval_type: /* DWARF5 */ case DW_OP_GNU_regval_type: /* 0xf5 */ /* reg num uleb*/ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; /* cu die off uleb*/ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand2,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_convert: /* DWARF5 */ case DW_OP_GNU_convert: /* 0xf7 */ case DW_OP_reinterpret: /* DWARF5 */ case DW_OP_GNU_reinterpret: /* 0xf9 */ /* die offset or zero */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_GNU_parameter_ref : /* 0xfa */ /* 4 byte unsigned int */ READ_UNALIGNED_CK(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4, error,section_end);; loc_ptr = loc_ptr + 4; offset = offset + 4; break; case DW_OP_addrx : /* DWARF5 */ case DW_OP_GNU_addr_index : /* 0xfb DebugFission */ /* Index into .debug_addr. The value in .debug_addr is an address. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; case DW_OP_constx : /* DWARF5 */ case DW_OP_GNU_const_index : /* 0xfc DebugFission */ /* Index into .debug_addr. The value in .debug_addr is a constant that fits in an address. */ DECODE_LEB128_UWORD_LEN_CK(loc_ptr, operand1,leb128_length, dbg,error,section_end); offset = offset + leb128_length; break; default: _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); return DW_DLV_ERROR; } if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; } /* If offset == loc_len this would be normal end-of-expression. */ if (offset > loc_len) { /* We stepped past the end of the expression. This has to be a compiler bug. Operators missing their values cannot be detected as such except at the end of an expression (like this). The results would be wrong if returned. */ _dwarf_error(dbg, error, DW_DLE_LOC_BAD_TERMINATION); return DW_DLV_ERROR; } curr_loc->lr_atom = atom; curr_loc->lr_number = operand1; curr_loc->lr_number2 = operand2; curr_loc->lr_number3 = operand3; *nextoffset_out = offset; return DW_DLV_OK; } /* Given a Dwarf_Block that represents a location expression, this function returns a pointer to a Dwarf_Locdesc struct that has its ld_cents field set to the number of location operators in the block, and its ld_s field pointing to a contiguous block of Dwarf_Loc structs. However, the ld_lopc and ld_hipc values are uninitialized. Returns DW_DLV_ERROR on error. This function assumes that the length of the block is greater than 0. Zero length location expressions to represent variables that have been optimized away are handled in the calling function. address_size, offset_size, and version_stamp are per-CU, not per-object or per dbg. We cannot use dbg directly to get those values. Use for DWARF 2,3,4. Not for DWARF5. */ static int _dwarf_get_locdesc(Dwarf_Debug dbg, Dwarf_Block_c * loc_block, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small version_stamp, Dwarf_Addr lowpc, Dwarf_Addr highpc, Dwarf_Small * section_end, Dwarf_Locdesc ** locdesc_out, Dwarf_Error * error) { /* Offset of current operator from start of block. */ Dwarf_Unsigned offset = 0; /* Used to chain the Dwarf_Loc_Chain_s structs. */ Dwarf_Loc_Chain new_loc = NULL; Dwarf_Loc_Chain prev_loc = NULL; Dwarf_Loc_Chain head_loc = NULL; /* Count of the number of location operators. */ Dwarf_Unsigned op_count = 0; /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */ Dwarf_Loc *block_loc = 0; /* Dwarf_Locdesc pointer to be returned. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Unsigned i = 0; int res = 0; /* ***** BEGIN CODE ***** */ offset = 0; op_count = 0; res = _dwarf_loc_block_sanity_check(dbg,loc_block,error); if (res != DW_DLV_OK) { return res; } /* OLD loop getting Loc operators. No DWARF5 */ while (offset <= loc_block->bl_len) { Dwarf_Unsigned nextoffset = 0; struct Dwarf_Loc_c_s temp_loc; res = _dwarf_read_loc_expr_op(dbg,loc_block, op_count, version_stamp, offset_size, address_size, offset, section_end, &nextoffset, &temp_loc, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { /* Normal end. */ break; } op_count++; new_loc = (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1); if (new_loc == NULL) { /* Some memory may leak here. */ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Copying only the fields needed by DWARF 2,3,4 */ new_loc->lc_atom = temp_loc.lr_atom; new_loc->lc_opnumber= temp_loc.lr_opnumber; new_loc->lc_number = temp_loc.lr_number; new_loc->lc_number2 = temp_loc.lr_number2; new_loc->lc_offset = temp_loc.lr_offset; offset = nextoffset; if (head_loc == NULL) head_loc = prev_loc = new_loc; else { prev_loc->lc_next = new_loc; prev_loc = new_loc; } } block_loc = (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count); if (block_loc == NULL) { /* Some memory does leak here. */ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_loc = head_loc; for (i = 0; i < op_count; i++) { /* Copying only the fields needed by DWARF 2,3,4 */ (block_loc + i)->lr_atom = new_loc->lc_atom; (block_loc + i)->lr_number = new_loc->lc_number; (block_loc + i)->lr_number2 = new_loc->lc_number2; (block_loc + i)->lr_offset = new_loc->lc_offset; prev_loc = new_loc; new_loc = prev_loc->lc_next; dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); } locdesc = (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1); if (locdesc == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } locdesc->ld_cents = op_count; locdesc->ld_s = block_loc; locdesc->ld_from_loclist = loc_block->bl_from_loclist; locdesc->ld_section_offset = loc_block->bl_section_offset; locdesc->ld_lopc = lowpc; locdesc->ld_hipc = highpc; *locdesc_out = locdesc; return DW_DLV_OK; } /* Using a loclist offset to get the in-memory address of .debug_loc data to read, returns the loclist 'header' info in return_block. */ #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) static int _dwarf_read_loc_section(Dwarf_Debug dbg, Dwarf_Block_c * return_block, Dwarf_Addr * lowpc, Dwarf_Addr * hipc, Dwarf_Off sec_offset, Dwarf_Half address_size, Dwarf_Error * error) { Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset; Dwarf_Small *loc_section_end = dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size; /* start_addr and end_addr are actually offsets of the applicable base address of the CU. They are address-size. */ Dwarf_Addr start_addr = 0; Dwarf_Addr end_addr = 0; Dwarf_Half exprblock_size = 0; Dwarf_Unsigned exprblock_off = 2 * address_size + DWARF_HALF_SIZE; if (sec_offset >= dbg->de_debug_loc.dss_size) { /* We're at the end. No more present. */ return DW_DLV_NO_ENTRY; } /* If it goes past end, error */ if (exprblock_off > dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, start_addr, Dwarf_Addr, beg, address_size, error,loc_section_end); READ_UNALIGNED_CK(dbg, end_addr, Dwarf_Addr, beg + address_size, address_size, error,loc_section_end); if (start_addr == 0 && end_addr == 0) { /* If start_addr and end_addr are 0, it's the end and no exprblock_size field follows. */ exprblock_size = 0; exprblock_off -= DWARF_HALF_SIZE; } else if (start_addr == MAX_ADDR) { /* End address is a base address, no exprblock_size field here either */ exprblock_size = 0; exprblock_off -= DWARF_HALF_SIZE; } else { READ_UNALIGNED_CK(dbg, exprblock_size, Dwarf_Half, beg + 2 * address_size, DWARF_HALF_SIZE, error,loc_section_end); /* exprblock_size can be zero, means no expression */ if ( exprblock_size >= dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } if ((sec_offset +exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } } *lowpc = start_addr; *hipc = end_addr; return_block->bl_len = exprblock_size; return_block->bl_from_loclist = 1; return_block->bl_data = beg + exprblock_off; return_block->bl_section_offset = ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc.dss_data; return DW_DLV_OK; } static int _dwarf_get_loclist_count(Dwarf_Debug dbg, Dwarf_Off loclist_offset, Dwarf_Half address_size, int *loclist_count, Dwarf_Error * error) { int count = 0; Dwarf_Off offset = loclist_offset; for (;;) { Dwarf_Block_c b; Dwarf_Addr lowpc; Dwarf_Addr highpc; int res = _dwarf_read_loc_section(dbg, &b, &lowpc, &highpc, offset, address_size,error); if (res != DW_DLV_OK) { return res; } offset = b.bl_len + b.bl_section_offset; if (lowpc == 0 && highpc == 0) { break; } count++; } *loclist_count = count; return DW_DLV_OK; } /* Helper routine to avoid code duplication. */ static int _dwarf_setup_loc(Dwarf_Attribute attr, Dwarf_Debug * dbg_ret, Dwarf_CU_Context *cucontext_ret, Dwarf_Half *form_ret, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Half form = 0; int blkres = DW_DLV_ERROR; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); return (DW_DLV_ERROR); } if (attr->ar_cu_context == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return (DW_DLV_ERROR); } *cucontext_ret = attr->ar_cu_context; dbg = attr->ar_cu_context->cc_dbg; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } *dbg_ret = dbg; blkres = dwarf_whatform(attr, &form, error); if (blkres != DW_DLV_OK) { _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); return blkres; } *form_ret = form; return DW_DLV_OK; } /* Helper routine to avoid code duplication. */ static int _dwarf_get_loclist_header_start(Dwarf_Debug dbg, Dwarf_Attribute attr, Dwarf_Unsigned * loclist_offset_out, Dwarf_Error * error) { Dwarf_Unsigned loc_sec_size = 0; Dwarf_Unsigned loclist_offset = 0; int blkres = dwarf_global_formref(attr, &loclist_offset, error); if (blkres != DW_DLV_OK) { return (blkres); } if (!dbg->de_debug_loc.dss_data) { int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error); if (secload != DW_DLV_OK) { return secload; } if (!dbg->de_debug_loc.dss_size) { return (DW_DLV_NO_ENTRY); } } loc_sec_size = dbg->de_debug_loc.dss_size; if (loclist_offset >= loc_sec_size) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); return DW_DLV_ERROR; } { int fisres = 0; Dwarf_Unsigned fissoff = 0; Dwarf_Unsigned size = 0; fisres = _dwarf_get_fission_addition_die(attr->ar_die, DW_SECT_LOCLISTS, &fissoff, &size,error); if(fisres != DW_DLV_OK) { return fisres; } if (fissoff >= loc_sec_size) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); return DW_DLV_ERROR; } loclist_offset += fissoff; if (loclist_offset >= loc_sec_size) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); return DW_DLV_ERROR; } } *loclist_offset_out = loclist_offset; return DW_DLV_OK; } /* When llbuf (see dwarf_loclist_n) is partially set up and an error is encountered, tear it down as it won't be used. */ static void _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count) { int i; for (i = 0; i < count; ++i) { dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); } static int context_is_cu_not_tu(Dwarf_CU_Context context, Dwarf_Bool *r) { int ut = context->cc_unit_type; if (ut == DW_UT_type || ut == DW_UT_split_type ) { *r =FALSE; return DW_DLV_OK; } *r = TRUE; return DW_DLV_OK; } /* Handles simple location entries and loclists. Returns all the Locdesc's thru llbuf. Will not work properly for DWARF5 and may not work for some recent versions of gcc or llvm emitting DWARF4 with location extensions. Does not work for .debug_loc.dwo */ int dwarf_loclist_n(Dwarf_Attribute attr, Dwarf_Locdesc *** llbuf_out, Dwarf_Signed * listlen_out, Dwarf_Error * error) { Dwarf_Debug dbg = 0; /* Dwarf_Attribute that describes the DW_AT_location in die, if present. */ Dwarf_Attribute loc_attr = attr; /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; /* A pointer to the current Dwarf_Locdesc read. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Half form = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Signed listlen = 0; Dwarf_Locdesc **llbuf = 0; Dwarf_CU_Context cucontext = 0; unsigned address_size = 0; int cuvstamp = 0; Dwarf_Bool is_cu = FALSE; int blkres = DW_DLV_ERROR; int setup_res = DW_DLV_ERROR; Dwarf_Small * info_section_end = 0; /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error); if (setup_res != DW_DLV_OK) { return setup_res; } info_section_end = _dwarf_calculate_info_section_end_ptr(cucontext); cuvstamp = cucontext->cc_version_stamp; address_size = cucontext->cc_address_size; /* If this is a form_block then it's a location expression. If it's DW_FORM_data4 or DW_FORM_data8 in DWARF2 or DWARF3 (or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */ if (cuvstamp == DW_CU_VERSION5) { /* Use a newer interface. */ _dwarf_error(dbg, error, DW_DLE_LOCLIST_INTERFACE_ERROR); return (DW_DLV_ERROR); } if (((cuvstamp == DW_CU_VERSION2 || cuvstamp == DW_CU_VERSION3) && (form == DW_FORM_data4 || form == DW_FORM_data8)) || ((cuvstamp == DW_CU_VERSION4) && form == DW_FORM_sec_offset)) { /* A reference to .debug_loc, with an offset in .debug_loc of a loclist */ Dwarf_Small *loc_section_end = 0; Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; int count_res = DW_DLV_ERROR; int loclist_count = 0; int lli = 0; setup_res = context_is_cu_not_tu(cucontext,&is_cu); if(setup_res != DW_DLV_OK) { return setup_res; } off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } count_res = _dwarf_get_loclist_count(dbg, loclist_offset, address_size, &loclist_count, error); listlen = loclist_count; if (count_res != DW_DLV_OK) { return count_res; } if (loclist_count == 0) { return DW_DLV_NO_ENTRY; } llbuf = (Dwarf_Locdesc **) _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count); if (!llbuf) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (lli = 0; lli < loclist_count; ++lli) { int lres = 0; blkres = _dwarf_read_loc_section(dbg, &loc_block, &lowpc, &highpc, loclist_offset, address_size, error); if (blkres != DW_DLV_OK) { _dwarf_cleanup_llbuf(dbg, llbuf, lli); return (blkres); } loc_section_end = dbg->de_debug_loc.dss_data+ dbg->de_debug_loc.dss_size; lres = _dwarf_get_locdesc(dbg, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, loc_section_end, &locdesc, error); if (lres != DW_DLV_OK) { _dwarf_cleanup_llbuf(dbg, llbuf, lli); /* low level error already set: let it be passed back */ return lres; } llbuf[lli] = locdesc; /* Now get to next loclist entry offset. */ loclist_offset = loc_block.bl_section_offset + loc_block.bl_len; } } else { if( form == DW_FORM_exprloc) { blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len, &loc_block.bl_data,error); if(blkres != DW_DLV_OK) { return blkres; } loc_block.bl_from_loclist = 0; loc_block.bl_section_offset = (char *)loc_block.bl_data - (char *)dbg->de_debug_info.dss_data; } else { Dwarf_Block *tblock = 0; blkres = dwarf_formblock(loc_attr, &tblock, error); if (blkres != DW_DLV_OK) { return (blkres); } loc_block.bl_len = tblock->bl_len; loc_block.bl_data = tblock->bl_data; loc_block.bl_from_loclist = tblock->bl_from_loclist; loc_block.bl_section_offset = tblock->bl_section_offset; loc_block.bl_locdesc_offset = 0; /* not relevent */ /* We copied tblock contents to the stack var, so can dealloc tblock now. Avoids leaks. */ dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); } listlen = 1; /* One by definition of a location entry. */ lowpc = 0; /* HACK */ highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ blkres = _dwarf_get_locdesc(dbg, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, info_section_end, &locdesc, error); if (blkres != DW_DLV_OK) { /* low level error already set: let it be passed back */ return blkres; } llbuf = (Dwarf_Locdesc **) _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen); if (!llbuf) { /* Free the locdesc we allocated but won't use. */ dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } llbuf[0] = locdesc; } *llbuf_out = llbuf; *listlen_out = listlen; return (DW_DLV_OK); } /* Handles only a location expression. If called on a loclist, just returns one of those. Cannot not handle a real loclist. It returns the location expression as a loclist with a single entry. See dwarf_loclist_n() which handles any number of location list entries. This is the original definition, and it simply does not work for loclists. Nor does it work on DWARF4 nor on some versions of gcc generating DWARF4. Kept for compatibility. */ int dwarf_loclist(Dwarf_Attribute attr, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { Dwarf_Debug dbg; /* Dwarf_Attribute that describes the DW_AT_location in die, if present. */ Dwarf_Attribute loc_attr = attr; /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; /* A pointer to the current Dwarf_Locdesc read. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Small *info_section_end = 0; Dwarf_Half form = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_CU_Context cucontext = 0; unsigned address_size = 0; int blkres = DW_DLV_ERROR; int setup_res = DW_DLV_ERROR; int cuvstamp = 0; /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg, &cucontext, &form, error); if (setup_res != DW_DLV_OK) { return setup_res; } info_section_end = _dwarf_calculate_info_section_end_ptr(cucontext); cuvstamp = cucontext->cc_version_stamp; address_size = cucontext->cc_address_size; /* If this is a form_block then it's a location expression. If it's DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */ if (((cuvstamp == DW_CU_VERSION2 || cuvstamp == DW_CU_VERSION3) && (form == DW_FORM_data4 || form == DW_FORM_data8)) || ((cuvstamp == DW_CU_VERSION4) && form == DW_FORM_sec_offset)) { /* A reference to .debug_loc, with an offset in .debug_loc of a loclist. */ Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } /* With dwarf_loclist, just read a single entry */ blkres = _dwarf_read_loc_section(dbg, &loc_block, &lowpc, &highpc, loclist_offset, address_size, error); if (blkres != DW_DLV_OK) { return (blkres); } } else { if( form == DW_FORM_exprloc) { blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len, &loc_block.bl_data,error); if(blkres != DW_DLV_OK) { return blkres; } loc_block.bl_from_loclist = 0; loc_block.bl_section_offset = (char *)loc_block.bl_data - (char *)dbg->de_debug_info.dss_data; } else { Dwarf_Block *tblock = 0; /* If DWARF5 this will surely fail, get an error. */ blkres = dwarf_formblock(loc_attr, &tblock, error); if (blkres != DW_DLV_OK) { return (blkres); } loc_block.bl_len = tblock->bl_len; loc_block.bl_data = tblock->bl_data; loc_block.bl_from_loclist = tblock->bl_from_loclist; loc_block.bl_section_offset = tblock->bl_section_offset; /* We copied tblock contents to the stack var, so can dealloc tblock now. Avoids leaks. */ dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); } lowpc = 0; /* HACK */ highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ } /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. See *dwarf_loclist_n() which handles the general case, this case handles only a single location expression. */ blkres = _dwarf_get_locdesc(dbg, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, info_section_end, &locdesc, error); if (blkres != DW_DLV_OK) { /* low level error already set: let it be passed back */ return blkres; } *llbuf = locdesc; *listlen = 1; return (DW_DLV_OK); } /* Handles only a location expression. It returns the location expression as a loclist with a single entry. Usable to access dwarf expressions from any source, but specifically from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression_in must point to a valid dwarf expression set of bytes of length expression_length. Not a DW_FORM_block*, just the expression bytes. If the address_size != de_pointer_size this will not work right. See dwarf_loclist_from_expr_b() for a better interface. */ int dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { int res = 0; Dwarf_Half addr_size = dbg->de_pointer_size; res = dwarf_loclist_from_expr_a(dbg,expression_in, expression_length, addr_size,llbuf,listlen,error); return res; } /* New April 27 2009. Adding addr_size argument for the rare cases where an object has CUs with a different address_size. As of 2012 we have yet another version, dwarf_loclist_from_expr_b() with the version_stamp and offset size (length size) passed in. */ int dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half addr_size, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { int res; Dwarf_Debug_InfoTypes info_reading = &dbg->de_info_reading; Dwarf_CU_Context current_cu_context = info_reading->de_cu_context; Dwarf_Small version_stamp = DW_CU_VERSION2; Dwarf_Half offset_size = dbg->de_length_size; if (current_cu_context) { /* This is ugly. It is not necessarily right. Due to oddity in DW_OP_GNU_implicit_pointer, see its implementation above. For correctness, use dwarf_loclist_from_expr_b() instead of dwarf_loclist_from_expr_a(). */ version_stamp = current_cu_context->cc_version_stamp; offset_size = current_cu_context->cc_length_size; if (version_stamp < 2) { /* This is probably totally silly. */ version_stamp = DW_CU_VERSION2; } } res = dwarf_loclist_from_expr_b(dbg, expression_in, expression_length, addr_size, offset_size, version_stamp, /* CU context DWARF version */ llbuf, listlen, error); return res; } /* New November 13 2012. Adding DWARF version number argument. */ int dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Small dwarf_version, Dwarf_Locdesc ** llbuf, Dwarf_Signed * listlen, Dwarf_Error * error) { /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; /* A pointer to the current Dwarf_Locdesc read. */ Dwarf_Locdesc *locdesc = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL); Dwarf_Small version_stamp = dwarf_version; int res = 0; /* We do not know what the end is in this interface. */ Dwarf_Small *section_start = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *section_end = 0; const char *section_name = 0; res = _dwarf_what_section_are_we(dbg, expression_in,§ion_name,§ion_start, §ion_size,§ion_end,error); if (res != DW_DLV_OK) { _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN); return DW_DLV_ERROR; } memset(&loc_block,0,sizeof(loc_block)); loc_block.bl_len = expression_length; loc_block.bl_data = expression_in; loc_block.bl_from_loclist = 0; /* Not from loclist. */ loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */ /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ /* We need the DWARF version to get a locdesc! */ res = _dwarf_get_locdesc(dbg, &loc_block, addr_size, offset_size, version_stamp, lowpc, highpc, section_end, &locdesc, error); if (res != DW_DLV_OK) { /* low level error already set: let it be passed back */ return res; } *llbuf = locdesc; *listlen = 1; return DW_DLV_OK; } /* Usable to read a single loclist or to read a block of them or to read an entire section's loclists. It's BROKEN because it's not safe to read a loclist entry when we do not know the address size (in any object where address size can vary by compilation unit). It also does not recognize split dwarf or DWARF4 or DWARF5 adequately. */ /*ARGSUSED*/ int dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Addr * hipc_offset, Dwarf_Addr * lopc_offset, Dwarf_Ptr * data, Dwarf_Unsigned * entry_len, Dwarf_Unsigned * next_entry, Dwarf_Error * error) { Dwarf_Block_c b; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Half address_size = 0; int res = DW_DLV_ERROR; if (!dbg->de_debug_loc.dss_data) { int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error); if (secload != DW_DLV_OK) { return secload; } } /* FIXME: address_size is not necessarily the same in every frame. */ address_size = dbg->de_pointer_size; res = _dwarf_read_loc_section(dbg, &b, &lowpc, &highpc, offset, address_size,error); if (res != DW_DLV_OK) { return res; } *hipc_offset = highpc; *lopc_offset = lowpc; *entry_len = b.bl_len; *data = b.bl_data; *next_entry = b.bl_len + b.bl_section_offset; return DW_DLV_OK; } /* Bring in the code for the October 2015 interfaces. */ #include "dwarf_loc2.h" dwarfutils-20200114/libdwarf/dwarf_loc.h000066400000000000000000000123071361531463500200460ustar00rootroot00000000000000/* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain; struct Dwarf_Loc_Chain_s { Dwarf_Small lc_atom; Dwarf_Unsigned lc_number; Dwarf_Unsigned lc_number2; Dwarf_Unsigned lc_number3; Dwarf_Unsigned lc_offset; Dwarf_Unsigned lc_opnumber; Dwarf_Loc_Chain lc_next; }; /* Contains info on an uninterpreted block of data Used with certain frame information functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* 0 if location description, 1 if .debug_info loclist, 2 if .debug_info.dwo split dwarf loclist. */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; /* Section offset where the location description itself starts. So a few bytes lower than bl_section_offset */ Dwarf_Unsigned bl_locdesc_offset; } Dwarf_Block_c; /* Location record. Records up to 3 operand values. For DWARF5 ops with a 1 byte size and then a block of data of that size we the size in an operand and follow that with the next operand as a pointer to the block. The pointer is inserted via cast, so an ugly hack. This struct is opaque. Not visible to callers. */ struct Dwarf_Loc_c_s { Dwarf_Small lr_atom; /* Location operation */ Dwarf_Unsigned lr_number; /* First operand */ /* Second operand. For OP_bregx, OP_bit_piece, OP_[GNU_]const_type, OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value, OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, OP_xderef_type, */ Dwarf_Unsigned lr_number2; /* Third Operand. For OP_[GNU_]const type, pointer to block of length 'lr_number2' */ Dwarf_Unsigned lr_number3; /* The number assigned. 0 to the number-of-ops - 1 in the expression we are expanding. */ Dwarf_Unsigned lr_opnumber; Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ Dwarf_Loc_c lr_next; /* When a list is useful. */ }; /* Location description DWARF 2,3,4,5 Adds the DW_LLE value (new in DWARF5). This struct is opaque. Not visible to callers. */ struct Dwarf_Locdesc_c_s { /* The DW_LLE value of the entry. Synthesized by libdwarf in a non-split-dwarf loclist, recorded in a split dwarf loclist. */ Dwarf_Small ld_lle_value; /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, or a length, never a pc value. */ Dwarf_Addr ld_hipc; /* end of active range */ /* count of struct Dwarf_Loc_c_s in array. */ Dwarf_Half ld_cents; /* pointer to array of struct Dwarf_Loc_c_s*/ Dwarf_Loc_c ld_s; Dwarf_Small ld_from_loclist; /* Section (not CU) offset where loc-expr begins*/ Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where location descr begins*/ Dwarf_Unsigned ld_locdesc_offset; /* Pointer to our header (in which we are located). */ Dwarf_Loc_Head_c ld_loclist_head; }; /* A 'header' to the loclist and the location description(s) attached to an attribute. This struct is opaque. Not visible to callers. */ struct Dwarf_Loc_Head_c_s { /* The array (1 or more entries) of struct Loc_Desc_c_s If 1 it may really be a locexpr */ Dwarf_Locdesc_c ll_locdesc; /* Entry count of the ll_locdesc array. */ Dwarf_Unsigned ll_locdesc_count; /* 0 if locexpr (in which case ll_locdesc_count is 1), 1 if non-split (dwarf 2,3,4) .debug_loc, 2 if split-dwarf .debug_loc.dwo */ Dwarf_Small ll_from_loclist; /* The CU Context of this loclist or locexpr. */ Dwarf_CU_Context ll_context; Dwarf_Debug ll_dbg; }; int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error*error); dwarfutils-20200114/libdwarf/dwarf_loc2.h000066400000000000000000000723671361531463500201440ustar00rootroot00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 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 and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error* error) { if (loc_block->bl_from_loclist) { Dwarf_Small *loc_ptr = 0; Dwarf_Unsigned loc_len = 0; Dwarf_Small *end_ptr = 0; loc_ptr = loc_block->bl_data; loc_len = loc_block->bl_len; end_ptr = dbg->de_debug_loc.dss_size + dbg->de_debug_loc.dss_data; if ((loc_ptr +loc_len) > end_ptr) { _dwarf_error(dbg,error,DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } } return DW_DLV_OK; } /* #included in dwarf_loc.c to compile. This in a separate file to make it easy to see the early (pre _c) and current (_c) versions at the same time (in distinct windows). This synthesizes the ld_lle_value of the locdesc, but when it is an actual dwo this value gets overridden by our caller with the true ld_lle_value. */ static int _dwarf_get_locdesc_op_c(Dwarf_Debug dbg, Dwarf_Unsigned locdesc_index, Dwarf_Loc_Head_c loc_head, Dwarf_Block_c * loc_block, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small version_stamp, Dwarf_Addr lowpc, Dwarf_Addr highpc, Dwarf_Error * error) { /* Offset of current operator from start of block. */ Dwarf_Unsigned offset = 0; /* Used to chain the Dwarf_Loc_Chain_s structs. */ Dwarf_Loc_Chain new_loc = NULL; Dwarf_Loc_Chain prev_loc = NULL; Dwarf_Loc_Chain head_loc = NULL; Dwarf_Unsigned op_count = 0; /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */ Dwarf_Loc_c block_loc = 0; Dwarf_Locdesc_c locdesc = loc_head->ll_locdesc + locdesc_index; Dwarf_Unsigned i = 0; int res = 0; Dwarf_Small *section_start = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *section_end = 0; const char *section_name = 0; Dwarf_Small *blockdataptr = 0; /* ***** BEGIN CODE ***** */ blockdataptr = loc_block->bl_data; if (!blockdataptr || !loc_block->bl_len) { /* an empty block has no operations so no section or tests need be done.. */ } else { res = _dwarf_what_section_are_we(dbg, blockdataptr,§ion_name,§ion_start, §ion_size,§ion_end,error); if (res != DW_DLV_OK) { _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN); return DW_DLV_ERROR; } res = _dwarf_loc_block_sanity_check(dbg,loc_block,error); if (res != DW_DLV_OK) { return res; } } /* New loop getting Loc operators. Non DWO */ while (offset <= loc_block->bl_len) { Dwarf_Unsigned nextoffset = 0; struct Dwarf_Loc_c_s temp_loc; /* This call is ok even if bl_data NULL and bl_len 0 */ res = _dwarf_read_loc_expr_op(dbg,loc_block, op_count, version_stamp, offset_size, address_size, offset, section_end, &nextoffset, &temp_loc, error); if (res == DW_DLV_ERROR) { return res; } if (res == DW_DLV_NO_ENTRY) { /* Normal end. Also the end for an empty loc_block. */ break; } op_count++; new_loc = (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 1); if (new_loc == NULL) { /* Some memory may leak here. */ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Copying all the fields. DWARF 2,3,4,5. */ new_loc->lc_atom = temp_loc.lr_atom; new_loc->lc_opnumber= temp_loc.lr_opnumber; new_loc->lc_number = temp_loc.lr_number; new_loc->lc_number2 = temp_loc.lr_number2; new_loc->lc_number3 = temp_loc.lr_number3; new_loc->lc_offset = temp_loc.lr_offset; if (head_loc == NULL) head_loc = prev_loc = new_loc; else { prev_loc->lc_next = new_loc; prev_loc = new_loc; } offset = nextoffset; } block_loc = (Dwarf_Loc_c ) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK_C, op_count); if (block_loc == NULL) { /* Some memory does leak here. */ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* op_count could be zero. */ new_loc = head_loc; for (i = 0; i < op_count; i++) { /* Copying only the fields needed by DWARF 2,3,4 */ (block_loc + i)->lr_atom = new_loc->lc_atom; (block_loc + i)->lr_number = new_loc->lc_number; (block_loc + i)->lr_number2 = new_loc->lc_number2; (block_loc + i)->lr_number3 = new_loc->lc_number3; (block_loc + i)->lr_offset = new_loc->lc_offset; (block_loc + i)->lr_opnumber = new_loc->lc_opnumber; prev_loc = new_loc; new_loc = prev_loc->lc_next; dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); } /* Synthesizing the DW_LLE values. */ if(highpc == 0 && lowpc == 0) { locdesc->ld_lle_value = DW_LLEX_end_of_list_entry; } else if(lowpc == MAX_ADDR) { locdesc->ld_lle_value = DW_LLEX_base_address_selection_entry; } else { locdesc->ld_lle_value = DW_LLEX_offset_pair_entry; } locdesc->ld_cents = op_count; locdesc->ld_s = block_loc; locdesc->ld_from_loclist = loc_block->bl_from_loclist; locdesc->ld_section_offset = loc_block->bl_section_offset; locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset; locdesc->ld_lopc = lowpc; locdesc->ld_hipc = highpc; return DW_DLV_OK; } static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, Dwarf_Block_c * return_block, Dwarf_Addr * lowpc, Dwarf_Addr * highpc, Dwarf_Bool *at_end, Dwarf_Half * lle_op, Dwarf_Off sec_offset, Dwarf_Half address_size, Dwarf_Error * error) { Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset; Dwarf_Small *locptr = 0; Dwarf_Small llecode = 0; Dwarf_Unsigned expr_offset = sec_offset; Dwarf_Byte_Ptr section_end = dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size; if (sec_offset >= dbg->de_debug_loc.dss_size) { /* We're at the end. No more present. */ return DW_DLV_NO_ENTRY; } memset(return_block,0,sizeof(*return_block)); /* not the same as non-split loclist, but still a list. */ return_block->bl_from_loclist = 2; return_block->bl_locdesc_offset = sec_offset; llecode = *beg; locptr = beg +1; expr_offset++; switch(llecode) { case DW_LLEX_end_of_list_entry: *at_end = TRUE; return_block->bl_section_offset = expr_offset; expr_offset++; break; case DW_LLEX_base_address_selection_entry: { Dwarf_Unsigned addr_index = 0; DECODE_LEB128_UWORD_CK(locptr,addr_index, dbg,error,section_end); return_block->bl_section_offset = expr_offset; /* So this behaves much like non-dwo loclist */ *lowpc=MAX_ADDR; *highpc=addr_index; } break; case DW_LLEX_start_end_entry: { Dwarf_Unsigned addr_indexs = 0; Dwarf_Unsigned addr_indexe= 0; Dwarf_Unsigned exprlen = 0; Dwarf_Unsigned leb128_length = 0; DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexs, leb128_length, dbg,error,section_end); expr_offset += leb128_length; DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexe, leb128_length, dbg,error,section_end); expr_offset +=leb128_length; *lowpc=addr_indexs; *highpc=addr_indexe; READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, DWARF_HALF_SIZE, error,section_end); locptr += DWARF_HALF_SIZE; expr_offset += DWARF_HALF_SIZE; return_block->bl_len = exprlen; return_block->bl_data = locptr; return_block->bl_section_offset = expr_offset; expr_offset += exprlen; if (expr_offset > dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } } break; case DW_LLEX_start_length_entry: { Dwarf_Unsigned addr_index = 0; Dwarf_Unsigned range_length = 0; Dwarf_Unsigned exprlen = 0; Dwarf_Unsigned leb128_length = 0; DECODE_LEB128_UWORD_LEN_CK(locptr,addr_index, leb128_length, dbg,error,section_end); expr_offset +=leb128_length; READ_UNALIGNED_CK(dbg, range_length, Dwarf_Unsigned, locptr, DWARF_32BIT_SIZE, error,section_end); locptr += DWARF_32BIT_SIZE; expr_offset += DWARF_32BIT_SIZE; READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, DWARF_HALF_SIZE, error,section_end); locptr += DWARF_HALF_SIZE; expr_offset += DWARF_HALF_SIZE; *lowpc = addr_index; *highpc = range_length; return_block->bl_len = exprlen; return_block->bl_data = locptr; return_block->bl_section_offset = expr_offset; /* exprblock_size can be zero, means no expression */ expr_offset += exprlen; if (expr_offset > dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } } break; case DW_LLEX_offset_pair_entry: { Dwarf_Unsigned startoffset = 0; Dwarf_Unsigned endoffset = 0; Dwarf_Unsigned exprlen = 0; READ_UNALIGNED_CK(dbg, startoffset, Dwarf_Unsigned, locptr, DWARF_32BIT_SIZE, error,section_end); locptr += DWARF_32BIT_SIZE; expr_offset += DWARF_32BIT_SIZE; READ_UNALIGNED_CK(dbg, endoffset, Dwarf_Unsigned, locptr, DWARF_32BIT_SIZE, error,section_end); locptr += DWARF_32BIT_SIZE; expr_offset += DWARF_32BIT_SIZE; *lowpc= startoffset; *highpc = endoffset; READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, DWARF_HALF_SIZE, error,section_end); locptr += DWARF_HALF_SIZE; expr_offset += DWARF_HALF_SIZE; return_block->bl_len = exprlen; return_block->bl_data = locptr; return_block->bl_section_offset = expr_offset; expr_offset += exprlen; if (expr_offset > dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); return DW_DLV_ERROR; } } break; default: _dwarf_error(dbg,error,DW_DLE_LLE_CODE_UNKNOWN); return DW_DLV_ERROR; } *lle_op = llecode; return DW_DLV_OK; } static int _dwarf_get_loclist_count_dwo(Dwarf_Debug dbg, Dwarf_Off loclist_offset, Dwarf_Half address_size, int *loclist_count, Dwarf_Error * error) { int count = 0; Dwarf_Off offset = loclist_offset; for (;;) { Dwarf_Block_c b; Dwarf_Bool at_end = FALSE; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Half lle_op = 0; int res = _dwarf_read_loc_section_dwo(dbg, &b, &lowpc, &highpc, &at_end, &lle_op, offset, address_size, error); if (res != DW_DLV_OK) { return res; } if (at_end) { count++; break; } offset = b.bl_len + b.bl_section_offset; count++; } *loclist_count = count; return DW_DLV_OK; } /* New October 2015 This interface requires the use of interface functions to get data from Dwarf_Locdesc_c. The structures are not visible to callers. */ int dwarf_get_loclist_c(Dwarf_Attribute attr, Dwarf_Loc_Head_c * ll_header_out, Dwarf_Unsigned * listlen_out, Dwarf_Error * error) { Dwarf_Debug dbg; /* Dwarf_Attribute that describes the DW_AT_location in die, if present. */ Dwarf_Attribute loc_attr = attr; /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; Dwarf_Half form = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Unsigned listlen = 0; Dwarf_Locdesc_c llbuf = 0; Dwarf_Loc_Head_c llhead = 0; Dwarf_CU_Context cucontext = 0; unsigned address_size = 0; int cuvstamp = 0; Dwarf_Bool is_cu = FALSE; int blkres = DW_DLV_ERROR; int setup_res = DW_DLV_ERROR; /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error); if (setup_res != DW_DLV_OK) { return setup_res; } cuvstamp = cucontext->cc_version_stamp; address_size = cucontext->cc_address_size; /* If this is a form_block then it's a location expression. If it's DW_FORM_data4 or DW_FORM_data8 in DWARF2 or DWARF3 (or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */ /* In final DWARF5 the situation changes . FIXME */ if (((cuvstamp == DW_CU_VERSION2 || cuvstamp == DW_CU_VERSION3) && (form == DW_FORM_data4 || form == DW_FORM_data8)) || ((cuvstamp == DW_CU_VERSION4 || cuvstamp == DW_CU_VERSION5) && form == DW_FORM_sec_offset)) { /* Here we have a loclist to deal with. */ setup_res = context_is_cu_not_tu(cucontext,&is_cu); if(setup_res != DW_DLV_OK) { return setup_res; } if (cucontext->cc_is_dwo) { /* dwo loclist. If this were a skeleton CU (ie, in the base, not dwo/dwp) then it could not have a loclist. */ /* A reference to .debug_loc.dwo, with an offset in .debug_loc.dwo of a loclist */ /* In DWARF5 the situation changes . FIXME */ Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; int count_res = DW_DLV_ERROR; int loclist_count = 0; Dwarf_Unsigned lli = 0; off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } count_res = _dwarf_get_loclist_count_dwo(dbg, loclist_offset, address_size, &loclist_count, error); if (count_res != DW_DLV_OK) { return count_res; } if (loclist_count == 0) { return DW_DLV_NO_ENTRY; } llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } listlen = loclist_count; llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen); if (!llbuf) { dwarf_loc_head_c_dealloc(llhead); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } llhead->ll_locdesc = llbuf; llhead->ll_locdesc_count = listlen; llhead->ll_from_loclist = 2; llhead->ll_context = cucontext; llhead->ll_dbg = dbg; /* New get loc ops, DWO version */ for (lli = 0; lli < listlen; ++lli) { int lres = 0; Dwarf_Half lle_op = 0; Dwarf_Bool at_end = 0; blkres = _dwarf_read_loc_section_dwo(dbg, &loc_block, &lowpc, &highpc, &at_end, &lle_op, loclist_offset, address_size, error); if (blkres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return blkres; } /* Fills in the locdesc op at index lli */ lres = _dwarf_get_locdesc_op_c(dbg, lli, llhead, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, error); if (lres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); /* low level error already set: let it be passed back */ return lres; } /* Override the syntesized lle value with the real one. */ llhead->ll_locdesc[lli].ld_lle_value = lle_op; /* Now get to next loclist entry offset. */ loclist_offset = loc_block.bl_section_offset + loc_block.bl_len; } } else { /* Non-dwo loclist. If this were a skeleton CU (ie, in the base, not dwo/dwp) then it could not have a loclist. */ /* A reference to .debug_loc, with an offset in .debug_loc of a loclist */ Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; int count_res = DW_DLV_ERROR; int loclist_count = 0; Dwarf_Unsigned lli = 0; off_res = _dwarf_get_loclist_header_start(dbg, attr, &loclist_offset, error); if (off_res != DW_DLV_OK) { return off_res; } count_res = _dwarf_get_loclist_count(dbg, loclist_offset, address_size, &loclist_count, error); if (count_res != DW_DLV_OK) { return count_res; } if (loclist_count == 0) { return DW_DLV_NO_ENTRY; } llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } listlen = loclist_count; llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen); if (!llbuf) { dwarf_loc_head_c_dealloc(llhead); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } llhead->ll_locdesc = llbuf; llhead->ll_locdesc_count = listlen; llhead->ll_from_loclist = 1; llhead->ll_context = cucontext; llhead->ll_dbg = dbg; /* New locdesc and Loc, non-DWO, so old format */ for (lli = 0; lli < listlen; ++lli) { int lres = 0; Dwarf_Block_c c; blkres = _dwarf_read_loc_section(dbg, &c, &lowpc, &highpc, loclist_offset, address_size, error); if (blkres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return (blkres); } loc_block.bl_len = c.bl_len; loc_block.bl_data = c.bl_data; loc_block.bl_from_loclist = c.bl_from_loclist; loc_block.bl_section_offset = c.bl_section_offset; loc_block.bl_locdesc_offset = loclist_offset; /* Fills in the locdesc at index lli */ lres = _dwarf_get_locdesc_op_c(dbg, lli, llhead, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, error); if (lres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); /* low level error already set: let it be passed back */ return lres; } /* Now get to next loclist entry offset. */ loclist_offset = loc_block.bl_section_offset + loc_block.bl_len; } } } else { llhead = (Dwarf_Loc_Head_c) _dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } if( form == DW_FORM_exprloc) { blkres = dwarf_formexprloc(loc_attr,&loc_block.bl_len, &loc_block.bl_data,error); if(blkres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return blkres; } loc_block.bl_from_loclist = 0; loc_block.bl_section_offset = (char *)loc_block.bl_data - (char *)dbg->de_debug_info.dss_data; loc_block.bl_locdesc_offset = 0; /* not relevant */ } else { Dwarf_Block *tblock = 0; blkres = dwarf_formblock(loc_attr, &tblock, error); if (blkres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); return (blkres); } loc_block.bl_len = tblock->bl_len; loc_block.bl_data = tblock->bl_data; loc_block.bl_from_loclist = tblock->bl_from_loclist; loc_block.bl_section_offset = tblock->bl_section_offset; loc_block.bl_locdesc_offset = 0; /* not relevant */ /* We copied tblock contents to the stack var, so can dealloc tblock now. Avoids leaks. */ dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); } listlen = 1; /* One by definition of a location entry. */ /* This hack ensures that the Locdesc_c is marked DW_LLEX_start_end_entry */ lowpc = 0; /* HACK */ highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, listlen); if (!llbuf) { dwarf_loc_head_c_dealloc(llhead); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } llhead->ll_locdesc = llbuf; llhead->ll_locdesc = llbuf; llhead->ll_locdesc_count = listlen; llhead->ll_from_loclist = 0; llhead->ll_context = cucontext; llhead->ll_dbg = dbg; /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ /* Fills in the locdesc at index 0 */ blkres = _dwarf_get_locdesc_op_c(dbg, 0, /* fake locdesc is index 0 */ llhead, &loc_block, address_size, cucontext->cc_length_size, cucontext->cc_version_stamp, lowpc, highpc, error); if (blkres != DW_DLV_OK) { dwarf_loc_head_c_dealloc(llhead); /* low level error already set: let it be passed back */ return blkres; } } *ll_header_out = llhead; *listlen_out = listlen; return (DW_DLV_OK); } /* An interface giving us no cu context! */ int dwarf_loclist_from_expr_c(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small dwarf_version, Dwarf_Loc_Head_c *loc_head, Dwarf_Unsigned * listlen, Dwarf_Error * error) { /* Dwarf_Block that describes a single location expression. */ Dwarf_Block_c loc_block; Dwarf_Loc_Head_c llhead = 0; Dwarf_Locdesc_c llbuf = 0; int local_listlen = 1; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = MAX_ADDR; Dwarf_Small version_stamp = dwarf_version; int res = 0; llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } memset(&loc_block,0,sizeof(loc_block)); loc_block.bl_len = expression_length; loc_block.bl_data = expression_in; loc_block.bl_from_loclist = 0; /* Not from loclist. */ loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */ loc_block.bl_locdesc_offset = 0; /* Fake. Not meaningful. */ llbuf = (Dwarf_Locdesc_c) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC_C, local_listlen); if (!llbuf) { dwarf_loc_head_c_dealloc(llhead); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } llhead->ll_locdesc = llbuf; llhead->ll_locdesc_count = local_listlen; llhead->ll_from_loclist = 0; llhead->ll_context = 0; /* Not available! */ llhead->ll_dbg = dbg; /* An empty location description (block length 0) means the code generator emitted no variable, the variable was not generated, it was unused or perhaps never tested after being set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ res = _dwarf_get_locdesc_op_c(dbg, 0, llhead, &loc_block, address_size, offset_size, version_stamp, lowpc, highpc, error); if (res != DW_DLV_OK) { /* low level error already set: let it be passed back */ dwarf_loc_head_c_dealloc(llhead); return (DW_DLV_ERROR); } *loc_head = llhead; *listlen = local_listlen; return (DW_DLV_OK); } int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c loclist_head, Dwarf_Unsigned index, Dwarf_Small * lle_value_out, /* identifies type of loclist entry*/ Dwarf_Addr * lowpc_out, Dwarf_Addr * hipc_out, Dwarf_Unsigned * loclist_count_out, /* Returns pointer to the specific locdesc of the index; */ Dwarf_Locdesc_c* locdesc_entry_out, Dwarf_Small * loclist_source_out, /* 0,1, or 2 */ Dwarf_Unsigned * expression_offset_out, Dwarf_Unsigned * locdesc_offset_out, Dwarf_Error * error) { Dwarf_Locdesc_c descs_base = 0; Dwarf_Locdesc_c desc = 0; Dwarf_Unsigned desc_count = 0; Dwarf_Debug dbg; desc_count = loclist_head->ll_locdesc_count; descs_base = loclist_head->ll_locdesc; dbg = loclist_head->ll_dbg; if (index >= desc_count) { _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR); return (DW_DLV_ERROR); } desc = descs_base + index; *lle_value_out = desc->ld_lle_value; *lowpc_out = desc->ld_lopc; *hipc_out = desc->ld_hipc; *loclist_count_out = desc->ld_cents; *locdesc_entry_out = desc; *loclist_source_out = desc->ld_from_loclist; *expression_offset_out = desc->ld_section_offset; *locdesc_offset_out = desc->ld_locdesc_offset; return DW_DLV_OK; } int dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc, Dwarf_Unsigned index, Dwarf_Small * atom_out, Dwarf_Unsigned * operand1, Dwarf_Unsigned * operand2, Dwarf_Unsigned * operand3, Dwarf_Unsigned * offset_for_branch, Dwarf_Error* error) { Dwarf_Loc_c op = 0; Dwarf_Unsigned max = locdesc->ld_cents; if(index >= max) { Dwarf_Debug dbg = locdesc->ld_loclist_head->ll_dbg; _dwarf_error(dbg, error, DW_DLE_LOCLIST_INDEX_ERROR); return (DW_DLV_ERROR); } op = locdesc->ld_s + index; *atom_out = op->lr_atom; *operand1 = op->lr_number; *operand2 = op->lr_number2; *operand3 = op->lr_number3; *offset_for_branch = op->lr_offset; return DW_DLV_OK; } void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head) { Dwarf_Debug dbg = loclist_head->ll_dbg; Dwarf_Locdesc_c desc = loclist_head->ll_locdesc; if( desc) { Dwarf_Unsigned listlen = loclist_head->ll_locdesc_count; Dwarf_Unsigned i = 0; for ( ; i < listlen; ++i) { Dwarf_Loc_c loc = desc[i].ld_s; if(loc) { dwarf_dealloc(dbg,loc,DW_DLA_LOC_BLOCK_C); } } dwarf_dealloc(dbg,desc,DW_DLA_LOCDESC_C); } dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C); } dwarfutils-20200114/libdwarf/dwarf_macho_loader.h000066400000000000000000002063411361531463500217110ustar00rootroot00000000000000/* This is a cut-down version of loader.h from cctools-895, shrunk to eliminate aspects unwanted in libdwarf and to avoid #include entirely. All tab characters replaced with 4 spaces so various things no line up as they used to. cctools-895 in its original form is available from https://opensource.apple.com/ see Developer Tools version 8.2.1. cctools-895/include/loader.h */ /* * Copyright (c) 1999-2010 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef MACHO_LOADER_H #define MACHO_LOADER_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if 0 /* Not used here. DavidA. September 2018 */ /* * This file describes the format of mach object files. */ #include /* * is needed here for the cpu_type_t and cpu_subtype_t types * and contains the constants for the possible values of these types. */ #include /* * is needed here for the vm_prot_t type and contains the * constants that are or'ed together for the possible values of this type. */ #include /* * is expected to define the flavors of the thread * states and the structures of those flavors for each machine. */ #include #include #endif /* 0 */ #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYP */ /* * The 32-bit mach header appears at the very beginning of the object file for * 32-bit architectures. */ struct mach_header { TYP(magic,4); /* mach magic number identifier */ TYP(cputype,4); /* cpu specifier */ TYP(cpusubtype,4); /* machine specifier */ TYP(filetype,4); /* type of file */ TYP(ncmds,4); /* number of load commands */ TYP(sizeofcmds,4); /* the size of all the load commands */ TYP(flags,4); /* flags */ }; /* Constant for the magic field of the mach_header (32-bit architectures) MH_MAGIC MH_MAGIC_64 appear in big-endian objects MH_CIGAM MH_CIGAM_64 appear in little-endian objects */ #define MH_MAGIC 0xfeedface /* the mach magic number */ #define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ /* * The 64-bit mach header appears at the very beginning of object files for * 64-bit architectures. */ struct mach_header_64 { TYP(magic,4); /* mach magic number identifier */ TYP(cputype,4); /* cpu specifier */ TYP(cpusubtype,4); /* machine specifier */ TYP(filetype,4); /* type of file */ TYP(ncmds,4); /* number of load commands */ TYP(sizeofcmds,4); /* the size of all the load commands */ TYP(flags,4); /* flags */ TYP(reserved,4); /* reserved */ }; /* Constant for the magic field of the mach_header_64 (64-bit architectures) */ #define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ #define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ /* * The layout of the file depends on the filetype. For all but the MH_OBJECT * file type the segments are padded out and aligned on a segment alignment * boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part * of their first segment. * * The file type MH_OBJECT is a compact format intended as output of the * assembler and input (and possibly output) of the link editor (the .o * format). All sections are in one unnamed segment with no segment padding. * This format is used as an executable format when the file is so small the * segment padding greatly increases its size. * * The file type MH_PRELOAD is an executable format intended for things that * are not executed under the kernel (proms, stand alones, kernels, etc). The * format can be executed under the kernel but may demand paged it and not * preload it before execution. * * A core file is in MH_CORE format and can be any in an arbritray legal * Mach-O file. * * Constants for the filetype field of the mach_header */ #define MH_OBJECT 0x1 /* relocatable object file */ #define MH_EXECUTE 0x2 /* demand paged executable file */ #define MH_FVMLIB 0x3 /* fixed VM shared library file */ #define MH_CORE 0x4 /* core file */ #define MH_PRELOAD 0x5 /* preloaded executable file */ #define MH_DYLIB 0x6 /* dynamically bound shared library */ #define MH_DYLINKER 0x7 /* dynamic link editor */ #define MH_BUNDLE 0x8 /* dynamically bound bundle file */ #define MH_DYLIB_STUB 0x9 /* shared library stub for static */ /* linking only, no section contents */ #define MH_DSYM 0xa /* companion file with only debug */ /* sections */ #define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */ /* Constants for the flags field of the mach_header */ #define MH_NOUNDEFS 0x1 /* the object file has no undefined references */ #define MH_INCRLINK 0x2 /* the object file is the output of an incremental link against a base file and can't be link edited again */ #define MH_DYLDLINK 0x4 /* the object file is input for the dynamic linker and can't be staticly link edited again */ #define MH_BINDATLOAD 0x8 /* the object file's undefined references are bound by the dynamic linker when loaded. */ #define MH_PREBOUND 0x10 /* the file has its dynamic undefined references prebound. */ #define MH_SPLIT_SEGS 0x20 /* the file has its read-only and read-write segments split */ #define MH_LAZY_INIT 0x40 /* the shared library init routine is to be run lazily via catching memory faults to its writeable segments (obsolete) */ #define MH_TWOLEVEL 0x80 /* the image is using two-level name space bindings */ #define MH_FORCE_FLAT 0x100 /* the executable is forcing all images to use flat name space bindings */ #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple defintions of symbols in its sub-images so the two-level namespace hints can always be used. */ #define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the prebinding agent about this executable */ #define MH_PREBINDABLE 0x800 /* the binary is not prebound but can have its prebinding redone. only used when MH_PREBOUND is not set. */ #define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to all two-level namespace modules of its dependent libraries. only used when MH_PREBINDABLE and MH_TWOLEVEL are both set. */ #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into sub-sections via symbols for dead code stripping */ #define MH_CANONICAL 0x4000 /* the binary has been canonicalized via the unprebind operation */ #define MH_WEAK_DEFINES 0x8000 /* the final linked image contains external weak symbols */ #define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses weak symbols */ #define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks in the task will be given stack execution privilege. Only used in MH_EXECUTE filetypes. */ #define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary declares it is safe for use in processes with uid zero */ #define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary declares it is safe for use in processes when issetugid() is true */ #define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, the static linker does not need to examine dependent dylibs to see if any are re-exported */ #define MH_PIE 0x200000 /* When this bit is set, the OS will load the main executable at a random address. Only used in MH_EXECUTE filetypes. */ #define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When linking against a dylib that has this bit set, the static linker will automatically not create a LC_LOAD_DYLIB load command to the dylib if no symbols are being referenced from the dylib. */ #define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type S_THREAD_LOCAL_VARIABLES */ #define MH_NO_HEAP_EXECUTION 0x1000000 /* When this bit is set, the OS will run the main executable with a non-executable heap even on platforms (e.g. i386) that don't require it. Only used in MH_EXECUTE filetypes. */ #define MH_APP_EXTENSION_SAFE 0x02000000 /* The code was linked for use in an application extension. */ /* * The load commands directly follow the mach_header. The total size of all * of the commands is given by the sizeofcmds field in the mach_header. All * load commands must have as their first two fields cmd and cmdsize. The cmd * field is filled in with a constant for that command type. Each command type * has a structure specifically for it. The cmdsize field is the size in bytes * of the particular load command structure plus anything that follows it that * is a part of the load command (i.e. section structures, strings, etc.). To * advance to the next load command the cmdsize can be added to the offset or * pointer of the current load command. The cmdsize for 32-bit architectures * MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple * of 8 bytes (these are forever the maximum alignment of any load commands). * The padded bytes must be zero. All tables in the object file must also * follow these rules so the file can be memory mapped. Otherwise the pointers * to these tables will not work well or at all on some machines. With all * padding zeroed like objects will compare byte for byte. */ struct load_command { TYP(cmd,4); /* type of load command */ TYP(cmdsize,4); /* total size of command in bytes */ }; /* * After MacOS X 10.1 when a new load command is added that is required to be * understood by the dynamic linker for the image to execute properly the * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic * linker sees such a load command it it does not understand will issue a * "unknown load command required for execution" error and refuse to use the * image. Other load commands without this bit that are not understood will * simply be ignored. */ #define LC_REQ_DYLD 0x80000000 /* Constants for the cmd field of all load commands, the type */ #define LC_SEGMENT 0x1 /* segment of this file to be mapped */ #define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ #define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ #define LC_THREAD 0x4 /* thread */ #define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ #define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ #define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ #define LC_IDENT 0x8 /* object identification info (obsolete) */ #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ #define LC_PREPAGE 0xa /* prepage command (internal use) */ #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ #define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ #define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ #define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ /* linked shared library */ #define LC_ROUTINES 0x11 /* image routines */ #define LC_SUB_FRAMEWORK 0x12 /* sub framework */ #define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ #define LC_SUB_CLIENT 0x14 /* sub client */ #define LC_SUB_LIBRARY 0x15 /* sub library */ #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ /* * load a dynamically linked shared library that is allowed to be missing * (all symbols are weak imported). */ #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) #define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be mapped */ #define LC_ROUTINES_64 0x1a /* 64-bit image routines */ #define LC_UUID 0x1b /* the uuid */ #define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ #define LC_CODE_SIGNATURE 0x1d /* local of code signature */ #define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ #define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ #define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ #define LC_DYLD_INFO 0x22 /* compressed dyld information */ #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ #define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ #define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */ #define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */ #define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ #define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat like environment variable */ #define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */ #define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */ #define LC_SOURCE_VERSION 0x2A /* source version used to build binary */ #define LC_DYLIB_CODE_SIGN_DRS 0x2B /* Code signing DRs copied from linked dylibs */ #define LC_ENCRYPTION_INFO_64 0x2C /* 64-bit encrypted segment information */ #define LC_LINKER_OPTION 0x2D /* linker options in MH_OBJECT files */ #define LC_LINKER_OPTIMIZATION_HINT 0x2E /* optimization hints in MH_OBJECT files */ #define LC_VERSION_MIN_TVOS 0x2F /* build for AppleTV min OS version */ #define LC_VERSION_MIN_WATCHOS 0x30 /* build for Watch min OS version */ /* * A variable length string in a load command is represented by an lc_str * union. The strings are stored just after the load command structure and * the offset is from the start of the load command structure. The size * of the string is reflected in the cmdsize field of the load command. * Once again any padded bytes to bring the cmdsize field to a multiple * of 4 bytes must be zero. */ union lc_str { TYP(offset,4); /* offset to the string */ #ifndef __LP64__ char *ptr; /* pointer to the string */ #endif }; /* * The segment load command indicates that a part of this file is to be * mapped into the task's address space. The size of this segment in memory, * vmsize, maybe equal to or larger than the amount to map from this file, * filesize. The file is mapped starting at fileoff to the beginning of * the segment in memory, vmaddr. The rest of the memory of the segment, * if any, is allocated zero fill on demand. The segment's maximum virtual * memory protection and initial virtual memory protection are specified * by the maxprot and initprot fields. If the segment has sections then the * section structures directly follow the segment command and their size is * reflected in cmdsize. */ struct segment_command { /* for 32-bit architectures */ TYP(cmd,4); /* LC_SEGMENT */ TYP(cmdsize,4); /* includes sizeof section structs */ char segname[16]; /* segment name */ TYP(vmaddr,4); /* memory address of this segment */ TYP(vmsize,4); /* memory size of this segment */ TYP(fileoff,4); /* file offset of this segment */ TYP(filesize,4); /* amount to map from the file */ TYP(maxprot,4); /* maximum VM protection */ TYP(initprot,4); /* initial VM protection */ TYP(nsects,4); /* number of sections in segment */ TYP(flags,4); /* flags */ }; /* * The 64-bit segment load command indicates that a part of this file is to be * mapped into a 64-bit task's address space. If the 64-bit segment has * sections then section_64 structures directly follow the 64-bit segment * command and their size is reflected in cmdsize. */ struct segment_command_64 { /* for 64-bit architectures */ TYP(cmd,4); /* LC_SEGMENT_64 */ TYP(cmdsize,4); /* includes sizeof section_64 structs */ char segname[16]; /* segment name */ TYP(vmaddr,8); /* memory address of this segment */ TYP(vmsize,8); /* memory size of this segment */ TYP(fileoff,8); /* file offset of this segment */ TYP(filesize,8); /* amount to map from the file */ TYP(maxprot,4); /* maximum VM protection */ TYP(initprot,4); /* initial VM protection */ TYP(nsects,4); /* number of sections in segment */ TYP(flags,4); /* flags */ }; /* Constants for the flags field of the segment_command */ #define SG_HIGHVM 0x1 /* the file contents for this segment is for the high part of the VM space, the low part is zero filled (for stacks in core files) */ #define SG_FVMLIB 0x2 /* this segment is the VM that is allocated by a fixed VM library, for overlap checking in the link editor */ #define SG_NORELOC 0x4 /* this segment has nothing that was relocated in it and nothing relocated to it, that is it maybe safely replaced without relocation*/ #define SG_PROTECTED_VERSION_1 0x8 /* This segment is protected. If the segment starts at file offset 0, the first page of the segment is not protected. All other pages of the segment are protected. */ /* * A segment is made up of zero or more sections. Non-MH_OBJECT files have * all of their segments with the proper sections in each, and padded to the * specified segment alignment when produced by the link editor. The first * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header * and load commands of the object file before its first section. The zero * fill sections are always last in their segment (in all formats). This * allows the zeroed segment padding to be mapped into memory where zero fill * sections might be. The gigabyte zero fill sections, those with the section * type S_GB_ZEROFILL, can only be in a segment with sections of this type. * These segments are then placed after all other segments. * * The MH_OBJECT format has all of its sections in one segment for * compactness. There is no padding to a specified segment boundary and the * mach_header and load commands are not part of the segment. * * Sections with the same section name, sectname, going into the same segment, * segname, are combined by the link editor. The resulting section is aligned * to the maximum alignment of the combined sections and is the new section's * alignment. The combined sections are aligned to their original alignment in * the combined section. Any padded bytes to get the specified alignment are * zeroed. * * The format of the relocation entries referenced by the reloff and nreloc * fields of the section structure for mach object files is described in the * header file . */ struct section { /* for 32-bit architectures */ char sectname[16]; /* name of this section */ char segname[16]; /* segment this section goes in */ TYP(addr,4); /* memory address of this section */ TYP(size,4); /* size in bytes of this section */ TYP(offset,4); /* file offset of this section */ TYP(align,4); /* section alignment (power of 2) */ TYP(reloff,4); /* file offset of relocation entries */ TYP(nreloc,4); /* number of relocation entries */ TYP(flags,4); /* flags (section type and attributes)*/ TYP(reserved1,4); /* reserved (for offset or index) */ TYP(reserved2,4); /* reserved (for count or sizeof) */ }; struct section_64 { /* for 64-bit architectures */ char sectname[16]; /* name of this section */ char segname[16]; /* segment this section goes in */ TYP(addr,8); /* memory address of this section */ TYP(size,8); /* size in bytes of this section */ TYP(offset,4); /* file offset of this section */ TYP(align,4); /* section alignment (power of 2) */ TYP(reloff,4); /* file offset of relocation entries */ TYP(nreloc,4); /* number of relocation entries */ TYP(flags,4); /* flags (section type and attributes)*/ TYP(reserved1,4); /* reserved (for offset or index) */ TYP(reserved2,4); /* reserved (for count or sizeof) */ TYP(reserved3,4); /* reserved */ }; /* * The flags field of a section structure is separated into two parts a section * type and section attributes. The section types are mutually exclusive (it * can only have one type) but the section attributes are not (it may have more * than one attribute). */ #define SECTION_TYPE 0x000000ff /* 256 section types */ #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */ /* Constants for the type of a section */ #define S_REGULAR 0x0 /* regular section */ #define S_ZEROFILL 0x1 /* zero fill on demand section */ #define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/ #define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */ #define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */ #define S_LITERAL_POINTERS 0x5 /* section with only pointers to */ /* literals */ /* * For the two types of symbol pointers sections and the symbol stubs section * they have indirect symbol table entries. For each of the entries in the * section the indirect symbol table entries, in corresponding order in the * indirect symbol table, start at the index stored in the reserved1 field * of the section structure. Since the indirect symbol table entries * correspond to the entries in the section the number of indirect symbol table * entries is inferred from the size of the section divided by the size of the * entries in the section. For symbol pointers sections the size of the entries * in the section is 4 bytes and for symbol stubs sections the byte size of the * stubs is stored in the reserved2 field of the section structure. */ #define S_NON_LAZY_SYMBOL_POINTERS 0x6 /* section with only non-lazy symbol pointers */ #define S_LAZY_SYMBOL_POINTERS 0x7 /* section with only lazy symbol pointers */ #define S_SYMBOL_STUBS 0x8 /* section with only symbol stubs, byte size of stub in the reserved2 field */ #define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function pointers for initialization*/ #define S_MOD_TERM_FUNC_POINTERS 0xa /* section with only function pointers for termination */ #define S_COALESCED 0xb /* section contains symbols that are to be coalesced */ #define S_GB_ZEROFILL 0xc /* zero fill on demand section (that can be larger than 4 gigabytes) */ #define S_INTERPOSING 0xd /* section with only pairs of function pointers for interposing */ #define S_16BYTE_LITERALS 0xe /* section with only 16 byte literals */ #define S_DTRACE_DOF 0xf /* section contains DTrace Object Format */ #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy symbol pointers to lazy loaded dylibs */ /* * Section types to support thread local variables */ #define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial values for TLVs */ #define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial values for TLVs */ #define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */ #define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV descriptors */ #define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call to initialize TLV values */ /* * Constants for the section attributes part of the flags field of a section * structure. */ #define SECTION_ATTRIBUTES_USR 0xff000000 /* User setable attributes */ #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section contains only true machine instructions */ #define S_ATTR_NO_TOC 0x40000000 /* section contains coalesced symbols that are not to be in a ranlib table of contents */ #define S_ATTR_STRIP_STATIC_SYMS 0x20000000 /* ok to strip static symbols in this section in files with the MH_DYLDLINK flag */ #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */ #define S_ATTR_LIVE_SUPPORT 0x08000000 /* blocks are live if they reference live blocks */ #define S_ATTR_SELF_MODIFYING_CODE 0x04000000 /* Used with i386 code stubs written on by dyld */ /* * If a segment contains any sections marked with S_ATTR_DEBUG then all * sections in that segment must have this attribute. No section other than * a section marked with this attribute may reference the contents of this * section. A section with this attribute may contain no symbols and must have * a section type S_REGULAR. The static linker will not copy section contents * from sections with this attribute into its output file. These sections * generally contain DWARF debugging info. */ #define S_ATTR_DEBUG 0x02000000 /* a debug section */ #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */ #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some machine instructions */ #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */ #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */ /* * The names of segments and sections in them are mostly meaningless to the * link-editor. But there are few things to support traditional UNIX * executables that require the link-editor and assembler to use some names * agreed upon by convention. * * The initial protection of the "__TEXT" segment has write protection turned * off (not writeable). * * The link-editor will allocate common symbols at the end of the "__common" * section in the "__DATA" segment. It will create the section and segment * if needed. */ /* The currently known segment names and the section names in those segments */ #define SEG_PAGEZERO "__PAGEZERO" /* the pagezero segment which has no */ /* protections and catches NULL */ /* references for MH_EXECUTE files */ #define SEG_TEXT "__TEXT" /* the tradition UNIX text segment */ #define SECT_TEXT "__text" /* the real text part of the text */ /* section no headers, and no padding */ #define SECT_FVMLIB_INIT0 "__fvmlib_init0" /* the fvmlib initialization */ /* section */ #define SECT_FVMLIB_INIT1 "__fvmlib_init1" /* the section following the */ /* fvmlib initialization */ /* section */ #define SEG_DATA "__DATA" /* the tradition UNIX data segment */ #define SECT_DATA "__data" /* the real initialized data section */ /* no padding, no bss overlap */ #define SECT_BSS "__bss" /* the real uninitialized data section*/ /* no padding */ #define SECT_COMMON "__common" /* the section common symbols are */ /* allocated in by the link editor */ #define SEG_OBJC "__OBJC" /* objective-C runtime segment */ #define SECT_OBJC_SYMBOLS "__symbol_table" /* symbol table */ #define SECT_OBJC_MODULES "__module_info" /* module information */ #define SECT_OBJC_STRINGS "__selector_strs" /* string table */ #define SECT_OBJC_REFS "__selector_refs" /* string table */ #define SEG_ICON "__ICON" /* the icon segment */ #define SECT_ICON_HEADER "__header" /* the icon headers */ #define SECT_ICON_TIFF "__tiff" /* the icons in tiff format */ #define SEG_LINKEDIT "__LINKEDIT" /* the segment containing all structs */ /* created and maintained by the link */ /* editor. Created with -seglinkedit */ /* option to ld(1) for MH_EXECUTE and */ /* FVMLIB file types only */ #define SEG_UNIXSTACK "__UNIXSTACK" /* the unix stack segment */ #define SEG_IMPORT "__IMPORT" /* the segment for the self (dyld) */ /* modifing code stubs that has read, */ /* write and execute permissions */ /* * Fixed virtual memory shared libraries are identified by two things. The * target pathname (the name of the library as found for execution), and the * minor version number. The address of where the headers are loaded is in * header_addr. (THIS IS OBSOLETE and no longer supported). */ struct fvmlib { union lc_str name; /* library's target pathname */ TYP(minor_version,4); /* library's minor version number */ TYP(header_addr,4); /* library's header address */ }; /* * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) * contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library. * An object that uses a fixed virtual shared library also contains a * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses. * (THIS IS OBSOLETE and no longer supported). */ struct fvmlib_command { TYP(cmd,4); /* LC_IDFVMLIB or LC_LOADFVMLIB */ TYP(cmdsize,4); /* includes pathname string */ struct fvmlib fvmlib; /* the library identification */ }; /* * Dynamicly linked shared libraries are identified by two things. The * pathname (the name of the library as found for execution), and the * compatibility version number. The pathname must match and the compatibility * number in the user of the library must be greater than or equal to the * library being used. The time stamp is used to record the time a library was * built and copied into user so it can be use to determined if the library used * at runtime is exactly the same as used to built the program. */ struct dylib { union lc_str name; /* library's path name */ TYP(timestamp,4); /* library's build time stamp */ TYP(current_version,4); /* library's current version number */ TYP(compatibility_version,4); /* library's compatibility vers number*/ }; /* * A dynamically linked shared library (filetype == MH_DYLIB in the mach header) * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library. * An object that uses a dynamically linked shared library also contains a * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or * LC_REEXPORT_DYLIB) for each library it uses. */ struct dylib_command { TYP(cmd,4); /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB */ TYP(cmdsize,4); /* includes pathname string */ struct dylib dylib; /* the library identification */ }; /* * A dynamically linked shared library may be a subframework of an umbrella * framework. If so it will be linked with "-umbrella umbrella_name" where * Where "umbrella_name" is the name of the umbrella framework. A subframework * can only be linked against by its umbrella framework or other subframeworks * that are part of the same umbrella framework. Otherwise the static link * editor produces an error and states to link against the umbrella framework. * The name of the umbrella framework for subframeworks is recorded in the * following structure. */ struct sub_framework_command { TYP(cmd,4); /* LC_SUB_FRAMEWORK */ TYP(cmdsize,4); /* includes umbrella string */ union lc_str umbrella; /* the umbrella framework name */ }; /* * For dynamically linked shared libraries that are subframework of an umbrella * framework they can allow clients other than the umbrella framework or other * subframeworks in the same umbrella framework. To do this the subframework * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load * command is created for each -allowable_client flag. The client_name is * usually a framework name. It can also be a name used for bundles clients * where the bundle is built with "-client_name client_name". */ struct sub_client_command { TYP(cmd,4); /* LC_SUB_CLIENT */ TYP(cmdsize,4); /* includes client string */ union lc_str client; /* the client name */ }; /* * A dynamically linked shared library may be a sub_umbrella of an umbrella * framework. If so it will be linked with "-sub_umbrella umbrella_name" where * Where "umbrella_name" is the name of the sub_umbrella framework. When * staticly linking when -twolevel_namespace is in effect a twolevel namespace * umbrella framework will only cause its subframeworks and those frameworks * listed as sub_umbrella frameworks to be implicited linked in. Any other * dependent dynamic libraries will not be linked it when -twolevel_namespace * is in effect. The primary library recorded by the static linker when * resolving a symbol in these libraries will be the umbrella framework. * Zero or more sub_umbrella frameworks may be use by an umbrella framework. * The name of a sub_umbrella framework is recorded in the following structure. */ struct sub_umbrella_command { TYP(cmd,4); /* LC_SUB_UMBRELLA */ TYP(cmdsize,4); /* includes sub_umbrella string */ union lc_str sub_umbrella; /* the sub_umbrella framework name */ }; /* * A dynamically linked shared library may be a sub_library of another shared * library. If so it will be linked with "-sub_library library_name" where * Where "library_name" is the name of the sub_library shared library. When * staticly linking when -twolevel_namespace is in effect a twolevel namespace * shared library will only cause its subframeworks and those frameworks * listed as sub_umbrella frameworks and libraries listed as sub_libraries to * be implicited linked in. Any other dependent dynamic libraries will not be * linked it when -twolevel_namespace is in effect. The primary library * recorded by the static linker when resolving a symbol in these libraries * will be the umbrella framework (or dynamic library). Zero or more sub_library * shared libraries may be use by an umbrella framework or (or dynamic library). * The name of a sub_library framework is recorded in the following structure. * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc". */ struct sub_library_command { TYP(cmd,4); /* LC_SUB_LIBRARY */ TYP(cmdsize,4); /* includes sub_library string */ union lc_str sub_library; /* the sub_library name */ }; /* * A program (filetype == MH_EXECUTE) that is * prebound to its dynamic libraries has one of these for each library that * the static linker used in prebinding. It contains a bit vector for the * modules in the library. The bits indicate which modules are bound (1) and * which are not (0) from the library. The bit for module 0 is the low bit * of the first byte. So the bit for the Nth module is: * (linked_modules[N/8] >> N%8) & 1 */ struct prebound_dylib_command { TYP(cmd,4); /* LC_PREBOUND_DYLIB */ TYP(cmdsize,4); /* includes strings */ union lc_str name; /* library's path name */ TYP(nmodules,4); /* number of modules in library */ union lc_str linked_modules; /* bit vector of linked modules */ }; /* * A program that uses a dynamic linker contains a dylinker_command to identify * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). * A file can have at most one of these. * This struct is also used for the LC_DYLD_ENVIRONMENT load command and * contains string for dyld to treat like environment variable. */ struct dylinker_command { TYP(cmd,4); /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or LC_DYLD_ENVIRONMENT */ TYP(cmdsize,4); /* includes pathname string */ union lc_str name; /* dynamic linker's path name */ }; /* * Thread commands contain machine-specific data structures suitable for * use in the thread state primitives. The machine specific data structures * follow the struct thread_command as follows. * Each flavor of machine specific data structure is preceded by an unsigned * long constant for the flavor of that data structure, an uint32_t * that is the count of longs of the size of the state data structure and then * the state data structure follows. This triple may be repeated for many * flavors. The constants for the flavors, counts and state data structure * definitions are expected to be in the header file . * These machine specific data structures sizes must be multiples of * 4 bytes The cmdsize reflects the total size of the thread_command * and all of the sizes of the constants for the flavors, counts and state * data structures. * * For executable objects that are unix processes there will be one * thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor. * This is the same as a LC_THREAD, except that a stack is automatically * created (based on the shell's limit for the stack size). Command arguments * and environment variables are copied onto that stack. */ struct thread_command { TYP(cmd,4); /* LC_THREAD or LC_UNIXTHREAD */ TYP(cmdsize,4); /* total size of this command */ /* uint32_t flavor flavor of thread state */ /* uint32_t count count of longs in thread state */ /* struct XXX_thread_state state thread state for this flavor */ /* ... */ }; /* * The routines command contains the address of the dynamic shared library * initialization routine and an index into the module table for the module * that defines the routine. Before any modules are used from the library the * dynamic linker fully binds the module that defines the initialization routine * and then calls it. This gets called before any module initialization * routines (used for C++ static constructors) in the library. */ struct routines_command { /* for 32-bit architectures */ TYP(cmd,4); /* LC_ROUTINES */ TYP(cmdsize,4); /* total size of this command */ TYP(init_address,4); /* address of initialization routine */ TYP(init_module,4); /* index into the module table that */ /* the init routine is defined in */ TYP(reserved1,4); TYP(reserved2,4); TYP(reserved3,4); TYP(reserved4,4); TYP(reserved5,4); TYP(reserved6,4); }; /* * The 64-bit routines command. Same use as above. */ struct routines_command_64 { /* for 64-bit architectures */ TYP(cmd,4); /* LC_ROUTINES_64 */ TYP(cmdsize,4); /* total size of this command */ TYP(init_address,8); /* address of initialization routine */ TYP(init_module,8); /* index into the module table that */ /* the init routine is defined in */ TYP(reserved1,8); TYP(reserved2,8); TYP(reserved3,8); TYP(reserved4,8); TYP(reserved5,8); TYP(reserved6,8); }; /* * The symtab_command contains the offsets and sizes of the link-edit 4.3BSD * "stab" style symbol table information as described in the header files * and . */ struct symtab_command { TYP(cmd,4); /* LC_SYMTAB */ TYP(cmdsize,4); /* sizeof(struct symtab_command) */ TYP(symoff,4); /* symbol table offset */ TYP(nsyms,4); /* number of symbol table entries */ TYP(stroff,4); /* string table offset */ TYP(strsize,4); /* string table size in bytes */ }; /* * This is the second set of the symbolic information which is used to support * the data structures for the dynamically link editor. * * The original set of symbolic information in the symtab_command which contains * the symbol and string tables must also be present when this load command is * present. When this load command is present the symbol table is organized * into three groups of symbols: * local symbols (static and debugging symbols) - grouped by module * defined external symbols - grouped by module (sorted by name if not lib) * undefined external symbols (sorted by name if MH_BINDATLOAD is not set, * and in order the were seen by the static * linker if MH_BINDATLOAD is set) * In this load command there are offsets and counts to each of the three groups * of symbols. * * This load command contains a the offsets and sizes of the following new * symbolic information tables: * table of contents * module table * reference symbol table * indirect symbol table * The first three tables above (the table of contents, module table and * reference symbol table) are only present if the file is a dynamically linked * shared library. For executable and object modules, which are files * containing only one module, the information that would be in these three * tables is determined as follows: * table of contents - the defined external symbols are sorted by name * module table - the file contains only one module so everything in the * file is part of the module. * reference symbol table - is the defined and undefined external symbols * * For dynamically linked shared library files this load command also contains * offsets and sizes to the pool of relocation entries for all sections * separated into two groups: * external relocation entries * local relocation entries * For executable and object modules the relocation entries continue to hang * off the section structures. */ struct dysymtab_command { TYP(cmd,4); /* LC_DYSYMTAB */ TYP(cmdsize,4); /* sizeof(struct dysymtab_command) */ /* * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command * are grouped into the following three groups: * local symbols (further grouped by the module they are from) * defined external symbols (further grouped by the module they are from) * undefined symbols * * The local symbols are used only for debugging. The dynamic binding * process may have to use them to indicate to the debugger the local * symbols for a module that is being bound. * * The last two groups are used by the dynamic binding process to do the * binding (indirectly through the module table and the reference symbol * table when this is a dynamically linked shared library file). */ TYP(ilocalsym,4); /* index to local symbols */ TYP(nlocalsym,4); /* number of local symbols */ TYP(iextdefsym,4); /* index to externally defined symbols */ TYP(nextdefsym,4); /* number of externally defined symbols */ TYP(iundefsym,4); /* index to undefined symbols */ TYP(nundefsym,4); /* number of undefined symbols */ /* * For the for the dynamic binding process to find which module a symbol * is defined in the table of contents is used (analogous to the ranlib * structure in an archive) which maps defined external symbols to modules * they are defined in. This exists only in a dynamically linked shared * library file. For executable and object modules the defined external * symbols are sorted by name and is use as the table of contents. */ TYP(tocoff,4); /* file offset to table of contents */ TYP(ntoc,4); /* number of entries in table of contents */ /* * To support dynamic binding of "modules" (whole object files) the symbol * table must reflect the modules that the file was created from. This is * done by having a module table that has indexes and counts into the merged * tables for each module. The module structure that these two entries * refer to is described below. This exists only in a dynamically linked * shared library file. For executable and object modules the file only * contains one module so everything in the file belongs to the module. */ TYP(modtaboff,4); /* file offset to module table */ TYP(nmodtab,4); /* number of module table entries */ /* * To support dynamic module binding the module structure for each module * indicates the external references (defined and undefined) each module * makes. For each module there is an offset and a count into the * reference symbol table for the symbols that the module references. * This exists only in a dynamically linked shared library file. For * executable and object modules the defined external symbols and the * undefined external symbols indicates the external references. */ TYP(extrefsymoff,4); /* offset to referenced symbol table */ TYP(nextrefsyms,4); /* number of referenced symbol table entries */ /* * The sections that contain "symbol pointers" and "routine stubs" have * indexes and (implied counts based on the size of the section and fixed * size of the entry) into the "indirect symbol" table for each pointer * and stub. For every section of these two types the index into the * indirect symbol table is stored in the section header in the field * reserved1. An indirect symbol table entry is simply a 32bit index into * the symbol table to the symbol that the pointer or stub is referring to. * The indirect symbol table is ordered to match the entries in the section. */ TYP(indirectsymoff,4); /* file offset to the indirect symbol table */ TYP(nindirectsyms,4); /* number of indirect symbol table entries */ /* * To support relocating an individual module in a library file quickly the * external relocation entries for each module in the library need to be * accessed efficiently. Since the relocation entries can't be accessed * through the section headers for a library file they are separated into * groups of local and external entries further grouped by module. In this * case the presents of this load command who's extreloff, nextrel, * locreloff and nlocrel fields are non-zero indicates that the relocation * entries of non-merged sections are not referenced through the section * structures (and the reloff and nreloc fields in the section headers are * set to zero). * * Since the relocation entries are not accessed through the section headers * this requires the r_address field to be something other than a section * offset to identify the item to be relocated. In this case r_address is * set to the offset from the vmaddr of the first LC_SEGMENT command. * For MH_SPLIT_SEGS images r_address is set to the the offset from the * vmaddr of the first read-write LC_SEGMENT command. * * The relocation entries are grouped by module and the module table * entries have indexes and counts into them for the group of external * relocation entries for that the module. * * For sections that are merged across modules there must not be any * remaining external relocation entries for them (for merged sections * remaining relocation entries must be local). */ TYP(extreloff,4); /* offset to external relocation entries */ TYP(nextrel,4); /* number of external relocation entries */ /* * All the local relocation entries are grouped together (they are not * grouped by their module since they are only used if the object is moved * from it staticly link edited address). */ TYP(locreloff,4); /* offset to local relocation entries */ TYP(nlocrel,4); /* number of local relocation entries */ }; /* * An indirect symbol table entry is simply a 32bit index into the symbol table * to the symbol that the pointer or stub is refering to. Unless it is for a * non-lazy symbol pointer section for a defined symbol which strip(1) as * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. */ #define INDIRECT_SYMBOL_LOCAL 0x80000000 #define INDIRECT_SYMBOL_ABS 0x40000000 /* a table of contents entry */ struct dylib_table_of_contents { TYP(symbol_index,4); /* the defined external symbol (index into the symbol table) */ TYP(module_index,4); /* index into the module table this symbol is defined in */ }; /* a module table entry */ struct dylib_module { TYP(module_name,4); /* the module name (index into string table) */ TYP(iextdefsym,4); /* index into externally defined symbols */ TYP(nextdefsym,4); /* number of externally defined symbols */ TYP(irefsym,4); /* index into reference symbol table */ TYP(nrefsym,4); /* number of reference symbol table entries */ TYP(ilocalsym,4); /* index into symbols for local symbols */ TYP(nlocalsym,4); /* number of local symbols */ TYP(iextrel,4); /* index into external relocation entries */ TYP(nextrel,4); /* number of external relocation entries */ TYP(iinit_iterm,4); /* low 16 bits are the index into the init section, high 16 bits are the index into the term section */ TYP(ninit_nterm,4); /* low 16 bits are the number of init section entries, high 16 bits are the number of term section entries */ /* for this module address of the start of */ /* the (__OBJC,__module_info) section */ TYP(objc_module_info_addr,4); /* for this module size of */ /* the (__OBJC,__module_info) section */ TYP(objc_module_info_size,4); }; /* a 64-bit module table entry */ struct dylib_module_64 { TYP(module_name,4); /* the module name (index into string table) */ TYP(iextdefsym,4); /* index into externally defined symbols */ TYP(nextdefsym,4); /* number of externally defined symbols */ TYP(irefsym,4); /* index into reference symbol table */ TYP(nrefsym,4); /* number of reference symbol table entries */ TYP(ilocalsym,4); /* index into symbols for local symbols */ TYP(nlocalsym,4); /* number of local symbols */ TYP(iextrel,4); /* index into external relocation entries */ TYP(nextrel,4); /* number of external relocation entries */ TYP(iinit_iterm,4); /* low 16 bits are the index into the init section, high 16 bits are the index into the term section */ TYP(ninit_nterm,4); /* low 16 bits are the number of init section entries, high 16 bits are the number of term section entries */ TYP(objc_module_info_size,4); /* for this module size of */ /* the (__OBJC,__module_info) section */ TYP(objc_module_info_addr,8); /* for this module address of the start of */ /* the (__OBJC,__module_info) section */ }; /* * The entries in the reference symbol table are used when loading the module * (both by the static and dynamic link editors) and if the module is unloaded * or replaced. Therefore all external symbols (defined and undefined) are * listed in the module's reference table. The flags describe the type of * reference that is being made. The constants for the flags are defined in * as they are also used for symbol table entries. */ #if 0 /* dwarf readers not using this */ struct dylib_reference { UNUSED uint32_t isym:24, /* index into the symbol table */ UNUSED flags:8; /* flags to indicate the type of reference */ }; #endif /* 0 */ /* * The twolevel_hints_command contains the offset and number of hints in the * two-level namespace lookup hints table. */ struct twolevel_hints_command { TYP(cmd,4); /* LC_TWOLEVEL_HINTS */ TYP(cmdsize,4); /* sizeof(struct twolevel_hints_command) */ TYP(offset,4); /* offset to the hint table */ TYP(nhints,4); /* number of hints in the hint table */ }; /* * The entries in the two-level namespace lookup hints table are twolevel_hint * structs. These provide hints to the dynamic link editor where to start * looking for an undefined symbol in a two-level namespace image. The * isub_image field is an index into the sub-images (sub-frameworks and * sub-umbrellas list) that made up the two-level image that the undefined * symbol was found in when it was built by the static link editor. If * isub-image is 0 the the symbol is expected to be defined in library and not * in the sub-images. If isub-image is non-zero it is an index into the array * of sub-images for the umbrella with the first index in the sub-images being * 1. The array of sub-images is the ordered list of sub-images of the umbrella * that would be searched for a symbol that has the umbrella recorded as its * primary library. The table of contents index is an index into the * library's table of contents. This is used as the starting point of the * binary search or a directed linear search. */ #if 0 /* Not used by dwarf readers. */ struct twolevel_hint { UNUSED uint32_t isub_image:8, /* index into the sub images */ itoc:24; /* index into the table of contents */ }; #endif /* * The prebind_cksum_command contains the value of the original check sum for * prebound files or zero. When a prebound file is first created or modified * for other than updating its prebinding information the value of the check sum * is set to zero. When the file has it prebinding re-done and if the value of * the check sum is zero the original check sum is calculated and stored in * cksum field of this load command in the output file. If when the prebinding * is re-done and the cksum field is non-zero it is left unchanged from the * input file. */ struct prebind_cksum_command { TYP(cmd,4); /* LC_PREBIND_CKSUM */ TYP(cmdsize,4); /* sizeof(struct prebind_cksum_command) */ TYP(cksum,4); /* the check sum or zero */ }; /* * The uuid load command contains a single 128-bit unique random number that * identifies an object produced by the static link editor. */ struct uuid_command { TYP(cmd,4); /* LC_UUID */ TYP(cmdsize,4); /* sizeof(struct uuid_command) */ unsigned char uuid[16]; /* the 128-bit uuid */ }; /* * The rpath_command contains a path which at runtime should be added to * the current run path used to find @rpath prefixed dylibs. */ struct rpath_command { TYP(cmd,4); /* LC_RPATH */ TYP(cmdsize,4); /* includes string */ union lc_str path; /* path to add to run path */ }; /* * The linkedit_data_command contains the offsets and sizes of a blob * of data in the __LINKEDIT segment. */ struct linkedit_data_command { TYP(cmd,4); /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS or LC_LINKER_OPTIMIZATION_HINT. */ TYP(cmdsize,4); /* sizeof(struct linkedit_data_command) */ TYP(dataoff,4); /* file offset of data in __LINKEDIT segment */ TYP(datasize,4); /* file size of data in __LINKEDIT segment */ }; /* * The encryption_info_command contains the file offset and size of an * of an encrypted segment. */ struct encryption_info_command { TYP(cmd,4); /* LC_ENCRYPTION_INFO */ TYP(cmdsize,4); /* sizeof(struct encryption_info_command) */ TYP(cryptoff,4); /* file offset of encrypted range */ TYP(cryptsize,4); /* file size of encrypted range */ TYP(cryptid,4); /* which enryption system, 0 means not-encrypted yet */ }; /* * The encryption_info_command_64 contains the file offset and size of an * of an encrypted segment (for use in x86_64 targets). */ struct encryption_info_command_64 { TYP(cmd,4); /* LC_ENCRYPTION_INFO_64 */ TYP(cmdsize,4); /* sizeof(struct encryption_info_command_64) */ TYP(cryptoff,4); /* file offset of encrypted range */ TYP(cryptsize,4); /* file size of encrypted range */ TYP(cryptid,4); /* which enryption system, 0 means not-encrypted yet */ TYP(pad,4); /* padding to make this struct's size a multiple of 8 bytes */ }; /* * The version_min_command contains the min OS version on which this * binary was built to run. */ struct version_min_command { TYP(cmd,4); /* LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS or LC_VERSION_MIN_WATCHOS or LC_VERSION_MIN_TVOS */ TYP(cmdsize,4); /* sizeof(struct min_version_command) */ TYP(version,4); /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ TYP(sdk,4); /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ }; /* * The dyld_info_command contains the file offsets and sizes of * the new compressed form of the information dyld needs to * load the image. This information is used by dyld on Mac OS X * 10.6 and later. All information pointed to by this command * is encoded using byte streams, so no endian swapping is needed * to interpret it. */ struct dyld_info_command { TYP(cmd,4); /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ TYP(cmdsize,4); /* sizeof(struct dyld_info_command) */ /* * Dyld rebases an image whenever dyld loads it at an address different * from its preferred address. The rebase information is a stream * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. * Conceptually the rebase information is a table of tuples: * * The opcodes are a compressed way to encode the table by only * encoding when a column changes. In addition simple patterns * like "every n'th offset for m times" can be encoded in a few * bytes. */ TYP(rebase_off,4); /* file offset to rebase info */ TYP(rebase_size,4); /* size of rebase info */ /* * Dyld binds an image during the loading process, if the image * requires any pointers to be initialized to symbols in other images. * The bind information is a stream of byte sized * opcodes whose symbolic names start with BIND_OPCODE_. * Conceptually the bind information is a table of tuples: * * The opcodes are a compressed way to encode the table by only * encoding when a column changes. In addition simple patterns * like for runs of pointers initialzed to the same value can be * encoded in a few bytes. */ TYP(bind_off,4); /* file offset to binding info */ TYP(bind_size,4); /* size of binding info */ /* * Some C++ programs require dyld to unique symbols so that all * images in the process use the same copy of some code/data. * This step is done after binding. The content of the weak_bind * info is an opcode stream like the bind_info. But it is sorted * alphabetically by symbol name. This enable dyld to walk * all images with weak binding information in order and look * for collisions. If there are no collisions, dyld does * no updating. That means that some fixups are also encoded * in the bind_info. For instance, all calls to "operator new" * are first bound to libstdc++.dylib using the information * in bind_info. Then if some image overrides operator new * that is detected when the weak_bind information is processed * and the call to operator new is then rebound. */ TYP(weak_bind_off,4); /* file offset to weak binding info */ TYP(weak_bind_size,4); /* size of weak binding info */ /* * Some uses of external symbols do not need to be bound immediately. * Instead they can be lazily bound on first use. The lazy_bind * are contains a stream of BIND opcodes to bind all lazy symbols. * Normal use is that dyld ignores the lazy_bind section when * loading an image. Instead the static linker arranged for the * lazy pointer to initially point to a helper function which * pushes the offset into the lazy_bind area for the symbol * needing to be bound, then jumps to dyld which simply adds * the offset to lazy_bind_off to get the information on what * to bind. */ TYP(lazy_bind_off,4); /* file offset to lazy binding info */ TYP(lazy_bind_size,4); /* size of lazy binding infs */ /* * The symbols exported by a dylib are encoded in a trie. This * is a compact representation that factors out common prefixes. * It also reduces LINKEDIT pages in RAM because it encodes all * information (name, address, flags) in one small, contiguous range. * The export area is a stream of nodes. The first node sequentially * is the start node for the trie. * * Nodes for a symbol start with a uleb128 that is the length of * the exported symbol information for the string so far. * If there is no exported symbol, the node starts with a zero byte. * If there is exported info, it follows the length. * * First is a uleb128 containing flags. Normally, it is followed by * a uleb128 encoded offset which is location of the content named * by the symbol from the mach_header for the image. If the flags * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is * a uleb128 encoded library ordinal, then a zero terminated * UTF8 string. If the string is zero length, then the symbol * is re-export from the specified dylib with the same name. * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following * the flags is two uleb128s: the stub offset and the resolver offset. * The stub is used by non-lazy pointers. The resolver is used * by lazy pointers and must be called to get the actual address to use. * * After the optional exported symbol information is a byte of * how many edges (0-255) that this node has leaving it, * followed by each edge. * Each edge is a zero terminated UTF8 of the addition chars * in the symbol, followed by a uleb128 offset for the node that * edge points to. * */ TYP(export_off,4); /* file offset to lazy binding info */ TYP(export_size,4); /* size of lazy binding infs */ }; /* * The following are used to encode rebasing information */ #define REBASE_TYPE_POINTER 1 #define REBASE_TYPE_TEXT_ABSOLUTE32 2 #define REBASE_TYPE_TEXT_PCREL32 3 #define REBASE_OPCODE_MASK 0xF0 #define REBASE_IMMEDIATE_MASK 0x0F #define REBASE_OPCODE_DONE 0x00 #define REBASE_OPCODE_SET_TYPE_IMM 0x10 #define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20 #define REBASE_OPCODE_ADD_ADDR_ULEB 0x30 #define REBASE_OPCODE_ADD_ADDR_IMM_SCALED 0x40 #define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50 #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES 0x60 #define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB 0x70 #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB 0x80 /* * The following are used to encode binding information */ #define BIND_TYPE_POINTER 1 #define BIND_TYPE_TEXT_ABSOLUTE32 2 #define BIND_TYPE_TEXT_PCREL32 3 #define BIND_SPECIAL_DYLIB_SELF 0 #define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1 #define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 #define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 #define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 0x8 #define BIND_OPCODE_MASK 0xF0 #define BIND_IMMEDIATE_MASK 0x0F #define BIND_OPCODE_DONE 0x00 #define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM 0x10 #define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB 0x20 #define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30 #define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40 #define BIND_OPCODE_SET_TYPE_IMM 0x50 #define BIND_OPCODE_SET_ADDEND_SLEB 0x60 #define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 #define BIND_OPCODE_ADD_ADDR_ULEB 0x80 #define BIND_OPCODE_DO_BIND 0x90 #define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB 0xA0 #define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED 0xB0 #define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0xC0 /* * The following are used on the flags byte of a terminal node * in the export information. */ #define EXPORT_SYMBOL_FLAGS_KIND_MASK 0x03 #define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00 #define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL 0x01 #define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 #define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 #define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 /* * The linker_option_command contains linker options embedded in object files. */ struct linker_option_command { TYP(cmd,4); /* LC_LINKER_OPTION only used in MH_OBJECT filetypes */ TYP(cmdsize,4); TYP(count,4); /* number of strings */ /* concatenation of zero terminated UTF8 strings. Zero filled at end to align */ }; /* * The symseg_command contains the offset and size of the GNU style * symbol table information as described in the header file . * The symbol roots of the symbol segments must also be aligned properly * in the file. So the requirement of keeping the offsets aligned to a * multiple of a 4 bytes translates to the length field of the symbol * roots also being a multiple of a long. Also the padding must again be * zeroed. (THIS IS OBSOLETE and no longer supported). */ struct symseg_command { TYP(cmd,4); /* LC_SYMSEG */ TYP(cmdsize,4); /* sizeof(struct symseg_command) */ TYP(offset,4); /* symbol segment offset */ TYP(size,4); /* symbol segment size in bytes */ }; /* * The ident_command contains a free format string table following the * ident_command structure. The strings are null terminated and the size of * the command is padded out with zero bytes to a multiple of 4 bytes/ * (THIS IS OBSOLETE and no longer supported). */ struct ident_command { TYP(cmd,4); /* LC_IDENT */ TYP(cmdsize,4); /* strings that follow this command */ }; /* * The fvmfile_command contains a reference to a file to be loaded at the * specified virtual address. (Presently, this command is reserved for * internal use. The kernel ignores this command when loading a program into * memory). */ struct fvmfile_command { TYP(cmd,4); /* LC_FVMFILE */ TYP(cmdsize,4); /* includes pathname string */ union lc_str name; /* files pathname */ TYP(header_addr,4); /* files virtual address */ }; /* * The entry_point_command is a replacement for thread_command. * It is used for main executables to specify the location (file offset) * of main(). If -stack_size was used at link time, the stacksize * field will contain the stack size need for the main thread. */ struct entry_point_command { TYP(cmd,4); /* LC_MAIN only used in MH_EXECUTE filetypes */ TYP(cmdsize,4); /* 24 */ TYP(entryoff,8); /* file (__TEXT) offset of main() */ TYP(stacksize,8); /* if not zero, initial stack size */ }; /* * The source_version_command is an optional load command containing * the version of the sources used to build the binary. */ struct source_version_command { TYP(cmd,4); /* LC_SOURCE_VERSION */ TYP(cmdsize,4); /* 16 */ TYP(version,8); /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */ }; /* * The LC_DATA_IN_CODE load commands uses a linkedit_data_command * to point to an array of data_in_code_entry entries. Each entry * describes a range of data in a code section. */ struct data_in_code_entry { TYP(offset,4); /* from mach_header to start of data range*/ TYP(length,2); /* number of bytes in data range */ TYP(kind,2); /* a DICE_KIND_* value */ }; #define DICE_KIND_DATA 0x0001 #define DICE_KIND_JUMP_TABLE8 0x0002 #define DICE_KIND_JUMP_TABLE16 0x0003 #define DICE_KIND_JUMP_TABLE32 0x0004 #define DICE_KIND_ABS_JUMP_TABLE32 0x0005 /* * Sections of type S_THREAD_LOCAL_VARIABLES contain an array * of tlv_descriptor structures. */ struct tlv_descriptor { void* (*thunk)(struct tlv_descriptor*); unsigned long key; unsigned long offset; }; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MACHO_LOADER_H */ dwarfutils-20200114/libdwarf/dwarf_machoread.c000066400000000000000000000735141361531463500212160ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. cc Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file reads the parts of an Apple mach-o object file appropriate to reading DWARF debugging data. Overview: _dwarf_macho_setup() Does all macho setup. calls _dwarf_macho_access_init() calls _dwarf_macho_object_access_internals_init() Creates internals record 'M', dwarf_macho_object_access_internals_t Sets flags/data in internals record Loads macho object data needed later. Sets methods struct to access macho object. calls _dwarf_object_init_b() Creates Dwarf_Debug, independent of any macho code. Sets internals record into dbg. ---------------------- _dwarf_destruct_macho_access(). This frees the macho internals record created in _dwarf_macho_object_access_internals_init() in case of errors during setup or when dwarf_finish() is called. Works safely for partially or fully set-up macho internals record. Other than in _dwarf_macho_setup() the macho code knows nothing about Dwarf_Debug, and the rest of libdwarf knows nothing about the content of the macho internals record. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #include /* open() */ #include /* open() */ #include /* open() */ #include #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "libdwarfdefs.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "dwarf_error.h" /* for _dwarf_error() declaration */ #include "dwarf_reading.h" #include "memcpy_swap.h" #include "dwarf_object_read_common.h" #include "dwarf_machoread.h" #include "dwarf_object_detector.h" #include "dwarf_macho_loader.h" #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYPE */ #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ /* MACH-O and dwarf section names */ static struct macho_sect_names_s { char const *ms_moname; char const *ms_dwname; } const SectionNames [] = { { "", "" }, /* ELF index-0 entry */ { "__debug_abbrev", ".debug_abbrev" }, { "__debug_aranges", ".debug_aranges" }, { "__debug_frame", ".debug_frame" }, { "__debug_info", ".debug_info" }, { "__debug_line", ".debug_line" }, { "__debug_macinfo", ".debug_macinfo" }, { "__debug_loc", ".debug_loc" }, { "__debug_pubnames", ".debug_pubnames" }, { "__debug_pubtypes", ".debug_pubtypes" }, { "__debug_str", ".debug_str" }, { "__debug_ranges", ".debug_ranges" }, { "__debug_macro", ".debug_macro" }, { "__debug_gdb_scri", ".debug_gdb_scripts" } }; static int _dwarf_macho_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum); static Dwarf_Endianness macho_get_byte_order (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_endian; } static Dwarf_Small macho_get_length_size (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_offsetsize/8; } static Dwarf_Small macho_get_pointer_size (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_pointersize/8; } static Dwarf_Unsigned macho_get_section_count (void *obj) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); return macho->mo_dwarf_sectioncount; } static int macho_get_section_info (void *obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section *return_section, UNUSEDARG int *error) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); if (section_index < macho->mo_dwarf_sectioncount) { struct generic_macho_section *sp = 0; sp = macho->mo_dwarf_sections + section_index; return_section->addr = 0; return_section->type = 0; return_section->size = sp->size; return_section->name = sp->dwarfsectname; return_section->link = 0; return_section->info = 0; return_section->entrysize = 0; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int macho_load_section (void *obj, Dwarf_Half section_index, Dwarf_Small **return_data, int *error) { dwarf_macho_object_access_internals_t *macho = (dwarf_macho_object_access_internals_t*)(obj); if (0 < section_index && section_index < macho->mo_dwarf_sectioncount) { int res = 0; struct generic_macho_section *sp = macho->mo_dwarf_sections + section_index; if(sp->loaded_data) { *return_data = sp->loaded_data; return DW_DLV_OK; } if (!sp->size) { return DW_DLV_NO_ENTRY; } if ((sp->size + sp->offset) > macho->mo_filesize) { *error = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } sp->loaded_data = malloc((size_t)sp->size); if (!sp->loaded_data) { *error = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = RRMOA(macho->mo_fd, sp->loaded_data, (off_t)sp->offset, (size_t)sp->size, (off_t)macho->mo_filesize, error); if (res != DW_DLV_OK) { free(sp->loaded_data); sp->loaded_data = 0; return res; } *return_data = sp->loaded_data; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } void _dwarf_destruct_macho_access( struct Dwarf_Obj_Access_Interface_s *aip) { dwarf_macho_object_access_internals_t *mp = 0; Dwarf_Unsigned i = 0; if(!aip) { return; } mp = (dwarf_macho_object_access_internals_t *)aip->object; if (mp->mo_destruct_close_fd) { close(mp->mo_fd); mp->mo_fd = -1; } if (mp->mo_commands){ free(mp->mo_commands); mp->mo_commands = 0; } if (mp->mo_segment_commands){ free(mp->mo_segment_commands); mp->mo_segment_commands = 0; } free((char *)mp->mo_path); if (mp->mo_dwarf_sections) { struct generic_macho_section *sp = 0; sp = mp->mo_dwarf_sections; for( i=0; i < mp->mo_dwarf_sectioncount; ++i,++sp) { if (sp->loaded_data) { free(sp->loaded_data); sp->loaded_data = 0; } } free(mp->mo_dwarf_sections); mp->mo_dwarf_sections = 0; } free(mp); free(aip); return; } /* load_macho_header32(dwarf_macho_object_access_internals_t *mfp)*/ static int load_macho_header32(dwarf_macho_object_access_internals_t *mfp, int *errcode) { struct mach_header mh32; int res = 0; if (sizeof(mh32) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &mh32, 0, sizeof(mh32), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* Do not adjust endianness of magic, leave as-is. */ ASNAR(memcpy,mfp->mo_header.magic,mh32.magic); ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh32.cputype); ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype,mh32.cpusubtype); ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh32.filetype); ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh32.ncmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds,mh32.sizeofcmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh32.flags); mfp->mo_header.reserved = 0; mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds; mfp->mo_command_start_offset = sizeof(mh32); return DW_DLV_OK; } /* load_macho_header64(dwarf_macho_object_access_internals_t *mfp) */ static int load_macho_header64(dwarf_macho_object_access_internals_t *mfp, int *errcode) { struct mach_header_64 mh64; int res = 0; if (sizeof(mh64) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &mh64, 0, sizeof(mh64), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* Do not adjust endianness of magic, leave as-is. */ ASNAR(memcpy,mfp->mo_header.magic,mh64.magic); ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh64.cputype); ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype,mh64.cpusubtype); ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh64.filetype); ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh64.ncmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds,mh64.sizeofcmds); ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh64.flags); ASNAR(mfp->mo_copy_word,mfp->mo_header.reserved,mh64.reserved); mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds; mfp->mo_command_start_offset = sizeof(mh64); return DW_DLV_OK; } int dwarf_load_macho_header(dwarf_macho_object_access_internals_t *mfp, int *errcode) { int res = 0; if (mfp->mo_offsetsize == 32) { res = load_macho_header32(mfp,errcode); } else if (mfp->mo_offsetsize == 64) { res = load_macho_header64(mfp,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } return res; } static int load_segment_command_content32( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_command *mmp, struct generic_macho_segment_command *msp, Dwarf_Unsigned mmpindex, int *errcode) { struct segment_command sc; int res = 0; Dwarf_Unsigned filesize = mfp->mo_filesize; Dwarf_Unsigned segoffset = mmp->offset_this_command; Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc); if (mmp->offset_this_command > filesize || mmp->cmdsize > filesize || (mmp->cmdsize + mmp->offset_this_command) > filesize ) { *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc), (off_t)filesize, errcode); if (res != DW_DLV_OK) { return res; } ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd); ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize); strncpy(msp->segname,sc.segname,16); msp->segname[15] =0; ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr); ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize); ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff); ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize); if (msp->fileoff > mfp->mo_filesize || msp->filesize > mfp->mo_filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } if ((msp->fileoff+msp->filesize ) > filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot); ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot); ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects); ASNAR(mfp->mo_copy_word,msp->flags,sc.flags); msp->macho_command_index = mmpindex; msp->sectionsoffset = afterseghdr; return DW_DLV_OK; } static int load_segment_command_content64( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_command *mmp, struct generic_macho_segment_command *msp, Dwarf_Unsigned mmpindex,int *errcode) { struct segment_command_64 sc; int res = 0; Dwarf_Unsigned filesize = mfp->mo_filesize; Dwarf_Unsigned segoffset = mmp->offset_this_command; Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc); if (mmp->offset_this_command > filesize || mmp->cmdsize > filesize || (mmp->cmdsize + mmp->offset_this_command) > filesize ) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc), (off_t)filesize, errcode); if (res != DW_DLV_OK) { return res; } ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd); ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize); strncpy(msp->segname,sc.segname,16); msp->segname[16] =0; ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr); ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize); ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff); ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize); if (msp->fileoff > filesize || msp->filesize > filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } if ((msp->fileoff+msp->filesize ) > filesize) { /* corrupt */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot); ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot); ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects); ASNAR(mfp->mo_copy_word,msp->flags,sc.flags); msp->macho_command_index = mmpindex; msp->sectionsoffset = afterseghdr; return DW_DLV_OK; } static int dwarf_macho_load_segment_commands( dwarf_macho_object_access_internals_t *mfp,int *errcode) { Dwarf_Unsigned i = 0; struct generic_macho_command *mmp = 0; struct generic_macho_segment_command *msp = 0; if (mfp->mo_segment_count < 1) { return DW_DLV_OK; } mfp->mo_segment_commands = (struct generic_macho_segment_command *) calloc(sizeof(struct generic_macho_segment_command), (size_t)mfp->mo_segment_count); if (!mfp->mo_segment_commands) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } mmp = mfp->mo_commands; msp = mfp->mo_segment_commands; for (i = 0 ; i < mfp->mo_command_count; ++i,++mmp) { unsigned cmd = (unsigned)mmp->cmd; int res = 0; if (cmd == LC_SEGMENT) { res = load_segment_command_content32(mfp,mmp,msp,i,errcode); ++msp; } else if (cmd == LC_SEGMENT_64) { res = load_segment_command_content64(mfp,mmp,msp,i,errcode); ++msp; } if (res != DW_DLV_OK) { return res; } } return DW_DLV_OK; } static int dwarf_macho_load_dwarf_section_details32( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_segment_command *segp, Dwarf_Unsigned segi, int *errcode) { Dwarf_Unsigned seci = 0; Dwarf_Unsigned seccount = segp->nsects; Dwarf_Unsigned secalloc = seccount+1; Dwarf_Unsigned curoff = segp->sectionsoffset; Dwarf_Unsigned shdrlen = sizeof(struct section); struct generic_macho_section *secs = 0; secs = (struct generic_macho_section *)calloc( sizeof(struct generic_macho_section), (size_t)secalloc); if (!secs) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_OK; } mfp->mo_dwarf_sections = secs; mfp->mo_dwarf_sectioncount = secalloc; if ((curoff > mfp->mo_filesize) || (seccount > mfp->mo_filesize) || (curoff+(seccount*sizeof(struct section)) > mfp->mo_filesize)) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } secs->offset_of_sec_rec = curoff; /* Leave 0 section all zeros except our offset, elf-like in a sense */ secs->dwarfsectname = ""; ++secs; seci = 1; for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) { struct section mosec; int res = 0; res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } strncpy(secs->sectname,mosec.sectname,16); secs->sectname[16] = 0; strncpy(secs->segname,mosec.segname,16); secs->segname[16] = 0; ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr); ASNAR(mfp->mo_copy_word,secs->size,mosec.size); ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset); ASNAR(mfp->mo_copy_word,secs->align,mosec.align); ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff); ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc); ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags); if (secs->offset > mfp->mo_filesize || secs->size > mfp->mo_filesize || (secs->offset+secs->size) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } secs->reserved1 = 0; secs->reserved2 = 0; secs->reserved3 = 0; secs->generic_segment_num = segi; secs->offset_of_sec_rec = curoff; } return DW_DLV_OK; } static int dwarf_macho_load_dwarf_section_details64( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_segment_command *segp, Dwarf_Unsigned segi, int *errcode) { Dwarf_Unsigned seci = 0; Dwarf_Unsigned seccount = segp->nsects; Dwarf_Unsigned secalloc = seccount+1; Dwarf_Unsigned curoff = segp->sectionsoffset; Dwarf_Unsigned shdrlen = sizeof(struct section_64); struct generic_macho_section *secs = 0; secs = (struct generic_macho_section *)calloc( sizeof(struct generic_macho_section), (size_t)secalloc); if (!secs) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } mfp->mo_dwarf_sections = secs; mfp->mo_dwarf_sectioncount = secalloc; secs->offset_of_sec_rec = curoff; /* Leave 0 section all zeros except our offset, elf-like in a sense */ secs->dwarfsectname = ""; ++secs; if ((curoff > mfp->mo_filesize) || (seccount > mfp->mo_filesize) || (curoff+(seccount*sizeof(struct section_64)) > mfp->mo_filesize)) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } seci = 1; for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) { int res = 0; struct section_64 mosec; res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } strncpy(secs->sectname,mosec.sectname,16); secs->sectname[16] = 0; strncpy(secs->segname,mosec.segname,16); secs->segname[16] = 0; ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr); ASNAR(mfp->mo_copy_word,secs->size,mosec.size); ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset); ASNAR(mfp->mo_copy_word,secs->align,mosec.align); ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff); ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc); ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags); if (secs->offset > mfp->mo_filesize || secs->size > mfp->mo_filesize || (secs->offset+secs->size) > mfp->mo_filesize) { *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_OK; } secs->reserved1 = 0; secs->reserved2 = 0; secs->reserved3 = 0; secs->offset_of_sec_rec = curoff; secs->generic_segment_num = segi; } return DW_DLV_OK; } static int dwarf_macho_load_dwarf_section_details( dwarf_macho_object_access_internals_t *mfp, struct generic_macho_segment_command *segp, Dwarf_Unsigned segi,int *errcode) { int res = 0; if (mfp->mo_offsetsize == 32) { res = dwarf_macho_load_dwarf_section_details32(mfp, segp,segi,errcode); } else if (mfp->mo_offsetsize == 64) { res = dwarf_macho_load_dwarf_section_details64(mfp, segp,segi,errcode); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } return res; } static int dwarf_macho_load_dwarf_sections( dwarf_macho_object_access_internals_t *mfp,int *errcode) { Dwarf_Unsigned segi = 0; struct generic_macho_segment_command *segp = mfp->mo_segment_commands; for ( ; segi < mfp->mo_segment_count; ++segi,++segp) { int res = 0; if (strcmp(segp->segname,"__DWARF")) { continue; } /* Found DWARF, for now assume only one such. */ res = dwarf_macho_load_dwarf_section_details(mfp,segp,segi,errcode); return res; } return DW_DLV_OK; } /* Works the same, 32 or 64 bit */ int dwarf_load_macho_commands( dwarf_macho_object_access_internals_t *mfp,int *errcode) { Dwarf_Unsigned cmdi = 0; Dwarf_Unsigned curoff = mfp->mo_command_start_offset; Dwarf_Unsigned cmdspace = 0; struct load_command mc; struct generic_macho_command *mcp = 0; unsigned segment_command_count = 0; int res = 0; if (mfp->mo_command_count >= mfp->mo_filesize) { /* corrupt object. */ *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; return DW_DLV_ERROR; } if ((curoff + mfp->mo_command_count * sizeof(mc)) >= mfp->mo_filesize) { /* corrupt object. */ *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; return DW_DLV_ERROR; } mfp->mo_commands = (struct generic_macho_command *) calloc( mfp->mo_command_count,sizeof(struct generic_macho_command)); if( !mfp->mo_commands) { /* out of memory */ *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } mcp = mfp->mo_commands; for ( ; cmdi < mfp->mo_header.ncmds; ++cmdi,++mcp ) { res = RRMOA(mfp->mo_fd, &mc, (off_t)curoff, sizeof(mc), (off_t)mfp->mo_filesize, errcode); if (res != DW_DLV_OK) { return res; } ASNAR(mfp->mo_copy_word,mcp->cmd,mc.cmd); ASNAR(mfp->mo_copy_word,mcp->cmdsize,mc.cmdsize); mcp->offset_this_command = curoff; curoff += mcp->cmdsize; cmdspace += mcp->cmdsize; if (mcp->cmdsize > mfp->mo_filesize || curoff > mfp->mo_filesize) { /* corrupt object */ *errcode = DW_DLE_FILE_OFFSET_BAD; return DW_DLV_ERROR; } if (mcp->cmd == LC_SEGMENT || mcp->cmd == LC_SEGMENT_64) { segment_command_count++; } } mfp->mo_segment_count = segment_command_count; res = dwarf_macho_load_segment_commands(mfp,errcode); if (res != DW_DLV_OK) { return res; } res = dwarf_macho_load_dwarf_sections(mfp,errcode); return res; } int _dwarf_macho_setup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error) { Dwarf_Obj_Access_Interface *binary_interface = 0; dwarf_macho_object_access_internals_t *intfc = 0; int res = DW_DLV_OK; int localerrnum = 0; res = _dwarf_macho_object_access_init( fd, ftype,endian,offsetsize,filesize,access, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } _dwarf_error(NULL, error, localerrnum); return DW_DLV_ERROR; } /* allocates and initializes Dwarf_Debug, generic code */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ _dwarf_destruct_macho_access(binary_interface); return res; } intfc = binary_interface->object; intfc->mo_path = strdup(true_path); return res; } static Dwarf_Obj_Access_Methods const macho_methods = { macho_get_section_info, macho_get_byte_order, macho_get_length_size, macho_get_pointer_size, macho_get_section_count, macho_load_section, /* We do not do macho relocations. dsym files do not require it. */ NULL }; /* On any error this frees internals argument. */ static int _dwarf_macho_object_access_internals_init( dwarf_macho_object_access_internals_t * internals, int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, int *errcode) { dwarf_macho_object_access_internals_t * intfc = internals; Dwarf_Unsigned i = 0; struct generic_macho_section *sp = 0; struct Dwarf_Obj_Access_Interface_s *localdoas; int res = 0; /* Must malloc as _dwarf_destruct_macho_access() forces that due to other uses. */ localdoas = (struct Dwarf_Obj_Access_Interface_s *) malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); if (!localdoas) { free(internals); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); intfc->mo_ident[0] = 'M'; intfc->mo_ident[1] = '1'; intfc->mo_fd = fd; intfc->mo_is_64bit = ((offsetsize==64)?TRUE:FALSE); intfc->mo_offsetsize = offsetsize; intfc->mo_pointersize = offsetsize; intfc->mo_filesize = filesize; intfc->mo_ftype = ftype; #ifdef WORDS_BIGENDIAN if (endian == DW_ENDIAN_LITTLE ) { intfc->mo_copy_word = _dwarf_memcpy_swap_bytes; intfc->mo_endian = DW_OBJECT_LSB; } else { intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes; intfc->mo_endian = DW_OBJECT_MSB; } #else /* LITTLE ENDIAN */ if (endian == DW_ENDIAN_LITTLE ) { intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes; intfc->mo_endian = DW_OBJECT_LSB; } else { intfc->mo_copy_word = _dwarf_memcpy_swap_bytes; intfc->mo_endian = DW_OBJECT_MSB; } #endif /* LITTLE- BIG-ENDIAN */ res = dwarf_load_macho_header(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_macho_access(localdoas); return res; } /* Load sections */ res = dwarf_load_macho_commands(intfc,errcode); if (res != DW_DLV_OK) { localdoas->methods = 0; localdoas->object = intfc; _dwarf_destruct_macho_access(localdoas); return res; } sp = intfc->mo_dwarf_sections+1; for(i = 1; i < intfc->mo_dwarf_sectioncount ; ++i,++sp) { int j = 1; int lim = sizeof(SectionNames)/sizeof(SectionNames[0]); sp->dwarfsectname = ""; for( ; j < lim; ++j) { if(!strcmp(sp->sectname,SectionNames[j].ms_moname)) { sp->dwarfsectname = SectionNames[j].ms_dwname; break; } } } free(localdoas); return DW_DLV_OK; } static int _dwarf_macho_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum) { int res = 0; dwarf_macho_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_macho_object_access_internals_t)); if (!internals) { *localerrnum = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = _dwarf_macho_object_access_internals_init(internals, fd, ftype, endian, offsetsize, filesize, access, localerrnum); if (res != DW_DLV_OK){ /* *err is already set and the call freed internals. */ return DW_DLV_ERROR; } intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ free(internals); *localerrnum = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &macho_methods; *binary_interface = intfc; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_machoread.h000066400000000000000000000105461361531463500212170ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_MACHOREAD_H #define DWARF_MACHOREAD_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct generic_macho_header { Dwarf_Unsigned magic; Dwarf_Unsigned cputype; Dwarf_Unsigned cpusubtype; Dwarf_Unsigned filetype; Dwarf_Unsigned ncmds; /* number of load commands */ Dwarf_Unsigned sizeofcmds; /* the size of all the load commands */ Dwarf_Unsigned flags; Dwarf_Unsigned reserved; }; struct generic_macho_command { Dwarf_Unsigned cmd; Dwarf_Unsigned cmdsize; Dwarf_Unsigned offset_this_command; }; struct generic_macho_segment_command { Dwarf_Unsigned cmd; Dwarf_Unsigned cmdsize; char segname[24]; Dwarf_Unsigned vmaddr; Dwarf_Unsigned vmsize; Dwarf_Unsigned fileoff; Dwarf_Unsigned filesize; Dwarf_Unsigned maxprot; Dwarf_Unsigned initprot; Dwarf_Unsigned nsects; Dwarf_Unsigned flags; /* our index into mo_commands */ Dwarf_Unsigned macho_command_index; Dwarf_Unsigned sectionsoffset; }; struct generic_macho_section { /* Larger than in file, room for NUL guaranteed */ char sectname[24]; char segname[24]; const char * dwarfsectname; Dwarf_Unsigned addr; Dwarf_Unsigned size; Dwarf_Unsigned offset; Dwarf_Unsigned align; Dwarf_Unsigned reloff; Dwarf_Unsigned nreloc; Dwarf_Unsigned flags; Dwarf_Unsigned reserved1; Dwarf_Unsigned reserved2; Dwarf_Unsigned reserved3; Dwarf_Unsigned generic_segment_num; Dwarf_Unsigned offset_of_sec_rec; Dwarf_Small* loaded_data; }; /* ident[0] == 'M' means this is a macho header. ident[1] will be 1 indicating version 1. Other bytes in ident not defined, should be zero. */ typedef struct dwarf_macho_filedata_s { char mo_ident[8]; const char * mo_path; /* libdwarf must free.*/ int mo_fd; int mo_destruct_close_fd; /*aka: lib owns fd */ int mo_is_64bit; Dwarf_Unsigned mo_filesize; Dwarf_Small mo_offsetsize; /* 32 or 64 section data */ Dwarf_Small mo_pointersize; int mo_ftype; Dwarf_Endianness mo_endian; /*Dwarf_Small mo_machine; */ void (*mo_copy_word) (void *, const void *, unsigned long); /* Used to hold 32 and 64 header data */ struct generic_macho_header mo_header; unsigned mo_command_count; Dwarf_Unsigned mo_command_start_offset; struct generic_macho_command *mo_commands; Dwarf_Unsigned mo_offset_after_commands; Dwarf_Unsigned mo_segment_count; struct generic_macho_segment_command *mo_segment_commands; Dwarf_Unsigned mo_dwarf_sectioncount; struct generic_macho_section *mo_dwarf_sections; } dwarf_macho_object_access_internals_t; int dwarf_load_macho_header(dwarf_macho_object_access_internals_t * mfp, int *errcode); int dwarf_load_macho_commands(dwarf_macho_object_access_internals_t * mfp, int *errcode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_MACHOREAD_H */ dwarfutils-20200114/libdwarf/dwarf_macro.c000066400000000000000000000373771361531463500204030ustar00rootroot00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_macro.h" #define LEFTPAREN '(' #define RIGHTPAREN ')' #define SPACE ' ' /* Given the dwarf macro string, return a pointer to the value. Returns pointer to 0 byte at end of string if no value found (meaning the value is the empty string). Only understands well-formed dwarf macinfo strings. */ char * dwarf_find_macro_value_start(char *str) { char *lcp; int funclike = 0; for (lcp = str; *lcp; ++lcp) { switch (*lcp) { case LEFTPAREN: funclike = 1; break; case RIGHTPAREN: /* lcp+1 must be a space, and following char is the value */ return lcp + 2; case SPACE: /* We allow extraneous spaces inside macro parameter ** list, just in case... This is not really needed. */ if (!funclike) { return lcp + 1; } break; } } /* Never found value: returns pointer to the 0 byte at end of string. */ return lcp; } /* Try to keep fileindex correct in every Macro_Details record by tracking file starts and ends. Uses high water mark: space reused, not freed. Presumption is that this makes sense for most uses. STARTERMAX is set so that the array need not be expanded for most files: it is the initial include file depth. */ struct macro_stack_s { Dwarf_Signed *st_base; long st_max; long st_next_to_use; int st_was_fault; }; static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms); static void free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms) { dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING); _dwarf_reset_index_macro_stack(ms); } #define STARTERMAX 10 static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms) { ms->st_base = 0; ms->st_max = 0; ms->st_next_to_use = 0; ms->st_was_fault = 0; } static int _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx, struct macro_stack_s *ms) { if (!ms->st_max || ms->st_next_to_use >= ms->st_max) { long new_size = ms->st_max; Dwarf_Signed *newbase = 0; if (!new_size) { new_size = STARTERMAX; } new_size = new_size * 2; newbase = (Dwarf_Signed *)_dwarf_get_alloc(dbg, DW_DLA_STRING, new_size * sizeof(Dwarf_Signed)); if (!newbase) { /* just leave the old array in place */ ms->st_was_fault = 1; return DW_DLV_ERROR; } if (ms->st_base) { memcpy(newbase, ms->st_base, ms->st_next_to_use * sizeof(Dwarf_Signed)); dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING); } ms->st_base = newbase; ms->st_max = new_size; } ms->st_base[ms->st_next_to_use] = indx; ++ms->st_next_to_use; return DW_DLV_OK; } static Dwarf_Signed _dwarf_macro_stack_pop_index(struct macro_stack_s *ms) { if (ms->st_was_fault) { return -1; } if (ms->st_next_to_use > 0) { ms->st_next_to_use--; return (ms->st_base[ms->st_next_to_use]); } else { ms->st_was_fault = 1; } return -1; } /* Starting at macro_offset in .debug_macinfo, if maximum_count is 0, treat as if it is infinite. get macro data up thru maximum_count entries or the end of a compilation unit's entries (whichever comes first). .debug_macinfo never appears in a .dwp Package File. So offset adjustment for such is not needed. */ int dwarf_get_macro_details(Dwarf_Debug dbg, Dwarf_Off macro_offset, Dwarf_Unsigned maximum_count, Dwarf_Signed * entry_count, Dwarf_Macro_Details ** details, Dwarf_Error * error) { Dwarf_Small *macro_base = 0; Dwarf_Small *macro_end = 0; Dwarf_Small *pnext = 0; Dwarf_Unsigned endloc = 0; unsigned char uc = 0; unsigned long depth = 0; /* By section 6.3.2 Dwarf3 draft 8/9, the base file should appear as DW_MACINFO_start_file. See http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html on "[Bug debug/20253] New: [3.4/4.0 regression]: Macro debug info broken due to lexer change" for how gcc is broken in some versions. We no longer use depth as a stopping point, it's not needed as a stopping point anyway. */ int res = 0; /* count space used by strings */ unsigned long str_space = 0; int done = 0; unsigned long space_needed = 0; unsigned long string_offset = 0; Dwarf_Small *return_data = 0; Dwarf_Small *pdata = 0; unsigned long final_count = 0; Dwarf_Signed fileindex = -1; Dwarf_Small *latest_str_loc = 0; struct macro_stack_s msdata; unsigned long count = 0; unsigned long max_count = (unsigned long) maximum_count; _dwarf_reset_index_macro_stack(&msdata); if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); free_macro_stack(dbg,&msdata); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_macinfo,error); if (res != DW_DLV_OK) { free_macro_stack(dbg,&msdata); return res; } if (!dbg->de_debug_abbrev.dss_size) { free_macro_stack(dbg,&msdata); return (DW_DLV_NO_ENTRY); } macro_base = dbg->de_debug_macinfo.dss_data; if (macro_base == NULL) { free_macro_stack(dbg,&msdata); return (DW_DLV_NO_ENTRY); } if (macro_offset >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); return (DW_DLV_NO_ENTRY); } macro_end = macro_base + dbg->de_debug_macinfo.dss_size; /* FIXME debugfission is NOT handled here. */ pnext = macro_base + macro_offset; if (maximum_count == 0) { max_count = ULONG_MAX; } /* how many entries and how much space will they take? */ endloc = (pnext - macro_base); if (endloc >= dbg->de_debug_macinfo.dss_size) { if (endloc == dbg->de_debug_macinfo.dss_size) { /* normal: found last entry */ free_macro_stack(dbg,&msdata); return DW_DLV_NO_ENTRY; } _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); free_macro_stack(dbg,&msdata); return (DW_DLV_ERROR); } for (count = 0; !done && count < max_count; ++count) { unsigned long slen = 0; /* Set but not used */ UNUSEDARG Dwarf_Unsigned utemp = 0; uc = *pnext; ++pnext; /* get past the type code */ switch (uc) { case DW_MACINFO_define: case DW_MACINFO_undef: /* line, string */ case DW_MACINFO_vendor_ext: /* number, string */ DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, macro_end); if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } res = _dwarf_check_string_valid(dbg, macro_base,pnext,macro_end, DW_DLE_MACINFO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } slen = strlen((char *) pnext) + 1; pnext += slen; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } str_space += slen; break; case DW_MACINFO_start_file: /* line, file index */ DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, macro_end); if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, macro_end); if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } ++depth; break; case DW_MACINFO_end_file: if (--depth == 0) { /* done = 1; no, do not stop here, at least one gcc had the wrong depth settings in the gcc 3.4 timeframe. */ } /* no string or number here */ break; case 0: /* end of cu's entries */ done = 1; break; default: free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); /* bogus macinfo! */ } endloc = (pnext - macro_base); if (endloc == dbg->de_debug_macinfo.dss_size) { done = 1; } else if (endloc > dbg->de_debug_macinfo.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); free_macro_stack(dbg,&msdata); return (DW_DLV_ERROR); } } /* ASSERT: The above loop will never let us get here with count < 1. No need to test for a zero count. We have 'count' array entries to allocate and str_space bytes of string space to provide for. */ string_offset = count * sizeof(Dwarf_Macro_Details); /* extra 2 not really needed */ space_needed = string_offset + str_space + 2; return_data = pdata = (Dwarf_Small *)_dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed); latest_str_loc = pdata + string_offset; if (pdata == 0) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE); return (DW_DLV_ERROR); } pnext = macro_base + macro_offset; done = 0; /* A series ends with a type code of 0. */ for (final_count = 0; !done && final_count < count; ++final_count) { unsigned long slen = 0; Dwarf_Unsigned v1 = 0; Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata + (final_count * sizeof (Dwarf_Macro_Details))); endloc = (pnext - macro_base); if (endloc > dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD); return (DW_DLV_ERROR); } uc = *pnext; pdmd->dmd_offset = (pnext - macro_base); pdmd->dmd_type = uc; pdmd->dmd_fileindex = fileindex; pdmd->dmd_lineno = 0; pdmd->dmd_macro = 0; ++pnext; /* get past the type code */ switch (uc) { case DW_MACINFO_define: case DW_MACINFO_undef: /* line, string */ case DW_MACINFO_vendor_ext: /* number, string */ DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, macro_end); pdmd->dmd_lineno = v1; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } res = _dwarf_check_string_valid(dbg, macro_base,pnext,macro_end, DW_DLE_MACINFO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } slen = strlen((char *) pnext) + 1; strcpy((char *) latest_str_loc, (char *) pnext); pdmd->dmd_macro = (char *) latest_str_loc; latest_str_loc += slen; pnext += slen; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } break; case DW_MACINFO_start_file: /* Line, file index */ DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, macro_end); pdmd->dmd_lineno = v1; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, macro_end); pdmd->dmd_fileindex = v1; (void) _dwarf_macro_stack_push_index(dbg, fileindex, &msdata); /* We ignore the error, we just let fileindex ** be -1 when we pop this one. */ fileindex = v1; if (((Dwarf_Unsigned)(pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } break; case DW_MACINFO_end_file: fileindex = _dwarf_macro_stack_pop_index(&msdata); break; /* no string or number here */ case 0: /* Type code of 0 means the end of cu's entries. */ done = 1; break; default: /* Bogus macinfo! */ dwarf_dealloc(dbg, return_data, DW_DLA_STRING); free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } } *entry_count = count; *details = (Dwarf_Macro_Details *) return_data; free_macro_stack(dbg,&msdata); return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_macro.h000066400000000000000000000022171361531463500203710ustar00rootroot00000000000000/* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* dwarf_macro.h $Revision: 1.4 $ $Date: 2004/10/28 22:19:14 $ */ dwarfutils-20200114/libdwarf/dwarf_macro5.c000066400000000000000000001403521361531463500204540ustar00rootroot00000000000000/* Copyright (C) 2015-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_macro5.h" #define TRUE 1 #define FALSE 0 /* Section 6.3: Macro Information: Each macro unit ends with an entry containing an opcode of 0. */ static const Dwarf_Small dwarf_udata_string_form[] = {DW_FORM_udata,DW_FORM_string}; static const Dwarf_Small dwarf_udata_udata_form[] = {DW_FORM_udata,DW_FORM_udata}; static const Dwarf_Small dwarf_udata_strp_form[] = {DW_FORM_udata,DW_FORM_strp}; static const Dwarf_Small dwarf_udata_strp_sup_form[] = {DW_FORM_udata,DW_FORM_strp_sup}; static const Dwarf_Small dwarf_secoffset_form[] = {DW_FORM_sec_offset}; static const Dwarf_Small dwarf_udata_strx_form[] = {DW_FORM_udata,DW_FORM_strx}; struct Dwarf_Macro_Forms_s dw5formsarray[] = { {0,0,0}, {DW_MACRO_define,2,dwarf_udata_string_form}, {DW_MACRO_undef,2,dwarf_udata_string_form}, {DW_MACRO_start_file,2,dwarf_udata_udata_form}, {DW_MACRO_end_file,0,0}, {DW_MACRO_define_strp,2,dwarf_udata_strp_form}, {DW_MACRO_undef_strp,2,dwarf_udata_strp_form}, {DW_MACRO_import,1,dwarf_secoffset_form}, {DW_MACRO_define_sup,2,dwarf_udata_strp_sup_form}, {DW_MACRO_undef_sup,2,dwarf_udata_strp_sup_form}, {DW_MACRO_import_sup,1,dwarf_secoffset_form}, {DW_MACRO_define_strx,2,dwarf_udata_strx_form}, {DW_MACRO_undef_strx,2,dwarf_udata_strx_form}, }; /* Represents DWARF 5 macro info */ /* .debug_macro predefined, in order by value */ static const struct Dwarf_Macro_OperationsList_s dwarf_default_macro_opslist = { 13, dw5formsarray }; static int _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned *macro_ops_count_out, Dwarf_Unsigned *macro_ops_data_length, char **srcfiles, Dwarf_Signed srcfilescount, const char *comp_dir, const char *comp_name, Dwarf_CU_Context cu_context, Dwarf_Error * error); static int _dwarf_internal_macro_context(Dwarf_Die die, Dwarf_Bool offset_specified, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned *macro_unit_offset_out, Dwarf_Unsigned *macro_ops_count_out, Dwarf_Unsigned *macro_ops_data_length, Dwarf_Error * error); static int is_std_moperator(Dwarf_Small op) { if (op >= 1 && op <= DW_MACRO_undef_strx) { return TRUE; } return FALSE; } static int _dwarf_skim_forms(Dwarf_Debug dbg, Dwarf_Macro_Context mcontext, Dwarf_Small *mdata_start, unsigned formcount, const Dwarf_Small *forms, Dwarf_Small *section_end, Dwarf_Unsigned *forms_length, Dwarf_Error *error) { unsigned i = 0; Dwarf_Small curform = 0 ; Dwarf_Unsigned totallen = 0; Dwarf_Unsigned v = 0; Dwarf_Unsigned ret_value = 0; Dwarf_Unsigned length; Dwarf_Small *mdata = mdata_start; Dwarf_Unsigned leb128_length = 0; for( ; i < formcount; ++i) { curform = forms[i]; if (mdata >= section_end) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } switch(curform) { default: _dwarf_error(dbg,error,DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE); return DW_DLV_ERROR; case DW_FORM_block1: v = *(Dwarf_Small *) mdata; totallen += v+1; mdata += v+1; break; case DW_FORM_block2: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, mdata, DWARF_HALF_SIZE, error,section_end); v = ret_value + DWARF_HALF_SIZE; totallen += v; mdata += v; break; case DW_FORM_block4: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, mdata, DWARF_32BIT_SIZE, error,section_end); v = ret_value + DWARF_32BIT_SIZE; totallen += v; mdata += v; break; case DW_FORM_data1: v = 1; totallen += v; mdata += v; break; case DW_FORM_data2: v = 2; totallen += v; mdata += v; break; case DW_FORM_data4: v = 4; totallen += v; mdata += v; break; case DW_FORM_data8: v = 8; totallen += v; mdata += v; break; case DW_FORM_data16: v = 8; totallen += v; mdata += v; break; case DW_FORM_string: { int res = _dwarf_check_string_valid(dbg, mdata,mdata, section_end, DW_DLE_MACRO_STRING_BAD,error); if(res != DW_DLV_OK) { return res; } v = strlen((char *) mdata) + 1; totallen += v; mdata += v; } break; case DW_FORM_block: DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); v = length + leb128_length; totallen += v; break; case DW_FORM_flag: v = 1; totallen += v; mdata += v; break; case DW_FORM_sec_offset: /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */ v = mcontext->mc_offset_size; totallen += v; mdata += v; break; case DW_FORM_sdata: /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); totallen += v; break; case DW_FORM_strx: DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); totallen += leb128_length;; break; case DW_FORM_strp: v = mcontext->mc_offset_size; mdata += v; totallen += v; break; case DW_FORM_udata: /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, dbg, error,section_end); totallen += leb128_length; break; } } if (mdata > section_end) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } *forms_length = totallen; return DW_DLV_OK; } #if 0 /* FOR DEBUGGING */ static void dump_bytes(Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; unsigned pos = 0; printf("dump %ld bytes, start at 0x%lx\n",len,(unsigned long)start); printf("0x"); for (; cur < end;pos++, cur++) { if (!(pos %4)) { printf(" "); } printf("%02x",*cur); } printf("\n"); } Dwarf_Bool is_defundef(unsigned op) { switch(op){ case DW_MACRO_define: case DW_MACRO_undef: case DW_MACRO_define_strp: case DW_MACRO_undef_strp: case DW_MACRO_define_strx: case DW_MACRO_undef_strx: case DW_MACRO_define_sup: case DW_MACRO_undef_sup: return TRUE; } return FALSE; } #endif /* FOR DEBUGGING */ /* On first call (for this macro_context), build_ops_array is FALSE. On second, it is TRUE and we know the count so we allocate and fill in the ops array. */ static int _dwarf_get_macro_ops_count_internal(Dwarf_Macro_Context macro_context, Dwarf_Bool build_ops_array, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Small *mdata = 0; Dwarf_Small *section_end = 0; Dwarf_Small *section_base = 0; Dwarf_Unsigned opcount = 0; Dwarf_Unsigned known_ops_count = 0; struct Dwarf_Macro_Operator_s *opsarray = 0; struct Dwarf_Macro_Operator_s *curopsentry = 0; int res = 0; dbg = macro_context->mc_dbg; if (build_ops_array) { known_ops_count = macro_context->mc_macro_ops_count; opsarray = (struct Dwarf_Macro_Operator_s *) calloc(known_ops_count,sizeof(struct Dwarf_Macro_Operator_s)); if(!opsarray) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curopsentry = opsarray; macro_context->mc_ops = opsarray; } section_base = dbg->de_debug_macro.dss_data; section_end = section_base + dbg->de_debug_macro.dss_size; mdata = macro_context->mc_macro_ops; while (mdata < section_end) { Dwarf_Small op = 0; op = *mdata; ++opcount; ++mdata; if (!op) { Dwarf_Unsigned opslen = 0; /* End of ops, this is terminator, count the ending 0 as an operator so dwarfdump can print it. */ opslen = mdata - macro_context->mc_macro_ops; macro_context->mc_macro_ops_count = opcount; macro_context->mc_ops_data_length = opslen; macro_context->mc_total_length = opslen + macro_context->mc_macro_header_length; return DW_DLV_OK; } if (is_std_moperator(op)) { struct Dwarf_Macro_Forms_s * ourform = dw5formsarray + op; /* ASSERT: op == ourform->mf_code */ unsigned formcount = ourform->mf_formcount; const Dwarf_Small *forms = ourform->mf_formbytes; Dwarf_Unsigned forms_length = 0; res = _dwarf_skim_forms(dbg,macro_context,mdata, formcount,forms, section_end, &forms_length,error); if ( res != DW_DLV_OK) { return res; } if(build_ops_array) { curopsentry->mo_opcode = op; curopsentry->mo_form = ourform; curopsentry->mo_data = mdata; } mdata += forms_length; } else { /* FIXME Add support for user defined ops. */ _dwarf_error(dbg, error, DW_DLE_MACRO_OP_UNHANDLED); return DW_DLV_ERROR; } if (mdata > section_end) { _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); return DW_DLV_ERROR; } if (build_ops_array) { curopsentry++; } } _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); return DW_DLV_ERROR; } int dwarf_get_macro_op(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * op_start_section_offset, Dwarf_Half * macro_operator, Dwarf_Half * forms_count, const Dwarf_Small ** formcode_array, Dwarf_Error *error) { struct Dwarf_Macro_Operator_s *curop = 0; Dwarf_Debug dbg = 0; if (!macro_context || macro_context->mc_sentinel != 0xada) { if(macro_context) { dbg = macro_context->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } curop = macro_context->mc_ops + op_number; /* ASSERT: *op_start_section_offset == (curop->mo_data -1) - dbg->de_debug_macro.dss_data */ *op_start_section_offset = ((curop->mo_data -1) - macro_context->mc_macro_header) + macro_context->mc_section_offset; *macro_operator = curop->mo_opcode; if (curop->mo_form) { *forms_count = curop->mo_form->mf_formcount; *formcode_array = curop->mo_form->mf_formbytes; } else { /* ASSERT: macro_operator == 0 */ *forms_count = 0; *formcode_array = 0; } return DW_DLV_OK; } /* Here a DW_DLV_NO_ENTRY return means the macro operator is not a def/undef operator. */ int dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * index, Dwarf_Unsigned * offset, Dwarf_Half * forms_count, const char ** macro_string, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Small *mdata = 0; int res = 0; Dwarf_Small *startptr = 0; Dwarf_Small *endptr = 0; Dwarf_Half lformscount = 0; struct Dwarf_Macro_Operator_s *curop = 0; unsigned macop = 0; if (!macro_context || macro_context->mc_sentinel != 0xada) { if(macro_context) { dbg = macro_context->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } curop = macro_context->mc_ops + op_number; macop = curop->mo_opcode; startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; mdata = curop->mo_data; lformscount = curop->mo_form->mf_formcount; if (lformscount != 2) { /*_dwarf_error(dbg, error,DW_DLE_MACRO_OPCODE_FORM_BAD);*/ return DW_DLV_NO_ENTRY; } switch(macop){ case DW_MACRO_define: case DW_MACRO_undef: { Dwarf_Unsigned linenum = 0; const char * content = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); content = (const char *)mdata; res = _dwarf_check_string_valid(dbg, startptr,mdata, endptr, DW_DLE_MACRO_STRING_BAD,error); if(res != DW_DLV_OK) { return res; } *line_number = linenum; *index = 0; *offset = 0; *forms_count = lformscount; *macro_string = content; } return DW_DLV_OK; case DW_MACRO_define_strp: case DW_MACRO_undef_strp: { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned stringoffset = 0; Dwarf_Small form1 = curop->mo_form->mf_formbytes[1]; char * localstr = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); READ_UNALIGNED_CK(dbg,stringoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); res = _dwarf_extract_local_debug_str_string_given_offset(dbg, form1, stringoffset, &localstr, error); *index = 0; *line_number = linenum; *offset = stringoffset; *forms_count = lformscount; if (res == DW_DLV_ERROR) { *macro_string = ""; return res; } else if (res == DW_DLV_NO_ENTRY) { *macro_string = ""; } else { *macro_string = (const char *)localstr; } } return DW_DLV_OK; case DW_MACRO_define_strx: case DW_MACRO_undef_strx: { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned stringindex = 0; Dwarf_Unsigned offsettostr= 0; int ress = 0; Dwarf_Byte_Ptr mdata_copy = 0; Dwarf_Small form1 = curop->mo_form->mf_formbytes[1]; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); *line_number = linenum; mdata_copy = mdata; DECODE_LEB128_UWORD_CK(mdata_copy,stringindex, dbg, error,endptr); /* mdata_copy is for call below */ *index = stringindex; *forms_count = lformscount; /* Redoes the index-getting. Gets offset. */ ress = _dwarf_extract_string_offset_via_str_offsets(dbg, mdata_copy, endptr, DW_AT_macros, /*arbitrary, unused by called routine. */ form1, macro_context->mc_cu_context, &offsettostr, error); if (ress == DW_DLV_ERROR) { return ress; } if (ress == DW_DLV_OK) { char *localstr = 0; *index = stringindex; *offset = offsettostr; ress = _dwarf_extract_local_debug_str_string_given_offset(dbg, form1, offsettostr, &localstr, error); if(ress == DW_DLV_ERROR) { return ress; } else if (ress == DW_DLV_NO_ENTRY){ *macro_string = "<:No string available>"; } else { *macro_string = (const char *)localstr; /* All is ok. */ } } else { *index = stringindex; *offset = 0; *macro_string = "<.debug_str_offsets not available>"; } } return DW_DLV_OK; case DW_MACRO_define_sup: case DW_MACRO_undef_sup: { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned supoffset = 0; char *localstring = 0; int resup = 0; Dwarf_Error lerr = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); *line_number = linenum; *index = 0; *offset = supoffset; *forms_count = lformscount; resup = _dwarf_get_string_from_tied(dbg, supoffset, &localstring, &lerr); if (resup != DW_DLV_OK) { if (resup == DW_DLV_ERROR) { int myerrno = dwarf_errno(lerr); if(myerrno == DW_DLE_NO_TIED_FILE_AVAILABLE) { *macro_string = (char *)""; } else { _dwarf_error(dbg,error,myerrno); *macro_string = (char *)""; } dwarf_dealloc(dbg,lerr,DW_DLA_ERROR); } else { *macro_string = ""; } return resup; } *macro_string = (const char *)localstring; /* If NO ENTRY available, return DW_DLV_NO_ENTRY. We suspect this is better than DW_DLV_OK. */ return resup; } default: _dwarf_error(dbg,error,DW_DLE_MACRO_OP_UNHANDLED); return DW_DLV_ERROR; } return DW_DLV_NO_ENTRY; } /* ASSERT: we elsewhere guarantee room to copy into. If trimtarg ==1, trim trailing slash in targ. Caller should not pass in 'src' with leading / */ static void specialcat(char *targ,char *src,int trimtarg) { char *last = 0; while( *targ) { last = targ; targ++; } /* TARG now points at terminating NUL */ /* LAST points at final character in targ. */ if (trimtarg ) { if(last && *last == '/') { /* Truncate. */ *last = 0; targ = last; /* TARG again points at terminating NUL */ } } while (*src) { *targ = *src; targ++; src++; } *targ = 0; } /* If returns NULL caller must handle it. */ static const char * construct_from_dir_and_name(const char *dir, const char *name) { int truelen = 0; char *final = 0; /* Allow for NUL char and added / */ truelen = strlen(dir) + strlen(name) + 1 +1; final = (char *)malloc(truelen); if(!final) { return NULL; } final[0] = 0; specialcat(final,(char *)dir,1); strcat(final,"/"); specialcat(final,(char *)name,0); return final; } /* If returns NULL caller must handle it. */ static const char * construct_at_path_from_parts(Dwarf_Macro_Context mc) { if (mc->mc_file_path) { return mc->mc_file_path; } if(!mc->mc_at_comp_dir || !mc->mc_at_comp_dir[0]) { return mc->mc_at_name; } if (!mc->mc_at_name || !mc->mc_at_name[0]) { return NULL; } if(_dwarf_file_name_is_full_path((Dwarf_Small *)mc->mc_at_name)) { return mc->mc_at_name; } /* Dwarf_Macro_Context destructor will free this. */ mc->mc_file_path = construct_from_dir_and_name( mc->mc_at_comp_dir,mc->mc_at_name); return mc->mc_file_path; } int dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * name_index_to_line_tab, const char ** src_file_name, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_Small *mdata = 0; unsigned macop = 0; struct Dwarf_Macro_Operator_s *curop = 0; Dwarf_Byte_Ptr startptr = 0; Dwarf_Byte_Ptr endptr = 0; if (!macro_context || macro_context->mc_sentinel != 0xada) { if(macro_context) { dbg = macro_context->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; curop = macro_context->mc_ops + op_number; macop = curop->mo_opcode; mdata = curop->mo_data; if (macop != DW_MACRO_start_file && macop != DW_MACRO_end_file) { return DW_DLV_NO_ENTRY; } if (macop == DW_MACRO_start_file) { Dwarf_Unsigned linenum = 0; Dwarf_Unsigned srcindex = 0; Dwarf_Signed trueindex = 0; DECODE_LEB128_UWORD_CK(mdata,linenum, dbg, error,endptr); DECODE_LEB128_UWORD_CK(mdata,srcindex, dbg, error,endptr); *line_number = linenum; *name_index_to_line_tab = srcindex; /* For DWARF 2,3,4, decrement by 1. FOR DWARF 5 do not decrement. */ if(macro_context->mc_version_number >= 5) { trueindex = srcindex; if (trueindex < 0) { *src_file_name = ""; return DW_DLV_OK; } if (trueindex < macro_context->mc_srcfiles_count) { *src_file_name = macro_context->mc_srcfiles[trueindex]; return DW_DLV_OK; } else { *src_file_name = ""; return DW_DLV_OK; } } else { /* Unsigned to signed here. */ trueindex = srcindex; /* Protects against crazy big srcindex, overflow territory. */ if (trueindex < 0 ) { /* Something insane here. */ *src_file_name = ""; return DW_DLV_OK; } /* Protects against crazy big srcindex, overflow territory. */ if (trueindex > (macro_context->mc_srcfiles_count+1)) { /* Something insane here. */ *src_file_name = ""; return DW_DLV_OK; } --trueindex; if (trueindex > macro_context->mc_srcfiles_count) { *src_file_name = ""; } if (srcindex > 0 && trueindex < macro_context->mc_srcfiles_count) { *src_file_name = macro_context->mc_srcfiles[trueindex]; } else { const char *mcatcomp = construct_at_path_from_parts( macro_context); if(mcatcomp) { *src_file_name = mcatcomp; } else { *src_file_name = ""; } } } } else { /* DW_MACRO_end_file. No operands. */ } return DW_DLV_OK; } /* Target_offset is the offset in a .debug_macro section, of a macro unit header. Returns DW_DLV_NO_ENTRY if the macro operator is not one of the import operators. */ int dwarf_get_macro_import(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * target_offset, Dwarf_Error *error) { Dwarf_Unsigned supoffset = 0; Dwarf_Debug dbg = 0; unsigned macop = 0; struct Dwarf_Macro_Operator_s *curop = 0; Dwarf_Small *mdata = 0; Dwarf_Byte_Ptr startptr = 0; Dwarf_Byte_Ptr endptr = 0; if (!macro_context || macro_context->mc_sentinel != 0xada) { if(macro_context) { dbg = macro_context->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; dbg = macro_context->mc_dbg; if (op_number >= macro_context->mc_macro_ops_count) { _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } curop = macro_context->mc_ops + op_number; macop = curop->mo_opcode; mdata = curop->mo_data; if (macop != DW_MACRO_import && macop != DW_MACRO_import_sup) { return DW_DLV_NO_ENTRY; } READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); *target_offset = supoffset; return DW_DLV_OK; } /* */ static int valid_macro_form(Dwarf_Half form) { switch(form) { case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_data16: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_flag: case DW_FORM_sec_offset: case DW_FORM_string: case DW_FORM_strp: case DW_FORM_strx: return TRUE; } return FALSE; } static int validate_opcode(Dwarf_Debug dbg, struct Dwarf_Macro_Forms_s *curform, Dwarf_Error * error) { unsigned i = 0; struct Dwarf_Macro_Forms_s *stdfptr = 0; if (curform->mf_code >= DW_MACRO_lo_user) { /* Nothing to check. user level. */ return DW_DLV_OK; } if (curform->mf_code > DW_MACRO_undef_strx) { _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_BAD); return (DW_DLV_ERROR); } if (!curform->mf_code){ _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_BAD); return (DW_DLV_ERROR); } stdfptr = &dwarf_default_macro_opslist.mol_data[curform->mf_code]; if (curform->mf_formcount != stdfptr->mf_formcount) { _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_FORM_BAD); return (DW_DLV_ERROR); } for(i = 0; i < curform->mf_formcount; ++i) { if (curform->mf_formbytes[i] != stdfptr->mf_formbytes[1]) { _dwarf_error(dbg, error, DW_DLE_MACRO_OPCODE_FORM_BAD); return (DW_DLV_ERROR); } } return DW_DLV_OK; } static int read_operands_table(Dwarf_Macro_Context macro_context, Dwarf_Small * macro_header, Dwarf_Small * macro_data, Dwarf_Small * section_base, Dwarf_Unsigned section_size, Dwarf_Unsigned *table_size_out, Dwarf_Error *error) { Dwarf_Small* table_data_start = macro_data; Dwarf_Unsigned local_size = 0; Dwarf_Unsigned cur_offset = 0; Dwarf_Small operand_table_count = 0; unsigned i = 0; struct Dwarf_Macro_Forms_s *curformentry = 0; Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr startptr = 0; Dwarf_Byte_Ptr endptr = 0; if (!macro_context || macro_context->mc_sentinel != 0xada) { if(macro_context) { dbg = macro_context->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } dbg = macro_context->mc_dbg; cur_offset = (1+ macro_data) - macro_header; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } startptr = macro_context->mc_macro_header; endptr = startptr + macro_context->mc_total_length; READ_UNALIGNED_CK(dbg,operand_table_count,Dwarf_Small, macro_data,sizeof(Dwarf_Small),error,endptr); macro_data += sizeof(Dwarf_Small); /* Estimating minimum size */ local_size = operand_table_count * 4; cur_offset = (local_size+ macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } /* first, get size of table. */ table_data_start = macro_data; for (i = 0; i < operand_table_count; ++i) { /* Compiler warning about unused opcode_number variable should be ignored. */ UNUSEDARG Dwarf_Small opcode_number = 0; Dwarf_Unsigned formcount = 0; READ_UNALIGNED_CK(dbg,opcode_number,Dwarf_Small, macro_data,sizeof(Dwarf_Small),error,endptr); macro_data += sizeof(Dwarf_Small); DECODE_LEB128_UWORD_CK(macro_data,formcount, dbg, error, endptr); cur_offset = (formcount+ macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } /* The 1 ubyte forms follow. Step past them. */ macro_data += formcount; } /* reset for reread. */ macro_data = table_data_start; /* allocate table */ macro_context->mc_opcode_forms = (struct Dwarf_Macro_Forms_s *) calloc(operand_table_count, sizeof(struct Dwarf_Macro_Forms_s)); macro_context->mc_opcode_count = operand_table_count; if(!macro_context->mc_opcode_forms) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } curformentry = macro_context->mc_opcode_forms; for (i = 0; i < operand_table_count; ++i,++curformentry) { Dwarf_Small opcode_number = 0; Dwarf_Unsigned formcount = 0; int res = 0; cur_offset = (2 + macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg,opcode_number,Dwarf_Small, macro_data,sizeof(Dwarf_Small), error,endptr); macro_data += sizeof(Dwarf_Small); DECODE_LEB128_UWORD_CK(macro_data,formcount, dbg, error, endptr); curformentry->mf_code = opcode_number; curformentry->mf_formcount = formcount; cur_offset = (formcount+ macro_data) - section_base; if (cur_offset >= section_size) { _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } curformentry->mf_formbytes = macro_data; macro_data += formcount; if (opcode_number > DW_MACRO_undef_strx ) { Dwarf_Half k = 0; for(k = 0; k < formcount; ++k) { if (!valid_macro_form(curformentry->mf_formbytes[k])) { _dwarf_error(dbg, error, DW_DLE_MACRO_OP_UNHANDLED); return (DW_DLV_ERROR); } } } res = validate_opcode(macro_context->mc_dbg,curformentry, error); if(res != DW_DLV_OK) { return res; } } *table_size_out = macro_data - table_data_start; return DW_DLV_OK; } /* This is not the normal srcfiles from dwarf_srcfiles. See translate translate_srcfiles_to_srcfiles2(). It is a list, but the contents were directly malloc, not _dwarf_get_alloc. */ static void dealloc_macro_srcfiles(char ** srcfiles, Dwarf_Signed srcfiles_count) { Dwarf_Signed i = 0; if (!srcfiles || !srcfiles_count) { return; } for (i = 0; i < srcfiles_count; ++i) { if (srcfiles[i]) { free(srcfiles[i]); srcfiles[i] = 0; } } free(srcfiles); } /* This makes the macro context safe from duplicate frees in case of error. */ static int translate_srcfiles_to_srcfiles2(char **srcfiles, Dwarf_Signed srcfiles_count, char **srcfiles2) { Dwarf_Signed i = 0; for(i = 0; i < srcfiles_count; ++i) { char * ostr = 0; char * newstr = 0; size_t slen = 0; ostr = srcfiles[i]; slen = strlen(ostr); newstr = calloc(1,slen+1); if (!newstr) { return DW_DLV_ERROR; } strcpy(newstr,ostr); srcfiles[i] = 0; srcfiles2[i] = newstr; } return DW_DLV_OK; } static int _dwarf_internal_macro_context(Dwarf_Die die, Dwarf_Bool offset_specified, Dwarf_Unsigned offset_in, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned * macro_unit_offset_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; int res = DW_DLV_ERROR; Dwarf_Unsigned macro_offset = 0; Dwarf_Attribute macro_attr = 0; Dwarf_Signed srcfiles_count = 0; char ** srcfiles = 0; /* srcfiles uses dwarf_get_alloc for strings so dealloc_macro_srcfiles() here will result in double-dealloc when dwarf_finish() happens to see the string deallocs before the macro context dealloc (the context dealloc will call dealloc_macro_srcfiles() !). Also see the comment at _dwarf_macro_destructor() here. */ char ** srcfiles2 = 0; const char *comp_dir = 0; const char *comp_name = 0; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = cu_context->cc_dbg; /* Doing the load here results in duplication of the section-load call (in the by_offset interface below) but detects the missing section quickly. */ res = _dwarf_load_section(dbg, &dbg->de_debug_macro,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_macro.dss_size) { return (DW_DLV_NO_ENTRY); } resattr = dwarf_attr(die, DW_AT_macros, ¯o_attr, error); if (resattr == DW_DLV_NO_ENTRY) { resattr = dwarf_attr(die, DW_AT_GNU_macros, ¯o_attr, error); } if (resattr != DW_DLV_OK) { return resattr; } if (!offset_specified) { lres = dwarf_global_formref(macro_attr, ¯o_offset, error); if (lres != DW_DLV_OK) { return lres; } } else { macro_offset = offset_in; } lres = dwarf_srcfiles(die,&srcfiles,&srcfiles_count, error); if (lres == DW_DLV_ERROR) { return lres; } lres = _dwarf_internal_get_die_comp_dir(die, &comp_dir, &comp_name,error); if (lres == DW_DLV_ERROR) { Dwarf_Signed i = 0; for (i = 0; i < srcfiles_count; ++i) { if(srcfiles[i]) { dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); } } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); srcfiles = 0; return lres; } *macro_unit_offset_out = macro_offset; /* We cannot use space allocated by _dwarf_get_alloc() in the macro_context we will allocate shortly. So copy from what we have to a similar data set but malloc space directly. */ if (srcfiles_count > 0) { srcfiles2 = (char **) calloc(srcfiles_count, sizeof(char *)); if (!srcfiles2) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } lres = translate_srcfiles_to_srcfiles2(srcfiles, srcfiles_count,srcfiles2); { Dwarf_Signed i = 0; for (i = 0; i < srcfiles_count; ++i) { if(srcfiles[i]) { dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); srcfiles[i] = 0; } } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); srcfiles = 0; } if (lres == DW_DLV_OK) { srcfiles = 0; } else { dealloc_macro_srcfiles(srcfiles2, srcfiles_count); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return lres; } } /* NO ENTRY or OK we accept, though NO ENTRY means there are no source files available. */ lres = _dwarf_internal_macro_context_by_offset(dbg, macro_offset,version_out,macro_context_out, macro_ops_count_out, macro_ops_data_length, srcfiles2,srcfiles_count, comp_dir, comp_name, cu_context, error); /* In case of ERROR or NO_ENTRY srcfiles2 is already freed. */ return lres; } static int _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, char **srcfiles, Dwarf_Signed srcfilescount, const char *comp_dir, const char *comp_name, Dwarf_CU_Context cu_context, Dwarf_Error * error) { Dwarf_Unsigned line_table_offset = 0; Dwarf_Small * macro_header = 0; Dwarf_Small * macro_data = 0; Dwarf_Half version = 0; Dwarf_Small flags = 0; Dwarf_Small offset_size = 4; Dwarf_Unsigned cur_offset = 0; Dwarf_Unsigned section_size = 0; Dwarf_Small *section_base = 0; Dwarf_Small *section_end = 0; Dwarf_Unsigned optablesize = 0; Dwarf_Unsigned macro_offset = offset; int res = 0; Dwarf_Macro_Context macro_context = 0; Dwarf_Bool build_ops_array = FALSE; res = _dwarf_load_section(dbg, &dbg->de_debug_macro,error); if (res != DW_DLV_OK) { dealloc_macro_srcfiles(srcfiles,srcfilescount); return res; } if (!dbg->de_debug_macro.dss_size) { dealloc_macro_srcfiles(srcfiles,srcfilescount); return (DW_DLV_NO_ENTRY); } section_base = dbg->de_debug_macro.dss_data; section_size = dbg->de_debug_macro.dss_size; /* The '3' ensures the header initial bytes present too. */ if ((3+macro_offset) >= section_size) { dealloc_macro_srcfiles(srcfiles,srcfilescount); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } macro_header = macro_offset + section_base; macro_data = macro_header; section_end = section_base +section_size; macro_context = (Dwarf_Macro_Context) _dwarf_get_alloc(dbg,DW_DLA_MACRO_CONTEXT,1); if (!macro_context) { dealloc_macro_srcfiles(srcfiles,srcfilescount); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if ((section_base + DWARF_HALF_SIZE + sizeof(Dwarf_Small)) > section_end ) { dealloc_macro_srcfiles(srcfiles,srcfilescount); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; } /* Note here so if error return we get these freed eventually. */ macro_context->mc_srcfiles = srcfiles; macro_context->mc_srcfiles_count = srcfilescount; macro_context->mc_cu_context = cu_context; READ_UNALIGNED_CK(dbg,version, Dwarf_Half, macro_data, DWARF_HALF_SIZE,error,section_end); macro_data += DWARF_HALF_SIZE; READ_UNALIGNED_CK(dbg,flags, Dwarf_Small, macro_data,sizeof(Dwarf_Small),error,section_end); macro_data += sizeof(Dwarf_Small); macro_context->mc_at_comp_dir = comp_dir; macro_context->mc_at_name = comp_name; macro_context->mc_macro_header = macro_header; macro_context->mc_section_offset = macro_offset; macro_context->mc_version_number = version; macro_context->mc_flags = flags; macro_context->mc_dbg = dbg; macro_context->mc_offset_size_flag = flags& MACRO_OFFSET_SIZE_FLAG?TRUE:FALSE; macro_context->mc_debug_line_offset_flag = flags& MACRO_LINE_OFFSET_FLAG?TRUE:FALSE; macro_context->mc_operands_table_flag = flags& MACRO_OP_TABLE_FLAG?TRUE:FALSE; offset_size = macro_context->mc_offset_size_flag?8:4; macro_context->mc_offset_size = offset_size; if (macro_context->mc_debug_line_offset_flag) { cur_offset = (offset_size+ macro_data) - section_base; if (cur_offset >= section_size) { dwarf_dealloc_macro_context(macro_context); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg,line_table_offset,Dwarf_Unsigned, macro_data,offset_size,error,section_end); macro_data += offset_size; macro_context->mc_debug_line_offset = line_table_offset; } if (macro_context->mc_operands_table_flag) { res = read_operands_table(macro_context, macro_header, macro_data, section_base, section_size, &optablesize, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } } macro_data += optablesize; macro_context->mc_macro_ops = macro_data; macro_context->mc_macro_header_length =macro_data - macro_header; build_ops_array = FALSE; res = _dwarf_get_macro_ops_count_internal(macro_context, build_ops_array, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } build_ops_array = TRUE; res = _dwarf_get_macro_ops_count_internal(macro_context, build_ops_array, error); if (res != DW_DLV_OK) { dwarf_dealloc_macro_context(macro_context); return res; } *macro_ops_count_out = macro_context->mc_macro_ops_count; *macro_ops_data_length = macro_context->mc_ops_data_length; *version_out = version; *macro_context_out = macro_context; return DW_DLV_OK; } int dwarf_macro_context_head(Dwarf_Macro_Context head, Dwarf_Half * version, Dwarf_Unsigned * mac_offset, Dwarf_Unsigned * mac_len, Dwarf_Unsigned * mac_header_len, unsigned * flags, Dwarf_Bool * has_line_offset, Dwarf_Unsigned * line_offset, Dwarf_Bool * has_offset_size_64, Dwarf_Bool * has_operands_table, Dwarf_Half * opcode_count, Dwarf_Error *error) { if (!head || head->mc_sentinel != 0xada) { Dwarf_Debug dbg = 0; if(head) { dbg = head->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } *version = head->mc_version_number; *mac_offset = head->mc_section_offset; *mac_len = head->mc_total_length; *mac_header_len = head->mc_macro_header_length; *flags = head->mc_flags; *line_offset = head->mc_debug_line_offset; *has_line_offset = head->mc_debug_line_offset_flag; *has_offset_size_64 = head->mc_offset_size_flag; *has_operands_table = head->mc_operands_table_flag; *opcode_count = head->mc_opcode_count; return DW_DLV_OK; } int dwarf_macro_operands_table(Dwarf_Macro_Context head, Dwarf_Half index, /* 0 to opcode_count -1 */ Dwarf_Half *opcode_number, Dwarf_Half *operand_count, const Dwarf_Small **operand_array, Dwarf_Error *error) { struct Dwarf_Macro_Forms_s * ops = 0; Dwarf_Debug dbg = 0; if (!head || head->mc_sentinel != 0xada) { if(head) { dbg = head->mc_dbg; } _dwarf_error(dbg, error,DW_DLE_BAD_MACRO_HEADER_POINTER); return DW_DLV_ERROR; } dbg = head->mc_dbg; if (index >= head->mc_opcode_count) { _dwarf_error(dbg, error, DW_DLE_BAD_MACRO_INDEX); return DW_DLV_ERROR; } ops = head->mc_opcode_forms + index; *opcode_number = ops->mf_code; *operand_count = ops->mf_formcount; *operand_array = ops->mf_formbytes; return DW_DLV_OK; } /* The base interface to the .debug_macro section data for a specific CU. The version number passed back by *version_out may be 4 (a gnu extension of DWARF) or 5. */ int dwarf_get_macro_context(Dwarf_Die cu_die, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_unit_offset_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, Dwarf_Error * error) { int res = 0; Dwarf_Bool offset_specified = FALSE; Dwarf_Unsigned offset = 0; res = _dwarf_internal_macro_context(cu_die, offset_specified, offset, version_out, macro_context, macro_unit_offset_out, macro_ops_count_out, macro_ops_data_length, error); return res; } /* Like dwarf_get_macro_context but here we use a specfied offset instead of the offset in the cu_die. */ int dwarf_get_macro_context_by_offset(Dwarf_Die cu_die, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length, Dwarf_Error * error) { int res = 0; Dwarf_Bool offset_specified = TRUE; Dwarf_Unsigned macro_unit_offset_out = 0; res = _dwarf_internal_macro_context(cu_die, offset_specified, offset, version_out, macro_context, ¯o_unit_offset_out, macro_ops_count_out, macro_ops_data_length, error); return res; } int dwarf_get_macro_section_name(Dwarf_Debug dbg, const char **sec_name_out, UNUSEDARG Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; sec = &dbg->de_debug_macro; if (sec->dss_size == 0) { /* We don't have such a section at all. */ return DW_DLV_NO_ENTRY; } *sec_name_out = sec->dss_name; return DW_DLV_OK; } void dwarf_dealloc_macro_context(Dwarf_Macro_Context mc) { Dwarf_Debug dbg = mc->mc_dbg; dwarf_dealloc(dbg,mc,DW_DLA_MACRO_CONTEXT); } int _dwarf_macro_constructor(Dwarf_Debug dbg, void *m) { /* Nothing to do, the space is zeroed out */ Dwarf_Macro_Context mc= (Dwarf_Macro_Context)m; /* Arbitrary sentinel. For debugging. */ mc->mc_sentinel = 0xada; mc->mc_dbg = dbg; return DW_DLV_OK; } /* Here we free various fields of Dwarf_Macro_Context. The fields do not get dealloc'd. If we had a separate destructor for hand-calling (meaning when an error is detected during creation of a Dwarf_Macro_Context) and one for calling by dwarf_dealloc() then we could have the hand-calling dwarf_dealloc the fields and the one called on the dealloc of a Dwarf_Macro_Context could leave the _dwarf_get_alloc() fields for for normal dwarf_finish() cleanup. But for now we share this destructor for both purposes so no fields are _dwarf_get_alloc() and all are free-d here.. */ void _dwarf_macro_destructor(void *m) { Dwarf_Macro_Context mc= (Dwarf_Macro_Context)m; dealloc_macro_srcfiles(mc->mc_srcfiles, mc->mc_srcfiles_count); mc->mc_srcfiles = 0; mc->mc_srcfiles_count = 0; free((void *)mc->mc_file_path); mc->mc_file_path = 0; free(mc->mc_ops); mc->mc_ops = 0; free(mc->mc_opcode_forms); mc->mc_opcode_forms = 0; memset(mc,0,sizeof(*mc)); /* Just a recognizable sentinel. For debugging. No real meaning. */ mc->mc_sentinel = 0xdeadbeef; } dwarfutils-20200114/libdwarf/dwarf_macro5.h000066400000000000000000000110531361531463500204540ustar00rootroot00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* dwarf_macro5.h For the DWARF5 .debug_macro section (also appears as an extension to DWARF4) */ struct Dwarf_Macro_Forms_s { /* Code means DW_MACRO_define etc. */ Dwarf_Small mf_code; /* How many entries in mf_formbytes array. */ Dwarf_Small mf_formcount; /* Never free these, these are in the object file memory */ const Dwarf_Small * mf_formbytes; }; struct Dwarf_Macro_OperationsList_s { unsigned mol_count; struct Dwarf_Macro_Forms_s * mol_data; }; struct Dwarf_Macro_Operator_s { /* mo_opcode == mo_form->mf_code */ Dwarf_Small mo_opcode; struct Dwarf_Macro_Forms_s * mo_form; /* Points at the first byte of the data, meaning it points one-past the macro operation code byte. */ Dwarf_Small * mo_data; }; #define MACRO_OFFSET_SIZE_FLAG 1 #define MACRO_LINE_OFFSET_FLAG 2 #define MACRO_OP_TABLE_FLAG 4 /* Could be reordered to be most space efficient. That might be a little harder to read. Hmm. */ struct Dwarf_Macro_Context_s { Dwarf_Unsigned mc_sentinel; Dwarf_Half mc_version_number; /* Section_offset in .debug_macro of macro header */ Dwarf_Unsigned mc_section_offset; /* Total length of the macro data for this CU. Calculated, not part of header. */ Dwarf_Unsigned mc_total_length; Dwarf_Half mc_macro_header_length; Dwarf_Small mc_flags; /* If DW_MACRO_start_file is in the operators of this table then the mc_debug_line_offset must be present from the header. */ Dwarf_Unsigned mc_debug_line_offset; /* the following three set from the bits in mc_flags */ /* If 1, offsets 64 bits */ Dwarf_Bool mc_offset_size_flag; /* if 1, debug_line offset is present. */ Dwarf_Bool mc_debug_line_offset_flag; /* 4 or 8, depending on mc_offset_size_flag */ Dwarf_Small mc_offset_size; /* If one the operands/opcodes (mc_opcode_forms) table is present in the header. If not we use a default table. Even when there are operands in the header the standardops may or may not be defined in the header. */ Dwarf_Bool mc_operands_table_flag; /* Count of the Dwarf_Macro_Forms_s structs pointed to by mc_opcode_forms. These from the header. */ Dwarf_Small mc_opcode_count; struct Dwarf_Macro_Forms_s *mc_opcode_forms; /* mc_ops must be free()d, but pointers inside mc_ops are to static or section data so must not be freed. */ Dwarf_Unsigned mc_macro_ops_count; Dwarf_Unsigned mc_ops_data_length; struct Dwarf_Macro_Operator_s *mc_ops; Dwarf_Small * mc_macro_header; Dwarf_Small * mc_macro_ops; /* These are malloc space, not _dwarf_get_alloc() so the DW_DLA_MACRO_CONTEXT dealloc will free them. */ char ** mc_srcfiles; Dwarf_Signed mc_srcfiles_count; /* These are from CU DIE attribute names. They may be NULL or point at data in a dwarf section. Do not free(). This attempts to make up for the lack of a base file name in DWARF2,3,4 line tables. */ const char * mc_at_comp_dir; const char * mc_at_name; /* The following is malloc,so macro_context_s destructor needs to free it. */ const char * mc_file_path; Dwarf_Debug mc_dbg; Dwarf_CU_Context mc_cu_context; }; int _dwarf_macro_constructor(Dwarf_Debug dbg, void *m); void _dwarf_macro_destructor(void *m); dwarfutils-20200114/libdwarf/dwarf_names.c000066400000000000000000003013701361531463500203700ustar00rootroot00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #include "dwarf.h" #include "libdwarf.h" /* ARGSUSED */ int dwarf_get_TAG_name (unsigned int val,const char ** s_out) { switch (val) { case DW_TAG_array_type: *s_out = "DW_TAG_array_type"; return DW_DLV_OK; case DW_TAG_class_type: *s_out = "DW_TAG_class_type"; return DW_DLV_OK; case DW_TAG_entry_point: *s_out = "DW_TAG_entry_point"; return DW_DLV_OK; case DW_TAG_enumeration_type: *s_out = "DW_TAG_enumeration_type"; return DW_DLV_OK; case DW_TAG_formal_parameter: *s_out = "DW_TAG_formal_parameter"; return DW_DLV_OK; case DW_TAG_imported_declaration: *s_out = "DW_TAG_imported_declaration"; return DW_DLV_OK; case DW_TAG_label: *s_out = "DW_TAG_label"; return DW_DLV_OK; case DW_TAG_lexical_block: *s_out = "DW_TAG_lexical_block"; return DW_DLV_OK; case DW_TAG_member: *s_out = "DW_TAG_member"; return DW_DLV_OK; case DW_TAG_pointer_type: *s_out = "DW_TAG_pointer_type"; return DW_DLV_OK; case DW_TAG_reference_type: *s_out = "DW_TAG_reference_type"; return DW_DLV_OK; case DW_TAG_compile_unit: *s_out = "DW_TAG_compile_unit"; return DW_DLV_OK; case DW_TAG_string_type: *s_out = "DW_TAG_string_type"; return DW_DLV_OK; case DW_TAG_structure_type: *s_out = "DW_TAG_structure_type"; return DW_DLV_OK; case DW_TAG_subroutine_type: *s_out = "DW_TAG_subroutine_type"; return DW_DLV_OK; case DW_TAG_typedef: *s_out = "DW_TAG_typedef"; return DW_DLV_OK; case DW_TAG_union_type: *s_out = "DW_TAG_union_type"; return DW_DLV_OK; case DW_TAG_unspecified_parameters: *s_out = "DW_TAG_unspecified_parameters"; return DW_DLV_OK; case DW_TAG_variant: *s_out = "DW_TAG_variant"; return DW_DLV_OK; case DW_TAG_common_block: *s_out = "DW_TAG_common_block"; return DW_DLV_OK; case DW_TAG_common_inclusion: *s_out = "DW_TAG_common_inclusion"; return DW_DLV_OK; case DW_TAG_inheritance: *s_out = "DW_TAG_inheritance"; return DW_DLV_OK; case DW_TAG_inlined_subroutine: *s_out = "DW_TAG_inlined_subroutine"; return DW_DLV_OK; case DW_TAG_module: *s_out = "DW_TAG_module"; return DW_DLV_OK; case DW_TAG_ptr_to_member_type: *s_out = "DW_TAG_ptr_to_member_type"; return DW_DLV_OK; case DW_TAG_set_type: *s_out = "DW_TAG_set_type"; return DW_DLV_OK; case DW_TAG_subrange_type: *s_out = "DW_TAG_subrange_type"; return DW_DLV_OK; case DW_TAG_with_stmt: *s_out = "DW_TAG_with_stmt"; return DW_DLV_OK; case DW_TAG_access_declaration: *s_out = "DW_TAG_access_declaration"; return DW_DLV_OK; case DW_TAG_base_type: *s_out = "DW_TAG_base_type"; return DW_DLV_OK; case DW_TAG_catch_block: *s_out = "DW_TAG_catch_block"; return DW_DLV_OK; case DW_TAG_const_type: *s_out = "DW_TAG_const_type"; return DW_DLV_OK; case DW_TAG_constant: *s_out = "DW_TAG_constant"; return DW_DLV_OK; case DW_TAG_enumerator: *s_out = "DW_TAG_enumerator"; return DW_DLV_OK; case DW_TAG_file_type: *s_out = "DW_TAG_file_type"; return DW_DLV_OK; case DW_TAG_friend: *s_out = "DW_TAG_friend"; return DW_DLV_OK; case DW_TAG_namelist: *s_out = "DW_TAG_namelist"; return DW_DLV_OK; case DW_TAG_namelist_item: *s_out = "DW_TAG_namelist_item"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2c. DW_TAG_namelist_items */ case DW_TAG_packed_type: *s_out = "DW_TAG_packed_type"; return DW_DLV_OK; case DW_TAG_subprogram: *s_out = "DW_TAG_subprogram"; return DW_DLV_OK; case DW_TAG_template_type_parameter: *s_out = "DW_TAG_template_type_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2f. DW_TAG_template_type_param */ case DW_TAG_template_value_parameter: *s_out = "DW_TAG_template_value_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x30. DW_TAG_template_value_param */ case DW_TAG_thrown_type: *s_out = "DW_TAG_thrown_type"; return DW_DLV_OK; case DW_TAG_try_block: *s_out = "DW_TAG_try_block"; return DW_DLV_OK; case DW_TAG_variant_part: *s_out = "DW_TAG_variant_part"; return DW_DLV_OK; case DW_TAG_variable: *s_out = "DW_TAG_variable"; return DW_DLV_OK; case DW_TAG_volatile_type: *s_out = "DW_TAG_volatile_type"; return DW_DLV_OK; case DW_TAG_dwarf_procedure: *s_out = "DW_TAG_dwarf_procedure"; return DW_DLV_OK; case DW_TAG_restrict_type: *s_out = "DW_TAG_restrict_type"; return DW_DLV_OK; case DW_TAG_interface_type: *s_out = "DW_TAG_interface_type"; return DW_DLV_OK; case DW_TAG_namespace: *s_out = "DW_TAG_namespace"; return DW_DLV_OK; case DW_TAG_imported_module: *s_out = "DW_TAG_imported_module"; return DW_DLV_OK; case DW_TAG_unspecified_type: *s_out = "DW_TAG_unspecified_type"; return DW_DLV_OK; case DW_TAG_partial_unit: *s_out = "DW_TAG_partial_unit"; return DW_DLV_OK; case DW_TAG_imported_unit: *s_out = "DW_TAG_imported_unit"; return DW_DLV_OK; case DW_TAG_mutable_type: *s_out = "DW_TAG_mutable_type"; return DW_DLV_OK; case DW_TAG_condition: *s_out = "DW_TAG_condition"; return DW_DLV_OK; case DW_TAG_shared_type: *s_out = "DW_TAG_shared_type"; return DW_DLV_OK; case DW_TAG_type_unit: *s_out = "DW_TAG_type_unit"; return DW_DLV_OK; case DW_TAG_rvalue_reference_type: *s_out = "DW_TAG_rvalue_reference_type"; return DW_DLV_OK; case DW_TAG_template_alias: *s_out = "DW_TAG_template_alias"; return DW_DLV_OK; case DW_TAG_coarray_type: *s_out = "DW_TAG_coarray_type"; return DW_DLV_OK; case DW_TAG_generic_subrange: *s_out = "DW_TAG_generic_subrange"; return DW_DLV_OK; case DW_TAG_dynamic_type: *s_out = "DW_TAG_dynamic_type"; return DW_DLV_OK; case DW_TAG_atomic_type: *s_out = "DW_TAG_atomic_type"; return DW_DLV_OK; case DW_TAG_call_site: *s_out = "DW_TAG_call_site"; return DW_DLV_OK; case DW_TAG_call_site_parameter: *s_out = "DW_TAG_call_site_parameter"; return DW_DLV_OK; case DW_TAG_skeleton_unit: *s_out = "DW_TAG_skeleton_unit"; return DW_DLV_OK; case DW_TAG_immutable_type: *s_out = "DW_TAG_immutable_type"; return DW_DLV_OK; case DW_TAG_lo_user: *s_out = "DW_TAG_lo_user"; return DW_DLV_OK; case DW_TAG_MIPS_loop: *s_out = "DW_TAG_MIPS_loop"; return DW_DLV_OK; case DW_TAG_HP_array_descriptor: *s_out = "DW_TAG_HP_array_descriptor"; return DW_DLV_OK; case DW_TAG_format_label: *s_out = "DW_TAG_format_label"; return DW_DLV_OK; case DW_TAG_function_template: *s_out = "DW_TAG_function_template"; return DW_DLV_OK; case DW_TAG_class_template: *s_out = "DW_TAG_class_template"; return DW_DLV_OK; case DW_TAG_GNU_BINCL: *s_out = "DW_TAG_GNU_BINCL"; return DW_DLV_OK; case DW_TAG_GNU_EINCL: *s_out = "DW_TAG_GNU_EINCL"; return DW_DLV_OK; case DW_TAG_GNU_template_template_parameter: *s_out = "DW_TAG_GNU_template_template_parameter"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x4106. DW_TAG_GNU_template_template_param */ case DW_TAG_GNU_template_parameter_pack: *s_out = "DW_TAG_GNU_template_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_formal_parameter_pack: *s_out = "DW_TAG_GNU_formal_parameter_pack"; return DW_DLV_OK; case DW_TAG_GNU_call_site: *s_out = "DW_TAG_GNU_call_site"; return DW_DLV_OK; case DW_TAG_GNU_call_site_parameter: *s_out = "DW_TAG_GNU_call_site_parameter"; return DW_DLV_OK; case DW_TAG_SUN_function_template: *s_out = "DW_TAG_SUN_function_template"; return DW_DLV_OK; case DW_TAG_SUN_class_template: *s_out = "DW_TAG_SUN_class_template"; return DW_DLV_OK; case DW_TAG_SUN_struct_template: *s_out = "DW_TAG_SUN_struct_template"; return DW_DLV_OK; case DW_TAG_SUN_union_template: *s_out = "DW_TAG_SUN_union_template"; return DW_DLV_OK; case DW_TAG_SUN_indirect_inheritance: *s_out = "DW_TAG_SUN_indirect_inheritance"; return DW_DLV_OK; case DW_TAG_SUN_codeflags: *s_out = "DW_TAG_SUN_codeflags"; return DW_DLV_OK; case DW_TAG_SUN_memop_info: *s_out = "DW_TAG_SUN_memop_info"; return DW_DLV_OK; case DW_TAG_SUN_omp_child_func: *s_out = "DW_TAG_SUN_omp_child_func"; return DW_DLV_OK; case DW_TAG_SUN_rtti_descriptor: *s_out = "DW_TAG_SUN_rtti_descriptor"; return DW_DLV_OK; case DW_TAG_SUN_dtor_info: *s_out = "DW_TAG_SUN_dtor_info"; return DW_DLV_OK; case DW_TAG_SUN_dtor: *s_out = "DW_TAG_SUN_dtor"; return DW_DLV_OK; case DW_TAG_SUN_f90_interface: *s_out = "DW_TAG_SUN_f90_interface"; return DW_DLV_OK; case DW_TAG_SUN_fortran_vax_structure: *s_out = "DW_TAG_SUN_fortran_vax_structure"; return DW_DLV_OK; case DW_TAG_SUN_hi: *s_out = "DW_TAG_SUN_hi"; return DW_DLV_OK; case DW_TAG_ALTIUM_circ_type: *s_out = "DW_TAG_ALTIUM_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_mwa_circ_type: *s_out = "DW_TAG_ALTIUM_mwa_circ_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rev_carry_type: *s_out = "DW_TAG_ALTIUM_rev_carry_type"; return DW_DLV_OK; case DW_TAG_ALTIUM_rom: *s_out = "DW_TAG_ALTIUM_rom"; return DW_DLV_OK; case DW_TAG_upc_shared_type: *s_out = "DW_TAG_upc_shared_type"; return DW_DLV_OK; case DW_TAG_upc_strict_type: *s_out = "DW_TAG_upc_strict_type"; return DW_DLV_OK; case DW_TAG_upc_relaxed_type: *s_out = "DW_TAG_upc_relaxed_type"; return DW_DLV_OK; case DW_TAG_PGI_kanji_type: *s_out = "DW_TAG_PGI_kanji_type"; return DW_DLV_OK; case DW_TAG_PGI_interface_block: *s_out = "DW_TAG_PGI_interface_block"; return DW_DLV_OK; case DW_TAG_hi_user: *s_out = "DW_TAG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_children_name (unsigned int val,const char ** s_out) { switch (val) { case DW_children_no: *s_out = "DW_children_no"; return DW_DLV_OK; case DW_children_yes: *s_out = "DW_children_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FORM_name (unsigned int val,const char ** s_out) { switch (val) { case DW_FORM_addr: *s_out = "DW_FORM_addr"; return DW_DLV_OK; case DW_FORM_block2: *s_out = "DW_FORM_block2"; return DW_DLV_OK; case DW_FORM_block4: *s_out = "DW_FORM_block4"; return DW_DLV_OK; case DW_FORM_data2: *s_out = "DW_FORM_data2"; return DW_DLV_OK; case DW_FORM_data4: *s_out = "DW_FORM_data4"; return DW_DLV_OK; case DW_FORM_data8: *s_out = "DW_FORM_data8"; return DW_DLV_OK; case DW_FORM_string: *s_out = "DW_FORM_string"; return DW_DLV_OK; case DW_FORM_block: *s_out = "DW_FORM_block"; return DW_DLV_OK; case DW_FORM_block1: *s_out = "DW_FORM_block1"; return DW_DLV_OK; case DW_FORM_data1: *s_out = "DW_FORM_data1"; return DW_DLV_OK; case DW_FORM_flag: *s_out = "DW_FORM_flag"; return DW_DLV_OK; case DW_FORM_sdata: *s_out = "DW_FORM_sdata"; return DW_DLV_OK; case DW_FORM_strp: *s_out = "DW_FORM_strp"; return DW_DLV_OK; case DW_FORM_udata: *s_out = "DW_FORM_udata"; return DW_DLV_OK; case DW_FORM_ref_addr: *s_out = "DW_FORM_ref_addr"; return DW_DLV_OK; case DW_FORM_ref1: *s_out = "DW_FORM_ref1"; return DW_DLV_OK; case DW_FORM_ref2: *s_out = "DW_FORM_ref2"; return DW_DLV_OK; case DW_FORM_ref4: *s_out = "DW_FORM_ref4"; return DW_DLV_OK; case DW_FORM_ref8: *s_out = "DW_FORM_ref8"; return DW_DLV_OK; case DW_FORM_ref_udata: *s_out = "DW_FORM_ref_udata"; return DW_DLV_OK; case DW_FORM_indirect: *s_out = "DW_FORM_indirect"; return DW_DLV_OK; case DW_FORM_sec_offset: *s_out = "DW_FORM_sec_offset"; return DW_DLV_OK; case DW_FORM_exprloc: *s_out = "DW_FORM_exprloc"; return DW_DLV_OK; case DW_FORM_flag_present: *s_out = "DW_FORM_flag_present"; return DW_DLV_OK; case DW_FORM_strx: *s_out = "DW_FORM_strx"; return DW_DLV_OK; case DW_FORM_addrx: *s_out = "DW_FORM_addrx"; return DW_DLV_OK; case DW_FORM_ref_sup4: *s_out = "DW_FORM_ref_sup4"; return DW_DLV_OK; case DW_FORM_strp_sup: *s_out = "DW_FORM_strp_sup"; return DW_DLV_OK; case DW_FORM_data16: *s_out = "DW_FORM_data16"; return DW_DLV_OK; case DW_FORM_line_strp: *s_out = "DW_FORM_line_strp"; return DW_DLV_OK; case DW_FORM_ref_sig8: *s_out = "DW_FORM_ref_sig8"; return DW_DLV_OK; case DW_FORM_implicit_const: *s_out = "DW_FORM_implicit_const"; return DW_DLV_OK; case DW_FORM_loclistx: *s_out = "DW_FORM_loclistx"; return DW_DLV_OK; case DW_FORM_rnglistx: *s_out = "DW_FORM_rnglistx"; return DW_DLV_OK; case DW_FORM_ref_sup8: *s_out = "DW_FORM_ref_sup8"; return DW_DLV_OK; case DW_FORM_strx1: *s_out = "DW_FORM_strx1"; return DW_DLV_OK; case DW_FORM_strx2: *s_out = "DW_FORM_strx2"; return DW_DLV_OK; case DW_FORM_strx3: *s_out = "DW_FORM_strx3"; return DW_DLV_OK; case DW_FORM_strx4: *s_out = "DW_FORM_strx4"; return DW_DLV_OK; case DW_FORM_addrx1: *s_out = "DW_FORM_addrx1"; return DW_DLV_OK; case DW_FORM_addrx2: *s_out = "DW_FORM_addrx2"; return DW_DLV_OK; case DW_FORM_addrx3: *s_out = "DW_FORM_addrx3"; return DW_DLV_OK; case DW_FORM_addrx4: *s_out = "DW_FORM_addrx4"; return DW_DLV_OK; case DW_FORM_GNU_addr_index: *s_out = "DW_FORM_GNU_addr_index"; return DW_DLV_OK; case DW_FORM_GNU_str_index: *s_out = "DW_FORM_GNU_str_index"; return DW_DLV_OK; case DW_FORM_GNU_ref_alt: *s_out = "DW_FORM_GNU_ref_alt"; return DW_DLV_OK; case DW_FORM_GNU_strp_alt: *s_out = "DW_FORM_GNU_strp_alt"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_AT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_AT_sibling: *s_out = "DW_AT_sibling"; return DW_DLV_OK; case DW_AT_location: *s_out = "DW_AT_location"; return DW_DLV_OK; case DW_AT_name: *s_out = "DW_AT_name"; return DW_DLV_OK; case DW_AT_ordering: *s_out = "DW_AT_ordering"; return DW_DLV_OK; case DW_AT_subscr_data: *s_out = "DW_AT_subscr_data"; return DW_DLV_OK; case DW_AT_byte_size: *s_out = "DW_AT_byte_size"; return DW_DLV_OK; case DW_AT_bit_offset: *s_out = "DW_AT_bit_offset"; return DW_DLV_OK; case DW_AT_bit_size: *s_out = "DW_AT_bit_size"; return DW_DLV_OK; case DW_AT_element_list: *s_out = "DW_AT_element_list"; return DW_DLV_OK; case DW_AT_stmt_list: *s_out = "DW_AT_stmt_list"; return DW_DLV_OK; case DW_AT_low_pc: *s_out = "DW_AT_low_pc"; return DW_DLV_OK; case DW_AT_high_pc: *s_out = "DW_AT_high_pc"; return DW_DLV_OK; case DW_AT_language: *s_out = "DW_AT_language"; return DW_DLV_OK; case DW_AT_member: *s_out = "DW_AT_member"; return DW_DLV_OK; case DW_AT_discr: *s_out = "DW_AT_discr"; return DW_DLV_OK; case DW_AT_discr_value: *s_out = "DW_AT_discr_value"; return DW_DLV_OK; case DW_AT_visibility: *s_out = "DW_AT_visibility"; return DW_DLV_OK; case DW_AT_import: *s_out = "DW_AT_import"; return DW_DLV_OK; case DW_AT_string_length: *s_out = "DW_AT_string_length"; return DW_DLV_OK; case DW_AT_common_reference: *s_out = "DW_AT_common_reference"; return DW_DLV_OK; case DW_AT_comp_dir: *s_out = "DW_AT_comp_dir"; return DW_DLV_OK; case DW_AT_const_value: *s_out = "DW_AT_const_value"; return DW_DLV_OK; case DW_AT_containing_type: *s_out = "DW_AT_containing_type"; return DW_DLV_OK; case DW_AT_default_value: *s_out = "DW_AT_default_value"; return DW_DLV_OK; case DW_AT_inline: *s_out = "DW_AT_inline"; return DW_DLV_OK; case DW_AT_is_optional: *s_out = "DW_AT_is_optional"; return DW_DLV_OK; case DW_AT_lower_bound: *s_out = "DW_AT_lower_bound"; return DW_DLV_OK; case DW_AT_producer: *s_out = "DW_AT_producer"; return DW_DLV_OK; case DW_AT_prototyped: *s_out = "DW_AT_prototyped"; return DW_DLV_OK; case DW_AT_return_addr: *s_out = "DW_AT_return_addr"; return DW_DLV_OK; case DW_AT_start_scope: *s_out = "DW_AT_start_scope"; return DW_DLV_OK; case DW_AT_bit_stride: *s_out = "DW_AT_bit_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2e. DW_AT_stride_size */ case DW_AT_upper_bound: *s_out = "DW_AT_upper_bound"; return DW_DLV_OK; case DW_AT_abstract_origin: *s_out = "DW_AT_abstract_origin"; return DW_DLV_OK; case DW_AT_accessibility: *s_out = "DW_AT_accessibility"; return DW_DLV_OK; case DW_AT_address_class: *s_out = "DW_AT_address_class"; return DW_DLV_OK; case DW_AT_artificial: *s_out = "DW_AT_artificial"; return DW_DLV_OK; case DW_AT_base_types: *s_out = "DW_AT_base_types"; return DW_DLV_OK; case DW_AT_calling_convention: *s_out = "DW_AT_calling_convention"; return DW_DLV_OK; case DW_AT_count: *s_out = "DW_AT_count"; return DW_DLV_OK; case DW_AT_data_member_location: *s_out = "DW_AT_data_member_location"; return DW_DLV_OK; case DW_AT_decl_column: *s_out = "DW_AT_decl_column"; return DW_DLV_OK; case DW_AT_decl_file: *s_out = "DW_AT_decl_file"; return DW_DLV_OK; case DW_AT_decl_line: *s_out = "DW_AT_decl_line"; return DW_DLV_OK; case DW_AT_declaration: *s_out = "DW_AT_declaration"; return DW_DLV_OK; case DW_AT_discr_list: *s_out = "DW_AT_discr_list"; return DW_DLV_OK; case DW_AT_encoding: *s_out = "DW_AT_encoding"; return DW_DLV_OK; case DW_AT_external: *s_out = "DW_AT_external"; return DW_DLV_OK; case DW_AT_frame_base: *s_out = "DW_AT_frame_base"; return DW_DLV_OK; case DW_AT_friend: *s_out = "DW_AT_friend"; return DW_DLV_OK; case DW_AT_identifier_case: *s_out = "DW_AT_identifier_case"; return DW_DLV_OK; case DW_AT_macro_info: *s_out = "DW_AT_macro_info"; return DW_DLV_OK; case DW_AT_namelist_item: *s_out = "DW_AT_namelist_item"; return DW_DLV_OK; case DW_AT_priority: *s_out = "DW_AT_priority"; return DW_DLV_OK; case DW_AT_segment: *s_out = "DW_AT_segment"; return DW_DLV_OK; case DW_AT_specification: *s_out = "DW_AT_specification"; return DW_DLV_OK; case DW_AT_static_link: *s_out = "DW_AT_static_link"; return DW_DLV_OK; case DW_AT_type: *s_out = "DW_AT_type"; return DW_DLV_OK; case DW_AT_use_location: *s_out = "DW_AT_use_location"; return DW_DLV_OK; case DW_AT_variable_parameter: *s_out = "DW_AT_variable_parameter"; return DW_DLV_OK; case DW_AT_virtuality: *s_out = "DW_AT_virtuality"; return DW_DLV_OK; case DW_AT_vtable_elem_location: *s_out = "DW_AT_vtable_elem_location"; return DW_DLV_OK; case DW_AT_allocated: *s_out = "DW_AT_allocated"; return DW_DLV_OK; case DW_AT_associated: *s_out = "DW_AT_associated"; return DW_DLV_OK; case DW_AT_data_location: *s_out = "DW_AT_data_location"; return DW_DLV_OK; case DW_AT_byte_stride: *s_out = "DW_AT_byte_stride"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x51. DW_AT_stride */ case DW_AT_entry_pc: *s_out = "DW_AT_entry_pc"; return DW_DLV_OK; case DW_AT_use_UTF8: *s_out = "DW_AT_use_UTF8"; return DW_DLV_OK; case DW_AT_extension: *s_out = "DW_AT_extension"; return DW_DLV_OK; case DW_AT_ranges: *s_out = "DW_AT_ranges"; return DW_DLV_OK; case DW_AT_trampoline: *s_out = "DW_AT_trampoline"; return DW_DLV_OK; case DW_AT_call_column: *s_out = "DW_AT_call_column"; return DW_DLV_OK; case DW_AT_call_file: *s_out = "DW_AT_call_file"; return DW_DLV_OK; case DW_AT_call_line: *s_out = "DW_AT_call_line"; return DW_DLV_OK; case DW_AT_description: *s_out = "DW_AT_description"; return DW_DLV_OK; case DW_AT_binary_scale: *s_out = "DW_AT_binary_scale"; return DW_DLV_OK; case DW_AT_decimal_scale: *s_out = "DW_AT_decimal_scale"; return DW_DLV_OK; case DW_AT_small: *s_out = "DW_AT_small"; return DW_DLV_OK; case DW_AT_decimal_sign: *s_out = "DW_AT_decimal_sign"; return DW_DLV_OK; case DW_AT_digit_count: *s_out = "DW_AT_digit_count"; return DW_DLV_OK; case DW_AT_picture_string: *s_out = "DW_AT_picture_string"; return DW_DLV_OK; case DW_AT_mutable: *s_out = "DW_AT_mutable"; return DW_DLV_OK; case DW_AT_threads_scaled: *s_out = "DW_AT_threads_scaled"; return DW_DLV_OK; case DW_AT_explicit: *s_out = "DW_AT_explicit"; return DW_DLV_OK; case DW_AT_object_pointer: *s_out = "DW_AT_object_pointer"; return DW_DLV_OK; case DW_AT_endianity: *s_out = "DW_AT_endianity"; return DW_DLV_OK; case DW_AT_elemental: *s_out = "DW_AT_elemental"; return DW_DLV_OK; case DW_AT_pure: *s_out = "DW_AT_pure"; return DW_DLV_OK; case DW_AT_recursive: *s_out = "DW_AT_recursive"; return DW_DLV_OK; case DW_AT_signature: *s_out = "DW_AT_signature"; return DW_DLV_OK; case DW_AT_main_subprogram: *s_out = "DW_AT_main_subprogram"; return DW_DLV_OK; case DW_AT_data_bit_offset: *s_out = "DW_AT_data_bit_offset"; return DW_DLV_OK; case DW_AT_const_expr: *s_out = "DW_AT_const_expr"; return DW_DLV_OK; case DW_AT_enum_class: *s_out = "DW_AT_enum_class"; return DW_DLV_OK; case DW_AT_linkage_name: *s_out = "DW_AT_linkage_name"; return DW_DLV_OK; case DW_AT_string_length_bit_size: *s_out = "DW_AT_string_length_bit_size"; return DW_DLV_OK; case DW_AT_string_length_byte_size: *s_out = "DW_AT_string_length_byte_size"; return DW_DLV_OK; case DW_AT_rank: *s_out = "DW_AT_rank"; return DW_DLV_OK; case DW_AT_str_offsets_base: *s_out = "DW_AT_str_offsets_base"; return DW_DLV_OK; case DW_AT_addr_base: *s_out = "DW_AT_addr_base"; return DW_DLV_OK; case DW_AT_rnglists_base: *s_out = "DW_AT_rnglists_base"; return DW_DLV_OK; case DW_AT_dwo_id: *s_out = "DW_AT_dwo_id"; return DW_DLV_OK; case DW_AT_dwo_name: *s_out = "DW_AT_dwo_name"; return DW_DLV_OK; case DW_AT_reference: *s_out = "DW_AT_reference"; return DW_DLV_OK; case DW_AT_rvalue_reference: *s_out = "DW_AT_rvalue_reference"; return DW_DLV_OK; case DW_AT_macros: *s_out = "DW_AT_macros"; return DW_DLV_OK; case DW_AT_call_all_calls: *s_out = "DW_AT_call_all_calls"; return DW_DLV_OK; case DW_AT_call_all_source_calls: *s_out = "DW_AT_call_all_source_calls"; return DW_DLV_OK; case DW_AT_call_all_tail_calls: *s_out = "DW_AT_call_all_tail_calls"; return DW_DLV_OK; case DW_AT_call_return_pc: *s_out = "DW_AT_call_return_pc"; return DW_DLV_OK; case DW_AT_call_value: *s_out = "DW_AT_call_value"; return DW_DLV_OK; case DW_AT_call_origin: *s_out = "DW_AT_call_origin"; return DW_DLV_OK; case DW_AT_call_parameter: *s_out = "DW_AT_call_parameter"; return DW_DLV_OK; case DW_AT_call_pc: *s_out = "DW_AT_call_pc"; return DW_DLV_OK; case DW_AT_call_tail_call: *s_out = "DW_AT_call_tail_call"; return DW_DLV_OK; case DW_AT_call_target: *s_out = "DW_AT_call_target"; return DW_DLV_OK; case DW_AT_call_target_clobbered: *s_out = "DW_AT_call_target_clobbered"; return DW_DLV_OK; case DW_AT_call_data_location: *s_out = "DW_AT_call_data_location"; return DW_DLV_OK; case DW_AT_call_data_value: *s_out = "DW_AT_call_data_value"; return DW_DLV_OK; case DW_AT_noreturn: *s_out = "DW_AT_noreturn"; return DW_DLV_OK; case DW_AT_alignment: *s_out = "DW_AT_alignment"; return DW_DLV_OK; case DW_AT_export_symbols: *s_out = "DW_AT_export_symbols"; return DW_DLV_OK; case DW_AT_deleted: *s_out = "DW_AT_deleted"; return DW_DLV_OK; case DW_AT_defaulted: *s_out = "DW_AT_defaulted"; return DW_DLV_OK; case DW_AT_loclists_base: *s_out = "DW_AT_loclists_base"; return DW_DLV_OK; case DW_AT_HP_block_index: *s_out = "DW_AT_HP_block_index"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2000. DW_AT_lo_user */ case DW_AT_MIPS_fde: *s_out = "DW_AT_MIPS_fde"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2001. DW_AT_HP_unmodifiable */ /* Skipping alternate spelling of value 0x2001. DW_AT_CPQ_discontig_ranges */ case DW_AT_MIPS_loop_begin: *s_out = "DW_AT_MIPS_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2002. DW_AT_CPQ_semantic_events */ case DW_AT_MIPS_tail_loop_begin: *s_out = "DW_AT_MIPS_tail_loop_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2003. DW_AT_CPQ_split_lifetimes_var */ case DW_AT_MIPS_epilog_begin: *s_out = "DW_AT_MIPS_epilog_begin"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2004. DW_AT_CPQ_split_lifetimes_rtn */ case DW_AT_MIPS_loop_unroll_factor: *s_out = "DW_AT_MIPS_loop_unroll_factor"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2005. DW_AT_CPQ_prologue_length */ case DW_AT_MIPS_software_pipeline_depth: *s_out = "DW_AT_MIPS_software_pipeline_depth"; return DW_DLV_OK; case DW_AT_MIPS_linkage_name: *s_out = "DW_AT_MIPS_linkage_name"; return DW_DLV_OK; case DW_AT_MIPS_stride: *s_out = "DW_AT_MIPS_stride"; return DW_DLV_OK; case DW_AT_MIPS_abstract_name: *s_out = "DW_AT_MIPS_abstract_name"; return DW_DLV_OK; case DW_AT_MIPS_clone_origin: *s_out = "DW_AT_MIPS_clone_origin"; return DW_DLV_OK; case DW_AT_MIPS_has_inlines: *s_out = "DW_AT_MIPS_has_inlines"; return DW_DLV_OK; case DW_AT_MIPS_stride_byte: *s_out = "DW_AT_MIPS_stride_byte"; return DW_DLV_OK; case DW_AT_MIPS_stride_elem: *s_out = "DW_AT_MIPS_stride_elem"; return DW_DLV_OK; case DW_AT_MIPS_ptr_dopetype: *s_out = "DW_AT_MIPS_ptr_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_allocatable_dopetype: *s_out = "DW_AT_MIPS_allocatable_dopetype"; return DW_DLV_OK; case DW_AT_MIPS_assumed_shape_dopetype: *s_out = "DW_AT_MIPS_assumed_shape_dopetype"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2010. DW_AT_HP_actuals_stmt_list */ case DW_AT_MIPS_assumed_size: *s_out = "DW_AT_MIPS_assumed_size"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2011. DW_AT_HP_proc_per_section */ case DW_AT_HP_raw_data_ptr: *s_out = "DW_AT_HP_raw_data_ptr"; return DW_DLV_OK; case DW_AT_HP_pass_by_reference: *s_out = "DW_AT_HP_pass_by_reference"; return DW_DLV_OK; case DW_AT_HP_opt_level: *s_out = "DW_AT_HP_opt_level"; return DW_DLV_OK; case DW_AT_HP_prof_version_id: *s_out = "DW_AT_HP_prof_version_id"; return DW_DLV_OK; case DW_AT_HP_opt_flags: *s_out = "DW_AT_HP_opt_flags"; return DW_DLV_OK; case DW_AT_HP_cold_region_low_pc: *s_out = "DW_AT_HP_cold_region_low_pc"; return DW_DLV_OK; case DW_AT_HP_cold_region_high_pc: *s_out = "DW_AT_HP_cold_region_high_pc"; return DW_DLV_OK; case DW_AT_HP_all_variables_modifiable: *s_out = "DW_AT_HP_all_variables_modifiable"; return DW_DLV_OK; case DW_AT_HP_linkage_name: *s_out = "DW_AT_HP_linkage_name"; return DW_DLV_OK; case DW_AT_HP_prof_flags: *s_out = "DW_AT_HP_prof_flags"; return DW_DLV_OK; case DW_AT_INTEL_other_endian: *s_out = "DW_AT_INTEL_other_endian"; return DW_DLV_OK; case DW_AT_sf_names: *s_out = "DW_AT_sf_names"; return DW_DLV_OK; case DW_AT_src_info: *s_out = "DW_AT_src_info"; return DW_DLV_OK; case DW_AT_mac_info: *s_out = "DW_AT_mac_info"; return DW_DLV_OK; case DW_AT_src_coords: *s_out = "DW_AT_src_coords"; return DW_DLV_OK; case DW_AT_body_begin: *s_out = "DW_AT_body_begin"; return DW_DLV_OK; case DW_AT_body_end: *s_out = "DW_AT_body_end"; return DW_DLV_OK; case DW_AT_GNU_vector: *s_out = "DW_AT_GNU_vector"; return DW_DLV_OK; case DW_AT_GNU_guarded_by: *s_out = "DW_AT_GNU_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded_by: *s_out = "DW_AT_GNU_pt_guarded_by"; return DW_DLV_OK; case DW_AT_GNU_guarded: *s_out = "DW_AT_GNU_guarded"; return DW_DLV_OK; case DW_AT_GNU_pt_guarded: *s_out = "DW_AT_GNU_pt_guarded"; return DW_DLV_OK; case DW_AT_GNU_locks_excluded: *s_out = "DW_AT_GNU_locks_excluded"; return DW_DLV_OK; case DW_AT_GNU_exclusive_locks_required: *s_out = "DW_AT_GNU_exclusive_locks_required"; return DW_DLV_OK; case DW_AT_GNU_shared_locks_required: *s_out = "DW_AT_GNU_shared_locks_required"; return DW_DLV_OK; case DW_AT_GNU_odr_signature: *s_out = "DW_AT_GNU_odr_signature"; return DW_DLV_OK; case DW_AT_GNU_template_name: *s_out = "DW_AT_GNU_template_name"; return DW_DLV_OK; case DW_AT_GNU_call_site_value: *s_out = "DW_AT_GNU_call_site_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_data_value: *s_out = "DW_AT_GNU_call_site_data_value"; return DW_DLV_OK; case DW_AT_GNU_call_site_target: *s_out = "DW_AT_GNU_call_site_target"; return DW_DLV_OK; case DW_AT_GNU_call_site_target_clobbered: *s_out = "DW_AT_GNU_call_site_target_clobbered"; return DW_DLV_OK; case DW_AT_GNU_tail_call: *s_out = "DW_AT_GNU_tail_call"; return DW_DLV_OK; case DW_AT_GNU_all_tail_call_sites: *s_out = "DW_AT_GNU_all_tail_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_call_sites: *s_out = "DW_AT_GNU_all_call_sites"; return DW_DLV_OK; case DW_AT_GNU_all_source_call_sites: *s_out = "DW_AT_GNU_all_source_call_sites"; return DW_DLV_OK; case DW_AT_GNU_macros: *s_out = "DW_AT_GNU_macros"; return DW_DLV_OK; case DW_AT_GNU_dwo_name: *s_out = "DW_AT_GNU_dwo_name"; return DW_DLV_OK; case DW_AT_GNU_dwo_id: *s_out = "DW_AT_GNU_dwo_id"; return DW_DLV_OK; case DW_AT_GNU_ranges_base: *s_out = "DW_AT_GNU_ranges_base"; return DW_DLV_OK; case DW_AT_GNU_addr_base: *s_out = "DW_AT_GNU_addr_base"; return DW_DLV_OK; case DW_AT_GNU_pubnames: *s_out = "DW_AT_GNU_pubnames"; return DW_DLV_OK; case DW_AT_GNU_pubtypes: *s_out = "DW_AT_GNU_pubtypes"; return DW_DLV_OK; case DW_AT_GNU_discriminator: *s_out = "DW_AT_GNU_discriminator"; return DW_DLV_OK; case DW_AT_SUN_template: *s_out = "DW_AT_SUN_template"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x2201. DW_AT_VMS_rtnbeg_pd_address */ case DW_AT_SUN_alignment: *s_out = "DW_AT_SUN_alignment"; return DW_DLV_OK; case DW_AT_SUN_vtable: *s_out = "DW_AT_SUN_vtable"; return DW_DLV_OK; case DW_AT_SUN_count_guarantee: *s_out = "DW_AT_SUN_count_guarantee"; return DW_DLV_OK; case DW_AT_SUN_command_line: *s_out = "DW_AT_SUN_command_line"; return DW_DLV_OK; case DW_AT_SUN_vbase: *s_out = "DW_AT_SUN_vbase"; return DW_DLV_OK; case DW_AT_SUN_compile_options: *s_out = "DW_AT_SUN_compile_options"; return DW_DLV_OK; case DW_AT_SUN_language: *s_out = "DW_AT_SUN_language"; return DW_DLV_OK; case DW_AT_SUN_browser_file: *s_out = "DW_AT_SUN_browser_file"; return DW_DLV_OK; case DW_AT_SUN_vtable_abi: *s_out = "DW_AT_SUN_vtable_abi"; return DW_DLV_OK; case DW_AT_SUN_func_offsets: *s_out = "DW_AT_SUN_func_offsets"; return DW_DLV_OK; case DW_AT_SUN_cf_kind: *s_out = "DW_AT_SUN_cf_kind"; return DW_DLV_OK; case DW_AT_SUN_vtable_index: *s_out = "DW_AT_SUN_vtable_index"; return DW_DLV_OK; case DW_AT_SUN_omp_tpriv_addr: *s_out = "DW_AT_SUN_omp_tpriv_addr"; return DW_DLV_OK; case DW_AT_SUN_omp_child_func: *s_out = "DW_AT_SUN_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_func_offset: *s_out = "DW_AT_SUN_func_offset"; return DW_DLV_OK; case DW_AT_SUN_memop_type_ref: *s_out = "DW_AT_SUN_memop_type_ref"; return DW_DLV_OK; case DW_AT_SUN_profile_id: *s_out = "DW_AT_SUN_profile_id"; return DW_DLV_OK; case DW_AT_SUN_memop_signature: *s_out = "DW_AT_SUN_memop_signature"; return DW_DLV_OK; case DW_AT_SUN_obj_dir: *s_out = "DW_AT_SUN_obj_dir"; return DW_DLV_OK; case DW_AT_SUN_obj_file: *s_out = "DW_AT_SUN_obj_file"; return DW_DLV_OK; case DW_AT_SUN_original_name: *s_out = "DW_AT_SUN_original_name"; return DW_DLV_OK; case DW_AT_SUN_hwcprof_signature: *s_out = "DW_AT_SUN_hwcprof_signature"; return DW_DLV_OK; case DW_AT_SUN_amd64_parmdump: *s_out = "DW_AT_SUN_amd64_parmdump"; return DW_DLV_OK; case DW_AT_SUN_part_link_name: *s_out = "DW_AT_SUN_part_link_name"; return DW_DLV_OK; case DW_AT_SUN_link_name: *s_out = "DW_AT_SUN_link_name"; return DW_DLV_OK; case DW_AT_SUN_pass_with_const: *s_out = "DW_AT_SUN_pass_with_const"; return DW_DLV_OK; case DW_AT_SUN_return_with_const: *s_out = "DW_AT_SUN_return_with_const"; return DW_DLV_OK; case DW_AT_SUN_import_by_name: *s_out = "DW_AT_SUN_import_by_name"; return DW_DLV_OK; case DW_AT_SUN_f90_pointer: *s_out = "DW_AT_SUN_f90_pointer"; return DW_DLV_OK; case DW_AT_SUN_pass_by_ref: *s_out = "DW_AT_SUN_pass_by_ref"; return DW_DLV_OK; case DW_AT_SUN_f90_allocatable: *s_out = "DW_AT_SUN_f90_allocatable"; return DW_DLV_OK; case DW_AT_SUN_f90_assumed_shape_array: *s_out = "DW_AT_SUN_f90_assumed_shape_array"; return DW_DLV_OK; case DW_AT_SUN_c_vla: *s_out = "DW_AT_SUN_c_vla"; return DW_DLV_OK; case DW_AT_SUN_return_value_ptr: *s_out = "DW_AT_SUN_return_value_ptr"; return DW_DLV_OK; case DW_AT_SUN_dtor_start: *s_out = "DW_AT_SUN_dtor_start"; return DW_DLV_OK; case DW_AT_SUN_dtor_length: *s_out = "DW_AT_SUN_dtor_length"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_initial: *s_out = "DW_AT_SUN_dtor_state_initial"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_final: *s_out = "DW_AT_SUN_dtor_state_final"; return DW_DLV_OK; case DW_AT_SUN_dtor_state_deltas: *s_out = "DW_AT_SUN_dtor_state_deltas"; return DW_DLV_OK; case DW_AT_SUN_import_by_lname: *s_out = "DW_AT_SUN_import_by_lname"; return DW_DLV_OK; case DW_AT_SUN_f90_use_only: *s_out = "DW_AT_SUN_f90_use_only"; return DW_DLV_OK; case DW_AT_SUN_namelist_spec: *s_out = "DW_AT_SUN_namelist_spec"; return DW_DLV_OK; case DW_AT_SUN_is_omp_child_func: *s_out = "DW_AT_SUN_is_omp_child_func"; return DW_DLV_OK; case DW_AT_SUN_fortran_main_alias: *s_out = "DW_AT_SUN_fortran_main_alias"; return DW_DLV_OK; case DW_AT_SUN_fortran_based: *s_out = "DW_AT_SUN_fortran_based"; return DW_DLV_OK; case DW_AT_ALTIUM_loclist: *s_out = "DW_AT_ALTIUM_loclist"; return DW_DLV_OK; case DW_AT_use_GNAT_descriptive_type: *s_out = "DW_AT_use_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNAT_descriptive_type: *s_out = "DW_AT_GNAT_descriptive_type"; return DW_DLV_OK; case DW_AT_GNU_numerator: *s_out = "DW_AT_GNU_numerator"; return DW_DLV_OK; case DW_AT_GNU_denominator: *s_out = "DW_AT_GNU_denominator"; return DW_DLV_OK; case DW_AT_GNU_bias: *s_out = "DW_AT_GNU_bias"; return DW_DLV_OK; case DW_AT_go_kind: *s_out = "DW_AT_go_kind"; return DW_DLV_OK; case DW_AT_go_key: *s_out = "DW_AT_go_key"; return DW_DLV_OK; case DW_AT_go_elem: *s_out = "DW_AT_go_elem"; return DW_DLV_OK; case DW_AT_go_embedded_field: *s_out = "DW_AT_go_embedded_field"; return DW_DLV_OK; case DW_AT_go_runtime_type: *s_out = "DW_AT_go_runtime_type"; return DW_DLV_OK; case DW_AT_upc_threads_scaled: *s_out = "DW_AT_upc_threads_scaled"; return DW_DLV_OK; case DW_AT_PGI_lbase: *s_out = "DW_AT_PGI_lbase"; return DW_DLV_OK; case DW_AT_PGI_soffset: *s_out = "DW_AT_PGI_soffset"; return DW_DLV_OK; case DW_AT_PGI_lstride: *s_out = "DW_AT_PGI_lstride"; return DW_DLV_OK; case DW_AT_APPLE_optimized: *s_out = "DW_AT_APPLE_optimized"; return DW_DLV_OK; case DW_AT_APPLE_flags: *s_out = "DW_AT_APPLE_flags"; return DW_DLV_OK; case DW_AT_APPLE_isa: *s_out = "DW_AT_APPLE_isa"; return DW_DLV_OK; case DW_AT_APPLE_block: *s_out = "DW_AT_APPLE_block"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3fe4. DW_AT_APPLE_closure */ case DW_AT_APPLE_major_runtime_vers: *s_out = "DW_AT_APPLE_major_runtime_vers"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3fe5. DW_AT_APPLE_major_runtime_vers */ case DW_AT_APPLE_runtime_class: *s_out = "DW_AT_APPLE_runtime_class"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x3fe6. DW_AT_APPLE_runtime_class */ case DW_AT_APPLE_omit_frame_ptr: *s_out = "DW_AT_APPLE_omit_frame_ptr"; return DW_DLV_OK; case DW_AT_hi_user: *s_out = "DW_AT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_OP_name (unsigned int val,const char ** s_out) { switch (val) { case DW_OP_addr: *s_out = "DW_OP_addr"; return DW_DLV_OK; case DW_OP_deref: *s_out = "DW_OP_deref"; return DW_DLV_OK; case DW_OP_const1u: *s_out = "DW_OP_const1u"; return DW_DLV_OK; case DW_OP_const1s: *s_out = "DW_OP_const1s"; return DW_DLV_OK; case DW_OP_const2u: *s_out = "DW_OP_const2u"; return DW_DLV_OK; case DW_OP_const2s: *s_out = "DW_OP_const2s"; return DW_DLV_OK; case DW_OP_const4u: *s_out = "DW_OP_const4u"; return DW_DLV_OK; case DW_OP_const4s: *s_out = "DW_OP_const4s"; return DW_DLV_OK; case DW_OP_const8u: *s_out = "DW_OP_const8u"; return DW_DLV_OK; case DW_OP_const8s: *s_out = "DW_OP_const8s"; return DW_DLV_OK; case DW_OP_constu: *s_out = "DW_OP_constu"; return DW_DLV_OK; case DW_OP_consts: *s_out = "DW_OP_consts"; return DW_DLV_OK; case DW_OP_dup: *s_out = "DW_OP_dup"; return DW_DLV_OK; case DW_OP_drop: *s_out = "DW_OP_drop"; return DW_DLV_OK; case DW_OP_over: *s_out = "DW_OP_over"; return DW_DLV_OK; case DW_OP_pick: *s_out = "DW_OP_pick"; return DW_DLV_OK; case DW_OP_swap: *s_out = "DW_OP_swap"; return DW_DLV_OK; case DW_OP_rot: *s_out = "DW_OP_rot"; return DW_DLV_OK; case DW_OP_xderef: *s_out = "DW_OP_xderef"; return DW_DLV_OK; case DW_OP_abs: *s_out = "DW_OP_abs"; return DW_DLV_OK; case DW_OP_and: *s_out = "DW_OP_and"; return DW_DLV_OK; case DW_OP_div: *s_out = "DW_OP_div"; return DW_DLV_OK; case DW_OP_minus: *s_out = "DW_OP_minus"; return DW_DLV_OK; case DW_OP_mod: *s_out = "DW_OP_mod"; return DW_DLV_OK; case DW_OP_mul: *s_out = "DW_OP_mul"; return DW_DLV_OK; case DW_OP_neg: *s_out = "DW_OP_neg"; return DW_DLV_OK; case DW_OP_not: *s_out = "DW_OP_not"; return DW_DLV_OK; case DW_OP_or: *s_out = "DW_OP_or"; return DW_DLV_OK; case DW_OP_plus: *s_out = "DW_OP_plus"; return DW_DLV_OK; case DW_OP_plus_uconst: *s_out = "DW_OP_plus_uconst"; return DW_DLV_OK; case DW_OP_shl: *s_out = "DW_OP_shl"; return DW_DLV_OK; case DW_OP_shr: *s_out = "DW_OP_shr"; return DW_DLV_OK; case DW_OP_shra: *s_out = "DW_OP_shra"; return DW_DLV_OK; case DW_OP_xor: *s_out = "DW_OP_xor"; return DW_DLV_OK; case DW_OP_bra: *s_out = "DW_OP_bra"; return DW_DLV_OK; case DW_OP_eq: *s_out = "DW_OP_eq"; return DW_DLV_OK; case DW_OP_ge: *s_out = "DW_OP_ge"; return DW_DLV_OK; case DW_OP_gt: *s_out = "DW_OP_gt"; return DW_DLV_OK; case DW_OP_le: *s_out = "DW_OP_le"; return DW_DLV_OK; case DW_OP_lt: *s_out = "DW_OP_lt"; return DW_DLV_OK; case DW_OP_ne: *s_out = "DW_OP_ne"; return DW_DLV_OK; case DW_OP_skip: *s_out = "DW_OP_skip"; return DW_DLV_OK; case DW_OP_lit0: *s_out = "DW_OP_lit0"; return DW_DLV_OK; case DW_OP_lit1: *s_out = "DW_OP_lit1"; return DW_DLV_OK; case DW_OP_lit2: *s_out = "DW_OP_lit2"; return DW_DLV_OK; case DW_OP_lit3: *s_out = "DW_OP_lit3"; return DW_DLV_OK; case DW_OP_lit4: *s_out = "DW_OP_lit4"; return DW_DLV_OK; case DW_OP_lit5: *s_out = "DW_OP_lit5"; return DW_DLV_OK; case DW_OP_lit6: *s_out = "DW_OP_lit6"; return DW_DLV_OK; case DW_OP_lit7: *s_out = "DW_OP_lit7"; return DW_DLV_OK; case DW_OP_lit8: *s_out = "DW_OP_lit8"; return DW_DLV_OK; case DW_OP_lit9: *s_out = "DW_OP_lit9"; return DW_DLV_OK; case DW_OP_lit10: *s_out = "DW_OP_lit10"; return DW_DLV_OK; case DW_OP_lit11: *s_out = "DW_OP_lit11"; return DW_DLV_OK; case DW_OP_lit12: *s_out = "DW_OP_lit12"; return DW_DLV_OK; case DW_OP_lit13: *s_out = "DW_OP_lit13"; return DW_DLV_OK; case DW_OP_lit14: *s_out = "DW_OP_lit14"; return DW_DLV_OK; case DW_OP_lit15: *s_out = "DW_OP_lit15"; return DW_DLV_OK; case DW_OP_lit16: *s_out = "DW_OP_lit16"; return DW_DLV_OK; case DW_OP_lit17: *s_out = "DW_OP_lit17"; return DW_DLV_OK; case DW_OP_lit18: *s_out = "DW_OP_lit18"; return DW_DLV_OK; case DW_OP_lit19: *s_out = "DW_OP_lit19"; return DW_DLV_OK; case DW_OP_lit20: *s_out = "DW_OP_lit20"; return DW_DLV_OK; case DW_OP_lit21: *s_out = "DW_OP_lit21"; return DW_DLV_OK; case DW_OP_lit22: *s_out = "DW_OP_lit22"; return DW_DLV_OK; case DW_OP_lit23: *s_out = "DW_OP_lit23"; return DW_DLV_OK; case DW_OP_lit24: *s_out = "DW_OP_lit24"; return DW_DLV_OK; case DW_OP_lit25: *s_out = "DW_OP_lit25"; return DW_DLV_OK; case DW_OP_lit26: *s_out = "DW_OP_lit26"; return DW_DLV_OK; case DW_OP_lit27: *s_out = "DW_OP_lit27"; return DW_DLV_OK; case DW_OP_lit28: *s_out = "DW_OP_lit28"; return DW_DLV_OK; case DW_OP_lit29: *s_out = "DW_OP_lit29"; return DW_DLV_OK; case DW_OP_lit30: *s_out = "DW_OP_lit30"; return DW_DLV_OK; case DW_OP_lit31: *s_out = "DW_OP_lit31"; return DW_DLV_OK; case DW_OP_reg0: *s_out = "DW_OP_reg0"; return DW_DLV_OK; case DW_OP_reg1: *s_out = "DW_OP_reg1"; return DW_DLV_OK; case DW_OP_reg2: *s_out = "DW_OP_reg2"; return DW_DLV_OK; case DW_OP_reg3: *s_out = "DW_OP_reg3"; return DW_DLV_OK; case DW_OP_reg4: *s_out = "DW_OP_reg4"; return DW_DLV_OK; case DW_OP_reg5: *s_out = "DW_OP_reg5"; return DW_DLV_OK; case DW_OP_reg6: *s_out = "DW_OP_reg6"; return DW_DLV_OK; case DW_OP_reg7: *s_out = "DW_OP_reg7"; return DW_DLV_OK; case DW_OP_reg8: *s_out = "DW_OP_reg8"; return DW_DLV_OK; case DW_OP_reg9: *s_out = "DW_OP_reg9"; return DW_DLV_OK; case DW_OP_reg10: *s_out = "DW_OP_reg10"; return DW_DLV_OK; case DW_OP_reg11: *s_out = "DW_OP_reg11"; return DW_DLV_OK; case DW_OP_reg12: *s_out = "DW_OP_reg12"; return DW_DLV_OK; case DW_OP_reg13: *s_out = "DW_OP_reg13"; return DW_DLV_OK; case DW_OP_reg14: *s_out = "DW_OP_reg14"; return DW_DLV_OK; case DW_OP_reg15: *s_out = "DW_OP_reg15"; return DW_DLV_OK; case DW_OP_reg16: *s_out = "DW_OP_reg16"; return DW_DLV_OK; case DW_OP_reg17: *s_out = "DW_OP_reg17"; return DW_DLV_OK; case DW_OP_reg18: *s_out = "DW_OP_reg18"; return DW_DLV_OK; case DW_OP_reg19: *s_out = "DW_OP_reg19"; return DW_DLV_OK; case DW_OP_reg20: *s_out = "DW_OP_reg20"; return DW_DLV_OK; case DW_OP_reg21: *s_out = "DW_OP_reg21"; return DW_DLV_OK; case DW_OP_reg22: *s_out = "DW_OP_reg22"; return DW_DLV_OK; case DW_OP_reg23: *s_out = "DW_OP_reg23"; return DW_DLV_OK; case DW_OP_reg24: *s_out = "DW_OP_reg24"; return DW_DLV_OK; case DW_OP_reg25: *s_out = "DW_OP_reg25"; return DW_DLV_OK; case DW_OP_reg26: *s_out = "DW_OP_reg26"; return DW_DLV_OK; case DW_OP_reg27: *s_out = "DW_OP_reg27"; return DW_DLV_OK; case DW_OP_reg28: *s_out = "DW_OP_reg28"; return DW_DLV_OK; case DW_OP_reg29: *s_out = "DW_OP_reg29"; return DW_DLV_OK; case DW_OP_reg30: *s_out = "DW_OP_reg30"; return DW_DLV_OK; case DW_OP_reg31: *s_out = "DW_OP_reg31"; return DW_DLV_OK; case DW_OP_breg0: *s_out = "DW_OP_breg0"; return DW_DLV_OK; case DW_OP_breg1: *s_out = "DW_OP_breg1"; return DW_DLV_OK; case DW_OP_breg2: *s_out = "DW_OP_breg2"; return DW_DLV_OK; case DW_OP_breg3: *s_out = "DW_OP_breg3"; return DW_DLV_OK; case DW_OP_breg4: *s_out = "DW_OP_breg4"; return DW_DLV_OK; case DW_OP_breg5: *s_out = "DW_OP_breg5"; return DW_DLV_OK; case DW_OP_breg6: *s_out = "DW_OP_breg6"; return DW_DLV_OK; case DW_OP_breg7: *s_out = "DW_OP_breg7"; return DW_DLV_OK; case DW_OP_breg8: *s_out = "DW_OP_breg8"; return DW_DLV_OK; case DW_OP_breg9: *s_out = "DW_OP_breg9"; return DW_DLV_OK; case DW_OP_breg10: *s_out = "DW_OP_breg10"; return DW_DLV_OK; case DW_OP_breg11: *s_out = "DW_OP_breg11"; return DW_DLV_OK; case DW_OP_breg12: *s_out = "DW_OP_breg12"; return DW_DLV_OK; case DW_OP_breg13: *s_out = "DW_OP_breg13"; return DW_DLV_OK; case DW_OP_breg14: *s_out = "DW_OP_breg14"; return DW_DLV_OK; case DW_OP_breg15: *s_out = "DW_OP_breg15"; return DW_DLV_OK; case DW_OP_breg16: *s_out = "DW_OP_breg16"; return DW_DLV_OK; case DW_OP_breg17: *s_out = "DW_OP_breg17"; return DW_DLV_OK; case DW_OP_breg18: *s_out = "DW_OP_breg18"; return DW_DLV_OK; case DW_OP_breg19: *s_out = "DW_OP_breg19"; return DW_DLV_OK; case DW_OP_breg20: *s_out = "DW_OP_breg20"; return DW_DLV_OK; case DW_OP_breg21: *s_out = "DW_OP_breg21"; return DW_DLV_OK; case DW_OP_breg22: *s_out = "DW_OP_breg22"; return DW_DLV_OK; case DW_OP_breg23: *s_out = "DW_OP_breg23"; return DW_DLV_OK; case DW_OP_breg24: *s_out = "DW_OP_breg24"; return DW_DLV_OK; case DW_OP_breg25: *s_out = "DW_OP_breg25"; return DW_DLV_OK; case DW_OP_breg26: *s_out = "DW_OP_breg26"; return DW_DLV_OK; case DW_OP_breg27: *s_out = "DW_OP_breg27"; return DW_DLV_OK; case DW_OP_breg28: *s_out = "DW_OP_breg28"; return DW_DLV_OK; case DW_OP_breg29: *s_out = "DW_OP_breg29"; return DW_DLV_OK; case DW_OP_breg30: *s_out = "DW_OP_breg30"; return DW_DLV_OK; case DW_OP_breg31: *s_out = "DW_OP_breg31"; return DW_DLV_OK; case DW_OP_regx: *s_out = "DW_OP_regx"; return DW_DLV_OK; case DW_OP_fbreg: *s_out = "DW_OP_fbreg"; return DW_DLV_OK; case DW_OP_bregx: *s_out = "DW_OP_bregx"; return DW_DLV_OK; case DW_OP_piece: *s_out = "DW_OP_piece"; return DW_DLV_OK; case DW_OP_deref_size: *s_out = "DW_OP_deref_size"; return DW_DLV_OK; case DW_OP_xderef_size: *s_out = "DW_OP_xderef_size"; return DW_DLV_OK; case DW_OP_nop: *s_out = "DW_OP_nop"; return DW_DLV_OK; case DW_OP_push_object_address: *s_out = "DW_OP_push_object_address"; return DW_DLV_OK; case DW_OP_call2: *s_out = "DW_OP_call2"; return DW_DLV_OK; case DW_OP_call4: *s_out = "DW_OP_call4"; return DW_DLV_OK; case DW_OP_call_ref: *s_out = "DW_OP_call_ref"; return DW_DLV_OK; case DW_OP_form_tls_address: *s_out = "DW_OP_form_tls_address"; return DW_DLV_OK; case DW_OP_call_frame_cfa: *s_out = "DW_OP_call_frame_cfa"; return DW_DLV_OK; case DW_OP_bit_piece: *s_out = "DW_OP_bit_piece"; return DW_DLV_OK; case DW_OP_implicit_value: *s_out = "DW_OP_implicit_value"; return DW_DLV_OK; case DW_OP_stack_value: *s_out = "DW_OP_stack_value"; return DW_DLV_OK; case DW_OP_implicit_pointer: *s_out = "DW_OP_implicit_pointer"; return DW_DLV_OK; case DW_OP_addrx: *s_out = "DW_OP_addrx"; return DW_DLV_OK; case DW_OP_constx: *s_out = "DW_OP_constx"; return DW_DLV_OK; case DW_OP_entry_value: *s_out = "DW_OP_entry_value"; return DW_DLV_OK; case DW_OP_const_type: *s_out = "DW_OP_const_type"; return DW_DLV_OK; case DW_OP_regval_type: *s_out = "DW_OP_regval_type"; return DW_DLV_OK; case DW_OP_deref_type: *s_out = "DW_OP_deref_type"; return DW_DLV_OK; case DW_OP_xderef_type: *s_out = "DW_OP_xderef_type"; return DW_DLV_OK; case DW_OP_convert: *s_out = "DW_OP_convert"; return DW_DLV_OK; case DW_OP_reinterpret: *s_out = "DW_OP_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_push_tls_address: *s_out = "DW_OP_GNU_push_tls_address"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xe0. DW_OP_lo_user */ /* Skipping alternate spelling of value 0xe0. DW_OP_HP_unknown */ case DW_OP_HP_is_value: *s_out = "DW_OP_HP_is_value"; return DW_DLV_OK; case DW_OP_HP_fltconst4: *s_out = "DW_OP_HP_fltconst4"; return DW_DLV_OK; case DW_OP_HP_fltconst8: *s_out = "DW_OP_HP_fltconst8"; return DW_DLV_OK; case DW_OP_HP_mod_range: *s_out = "DW_OP_HP_mod_range"; return DW_DLV_OK; case DW_OP_HP_unmod_range: *s_out = "DW_OP_HP_unmod_range"; return DW_DLV_OK; case DW_OP_HP_tls: *s_out = "DW_OP_HP_tls"; return DW_DLV_OK; case DW_OP_INTEL_bit_piece: *s_out = "DW_OP_INTEL_bit_piece"; return DW_DLV_OK; case DW_OP_GNU_uninit: *s_out = "DW_OP_GNU_uninit"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xf0. DW_OP_APPLE_uninit */ case DW_OP_GNU_encoded_addr: *s_out = "DW_OP_GNU_encoded_addr"; return DW_DLV_OK; case DW_OP_GNU_implicit_pointer: *s_out = "DW_OP_GNU_implicit_pointer"; return DW_DLV_OK; case DW_OP_GNU_entry_value: *s_out = "DW_OP_GNU_entry_value"; return DW_DLV_OK; case DW_OP_GNU_const_type: *s_out = "DW_OP_GNU_const_type"; return DW_DLV_OK; case DW_OP_GNU_regval_type: *s_out = "DW_OP_GNU_regval_type"; return DW_DLV_OK; case DW_OP_GNU_deref_type: *s_out = "DW_OP_GNU_deref_type"; return DW_DLV_OK; case DW_OP_GNU_convert: *s_out = "DW_OP_GNU_convert"; return DW_DLV_OK; case DW_OP_PGI_omp_thread_num: *s_out = "DW_OP_PGI_omp_thread_num"; return DW_DLV_OK; case DW_OP_GNU_reinterpret: *s_out = "DW_OP_GNU_reinterpret"; return DW_DLV_OK; case DW_OP_GNU_parameter_ref: *s_out = "DW_OP_GNU_parameter_ref"; return DW_DLV_OK; case DW_OP_GNU_addr_index: *s_out = "DW_OP_GNU_addr_index"; return DW_DLV_OK; case DW_OP_GNU_const_index: *s_out = "DW_OP_GNU_const_index"; return DW_DLV_OK; case DW_OP_hi_user: *s_out = "DW_OP_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ATE_address: *s_out = "DW_ATE_address"; return DW_DLV_OK; case DW_ATE_boolean: *s_out = "DW_ATE_boolean"; return DW_DLV_OK; case DW_ATE_complex_float: *s_out = "DW_ATE_complex_float"; return DW_DLV_OK; case DW_ATE_float: *s_out = "DW_ATE_float"; return DW_DLV_OK; case DW_ATE_signed: *s_out = "DW_ATE_signed"; return DW_DLV_OK; case DW_ATE_signed_char: *s_out = "DW_ATE_signed_char"; return DW_DLV_OK; case DW_ATE_unsigned: *s_out = "DW_ATE_unsigned"; return DW_DLV_OK; case DW_ATE_unsigned_char: *s_out = "DW_ATE_unsigned_char"; return DW_DLV_OK; case DW_ATE_imaginary_float: *s_out = "DW_ATE_imaginary_float"; return DW_DLV_OK; case DW_ATE_packed_decimal: *s_out = "DW_ATE_packed_decimal"; return DW_DLV_OK; case DW_ATE_numeric_string: *s_out = "DW_ATE_numeric_string"; return DW_DLV_OK; case DW_ATE_edited: *s_out = "DW_ATE_edited"; return DW_DLV_OK; case DW_ATE_signed_fixed: *s_out = "DW_ATE_signed_fixed"; return DW_DLV_OK; case DW_ATE_unsigned_fixed: *s_out = "DW_ATE_unsigned_fixed"; return DW_DLV_OK; case DW_ATE_decimal_float: *s_out = "DW_ATE_decimal_float"; return DW_DLV_OK; case DW_ATE_UTF: *s_out = "DW_ATE_UTF"; return DW_DLV_OK; case DW_ATE_UCS: *s_out = "DW_ATE_UCS"; return DW_DLV_OK; case DW_ATE_ASCII: *s_out = "DW_ATE_ASCII"; return DW_DLV_OK; case DW_ATE_ALTIUM_fract: *s_out = "DW_ATE_ALTIUM_fract"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_ATE_lo_user */ /* Skipping alternate spelling of value 0x80. DW_ATE_HP_float80 */ case DW_ATE_ALTIUM_accum: *s_out = "DW_ATE_ALTIUM_accum"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x81. DW_ATE_HP_complex_float80 */ case DW_ATE_HP_float128: *s_out = "DW_ATE_HP_float128"; return DW_DLV_OK; case DW_ATE_HP_complex_float128: *s_out = "DW_ATE_HP_complex_float128"; return DW_DLV_OK; case DW_ATE_HP_floathpintel: *s_out = "DW_ATE_HP_floathpintel"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float80: *s_out = "DW_ATE_HP_imaginary_float80"; return DW_DLV_OK; case DW_ATE_HP_imaginary_float128: *s_out = "DW_ATE_HP_imaginary_float128"; return DW_DLV_OK; case DW_ATE_SUN_interval_float: *s_out = "DW_ATE_SUN_interval_float"; return DW_DLV_OK; case DW_ATE_SUN_imaginary_float: *s_out = "DW_ATE_SUN_imaginary_float"; return DW_DLV_OK; case DW_ATE_hi_user: *s_out = "DW_ATE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DEFAULTED_name (unsigned int val,const char ** s_out) { switch (val) { case DW_DEFAULTED_no: *s_out = "DW_DEFAULTED_no"; return DW_DLV_OK; case DW_DEFAULTED_in_class: *s_out = "DW_DEFAULTED_in_class"; return DW_DLV_OK; case DW_DEFAULTED_out_of_class: *s_out = "DW_DEFAULTED_out_of_class"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_IDX_name (unsigned int val,const char ** s_out) { switch (val) { case DW_IDX_compile_unit: *s_out = "DW_IDX_compile_unit"; return DW_DLV_OK; case DW_IDX_type_unit: *s_out = "DW_IDX_type_unit"; return DW_DLV_OK; case DW_IDX_die_offset: *s_out = "DW_IDX_die_offset"; return DW_DLV_OK; case DW_IDX_parent: *s_out = "DW_IDX_parent"; return DW_DLV_OK; case DW_IDX_type_hash: *s_out = "DW_IDX_type_hash"; return DW_DLV_OK; case DW_IDX_hi_user: *s_out = "DW_IDX_hi_user"; return DW_DLV_OK; case DW_IDX_lo_user: *s_out = "DW_IDX_lo_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLEX_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LLEX_end_of_list_entry: *s_out = "DW_LLEX_end_of_list_entry"; return DW_DLV_OK; case DW_LLEX_base_address_selection_entry: *s_out = "DW_LLEX_base_address_selection_entry"; return DW_DLV_OK; case DW_LLEX_start_end_entry: *s_out = "DW_LLEX_start_end_entry"; return DW_DLV_OK; case DW_LLEX_start_length_entry: *s_out = "DW_LLEX_start_length_entry"; return DW_DLV_OK; case DW_LLEX_offset_pair_entry: *s_out = "DW_LLEX_offset_pair_entry"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LLE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LLE_end_of_list: *s_out = "DW_LLE_end_of_list"; return DW_DLV_OK; case DW_LLE_base_addressx: *s_out = "DW_LLE_base_addressx"; return DW_DLV_OK; case DW_LLE_startx_endx: *s_out = "DW_LLE_startx_endx"; return DW_DLV_OK; case DW_LLE_startx_length: *s_out = "DW_LLE_startx_length"; return DW_DLV_OK; case DW_LLE_offset_pair: *s_out = "DW_LLE_offset_pair"; return DW_DLV_OK; case DW_LLE_default_location: *s_out = "DW_LLE_default_location"; return DW_DLV_OK; case DW_LLE_base_address: *s_out = "DW_LLE_base_address"; return DW_DLV_OK; case DW_LLE_start_end: *s_out = "DW_LLE_start_end"; return DW_DLV_OK; case DW_LLE_start_length: *s_out = "DW_LLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_RLE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_RLE_end_of_list: *s_out = "DW_RLE_end_of_list"; return DW_DLV_OK; case DW_RLE_base_addressx: *s_out = "DW_RLE_base_addressx"; return DW_DLV_OK; case DW_RLE_startx_endx: *s_out = "DW_RLE_startx_endx"; return DW_DLV_OK; case DW_RLE_startx_length: *s_out = "DW_RLE_startx_length"; return DW_DLV_OK; case DW_RLE_offset_pair: *s_out = "DW_RLE_offset_pair"; return DW_DLV_OK; case DW_RLE_base_address: *s_out = "DW_RLE_base_address"; return DW_DLV_OK; case DW_RLE_start_end: *s_out = "DW_RLE_start_end"; return DW_DLV_OK; case DW_RLE_start_length: *s_out = "DW_RLE_start_length"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_UT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_UT_compile: *s_out = "DW_UT_compile"; return DW_DLV_OK; case DW_UT_type: *s_out = "DW_UT_type"; return DW_DLV_OK; case DW_UT_partial: *s_out = "DW_UT_partial"; return DW_DLV_OK; case DW_UT_skeleton: *s_out = "DW_UT_skeleton"; return DW_DLV_OK; case DW_UT_split_compile: *s_out = "DW_UT_split_compile"; return DW_DLV_OK; case DW_UT_split_type: *s_out = "DW_UT_split_type"; return DW_DLV_OK; case DW_UT_lo_user: *s_out = "DW_UT_lo_user"; return DW_DLV_OK; case DW_UT_hi_user: *s_out = "DW_UT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_SECT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_SECT_INFO: *s_out = "DW_SECT_INFO"; return DW_DLV_OK; case DW_SECT_TYPES: *s_out = "DW_SECT_TYPES"; return DW_DLV_OK; case DW_SECT_ABBREV: *s_out = "DW_SECT_ABBREV"; return DW_DLV_OK; case DW_SECT_LINE: *s_out = "DW_SECT_LINE"; return DW_DLV_OK; case DW_SECT_LOCLISTS: *s_out = "DW_SECT_LOCLISTS"; return DW_DLV_OK; case DW_SECT_STR_OFFSETS: *s_out = "DW_SECT_STR_OFFSETS"; return DW_DLV_OK; case DW_SECT_MACRO: *s_out = "DW_SECT_MACRO"; return DW_DLV_OK; case DW_SECT_RNGLISTS: *s_out = "DW_SECT_RNGLISTS"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_DS_unsigned: *s_out = "DW_DS_unsigned"; return DW_DLV_OK; case DW_DS_leading_overpunch: *s_out = "DW_DS_leading_overpunch"; return DW_DLV_OK; case DW_DS_trailing_overpunch: *s_out = "DW_DS_trailing_overpunch"; return DW_DLV_OK; case DW_DS_leading_separate: *s_out = "DW_DS_leading_separate"; return DW_DLV_OK; case DW_DS_trailing_separate: *s_out = "DW_DS_trailing_separate"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_END_name (unsigned int val,const char ** s_out) { switch (val) { case DW_END_default: *s_out = "DW_END_default"; return DW_DLV_OK; case DW_END_big: *s_out = "DW_END_big"; return DW_DLV_OK; case DW_END_little: *s_out = "DW_END_little"; return DW_DLV_OK; case DW_END_lo_user: *s_out = "DW_END_lo_user"; return DW_DLV_OK; case DW_END_hi_user: *s_out = "DW_END_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ATCF_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ATCF_lo_user: *s_out = "DW_ATCF_lo_user"; return DW_DLV_OK; case DW_ATCF_SUN_mop_bitfield: *s_out = "DW_ATCF_SUN_mop_bitfield"; return DW_DLV_OK; case DW_ATCF_SUN_mop_spill: *s_out = "DW_ATCF_SUN_mop_spill"; return DW_DLV_OK; case DW_ATCF_SUN_mop_scopy: *s_out = "DW_ATCF_SUN_mop_scopy"; return DW_DLV_OK; case DW_ATCF_SUN_func_start: *s_out = "DW_ATCF_SUN_func_start"; return DW_DLV_OK; case DW_ATCF_SUN_end_ctors: *s_out = "DW_ATCF_SUN_end_ctors"; return DW_DLV_OK; case DW_ATCF_SUN_branch_target: *s_out = "DW_ATCF_SUN_branch_target"; return DW_DLV_OK; case DW_ATCF_SUN_mop_stack_probe: *s_out = "DW_ATCF_SUN_mop_stack_probe"; return DW_DLV_OK; case DW_ATCF_SUN_func_epilog: *s_out = "DW_ATCF_SUN_func_epilog"; return DW_DLV_OK; case DW_ATCF_hi_user: *s_out = "DW_ATCF_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ACCESS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ACCESS_public: *s_out = "DW_ACCESS_public"; return DW_DLV_OK; case DW_ACCESS_protected: *s_out = "DW_ACCESS_protected"; return DW_DLV_OK; case DW_ACCESS_private: *s_out = "DW_ACCESS_private"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_VIS_local: *s_out = "DW_VIS_local"; return DW_DLV_OK; case DW_VIS_exported: *s_out = "DW_VIS_exported"; return DW_DLV_OK; case DW_VIS_qualified: *s_out = "DW_VIS_qualified"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_VIRTUALITY_name (unsigned int val,const char ** s_out) { switch (val) { case DW_VIRTUALITY_none: *s_out = "DW_VIRTUALITY_none"; return DW_DLV_OK; case DW_VIRTUALITY_virtual: *s_out = "DW_VIRTUALITY_virtual"; return DW_DLV_OK; case DW_VIRTUALITY_pure_virtual: *s_out = "DW_VIRTUALITY_pure_virtual"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LANG_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LANG_C89: *s_out = "DW_LANG_C89"; return DW_DLV_OK; case DW_LANG_C: *s_out = "DW_LANG_C"; return DW_DLV_OK; case DW_LANG_Ada83: *s_out = "DW_LANG_Ada83"; return DW_DLV_OK; case DW_LANG_C_plus_plus: *s_out = "DW_LANG_C_plus_plus"; return DW_DLV_OK; case DW_LANG_Cobol74: *s_out = "DW_LANG_Cobol74"; return DW_DLV_OK; case DW_LANG_Cobol85: *s_out = "DW_LANG_Cobol85"; return DW_DLV_OK; case DW_LANG_Fortran77: *s_out = "DW_LANG_Fortran77"; return DW_DLV_OK; case DW_LANG_Fortran90: *s_out = "DW_LANG_Fortran90"; return DW_DLV_OK; case DW_LANG_Pascal83: *s_out = "DW_LANG_Pascal83"; return DW_DLV_OK; case DW_LANG_Modula2: *s_out = "DW_LANG_Modula2"; return DW_DLV_OK; case DW_LANG_Java: *s_out = "DW_LANG_Java"; return DW_DLV_OK; case DW_LANG_C99: *s_out = "DW_LANG_C99"; return DW_DLV_OK; case DW_LANG_Ada95: *s_out = "DW_LANG_Ada95"; return DW_DLV_OK; case DW_LANG_Fortran95: *s_out = "DW_LANG_Fortran95"; return DW_DLV_OK; case DW_LANG_PLI: *s_out = "DW_LANG_PLI"; return DW_DLV_OK; case DW_LANG_ObjC: *s_out = "DW_LANG_ObjC"; return DW_DLV_OK; case DW_LANG_ObjC_plus_plus: *s_out = "DW_LANG_ObjC_plus_plus"; return DW_DLV_OK; case DW_LANG_UPC: *s_out = "DW_LANG_UPC"; return DW_DLV_OK; case DW_LANG_D: *s_out = "DW_LANG_D"; return DW_DLV_OK; case DW_LANG_Python: *s_out = "DW_LANG_Python"; return DW_DLV_OK; case DW_LANG_OpenCL: *s_out = "DW_LANG_OpenCL"; return DW_DLV_OK; case DW_LANG_Go: *s_out = "DW_LANG_Go"; return DW_DLV_OK; case DW_LANG_Modula3: *s_out = "DW_LANG_Modula3"; return DW_DLV_OK; case DW_LANG_Haskel: *s_out = "DW_LANG_Haskel"; return DW_DLV_OK; case DW_LANG_C_plus_plus_03: *s_out = "DW_LANG_C_plus_plus_03"; return DW_DLV_OK; case DW_LANG_C_plus_plus_11: *s_out = "DW_LANG_C_plus_plus_11"; return DW_DLV_OK; case DW_LANG_OCaml: *s_out = "DW_LANG_OCaml"; return DW_DLV_OK; case DW_LANG_Rust: *s_out = "DW_LANG_Rust"; return DW_DLV_OK; case DW_LANG_C11: *s_out = "DW_LANG_C11"; return DW_DLV_OK; case DW_LANG_Swift: *s_out = "DW_LANG_Swift"; return DW_DLV_OK; case DW_LANG_Julia: *s_out = "DW_LANG_Julia"; return DW_DLV_OK; case DW_LANG_Dylan: *s_out = "DW_LANG_Dylan"; return DW_DLV_OK; case DW_LANG_C_plus_plus_14: *s_out = "DW_LANG_C_plus_plus_14"; return DW_DLV_OK; case DW_LANG_Fortran03: *s_out = "DW_LANG_Fortran03"; return DW_DLV_OK; case DW_LANG_Fortran08: *s_out = "DW_LANG_Fortran08"; return DW_DLV_OK; case DW_LANG_RenderScript: *s_out = "DW_LANG_RenderScript"; return DW_DLV_OK; case DW_LANG_BLISS: *s_out = "DW_LANG_BLISS"; return DW_DLV_OK; case DW_LANG_lo_user: *s_out = "DW_LANG_lo_user"; return DW_DLV_OK; case DW_LANG_Mips_Assembler: *s_out = "DW_LANG_Mips_Assembler"; return DW_DLV_OK; case DW_LANG_Upc: *s_out = "DW_LANG_Upc"; return DW_DLV_OK; case DW_LANG_SUN_Assembler: *s_out = "DW_LANG_SUN_Assembler"; return DW_DLV_OK; case DW_LANG_ALTIUM_Assembler: *s_out = "DW_LANG_ALTIUM_Assembler"; return DW_DLV_OK; case DW_LANG_hi_user: *s_out = "DW_LANG_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ID_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ID_case_sensitive: *s_out = "DW_ID_case_sensitive"; return DW_DLV_OK; case DW_ID_up_case: *s_out = "DW_ID_up_case"; return DW_DLV_OK; case DW_ID_down_case: *s_out = "DW_ID_down_case"; return DW_DLV_OK; case DW_ID_case_insensitive: *s_out = "DW_ID_case_insensitive"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CC_name (unsigned int val,const char ** s_out) { switch (val) { case DW_CC_normal: *s_out = "DW_CC_normal"; return DW_DLV_OK; case DW_CC_program: *s_out = "DW_CC_program"; return DW_DLV_OK; case DW_CC_nocall: *s_out = "DW_CC_nocall"; return DW_DLV_OK; case DW_CC_pass_by_reference: *s_out = "DW_CC_pass_by_reference"; return DW_DLV_OK; case DW_CC_pass_by_value: *s_out = "DW_CC_pass_by_value"; return DW_DLV_OK; case DW_CC_lo_user: *s_out = "DW_CC_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x40. DW_CC_GNU_renesas_sh */ case DW_CC_GNU_borland_fastcall_i386: *s_out = "DW_CC_GNU_borland_fastcall_i386"; return DW_DLV_OK; case DW_CC_ALTIUM_interrupt: *s_out = "DW_CC_ALTIUM_interrupt"; return DW_DLV_OK; case DW_CC_ALTIUM_near_system_stack: *s_out = "DW_CC_ALTIUM_near_system_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_near_user_stack: *s_out = "DW_CC_ALTIUM_near_user_stack"; return DW_DLV_OK; case DW_CC_ALTIUM_huge_user_stack: *s_out = "DW_CC_ALTIUM_huge_user_stack"; return DW_DLV_OK; case DW_CC_hi_user: *s_out = "DW_CC_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_INL_name (unsigned int val,const char ** s_out) { switch (val) { case DW_INL_not_inlined: *s_out = "DW_INL_not_inlined"; return DW_DLV_OK; case DW_INL_inlined: *s_out = "DW_INL_inlined"; return DW_DLV_OK; case DW_INL_declared_not_inlined: *s_out = "DW_INL_declared_not_inlined"; return DW_DLV_OK; case DW_INL_declared_inlined: *s_out = "DW_INL_declared_inlined"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ORD_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ORD_row_major: *s_out = "DW_ORD_row_major"; return DW_DLV_OK; case DW_ORD_col_major: *s_out = "DW_ORD_col_major"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_DSC_name (unsigned int val,const char ** s_out) { switch (val) { case DW_DSC_label: *s_out = "DW_DSC_label"; return DW_DLV_OK; case DW_DSC_range: *s_out = "DW_DSC_range"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNCT_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LNCT_path: *s_out = "DW_LNCT_path"; return DW_DLV_OK; case DW_LNCT_directory_index: *s_out = "DW_LNCT_directory_index"; return DW_DLV_OK; case DW_LNCT_timestamp: *s_out = "DW_LNCT_timestamp"; return DW_DLV_OK; case DW_LNCT_size: *s_out = "DW_LNCT_size"; return DW_DLV_OK; case DW_LNCT_MD5: *s_out = "DW_LNCT_MD5"; return DW_DLV_OK; case DW_LNCT_GNU_subprogram_name: *s_out = "DW_LNCT_GNU_subprogram_name"; return DW_DLV_OK; case DW_LNCT_GNU_decl_file: *s_out = "DW_LNCT_GNU_decl_file"; return DW_DLV_OK; case DW_LNCT_GNU_decl_line: *s_out = "DW_LNCT_GNU_decl_line"; return DW_DLV_OK; case DW_LNCT_lo_user: *s_out = "DW_LNCT_lo_user"; return DW_DLV_OK; case DW_LNCT_hi_user: *s_out = "DW_LNCT_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNS_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LNS_copy: *s_out = "DW_LNS_copy"; return DW_DLV_OK; case DW_LNS_advance_pc: *s_out = "DW_LNS_advance_pc"; return DW_DLV_OK; case DW_LNS_advance_line: *s_out = "DW_LNS_advance_line"; return DW_DLV_OK; case DW_LNS_set_file: *s_out = "DW_LNS_set_file"; return DW_DLV_OK; case DW_LNS_set_column: *s_out = "DW_LNS_set_column"; return DW_DLV_OK; case DW_LNS_negate_stmt: *s_out = "DW_LNS_negate_stmt"; return DW_DLV_OK; case DW_LNS_set_basic_block: *s_out = "DW_LNS_set_basic_block"; return DW_DLV_OK; case DW_LNS_const_add_pc: *s_out = "DW_LNS_const_add_pc"; return DW_DLV_OK; case DW_LNS_fixed_advance_pc: *s_out = "DW_LNS_fixed_advance_pc"; return DW_DLV_OK; case DW_LNS_set_prologue_end: *s_out = "DW_LNS_set_prologue_end"; return DW_DLV_OK; case DW_LNS_set_epilogue_begin: *s_out = "DW_LNS_set_epilogue_begin"; return DW_DLV_OK; case DW_LNS_set_isa: *s_out = "DW_LNS_set_isa"; return DW_DLV_OK; case DW_LNS_set_address_from_logical: *s_out = "DW_LNS_set_address_from_logical"; return DW_DLV_OK; /* Skipping alternate spelling of value 0xd. DW_LNS_set_subprogram */ case DW_LNS_inlined_call: *s_out = "DW_LNS_inlined_call"; return DW_DLV_OK; case DW_LNS_pop_context: *s_out = "DW_LNS_pop_context"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_LNE_name (unsigned int val,const char ** s_out) { switch (val) { case DW_LNE_end_sequence: *s_out = "DW_LNE_end_sequence"; return DW_DLV_OK; case DW_LNE_set_address: *s_out = "DW_LNE_set_address"; return DW_DLV_OK; case DW_LNE_define_file: *s_out = "DW_LNE_define_file"; return DW_DLV_OK; case DW_LNE_set_discriminator: *s_out = "DW_LNE_set_discriminator"; return DW_DLV_OK; case DW_LNE_HP_negate_is_UV_update: *s_out = "DW_LNE_HP_negate_is_UV_update"; return DW_DLV_OK; case DW_LNE_HP_push_context: *s_out = "DW_LNE_HP_push_context"; return DW_DLV_OK; case DW_LNE_HP_pop_context: *s_out = "DW_LNE_HP_pop_context"; return DW_DLV_OK; case DW_LNE_HP_set_file_line_column: *s_out = "DW_LNE_HP_set_file_line_column"; return DW_DLV_OK; case DW_LNE_HP_set_routine_name: *s_out = "DW_LNE_HP_set_routine_name"; return DW_DLV_OK; case DW_LNE_HP_set_sequence: *s_out = "DW_LNE_HP_set_sequence"; return DW_DLV_OK; case DW_LNE_HP_negate_post_semantics: *s_out = "DW_LNE_HP_negate_post_semantics"; return DW_DLV_OK; case DW_LNE_HP_negate_function_exit: *s_out = "DW_LNE_HP_negate_function_exit"; return DW_DLV_OK; case DW_LNE_HP_negate_front_end_logical: *s_out = "DW_LNE_HP_negate_front_end_logical"; return DW_DLV_OK; case DW_LNE_HP_define_proc: *s_out = "DW_LNE_HP_define_proc"; return DW_DLV_OK; case DW_LNE_HP_source_file_correlation: *s_out = "DW_LNE_HP_source_file_correlation"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x80. DW_LNE_lo_user */ case DW_LNE_hi_user: *s_out = "DW_LNE_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ISA_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ISA_UNKNOWN: *s_out = "DW_ISA_UNKNOWN"; return DW_DLV_OK; case DW_ISA_ARM_thumb: *s_out = "DW_ISA_ARM_thumb"; return DW_DLV_OK; case DW_ISA_ARM_arm: *s_out = "DW_ISA_ARM_arm"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACRO_name (unsigned int val,const char ** s_out) { switch (val) { case DW_MACRO_define: *s_out = "DW_MACRO_define"; return DW_DLV_OK; case DW_MACRO_undef: *s_out = "DW_MACRO_undef"; return DW_DLV_OK; case DW_MACRO_start_file: *s_out = "DW_MACRO_start_file"; return DW_DLV_OK; case DW_MACRO_end_file: *s_out = "DW_MACRO_end_file"; return DW_DLV_OK; case DW_MACRO_define_strp: *s_out = "DW_MACRO_define_strp"; return DW_DLV_OK; case DW_MACRO_undef_strp: *s_out = "DW_MACRO_undef_strp"; return DW_DLV_OK; case DW_MACRO_import: *s_out = "DW_MACRO_import"; return DW_DLV_OK; case DW_MACRO_define_sup: *s_out = "DW_MACRO_define_sup"; return DW_DLV_OK; case DW_MACRO_undef_sup: *s_out = "DW_MACRO_undef_sup"; return DW_DLV_OK; case DW_MACRO_import_sup: *s_out = "DW_MACRO_import_sup"; return DW_DLV_OK; case DW_MACRO_define_strx: *s_out = "DW_MACRO_define_strx"; return DW_DLV_OK; case DW_MACRO_undef_strx: *s_out = "DW_MACRO_undef_strx"; return DW_DLV_OK; case DW_MACRO_lo_user: *s_out = "DW_MACRO_lo_user"; return DW_DLV_OK; case DW_MACRO_hi_user: *s_out = "DW_MACRO_hi_user"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_MACINFO_name (unsigned int val,const char ** s_out) { switch (val) { case DW_MACINFO_define: *s_out = "DW_MACINFO_define"; return DW_DLV_OK; case DW_MACINFO_undef: *s_out = "DW_MACINFO_undef"; return DW_DLV_OK; case DW_MACINFO_start_file: *s_out = "DW_MACINFO_start_file"; return DW_DLV_OK; case DW_MACINFO_end_file: *s_out = "DW_MACINFO_end_file"; return DW_DLV_OK; case DW_MACINFO_vendor_ext: *s_out = "DW_MACINFO_vendor_ext"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CFA_name (unsigned int val,const char ** s_out) { switch (val) { case DW_CFA_extended: *s_out = "DW_CFA_extended"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_CFA_nop */ case DW_CFA_set_loc: *s_out = "DW_CFA_set_loc"; return DW_DLV_OK; case DW_CFA_advance_loc1: *s_out = "DW_CFA_advance_loc1"; return DW_DLV_OK; case DW_CFA_advance_loc2: *s_out = "DW_CFA_advance_loc2"; return DW_DLV_OK; case DW_CFA_advance_loc4: *s_out = "DW_CFA_advance_loc4"; return DW_DLV_OK; case DW_CFA_offset_extended: *s_out = "DW_CFA_offset_extended"; return DW_DLV_OK; case DW_CFA_restore_extended: *s_out = "DW_CFA_restore_extended"; return DW_DLV_OK; case DW_CFA_undefined: *s_out = "DW_CFA_undefined"; return DW_DLV_OK; case DW_CFA_same_value: *s_out = "DW_CFA_same_value"; return DW_DLV_OK; case DW_CFA_register: *s_out = "DW_CFA_register"; return DW_DLV_OK; case DW_CFA_remember_state: *s_out = "DW_CFA_remember_state"; return DW_DLV_OK; case DW_CFA_restore_state: *s_out = "DW_CFA_restore_state"; return DW_DLV_OK; case DW_CFA_def_cfa: *s_out = "DW_CFA_def_cfa"; return DW_DLV_OK; case DW_CFA_def_cfa_register: *s_out = "DW_CFA_def_cfa_register"; return DW_DLV_OK; case DW_CFA_def_cfa_offset: *s_out = "DW_CFA_def_cfa_offset"; return DW_DLV_OK; case DW_CFA_def_cfa_expression: *s_out = "DW_CFA_def_cfa_expression"; return DW_DLV_OK; case DW_CFA_expression: *s_out = "DW_CFA_expression"; return DW_DLV_OK; case DW_CFA_offset_extended_sf: *s_out = "DW_CFA_offset_extended_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_sf: *s_out = "DW_CFA_def_cfa_sf"; return DW_DLV_OK; case DW_CFA_def_cfa_offset_sf: *s_out = "DW_CFA_def_cfa_offset_sf"; return DW_DLV_OK; case DW_CFA_val_offset: *s_out = "DW_CFA_val_offset"; return DW_DLV_OK; case DW_CFA_val_offset_sf: *s_out = "DW_CFA_val_offset_sf"; return DW_DLV_OK; case DW_CFA_val_expression: *s_out = "DW_CFA_val_expression"; return DW_DLV_OK; case DW_CFA_lo_user: *s_out = "DW_CFA_lo_user"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x1c. DW_CFA_low_user */ case DW_CFA_MIPS_advance_loc8: *s_out = "DW_CFA_MIPS_advance_loc8"; return DW_DLV_OK; case DW_CFA_GNU_window_save: *s_out = "DW_CFA_GNU_window_save"; return DW_DLV_OK; case DW_CFA_GNU_args_size: *s_out = "DW_CFA_GNU_args_size"; return DW_DLV_OK; case DW_CFA_GNU_negative_offset_extended: *s_out = "DW_CFA_GNU_negative_offset_extended"; return DW_DLV_OK; case DW_CFA_METAWARE_info: *s_out = "DW_CFA_METAWARE_info"; return DW_DLV_OK; case DW_CFA_high_user: *s_out = "DW_CFA_high_user"; return DW_DLV_OK; case DW_CFA_advance_loc: *s_out = "DW_CFA_advance_loc"; return DW_DLV_OK; case DW_CFA_offset: *s_out = "DW_CFA_offset"; return DW_DLV_OK; case DW_CFA_restore: *s_out = "DW_CFA_restore"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_EH_name (unsigned int val,const char ** s_out) { switch (val) { case DW_EH_PE_absptr: *s_out = "DW_EH_PE_absptr"; return DW_DLV_OK; case DW_EH_PE_uleb128: *s_out = "DW_EH_PE_uleb128"; return DW_DLV_OK; case DW_EH_PE_udata2: *s_out = "DW_EH_PE_udata2"; return DW_DLV_OK; case DW_EH_PE_udata4: *s_out = "DW_EH_PE_udata4"; return DW_DLV_OK; case DW_EH_PE_udata8: *s_out = "DW_EH_PE_udata8"; return DW_DLV_OK; case DW_EH_PE_sleb128: *s_out = "DW_EH_PE_sleb128"; return DW_DLV_OK; case DW_EH_PE_sdata2: *s_out = "DW_EH_PE_sdata2"; return DW_DLV_OK; case DW_EH_PE_sdata4: *s_out = "DW_EH_PE_sdata4"; return DW_DLV_OK; case DW_EH_PE_sdata8: *s_out = "DW_EH_PE_sdata8"; return DW_DLV_OK; case DW_EH_PE_pcrel: *s_out = "DW_EH_PE_pcrel"; return DW_DLV_OK; case DW_EH_PE_textrel: *s_out = "DW_EH_PE_textrel"; return DW_DLV_OK; case DW_EH_PE_datarel: *s_out = "DW_EH_PE_datarel"; return DW_DLV_OK; case DW_EH_PE_funcrel: *s_out = "DW_EH_PE_funcrel"; return DW_DLV_OK; case DW_EH_PE_aligned: *s_out = "DW_EH_PE_aligned"; return DW_DLV_OK; case DW_EH_PE_omit: *s_out = "DW_EH_PE_omit"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_FRAME_name (unsigned int val,const char ** s_out) { switch (val) { case DW_FRAME_CFA_COL: *s_out = "DW_FRAME_CFA_COL"; return DW_DLV_OK; /* Skipping alternate spelling of value 0x0. DW_FRAME_LAST_REG_NUM */ /* Skipping alternate spelling of value 0x0. DW_FRAME_RA_COL */ /* Skipping alternate spelling of value 0x0. DW_FRAME_STATIC_LINK */ case DW_FRAME_REG1: *s_out = "DW_FRAME_REG1"; return DW_DLV_OK; case DW_FRAME_REG2: *s_out = "DW_FRAME_REG2"; return DW_DLV_OK; case DW_FRAME_REG3: *s_out = "DW_FRAME_REG3"; return DW_DLV_OK; case DW_FRAME_REG4: *s_out = "DW_FRAME_REG4"; return DW_DLV_OK; case DW_FRAME_REG5: *s_out = "DW_FRAME_REG5"; return DW_DLV_OK; case DW_FRAME_REG6: *s_out = "DW_FRAME_REG6"; return DW_DLV_OK; case DW_FRAME_REG7: *s_out = "DW_FRAME_REG7"; return DW_DLV_OK; case DW_FRAME_REG8: *s_out = "DW_FRAME_REG8"; return DW_DLV_OK; case DW_FRAME_REG9: *s_out = "DW_FRAME_REG9"; return DW_DLV_OK; case DW_FRAME_REG10: *s_out = "DW_FRAME_REG10"; return DW_DLV_OK; case DW_FRAME_REG11: *s_out = "DW_FRAME_REG11"; return DW_DLV_OK; case DW_FRAME_REG12: *s_out = "DW_FRAME_REG12"; return DW_DLV_OK; case DW_FRAME_REG13: *s_out = "DW_FRAME_REG13"; return DW_DLV_OK; case DW_FRAME_REG14: *s_out = "DW_FRAME_REG14"; return DW_DLV_OK; case DW_FRAME_REG15: *s_out = "DW_FRAME_REG15"; return DW_DLV_OK; case DW_FRAME_REG16: *s_out = "DW_FRAME_REG16"; return DW_DLV_OK; case DW_FRAME_REG17: *s_out = "DW_FRAME_REG17"; return DW_DLV_OK; case DW_FRAME_REG18: *s_out = "DW_FRAME_REG18"; return DW_DLV_OK; case DW_FRAME_REG19: *s_out = "DW_FRAME_REG19"; return DW_DLV_OK; case DW_FRAME_REG20: *s_out = "DW_FRAME_REG20"; return DW_DLV_OK; case DW_FRAME_REG21: *s_out = "DW_FRAME_REG21"; return DW_DLV_OK; case DW_FRAME_REG22: *s_out = "DW_FRAME_REG22"; return DW_DLV_OK; case DW_FRAME_REG23: *s_out = "DW_FRAME_REG23"; return DW_DLV_OK; case DW_FRAME_REG24: *s_out = "DW_FRAME_REG24"; return DW_DLV_OK; case DW_FRAME_REG25: *s_out = "DW_FRAME_REG25"; return DW_DLV_OK; case DW_FRAME_REG26: *s_out = "DW_FRAME_REG26"; return DW_DLV_OK; case DW_FRAME_REG27: *s_out = "DW_FRAME_REG27"; return DW_DLV_OK; case DW_FRAME_REG28: *s_out = "DW_FRAME_REG28"; return DW_DLV_OK; case DW_FRAME_REG29: *s_out = "DW_FRAME_REG29"; return DW_DLV_OK; case DW_FRAME_REG30: *s_out = "DW_FRAME_REG30"; return DW_DLV_OK; case DW_FRAME_REG31: *s_out = "DW_FRAME_REG31"; return DW_DLV_OK; case DW_FRAME_FREG0: *s_out = "DW_FRAME_FREG0"; return DW_DLV_OK; case DW_FRAME_FREG1: *s_out = "DW_FRAME_FREG1"; return DW_DLV_OK; case DW_FRAME_FREG2: *s_out = "DW_FRAME_FREG2"; return DW_DLV_OK; case DW_FRAME_FREG3: *s_out = "DW_FRAME_FREG3"; return DW_DLV_OK; case DW_FRAME_FREG4: *s_out = "DW_FRAME_FREG4"; return DW_DLV_OK; case DW_FRAME_FREG5: *s_out = "DW_FRAME_FREG5"; return DW_DLV_OK; case DW_FRAME_FREG6: *s_out = "DW_FRAME_FREG6"; return DW_DLV_OK; case DW_FRAME_FREG7: *s_out = "DW_FRAME_FREG7"; return DW_DLV_OK; case DW_FRAME_FREG8: *s_out = "DW_FRAME_FREG8"; return DW_DLV_OK; case DW_FRAME_FREG9: *s_out = "DW_FRAME_FREG9"; return DW_DLV_OK; case DW_FRAME_FREG10: *s_out = "DW_FRAME_FREG10"; return DW_DLV_OK; case DW_FRAME_FREG11: *s_out = "DW_FRAME_FREG11"; return DW_DLV_OK; case DW_FRAME_FREG12: *s_out = "DW_FRAME_FREG12"; return DW_DLV_OK; case DW_FRAME_FREG13: *s_out = "DW_FRAME_FREG13"; return DW_DLV_OK; case DW_FRAME_FREG14: *s_out = "DW_FRAME_FREG14"; return DW_DLV_OK; case DW_FRAME_FREG15: *s_out = "DW_FRAME_FREG15"; return DW_DLV_OK; case DW_FRAME_FREG16: *s_out = "DW_FRAME_FREG16"; return DW_DLV_OK; case DW_FRAME_FREG17: *s_out = "DW_FRAME_FREG17"; return DW_DLV_OK; case DW_FRAME_FREG18: *s_out = "DW_FRAME_FREG18"; return DW_DLV_OK; case DW_FRAME_FREG19: *s_out = "DW_FRAME_FREG19"; return DW_DLV_OK; case DW_FRAME_FREG20: *s_out = "DW_FRAME_FREG20"; return DW_DLV_OK; case DW_FRAME_FREG21: *s_out = "DW_FRAME_FREG21"; return DW_DLV_OK; case DW_FRAME_FREG22: *s_out = "DW_FRAME_FREG22"; return DW_DLV_OK; case DW_FRAME_FREG23: *s_out = "DW_FRAME_FREG23"; return DW_DLV_OK; case DW_FRAME_FREG24: *s_out = "DW_FRAME_FREG24"; return DW_DLV_OK; case DW_FRAME_FREG25: *s_out = "DW_FRAME_FREG25"; return DW_DLV_OK; case DW_FRAME_FREG26: *s_out = "DW_FRAME_FREG26"; return DW_DLV_OK; case DW_FRAME_FREG27: *s_out = "DW_FRAME_FREG27"; return DW_DLV_OK; case DW_FRAME_FREG28: *s_out = "DW_FRAME_FREG28"; return DW_DLV_OK; case DW_FRAME_FREG29: *s_out = "DW_FRAME_FREG29"; return DW_DLV_OK; case DW_FRAME_FREG30: *s_out = "DW_FRAME_FREG30"; return DW_DLV_OK; case DW_FRAME_FREG31: *s_out = "DW_FRAME_FREG31"; return DW_DLV_OK; case DW_FRAME_FREG32: *s_out = "DW_FRAME_FREG32"; return DW_DLV_OK; case DW_FRAME_FREG33: *s_out = "DW_FRAME_FREG33"; return DW_DLV_OK; case DW_FRAME_FREG34: *s_out = "DW_FRAME_FREG34"; return DW_DLV_OK; case DW_FRAME_FREG35: *s_out = "DW_FRAME_FREG35"; return DW_DLV_OK; case DW_FRAME_FREG36: *s_out = "DW_FRAME_FREG36"; return DW_DLV_OK; case DW_FRAME_FREG37: *s_out = "DW_FRAME_FREG37"; return DW_DLV_OK; case DW_FRAME_FREG38: *s_out = "DW_FRAME_FREG38"; return DW_DLV_OK; case DW_FRAME_FREG39: *s_out = "DW_FRAME_FREG39"; return DW_DLV_OK; case DW_FRAME_FREG40: *s_out = "DW_FRAME_FREG40"; return DW_DLV_OK; case DW_FRAME_FREG41: *s_out = "DW_FRAME_FREG41"; return DW_DLV_OK; case DW_FRAME_FREG42: *s_out = "DW_FRAME_FREG42"; return DW_DLV_OK; case DW_FRAME_FREG43: *s_out = "DW_FRAME_FREG43"; return DW_DLV_OK; case DW_FRAME_FREG44: *s_out = "DW_FRAME_FREG44"; return DW_DLV_OK; case DW_FRAME_FREG45: *s_out = "DW_FRAME_FREG45"; return DW_DLV_OK; case DW_FRAME_FREG46: *s_out = "DW_FRAME_FREG46"; return DW_DLV_OK; case DW_FRAME_FREG47: *s_out = "DW_FRAME_FREG47"; return DW_DLV_OK; case DW_FRAME_FREG48: *s_out = "DW_FRAME_FREG48"; return DW_DLV_OK; case DW_FRAME_FREG49: *s_out = "DW_FRAME_FREG49"; return DW_DLV_OK; case DW_FRAME_FREG50: *s_out = "DW_FRAME_FREG50"; return DW_DLV_OK; case DW_FRAME_FREG51: *s_out = "DW_FRAME_FREG51"; return DW_DLV_OK; case DW_FRAME_FREG52: *s_out = "DW_FRAME_FREG52"; return DW_DLV_OK; case DW_FRAME_FREG53: *s_out = "DW_FRAME_FREG53"; return DW_DLV_OK; case DW_FRAME_FREG54: *s_out = "DW_FRAME_FREG54"; return DW_DLV_OK; case DW_FRAME_FREG55: *s_out = "DW_FRAME_FREG55"; return DW_DLV_OK; case DW_FRAME_FREG56: *s_out = "DW_FRAME_FREG56"; return DW_DLV_OK; case DW_FRAME_FREG57: *s_out = "DW_FRAME_FREG57"; return DW_DLV_OK; case DW_FRAME_FREG58: *s_out = "DW_FRAME_FREG58"; return DW_DLV_OK; case DW_FRAME_FREG59: *s_out = "DW_FRAME_FREG59"; return DW_DLV_OK; case DW_FRAME_FREG60: *s_out = "DW_FRAME_FREG60"; return DW_DLV_OK; case DW_FRAME_FREG61: *s_out = "DW_FRAME_FREG61"; return DW_DLV_OK; case DW_FRAME_FREG62: *s_out = "DW_FRAME_FREG62"; return DW_DLV_OK; case DW_FRAME_FREG63: *s_out = "DW_FRAME_FREG63"; return DW_DLV_OK; case DW_FRAME_FREG64: *s_out = "DW_FRAME_FREG64"; return DW_DLV_OK; case DW_FRAME_FREG65: *s_out = "DW_FRAME_FREG65"; return DW_DLV_OK; case DW_FRAME_FREG66: *s_out = "DW_FRAME_FREG66"; return DW_DLV_OK; case DW_FRAME_FREG67: *s_out = "DW_FRAME_FREG67"; return DW_DLV_OK; case DW_FRAME_FREG68: *s_out = "DW_FRAME_FREG68"; return DW_DLV_OK; case DW_FRAME_FREG69: *s_out = "DW_FRAME_FREG69"; return DW_DLV_OK; case DW_FRAME_FREG70: *s_out = "DW_FRAME_FREG70"; return DW_DLV_OK; case DW_FRAME_FREG71: *s_out = "DW_FRAME_FREG71"; return DW_DLV_OK; case DW_FRAME_FREG72: *s_out = "DW_FRAME_FREG72"; return DW_DLV_OK; case DW_FRAME_FREG73: *s_out = "DW_FRAME_FREG73"; return DW_DLV_OK; case DW_FRAME_FREG74: *s_out = "DW_FRAME_FREG74"; return DW_DLV_OK; case DW_FRAME_FREG75: *s_out = "DW_FRAME_FREG75"; return DW_DLV_OK; case DW_FRAME_FREG76: *s_out = "DW_FRAME_FREG76"; return DW_DLV_OK; case DW_FRAME_HIGHEST_NORMAL_REGISTER: *s_out = "DW_FRAME_HIGHEST_NORMAL_REGISTER"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_CHILDREN_name (unsigned int val,const char ** s_out) { switch (val) { case DW_CHILDREN_no: *s_out = "DW_CHILDREN_no"; return DW_DLV_OK; case DW_CHILDREN_yes: *s_out = "DW_CHILDREN_yes"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* ARGSUSED */ int dwarf_get_ADDR_name (unsigned int val,const char ** s_out) { switch (val) { case DW_ADDR_none: *s_out = "DW_ADDR_none"; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } /* END FILE */ dwarfutils-20200114/libdwarf/dwarf_names.h000066400000000000000000000063361361531463500204010ustar00rootroot00000000000000/* Generated routines, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #ifndef DWARF_NAMES_H #define DWARF_NAMES_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_NAMES_H */ /* END FILE */ dwarfutils-20200114/libdwarf/dwarf_names_enum.h000066400000000000000000001545031361531463500214250ustar00rootroot00000000000000/* Automatically generated, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ #ifndef __DWARF_NAMES_ENUM_H__ #define __DWARF_NAMES_ENUM_H__ enum Dwarf_TAG_e { DW_TAG_array_type = 0x0001, DW_TAG_class_type = 0x0002, DW_TAG_entry_point = 0x0003, DW_TAG_enumeration_type = 0x0004, DW_TAG_formal_parameter = 0x0005, DW_TAG_imported_declaration = 0x0008, DW_TAG_label = 0x000a, DW_TAG_lexical_block = 0x000b, DW_TAG_member = 0x000d, DW_TAG_pointer_type = 0x000f, DW_TAG_reference_type = 0x0010, DW_TAG_compile_unit = 0x0011, DW_TAG_string_type = 0x0012, DW_TAG_structure_type = 0x0013, DW_TAG_subroutine_type = 0x0015, DW_TAG_typedef = 0x0016, DW_TAG_union_type = 0x0017, DW_TAG_unspecified_parameters = 0x0018, DW_TAG_variant = 0x0019, DW_TAG_common_block = 0x001a, DW_TAG_common_inclusion = 0x001b, DW_TAG_inheritance = 0x001c, DW_TAG_inlined_subroutine = 0x001d, DW_TAG_module = 0x001e, DW_TAG_ptr_to_member_type = 0x001f, DW_TAG_set_type = 0x0020, DW_TAG_subrange_type = 0x0021, DW_TAG_with_stmt = 0x0022, DW_TAG_access_declaration = 0x0023, DW_TAG_base_type = 0x0024, DW_TAG_catch_block = 0x0025, DW_TAG_const_type = 0x0026, DW_TAG_constant = 0x0027, DW_TAG_enumerator = 0x0028, DW_TAG_file_type = 0x0029, DW_TAG_friend = 0x002a, DW_TAG_namelist = 0x002b, DW_TAG_namelist_item = 0x002c, DW_TAG_packed_type = 0x002d, DW_TAG_subprogram = 0x002e, DW_TAG_template_type_parameter = 0x002f, DW_TAG_template_value_parameter = 0x0030, DW_TAG_thrown_type = 0x0031, DW_TAG_try_block = 0x0032, DW_TAG_variant_part = 0x0033, DW_TAG_variable = 0x0034, DW_TAG_volatile_type = 0x0035, DW_TAG_dwarf_procedure = 0x0036, DW_TAG_restrict_type = 0x0037, DW_TAG_interface_type = 0x0038, DW_TAG_namespace = 0x0039, DW_TAG_imported_module = 0x003a, DW_TAG_unspecified_type = 0x003b, DW_TAG_partial_unit = 0x003c, DW_TAG_imported_unit = 0x003d, DW_TAG_mutable_type = 0x003e, DW_TAG_condition = 0x003f, DW_TAG_shared_type = 0x0040, DW_TAG_type_unit = 0x0041, DW_TAG_rvalue_reference_type = 0x0042, DW_TAG_template_alias = 0x0043, DW_TAG_coarray_type = 0x0044, DW_TAG_generic_subrange = 0x0045, DW_TAG_dynamic_type = 0x0046, DW_TAG_atomic_type = 0x0047, DW_TAG_call_site = 0x0048, DW_TAG_call_site_parameter = 0x0049, DW_TAG_skeleton_unit = 0x004a, DW_TAG_immutable_type = 0x004b, DW_TAG_lo_user = 0x4080, DW_TAG_MIPS_loop = 0x4081, DW_TAG_HP_array_descriptor = 0x4090, DW_TAG_format_label = 0x4101, DW_TAG_function_template = 0x4102, DW_TAG_class_template = 0x4103, DW_TAG_GNU_BINCL = 0x4104, DW_TAG_GNU_EINCL = 0x4105, DW_TAG_GNU_template_template_parameter = 0x4106, DW_TAG_GNU_template_parameter_pack = 0x4107, DW_TAG_GNU_formal_parameter_pack = 0x4108, DW_TAG_GNU_call_site = 0x4109, DW_TAG_GNU_call_site_parameter = 0x410a, DW_TAG_SUN_function_template = 0x4201, DW_TAG_SUN_class_template = 0x4202, DW_TAG_SUN_struct_template = 0x4203, DW_TAG_SUN_union_template = 0x4204, DW_TAG_SUN_indirect_inheritance = 0x4205, DW_TAG_SUN_codeflags = 0x4206, DW_TAG_SUN_memop_info = 0x4207, DW_TAG_SUN_omp_child_func = 0x4208, DW_TAG_SUN_rtti_descriptor = 0x4209, DW_TAG_SUN_dtor_info = 0x420a, DW_TAG_SUN_dtor = 0x420b, DW_TAG_SUN_f90_interface = 0x420c, DW_TAG_SUN_fortran_vax_structure = 0x420d, DW_TAG_SUN_hi = 0x42ff, DW_TAG_ALTIUM_circ_type = 0x5101, DW_TAG_ALTIUM_mwa_circ_type = 0x5102, DW_TAG_ALTIUM_rev_carry_type = 0x5103, DW_TAG_ALTIUM_rom = 0x5111, DW_TAG_upc_shared_type = 0x8765, DW_TAG_upc_strict_type = 0x8766, DW_TAG_upc_relaxed_type = 0x8767, DW_TAG_PGI_kanji_type = 0xa000, DW_TAG_PGI_interface_block = 0xa020, DW_TAG_hi_user = 0xffff }; enum Dwarf_children_e { DW_children_no = 0x0000, DW_children_yes = 0x0001 }; enum Dwarf_FORM_e { DW_FORM_addr = 0x0001, DW_FORM_block2 = 0x0003, DW_FORM_block4 = 0x0004, DW_FORM_data2 = 0x0005, DW_FORM_data4 = 0x0006, DW_FORM_data8 = 0x0007, DW_FORM_string = 0x0008, DW_FORM_block = 0x0009, DW_FORM_block1 = 0x000a, DW_FORM_data1 = 0x000b, DW_FORM_flag = 0x000c, DW_FORM_sdata = 0x000d, DW_FORM_strp = 0x000e, DW_FORM_udata = 0x000f, DW_FORM_ref_addr = 0x0010, DW_FORM_ref1 = 0x0011, DW_FORM_ref2 = 0x0012, DW_FORM_ref4 = 0x0013, DW_FORM_ref8 = 0x0014, DW_FORM_ref_udata = 0x0015, DW_FORM_indirect = 0x0016, DW_FORM_sec_offset = 0x0017, DW_FORM_exprloc = 0x0018, DW_FORM_flag_present = 0x0019, DW_FORM_strx = 0x001a, DW_FORM_addrx = 0x001b, DW_FORM_ref_sup4 = 0x001c, DW_FORM_strp_sup = 0x001d, DW_FORM_data16 = 0x001e, DW_FORM_line_strp = 0x001f, DW_FORM_ref_sig8 = 0x0020, DW_FORM_implicit_const = 0x0021, DW_FORM_loclistx = 0x0022, DW_FORM_rnglistx = 0x0023, DW_FORM_ref_sup8 = 0x0024, DW_FORM_strx1 = 0x0025, DW_FORM_strx2 = 0x0026, DW_FORM_strx3 = 0x0027, DW_FORM_strx4 = 0x0028, DW_FORM_addrx1 = 0x0029, DW_FORM_addrx2 = 0x002a, DW_FORM_addrx3 = 0x002b, DW_FORM_addrx4 = 0x002c, DW_FORM_GNU_addr_index = 0x1f01, DW_FORM_GNU_str_index = 0x1f02, DW_FORM_GNU_ref_alt = 0x1f20, DW_FORM_GNU_strp_alt = 0x1f21 }; enum Dwarf_AT_e { DW_AT_sibling = 0x0001, DW_AT_location = 0x0002, DW_AT_name = 0x0003, DW_AT_ordering = 0x0009, DW_AT_subscr_data = 0x000a, DW_AT_byte_size = 0x000b, DW_AT_bit_offset = 0x000c, DW_AT_bit_size = 0x000d, DW_AT_element_list = 0x000f, DW_AT_stmt_list = 0x0010, DW_AT_low_pc = 0x0011, DW_AT_high_pc = 0x0012, DW_AT_language = 0x0013, DW_AT_member = 0x0014, DW_AT_discr = 0x0015, DW_AT_discr_value = 0x0016, DW_AT_visibility = 0x0017, DW_AT_import = 0x0018, DW_AT_string_length = 0x0019, DW_AT_common_reference = 0x001a, DW_AT_comp_dir = 0x001b, DW_AT_const_value = 0x001c, DW_AT_containing_type = 0x001d, DW_AT_default_value = 0x001e, DW_AT_inline = 0x0020, DW_AT_is_optional = 0x0021, DW_AT_lower_bound = 0x0022, DW_AT_producer = 0x0025, DW_AT_prototyped = 0x0027, DW_AT_return_addr = 0x002a, DW_AT_start_scope = 0x002c, DW_AT_bit_stride = 0x002e, DW_AT_upper_bound = 0x002f, DW_AT_abstract_origin = 0x0031, DW_AT_accessibility = 0x0032, DW_AT_address_class = 0x0033, DW_AT_artificial = 0x0034, DW_AT_base_types = 0x0035, DW_AT_calling_convention = 0x0036, DW_AT_count = 0x0037, DW_AT_data_member_location = 0x0038, DW_AT_decl_column = 0x0039, DW_AT_decl_file = 0x003a, DW_AT_decl_line = 0x003b, DW_AT_declaration = 0x003c, DW_AT_discr_list = 0x003d, DW_AT_encoding = 0x003e, DW_AT_external = 0x003f, DW_AT_frame_base = 0x0040, DW_AT_friend = 0x0041, DW_AT_identifier_case = 0x0042, DW_AT_macro_info = 0x0043, DW_AT_namelist_item = 0x0044, DW_AT_priority = 0x0045, DW_AT_segment = 0x0046, DW_AT_specification = 0x0047, DW_AT_static_link = 0x0048, DW_AT_type = 0x0049, DW_AT_use_location = 0x004a, DW_AT_variable_parameter = 0x004b, DW_AT_virtuality = 0x004c, DW_AT_vtable_elem_location = 0x004d, DW_AT_allocated = 0x004e, DW_AT_associated = 0x004f, DW_AT_data_location = 0x0050, DW_AT_byte_stride = 0x0051, DW_AT_entry_pc = 0x0052, DW_AT_use_UTF8 = 0x0053, DW_AT_extension = 0x0054, DW_AT_ranges = 0x0055, DW_AT_trampoline = 0x0056, DW_AT_call_column = 0x0057, DW_AT_call_file = 0x0058, DW_AT_call_line = 0x0059, DW_AT_description = 0x005a, DW_AT_binary_scale = 0x005b, DW_AT_decimal_scale = 0x005c, DW_AT_small = 0x005d, DW_AT_decimal_sign = 0x005e, DW_AT_digit_count = 0x005f, DW_AT_picture_string = 0x0060, DW_AT_mutable = 0x0061, DW_AT_threads_scaled = 0x0062, DW_AT_explicit = 0x0063, DW_AT_object_pointer = 0x0064, DW_AT_endianity = 0x0065, DW_AT_elemental = 0x0066, DW_AT_pure = 0x0067, DW_AT_recursive = 0x0068, DW_AT_signature = 0x0069, DW_AT_main_subprogram = 0x006a, DW_AT_data_bit_offset = 0x006b, DW_AT_const_expr = 0x006c, DW_AT_enum_class = 0x006d, DW_AT_linkage_name = 0x006e, DW_AT_string_length_bit_size = 0x006f, DW_AT_string_length_byte_size = 0x0070, DW_AT_rank = 0x0071, DW_AT_str_offsets_base = 0x0072, DW_AT_addr_base = 0x0073, DW_AT_rnglists_base = 0x0074, DW_AT_dwo_id = 0x0075, DW_AT_dwo_name = 0x0076, DW_AT_reference = 0x0077, DW_AT_rvalue_reference = 0x0078, DW_AT_macros = 0x0079, DW_AT_call_all_calls = 0x007a, DW_AT_call_all_source_calls = 0x007b, DW_AT_call_all_tail_calls = 0x007c, DW_AT_call_return_pc = 0x007d, DW_AT_call_value = 0x007e, DW_AT_call_origin = 0x007f, DW_AT_call_parameter = 0x0080, DW_AT_call_pc = 0x0081, DW_AT_call_tail_call = 0x0082, DW_AT_call_target = 0x0083, DW_AT_call_target_clobbered = 0x0084, DW_AT_call_data_location = 0x0085, DW_AT_call_data_value = 0x0086, DW_AT_noreturn = 0x0087, DW_AT_alignment = 0x0088, DW_AT_export_symbols = 0x0089, DW_AT_deleted = 0x008a, DW_AT_defaulted = 0x008b, DW_AT_loclists_base = 0x008c, DW_AT_HP_block_index = 0x2000, DW_AT_MIPS_fde = 0x2001, DW_AT_MIPS_loop_begin = 0x2002, DW_AT_MIPS_tail_loop_begin = 0x2003, DW_AT_MIPS_epilog_begin = 0x2004, DW_AT_MIPS_loop_unroll_factor = 0x2005, DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_linkage_name = 0x2007, DW_AT_MIPS_stride = 0x2008, DW_AT_MIPS_abstract_name = 0x2009, DW_AT_MIPS_clone_origin = 0x200a, DW_AT_MIPS_has_inlines = 0x200b, DW_AT_MIPS_stride_byte = 0x200c, DW_AT_MIPS_stride_elem = 0x200d, DW_AT_MIPS_ptr_dopetype = 0x200e, DW_AT_MIPS_allocatable_dopetype = 0x200f, DW_AT_MIPS_assumed_shape_dopetype = 0x2010, DW_AT_MIPS_assumed_size = 0x2011, DW_AT_HP_raw_data_ptr = 0x2012, DW_AT_HP_pass_by_reference = 0x2013, DW_AT_HP_opt_level = 0x2014, DW_AT_HP_prof_version_id = 0x2015, DW_AT_HP_opt_flags = 0x2016, DW_AT_HP_cold_region_low_pc = 0x2017, DW_AT_HP_cold_region_high_pc = 0x2018, DW_AT_HP_all_variables_modifiable = 0x2019, DW_AT_HP_linkage_name = 0x201a, DW_AT_HP_prof_flags = 0x201b, DW_AT_INTEL_other_endian = 0x2026, DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, DW_AT_GNU_vector = 0x2107, DW_AT_GNU_guarded_by = 0x2108, DW_AT_GNU_pt_guarded_by = 0x2109, DW_AT_GNU_guarded = 0x210a, DW_AT_GNU_pt_guarded = 0x210b, DW_AT_GNU_locks_excluded = 0x210c, DW_AT_GNU_exclusive_locks_required = 0x210d, DW_AT_GNU_shared_locks_required = 0x210e, DW_AT_GNU_odr_signature = 0x210f, DW_AT_GNU_template_name = 0x2110, DW_AT_GNU_call_site_value = 0x2111, DW_AT_GNU_call_site_data_value = 0x2112, DW_AT_GNU_call_site_target = 0x2113, DW_AT_GNU_call_site_target_clobbered = 0x2114, DW_AT_GNU_tail_call = 0x2115, DW_AT_GNU_all_tail_call_sites = 0x2116, DW_AT_GNU_all_call_sites = 0x2117, DW_AT_GNU_all_source_call_sites = 0x2118, DW_AT_GNU_macros = 0x2119, DW_AT_GNU_dwo_name = 0x2130, DW_AT_GNU_dwo_id = 0x2131, DW_AT_GNU_ranges_base = 0x2132, DW_AT_GNU_addr_base = 0x2133, DW_AT_GNU_pubnames = 0x2134, DW_AT_GNU_pubtypes = 0x2135, DW_AT_GNU_discriminator = 0x2136, DW_AT_SUN_template = 0x2201, DW_AT_SUN_alignment = 0x2202, DW_AT_SUN_vtable = 0x2203, DW_AT_SUN_count_guarantee = 0x2204, DW_AT_SUN_command_line = 0x2205, DW_AT_SUN_vbase = 0x2206, DW_AT_SUN_compile_options = 0x2207, DW_AT_SUN_language = 0x2208, DW_AT_SUN_browser_file = 0x2209, DW_AT_SUN_vtable_abi = 0x2210, DW_AT_SUN_func_offsets = 0x2211, DW_AT_SUN_cf_kind = 0x2212, DW_AT_SUN_vtable_index = 0x2213, DW_AT_SUN_omp_tpriv_addr = 0x2214, DW_AT_SUN_omp_child_func = 0x2215, DW_AT_SUN_func_offset = 0x2216, DW_AT_SUN_memop_type_ref = 0x2217, DW_AT_SUN_profile_id = 0x2218, DW_AT_SUN_memop_signature = 0x2219, DW_AT_SUN_obj_dir = 0x2220, DW_AT_SUN_obj_file = 0x2221, DW_AT_SUN_original_name = 0x2222, DW_AT_SUN_hwcprof_signature = 0x2223, DW_AT_SUN_amd64_parmdump = 0x2224, DW_AT_SUN_part_link_name = 0x2225, DW_AT_SUN_link_name = 0x2226, DW_AT_SUN_pass_with_const = 0x2227, DW_AT_SUN_return_with_const = 0x2228, DW_AT_SUN_import_by_name = 0x2229, DW_AT_SUN_f90_pointer = 0x222a, DW_AT_SUN_pass_by_ref = 0x222b, DW_AT_SUN_f90_allocatable = 0x222c, DW_AT_SUN_f90_assumed_shape_array = 0x222d, DW_AT_SUN_c_vla = 0x222e, DW_AT_SUN_return_value_ptr = 0x2230, DW_AT_SUN_dtor_start = 0x2231, DW_AT_SUN_dtor_length = 0x2232, DW_AT_SUN_dtor_state_initial = 0x2233, DW_AT_SUN_dtor_state_final = 0x2234, DW_AT_SUN_dtor_state_deltas = 0x2235, DW_AT_SUN_import_by_lname = 0x2236, DW_AT_SUN_f90_use_only = 0x2237, DW_AT_SUN_namelist_spec = 0x2238, DW_AT_SUN_is_omp_child_func = 0x2239, DW_AT_SUN_fortran_main_alias = 0x223a, DW_AT_SUN_fortran_based = 0x223b, DW_AT_ALTIUM_loclist = 0x2300, DW_AT_use_GNAT_descriptive_type = 0x2301, DW_AT_GNAT_descriptive_type = 0x2302, DW_AT_GNU_numerator = 0x2303, DW_AT_GNU_denominator = 0x2304, DW_AT_GNU_bias = 0x2305, DW_AT_go_kind = 0x2900, DW_AT_go_key = 0x2901, DW_AT_go_elem = 0x2902, DW_AT_go_embedded_field = 0x2903, DW_AT_go_runtime_type = 0x2904, DW_AT_upc_threads_scaled = 0x3210, DW_AT_PGI_lbase = 0x3a00, DW_AT_PGI_soffset = 0x3a01, DW_AT_PGI_lstride = 0x3a02, DW_AT_APPLE_optimized = 0x3fe1, DW_AT_APPLE_flags = 0x3fe2, DW_AT_APPLE_isa = 0x3fe3, DW_AT_APPLE_block = 0x3fe4, DW_AT_APPLE_major_runtime_vers = 0x3fe5, DW_AT_APPLE_runtime_class = 0x3fe6, DW_AT_APPLE_omit_frame_ptr = 0x3fe7, DW_AT_hi_user = 0x3fff }; enum Dwarf_OP_e { DW_OP_addr = 0x0003, DW_OP_deref = 0x0006, DW_OP_const1u = 0x0008, DW_OP_const1s = 0x0009, DW_OP_const2u = 0x000a, DW_OP_const2s = 0x000b, DW_OP_const4u = 0x000c, DW_OP_const4s = 0x000d, DW_OP_const8u = 0x000e, DW_OP_const8s = 0x000f, DW_OP_constu = 0x0010, DW_OP_consts = 0x0011, DW_OP_dup = 0x0012, DW_OP_drop = 0x0013, DW_OP_over = 0x0014, DW_OP_pick = 0x0015, DW_OP_swap = 0x0016, DW_OP_rot = 0x0017, DW_OP_xderef = 0x0018, DW_OP_abs = 0x0019, DW_OP_and = 0x001a, DW_OP_div = 0x001b, DW_OP_minus = 0x001c, DW_OP_mod = 0x001d, DW_OP_mul = 0x001e, DW_OP_neg = 0x001f, DW_OP_not = 0x0020, DW_OP_or = 0x0021, DW_OP_plus = 0x0022, DW_OP_plus_uconst = 0x0023, DW_OP_shl = 0x0024, DW_OP_shr = 0x0025, DW_OP_shra = 0x0026, DW_OP_xor = 0x0027, DW_OP_bra = 0x0028, DW_OP_eq = 0x0029, DW_OP_ge = 0x002a, DW_OP_gt = 0x002b, DW_OP_le = 0x002c, DW_OP_lt = 0x002d, DW_OP_ne = 0x002e, DW_OP_skip = 0x002f, DW_OP_lit0 = 0x0030, DW_OP_lit1 = 0x0031, DW_OP_lit2 = 0x0032, DW_OP_lit3 = 0x0033, DW_OP_lit4 = 0x0034, DW_OP_lit5 = 0x0035, DW_OP_lit6 = 0x0036, DW_OP_lit7 = 0x0037, DW_OP_lit8 = 0x0038, DW_OP_lit9 = 0x0039, DW_OP_lit10 = 0x003a, DW_OP_lit11 = 0x003b, DW_OP_lit12 = 0x003c, DW_OP_lit13 = 0x003d, DW_OP_lit14 = 0x003e, DW_OP_lit15 = 0x003f, DW_OP_lit16 = 0x0040, DW_OP_lit17 = 0x0041, DW_OP_lit18 = 0x0042, DW_OP_lit19 = 0x0043, DW_OP_lit20 = 0x0044, DW_OP_lit21 = 0x0045, DW_OP_lit22 = 0x0046, DW_OP_lit23 = 0x0047, DW_OP_lit24 = 0x0048, DW_OP_lit25 = 0x0049, DW_OP_lit26 = 0x004a, DW_OP_lit27 = 0x004b, DW_OP_lit28 = 0x004c, DW_OP_lit29 = 0x004d, DW_OP_lit30 = 0x004e, DW_OP_lit31 = 0x004f, DW_OP_reg0 = 0x0050, DW_OP_reg1 = 0x0051, DW_OP_reg2 = 0x0052, DW_OP_reg3 = 0x0053, DW_OP_reg4 = 0x0054, DW_OP_reg5 = 0x0055, DW_OP_reg6 = 0x0056, DW_OP_reg7 = 0x0057, DW_OP_reg8 = 0x0058, DW_OP_reg9 = 0x0059, DW_OP_reg10 = 0x005a, DW_OP_reg11 = 0x005b, DW_OP_reg12 = 0x005c, DW_OP_reg13 = 0x005d, DW_OP_reg14 = 0x005e, DW_OP_reg15 = 0x005f, DW_OP_reg16 = 0x0060, DW_OP_reg17 = 0x0061, DW_OP_reg18 = 0x0062, DW_OP_reg19 = 0x0063, DW_OP_reg20 = 0x0064, DW_OP_reg21 = 0x0065, DW_OP_reg22 = 0x0066, DW_OP_reg23 = 0x0067, DW_OP_reg24 = 0x0068, DW_OP_reg25 = 0x0069, DW_OP_reg26 = 0x006a, DW_OP_reg27 = 0x006b, DW_OP_reg28 = 0x006c, DW_OP_reg29 = 0x006d, DW_OP_reg30 = 0x006e, DW_OP_reg31 = 0x006f, DW_OP_breg0 = 0x0070, DW_OP_breg1 = 0x0071, DW_OP_breg2 = 0x0072, DW_OP_breg3 = 0x0073, DW_OP_breg4 = 0x0074, DW_OP_breg5 = 0x0075, DW_OP_breg6 = 0x0076, DW_OP_breg7 = 0x0077, DW_OP_breg8 = 0x0078, DW_OP_breg9 = 0x0079, DW_OP_breg10 = 0x007a, DW_OP_breg11 = 0x007b, DW_OP_breg12 = 0x007c, DW_OP_breg13 = 0x007d, DW_OP_breg14 = 0x007e, DW_OP_breg15 = 0x007f, DW_OP_breg16 = 0x0080, DW_OP_breg17 = 0x0081, DW_OP_breg18 = 0x0082, DW_OP_breg19 = 0x0083, DW_OP_breg20 = 0x0084, DW_OP_breg21 = 0x0085, DW_OP_breg22 = 0x0086, DW_OP_breg23 = 0x0087, DW_OP_breg24 = 0x0088, DW_OP_breg25 = 0x0089, DW_OP_breg26 = 0x008a, DW_OP_breg27 = 0x008b, DW_OP_breg28 = 0x008c, DW_OP_breg29 = 0x008d, DW_OP_breg30 = 0x008e, DW_OP_breg31 = 0x008f, DW_OP_regx = 0x0090, DW_OP_fbreg = 0x0091, DW_OP_bregx = 0x0092, DW_OP_piece = 0x0093, DW_OP_deref_size = 0x0094, DW_OP_xderef_size = 0x0095, DW_OP_nop = 0x0096, DW_OP_push_object_address = 0x0097, DW_OP_call2 = 0x0098, DW_OP_call4 = 0x0099, DW_OP_call_ref = 0x009a, DW_OP_form_tls_address = 0x009b, DW_OP_call_frame_cfa = 0x009c, DW_OP_bit_piece = 0x009d, DW_OP_implicit_value = 0x009e, DW_OP_stack_value = 0x009f, DW_OP_implicit_pointer = 0x00a0, DW_OP_addrx = 0x00a1, DW_OP_constx = 0x00a2, DW_OP_entry_value = 0x00a3, DW_OP_const_type = 0x00a4, DW_OP_regval_type = 0x00a5, DW_OP_deref_type = 0x00a6, DW_OP_xderef_type = 0x00a7, DW_OP_convert = 0x00a8, DW_OP_reinterpret = 0x00a9, DW_OP_GNU_push_tls_address = 0x00e0, DW_OP_HP_is_value = 0x00e1, DW_OP_HP_fltconst4 = 0x00e2, DW_OP_HP_fltconst8 = 0x00e3, DW_OP_HP_mod_range = 0x00e4, DW_OP_HP_unmod_range = 0x00e5, DW_OP_HP_tls = 0x00e6, DW_OP_INTEL_bit_piece = 0x00e8, DW_OP_GNU_uninit = 0x00f0, DW_OP_GNU_encoded_addr = 0x00f1, DW_OP_GNU_implicit_pointer = 0x00f2, DW_OP_GNU_entry_value = 0x00f3, DW_OP_GNU_const_type = 0x00f4, DW_OP_GNU_regval_type = 0x00f5, DW_OP_GNU_deref_type = 0x00f6, DW_OP_GNU_convert = 0x00f7, DW_OP_PGI_omp_thread_num = 0x00f8, DW_OP_GNU_reinterpret = 0x00f9, DW_OP_GNU_parameter_ref = 0x00fa, DW_OP_GNU_addr_index = 0x00fb, DW_OP_GNU_const_index = 0x00fc, DW_OP_hi_user = 0x00ff }; enum Dwarf_ATE_e { DW_ATE_address = 0x0001, DW_ATE_boolean = 0x0002, DW_ATE_complex_float = 0x0003, DW_ATE_float = 0x0004, DW_ATE_signed = 0x0005, DW_ATE_signed_char = 0x0006, DW_ATE_unsigned = 0x0007, DW_ATE_unsigned_char = 0x0008, DW_ATE_imaginary_float = 0x0009, DW_ATE_packed_decimal = 0x000a, DW_ATE_numeric_string = 0x000b, DW_ATE_edited = 0x000c, DW_ATE_signed_fixed = 0x000d, DW_ATE_unsigned_fixed = 0x000e, DW_ATE_decimal_float = 0x000f, DW_ATE_UTF = 0x0010, DW_ATE_UCS = 0x0011, DW_ATE_ASCII = 0x0012, DW_ATE_ALTIUM_fract = 0x0080, DW_ATE_ALTIUM_accum = 0x0081, DW_ATE_HP_float128 = 0x0082, DW_ATE_HP_complex_float128 = 0x0083, DW_ATE_HP_floathpintel = 0x0084, DW_ATE_HP_imaginary_float80 = 0x0085, DW_ATE_HP_imaginary_float128 = 0x0086, DW_ATE_SUN_interval_float = 0x0091, DW_ATE_SUN_imaginary_float = 0x0092, DW_ATE_hi_user = 0x00ff }; enum Dwarf_DEFAULTED_e { DW_DEFAULTED_no = 0x0000, DW_DEFAULTED_in_class = 0x0001, DW_DEFAULTED_out_of_class = 0x0002 }; enum Dwarf_IDX_e { DW_IDX_compile_unit = 0x0001, DW_IDX_type_unit = 0x0002, DW_IDX_die_offset = 0x0003, DW_IDX_parent = 0x0004, DW_IDX_type_hash = 0x0005, DW_IDX_hi_user = 0x0fff, DW_IDX_lo_user = 0x2000 }; enum Dwarf_LLEX_e { DW_LLEX_end_of_list_entry = 0x0000, DW_LLEX_base_address_selection_entry = 0x0001, DW_LLEX_start_end_entry = 0x0002, DW_LLEX_start_length_entry = 0x0003, DW_LLEX_offset_pair_entry = 0x0004 }; enum Dwarf_LLE_e { DW_LLE_end_of_list = 0x0000, DW_LLE_base_addressx = 0x0001, DW_LLE_startx_endx = 0x0002, DW_LLE_startx_length = 0x0003, DW_LLE_offset_pair = 0x0004, DW_LLE_default_location = 0x0005, DW_LLE_base_address = 0x0006, DW_LLE_start_end = 0x0007, DW_LLE_start_length = 0x0008 }; enum Dwarf_RLE_e { DW_RLE_end_of_list = 0x0000, DW_RLE_base_addressx = 0x0001, DW_RLE_startx_endx = 0x0002, DW_RLE_startx_length = 0x0003, DW_RLE_offset_pair = 0x0004, DW_RLE_base_address = 0x0005, DW_RLE_start_end = 0x0006, DW_RLE_start_length = 0x0007 }; enum Dwarf_UT_e { DW_UT_compile = 0x0001, DW_UT_type = 0x0002, DW_UT_partial = 0x0003, DW_UT_skeleton = 0x0004, DW_UT_split_compile = 0x0005, DW_UT_split_type = 0x0006, DW_UT_lo_user = 0x0080, DW_UT_hi_user = 0x00ff }; enum Dwarf_SECT_e { DW_SECT_INFO = 0x0001, DW_SECT_TYPES = 0x0002, DW_SECT_ABBREV = 0x0003, DW_SECT_LINE = 0x0004, DW_SECT_LOCLISTS = 0x0005, DW_SECT_STR_OFFSETS = 0x0006, DW_SECT_MACRO = 0x0007, DW_SECT_RNGLISTS = 0x0008 }; enum Dwarf_DS_e { DW_DS_unsigned = 0x0001, DW_DS_leading_overpunch = 0x0002, DW_DS_trailing_overpunch = 0x0003, DW_DS_leading_separate = 0x0004, DW_DS_trailing_separate = 0x0005 }; enum Dwarf_END_e { DW_END_default = 0x0000, DW_END_big = 0x0001, DW_END_little = 0x0002, DW_END_lo_user = 0x0040, DW_END_hi_user = 0x00ff }; enum Dwarf_ATCF_e { DW_ATCF_lo_user = 0x0040, DW_ATCF_SUN_mop_bitfield = 0x0041, DW_ATCF_SUN_mop_spill = 0x0042, DW_ATCF_SUN_mop_scopy = 0x0043, DW_ATCF_SUN_func_start = 0x0044, DW_ATCF_SUN_end_ctors = 0x0045, DW_ATCF_SUN_branch_target = 0x0046, DW_ATCF_SUN_mop_stack_probe = 0x0047, DW_ATCF_SUN_func_epilog = 0x0048, DW_ATCF_hi_user = 0x00ff }; enum Dwarf_ACCESS_e { DW_ACCESS_public = 0x0001, DW_ACCESS_protected = 0x0002, DW_ACCESS_private = 0x0003 }; enum Dwarf_VIS_e { DW_VIS_local = 0x0001, DW_VIS_exported = 0x0002, DW_VIS_qualified = 0x0003 }; enum Dwarf_VIRTUALITY_e { DW_VIRTUALITY_none = 0x0000, DW_VIRTUALITY_virtual = 0x0001, DW_VIRTUALITY_pure_virtual = 0x0002 }; enum Dwarf_LANG_e { DW_LANG_C89 = 0x0001, DW_LANG_C = 0x0002, DW_LANG_Ada83 = 0x0003, DW_LANG_C_plus_plus = 0x0004, DW_LANG_Cobol74 = 0x0005, DW_LANG_Cobol85 = 0x0006, DW_LANG_Fortran77 = 0x0007, DW_LANG_Fortran90 = 0x0008, DW_LANG_Pascal83 = 0x0009, DW_LANG_Modula2 = 0x000a, DW_LANG_Java = 0x000b, DW_LANG_C99 = 0x000c, DW_LANG_Ada95 = 0x000d, DW_LANG_Fortran95 = 0x000e, DW_LANG_PLI = 0x000f, DW_LANG_ObjC = 0x0010, DW_LANG_ObjC_plus_plus = 0x0011, DW_LANG_UPC = 0x0012, DW_LANG_D = 0x0013, DW_LANG_Python = 0x0014, DW_LANG_OpenCL = 0x0015, DW_LANG_Go = 0x0016, DW_LANG_Modula3 = 0x0017, DW_LANG_Haskel = 0x0018, DW_LANG_C_plus_plus_03 = 0x0019, DW_LANG_C_plus_plus_11 = 0x001a, DW_LANG_OCaml = 0x001b, DW_LANG_Rust = 0x001c, DW_LANG_C11 = 0x001d, DW_LANG_Swift = 0x001e, DW_LANG_Julia = 0x001f, DW_LANG_Dylan = 0x0020, DW_LANG_C_plus_plus_14 = 0x0021, DW_LANG_Fortran03 = 0x0022, DW_LANG_Fortran08 = 0x0023, DW_LANG_RenderScript = 0x0024, DW_LANG_BLISS = 0x0025, DW_LANG_lo_user = 0x8000, DW_LANG_Mips_Assembler = 0x8001, DW_LANG_Upc = 0x8765, DW_LANG_SUN_Assembler = 0x9001, DW_LANG_ALTIUM_Assembler = 0x9101, DW_LANG_hi_user = 0xffff }; enum Dwarf_ID_e { DW_ID_case_sensitive = 0x0000, DW_ID_up_case = 0x0001, DW_ID_down_case = 0x0002, DW_ID_case_insensitive = 0x0003 }; enum Dwarf_CC_e { DW_CC_normal = 0x0001, DW_CC_program = 0x0002, DW_CC_nocall = 0x0003, DW_CC_pass_by_reference = 0x0004, DW_CC_pass_by_value = 0x0005, DW_CC_lo_user = 0x0040, DW_CC_GNU_borland_fastcall_i386 = 0x0041, DW_CC_ALTIUM_interrupt = 0x0065, DW_CC_ALTIUM_near_system_stack = 0x0066, DW_CC_ALTIUM_near_user_stack = 0x0067, DW_CC_ALTIUM_huge_user_stack = 0x0068, DW_CC_hi_user = 0x00ff }; enum Dwarf_INL_e { DW_INL_not_inlined = 0x0000, DW_INL_inlined = 0x0001, DW_INL_declared_not_inlined = 0x0002, DW_INL_declared_inlined = 0x0003 }; enum Dwarf_ORD_e { DW_ORD_row_major = 0x0000, DW_ORD_col_major = 0x0001 }; enum Dwarf_DSC_e { DW_DSC_label = 0x0000, DW_DSC_range = 0x0001 }; enum Dwarf_LNCT_e { DW_LNCT_path = 0x0001, DW_LNCT_directory_index = 0x0002, DW_LNCT_timestamp = 0x0003, DW_LNCT_size = 0x0004, DW_LNCT_MD5 = 0x0005, DW_LNCT_GNU_subprogram_name = 0x0006, DW_LNCT_GNU_decl_file = 0x0007, DW_LNCT_GNU_decl_line = 0x0008, DW_LNCT_lo_user = 0x2000, DW_LNCT_hi_user = 0x3fff }; enum Dwarf_LNS_e { DW_LNS_copy = 0x0001, DW_LNS_advance_pc = 0x0002, DW_LNS_advance_line = 0x0003, DW_LNS_set_file = 0x0004, DW_LNS_set_column = 0x0005, DW_LNS_negate_stmt = 0x0006, DW_LNS_set_basic_block = 0x0007, DW_LNS_const_add_pc = 0x0008, DW_LNS_fixed_advance_pc = 0x0009, DW_LNS_set_prologue_end = 0x000a, DW_LNS_set_epilogue_begin = 0x000b, DW_LNS_set_isa = 0x000c, DW_LNS_set_address_from_logical = 0x000d, DW_LNS_inlined_call = 0x000e, DW_LNS_pop_context = 0x000f }; enum Dwarf_LNE_e { DW_LNE_end_sequence = 0x0001, DW_LNE_set_address = 0x0002, DW_LNE_define_file = 0x0003, DW_LNE_set_discriminator = 0x0004, DW_LNE_HP_negate_is_UV_update = 0x0011, DW_LNE_HP_push_context = 0x0012, DW_LNE_HP_pop_context = 0x0013, DW_LNE_HP_set_file_line_column = 0x0014, DW_LNE_HP_set_routine_name = 0x0015, DW_LNE_HP_set_sequence = 0x0016, DW_LNE_HP_negate_post_semantics = 0x0017, DW_LNE_HP_negate_function_exit = 0x0018, DW_LNE_HP_negate_front_end_logical = 0x0019, DW_LNE_HP_define_proc = 0x0020, DW_LNE_HP_source_file_correlation = 0x0080, DW_LNE_hi_user = 0x00ff }; enum Dwarf_ISA_e { DW_ISA_UNKNOWN = 0x0000, DW_ISA_ARM_thumb = 0x0001, DW_ISA_ARM_arm = 0x0002 }; enum Dwarf_MACRO_e { DW_MACRO_define = 0x0001, DW_MACRO_undef = 0x0002, DW_MACRO_start_file = 0x0003, DW_MACRO_end_file = 0x0004, DW_MACRO_define_strp = 0x0005, DW_MACRO_undef_strp = 0x0006, DW_MACRO_import = 0x0007, DW_MACRO_define_sup = 0x0008, DW_MACRO_undef_sup = 0x0009, DW_MACRO_import_sup = 0x000a, DW_MACRO_define_strx = 0x000b, DW_MACRO_undef_strx = 0x000c, DW_MACRO_lo_user = 0x00e0, DW_MACRO_hi_user = 0x00ff }; enum Dwarf_MACINFO_e { DW_MACINFO_define = 0x0001, DW_MACINFO_undef = 0x0002, DW_MACINFO_start_file = 0x0003, DW_MACINFO_end_file = 0x0004, DW_MACINFO_vendor_ext = 0x00ff }; enum Dwarf_CFA_e { DW_CFA_extended = 0x0000, DW_CFA_set_loc = 0x0001, DW_CFA_advance_loc1 = 0x0002, DW_CFA_advance_loc2 = 0x0003, DW_CFA_advance_loc4 = 0x0004, DW_CFA_offset_extended = 0x0005, DW_CFA_restore_extended = 0x0006, DW_CFA_undefined = 0x0007, DW_CFA_same_value = 0x0008, DW_CFA_register = 0x0009, DW_CFA_remember_state = 0x000a, DW_CFA_restore_state = 0x000b, DW_CFA_def_cfa = 0x000c, DW_CFA_def_cfa_register = 0x000d, DW_CFA_def_cfa_offset = 0x000e, DW_CFA_def_cfa_expression = 0x000f, DW_CFA_expression = 0x0010, DW_CFA_offset_extended_sf = 0x0011, DW_CFA_def_cfa_sf = 0x0012, DW_CFA_def_cfa_offset_sf = 0x0013, DW_CFA_val_offset = 0x0014, DW_CFA_val_offset_sf = 0x0015, DW_CFA_val_expression = 0x0016, DW_CFA_lo_user = 0x001c, DW_CFA_MIPS_advance_loc8 = 0x001d, DW_CFA_GNU_window_save = 0x002d, DW_CFA_GNU_args_size = 0x002e, DW_CFA_GNU_negative_offset_extended = 0x002f, DW_CFA_METAWARE_info = 0x0034, DW_CFA_high_user = 0x003f, DW_CFA_advance_loc = 0x0040, DW_CFA_offset = 0x0080, DW_CFA_restore = 0x00c0 }; enum Dwarf_EH_e { DW_EH_PE_absptr = 0x0000, DW_EH_PE_uleb128 = 0x0001, DW_EH_PE_udata2 = 0x0002, DW_EH_PE_udata4 = 0x0003, DW_EH_PE_udata8 = 0x0004, DW_EH_PE_sleb128 = 0x0009, DW_EH_PE_sdata2 = 0x000a, DW_EH_PE_sdata4 = 0x000b, DW_EH_PE_sdata8 = 0x000c, DW_EH_PE_pcrel = 0x0010, DW_EH_PE_textrel = 0x0020, DW_EH_PE_datarel = 0x0030, DW_EH_PE_funcrel = 0x0040, DW_EH_PE_aligned = 0x0050, DW_EH_PE_omit = 0x00ff }; enum Dwarf_FRAME_e { DW_FRAME_CFA_COL = 0x0000, DW_FRAME_REG1 = 0x0001, DW_FRAME_REG2 = 0x0002, DW_FRAME_REG3 = 0x0003, DW_FRAME_REG4 = 0x0004, DW_FRAME_REG5 = 0x0005, DW_FRAME_REG6 = 0x0006, DW_FRAME_REG7 = 0x0007, DW_FRAME_REG8 = 0x0008, DW_FRAME_REG9 = 0x0009, DW_FRAME_REG10 = 0x0010, DW_FRAME_REG11 = 0x0011, DW_FRAME_REG12 = 0x0012, DW_FRAME_REG13 = 0x0013, DW_FRAME_REG14 = 0x0014, DW_FRAME_REG15 = 0x0015, DW_FRAME_REG16 = 0x0016, DW_FRAME_REG17 = 0x0017, DW_FRAME_REG18 = 0x0018, DW_FRAME_REG19 = 0x0019, DW_FRAME_REG20 = 0x0020, DW_FRAME_REG21 = 0x0021, DW_FRAME_REG22 = 0x0022, DW_FRAME_REG23 = 0x0023, DW_FRAME_REG24 = 0x0024, DW_FRAME_REG25 = 0x0025, DW_FRAME_REG26 = 0x0026, DW_FRAME_REG27 = 0x0027, DW_FRAME_REG28 = 0x0028, DW_FRAME_REG29 = 0x0029, DW_FRAME_REG30 = 0x0030, DW_FRAME_REG31 = 0x0031, DW_FRAME_FREG0 = 0x0032, DW_FRAME_FREG1 = 0x0033, DW_FRAME_FREG2 = 0x0034, DW_FRAME_FREG3 = 0x0035, DW_FRAME_FREG4 = 0x0036, DW_FRAME_FREG5 = 0x0037, DW_FRAME_FREG6 = 0x0038, DW_FRAME_FREG7 = 0x0039, DW_FRAME_FREG8 = 0x0040, DW_FRAME_FREG9 = 0x0041, DW_FRAME_FREG10 = 0x0042, DW_FRAME_FREG11 = 0x0043, DW_FRAME_FREG12 = 0x0044, DW_FRAME_FREG13 = 0x0045, DW_FRAME_FREG14 = 0x0046, DW_FRAME_FREG15 = 0x0047, DW_FRAME_FREG16 = 0x0048, DW_FRAME_FREG17 = 0x0049, DW_FRAME_FREG18 = 0x0050, DW_FRAME_FREG19 = 0x0051, DW_FRAME_FREG20 = 0x0052, DW_FRAME_FREG21 = 0x0053, DW_FRAME_FREG22 = 0x0054, DW_FRAME_FREG23 = 0x0055, DW_FRAME_FREG24 = 0x0056, DW_FRAME_FREG25 = 0x0057, DW_FRAME_FREG26 = 0x0058, DW_FRAME_FREG27 = 0x0059, DW_FRAME_FREG28 = 0x0060, DW_FRAME_FREG29 = 0x0061, DW_FRAME_FREG30 = 0x0062, DW_FRAME_FREG31 = 0x0063, DW_FRAME_FREG32 = 0x0064, DW_FRAME_FREG33 = 0x0065, DW_FRAME_FREG34 = 0x0066, DW_FRAME_FREG35 = 0x0067, DW_FRAME_FREG36 = 0x0068, DW_FRAME_FREG37 = 0x0069, DW_FRAME_FREG38 = 0x0070, DW_FRAME_FREG39 = 0x0071, DW_FRAME_FREG40 = 0x0072, DW_FRAME_FREG41 = 0x0073, DW_FRAME_FREG42 = 0x0074, DW_FRAME_FREG43 = 0x0075, DW_FRAME_FREG44 = 0x0076, DW_FRAME_FREG45 = 0x0077, DW_FRAME_FREG46 = 0x0078, DW_FRAME_FREG47 = 0x0079, DW_FRAME_FREG48 = 0x0080, DW_FRAME_FREG49 = 0x0081, DW_FRAME_FREG50 = 0x0082, DW_FRAME_FREG51 = 0x0083, DW_FRAME_FREG52 = 0x0084, DW_FRAME_FREG53 = 0x0085, DW_FRAME_FREG54 = 0x0086, DW_FRAME_FREG55 = 0x0087, DW_FRAME_FREG56 = 0x0088, DW_FRAME_FREG57 = 0x0089, DW_FRAME_FREG58 = 0x0090, DW_FRAME_FREG59 = 0x0091, DW_FRAME_FREG60 = 0x0092, DW_FRAME_FREG61 = 0x0093, DW_FRAME_FREG62 = 0x0094, DW_FRAME_FREG63 = 0x0095, DW_FRAME_FREG64 = 0x0096, DW_FRAME_FREG65 = 0x0097, DW_FRAME_FREG66 = 0x0098, DW_FRAME_FREG67 = 0x0099, DW_FRAME_FREG68 = 0x0100, DW_FRAME_FREG69 = 0x0101, DW_FRAME_FREG70 = 0x0102, DW_FRAME_FREG71 = 0x0103, DW_FRAME_FREG72 = 0x0104, DW_FRAME_FREG73 = 0x0105, DW_FRAME_FREG74 = 0x0106, DW_FRAME_FREG75 = 0x0107, DW_FRAME_FREG76 = 0x0108, DW_FRAME_HIGHEST_NORMAL_REGISTER = 0x0188 }; enum Dwarf_CHILDREN_e { DW_CHILDREN_no = 0x0000, DW_CHILDREN_yes = 0x0001 }; enum Dwarf_ADDR_e { DW_ADDR_none = 0x0000 }; #endif /* __DWARF_NAMES_ENUM_H__ */ /* END FILE */ dwarfutils-20200114/libdwarf/dwarf_names_new.h000066400000000000000000000047131361531463500212470ustar00rootroot00000000000000/* Automatically generated, do not edit. */ /* Generated sourcedate 2020-01-14 10:13:32-08:00 */ /* BEGIN FILE */ /* define DWARF_PRINT_PREFIX before this point if you wish to. */ #ifndef DWARF_PRINT_PREFIX #define DWARF_PRINT_PREFIX dwarf_ #endif #define dw_glue(x,y) x##y #define dw_glue2(x,y) dw_glue(x,y) #define DWPREFIX(x) dw_glue2(DWARF_PRINT_PREFIX,x) int DWPREFIX(get_TAG_name) (unsigned int, const char **); int DWPREFIX(get_children_name) (unsigned int, const char **); int DWPREFIX(get_FORM_name) (unsigned int, const char **); int DWPREFIX(get_AT_name) (unsigned int, const char **); int DWPREFIX(get_OP_name) (unsigned int, const char **); int DWPREFIX(get_ATE_name) (unsigned int, const char **); int DWPREFIX(get_DEFAULTED_name) (unsigned int, const char **); int DWPREFIX(get_IDX_name) (unsigned int, const char **); int DWPREFIX(get_LLEX_name) (unsigned int, const char **); int DWPREFIX(get_LLE_name) (unsigned int, const char **); int DWPREFIX(get_RLE_name) (unsigned int, const char **); int DWPREFIX(get_UT_name) (unsigned int, const char **); int DWPREFIX(get_SECT_name) (unsigned int, const char **); int DWPREFIX(get_DS_name) (unsigned int, const char **); int DWPREFIX(get_END_name) (unsigned int, const char **); int DWPREFIX(get_ATCF_name) (unsigned int, const char **); int DWPREFIX(get_ACCESS_name) (unsigned int, const char **); int DWPREFIX(get_VIS_name) (unsigned int, const char **); int DWPREFIX(get_VIRTUALITY_name) (unsigned int, const char **); int DWPREFIX(get_LANG_name) (unsigned int, const char **); int DWPREFIX(get_ID_name) (unsigned int, const char **); int DWPREFIX(get_CC_name) (unsigned int, const char **); int DWPREFIX(get_INL_name) (unsigned int, const char **); int DWPREFIX(get_ORD_name) (unsigned int, const char **); int DWPREFIX(get_DSC_name) (unsigned int, const char **); int DWPREFIX(get_LNCT_name) (unsigned int, const char **); int DWPREFIX(get_LNS_name) (unsigned int, const char **); int DWPREFIX(get_LNE_name) (unsigned int, const char **); int DWPREFIX(get_ISA_name) (unsigned int, const char **); int DWPREFIX(get_MACRO_name) (unsigned int, const char **); int DWPREFIX(get_MACINFO_name) (unsigned int, const char **); int DWPREFIX(get_CFA_name) (unsigned int, const char **); int DWPREFIX(get_EH_name) (unsigned int, const char **); int DWPREFIX(get_FRAME_name) (unsigned int, const char **); int DWPREFIX(get_CHILDREN_name) (unsigned int, const char **); int DWPREFIX(get_ADDR_name) (unsigned int, const char **); /* END FILE */ dwarfutils-20200114/libdwarf/dwarf_object_detector.c000066400000000000000000000375041361531463500224310ustar00rootroot00000000000000/* Copyright (c) 2018-2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #include /* open() */ #include /* open() */ #include /* O_RDONLY */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #include typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ #endif /* HAVE_UNISTD_H */ #ifdef HAVE_STRING_H #include /* memcpy, strcpy */ #endif /* HAVE_STRING_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "memcpy_swap.h" #include "dwarf_object_read_common.h" #include "dwarf_object_detector.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ /* This is the main() program for the object_detector executable. */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* TRUE */ #ifndef O_RDONLY #define O_RDONLY 0 #endif /* TYP, SIZEOFT32 and ASNAR mean we can use correctly-sized arrays of char for the struct members instead of determing a proper integer that size. We are dealing with carefully constructed structs that do not have any alignment-forced (hidden) unused bytes so reading lengths from the real structs works for each variable. */ #define TYP(n,l) char n[l] #define SIZEOFT32 4 #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 #ifndef EI_NIDENT #define EI_NIDENT 16 #define EI_CLASS 4 #define EI_DATA 5 #define EI_VERSION 6 #define ELFCLASS32 1 #define ELFCLASS64 2 #define ELFDATA2LSB 1 #define ELFDATA2MSB 2 #endif /* EI_NIDENT */ #define DSYM_SUFFIX ".dSYM/Contents/Resources/DWARF/" #define PATHSIZE 2000 #ifndef MH_MAGIC /* mach-o 32bit */ #define MH_MAGIC 0xfeedface #define MH_CIGAM 0xcefaedfe #endif /* MH_MAGIC */ #ifndef MH_MAGIC_64 /* mach-o 64bit */ #define MH_MAGIC_64 0xfeedfacf #define MH_CIGAM_64 0xcffaedfe #endif /* MH_MAGIC_64 */ static unsigned long magic_copy(unsigned char *d, unsigned len) { unsigned i = 0; unsigned long v = 0; v = d[0]; for(i = 1 ; i < len; ++i) { v <<= 8; v |= d[i]; } return v; } #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ #define EI_NIDENT 16 /* An incomplete elf header, good for 32 and 64bit elf */ struct elf_header { unsigned char e_ident[EI_NIDENT]; TYP(e_type,2); TYP(e_machine,2); TYP(e_version,4); #ifdef HAVE_CUSTOM_LIBELF /* In the case of custom ELF, use extra space */ TYP(e_custom,64); #endif /* HAVE_CUSTOM_LIBELF */ }; /* Windows. Certain PE objects. The following references may be of interest. https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx #PE format overview and various machine magic numbers https://msdn.microsoft.com/en-us/library/ms809762.aspx # describes some details of PE headers, basically an overview https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx #defines sizes of various types https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680313(v=vs.85).aspx #defines IMAGE_FILE_HEADER and Machine fields (32/64) https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680305(v=vs.85).aspx #defines IMAGE_DATA_DIRECTORY https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx #Defines IMAGE_OPTIONAL_HEADER and some magic numbers https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680336(v=vs.85).aspx # defines _IMAGE_NT_HEADERS 32 64 https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx # defines _IMAGE_SECTION_HEADER */ /* ===== START pe structures */ struct dos_header { TYP(dh_mz,2); TYP(dh_dos_data,58); TYP(dh_image_offset,4); }; #define IMAGE_DOS_SIGNATURE_dw 0x5A4D #define IMAGE_DOS_REVSIGNATURE_dw 0x4D5A #define IMAGE_NT_SIGNATURE_dw 0x00004550 #define IMAGE_FILE_MACHINE_I386_dw 0x14c #define IMAGE_FILE_MACHINE_IA64_dw 0x200 #define IMAGE_FILE_MACHINE_AMD64_dw 0x8664 struct pe_image_file_header { TYP(im_machine,2); TYP(im_sectioncount,2); TYP(im_ignoring,(3*4)); TYP(im_opt_header_size,2); TYP(im_ignoringb,2); }; /* ===== END pe structures */ /* For following MacOS file naming convention */ static const char * getseparator (const char *f) { const char *p = 0; const char *q = 0; char c = 0;; p = NULL; q = f; do { c = *q++; if (c == '\\' || c == '/' || c == ':') { p = q; } } while (c); return p; } static const char * getbasename (const char *f) { const char *pseparator = getseparator (f); if (!pseparator) { return f; } return pseparator; } /* Not a standard function, though part of GNU libc since 2008 (I have never examined the GNU version). */ static char * dw_stpcpy(char *dest,const char *src) { const char *cp = src; char *dp = dest; for ( ; *cp; ++cp,++dp) { *dp = *cp; } *dp = 0; return dp; } /* This started like Elf, so check initial fields. */ static int fill_in_elf_fields(struct elf_header *h, unsigned *endian, /* Size of the object file offsets, not DWARF offset size. */ unsigned *objoffsetsize, int *errcode) { unsigned locendian = 0; unsigned locoffsetsize = 0; switch(h->e_ident[EI_CLASS]) { case ELFCLASS32: locoffsetsize = 32; break; case ELFCLASS64: locoffsetsize = 64; break; default: *errcode = DW_DLE_ELF_CLASS_BAD; return DW_DLV_ERROR; } switch(h->e_ident[EI_DATA]) { case ELFDATA2LSB: locendian = DW_ENDIAN_LITTLE; break; case ELFDATA2MSB: locendian = DW_ENDIAN_BIG; break; default: *errcode = DW_DLE_ELF_ENDIAN_BAD; return DW_DLV_ERROR; } if (h->e_ident[EI_VERSION] != 1 /* EV_CURRENT */) { *errcode = DW_DLE_ELF_VERSION_BAD; return DW_DLV_ERROR; } *endian = locendian; *objoffsetsize = locoffsetsize; return DW_DLV_OK; } static char archive_magic[8] = { '!','<','a','r','c','h','>',0x0a }; static int is_archive_magic(struct elf_header *h) { int i = 0; int len = sizeof(archive_magic); const char *cp = (const char *)h; for( ; i < len; ++i) { if (cp[i] != archive_magic[i]) { return FALSE; } } return TRUE; } /* A bit unusual in that it always sets *is_pe_flag Return of DW_DLV_OK it is a PE file we recognize. */ static int is_pe_object(int fd, unsigned long filesize, unsigned *endian, unsigned *offsetsize, int *errcode) { unsigned dos_sig = 0; unsigned locendian = 0; void (*word_swap) (void *, const void *, unsigned long); unsigned long nt_address = 0; struct dos_header dhinmem; char nt_sig_array[4]; unsigned long nt_sig = 0; struct pe_image_file_header ifh; int res = 0; if (filesize < (sizeof (struct dos_header) + SIZEOFT32 + sizeof(struct pe_image_file_header))) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(fd,(char *)&dhinmem, 0,sizeof(dhinmem),filesize,errcode); if (res != DW_DLV_OK) { return res; } /* No swap here, want it as in the file */ dos_sig = magic_copy((unsigned char *)dhinmem.dh_mz, sizeof(dhinmem.dh_mz)); if (dos_sig == IMAGE_DOS_SIGNATURE_dw) { /* IMAGE_DOS_SIGNATURE_dw assumes bytes reversed by little-endian load, so we intrepet a match the other way. */ /* BIG ENDIAN. From looking at hex characters in object */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_noswap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_swap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_ENDIAN_BIG; } else if (dos_sig == IMAGE_DOS_REVSIGNATURE_dw) { /* raw load, so intrepet a match the other way. */ /* LITTLE ENDIAN */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_swap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_noswap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_ENDIAN_LITTLE; } else { /* Not dos header not a PE file we recognize */ *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } ASNAR(word_swap,nt_address, dhinmem.dh_image_offset); if (filesize < nt_address) { /* Not dos header not a PE file we recognize */ *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } if (filesize < (nt_address + SIZEOFT32 + sizeof(struct pe_image_file_header))) { *errcode = DW_DLE_FILE_TOO_SMALL; /* Not dos header not a PE file we recognize */ return DW_DLV_ERROR; } res = _dwarf_object_read_random(fd,(char *)&nt_sig_array[0], nt_address, sizeof(nt_sig_array),filesize,errcode); if (res != DW_DLV_OK) { return res; } { unsigned long lsig = 0; ASNAR(word_swap,lsig,nt_sig_array); nt_sig = lsig; } if (nt_sig != IMAGE_NT_SIGNATURE_dw) { *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } res = _dwarf_object_read_random(fd,(char *)&ifh, nt_address + SIZEOFT32, sizeof(struct pe_image_file_header), filesize, errcode); if (res != DW_DLV_OK) { return res; } { unsigned long machine = 0; ASNAR(word_swap,machine,ifh.im_machine); switch(machine) { case IMAGE_FILE_MACHINE_I386_dw: *offsetsize = 32; *endian = locendian; return DW_DLV_OK; case IMAGE_FILE_MACHINE_IA64_dw: case IMAGE_FILE_MACHINE_AMD64_dw: *offsetsize = 64; *endian = locendian; return DW_DLV_OK; } } *errcode = DW_DLE_IMAGE_FILE_UNKNOWN_TYPE; return DW_DLV_ERROR; } static int is_mach_o_magic(struct elf_header *h, unsigned *endian, unsigned *offsetsize) { unsigned long magicval = 0; unsigned locendian = 0; unsigned locoffsetsize = 0; /* No swapping here. Need to match size of Mach-o magic field. */ magicval = magic_copy(h->e_ident,4); if (magicval == MH_MAGIC) { locendian = DW_ENDIAN_BIG; locoffsetsize = 32; } else if (magicval == MH_CIGAM) { locendian = DW_ENDIAN_LITTLE; locoffsetsize = 32; }else if (magicval == MH_MAGIC_64) { locendian = DW_ENDIAN_BIG; locoffsetsize = 64; } else if (magicval == MH_CIGAM_64) { locendian = DW_ENDIAN_LITTLE; locoffsetsize = 64; } else { return FALSE; } *endian = locendian; *offsetsize = locoffsetsize; return TRUE; } int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int *errcode) { struct elf_header h; size_t readlen = sizeof(h); int res = 0; off_t fsize = 0; off_t lsval = 0; ssize_t readval = 0; fsize = lseek(fd,0L,SEEK_END); if(fsize < 0) { *errcode = DW_DLE_SEEK_ERROR; return DW_DLV_ERROR; } if (fsize <= (off_t)readlen) { /* Not a real object file */ *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } lsval = lseek(fd,0L,SEEK_SET); if(lsval < 0) { *errcode = DW_DLE_SEEK_ERROR; return DW_DLV_ERROR; } readval = read(fd,&h,readlen); if (readval != (ssize_t)readlen) { *errcode = DW_DLE_READ_ERROR; return DW_DLV_ERROR; } if (h.e_ident[0] == 0x7f && h.e_ident[1] == 'E' && h.e_ident[2] == 'L' && h.e_ident[3] == 'F') { /* is ELF */ res = fill_in_elf_fields(&h,endian,offsetsize,errcode); if (res != DW_DLV_OK) { return res; } *ftype = DW_FTYPE_ELF; *filesize = (size_t)fsize; return DW_DLV_OK; } if (is_mach_o_magic(&h,endian,offsetsize)) { *ftype = DW_FTYPE_MACH_O; *filesize = (size_t)fsize; return DW_DLV_OK; } if (is_archive_magic(&h)) { *ftype = DW_FTYPE_ARCHIVE; *filesize = (size_t)fsize; return DW_DLV_OK; } res = is_pe_object(fd,fsize,endian,offsetsize,errcode); if (res == DW_DLV_OK ) { *ftype = DW_FTYPE_PE; *filesize = (size_t)fsize; return DW_DLV_OK; } /* Check for custom ELF format. */ #ifdef HAVE_CUSTOM_LIBELF res = elf_is_custom_format(&h,readlen,&fsize,endian,offsetsize,errcode); if (res == DW_DLV_OK) { *ftype = DW_FTYPE_CUSTOM_ELF; *filesize = (size_t)fsize; return res; } #endif /* HAVE_CUSTOM_LIBELF */ /* Unknown object format. */ return DW_DLV_NO_ENTRY; } int dwarf_object_detector_path(const char *path, char *outpath,unsigned long outpath_len, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int *errcode) { char *cp = 0; size_t plen = strlen(path); size_t dsprefixlen = sizeof(DSYM_SUFFIX); int fd = -1; int res = 0; int have_outpath = outpath && outpath_len; #if !defined(S_ISREG) #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #endif #if !defined(S_ISDIR) #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif if (have_outpath) { if ((2*plen + dsprefixlen +2) >= outpath_len) { *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; return DW_DLV_ERROR; } cp = dw_stpcpy(outpath,path); cp = dw_stpcpy(cp,DSYM_SUFFIX); dw_stpcpy(cp,getbasename(path)); fd = open(outpath,O_RDONLY|O_BINARY); if (fd < 0) { *outpath = 0; fd = open(path,O_RDONLY|O_BINARY); dw_stpcpy(outpath,path); } } else { fd = open(path,O_RDONLY|O_BINARY); } if (fd < 0) { if (have_outpath) { *outpath = 0; } return DW_DLV_NO_ENTRY; } res = dwarf_object_detector_fd(fd, ftype,endian,offsetsize,filesize,errcode); if (res != DW_DLV_OK && have_outpath) { *outpath = 0; } close(fd); return res; } dwarfutils-20200114/libdwarf/dwarf_object_detector.h000066400000000000000000000070141361531463500224270ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_OBJECT_DETECTOR_H #define DWARF_OBJECT_DETECTOR_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Declares the interface function. outpath is a place you provide, of a length outpath_len you consider reasonable, where the final path used is recorded. outpath_len must be larger than strlen(path); This matters as for mach-o if the path is a directory name the function will look in the standard macho-place for the object file (useful for dSYM) and return the constructed path in oupath. returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY */ #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 #define DW_FTYPE_MACH_O 2 #define DW_FTYPE_PE 3 #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ /* offsetsize refers to the object-file-format. Elf 32 or macho-32 or PE 32, for example. Not to DWARF offset sizes. */ /* Path means look(first) for an dynsym object of the same name per MacOS standards, making the outpath space needed is more than that in path. Copies the actual path into outpath, (an error if the length in outpath_len is less than needed for the object found). For non-MacOS outpath will contain the string taken from path. If DW_DLV_NO_ENTRY or DW_DLV_ERROR returned the argument values other than path must be considered to be in an unknown state. */ /* The errcode is a small integer distinct from libdwarf and simply printing the integer (returned through *errcode when the function returns DW_DLV_ERROR) will hopefully suffice for most purposes. */ int dwarf_object_detector_path(const char *path, char *outpath, unsigned long outpath_len, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_OBJECT_DETECTOR_H */ dwarfutils-20200114/libdwarf/dwarf_object_read_common.c000066400000000000000000000062271361531463500231010ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #include /* memcpy */ #include /* lseek and read */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #include typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" /* For error codes. */ #include "dwarf_object_read_common.h" /* Neither off_t nor ssize_t is in C90. However, both are in Posix: IEEE Std 1003.1-1990, aka ISO/IEC 9954-1:1990. */ int _dwarf_object_read_random(int fd, char *buf, off_t loc, size_t size, off_t filesize, int *errc) { off_t scode = 0; ssize_t rcode = 0; off_t endpoint = 0; if (loc >= filesize) { /* Seek can seek off the end. Lets not allow that. The object is corrupt. */ *errc = DW_DLE_SEEK_OFF_END; return DW_DLV_ERROR; } endpoint = loc+size; if (endpoint > filesize) { /* Let us -not- try to read past end of object. The object is corrupt. */ *errc = DW_DLE_READ_OFF_END; return DW_DLV_ERROR; } scode = lseek(fd,loc,SEEK_SET); if (scode == (off_t)-1) { *errc = DW_DLE_SEEK_ERROR; return DW_DLV_ERROR; } rcode = read(fd,buf,size); if (rcode == -1 || (size_t)rcode != size) { *errc = DW_DLE_READ_ERROR; return DW_DLV_ERROR; } return DW_DLV_OK; } void _dwarf_safe_strcpy(char *out, long outlen, const char *in, long inlen) { if (inlen >= (outlen - 1)) { strncpy(out, in, outlen - 1); out[outlen - 1] = 0; } else { strcpy(out, in); } } dwarfutils-20200114/libdwarf/dwarf_object_read_common.h000066400000000000000000000032761361531463500231070ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_OBJECT_READ_COMMON_H #define DWARF_OBJECT_READ_COMMON_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int _dwarf_object_read_random(int fd,char *buf,off_t loc, size_t size,off_t filesize,int *errc); void _dwarf_safe_strcpy(char *out, long outlen, const char *in, long inlen); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_OBJECT_READ_COMMON_H */ dwarfutils-20200114/libdwarf/dwarf_opaque.h000066400000000000000000001055351361531463500205710ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Following the nomenclature of the DWARF standard Section Version Numbers (DWARF 5): * means not applicable. - means not defined in that version. The version numbers for .debug_info is the same as .debug_info.dwo (etc for the other dwo sections). The versions applicable by section are: . DWARF2 DWARF3 DWARF4 DWARF5 .debug_abbrev * * * * .debug_addr - - - 5 .debug_aranges 2 2 2 2 .debug_frame 1 3 4 4 .debug_info 2 3 4 5 .debug_line 2 3 4 5 .debug_line_str - - - 5 .debug_loc * * * - .debug_loclists - - - 5 .debug_macinfo * * * - .debug_macro - - - 5 .debug_names - - - 5 .debug_pubnames 2 2 2 - .debug_pubtypes - 2 2 - .debug_ranges - * * - .debug_rnglists - - - 5 .debug_str * * * * .debug_str_offsets - - - 5 .debug_sup - - - 5 .debug_types - - 4 - .debug_abbrev.dwo - - - * .debug_info.dwo - - - 5 .debug_line.dwo - - - 5 .debug_loc.dwo - - - - .debug_loclists.dwo - - - 5 .debug_macro.dwo - - - 5 .debug_rnglists.dwo - - - 5 .debug_str.dwo - - - * .debug_str_offsets.dwo - - - 5 .debug_cu_index - - - 5 .debug_tu_index - - - 5 */ struct Dwarf_Die_s { Dwarf_Byte_Ptr di_debug_ptr; Dwarf_Abbrev_List di_abbrev_list; Dwarf_CU_Context di_cu_context; int di_abbrev_code; /* TRUE if part of debug_info. FALSE if part of .debug_types. */ Dwarf_Bool di_is_info; }; struct Dwarf_Attribute_s { Dwarf_Half ar_attribute; /* Attribute Value. */ Dwarf_Half ar_attribute_form; /* Attribute Form. */ Dwarf_Half ar_attribute_form_direct; /* Identical to ar_attribute_form except that if the original form uleb was DW_FORM_indirect, ar_attribute_form_direct contains DW_FORM_indirect but ar_attribute_form contains the true form. */ Dwarf_CU_Context ar_cu_context; /* The following points to either debug_info or debug_types depending on if context is cc_is_info or not. */ Dwarf_Small *ar_debug_ptr; /* If DW_FORM_implicit const, the value is here, not in the DIE. */ Dwarf_Signed ar_implicit_const; Dwarf_Die ar_die;/* Access to the DIE owning the attribute */ Dwarf_Attribute ar_next; }; /* This structure provides the context for a compilation unit. Thus, it contains the Dwarf_Debug, cc_dbg, that this cu belongs to. It contains the information in the compilation unit header, cc_length, cc_version_stamp, cc_abbrev_offset, and cc_address_size, in the .debug_info section for that cu. In addition, it contains the count, cc_count_cu, of the cu number of that cu in the list of cu's in the .debug_info. The count starts at 1, ie cc_count_cu is 1 for the first cu, 2 for the second and so on. This struct also contains a pointer, cc_abbrev_table, to a list of pairs of abbrev code and a pointer to the start of that abbrev in the .debug_abbrev section. Each die will also contain a pointer to such a struct to record the context for that die. Notice that a pointer to the CU DIE itself is Dwarf_Off off2 = cu_context->cc_debug_info_offset; cu_die_info_ptr = dbg->de_debug_info.dss_data + off2 + _dwarf_length_of_cu_header(dbg, off2); Or similar for de_debug_types. **Updated by dwarf_next_cu_header in dwarf_die_deliv.c */ struct Dwarf_CU_Context_s { Dwarf_Debug cc_dbg; /* The sum of cc_length, cc_length_size, and cc_extension_size is the total length of the CU including its header. cc_length is the length of the compilation unit excluding cc_length_size and cc_extension_size. */ Dwarf_Unsigned cc_length; /* cc_length_size is the size in bytes of an offset. Should probably be renamed cc_offset_size. 4 for 32bit dwarf, 8 for 64bit dwarf (whether MIPS/IRIX 64bit dwarf or standard 64bit dwarf using the extension mechanism). */ Dwarf_Small cc_length_size; /* cc_extension_size is zero unless this is standard DWARF3 and later 64bit dwarf using the extension mechanism. 64bit DWARF3 and later: cc_extension_size is 4. 64bit DWARF2 MIPS/IRIX: cc_extension_size is zero. 32bit DWARF: cc_extension_size is zero. */ Dwarf_Small cc_extension_size; /* cc_version_stamp is the DWARF version number applicable to the DWARF in this compilation unit. 2,3,4,... */ Dwarf_Half cc_version_stamp; /* cc_abbrev_offset is the section-global offset of the .debug_abbrev section this CU uses. Data from CU header. Includes DWP adjustment made as soon as we create a cu_context. */ Dwarf_Unsigned cc_abbrev_offset; /* cc_address_size is the size of an address in this compilation unit. */ Dwarf_Small cc_address_size; Dwarf_Small cc_segment_selector_size; /* cc_debug_offset is the global offset in the section of the CU header of this CU. That is, it is a section global offset. May be debug_info or debug_types but those are distinct. Even in DWP this is set to true global offset right away when cu_context created. See cc_is_info flag. */ Dwarf_Unsigned cc_debug_offset; /* === START DEBUG FISSION (Split Dwarf) data cc_signature is in the TU header of a type unit of a TU DIE (or for DW5 in the skeleton or split_compile header is a dwo_id). Ignore this field if cc_signature_present is zero. (TU CUs signature is not the same namespace as DW_AT_dwo_id signatures. The two must be kept separate (for DWARF5)) If cc_unit_type == DW_UT_compile or DW_UT_partial the signature is a CU signature (dwo_id). Some early DW5 drafts encouraged DWARF4 output of some compilers to include dwo_id, but in a messier way(lacking DW_UT_*). If cc_unit_type == DW_UT_type ( DW_UT_split_type was never part of DW5, never standard). the signature is a type signature. */ Dwarf_Half cc_cu_die_tag; Dwarf_Sig8 cc_signature; /* cc_type_signature_offset contains the section-local DIE offset of the type the signature applies to if the cc_unit_type is DW_UT_type or DW_UT_split_type. */ Dwarf_Unsigned cc_signature_offset; /* For each CU and each TU in a dwp package file there is is a hash and a set of offsets indexed by DW_SECT_* id. Only one such set per CU or TU. The data on all that is in cc_dwp_offsets If it is a TU the signature in cc_dwp_offsets must match the signature in cc_signature. */ struct Dwarf_Debug_Fission_Per_CU_s cc_dwp_offsets; Dwarf_Bool cc_signature_present; /* Meaning type signature in TU header or, for CU header, signature in CU DIE. */ Dwarf_Bool cc_addr_base_present; /* Not TRUE in .dwo */ Dwarf_Bool cc_ranges_base_present; /* Not TRUE in .dwo */ Dwarf_Bool cc_str_offsets_base_present; Dwarf_Bool cc_loclists_base_present; Dwarf_Bool cc_cu_die_has_children; /* Non zero if this context is a dwo section. Either dwo or dwp file. */ Dwarf_Bool cc_is_dwo; /* cc_cu_die_offset_present is non-zero if cc_cu_die_global_sec_offset is meaningful. */ Dwarf_Bool cc_cu_die_offset_present; /* FIXME from DW_AT_addr_base in CU DIE */ Dwarf_Unsigned cc_addr_base; /* Zero in .dwo */ /* FIXME from DW_AT_rnglists_base in CU DIE */ Dwarf_Unsigned cc_ranges_base; /* Zero in .dwo */ /* FIXME from DW_AT_str_offsets_base in CU DIE */ Dwarf_Unsigned cc_str_offsets_base; char * cc_dwo_name; Dwarf_Unsigned cc_loclists_base; /* === END DEBUG FISSION (Split Dwarf) data */ /* Global section offset to the bytes of the CU die for this CU. Set when the CU die is accessed by dwarf_siblingof_b(). */ Dwarf_Unsigned cc_cu_die_global_sec_offset; Dwarf_Byte_Ptr cc_last_abbrev_ptr; Dwarf_Byte_Ptr cc_last_abbrev_endptr; Dwarf_Hash_Table cc_abbrev_hash_table; Dwarf_CU_Context cc_next; /*unsigned char cc_offset_length; */ Dwarf_Bool cc_is_info; /* TRUE means context is in debug_info, FALSE means is in debug_types. FALSE only possible for DWARF4 .debug_types section CUs. For DWARF5 all DIEs are in .debug_info[.dwo] */ Dwarf_Half cc_unit_type; /* DWARF5: set from header For DWARF 2,3,4 this is filled in initially from the CU header and refined by inspecting the CU DIE to detect the correct setting. */ }; /* Consolidates section-specific data in one place. Section is an Elf specific term, intended as a general term (for non-Elf objects some code must synthesize the values somehow). */ struct Dwarf_Section_s { Dwarf_Small * dss_data; Dwarf_Unsigned dss_size; /* Some Elf sections have a non-zero dss_entrysize which is the size in bytes of a table entry in the section. Relocations and symbols are both in tables, so have a non-zero entrysize. Object formats which do not care about this should leave this field zero. */ Dwarf_Unsigned dss_entrysize; /* dss_index is the section index as things are numbered in an object file being read. An Elf section number. */ Dwarf_Unsigned dss_index; /* dss_addr is the 'section address' which is only non-zero for a GNU eh section. Purpose: to handle DW_EH_PE_pcrel encoding. Leaving it zero is fine for non-elf. */ Dwarf_Addr dss_addr; Dwarf_Small dss_data_was_malloc; /* is_in_use set during initial object reading to detect duplicates. Ignored after setup done. */ Dwarf_Small dss_is_in_use; /* When loading COMDAT they refer (sometimes) to base sections, so we need to have the BASE group sections filled in when the corresponding is not in the COMDAT group list. .debug_abbrev is an example. */ Dwarf_Unsigned dss_group_number; /* These for reporting compression */ Dwarf_Unsigned dss_uncompressed_length; Dwarf_Unsigned dss_compressed_length; /* If this is zdebug, to start data/size are the raw section bytes. Initially for all sections dss_data_was_malloc set FALSE and dss_requires_decompress set FALSE. For zdebug set dss_zdebug_requires_decompress set TRUE In that case it is likely ZLIB compressed but we do not know that just scanning section headers. If not .zdebug but it is SHF_COMPRESSED then decompress is required. On translation (ie zlib use and malloc) Set dss_data dss_size to point to malloc space and malloc size. Set dss_did_decompress FALSE Set dss_was_malloc TRUE */ Dwarf_Small dss_zdebug_requires_decompress; Dwarf_Small dss_did_decompress; Dwarf_Small dss_shf_compressed; /* section flag SHF_COMPRESS */ Dwarf_Small dss_ZLIB_compressed; /* Section compression starts with ZLIB chars*/ /* For non-elf, leaving the following fields zero will mean they are ignored. */ /* dss_link should be zero unless a section has a link to another (sh_link). Used to access relocation data for a section (and for symtab section, access its strtab). */ Dwarf_Unsigned dss_link; /* The following is used when reading .rela sections (such sections appear in some .o files). */ Dwarf_Half dss_reloc_index; /* Zero means ignore the reloc fields. */ Dwarf_Small * dss_reloc_data; Dwarf_Unsigned dss_reloc_size; Dwarf_Unsigned dss_reloc_entrysize; Dwarf_Addr dss_reloc_addr; /* dss_reloc_symtab is the sh_link of a .rela to its .symtab, leave it 0 if non-meaningful. */ Dwarf_Addr dss_reloc_symtab; /* dss_reloc_link should be zero unless a reloc section has a link to another (sh_link). Used to access the symtab for relocations a section. */ Dwarf_Unsigned dss_reloc_link; /* Pointer to the elf symtab, used for elf .rela. Leave it 0 if not relevant. */ struct Dwarf_Section_s *dss_symtab; /* dss_name, dss_standard_name must never be freed, they are static strings in libdwarf. */ const char * dss_name; const char * dss_standard_name; /* Object section number in object file. */ unsigned dss_number; /* These are elf flags and non-elf object should just leave these fields zero. Which is essentially automatic as they are not in Dwarf_Obj_Access_Section_s. */ Dwarf_Unsigned dss_flags; Dwarf_Unsigned dss_addralign; /* Set when loading .group section as those are special and neither compressed nor have relocations so never malloc space for libdwarf. */ Dwarf_Small dss_ignore_reloc_group_sec; }; /* Overview: if next_to_use== first, no error slots are used. If next_to_use+1 (mod maxcount) == first the slots are all used */ struct Dwarf_Harmless_s { unsigned dh_maxcount; unsigned dh_next_to_use; unsigned dh_first; unsigned dh_errs_count; char ** dh_errors; }; /* Data needed seperately for debug_info and debug_types as we may be reading both interspersed. */ struct Dwarf_Debug_InfoTypes_s { /* Context for the compilation_unit just read by a call to dwarf_next_cu_header. **Updated by dwarf_next_cu_header in dwarf_die_deliv.c */ Dwarf_CU_Context de_cu_context; /* Points to linked list of CU Contexts for the CU's already read. These are only CU's read by dwarf_next_cu_header(). */ Dwarf_CU_Context de_cu_context_list; /* Points to the last CU Context added to the list by dwarf_next_cu_header(). */ Dwarf_CU_Context de_cu_context_list_end; /* This is the list of CU contexts read for dwarf_offdie(). These may read ahead of dwarf_next_cu_header(). */ Dwarf_CU_Context de_offdie_cu_context; Dwarf_CU_Context de_offdie_cu_context_end; /* Offset of last byte of last CU read. Actually one-past that last byte. So use care and compare as offset >= de_last_offset to know if offset is too big. */ Dwarf_Unsigned de_last_offset; /* de_last_di_info_ptr and de_last_die are used with dwarf_siblingof, dwarf_child, and dwarf_validate_die_sibling. dwarf_validate_die_sibling will not give meaningful results if called inappropriately. */ Dwarf_Byte_Ptr de_last_di_ptr; Dwarf_Die de_last_die; }; typedef struct Dwarf_Debug_InfoTypes_s *Dwarf_Debug_InfoTypes; /* As the tasks performed on a debug related section is the same, in order to make the process of adding a new section (very unlikely) a little bit easy and to reduce the possibility of errors, a simple table build dynamically, will contain the relevant information. */ struct Dwarf_dbg_sect_s { /* Debug section name must not be freed, is quoted string. This is the name from the object file itself. */ const char *ds_name; /* The section number in object section numbering. */ unsigned ds_number; /* Debug section information, points to de_debug_*member (or the like) of the dbg struct. */ struct Dwarf_Section_s *ds_secdata; unsigned ds_groupnumber; int ds_duperr; /* Error code for duplicated section */ int ds_emptyerr; /* Error code for empty section */ int ds_have_dwarf; /* Section contains DWARF */ int ds_have_zdebug; /* Section compressed: .zdebug name */ }; /* As the number of debug sections does not change very often, in the case a new section is added in 'enter_section_in_array()' the 'MAX_DEBUG_SECTIONS' must be updated accordingly. This does not yet allow for section-groups in object files, for which many .debug_info (and other) sections may exist. */ #define DWARF_MAX_DEBUG_SECTIONS 50 /* All the Dwarf_Debug tied-file info in one place. */ struct Dwarf_Tied_Data_s { /* Used to access executable from .dwo or .dwp object. Pointer to the tied_to Dwarf_Debug*/ Dwarf_Debug td_tied_object; /* TRUE if this tied object is tied to. It's extra work to look for a DW_AT_dwo_id. Set when tied dbg (on the base) was created. This helps us do it only when it may be productive. */ Dwarf_Bool td_is_tied_object; /* Used for Type Unit signatures. Type Units are in .debug_types in DW4 but in .debug_info in DW5. Some .debug_info point to them symbolically via DW_AT_signature attributes. If non-zero is a dwarf_tsearch 'tree'. Only non-zero if td_is_tied_object is set and we had a reason to build the search tree.. Type Units have a Dwarf_Sig8 signature in the header, and such is recorded here. Type Unit signatures can conflict with signatures in split-dwarf (dwo/dwp) sections. The Key for each record is a Dwarf_Sig8 (8 bytes). The data for each is a pointer to a Dwarf_CU_context record in this dbg (cu_context in one of tied dbg's de_cu_context_list). */ void *td_tied_search; }; /* dg_groupnum 0 does not exist. dg_groupnum 1 is base dg_groupnum 2 is dwo dg_groupnum 3 and higher are COMDAT groups (if any). */ struct Dwarf_Group_Data_s { /* For traditional DWARF the value is one, just one group. */ unsigned gd_number_of_groups; /* Raw elf (elf-like) section count. */ unsigned gd_number_of_sections; unsigned gd_map_entry_count; /* A map from section number to group number. */ void *gd_map; }; struct Dwarf_Debug_s { /* All file access methods and support data are hidden in this structure. We get a pointer, callers control the lifetime of the structure and contents. */ struct Dwarf_Obj_Access_Interface_s *de_obj_file; Dwarf_Handler de_errhand; Dwarf_Ptr de_errarg; /* Enabling us to close an fd if we own it, as in the case of dwarf_init_path(). de_fd is only meaningful if de_owns_fd is set. Each object file type has any necessary fd recorded under de_obj_file. */ int de_fd; char de_owns_fd; /* de_path is only set automatically if dwarf_init_path() was used to initialize things. Used with the .gnu_debuglink section. */ const char *de_path; const char ** de_gnu_global_paths; unsigned de_gnu_global_path_count; struct Dwarf_Debug_InfoTypes_s de_info_reading; struct Dwarf_Debug_InfoTypes_s de_types_reading; /* DW_GROUPNUMBER_ANY, DW_GROUPNUMBER_BASE, DW_GROUPNUMBER_DWO, or a comdat group number > 2 Selected at init time of this dbg based on user request and on data in the object. */ unsigned de_groupnumber; /* Supporting data for groupnumbers. */ struct Dwarf_Group_Data_s de_groupnumbers; /* Number of bytes in the length, and offset field in various .debu* sections. It's not very meaningful, and is only used in one 'approximate' calculation. de_offset_size would be a more appropos name. */ Dwarf_Small de_length_size; /* Size of the object file in bytes. If Unknown leave this zero. */ Dwarf_Unsigned de_filesize; /* number of bytes in a pointer of the target in various .debug_ sections. 4 in 32bit, 8 in MIPS 64, ia64. */ Dwarf_Small de_pointer_size; /* set at creation of a Dwarf_Debug to say if form_string should be checked for valid length at every call. 0 means do the check. non-zero means do not do the check. */ Dwarf_Small de_assume_string_in_bounds; /* Keep track of allocations so a dwarf_finish call can clean up. Null till a tree is created */ void * de_alloc_tree; /* These fields are used to process debug_frame section. **Updated by dwarf_get_fde_list in dwarf_frame.h */ /* Points to contiguous block of pointers to Dwarf_Cie_s structs. */ Dwarf_Cie *de_cie_data; /* Count of number of Dwarf_Cie_s structs. */ Dwarf_Signed de_cie_count; /* Keep eh (GNU) separate!. */ Dwarf_Cie *de_cie_data_eh; Dwarf_Signed de_cie_count_eh; /* Points to contiguous block of pointers to Dwarf_Fde_s structs. */ Dwarf_Fde *de_fde_data; /* Count of number of Dwarf_Fde_s structs. */ Dwarf_Unsigned de_fde_count; /* Keep eh (GNU) separate!. */ Dwarf_Fde *de_fde_data_eh; Dwarf_Unsigned de_fde_count_eh; struct Dwarf_Section_s de_debug_info; struct Dwarf_Section_s de_debug_types; struct Dwarf_Section_s de_debug_abbrev; struct Dwarf_Section_s de_debug_line; struct Dwarf_Section_s de_debug_line_str; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_loc; struct Dwarf_Section_s de_debug_aranges; struct Dwarf_Section_s de_debug_macinfo; struct Dwarf_Section_s de_debug_macro; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_names; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_pubnames; struct Dwarf_Section_s de_debug_str; struct Dwarf_Section_s de_debug_sup; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_loclists; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_rnglists; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_frame; struct Dwarf_Section_s de_gnu_debuglink; /* New September 2019 */ struct Dwarf_Section_s de_note_gnu_buildid; /* New September 2019 */ /* gnu: the g++ eh_frame section */ struct Dwarf_Section_s de_debug_frame_eh_gnu; struct Dwarf_Section_s de_debug_pubtypes; /* DWARF3 .debug_pubtypes */ /* Four SGI IRIX extensions essentially identical to DWARF3 .debug_pubtypes. Only on SGI IRIX. */ struct Dwarf_Section_s de_debug_funcnames; struct Dwarf_Section_s de_debug_typenames; struct Dwarf_Section_s de_debug_varnames; struct Dwarf_Section_s de_debug_weaknames; struct Dwarf_Section_s de_debug_ranges; /* Following two part of DebugFission and DWARF5 */ struct Dwarf_Section_s de_debug_str_offsets; struct Dwarf_Section_s de_debug_addr; /* Following for the .gdb_index section. */ struct Dwarf_Section_s de_debug_gdbindex; /* Types in DWARF5 are in .debug_info and in DWARF4 are in .debug_types. These indexes first standardized in DWARF5, DWARF4 can have them as an extension. The next to refer to the DWP index sections and the tu and cu indexes sections are distinct in DWARF4 & 5. */ struct Dwarf_Section_s de_debug_cu_index; struct Dwarf_Section_s de_debug_tu_index; /* For non-elf, simply leave the following two structs zeroed and they will be ignored. */ struct Dwarf_Section_s de_elf_symtab; struct Dwarf_Section_s de_elf_strtab; /* For a .dwp object file . For DWARF4, type units are in .debug_types (DWP is a GNU extension in DW4).. For DWARF5, type units are in .debug_info. */ 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; unsigned char de_elf_must_close; /* If non-zero, then it was dwarf_init (not dwarf_elf_init) so must elf_end() */ /* Default is DW_FRAME_INITIAL_VALUE from header. */ Dwarf_Half de_frame_rule_initial_value; /* Default is DW_FRAME_LAST_REG_NUM. */ Dwarf_Half de_frame_reg_rules_entry_count; Dwarf_Half de_frame_cfa_col_number; Dwarf_Half de_frame_same_value_number; Dwarf_Half de_frame_undefined_value_number; unsigned char de_big_endian_object; /* Non-zero if object being read is big-endian. */ /* Non-zero if dwarf_get_globals(), dwarf_get_funcs, dwarf_get_types,dwarf_get_pubtypes, dwarf_get_vars,dwarf_get_weaks should create and return a special zero-die-offset for the corresponding pubnames-style section CU header with zero pubnames-style named DIEs. In that case the list returned will have an entry with a zero for the die-offset (which is an impossible debug_info die_offset). New March 2019. See dwarf_return_empty_pubnames() */ unsigned char de_return_empty_pubnames; struct Dwarf_dbg_sect_s de_debug_sections[DWARF_MAX_DEBUG_SECTIONS]; unsigned de_debug_sections_total_entries; /* Number actually used. */ struct Dwarf_Harmless_s de_harmless_errors; struct Dwarf_Printf_Callback_Info_s de_printf_callback; void * de_printf_callback_null_device_handle; /* Used in a tied dbg to hold global info on the tied object (DW_AT_dwo_id). And for Type Unit signatures whether tied or not. */ struct Dwarf_Tied_Data_s de_tied_data; }; int dwarf_printf(Dwarf_Debug dbg, const char * format, ...) #ifdef __GNUC__ /* The following gets us printf-like arg checking. */ __attribute__ ((format (__printf__, 2, 3))) #endif ; typedef struct Dwarf_Chain_s *Dwarf_Chain; struct Dwarf_Chain_s { void *ch_item; Dwarf_Chain ch_next; }; typedef struct Dwarf_Chain_o *Dwarf_Chain_2; struct Dwarf_Chain_o { Dwarf_Off ch_item; Dwarf_Chain_2 ch_next; }; /* Size of cu header version stamp field. */ #define CU_VERSION_STAMP_SIZE DWARF_HALF_SIZE /* Size of cu header address size field. */ #define CU_ADDRESS_SIZE_SIZE sizeof(Dwarf_Small) #define ORIGINAL_DWARF_OFFSET_SIZE 4 /* The DISTINGUISHED VALUE is 4 byte value defined by DWARF since DWARF3. */ #define DISTINGUISHED_VALUE 0xffffffff #define DISTINGUISHED_VALUE_OFFSET_SIZE 8 #define DISTINGUISHED_VALUE_ARRAY(x) char x[4] = { 0xff,0xff,0xff,0xff } /* We don't load the sections until they are needed. This function is used to load the section. */ int _dwarf_load_section(Dwarf_Debug, struct Dwarf_Section_s *, Dwarf_Error *); int _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned *sbase_out, Dwarf_Error *error); int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Small *data_ptr, Dwarf_Small *end_data_ptr, Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, Dwarf_Unsigned *str_sect_offset_out, Dwarf_Error *error); int _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index, Dwarf_Addr *addr_out, Dwarf_Error *error); int _dwarf_siblingof_internal(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_CU_Context context, Dwarf_Bool is_info, Dwarf_Die * caller_ret_die, Dwarf_Error * error); int _dwarf_get_base_and_size_given_signature(Dwarf_CU_Context *context, Dwarf_Sig8 *signature_in, /* xu_sect_index means DW_SECT_info etc. */ Dwarf_Unsigned xu_sect_index, Dwarf_Unsigned *base_out, Dwarf_Unsigned *size_out, Dwarf_Error *err); Dwarf_Bool _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg); Dwarf_Bool _dwarf_file_has_debug_fission_tu_index(Dwarf_Debug dbg); Dwarf_Bool _dwarf_file_has_debug_fission_index(Dwarf_Debug dbg); /* This should only be called on a CU. Never a TU. */ int _dwarf_get_debugfission_for_offset(Dwarf_Debug dbg, Dwarf_Off offset_wanted, const char *keytype, /* "cu" or "tu" */ Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error *error); /* whichone: must be a valid DW_SECT* macro value. */ Dwarf_Unsigned _dwarf_get_dwp_extra_offset( struct Dwarf_Debug_Fission_Per_CU_s* dwp, unsigned whichone, Dwarf_Unsigned * size); /* This will look into the tied Dwarf_Debug to which should have a skeleton CU DIE and an addr_base and also have the .debug_addr section. */ int _dwarf_get_addr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned addrindex, Dwarf_Addr *addr_out, Dwarf_Error *error); int _dwarf_get_fission_addition_die(Dwarf_Die die, int dw_sect_index, Dwarf_Unsigned* offset, Dwarf_Unsigned*size, Dwarf_Error *error); int _dwarf_get_addr_index_itself(int theform, Dwarf_Small *info_ptr, Dwarf_Debug dbg, Dwarf_CU_Context cu_context, Dwarf_Unsigned *val_out, Dwarf_Error * error); int _dwarf_search_for_signature(Dwarf_Debug dbg, Dwarf_Sig8 sig, Dwarf_CU_Context *context_out, Dwarf_Error *error); void _dwarf_tied_destroy_free_node(void *node); void _dwarf_destroy_group_map(Dwarf_Debug dbg); int _dwarf_section_get_target_group(Dwarf_Debug dbg, unsigned obj_section_index, unsigned * groupnumber, Dwarf_Error * error); int _dwarf_dwo_groupnumber_given_name( const char *name, unsigned *grpnum_out); int _dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, unsigned obj_section_index, unsigned * groupnumber_out, UNUSEDARG Dwarf_Error * error); int _dwarf_insert_in_group_map(Dwarf_Debug dbg, unsigned groupnum, unsigned section_index, const char *name, Dwarf_Error * error); /* returns TRUE/FALSE: meaning this section name is in map for this groupnum or not.*/ int _dwarf_section_in_group_by_name(Dwarf_Debug dbg, const char * scn_name, unsigned groupnum); int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool is_info, 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_Bool * has_signature, Dwarf_Unsigned *typeoffset, Dwarf_Unsigned * next_cu_offset, Dwarf_Half * header_cu_type, Dwarf_Error * error); /* Relates to .debug_addr */ int _dwarf_look_in_local_and_tied(Dwarf_Half attr_form, Dwarf_CU_Context context, Dwarf_Small *info_ptr, Dwarf_Addr *return_addr, Dwarf_Error *error); int _dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned * ranges_base_out, Dwarf_Unsigned * addr_base_out, Dwarf_Error * error); int _dwarf_get_string_from_tied(Dwarf_Debug dbg, Dwarf_Unsigned offset, char **return_str, Dwarf_Error*error); int _dwarf_valid_form_we_know(Dwarf_Unsigned at_form, Dwarf_Unsigned at_name); int _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, unsigned attrform, Dwarf_Unsigned offset, char ** return_str, Dwarf_Error * error); int _dwarf_file_name_is_full_path(Dwarf_Small *fname); /* This is an elf-only extension to get SHF_COMPRESSED flag from sh_flags. if pointer not set (which is normal for non-elf objects) it is fine. */ typedef int (*_dwarf_get_elf_flags_func_ptr_type)( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error); extern _dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr; /* This is libelf access to Elf object. */ extern int _dwarf_elf_setup(int fd, char *true_path_out_buffer, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); /* This is non-libelf Elf access */ extern int _dwarf_elf_nlsetup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); void _dwarf_destruct_elf_nlaccess(struct Dwarf_Obj_Access_Interface_s *aip); extern int _dwarf_macho_setup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); void _dwarf_destruct_macho_access(struct Dwarf_Obj_Access_Interface_s *aip); extern int _dwarf_pe_setup(int fd, char *path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error); void _dwarf_destruct_pe_access(struct Dwarf_Obj_Access_Interface_s *aip); extern Dwarf_Bool _dwarf_allow_formudata(unsigned form); extern int _dwarf_formudata_internal(Dwarf_Debug dbg, unsigned form, Dwarf_Byte_Ptr data, Dwarf_Byte_Ptr section_end, Dwarf_Unsigned *return_uval, Dwarf_Unsigned *bytes_read, Dwarf_Error *error); Dwarf_Byte_Ptr _dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context, Dwarf_Unsigned *section_len_out); Dwarf_Byte_Ptr _dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context); Dwarf_Byte_Ptr _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context); int _dwarf_extract_data16(Dwarf_Debug dbg, Dwarf_Small *data, Dwarf_Small *section_start, Dwarf_Small *section_end, Dwarf_Form_Data16 * returned_val, Dwarf_Error *error); void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno); dwarfutils-20200114/libdwarf/dwarf_original_elf_init.c000066400000000000000000000151111361531463500227350ustar00rootroot00000000000000/* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2011-2015 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef HAVE_LIBELF_H #include #else #ifdef HAVE_LIBELF_LIBELF_H #include #endif #endif #include #include #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_elf_access.h" #include "dwarf_object_detector.h" #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 /* New March 2017 */ int dwarf_elf_init_b( #ifndef DWARF_WITH_LIBELF UNUSEDARG dwarf_elf_handle elf_file_pointer, UNUSEDARG Dwarf_Unsigned access, UNUSEDARG unsigned group_number, UNUSEDARG Dwarf_Handler errhand, UNUSEDARG Dwarf_Ptr errarg, UNUSEDARG Dwarf_Debug * ret_dbg, #else dwarf_elf_handle elf_file_pointer, Dwarf_Unsigned access, unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, #endif /* DWARF_WITH_LIBELF */ Dwarf_Error * error) { #ifndef DWARF_WITH_LIBELF DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR); #else /* DWARF_WITH_LIBELF */ Dwarf_Obj_Access_Interface *binary_interface = 0; int res = DW_DLV_OK; int localerrnum = 0; int libdwarf_owns_elf = FALSE; if (!ret_dbg) { DWARF_DBG_ERROR(NULL,DW_DLE_DWARF_INIT_DBG_NULL,DW_DLV_ERROR); } if (access != DW_DLC_READ) { DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); } /* This allocates and fills in *binary_interface. */ res = dwarf_elf_object_access_init( elf_file_pointer, libdwarf_owns_elf, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR); } /* allocates and initializes Dwarf_Debug */ res = dwarf_object_init_b(binary_interface, errhand, errarg, group_number, ret_dbg, error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); return res; } res = dwarf_add_debuglink_global_path(*ret_dbg, "/usr/lib/debug",error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); return res; } /* DBG known */ return res; #endif /* DWARF_WITH_LIBELF */ } int dwarf_elf_init( #ifndef DWARF_WITH_LIBELF UNUSEDARG dwarf_elf_handle elf_file_pointer, UNUSEDARG Dwarf_Unsigned access, UNUSEDARG Dwarf_Handler errhand, UNUSEDARG Dwarf_Ptr errarg, UNUSEDARG Dwarf_Debug * ret_dbg, #else dwarf_elf_handle elf_file_pointer, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, #endif Dwarf_Error * error) { #ifndef DWARF_WITH_LIBELF DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR); #else /* DWARF_WITH_LIBELF */ int res = 0; res = dwarf_elf_init_b(elf_file_pointer, DW_GROUPNUMBER_ANY, access,errhand,errarg,ret_dbg,error); return res; #endif /* DWARF_WITH_LIBELF */ } int _dwarf_elf_setup( #ifndef DWARF_WITH_LIBELF UNUSEDARG int fd, UNUSEDARG char *path, UNUSEDARG unsigned ftype, UNUSEDARG unsigned endian, UNUSEDARG unsigned offsetsize, UNUSEDARG size_t filesize, UNUSEDARG Dwarf_Unsigned access, UNUSEDARG unsigned groupnumber, UNUSEDARG Dwarf_Handler errhand, UNUSEDARG Dwarf_Ptr errarg, UNUSEDARG Dwarf_Debug *dbg, #else int fd, UNUSEDARG char *path, UNUSEDARG unsigned ftype, UNUSEDARG unsigned endian, UNUSEDARG unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg, #endif /* DWARF_WITH_LIBELF */ Dwarf_Error *error) { #ifndef DWARF_WITH_LIBELF DWARF_DBG_ERROR(NULL, DW_DLE_PRODUCER_CODE_NOT_AVAILABLE, DW_DLV_ERROR); #else /* DWARF_WITH_LIBELF */ Elf_Cmd what_kind_of_elf_read = ELF_C_READ; Dwarf_Obj_Access_Interface *binary_interface = 0; int res = DW_DLV_OK; int localerrnum = 0; int libdwarf_owns_elf = TRUE; dwarf_elf_handle elf_file_pointer = 0; elf_version(EV_CURRENT); elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0); if (elf_file_pointer == NULL) { DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); } /* Sets up elf access function pointers. */ res = dwarf_elf_object_access_init( elf_file_pointer, libdwarf_owns_elf, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR); } /* allocates and initializes Dwarf_Debug */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); return res; } (*dbg)->de_filesize = filesize; res = dwarf_add_debuglink_global_path(*dbg, "/usr/lib/debug",error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); } return res; #endif /* DWARF_WITH_LIBELF */ } dwarfutils-20200114/libdwarf/dwarf_pe_descr.h000066400000000000000000000175421361531463500210630ustar00rootroot00000000000000#ifndef DWARF_PE_DESCR_H #define DWARF_PE_DESCR_H /* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define IMAGE_DOS_SIGNATURE_dw 0x5a4d /* le on disk 'M' 'Z' */ #define IMAGE_DOS_REVSIGNATURE_dw 0x4d5a /* be on disk */ #define IMAGE_NT_SIGNATURE_dw 0x00004550 #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYPE */ /* Data types see https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx */ /*#define FIELD_OFFSET(type,field) ((LONG)(LONG_PTR)&(((type *)0)->field))*/ #define IMAGE_SIZEOF_SYMBOL 18 struct dos_header_dw { TYP(dh_mz,2); TYP(dh_dos_data,58); TYP(dh_image_offset,4); }; /* IMAGE_FILE_HEADER_dw see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680313(v=vs.85).aspx */ typedef struct { TYP(Machine,2); TYP(NumberOfSections,2); TYP(TimeDateStamp,4); TYP(PointerToSymbolTable,4); TYP(NumberOfSymbols,4); TYP(SizeOfOptionalHeader,2); TYP(Characteristics,2); } IMAGE_FILE_HEADER_dw; /* IMAGE_DATA_DIRECTORY_dw see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680305(v=vs.85).aspx */ typedef struct { TYP(VirtualAddress,4); TYP(Size,4); } IMAGE_DATA_DIRECTORY_dw; /* IMAGE_OPTIONAL_HEADER see https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx */ #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 typedef struct { TYP(Magic,2); unsigned char MajorLinkerVersion; unsigned char MinorLinkerVersion; TYP(SizeOfCode,4); TYP(SizeOfInitializedData,4); TYP(SizeOfUninitializedData,4); TYP(AddressOfEntryPoint,4); TYP(BaseOfCode,4); TYP(BaseOfData,4); TYP(ImageBase,4); TYP(SectionAlignment,4); TYP(FileAlignment,4); TYP(MajorOperatingSystemVersion,2); TYP(MinorOperatingSystemVersion,2); TYP(MajorImageVersion,2); TYP(MinorImageVersion,2); TYP(MajorSubsystemVersion,2); TYP(MinorSubsystemVersion,2); TYP(Win32VersionValue,4); TYP(SizeOfImage,4); TYP(SizeOfHeaders,4); TYP(CheckSum,4); TYP(Subsystem,2); TYP(DllCharacteristics,2); TYP(SizeOfStackReserve,4); TYP(SizeOfStackCommit,4); TYP(SizeOfHeapReserve,4); TYP(SizeOfHeapCommit,4); TYP(LoaderFlags,4); TYP(NumberOfRvaAndSizes,4); IMAGE_DATA_DIRECTORY_dw DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER32_dw; typedef struct { TYP(Magic,2); unsigned char MajorLinkerVersion; unsigned char MinorLinkerVersion; TYP(SizeOfCode,4); TYP(SizeOfInitializedData,4); TYP(SizeOfUninitializedData,4); TYP(AddressOfEntryPoint,4); TYP(BaseOfCode,4); TYP(ImageBase,8); TYP(SectionAlignment,4); TYP(FileAlignment,4); TYP(MajorOperatingSystemVersion,2); TYP(MinorOperatingSystemVersion,2); TYP(MajorImageVersion,2); TYP(MinorImageVersion,2); TYP(MajorSubsystemVersion,2); TYP(MinorSubsystemVersion,2); TYP(Win32VersionValue,4); TYP(SizeOfImage,4); TYP(SizeOfHeaders,4); TYP(CheckSum,4); TYP(Subsystem,2); TYP(DllCharacteristics,2); TYP(SizeOfStackReserve,8); TYP(SizeOfStackCommit,8); TYP(SizeOfHeapReserve,8); TYP(SizeOfHeapCommit,8); TYP(LoaderFlags,4); TYP(NumberOfRvaAndSizes,4); IMAGE_DATA_DIRECTORY_dw DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64_dw; /* IMAGE_NT_HEADERS see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680336(v=vs.85).aspx */ #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 typedef struct { TYP(Signature,4); IMAGE_FILE_HEADER_dw FileHeader; IMAGE_OPTIONAL_HEADER64_dw OptionalHeader; } IMAGE_NT_HEADERS64_dw, *PIMAGE_NT_HEADERS64_dw; typedef struct { TYP(Signature,4); IMAGE_FILE_HEADER_dw FileHeader; IMAGE_OPTIONAL_HEADER32_dw OptionalHeader; } IMAGE_NT_HEADERS32_dw, *PIMAGE_NT_HEADERS32_dw; /* IMAGE_SECTION_HEADER_dw see: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx and, for details on VirtualSize and SizeOfRawData: https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_image_section_header */ #define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct { char Name[IMAGE_SIZEOF_SHORT_NAME]; union { TYP(PhysicalAddress,4); TYP(VirtualSize,4); } Misc; TYP(VirtualAddress,4); TYP(SizeOfRawData,4); TYP(PointerToRawData,4); TYP(PointerToRelocations,4); TYP(PointerToLinenumbers,4); TYP(NumberOfRelocations,2); TYP(NumberOfLinenumbers,2); TYP(Characteristics,4); } IMAGE_SECTION_HEADER_dw, *PIMAGE_SECTION_HEADER_dw; #define IMAGE_SCN_SCALE_INDEX 0x00000001 #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 #define IMAGE_SCN_LNK_OTHER 0x00000100 #define IMAGE_SCN_LNK_INFO 0x00000200 #define IMAGE_SCN_LNK_REMOVE 0x00000800 #define IMAGE_SCN_LNK_COMDAT 0x00001000 #define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 #define IMAGE_SCN_MEM_FARDATA 0x00008000 #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 #define IMAGE_SCN_MEM_LOCKED 0x00040000 #define IMAGE_SCN_MEM_PRELOAD 0x00080000 #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 #define IMAGE_SCN_ALIGN_128BYTES 0x00800000 #define IMAGE_SCN_ALIGN_256BYTES 0x00900000 #define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 #define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 #define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 #define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 #define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 #define IMAGE_SCN_ALIGN_MASK 0x00F00000 #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 #define IMAGE_SCN_MEM_SHARED 0x10000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 #define IMAGE_SCN_MEM_WRITE 0x80000000 #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_PE_DESCR_H */ dwarfutils-20200114/libdwarf/dwarf_peread.c000066400000000000000000000656021361531463500205320ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* This file reads the parts of a Windows PE file appropriate to reading DWARF debugging data. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #include #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include /* memcpy */ #include /* open() */ #include /* open() */ #include /* open() */ #include #ifdef HAVE_UNISTD_H #include /* lseek read close */ #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarf.h" #include "libdwarfdefs.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" #include "memcpy_swap.h" #include "dwarf_error.h" /* for _dwarf_error() declaration */ #include "dwarf_reading.h" #include "dwarf_object_read_common.h" #include "dwarf_object_detector.h" #include "dwarf_pe_descr.h" #include "dwarf_peread.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #define DOS_HEADER_LEN 64 #ifndef TYP #define TYP(n,l) char n[l] #endif /* TYP */ #ifndef SIZEOFT32 #define SIZEOFT32 4 #endif /* SIZEOFT32 */ static int _dwarf_pe_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum); static unsigned long magic_copy(char *d, unsigned len) { unsigned i = 0; unsigned long v = 0; v = d[0]; for(i = 1 ; i < len; ++i) { v <<= 8; v |= 0xff&d[i]; } return v; } #ifdef WORDS_BIGENDIAN #define ASNAR(func,t,s) \ do { \ unsigned tbyte = sizeof(t) - sizeof(s); \ t = 0; \ func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(func,t,s) \ do { \ t = 0; \ func(&t,&s[0],sizeof(s)); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ /* name_array is 8 byte string */ static int pe_section_name_get(dwarf_pe_object_access_internals_t *pep, const char *name_array, const char ** name_out, int *errcode) { if (name_array[0] == '/') { long v = 0; unsigned long u = 0; const char *s = 0; char temp_array[9]; memcpy(temp_array,name_array+1,7); temp_array[7] = 0; v = atoi(temp_array); if (v < 0) { *errcode = DW_DLE_STRING_OFFSET_BAD; return DW_DLV_ERROR; } u = v; if (u > pep->pe_string_table_size) { *errcode = DW_DLE_STRING_OFFSET_BAD; return DW_DLV_ERROR; } s = pep->pe_string_table +u; *name_out = s; return DW_DLV_OK; } *name_out = name_array; return DW_DLV_OK; } static Dwarf_Endianness pe_get_byte_order (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_endian; } static Dwarf_Small pe_get_length_size (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_offsetsize/8; } static Dwarf_Small pe_get_pointer_size (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_pointersize/8; } static Dwarf_Unsigned pe_get_section_count (void *obj) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); return pep->pe_section_count; } static int pe_get_section_info (void *obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section *return_section, UNUSEDARG int *error) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); if (section_index < pep->pe_section_count) { struct dwarf_pe_generic_image_section_header *sp = 0; sp = pep->pe_sectionptr + section_index; return_section->addr = pep->pe_OptionalHeader.ImageBase + sp->VirtualAddress; ; return_section->type = 0; /* SizeOfRawData can be rounded or truncated, use VirtualSize for the real analog of Elf section size. */ return_section->size = sp->VirtualSize; return_section->name = sp->dwarfsectname; return_section->link = 0; return_section->info = 0; return_section->entrysize = 0; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int load_optional_header32(dwarf_pe_object_access_internals_t *pep, Dwarf_Unsigned offset, int*errcode) { int res = 0; IMAGE_OPTIONAL_HEADER32_dw hdr; pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER32_dw); if ((pep->pe_optional_header_size + offset) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)&hdr, (off_t)offset, sizeof(IMAGE_OPTIONAL_HEADER32_dw), (off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* This is a subset of fields. */ ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.Magic, hdr.Magic); pep->pe_OptionalHeader.MajorLinkerVersion= hdr.MajorLinkerVersion; pep->pe_OptionalHeader.MinorLinkerVersion= hdr.MinorLinkerVersion; ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.ImageBase, hdr.ImageBase); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfCode, hdr.SizeOfCode); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfImage, hdr.SizeOfImage); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfHeaders, hdr.SizeOfHeaders); pep->pe_OptionalHeader.SizeOfDataDirEntry = sizeof(IMAGE_DATA_DIRECTORY_dw); return DW_DLV_OK; } static int load_optional_header64(dwarf_pe_object_access_internals_t *pep, Dwarf_Unsigned offset, int*errcode ) { IMAGE_OPTIONAL_HEADER64_dw hdr; int res = 0; pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER64_dw); if ((pep->pe_optional_header_size + offset) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)&hdr, (off_t)offset, sizeof(IMAGE_OPTIONAL_HEADER64_dw), (off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* This is a subset of fields. */ ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.Magic, hdr.Magic); pep->pe_OptionalHeader.MajorLinkerVersion= hdr.MajorLinkerVersion; pep->pe_OptionalHeader.MinorLinkerVersion= hdr.MinorLinkerVersion; ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfCode, hdr.SizeOfCode); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfImage, hdr.SizeOfImage); ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfHeaders, hdr.SizeOfHeaders); pep->pe_OptionalHeader.SizeOfDataDirEntry = sizeof(IMAGE_DATA_DIRECTORY_dw); return DW_DLV_OK; } static int pe_load_section (void *obj, Dwarf_Half section_index, Dwarf_Small **return_data, int *error) { dwarf_pe_object_access_internals_t *pep = (dwarf_pe_object_access_internals_t*)(obj); if (0 < section_index && section_index < pep->pe_section_count) { int res = 0; struct dwarf_pe_generic_image_section_header *sp = pep->pe_sectionptr + section_index; Dwarf_Unsigned read_length = 0; if(sp->loaded_data) { *return_data = sp->loaded_data; return DW_DLV_OK; } if (!sp->VirtualSize) { return DW_DLV_NO_ENTRY; } read_length = sp->SizeOfRawData; if(sp->VirtualSize < read_length) { /* Don't read padding that wasn't allocated in memory */ read_length = sp->VirtualSize; } if ((read_length + sp->PointerToRawData) > pep->pe_filesize) { *error = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } sp->loaded_data = malloc((size_t)sp->SizeOfRawData); if(!sp->loaded_data) { *error = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)sp->loaded_data, (off_t)sp->PointerToRawData, (size_t)read_length, (off_t)pep->pe_filesize, error); if (res != DW_DLV_OK) { free(sp->loaded_data); sp->loaded_data = 0; return res; } if(sp->VirtualSize > read_length) { /* Zero space that was allocated but truncated from the file */ memset(sp->loaded_data + read_length, 0, (size_t)(sp->VirtualSize - read_length)); } *return_data = sp->loaded_data; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } void _dwarf_destruct_pe_access( struct Dwarf_Obj_Access_Interface_s *aip) { dwarf_pe_object_access_internals_t *pep = 0; Dwarf_Unsigned i = 0; if (!aip) { return; } pep = (dwarf_pe_object_access_internals_t*)(aip->object); if (pep->pe_destruct_close_fd) { close(pep->pe_fd); pep->pe_fd = -1; } free((char *)pep->pe_path); pep->pe_path = 0; if (pep->pe_sectionptr) { struct dwarf_pe_generic_image_section_header *sp = 0; sp = pep->pe_sectionptr; for( i=0; i < pep->pe_section_count; ++i,++sp) { if (sp->loaded_data) { free(sp->loaded_data); sp->loaded_data = 0; } free(sp->name); sp->name = 0; free(sp->dwarfsectname); sp->dwarfsectname = 0; } free(pep->pe_sectionptr); pep->pe_section_count = 0; } free(pep->pe_string_table); pep->pe_string_table = 0; free(pep); free(aip); return; } static int dwarf_pe_load_dwarf_section_headers( dwarf_pe_object_access_internals_t *pep,int *errcode) { Dwarf_Unsigned i = 0; Dwarf_Unsigned input_count = pep->pe_FileHeader.NumberOfSections; Dwarf_Unsigned offset_in_input = pep->pe_section_table_offset; Dwarf_Unsigned section_hdr_size = sizeof(IMAGE_SECTION_HEADER_dw); struct dwarf_pe_generic_image_section_header *sec_outp = 0; Dwarf_Unsigned cur_offset = offset_in_input; Dwarf_Unsigned past_end_hdrs = offset_in_input + section_hdr_size*input_count; /* internal sections include null initial section */ pep->pe_section_count = input_count+1; if (past_end_hdrs > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } if (!offset_in_input) { *errcode = DW_DLE_PE_OFFSET_BAD; return DW_DLV_ERROR; } pep->pe_sectionptr = (struct dwarf_pe_generic_image_section_header * ) calloc((size_t)pep->pe_section_count, sizeof(struct dwarf_pe_generic_image_section_header)); if (!pep->pe_sectionptr) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } sec_outp = pep->pe_sectionptr; sec_outp->name = strdup(""); sec_outp->dwarfsectname = strdup(""); sec_outp++; for ( ; i < input_count; ++i, cur_offset += section_hdr_size, sec_outp++) { int res = 0; IMAGE_SECTION_HEADER_dw filesect; char safe_name[IMAGE_SIZEOF_SHORT_NAME +1]; const char *expname = 0; res = _dwarf_object_read_random(pep->pe_fd, (char *)&filesect,(off_t)cur_offset, sizeof(filesect), (off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } /* The following is safe. filesect.Name is IMAGE_SIZEOF_SHORT_NAME bytes long and may not (not sure) have a NUL terminator. */ strncpy(safe_name,filesect.Name,IMAGE_SIZEOF_SHORT_NAME); /* Then add NUL terminator. */ safe_name[IMAGE_SIZEOF_SHORT_NAME] = 0; sec_outp->name = strdup(safe_name); res = pe_section_name_get(pep, safe_name,&expname,errcode); if (res != DW_DLV_OK) { return res; } sec_outp->dwarfsectname = strdup(expname); if ( !sec_outp->name || !sec_outp->dwarfsectname) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } sec_outp->SecHeaderOffset = cur_offset; ASNAR(pep->pe_copy_word,sec_outp->VirtualSize, filesect.Misc.VirtualSize); ASNAR(pep->pe_copy_word,sec_outp->VirtualAddress, filesect.VirtualAddress); ASNAR(pep->pe_copy_word,sec_outp->SizeOfRawData, filesect.SizeOfRawData); ASNAR(pep->pe_copy_word,sec_outp->PointerToRawData, filesect.PointerToRawData); if(sec_outp->SizeOfRawData > pep->pe_filesize || sec_outp->PointerToRawData > pep->pe_filesize || (sec_outp->SizeOfRawData+ sec_outp->PointerToRawData > pep->pe_filesize)) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } ASNAR(pep->pe_copy_word,sec_outp->PointerToRelocations, filesect.PointerToRelocations); ASNAR(pep->pe_copy_word,sec_outp->PointerToLinenumbers, filesect.PointerToLinenumbers); ASNAR(pep->pe_copy_word,sec_outp->NumberOfRelocations, filesect.NumberOfRelocations); ASNAR(pep->pe_copy_word,sec_outp->NumberOfLinenumbers, filesect.NumberOfLinenumbers); ASNAR(pep->pe_copy_word,sec_outp->Characteristics, filesect.Characteristics); /* sec_outp->loaded data set when we load a section */ } return DW_DLV_OK; } static int dwarf_load_pe_sections( dwarf_pe_object_access_internals_t *pep,int *errcode) { struct dos_header_dw dhinmem; IMAGE_FILE_HEADER_dw ifh; void (*word_swap) (void *, const void *, unsigned long); unsigned locendian = 0; int res = 0; Dwarf_Unsigned dos_sig = 0; Dwarf_Unsigned nt_address = 0; char nt_sig_array[4]; unsigned long nt_signature = 0; if ( (sizeof(ifh) + sizeof(dhinmem)) >= pep->pe_filesize) { /* corrupt object. */ *errcode = DW_DLE_PE_SIZE_SMALL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd,(char *)&dhinmem, 0, sizeof(dhinmem),(off_t)pep->pe_filesize, errcode); if (res != DW_DLV_OK) { return res; } dos_sig = magic_copy((char *)dhinmem.dh_mz, sizeof(dhinmem.dh_mz)); if (dos_sig == IMAGE_DOS_SIGNATURE_dw) { /* IMAGE_DOS_SIGNATURE_dw assumes bytes reversed by little-endian load, so we intrepet a match the other way. */ /* BIG ENDIAN. From looking at hex characters in object */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_noswap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_swap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_OBJECT_MSB; } else if (dos_sig == IMAGE_DOS_REVSIGNATURE_dw) { /* raw load, so intrepet a match the other way. */ /* LITTLE ENDIAN */ #ifdef WORDS_BIGENDIAN word_swap = _dwarf_memcpy_swap_bytes; #else /* LITTLE ENDIAN */ word_swap = _dwarf_memcpy_noswap_bytes; #endif /* LITTLE- BIG-ENDIAN */ locendian = DW_OBJECT_LSB; } else { /* Not dos header not a PE file we recognize */ *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } if (locendian != pep->pe_endian) { /* Really this is a coding botch somewhere here, not an object corruption. */ *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } pep->pe_copy_word = word_swap; ASNAR(word_swap,nt_address,dhinmem.dh_image_offset); if (pep->pe_filesize < (nt_address + sizeof(nt_sig_array))) { /* The nt_address is really a file offset. */ *errcode = DW_DLE_FILE_TOO_SMALL; /* Not dos header not a PE file we recognize */ return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)&nt_sig_array[0], (off_t)nt_address, sizeof(nt_sig_array), (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } { unsigned long lsig = 0; ASNAR(word_swap,lsig,nt_sig_array); nt_signature = lsig; } if (nt_signature != IMAGE_NT_SIGNATURE_dw) { *errcode = DW_DLE_FILE_WRONG_TYPE; return DW_DLV_ERROR; } pep->pe_nt_header_offset = nt_address + SIZEOFT32; if (pep->pe_filesize < (pep->pe_nt_header_offset + sizeof(ifh))) { *errcode = DW_DLE_FILE_TOO_SMALL; /* Not image header not a PE file we recognize */ return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd,(char *)&ifh, (off_t)pep->pe_nt_header_offset, sizeof(ifh), (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } ASNAR(word_swap,pep->pe_FileHeader.Machine,ifh.Machine); ASNAR(word_swap,pep->pe_FileHeader.NumberOfSections, ifh.NumberOfSections); ASNAR(word_swap,pep->pe_FileHeader.TimeDateStamp, ifh.TimeDateStamp); ASNAR(word_swap,pep->pe_FileHeader.PointerToSymbolTable, ifh.PointerToSymbolTable); ASNAR(word_swap,pep->pe_FileHeader.NumberOfSymbols, ifh.NumberOfSymbols); ASNAR(word_swap,pep->pe_FileHeader.SizeOfOptionalHeader, ifh.SizeOfOptionalHeader); ASNAR(word_swap,pep->pe_FileHeader.Characteristics, ifh.Characteristics); pep->pe_optional_header_offset = pep->pe_nt_header_offset+ sizeof(ifh); if (pep->pe_offsetsize == 32) { res = load_optional_header32(pep, pep->pe_optional_header_offset,errcode); pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER32_dw); } else if (pep->pe_offsetsize == 64) { res = load_optional_header64(pep, pep->pe_optional_header_offset,errcode); pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER64_dw); } else { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (res != DW_DLV_OK) { return res; } pep->pe_section_table_offset = pep->pe_optional_header_offset + pep->pe_optional_header_size; pep->pe_symbol_table_offset = pep->pe_FileHeader.PointerToSymbolTable; if (pep->pe_symbol_table_offset >= pep->pe_filesize) { *errcode = DW_DLE_OFFSET_SIZE; return DW_DLV_ERROR; } if (pep->pe_symbol_table_offset) { pep->pe_string_table_offset = pep->pe_symbol_table_offset + (pep->pe_FileHeader.NumberOfSymbols * IMAGE_SIZEOF_SYMBOL); } if (pep->pe_string_table_offset >= pep->pe_filesize) { *errcode = DW_DLE_OFFSET_SIZE; pep->pe_string_table_size = 0; return DW_DLV_ERROR; } if (pep->pe_string_table_offset) { /* https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#coff-string-table */ /* The first 4 bytes of the string table contain the size of the string table. */ char size_field[4]; if ((pep->pe_string_table_offset+sizeof(size_field)) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } memset(size_field,0,sizeof(size_field)); res = _dwarf_object_read_random(pep->pe_fd, (char *)size_field, (off_t)pep->pe_string_table_offset, sizeof(size_field), (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } ASNAR(pep->pe_copy_word,pep->pe_string_table_size, size_field); if( pep->pe_string_table_size >= pep->pe_filesize ) { *errcode = DW_DLE_PE_OFFSET_BAD; return DW_DLV_ERROR; } if ((pep->pe_string_table_offset+pep->pe_string_table_size) > pep->pe_filesize) { *errcode = DW_DLE_FILE_TOO_SMALL; return DW_DLV_ERROR; } pep->pe_string_table = (char *)malloc((size_t)pep->pe_string_table_size); if (!pep->pe_string_table) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } res = _dwarf_object_read_random(pep->pe_fd, (char *)pep->pe_string_table, (off_t)pep->pe_string_table_offset, (size_t)pep->pe_string_table_size, (off_t)pep->pe_filesize,errcode); if (res != DW_DLV_OK) { return res; } } res = dwarf_pe_load_dwarf_section_headers(pep,errcode); return res; } int _dwarf_pe_setup(int fd, char *true_path, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg,Dwarf_Error *error) { Dwarf_Obj_Access_Interface *binary_interface = 0; dwarf_pe_object_access_internals_t *pep = 0; int res = DW_DLV_OK; int localerrnum = 0; res = _dwarf_pe_object_access_init( fd, ftype,endian,offsetsize,filesize,access, &binary_interface, &localerrnum); if (res != DW_DLV_OK) { if (res == DW_DLV_NO_ENTRY) { return res; } _dwarf_error(NULL, error, localerrnum); return DW_DLV_ERROR; } /* allocates and initializes Dwarf_Debug, generic code */ res = dwarf_object_init_b(binary_interface, errhand, errarg, groupnumber, dbg, error); if (res != DW_DLV_OK){ _dwarf_destruct_pe_access(binary_interface); return res; } pep = binary_interface->object; pep->pe_path = strdup(true_path); return res; } static Dwarf_Obj_Access_Methods pe_methods = { pe_get_section_info, pe_get_byte_order, pe_get_length_size, pe_get_pointer_size, pe_get_section_count, pe_load_section, 0 /* ignore pe relocations. */ }; /* On any error this frees internals. */ static int _dwarf_pe_object_access_internals_init( dwarf_pe_object_access_internals_t * internals, int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, UNUSEDARG Dwarf_Unsigned access, int *errcode) { dwarf_pe_object_access_internals_t * intfc = internals; struct Dwarf_Obj_Access_Interface_s *localdoas = 0; int res = 0; /* Must malloc as _dwarf_destruct_pe_access() forces that due to other uses. */ localdoas = (struct Dwarf_Obj_Access_Interface_s *) malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); if (!localdoas) { free(internals); *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); intfc->pe_ident[0] = 'P'; intfc->pe_ident[1] = '1'; intfc->pe_fd = fd; intfc->pe_is_64bit = ((offsetsize==64)?TRUE:FALSE); intfc->pe_offsetsize = offsetsize; intfc->pe_pointersize = offsetsize; intfc->pe_filesize = filesize; intfc->pe_ftype = ftype; /* pe_path set by caller */ #ifdef WORDS_BIGENDIAN if (endian == DW_ENDIAN_LITTLE ) { intfc->pe_copy_word = _dwarf_memcpy_swap_bytes; intfc->pe_endian = DW_OBJECT_LSB; } else { intfc->pe_copy_word = _dwarf_memcpy_noswap_bytes; intfc->pe_endian = DW_OBJECT_MSB; } #else /* LITTLE ENDIAN */ if (endian == DW_ENDIAN_LITTLE ) { intfc->pe_copy_word = _dwarf_memcpy_noswap_bytes; intfc->pe_endian = DW_OBJECT_LSB; } else { intfc->pe_copy_word = _dwarf_memcpy_swap_bytes; intfc->pe_endian = DW_OBJECT_MSB; } #endif /* LITTLE- BIG-ENDIAN */ res = dwarf_load_pe_sections(intfc,errcode); if (res != DW_DLV_OK) { localdoas->object = intfc; localdoas->methods = 0; _dwarf_destruct_pe_access(localdoas); localdoas = 0; return res; } free(localdoas); localdoas = 0; return DW_DLV_OK; } static int _dwarf_pe_object_access_init( int fd, unsigned ftype, unsigned endian, unsigned offsetsize, size_t filesize, Dwarf_Unsigned access, Dwarf_Obj_Access_Interface **binary_interface, int *localerrnum) { int res = 0; dwarf_pe_object_access_internals_t *internals = 0; Dwarf_Obj_Access_Interface *intfc = 0; internals = malloc(sizeof(dwarf_pe_object_access_internals_t)); if (!internals) { *localerrnum = DW_DLE_ALLOC_FAIL; /* Impossible case, we hope. Give up. */ return DW_DLV_ERROR; } memset(internals,0,sizeof(*internals)); res = _dwarf_pe_object_access_internals_init(internals, fd, ftype, endian, offsetsize, filesize, access, localerrnum); if (res != DW_DLV_OK){ /* *err is already set. and the call freed internals */ return DW_DLV_ERROR; } intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); if (!intfc) { /* Impossible case, we hope. Give up. */ free(internals); *localerrnum = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; } /* Initialize the interface struct */ intfc->object = internals; intfc->methods = &pe_methods; *binary_interface = intfc; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_peread.h000066400000000000000000000126361361531463500205360ustar00rootroot00000000000000#ifndef PE_GENERIC_H #define PE_GENERIC_H /* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct dwarf_pe_generic_file_header { Dwarf_Unsigned Machine; Dwarf_Unsigned NumberOfSections; Dwarf_Unsigned TimeDateStamp; Dwarf_Unsigned PointerToSymbolTable; Dwarf_Unsigned NumberOfSymbols; Dwarf_Unsigned SizeOfOptionalHeader; /* in object file */ Dwarf_Unsigned Characteristics; }; struct dwarf_pe_generic_data_directory { Dwarf_Unsigned VirtualAddress; Dwarf_Unsigned Size; }; #define DWARF_PE_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 struct dwarf_pe_generic_optional_header { Dwarf_Unsigned Magic; unsigned char MajorLinkerVersion; unsigned char MinorLinkerVersion; Dwarf_Unsigned SizeOfCode; Dwarf_Unsigned SizeOfInitializedData; Dwarf_Unsigned SizeOfUninitializedData; Dwarf_Unsigned AddressOfEntryPoint; Dwarf_Unsigned BaseOfCode; Dwarf_Unsigned BaseOfData; Dwarf_Unsigned ImageBase; Dwarf_Unsigned SectionAlignment; Dwarf_Unsigned FileAlignment; Dwarf_Unsigned MajorOperatingSystemVersion; Dwarf_Unsigned MinorOperatingSystemVersion; Dwarf_Unsigned MajorImageVersion; Dwarf_Unsigned MinorImageVersion; Dwarf_Unsigned MajorSubsystemVersion; Dwarf_Unsigned MinorSubsystemVersion; Dwarf_Unsigned Win32VersionValue; Dwarf_Unsigned SizeOfImage; /* size in object file */ Dwarf_Unsigned SizeOfHeaders; /* size in object file */ Dwarf_Unsigned CheckSum; Dwarf_Unsigned Subsystem; Dwarf_Unsigned DllCharacteristics; Dwarf_Unsigned SizeOfStackReserve; Dwarf_Unsigned SizeOfStackCommit; Dwarf_Unsigned SizeOfHeapReserve; Dwarf_Unsigned SizeOfHeapCommit; Dwarf_Unsigned LoaderFlags; Dwarf_Unsigned NumberOfRvaAndSizes; Dwarf_Unsigned SizeOfDataDirEntry; /* size in object file */ struct dwarf_pe_generic_data_directory DataDirectory[DWARF_PE_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; }; struct dwarf_pe_generic_image_section_header { char *name; /* Name must be freed */ char *dwarfsectname; /* Name must be freed */ Dwarf_Unsigned SecHeaderOffset; /* offset in object file */ /* union { */ /* Dwarf_Unsigned PhysicalAddress; */ Dwarf_Unsigned VirtualSize; /* } Misc; */ Dwarf_Unsigned VirtualAddress; Dwarf_Unsigned SizeOfRawData; /* size we need */ Dwarf_Unsigned PointerToRawData; Dwarf_Unsigned PointerToRelocations; Dwarf_Unsigned PointerToLinenumbers; Dwarf_Unsigned NumberOfRelocations; Dwarf_Unsigned NumberOfLinenumbers; Dwarf_Unsigned Characteristics; Dwarf_Small * loaded_data; /* must be freed. */ }; #define DWARF_PE_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define DWARF_PE_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define DWARF_PE_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 /* ident[0] == 'P' means this is a PE header. ident[1] will be 1 indicating version 1. Other bytes in ident not defined, should be zero. */ typedef struct pe_filedata_s { char pe_ident[8]; const char * pe_path; /* must free.*/ int pe_fd; int pe_destruct_close_fd; /*aka: lib owns fd */ int pe_is_64bit; Dwarf_Unsigned pe_filesize; 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; Dwarf_Unsigned pe_optional_header_size; Dwarf_Unsigned pe_symbol_table_offset; Dwarf_Unsigned pe_string_table_offset; Dwarf_Unsigned pe_section_table_offset; Dwarf_Unsigned pe_signature; struct dwarf_pe_generic_file_header pe_FileHeader; struct dwarf_pe_generic_optional_header pe_OptionalHeader; Dwarf_Unsigned pe_section_count; struct dwarf_pe_generic_image_section_header *pe_sectionptr; Dwarf_Unsigned pe_string_table_size; char *pe_string_table; } dwarf_pe_object_access_internals_t; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PE_GENERIC_H */ dwarfutils-20200114/libdwarf/dwarf_print_lines.c000066400000000000000000000545131361531463500216170ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_line.h" #include "dwarfstring.h" #define PRINTING_DETAILS 1 static void print_line_header(Dwarf_Debug dbg, Dwarf_Bool is_single_tab, Dwarf_Bool is_actuals_tab) { if (!is_single_tab) { /* Ugly indenting follows, it makes lines shorter to see them better. */ if (is_actuals_tab) { dwarf_printf(dbg,"\nActuals Table\n"); dwarf_printf(dbg, " be\n" " ls\n" " ce\n" " section op kq\n" " offset code address/index row isa ??\n"); return; } else { dwarf_printf(dbg,"\nLogicals Table\n"); dwarf_printf(dbg, " s pe\n" " tirp\n" " msoi\n" " section op tall\n" " offset row code address/indx fil lne col disc cntx subp ????\n"); return; } } /* Single level table */ dwarf_printf(dbg, " s b e p e i d\n" " t l s r p s i\n" " m c e o i a s\n" " section op col t k q l l c\n" " offset code address file line umn ? ? ? ? ? \n"); } static void print_line_detail( Dwarf_Debug dbg, const char *prefix, int opcode, unsigned curr_line, struct Dwarf_Line_Registers_s * regs, Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table) { if(!is_single_table && is_actuals_table) { dwarf_printf(dbg, "%-15s %3d 0x%" DW_PR_XZEROS DW_PR_DUx "/%01u" " %5lu" /* lr_line, really logical row */ " %3d" /* isa */ " %1d" "%1d\n", prefix, (int) opcode, (Dwarf_Unsigned) regs->lr_address, (unsigned) regs->lr_op_index, (unsigned long) regs->lr_line, /*logical row */ regs->lr_isa, (int) regs->lr_basic_block, (int) regs->lr_end_sequence); return; } if(!is_single_table && !is_actuals_table) { dwarf_printf(dbg, "[%3d] " /* row number */ "%-15s %3d x%" DW_PR_XZEROS DW_PR_DUx "/%01u" " %2lu %4lu %1lu", curr_line, prefix, (int) opcode, (Dwarf_Unsigned) regs->lr_address, (unsigned) regs->lr_op_index, (unsigned long) regs->lr_file, (unsigned long) regs->lr_line, (unsigned long) regs->lr_column); if (regs->lr_discriminator || regs->lr_prologue_end || regs->lr_epilogue_begin || regs->lr_isa || regs->lr_is_stmt || regs->lr_call_context || regs->lr_subprogram) { dwarf_printf(dbg, " x%02" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */ dwarf_printf(dbg, " x%02" DW_PR_DUx , regs->lr_call_context); /* EXPERIMENTAL */ dwarf_printf(dbg, " x%02" DW_PR_DUx , regs->lr_subprogram); /* EXPERIMENTAL */ dwarf_printf(dbg, " %1d", (int) regs->lr_is_stmt); dwarf_printf(dbg, "%1d", (int) regs->lr_isa); dwarf_printf(dbg, "%1d", regs->lr_prologue_end); /* DWARF3 */ dwarf_printf(dbg, "%1d", regs->lr_epilogue_begin); /* DWARF3 */ } dwarf_printf(dbg, "\n"); return; } /* In the first quoted line below: 3d looks better than 2d, but best to do that as separate change and test from two-level-line-tables. */ dwarf_printf(dbg, "%-15s %2d 0x%" DW_PR_XZEROS DW_PR_DUx " " "%2lu %4lu %2lu %1d %1d %1d", prefix, (int) opcode, (Dwarf_Unsigned) regs->lr_address, (unsigned long) regs->lr_file, (unsigned long) regs->lr_line, (unsigned long) regs->lr_column, (int) regs->lr_is_stmt, (int) regs->lr_basic_block, (int) regs->lr_end_sequence); if (regs->lr_discriminator || regs->lr_prologue_end || regs->lr_epilogue_begin || regs->lr_isa) { dwarf_printf(dbg, " %1d", regs->lr_prologue_end); /* DWARF3 */ dwarf_printf(dbg, " %1d", regs->lr_epilogue_begin); /* DWARF3 */ dwarf_printf(dbg, " %1d", regs->lr_isa); /* DWARF3 */ dwarf_printf(dbg, " 0x%" DW_PR_DUx , regs->lr_discriminator); /* DWARF4 */ } dwarf_printf(dbg, "\n"); } #include "dwarf_line_table_reader_common.h" /* Not yet implemented, at least not usefully. FIXME */ void _dwarf_print_line_context_record(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Line_Context line_context) { return; } /* return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR If err_count_out is non-NULL, this is a special 'check' call. */ static int _dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error, int * err_count_out, int only_line_header) { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ Dwarf_Small *line_ptr = 0; Dwarf_Small *orig_line_ptr = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ Dwarf_Attribute stmt_list_attr = 0; /* Pointer to DW_AT_comp_dir attribute in die. */ Dwarf_Attribute comp_dir_attr = 0; /* Pointer to name of compilation directory. */ Dwarf_Small *comp_dir = NULL; /* Offset into .debug_line specified by a DW_AT_stmt_list attribute. */ Dwarf_Unsigned line_offset = 0; Dwarf_Signed i=0; Dwarf_Unsigned u=0; /* These variables are used to decode leb128 numbers. Leb128_num holds the decoded number, and leb128_length is its length in bytes. */ Dwarf_Half attrform = 0; /* In case there are wierd bytes 'after' the line table prologue this lets us print something. This is a gcc compiler bug and we expect the bytes count to be 12. */ Dwarf_Small* bogus_bytes_ptr = 0; Dwarf_Unsigned bogus_bytes_count = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned fission_offset = 0; /* The Dwarf_Debug this die belongs to. */ Dwarf_Debug dbg=0; Dwarf_CU_Context cu_context = 0; Dwarf_Line_Context line_context = 0; int resattr = DW_DLV_ERROR; int lres = DW_DLV_ERROR; int res = DW_DLV_ERROR; Dwarf_Small *line_ptr_actuals = 0; Dwarf_Small *line_ptr_end = 0; Dwarf_Small *section_start = 0; /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = cu_context->cc_dbg; res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_line.dss_size) { return (DW_DLV_NO_ENTRY); } address_size = _dwarf_get_address_size(dbg, die); resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { return resattr; } /* The list of relevant FORMs is small. DW_FORM_data4, DW_FORM_data8, DW_FORM_sec_offset */ lres = dwarf_whatform(stmt_list_attr,&attrform,error); if (lres != DW_DLV_OK) { return lres; } if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 && attrform != DW_FORM_sec_offset ) { _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return (DW_DLV_ERROR); } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return (DW_DLV_ERROR); } section_start = dbg->de_debug_line.dss_data; { Dwarf_Unsigned fission_size = 0; int resfis = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if(resfis != DW_DLV_OK) { return resfis; } } orig_line_ptr = section_start + line_offset + fission_offset; line_ptr = orig_line_ptr; dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); /* If die has DW_AT_comp_dir attribute, get the string that names the compilation directory. */ resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *cdir = 0; cres = dwarf_formstring(comp_dir_attr, &cdir, error); if (cres == DW_DLV_ERROR) { return cres; } else if (cres == DW_DLV_OK) { comp_dir = (Dwarf_Small *) cdir; } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); } line_context = (Dwarf_Line_Context) _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); if (line_context == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } { Dwarf_Small *newlinep = 0; int dres = _dwarf_read_line_table_header(dbg, cu_context, section_start, line_ptr, dbg->de_debug_line.dss_size, &newlinep, line_context, &bogus_bytes_ptr, &bogus_bytes_count, error, err_count_out); if (dres == DW_DLV_ERROR) { dwarf_srclines_dealloc_b(line_context); return dres; } if (dres == DW_DLV_NO_ENTRY) { dwarf_srclines_dealloc_b(line_context); return dres; } line_ptr_end = line_context->lc_line_ptr_end; line_ptr = newlinep; if (line_context->lc_actuals_table_offset > 0) { line_ptr_actuals = line_context->lc_line_prologue_start + line_context->lc_actuals_table_offset; } } line_context->lc_compilation_directory = comp_dir; if (only_line_header) { /* Just checking for header errors, nothing more here.*/ dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } dwarf_printf(dbg, "total line info length %ld bytes," " line offset 0x%" DW_PR_XZEROS DW_PR_DUx " %" DW_PR_DUu "\n", (long) line_context->lc_total_length, line_context->lc_section_offset, line_context->lc_section_offset); if (line_context->lc_version_number <= DW_LINE_VERSION5) { dwarf_printf(dbg, "line table version %d\n",(int) line_context->lc_version_number); } else { dwarf_printf(dbg, "line table version 0x%x\n",(int) line_context->lc_version_number); } dwarf_printf(dbg, "line table length field length %d prologue length %d\n", (int)line_context->lc_length_field_length, (int)line_context->lc_prologue_length); dwarf_printf(dbg, "compilation_directory %s\n", comp_dir ? ((char *) comp_dir) : ""); dwarf_printf(dbg, " min instruction length %d\n", (int) line_context->lc_minimum_instruction_length); if (line_context->lc_version_number == EXPERIMENTAL_LINE_TABLES_VERSION) { dwarf_printf(dbg, " actuals table offset " "0x%" DW_PR_XZEROS DW_PR_DUx " logicals table offset " "0x%" DW_PR_XZEROS DW_PR_DUx "\n", line_context->lc_actuals_table_offset, line_context->lc_logicals_table_offset); } if (line_context->lc_version_number == DW_LINE_VERSION5) { dwarf_printf(dbg, " segment selector size %d\n", (int) line_context->lc_segment_selector_size); dwarf_printf(dbg, " address size %d\n", (int) line_context->lc_address_size); } dwarf_printf(dbg, " default is stmt %d\n",(int)line_context->lc_default_is_stmt); dwarf_printf(dbg, " line base %d\n",(int)line_context->lc_line_base); dwarf_printf(dbg, " line_range %d\n",(int)line_context->lc_line_range); dwarf_printf(dbg, " opcode base %d\n",(int)line_context->lc_opcode_base); dwarf_printf(dbg, " standard opcode count %d\n",(int)line_context->lc_std_op_count); for (i = 1; i < line_context->lc_opcode_base; i++) { dwarf_printf(dbg, " opcode[%2d] length %d\n", (int) i, (int) line_context->lc_opcode_length_table[i - 1]); } dwarf_printf(dbg, " include directories count %d\n", (int) line_context->lc_include_directories_count); for (u = 0; u < line_context->lc_include_directories_count; ++u) { dwarf_printf(dbg, " include dir[%u] %s\n", (int) u, line_context->lc_include_directories[u]); } dwarf_printf(dbg, " files count %d\n", (int) line_context->lc_file_entry_count); if (line_context->lc_file_entry_count) { Dwarf_File_Entry fe = line_context->lc_file_entries; Dwarf_File_Entry fe2 = fe; unsigned fiu = 0; for (fiu = 0 ; fe2 ; fe2 = fe->fi_next,++fiu ) { Dwarf_Unsigned tlm2 = 0; Dwarf_Unsigned di = 0; Dwarf_Unsigned fl = 0; unsigned filenum = 0; fe = fe2; tlm2 = fe->fi_time_last_mod; di = fe->fi_dir_index; fl = fe->fi_file_length; filenum = fiu+1; /* Assuming DWARF2,3,4 */ if (line_context->lc_version_number == DW_LINE_VERSION5) { /* index starts 0 for DWARF5, show 0 base. */ filenum = fiu; } dwarf_printf(dbg, " file[%u] %s (file-number: %u) \n", (unsigned) fiu, (char *) fe->fi_file_name, (unsigned)(filenum)); dwarf_printf(dbg, " dir index %d\n", (int) di); { time_t tt = (time_t) tlm2; /* ctime supplies newline */ dwarf_printf(dbg, " last time 0x%x %s", (unsigned) tlm2, ctime(&tt)); } dwarf_printf(dbg, " file length %ld 0x%lx\n", (long) fl, (unsigned long) fl); if (fe->fi_md5_present) { char *c = (char *)&fe->fi_md5_value; char *end = c+sizeof(fe->fi_md5_value); dwarf_printf(dbg, " file md5 value 0x"); while(c < end) { dwarf_printf(dbg,"%02x",0xff&*c); ++c; } dwarf_printf(dbg,"\n"); } } } if (line_context->lc_version_number == EXPERIMENTAL_LINE_TABLES_VERSION) { /* Print the subprograms list. */ Dwarf_Unsigned count = line_context->lc_subprogs_count; Dwarf_Unsigned exu = 0; Dwarf_Subprog_Entry sub = line_context->lc_subprogs; dwarf_printf(dbg," subprograms count" " %" DW_PR_DUu "\n",count); if (count > 0) { dwarf_printf(dbg," indx file line name\n"); } for (exu = 0 ; exu < count ; exu++,sub++) { dwarf_printf(dbg," [%2" DW_PR_DUu "] %4" DW_PR_DUu " %4" DW_PR_DUu " %s\n", exu+1, sub->ds_decl_file, sub->ds_decl_line, sub->ds_subprog_name); } } { Dwarf_Unsigned offset = 0; if (bogus_bytes_count > 0) { Dwarf_Unsigned wcount = bogus_bytes_count; Dwarf_Unsigned boffset = bogus_bytes_ptr - section_start; dwarf_printf(dbg, "*** DWARF CHECK: the line table prologue header_length " " is %" DW_PR_DUu " too high, we pretend it is smaller." "Section offset: 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ") ***\n", wcount, boffset,boffset); *err_count_out += 1; } offset = line_ptr - section_start; dwarf_printf(dbg, " statement prog offset in section: 0x%" DW_PR_XZEROS DW_PR_DUx " (%" DW_PR_DUu ")\n", offset, offset); } { Dwarf_Bool doaddrs = false; Dwarf_Bool dolines = true; _dwarf_print_line_context_record(dbg,line_context); if (!line_ptr_actuals) { /* Normal single level line table. */ Dwarf_Bool is_single_table = true; Dwarf_Bool is_actuals_table = false; print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, is_single_table, is_actuals_table, error, err_count_out); if (res != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return res; } } else { Dwarf_Bool is_single_table = false; Dwarf_Bool is_actuals_table = false; if (line_context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) { dwarf_srclines_dealloc_b(line_context); _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return (DW_DLV_ERROR); } /* Read Logicals */ print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr, line_ptr_actuals, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, is_single_table, is_actuals_table, error,err_count_out); if (res != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return res; } if (line_context->lc_actuals_table_offset > 0) { is_actuals_table = true; /* Read Actuals */ print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr_actuals, line_ptr_end, orig_line_ptr, section_start, line_context, address_size, doaddrs, dolines, is_single_table, is_actuals_table, error, err_count_out); if (res != DW_DLV_OK) { dwarf_srclines_dealloc_b(line_context); return res; } } } } dwarf_srclines_dealloc_b(line_context); return DW_DLV_OK; } /* This is support for dwarfdump: making it possible for clients wanting line detail info on stdout to get that detail without including internal libdwarf header information. Caller passes in compilation unit DIE. The _dwarf_ version is obsolete (though supported for compatibility). The dwarf_ version is preferred. The functions are intentionally identical: having _dwarf_print_lines call dwarf_print_lines might better emphasize they are intentionally identical, but that seemed slightly silly given how short the functions are. Interface adds error_count (output value) February 2009. These *print_lines() functions print two-level tables in full even when the user is not asking for both (ie, when the caller asked for dwarf_srclines(). It was an accident, but after a short reflection this seems like a good idea for -vvv. */ int dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error,int *error_count) { int only_line_header = 0; int res = _dwarf_internal_printlines(die, error, error_count, only_line_header); return res; } int _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) { int only_line_header = 0; int err_count = 0; int res = _dwarf_internal_printlines(die, error, &err_count, only_line_header); /* No way to get error count back in this interface */ return res; } /* The check is in case we are not printing full line data, this gets some of the issues noted with .debug_line, but not all. Call dwarf_print_lines() to get all issues. Intended for apps like dwarfdump. */ void dwarf_check_lineheader(Dwarf_Die die, int *err_count_out) { Dwarf_Error err; int only_line_header = 1; _dwarf_internal_printlines(die, &err,err_count_out, only_line_header); return; } dwarfutils-20200114/libdwarf/dwarf_pubtypes.c000066400000000000000000000072561361531463500211460ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Reads DWARF3 .debug_pubtypes section. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_types.h" #include "dwarf_global.h" int dwarf_get_pubtypes(Dwarf_Debug dbg, Dwarf_Type ** types, Dwarf_Signed * ret_type_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_pubtypes,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_pubtypes.dss_size) { return (DW_DLV_NO_ENTRY); } return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_pubtypes.dss_data, dbg->de_debug_pubtypes.dss_size, (Dwarf_Global **) types, /* Type punning for sections with identical format. */ ret_type_count, error, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES, so use DW_DLA_GLOBAL. */ DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD, DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_pubtypes_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL, /* We don't have DW_DLA_PUBTYPES, so use DW_DLA_GLOBAL. */ DW_DLA_LIST); return; } int dwarf_pubtypename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; if (type == NULL) { _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (type->gl_name); return DW_DLV_OK; } int dwarf_pubtype_type_die_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_die_offset(type, ret_offset, error); } int dwarf_pubtype_cu_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_cu_offset(type, ret_offset, error); } int dwarf_pubtype_name_offsets(Dwarf_Type type_in, char **returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_name_offsets(type, returned_name, die_offset, cu_die_offset, error); } dwarfutils-20200114/libdwarf/dwarf_query.c000066400000000000000000001603661361531463500204420ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_die_deliv.h" #define TRUE 1 static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned * return_val, Dwarf_Error * error); static int _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned * rabase_out, Dwarf_Error * error); static int _dwarf_get_address_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned *abase_out, Dwarf_Error *error); 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); } *offset_size = dbg->de_length_size; return DW_DLV_OK; } #if 0 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 /* This is normally reliable. But not always. If different compilation units have different address sizes this may not give the correct value in all contexts. If the Elf offset size != address_size (for example if address_size = 4 but recorded in elf64 object) this may not give the correct value in all contexts. */ int dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half * ret_addr_size, Dwarf_Error * error) { Dwarf_Half address_size = 0; if (dbg == 0) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } address_size = dbg->de_pointer_size; *ret_addr_size = address_size; return DW_DLV_OK; } /* This will be correct in all contexts where the CU context of a DIE is known. */ int dwarf_get_die_address_size(Dwarf_Die die, Dwarf_Half * ret_addr_size, Dwarf_Error * error) { Dwarf_Half address_size = 0; CHECK_DIE(die, DW_DLV_ERROR); address_size = die->di_cu_context->cc_address_size; *ret_addr_size = address_size; return DW_DLV_OK; } int dwarf_dieoffset(Dwarf_Die die, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Small *dataptr = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dataptr = die->di_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; *ret_offset = (die->di_debug_ptr - dataptr); return DW_DLV_OK; } /* This function returns the offset of the die relative to the start of its compilation-unit rather than .debug_info. Returns DW_DLV_ERROR on error. */ int dwarf_die_CU_offset(Dwarf_Die die, Dwarf_Off * cu_off, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; Dwarf_Small *dataptr = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; dbg = die->di_cu_context->cc_dbg; dataptr = die->di_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; *cu_off = (die->di_debug_ptr - dataptr - cu_context->cc_debug_offset); return DW_DLV_OK; } /* A common function to get both offsets (local and global) It's unusual in that it sets both return offsets to zero on entry. Normally we only set any output-args (through their pointers) in case of success. */ int dwarf_die_offsets(Dwarf_Die die, Dwarf_Off *off, Dwarf_Off *cu_off, Dwarf_Error *error) { int res = 0; *off = 0; *cu_off = 0; res = dwarf_dieoffset(die,off,error); if (res == DW_DLV_OK) { res = dwarf_die_CU_offset(die,cu_off,error); } return res; } /* This function returns the global offset (meaning the section offset) and length of the CU that this die is a part of. Used for correctness checking by dwarfdump. */ int dwarf_die_CU_offset_range(Dwarf_Die die, Dwarf_Off * cu_off, Dwarf_Off * cu_length, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; CHECK_DIE(die, DW_DLV_ERROR); cu_context = die->di_cu_context; *cu_off = cu_context->cc_debug_offset; *cu_length = cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; return DW_DLV_OK; } int dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error) { CHECK_DIE(die, DW_DLV_ERROR); *tag = die->di_abbrev_list->abl_tag; return DW_DLV_OK; } /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Off **offbuf, Dwarf_Unsigned *offcnt, Dwarf_Error * error) { Dwarf_Die die = 0; Dwarf_Die child = 0; Dwarf_Die sib_die = 0; Dwarf_Die cur_die = 0; Dwarf_Unsigned off_count = 0; int res = 0; /* Temporary counter. */ Dwarf_Unsigned i = 0; /* Points to contiguous block of Dwarf_Off's to be returned. */ Dwarf_Off *ret_offsets = 0; Dwarf_Chain_2 curr_chain = 0; Dwarf_Chain_2 prev_chain = 0; Dwarf_Chain_2 head_chain = 0; *offbuf = NULL; *offcnt = 0; /* Get DIE for offset */ res = dwarf_offdie_b(dbg,offset,is_info,&die,error); if (DW_DLV_OK != res) { return res; } /* Get first child for die */ res = dwarf_child(die,&child,error); if (DW_DLV_ERROR == res || DW_DLV_NO_ENTRY == res) { return res; } cur_die = child; for (;;) { if (DW_DLV_OK == res) { int dres = 0; Dwarf_Off cur_off = 0; /* Get Global offset for current die */ dres = dwarf_dieoffset(cur_die,&cur_off,error); if (dres == DW_DLV_OK) { /* Normal. use cur_off. */ } else if (dres == DW_DLV_ERROR) { /* Should be impossible unless... */ /* avoid leak. */ /* Just leave cur_off as zero. */ /* dwarf_dealloc(dbg,*error,DW_DLA_ERROR); */ /* *error = NULL; */ return DW_DLV_ERROR; } else { /* DW_DLV_NO_ENTRY */ /* Impossible, dwarf_dieoffset never returns this */ } /* Record offset in current entry chain */ curr_chain = (Dwarf_Chain_2)_dwarf_get_alloc( dbg,DW_DLA_CHAIN_2,1); if (curr_chain == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Put current offset on singly_linked list. */ curr_chain->ch_item = cur_off; ++off_count; if (head_chain == NULL) { head_chain = prev_chain = curr_chain; } else { prev_chain->ch_next = curr_chain; prev_chain = curr_chain; } } /* Process any siblings entries if any */ sib_die = 0; res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,error); if (DW_DLV_ERROR == res) { return res; } if (DW_DLV_NO_ENTRY == res) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if (cur_die != die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); } cur_die = sib_die; } /* Points to contiguous block of Dwarf_Off's. */ ret_offsets = (Dwarf_Off *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, off_count); if (ret_offsets == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Store offsets in contiguous block, and deallocate the chain. */ curr_chain = head_chain; for (i = 0; i < off_count; i++) { *(ret_offsets + i) = curr_chain->ch_item; prev_chain = curr_chain; curr_chain = curr_chain->ch_next; dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN_2); } *offbuf = ret_offsets; *offcnt = off_count; return DW_DLV_OK; } /* If the input is improper (see DW_DLV_ERROR) this may leak memory. Such badly formed input should be very very rare. */ int dwarf_attrlist(Dwarf_Die die, Dwarf_Attribute ** attrbuf, Dwarf_Signed * attrcnt, Dwarf_Error * error) { Dwarf_Unsigned attr_count = 0; Dwarf_Unsigned i = 0; Dwarf_Half attr = 0; Dwarf_Half attr_form = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Abbrev_List abbrev_list = 0; Dwarf_Attribute new_attr = 0; Dwarf_Attribute head_attr = NULL; Dwarf_Attribute curr_attr = NULL; Dwarf_Attribute *attr_ptr = 0; Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Byte_Ptr die_info_end = 0; int lres = 0; Dwarf_CU_Context context = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; die_info_end = _dwarf_calculate_info_section_end_ptr(context); lres = _dwarf_get_abbrev_for_code(context, die->di_abbrev_list->abl_code, &abbrev_list,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { _dwarf_error(dbg, error, DW_DLE_ABBREV_MISSING); return DW_DLV_ERROR; } abbrev_ptr = abbrev_list->abl_abbrev_ptr; abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context); info_ptr = die->di_debug_ptr; SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); if (info_ptr >= die_info_end) { /* Stepped off the end SKIPping the leb */ _dwarf_error(dbg, error, DW_DLE_DIE_BAD); return DW_DLV_ERROR; } do { Dwarf_Unsigned utmp2; Dwarf_Signed implicit_const = 0; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end); if (utmp2 > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } attr = (Dwarf_Half) utmp2; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end); if (!_dwarf_valid_form_we_know(utmp2,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return (DW_DLV_ERROR); } attr_form = (Dwarf_Half) utmp2; if (attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, dbg,error,abbrev_end); } if (!_dwarf_valid_form_we_know(attr_form,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; } if (attr != 0) { new_attr = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (new_attr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form_direct = attr_form; new_attr->ar_attribute_form = attr_form; if (attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; if (_dwarf_reference_outside_section(die, (Dwarf_Small*) info_ptr, ((Dwarf_Small*) info_ptr )+1)) { _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); return DW_DLV_ERROR; } /* DECODE_LEB128_UWORD does info_ptr update */ DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end); attr_form = (Dwarf_Half) utmp6; new_attr->ar_attribute_form = attr_form; } /* Here the final address must be *inside* the section, as we will read from there, and read at least one byte, we think. We do not want info_ptr to point past end so we add 1 to the end-pointer. */ if ( attr_form != DW_FORM_implicit_const && _dwarf_reference_outside_section(die, (Dwarf_Small*) info_ptr, ((Dwarf_Small*) info_ptr )+1)) { _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); return DW_DLV_ERROR; } new_attr->ar_cu_context = die->di_cu_context; new_attr->ar_debug_ptr = info_ptr; new_attr->ar_die = die; if (attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. Do not increment info_ptr */ new_attr->ar_implicit_const = implicit_const; } else { Dwarf_Unsigned sov = 0; int res = 0; res = _dwarf_get_size_of_val(dbg, attr_form, die->di_cu_context->cc_version_stamp, die->di_cu_context->cc_address_size, info_ptr, die->di_cu_context->cc_length_size, &sov, die_info_end, error); if(res!= DW_DLV_OK) { return res; } info_ptr += sov; } if (head_attr == NULL) head_attr = curr_attr = new_attr; else { curr_attr->ar_next = new_attr; curr_attr = new_attr; } attr_count++; } } while (attr != 0 || attr_form != 0); if (attr_count == 0) { *attrbuf = NULL; *attrcnt = 0; return (DW_DLV_NO_ENTRY); } attr_ptr = (Dwarf_Attribute *) _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count); if (attr_ptr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } curr_attr = head_attr; for (i = 0; i < attr_count; i++) { *(attr_ptr + i) = curr_attr; curr_attr = curr_attr->ar_next; } *attrbuf = attr_ptr; *attrcnt = attr_count; return (DW_DLV_OK); } /* This function takes a die, and an attr, and returns a pointer to the start of the value of that attr in the given die in the .debug_info section. The form is returned in *attr_form. If the attr_form is DW_FORM_implicit_const (known signed, so most callers) that is fine, but in that case we do not need to actually set the *ptr_to_value. Returns NULL on error, or if attr is not found. However, *attr_form is 0 on error, and positive otherwise. */ static int _dwarf_get_value_ptr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Half * attr_form, Dwarf_Byte_Ptr * ptr_to_value, Dwarf_Signed *implicit_const_out, Dwarf_Error *error) { Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Abbrev_List abbrev_list; Dwarf_Half curr_attr = 0; Dwarf_Half curr_attr_form = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_CU_Context context = die->di_cu_context; Dwarf_Byte_Ptr die_info_end = 0; Dwarf_Debug dbg = 0; int lres = 0; if (!context) { _dwarf_error(NULL,error,DW_DLE_DIE_NO_CU_CONTEXT); return DW_DLV_ERROR; } dbg = context->cc_dbg; die_info_end = _dwarf_calculate_info_section_end_ptr(context); lres = _dwarf_get_abbrev_for_code(context, die->di_abbrev_list->abl_code, &abbrev_list,error); if (lres == DW_DLV_ERROR) { return lres; } if (lres == DW_DLV_NO_ENTRY) { _dwarf_error(dbg,error,DW_DLE_CU_DIE_NO_ABBREV_LIST); return DW_DLV_ERROR; } abbrev_ptr = abbrev_list->abl_abbrev_ptr; abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context); info_ptr = die->di_debug_ptr; /* This ensures and checks die_info_end >= info_ptr */ SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); do { Dwarf_Unsigned formtmp3 = 0; Dwarf_Unsigned atmp3 = 0; Dwarf_Unsigned value_size=0; Dwarf_Signed implicit_const = 0; int res = 0; DECODE_LEB128_UWORD_CK(abbrev_ptr, atmp3,dbg,error,abbrev_end); if (atmp3 > DW_AT_hi_user) { _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); return DW_DLV_ERROR; } curr_attr = (Dwarf_Half) atmp3; DECODE_LEB128_UWORD_CK(abbrev_ptr,formtmp3, dbg,error,abbrev_end); if (!_dwarf_valid_form_we_know(formtmp3,curr_attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return (DW_DLV_ERROR); } curr_attr_form = (Dwarf_Half) formtmp3; if (curr_attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; /* DECODE_LEB128_UWORD updates info_ptr */ DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end); curr_attr_form = (Dwarf_Half) utmp6; } if (curr_attr_form == DW_FORM_implicit_const) { /* The value is here, not in a DIE. */ DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, dbg,error,abbrev_end); } if (curr_attr == attr) { *attr_form = curr_attr_form; if(implicit_const_out) { *implicit_const_out = implicit_const; } *ptr_to_value = info_ptr; return DW_DLV_OK; } res = _dwarf_get_size_of_val(dbg, curr_attr_form, die->di_cu_context->cc_version_stamp, die->di_cu_context->cc_address_size, info_ptr, die->di_cu_context->cc_length_size, &value_size, die_info_end, error); if (res != DW_DLV_OK) { return res; } { /* ptrdiff_t is signed type, so use DW signed type */ Dwarf_Signed len = die_info_end - info_ptr; if (len < 0 || (value_size > ((Dwarf_Unsigned)len))) { /* Something badly wrong. We point past end of debug_info or debug_types or a section is unreasonably sized or we are pointing to two different sections? */ _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD); return DW_DLV_ERROR; } } info_ptr+= value_size; } while (curr_attr != 0 || curr_attr_form != 0); return DW_DLV_NO_ENTRY; } int dwarf_die_text(Dwarf_Die die, Dwarf_Half attrnum, char **ret_name, Dwarf_Error * error) { Dwarf_Debug dbg = 0; int res = DW_DLV_ERROR; Dwarf_Attribute attr = 0; Dwarf_Error lerr = 0; CHECK_DIE(die, DW_DLV_ERROR); res = dwarf_attr(die,attrnum,&attr,&lerr); dbg = die->di_cu_context->cc_dbg; if (res == DW_DLV_ERROR) { return DW_DLV_NO_ENTRY; } if (res == DW_DLV_NO_ENTRY) { return res; } res = dwarf_formstring(attr,ret_name,error); dwarf_dealloc(dbg,attr, DW_DLA_ATTR); attr = 0; return res; } int dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error) { return dwarf_die_text(die,DW_AT_name,ret_name,error); } int dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool * return_bool, Dwarf_Error * error) { Dwarf_Half attr_form = 0; Dwarf_Byte_Ptr info_ptr = 0; int res = 0; Dwarf_Signed implicit_const; CHECK_DIE(die, DW_DLV_ERROR); res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr, &implicit_const,error); if(res == DW_DLV_ERROR) { return res; } if(res == DW_DLV_NO_ENTRY) { *return_bool = false; return DW_DLV_OK; } *return_bool = (true); return DW_DLV_OK; } int dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute * ret_attr, Dwarf_Error * error) { Dwarf_Half attr_form = 0; Dwarf_Attribute attrib = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Signed implicit_const = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr, &implicit_const,error); if(res == DW_DLV_ERROR) { return res; } if(res == DW_DLV_NO_ENTRY) { return res; } attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (attrib == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } attrib->ar_attribute = attr; attrib->ar_attribute_form = attr_form; attrib->ar_attribute_form_direct = attr_form; attrib->ar_cu_context = die->di_cu_context; /* Only nonzero if DW_FORM_implicit_const */ attrib->ar_implicit_const = implicit_const; /* Only nonnull if not DW_FORM_implicit_const */ attrib->ar_debug_ptr = info_ptr; attrib->ar_die = die; *ret_attr = (attrib); return DW_DLV_OK; } /* A DWP (.dwp) package object never contains .debug_addr, only a normal .o or executable object. Error returned here is on dbg, not tieddbg. */ int _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index_to_addr, Dwarf_Addr *addr_out, Dwarf_Error *error) { Dwarf_Unsigned address_base = 0; Dwarf_Unsigned addrindex = index_to_addr; Dwarf_Unsigned addr_offset = 0; Dwarf_Unsigned ret_addr = 0; int res = 0; Dwarf_Byte_Ptr sectionstart = 0; Dwarf_Byte_Ptr sectionend = 0; Dwarf_Unsigned sectionsize = 0; res = _dwarf_get_address_base_attr_value(dbg,context, &address_base, error); if (res != DW_DLV_OK) { return res; } res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error); if (res != DW_DLV_OK) { /* Ignore the inner error, report something meaningful */ if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,*error, DW_DLA_ERROR); *error = 0; } _dwarf_error(dbg,error, DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION); return DW_DLV_ERROR; } /* DW_FORM_addrx has a base value from the CU die: DW_AT_addr_base. DW_OP_addrx and DW_OP_constx rely on DW_AT_addr_base too. */ /* DW_FORM_GNU_addr_index relies on DW_AT_GNU_addr_base which is in the CU die. */ sectionstart = dbg->de_debug_addr.dss_data; addr_offset = address_base + (addrindex * context->cc_address_size); /* The offsets table is a series of address-size entries but with a base. */ sectionsize = dbg->de_debug_addr.dss_size; sectionend = sectionstart + sectionsize; if (addr_offset > (sectionsize - context->cc_address_size)) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg,ret_addr,Dwarf_Addr, sectionstart + addr_offset, context->cc_address_size, error,sectionend); *addr_out = ret_addr; return DW_DLV_OK; } static int _dwarf_look_in_local_and_tied_by_index( Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index, Dwarf_Addr *return_addr, Dwarf_Error *error) { int res2 = 0; res2 = _dwarf_extract_address_from_debug_addr(dbg, context, index, return_addr, error); if (res2 != DW_DLV_OK) { if (res2 == DW_DLV_ERROR && error && dwarf_errno(*error) == DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION && dbg->de_tied_data.td_tied_object) { int res3 = 0; /* We do not want to leak error structs... */ dwarf_dealloc(dbg,*error,DW_DLA_ERROR); *error = 0; /* error is returned on dbg, not tieddbg. */ res3 = _dwarf_get_addr_from_tied(dbg, context,index,return_addr,error); if ( res3 == DW_DLV_ERROR) { return res3; } else if ( res3 == DW_DLV_NO_ENTRY) { return res3; } } else { return res2; } } return (DW_DLV_OK); } /* The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr */ int dwarf_debug_addr_index_to_addr(Dwarf_Die die, Dwarf_Unsigned index, Dwarf_Addr *return_addr, Dwarf_Error *error) { Dwarf_Debug dbg = 0; Dwarf_CU_Context context = 0; int res = 0; CHECK_DIE(die, DW_DLV_ERROR); context = die->di_cu_context; dbg = context->cc_dbg; /* error is returned on dbg, not tieddbg. */ res = _dwarf_look_in_local_and_tied_by_index(dbg, context, index, return_addr, error); return res; } /* ASSERT: attr_form == DW_FORM_GNU_addr_index || attr_form == DW_FORM_addrx */ int _dwarf_look_in_local_and_tied(Dwarf_Half attr_form, Dwarf_CU_Context context, Dwarf_Small *info_ptr, Dwarf_Addr *return_addr, Dwarf_Error *error) { int res2 = 0; Dwarf_Unsigned index_to_addr = 0; Dwarf_Debug dbg = 0; /* We get the index. It might apply here or in tied object. Checking that next. */ dbg = context->cc_dbg; res2 = _dwarf_get_addr_index_itself(attr_form, info_ptr,dbg,context, &index_to_addr,error); if(res2 != DW_DLV_OK) { return res2; } /* error is returned on dbg, not tieddbg. */ res2 = _dwarf_look_in_local_and_tied_by_index( dbg,context,index_to_addr,return_addr,error); return res2; } int dwarf_lowpc(Dwarf_Die die, Dwarf_Addr * return_addr, Dwarf_Error * error) { Dwarf_Addr ret_addr = 0; Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Half attr_form = 0; Dwarf_Debug dbg = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; int version = 0; enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN; int res = 0; Dwarf_CU_Context context = die->di_cu_context; Dwarf_Small *die_info_end = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = context->cc_dbg; address_size = context->cc_address_size; offset_size = context->cc_length_size; res = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form,&info_ptr,0,error); if(res == DW_DLV_ERROR) { return res; } if(res == DW_DLV_NO_ENTRY) { return res; } version = context->cc_version_stamp; class = dwarf_get_form_class(version,DW_AT_low_pc, offset_size,attr_form); if (class != DW_FORM_CLASS_ADDRESS) { /* Not the correct form for DW_AT_low_pc */ _dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS); return (DW_DLV_ERROR); } if(attr_form == DW_FORM_GNU_addr_index || attr_form == DW_FORM_addrx) { /* error is returned on dbg, not tieddbg. */ res = _dwarf_look_in_local_and_tied( attr_form, context, info_ptr, return_addr, error); return res; } die_info_end = _dwarf_calculate_info_section_end_ptr(context); READ_UNALIGNED_CK(dbg, ret_addr, Dwarf_Addr, info_ptr, address_size, error,die_info_end); *return_addr = ret_addr; return (DW_DLV_OK); } /* This works for DWARF2 and DWARF3 but fails for DWARF4 DW_AT_high_pc attributes of class constant. It is best to cease using this interface. */ int dwarf_highpc(Dwarf_Die die, Dwarf_Addr * return_addr, Dwarf_Error * error) { int res = 0; enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN; Dwarf_Half form = 0; CHECK_DIE(die, DW_DLV_ERROR); res = dwarf_highpc_b(die,return_addr,&form,&class,error); if (res != DW_DLV_OK) { return res; } if (form != DW_FORM_addr) { /* Not the correct form for DWARF2/3 DW_AT_high_pc */ Dwarf_Debug dbg = die->di_cu_context->cc_dbg; _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM); return (DW_DLV_ERROR); } return (DW_DLV_OK); } /* If the giving 'die' contains the DW_AT_type attribute, it returns the offset referenced by the attribute. In case of DW_DLV_NO_ENTRY or DW_DLV_ERROR it sets offset zero. */ int dwarf_dietype_offset(Dwarf_Die die, Dwarf_Off *return_off, Dwarf_Error *error) { int res = 0; Dwarf_Off offset = 0; Dwarf_Attribute attr = 0; CHECK_DIE(die, DW_DLV_ERROR); res = dwarf_attr(die,DW_AT_type,&attr,error); if (res == DW_DLV_OK) { res = dwarf_global_formref(attr,&offset,error); dwarf_dealloc(die->di_cu_context->cc_dbg,attr,DW_DLA_ATTR); } *return_off = offset; return res; } int _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned *sbase_out, Dwarf_Error *error) { int res = 0; Dwarf_Die cudie = 0; Dwarf_Unsigned cu_die_offset = 0; Dwarf_Attribute myattr = 0; if(context->cc_str_offsets_base_present) { *sbase_out = context->cc_str_offsets_base; return DW_DLV_OK; } cu_die_offset = context->cc_cu_die_global_sec_offset; context->cc_cu_die_offset_present = TRUE; res = dwarf_offdie_b(dbg,cu_die_offset, context->cc_is_info, &cudie, error); if(res != DW_DLV_OK) { return res; } res = dwarf_attr(cudie,DW_AT_str_offsets_base, &myattr,error); if(res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } if (res == DW_DLV_OK) { Dwarf_Unsigned val = 0; /* Expect DW_FORM_sec_offset */ if (myattr->ar_attribute_form != DW_FORM_sec_offset) { dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); _dwarf_error(dbg, error,DW_DLE_STR_OFFSETS_BASE_WRONG_FORM); return (DW_DLV_ERROR); } res = dwarf_global_formref(myattr,&val,error); dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); if(res != DW_DLV_OK) { return res; } *sbase_out = val; context->cc_str_offsets_base = val; context->cc_str_offsets_base_present = TRUE; return DW_DLV_OK; } /* NO ENTRY, No other attr.Not even GNU, this one is standard DWARF5 only. */ dwarf_dealloc(dbg,cudie,DW_DLA_DIE); /* We do not need a base for a .dwo. We might for .dwp and would or .o or executable. FIXME: assume we do not need this. Should we really return DW_DLV_NO_ENTRY? */ *sbase_out = 0; return DW_DLV_OK; } /* Goes to the CU die and finds the DW_AT_GNU_addr_base (or DW_AT_addr_base ) and gets the value from that CU die and returns it through abase_out. If we cannot find the value it is a serious error in the DWARF. */ static int _dwarf_get_address_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned *abase_out, Dwarf_Error *error) { int res = 0; Dwarf_Die cudie = 0; Dwarf_Bool cu_die_offset_present = 0; Dwarf_Unsigned cu_die_offset = 0; Dwarf_Attribute myattr = 0; if(context->cc_addr_base_present) { *abase_out = context->cc_addr_base; return DW_DLV_OK; } cu_die_offset = context->cc_cu_die_global_sec_offset; cu_die_offset_present = context->cc_cu_die_offset_present; if(!cu_die_offset_present) { _dwarf_error(dbg, error, DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM); return (DW_DLV_ERROR); } res = dwarf_offdie_b(dbg,cu_die_offset, context->cc_is_info, &cudie, error); if(res != DW_DLV_OK) { return res; } res = dwarf_attr(cudie,DW_AT_addr_base, &myattr,error); if(res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } if (res == DW_DLV_OK) { Dwarf_Unsigned val = 0; res = dwarf_formudata(myattr,&val,error); dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); if(res != DW_DLV_OK) { return res; } *abase_out = val; return DW_DLV_OK; } /* NO ENTRY, try the other attr. */ res = dwarf_attr(cudie,DW_AT_GNU_addr_base, &myattr,error); if(res == DW_DLV_NO_ENTRY) { res = dwarf_attr(cudie,DW_AT_addr_base, &myattr,error); if (res == DW_DLV_NO_ENTRY) { /* A .o or .dwp needs a base, but a .dwo does not. FIXME: check this claim... Assume zero is ok and works. */ *abase_out = 0; dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return DW_DLV_OK; } if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } } else if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } { Dwarf_Unsigned val = 0; res = dwarf_formudata(myattr,&val,error); dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); if(res != DW_DLV_OK) { return res; } *abase_out = val; } return DW_DLV_OK; } /* The dbg here will be the tieddbg, and context will be a tied context. */ static int _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned * rangesbase_out, Dwarf_Error * error) { int res = 0; Dwarf_Die cudie = 0; Dwarf_Bool cu_die_offset_present = 0; Dwarf_Unsigned cu_die_offset = 0; Dwarf_Attribute myattr = 0; if(context->cc_ranges_base_present) { *rangesbase_out = context->cc_ranges_base; return DW_DLV_OK; } cu_die_offset = context->cc_cu_die_global_sec_offset; cu_die_offset_present = context->cc_cu_die_offset_present; if(!cu_die_offset_present) { _dwarf_error(dbg, error, DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM); return (DW_DLV_ERROR); } res = dwarf_offdie_b(dbg,cu_die_offset, context->cc_is_info, &cudie, error); if(res != DW_DLV_OK) { return res; } res = dwarf_attr(cudie,DW_AT_rnglists_base, &myattr,error); if(res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } if (res == DW_DLV_OK) { Dwarf_Unsigned val = 0; res = dwarf_formudata(myattr,&val,error); dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); if(res != DW_DLV_OK) { return res; } *rangesbase_out = val; return DW_DLV_OK; } /* NO ENTRY, try the other attr. */ res = dwarf_attr(cudie,DW_AT_GNU_ranges_base, &myattr,error); if(res == DW_DLV_NO_ENTRY) { res = dwarf_attr(cudie,DW_AT_rnglists_base, &myattr,error); if (res == DW_DLV_NO_ENTRY) { /* A .o or execeutable skeleton needs a base , but a .dwo does not. Assume zero is ok and works. */ *rangesbase_out = 0; dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return DW_DLV_OK; } if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } } else if (res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); return res; } { Dwarf_Unsigned val = 0; res = dwarf_formudata(myattr,&val,error); dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); if(res != DW_DLV_OK) { return res; } *rangesbase_out = val; } return DW_DLV_OK; } /* This works for all versions of DWARF. This is the preferred interface, cease using dwarf_highpc. The consumer has to check the return_form or return_class to decide if the value returned through return_value is an address or an address-offset. See DWARF4 section 2.17.2, "Contiguous Address Range". */ int dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr * return_value, Dwarf_Half * return_form, enum Dwarf_Form_Class * return_class, Dwarf_Error * error) { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Half attr_form = 0; Dwarf_Debug dbg = 0; Dwarf_Half address_size = 0; Dwarf_Half offset_size = 0; enum Dwarf_Form_Class class = DW_FORM_CLASS_UNKNOWN; Dwarf_Half version = 0; Dwarf_Byte_Ptr die_info_end = 0; int res = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; address_size = die->di_cu_context->cc_address_size; res = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form,&info_ptr,0,error); if(res == DW_DLV_ERROR) { return res; } if(res == DW_DLV_NO_ENTRY) { return res; } die_info_end = _dwarf_calculate_info_section_end_ptr( die->di_cu_context); version = die->di_cu_context->cc_version_stamp; offset_size = die->di_cu_context->cc_length_size; class = dwarf_get_form_class(version,DW_AT_high_pc, offset_size,attr_form); if (class == DW_FORM_CLASS_ADDRESS) { Dwarf_Addr addr = 0; if (attr_form == DW_FORM_GNU_addr_index || attr_form == DW_FORM_addrx) { Dwarf_Unsigned addr_out = 0; Dwarf_Unsigned index_to_addr = 0; int res2 = 0; Dwarf_CU_Context context = die->di_cu_context; /* index_to_addr we get here might apply to this dbg or to tieddbg. */ /* error is returned on dbg, not tied */ res2 = _dwarf_get_addr_index_itself(attr_form, info_ptr,dbg,context,&index_to_addr,error); if(res2 != DW_DLV_OK) { return res2; } res2 = _dwarf_extract_address_from_debug_addr(dbg, context, index_to_addr, &addr_out, error); if(res2 != DW_DLV_OK) { if (res2 == DW_DLV_ERROR && error && dwarf_errno(*error) == DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION && dbg->de_tied_data.td_tied_object) { /* .debug_addr is in tied dbg. */ int res3 = 0; /* Do not leak the above error pointer, we have something else to try here. */ dwarf_dealloc(dbg,*error, DW_DLA_ERROR); *error = 0; /* .debug_addr is in tied dbg. Get the index of the addr */ res3 = _dwarf_get_addr_from_tied(dbg, context,index_to_addr,&addr_out,error); if ( res3 != DW_DLV_OK) { return res3; } } else { return res2; } } *return_value = addr_out; /* Allow null args starting 22 April 2019. */ if (return_form) { *return_form = attr_form; } if (return_class) { *return_class = class; } return (DW_DLV_OK); } READ_UNALIGNED_CK(dbg, addr, Dwarf_Addr, info_ptr, address_size, error,die_info_end); *return_value = addr; } else { int res3 = 0; Dwarf_Unsigned v = 0; res3 = _dwarf_die_attr_unsigned_constant(die,DW_AT_high_pc, &v,error); if(res3 != DW_DLV_OK) { Dwarf_Byte_Ptr info_ptr2 = 0; res3 = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form,&info_ptr2,0,error); if(res3 == DW_DLV_ERROR) { return res3; } if(res3 == DW_DLV_NO_ENTRY) { return res3; } if (attr_form == DW_FORM_sdata) { Dwarf_Signed sval = 0; /* DWARF4 defines the value as an unsigned offset in section 2.17.2. */ DECODE_LEB128_UWORD_CK(info_ptr2, sval, dbg,error,die_info_end); *return_value = (Dwarf_Unsigned)sval; } else { _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM); return DW_DLV_ERROR; } } else { *return_value = v; } } /* Allow null args starting 22 April 2019. */ if (return_form) { *return_form = attr_form; } if (return_class) { *return_class = class; } return DW_DLV_OK; } /* The dbg and context here are a file with DW_FORM_addrx but missing .debug_addr. So go to the tied file and using the signature from the current context locate the target CU in the tied file Then get the address. */ int _dwarf_get_addr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned index, Dwarf_Addr *addr_out, Dwarf_Error*error) { Dwarf_Debug tieddbg = 0; int res = 0; Dwarf_Addr local_addr = 0; Dwarf_CU_Context tiedcontext = 0; if (!context->cc_signature_present) { _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP); return DW_DLV_ERROR; } tieddbg = dbg->de_tied_data.td_tied_object; if (!tieddbg) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE); return DW_DLV_ERROR; } if (!context->cc_signature_present) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE); return DW_DLV_ERROR; } res = _dwarf_search_for_signature(tieddbg, context->cc_signature, &tiedcontext, error); if ( res == DW_DLV_ERROR) { /* Associate the error with dbg, not tieddbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } else if ( res == DW_DLV_NO_ENTRY) { return res; } res = _dwarf_extract_address_from_debug_addr(tieddbg, tiedcontext, index, &local_addr, error); if ( res == DW_DLV_ERROR) { /* Associate the error with dbg, not tidedbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } else if ( res == DW_DLV_NO_ENTRY) { return res; } *addr_out = local_addr; return DW_DLV_OK; } int _dwarf_get_ranges_base_attr_from_tied(Dwarf_Debug dbg, Dwarf_CU_Context context, Dwarf_Unsigned * ranges_base_out, Dwarf_Unsigned * addr_base_out, Dwarf_Error*error) { Dwarf_Debug tieddbg = 0; int res = 0; Dwarf_Unsigned tiedbase= 0; Dwarf_CU_Context tiedcontext = 0; if (!context->cc_signature_present) { _dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP); return DW_DLV_ERROR; } tieddbg = dbg->de_tied_data.td_tied_object; if (!tieddbg) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE); return DW_DLV_ERROR; } if (!context->cc_signature_present) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_SIG_AVAILABLE); return DW_DLV_ERROR; } res = _dwarf_search_for_signature(tieddbg, context->cc_signature, &tiedcontext, error); if ( res == DW_DLV_ERROR) { /* Associate the error with dbg, not tidedbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } else if ( res != DW_DLV_NO_ENTRY) { return res; } res = _dwarf_get_ranges_base_attr_value(tieddbg, tiedcontext, &tiedbase, error); if (res != DW_DLV_OK) { /* Associate the error with dbg, not tidedbg */ _dwarf_error_mv_s_to_t(tieddbg,error,dbg,error); return res; } *ranges_base_out = tiedbase; *addr_base_out = tiedcontext->cc_addr_base; return DW_DLV_OK; } /* Takes a die, an attribute attr, and checks if attr occurs in die. Attr is required to be an attribute whose form is in the "constant" class. If attr occurs in die, the value is returned. Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as appropriate. Sets the value thru the pointer return_val. This function is meant to do all the processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, and dwarf_srclang. And it helps in dwarf_highpc_with_form(). */ static int _dwarf_die_attr_unsigned_constant(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned * return_val, Dwarf_Error * error) { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Half attr_form = 0; Dwarf_Unsigned ret_value = 0; Dwarf_Debug dbg = 0; int res = 0; Dwarf_Byte_Ptr die_info_end = 0; CHECK_DIE(die, DW_DLV_ERROR); die_info_end = _dwarf_calculate_info_section_end_ptr(die->di_cu_context); dbg = die->di_cu_context->cc_dbg; res = _dwarf_get_value_ptr(die,attr,&attr_form, &info_ptr,0,error); if(res != DW_DLV_OK) { return res; } switch (attr_form) { case DW_FORM_data1: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, sizeof(Dwarf_Small), error,die_info_end); *return_val = ret_value; return (DW_DLV_OK); case DW_FORM_data2: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, sizeof(Dwarf_Shalf), error,die_info_end); *return_val = ret_value; return (DW_DLV_OK); case DW_FORM_data4: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, DWARF_32BIT_SIZE, error,die_info_end); *return_val = ret_value; return (DW_DLV_OK); case DW_FORM_data8: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, info_ptr, DWARF_64BIT_SIZE, error,die_info_end); *return_val = ret_value; return (DW_DLV_OK); case DW_FORM_udata: { Dwarf_Unsigned v = 0; DECODE_LEB128_UWORD_CK(info_ptr, v,dbg,error,die_info_end); *return_val = v; return DW_DLV_OK; } default: _dwarf_error(dbg, error, DW_DLE_DIE_BAD); return (DW_DLV_ERROR); } } int dwarf_bytesize(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns, error); *ret_size = luns; return res; } int dwarf_bitsize(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns, error); *ret_size = luns; return res; } int dwarf_bitoffset(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns, error); *ret_size = luns; return res; } /* Refer section 3.1, page 21 in Dwarf Definition. */ int dwarf_srclang(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns, error); *ret_size = luns; return res; } /* Refer section 5.4, page 37 in Dwarf Definition. */ int dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned * ret_size, Dwarf_Error * error) { Dwarf_Unsigned luns = 0; int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns, error); *ret_size = luns; return res; } /* Return DW_DLV_OK if ok DW_DLV_ERROR if failure. If the die and the attr are not related the result is meaningless. */ int dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset /* return offset thru this ptr */, Dwarf_Error * error) { Dwarf_Off attroff = 0; Dwarf_Small *dataptr = 0; Dwarf_Debug dbg = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; dataptr = die->di_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; attroff = (attr->ar_debug_ptr - dataptr); *offset = attroff; return DW_DLV_OK; } int dwarf_die_abbrev_code(Dwarf_Die die) { return die->di_abbrev_code; } /* Returns a flag through ablhas_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half *ab_has_child) { if (die->di_abbrev_list) { *ab_has_child = die->di_abbrev_list->abl_has_child; return DW_DLV_OK; } return DW_DLV_ERROR; } /* Helper function for finding form class. */ static enum Dwarf_Form_Class dw_get_special_offset(Dwarf_Half attrnum, Dwarf_Half dwversion) { switch (attrnum) { case DW_AT_stmt_list: return DW_FORM_CLASS_LINEPTR; case DW_AT_macro_info: /* DWARF2-DWARF4 */ return DW_FORM_CLASS_MACPTR; case DW_AT_start_scope: case DW_AT_ranges: { if (dwversion <= 4) { return DW_FORM_CLASS_RANGELISTPTR; } return DW_FORM_CLASS_RNGLIST; } case DW_AT_rnglists_base: /* DWARF5 */ return DW_FORM_CLASS_RNGLISTSPTR; case DW_AT_macros: /* DWARF5 */ return DW_FORM_CLASS_MACROPTR; case DW_AT_loclists_base: /* DWARF5 */ return DW_FORM_CLASS_LOCLISTSPTR; case DW_AT_addr_base: /* DWARF5 */ return DW_FORM_CLASS_ADDRPTR; case DW_AT_str_offsets_base: /* DWARF5 */ return DW_FORM_CLASS_STROFFSETSPTR; case DW_AT_location: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_segment: case DW_AT_static_link: case DW_AT_use_location: case DW_AT_vtable_elem_location: { if (dwversion <= 4) { return DW_FORM_CLASS_LOCLISTPTR; } return DW_FORM_CLASS_LOCLIST; } case DW_AT_sibling: case DW_AT_byte_size : case DW_AT_bit_offset : case DW_AT_bit_size : case DW_AT_discr : case DW_AT_import : case DW_AT_common_reference: case DW_AT_containing_type: case DW_AT_default_value: case DW_AT_lower_bound: case DW_AT_bit_stride: case DW_AT_upper_bound: case DW_AT_abstract_origin: case DW_AT_base_types: case DW_AT_count: case DW_AT_friend: case DW_AT_namelist_item: case DW_AT_priority: case DW_AT_specification: case DW_AT_type: case DW_AT_allocated: case DW_AT_associated: case DW_AT_byte_stride: case DW_AT_extension: case DW_AT_trampoline: case DW_AT_small: case DW_AT_object_pointer: case DW_AT_signature: return DW_FORM_CLASS_REFERENCE; case DW_AT_MIPS_fde: /* SGI/IRIX extension */ return DW_FORM_CLASS_FRAMEPTR; } return DW_FORM_CLASS_UNKNOWN; } /* It takes 4 pieces of data (including the FORM) to accurately determine the form 'class' as documented in the DWARF spec. This is per DWARF4, but will work for DWARF2 or 3 as well. */ enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half dwversion, Dwarf_Half attrnum, Dwarf_Half offset_size, Dwarf_Half form) { switch (form) { case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS; case DW_FORM_data2: return DW_FORM_CLASS_CONSTANT; case DW_FORM_data4: if (dwversion <= 3 && offset_size == 4) { enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } return DW_FORM_CLASS_CONSTANT; case DW_FORM_data8: if (dwversion <= 3 && offset_size == 8) { enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } return DW_FORM_CLASS_CONSTANT; case DW_FORM_sec_offset: { enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } /* We do not know what this is. */ break; case DW_FORM_string: return DW_FORM_CLASS_STRING; case DW_FORM_strp: return DW_FORM_CLASS_STRING; case DW_FORM_block: return DW_FORM_CLASS_BLOCK; case DW_FORM_block1: return DW_FORM_CLASS_BLOCK; case DW_FORM_block2: return DW_FORM_CLASS_BLOCK; case DW_FORM_block4: return DW_FORM_CLASS_BLOCK; case DW_FORM_data16: return DW_FORM_CLASS_CONSTANT; case DW_FORM_data1: return DW_FORM_CLASS_CONSTANT; case DW_FORM_sdata: return DW_FORM_CLASS_CONSTANT; case DW_FORM_udata: return DW_FORM_CLASS_CONSTANT; case DW_FORM_ref_addr: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref1: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref2: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref4: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref8: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref_udata: return DW_FORM_CLASS_REFERENCE; case DW_FORM_ref_sig8: return DW_FORM_CLASS_REFERENCE; case DW_FORM_exprloc: return DW_FORM_CLASS_EXPRLOC; case DW_FORM_flag: return DW_FORM_CLASS_FLAG; case DW_FORM_flag_present: return DW_FORM_CLASS_FLAG; case DW_FORM_addrx: return DW_FORM_CLASS_ADDRESS; /* DWARF5 */ case DW_FORM_GNU_addr_index: return DW_FORM_CLASS_ADDRESS; case DW_FORM_strx: return DW_FORM_CLASS_STRING; /* DWARF5 */ case DW_FORM_GNU_str_index: return DW_FORM_CLASS_STRING; case DW_FORM_rnglistx: return DW_FORM_CLASS_RNGLIST; /* DWARF5 */ case DW_FORM_loclistx: return DW_FORM_CLASS_LOCLIST; /* DWARF5 */ case DW_FORM_GNU_ref_alt: return DW_FORM_CLASS_REFERENCE; case DW_FORM_GNU_strp_alt: return DW_FORM_CLASS_STRING; case DW_FORM_strp_sup: return DW_FORM_CLASS_STRING; /* DWARF5 */ case DW_FORM_implicit_const: return DW_FORM_CLASS_CONSTANT; /* DWARF5 */ case DW_FORM_indirect: default: break; }; return DW_FORM_CLASS_UNKNOWN; } /* Given a DIE, figure out what the CU's DWARF version is and the size of an offset and return it through the *version pointer and return DW_DLV_OK. If we cannot find a CU, return DW_DLV_ERROR on error. In case of error no Dwarf_Debug was available, so setting a Dwarf_Error is somewhat futile. Never returns DW_DLV_NO_ENTRY. */ int dwarf_get_version_of_die(Dwarf_Die die, Dwarf_Half *version, Dwarf_Half *offset_size) { Dwarf_CU_Context cucontext = 0; if (!die) { return DW_DLV_ERROR; } cucontext = die->di_cu_context; if (!cucontext) { return DW_DLV_ERROR; } *version = cucontext->cc_version_stamp; *offset_size = cucontext->cc_length_size; return DW_DLV_OK; } Dwarf_Byte_Ptr _dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context, Dwarf_Unsigned *section_len) { Dwarf_Debug dbg = 0; Dwarf_Small *dataptr = 0; struct Dwarf_Section_s *sec = 0; dbg = context->cc_dbg; sec = context->cc_is_info? &dbg->de_debug_info: &dbg->de_debug_types; dataptr = sec->dss_data; *section_len = sec->dss_size; return dataptr; } Dwarf_Byte_Ptr _dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context) { Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr info_end = 0; Dwarf_Byte_Ptr info_start = 0; Dwarf_Off off2 = 0; Dwarf_Small *dataptr = 0; dbg = context->cc_dbg; dataptr = context->cc_is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; off2 = context->cc_debug_offset; info_start = dataptr + off2; info_end = info_start + context->cc_length + context->cc_length_size + context->cc_extension_size; return info_end; } Dwarf_Byte_Ptr _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context) { Dwarf_Debug dbg = 0; Dwarf_Byte_Ptr abbrev_end = 0; Dwarf_Byte_Ptr abbrev_start = 0; struct Dwarf_Section_s *sec = 0; dbg = context->cc_dbg; sec = &dbg->de_debug_abbrev; abbrev_start = sec->dss_data; abbrev_end = abbrev_start + sec->dss_size; return abbrev_end; } dwarfutils-20200114/libdwarf/dwarf_ranges.c000066400000000000000000000277211361531463500205510ustar00rootroot00000000000000/* Copyright (C) 2008-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" struct ranges_entry { struct ranges_entry *next; Dwarf_Ranges cur; }; static void free_allocated_ranges( struct ranges_entry *base) { struct ranges_entry *cur = 0; struct ranges_entry *next = 0; for ( cur = base ; cur ; cur = next ) { next = cur->next; free(cur); } } /* We encapsulate the macro use so we can free local malloc resources that would otherwise leak. See the call points below. */ static int read_unaligned_addr_check(Dwarf_Debug dbg, Dwarf_Addr *addr_out, Dwarf_Small *rangeptr, unsigned address_size, Dwarf_Error *error, Dwarf_Small *section_end) { Dwarf_Addr a = 0; READ_UNALIGNED_CK(dbg,a, Dwarf_Addr, rangeptr, address_size, error,section_end); *addr_out = a; return DW_DLV_OK; } /* As of DWARF5 the ranges section each range list set has a range-list-table header. See "7.28 Range List Table" in the DWARF5 standard. For DWARF5 the offset should be the offset of the range-list-table-header for that range list. For DWARF3 and DWARF4 the offset has to be that of a range list. */ /* Ranges and pc values can be in a split dwarf object. In that case the appropriate values need to be incremented by data from the executable in the compilation unit with the same dwo_id. We return an error which is on the incoming dbg, not the possibly-tied-dbg localdbg. If incoming die is NULL there is no context, so do not look for a tied file, and address_size is the size of the overall object, not the address_size of the context. */ #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) int dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Off rangesoffset, Dwarf_Die die, Dwarf_Ranges ** rangesbuf, Dwarf_Signed * listlen, Dwarf_Unsigned * bytecount, Dwarf_Error * error) { Dwarf_Small *rangeptr = 0; Dwarf_Small *beginrangeptr = 0; Dwarf_Small *section_end = 0; unsigned entry_count = 0; struct ranges_entry *base = 0; struct ranges_entry *last = 0; struct ranges_entry *curre = 0; Dwarf_Ranges * ranges_data_out = 0; unsigned copyindex = 0; Dwarf_Half address_size = 0; int res = DW_DLV_ERROR; Dwarf_Unsigned ranges_base = 0; Dwarf_Unsigned addr_base = 0; Dwarf_Debug localdbg = dbg; Dwarf_Error localerror = 0; Dwarf_Half die_version = 3; /* default for dwarf_get_ranges() */ UNUSEDARG Dwarf_Half offset_size = 4; Dwarf_CU_Context cucontext = 0; if (!dbg) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } address_size = localdbg->de_pointer_size; /* default */ if (die) { /* If we wind up using the tied file the die_version had better match! It cannot be other than a match. */ /* Can return DW_DLV_ERROR, not DW_DLV_NO_ENTRY. Add err code if error. Version comes from the cu context, not the DIE itself. */ res = dwarf_get_version_of_die(die,&die_version, &offset_size); if (res == DW_DLV_ERROR) { _dwarf_error(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); return DW_DLV_ERROR; } if (!die->di_cu_context) { _dwarf_error(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); return DW_DLV_ERROR; } cucontext = die->di_cu_context; /* The DW4 ranges base was never used in GNU but did get emitted. http://llvm.1065342.n5.nabble.com/DebugInfo-DW-AT-GNU-ranges-base-in-non-fission-td64194.html */ if (cucontext->cc_unit_type != DW_UT_skeleton && cucontext->cc_version_stamp != DW_CU_VERSION4 && cucontext->cc_ranges_base_present) { /* Never needed? */ ranges_base = cucontext->cc_ranges_base; } address_size = cucontext->cc_address_size; } /* If tied object exists, base object is DWP and tied object is the skeleton/executabl CU containing a skeleton CU with DW_AT_addr_base/DW_AT_GNU_addr_base and DW_AT_rnglists_base/DW_AT_GNU_ranges base. */ if (die &&dbg->de_tied_data.td_tied_object) { int restied = 0; /* dwo/dwp CU may have (DW5 pg 63) DW_AT_name DW_AT_language DW_AT_macros DW_AT_producer DW_AT_identifier_case DW_AT_main_subprogram DW_AT_entry_pc DW_AT_ranges if DW5 offset of header (see ranges_base/rnglists_base below), else of ranges DW_AT_GNU_pubnames DW_AT_stmt_list, a trivial stmt list with the list of directories and file names where needed for Type Units (DW5 pg 64) and must have DW_AT_[GNU_]dwo_id and inherited from skeleton: DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_stmt_list, DW_AT_comp_dir, DW_AT_use_UTF8, DW_AT_str_offsets_base, DW_AT_addr_base and DW_AT_rnglists_base. skeleton CU may have (DW5 pg 62) DW_AT_[GNU_]addr_base possibly needed by dwp DW_AT_str_offsets_base possibly needed by dwp DW_AT_GNU_ranges_base (GNU)possibly needed by dwp DW_AT_rnglists_base (DWARF5)possibly needed by dwp DW_AT_low_pc DW_AT_high_pc DW_AT_ranges DW_AT_str_offsets_base DW_AT_[GNU_]dwo_name DW_AT_stmt_list DW_AT_comp_dir DW_AT_use_UTF8 and must have DW_AT_[GNU_]dwo_id .debug_ranges does not exist in the DWP, it is only in the executable. */ restied = _dwarf_get_ranges_base_attr_from_tied(dbg, cucontext, &ranges_base, &addr_base, error); if (restied == DW_DLV_ERROR ) { if(!error) { return restied; } dwarf_dealloc(localdbg,*error,DW_DLA_ERROR); *error = 0; /* Nothing else to do. Look in original dbg. */ } else if (restied == DW_DLV_NO_ENTRY ) { /* Nothing else to do. Look in original dbg. */ } else { /* Ranges are never in a split dwarf object. In the base object instead. Use the tied_object */ localdbg = dbg->de_tied_data.td_tied_object; } } res = _dwarf_load_section(localdbg, &localdbg->de_debug_ranges,&localerror); if (res == DW_DLV_ERROR) { _dwarf_error_mv_s_to_t(localdbg,&localerror,dbg,error); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } /* Be safe in case adding rangesoffset and rangebase overflows. */ if (rangesoffset >= localdbg->de_debug_ranges.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); return (DW_DLV_ERROR); } if (ranges_base >= localdbg->de_debug_ranges.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); return (DW_DLV_ERROR); } if ((rangesoffset +ranges_base) >= localdbg->de_debug_ranges.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); return (DW_DLV_ERROR); } /* tied address_size must match the dwo address_size */ section_end = localdbg->de_debug_ranges.dss_data + localdbg->de_debug_ranges.dss_size; rangeptr = localdbg->de_debug_ranges.dss_data + rangesoffset + ranges_base; beginrangeptr = rangeptr; for (;;) { struct ranges_entry * re = 0; if (rangeptr == section_end) { break; } if (rangeptr > section_end) { free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); return (DW_DLV_ERROR); break; } re = calloc(sizeof(struct ranges_entry),1); if (!re) { free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); return (DW_DLV_ERROR); } if ((rangeptr + (2*address_size)) > section_end) { free(re); free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); return (DW_DLV_ERROR); } entry_count++; res = read_unaligned_addr_check(localdbg,&re->cur.dwr_addr1, rangeptr, address_size,error,section_end); if (res != DW_DLV_OK) { free(re); free_allocated_ranges(base); return res; } rangeptr += address_size; res = read_unaligned_addr_check(localdbg,&re->cur.dwr_addr2, rangeptr, address_size,error,section_end); if (res != DW_DLV_OK) { free(re); free_allocated_ranges(base); return res; } rangeptr += address_size; if (!base) { base = re; last = re; } else { last->next = re; last = re; } if (re->cur.dwr_addr1 == 0 && re->cur.dwr_addr2 == 0) { re->cur.dwr_type = DW_RANGES_END; break; } else if (re->cur.dwr_addr1 == MAX_ADDR) { re->cur.dwr_type = DW_RANGES_ADDRESS_SELECTION; } else { re->cur.dwr_type = DW_RANGES_ENTRY; } } /* We return ranges on dbg, so use that to allocate. */ ranges_data_out = (Dwarf_Ranges *) _dwarf_get_alloc(dbg,DW_DLA_RANGES,entry_count); if (!ranges_data_out) { /* Error, apply to original, not local dbg. */ free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); return (DW_DLV_ERROR); } curre = base; *rangesbuf = ranges_data_out; *listlen = entry_count; for (copyindex = 0; curre && (copyindex < entry_count); ++copyindex,++ranges_data_out) { *ranges_data_out = curre->cur; curre = curre->next; } /* ASSERT: curre == NULL */ free_allocated_ranges(base); base = 0; /* Callers will often not care about the bytes used. */ if (bytecount) { *bytecount = rangeptr - beginrangeptr; } return DW_DLV_OK; } int dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off rangesoffset, Dwarf_Ranges ** rangesbuf, Dwarf_Signed * listlen, Dwarf_Unsigned * bytecount, Dwarf_Error * error) { Dwarf_Die die = 0; int res = dwarf_get_ranges_a(dbg,rangesoffset,die, rangesbuf,listlen,bytecount,error); return res; } void dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf, UNUSEDARG Dwarf_Signed rangecount) { dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES); } dwarfutils-20200114/libdwarf/dwarf_reading.h000066400000000000000000000041711361531463500207020ustar00rootroot00000000000000/* Copyright (c) 2018, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DWARF_READING_H #define DWARF_READING_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef DW_DLV_OK /* DW_DLV_OK must match libdwarf.h */ /* DW_DLV_NO_ENTRY must match libdwarf.h */ #define DW_DLV_OK 0 #define DW_DLV_NO_ENTRY -1 #define DW_DLV_ERROR 1 #endif /* DW_DLV_OK */ #define TRUE 1 #define FALSE 0 #define ALIGN4 4 #define ALIGN8 8 #define PREFIX "\t" #define LUFMT "%lu" #define UFMT "%u" #define DFMT "%d" #define XFMT "0x%x" /* even if already seen, values must match, so no #ifdef needed. */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 #define P printf #define F fflush(stdout) #define RRMOA(f,buf,loc,siz,fsiz,errc) _dwarf_object_read_random(f, \ (char *)buf,loc,siz,fsiz,errc); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARF_READING_H */ dwarfutils-20200114/libdwarf/dwarf_reloc_386.h000066400000000000000000000071461361531463500210020ustar00rootroot00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DWARF_RELOC_386_H #define DWARF_RELOC_386_H /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for i386 architecture */ #define R_386_NONE 0 #define R_386_32 1 #define R_386_PC32 2 #define R_386_GOT32 3 #define R_386_PLT32 4 #define R_386_COPY 5 #define R_386_GLOB_DAT 6 #define R_386_JMP_SLOT 7 #define R_386_RELATIVE 8 #define R_386_GOTOFF 9 #define R_386_GOTPC 10 #define R_386_32PLT 11 #define R_386_TLS_TPOFF 14 #define R_386_TLS_IE 15 #define R_386_TLS_GOTIE 16 #define R_386_TLS_LE 17 #define R_386_TLS_LDM 19 #define R_386_16 20 #define R_386_PC16 21 #define R_386_8 22 #define R_386_PC8 23 #define R_386_TLS_GD_32 24 #define R_386_TLS_GD_PUSH 25 #define R_386_TLS_GD_CALL 26 #define R_386_TLS_GD_POP 27 #define R_386_TLS_LDM_32 28 #define R_386_TLS_LDM_PUSH 29 #define R_386_TLS_LDM_CALL 30 #define R_386_TLS_LDM_POP 31 #define R_386_TLS_LDO_32 32 #define R_386_TLS_IE_32 33 #define R_386_TLS_LE_32 34 #define R_386_TLS_DTPMOD32 35 #define R_386_TLS_DTPOFF32 36 #define R_386_TLS_TPOFF32 37 #define R_386_SIZE32 38 #define R_386_TLS_GOTDESC 39 #define R_386_TLS_DESC_CALL 40 #define R_386_TLS_DESC 41 #define R_386_IRELATIVE 42 #define R_386_NUM 43 /* Keep this the last entry. */ #define R_X86_64_NUM 39 #endif /* _WIN32 */ /* Relocation types for X86_64 */ static const char *reloc_type_names_386[] = { "R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32", "R_386_PLT32", "R_386_COPY", /* 5 */ "R_386_GLOB_DAT", "R_386_JMP_SLOT", "R_386_RELATIVE", "R_386_GOTOFF", "R_386_GOTPC", /* 10 */ "R_386_32PLT", "R_386_TLS_TPOFF", "R_386_TLS_IE", "R_386_TLS_GOTIE", "R_386_TLS_LE", "R_386_TLS_LDM", "R_386_16", /* 20 */ "R_386_PC16", "R_386_8", "R_386_PC8", "R_386_TLS_GD_32", "R_386_TLS_GD_PUSH", /* 25 */ "R_386_TLS_GD_CALL", "R_386_TLS_GD_POP", "R_386_TLS_LDM_32", "R_386_TLS_LDM_PUSH", "R_386_TLS_LDM_CALL", /* 30 */ "R_386_TLS_LDM_POP", "R_386_TLS_LDO_32", "R_386_TLS_IE_32", "R_386_TLS_LE_32", "R_386_TLS_DTPMOD32", /* 35 */ "R_386_TLS_DTPOFF32", "R_386_TLS_TPOFF32", "R_386_SIZE32", "R_386_TLS_GOTDESC", "R_386_TLS_DESC_CALL", /* 40 */ "R_386_TLS_DESC", "R_386_IRELATIVE", /* 42 */ }; #endif /* DWARF_RELOC_386_H */ dwarfutils-20200114/libdwarf/dwarf_reloc_arm.h000066400000000000000000000303271361531463500212360ustar00rootroot00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_ARM_H #define DWARF_RELOC_ARM_H /* Definitions for ARM */ #define DWARF_RELOC_ARM #ifndef EM_AARCH64 #define EM_AARCH64 183 /* Arm 64 */ #endif /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for ARM */ #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS32 2 #define R_ARM_REL32 3 #define R_ARM_LDR_PC_G0 4 #define R_ARM_ABS16 5 #define R_ARM_ABS12 6 #define R_ARM_THM_ABS5 7 #define R_ARM_ABS8 8 #define R_ARM_SBREL32 9 #define R_ARM_THM_CALL 10 #define R_ARM_THM_PC8 11 #define R_ARM_BREL_ADJ 12 #define R_ARM_TLS_DESC 13 #define R_ARM_THM_SWI8 14 #define R_ARM_XPC25 15 #define R_ARM_THM_XPC22 16 #define R_ARM_TLS_DTPMOD32 17 #define R_ARM_TLS_DTPOFF32 18 #define R_ARM_TLS_TPOFF32 19 #define R_ARM_COPY 20 #define R_ARM_GLOB_DAT 21 #define R_ARM_JUMP_SLOT 22 #define R_ARM_RELATIVE 23 #define R_ARM_GOTOFF32 24 #define R_ARM_BASE_PREL 25 #define R_ARM_GOT_BREL 26 #define R_ARM_PLT32 27 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 #define R_ARM_THM_JUMP24 30 #define R_ARM_BASE_ABS 31 #define R_ARM_ALU_PCREL_7_0 32 #define R_ARM_ALU_PCREL_15_8 33 #define R_ARM_ALU_PCREL_23_15 34 #define R_ARM_LDR_SBREL_11_0_NC 35 #define R_ARM_ALU_SBREL_19_12_NC 36 #define R_ARM_ALU_SBREL_27_20_CK 37 #define R_ARM_TARGET1 38 #define R_ARM_SBREL31 39 #define R_ARM_V4BX 40 #define R_ARM_TARGET2 41 #define R_ARM_PREL31 42 #define R_ARM_MOVW_ABS_NC 43 #define R_ARM_MOVT_ABS 44 #define R_ARM_MOVW_PREL_NC 45 #define R_ARM_MOVT_PREL 46 #define R_ARM_THM_MOVW_ABS_NC 47 #define R_ARM_THM_MOVT_ABS 48 #define R_ARM_THM_MOVW_PREL_NC 49 #define R_ARM_THM_MOVT_PREL 50 #define R_ARM_THM_JUMP19 51 #define R_ARM_THM_JUMP6 52 #define R_ARM_THM_ALU_PREL_11_0 53 #define R_ARM_THM_PC12 54 #define R_ARM_ABS32_NOI 55 #define R_ARM_REL32_NOI 56 #define R_ARM_ALU_PC_G0_NC 57 #define R_ARM_ALU_PC_G0 58 #define R_ARM_ALU_PC_G1_NC 59 #define R_ARM_ALU_PC_G1 60 #define R_ARM_ALU_PC_G2 61 #define R_ARM_LDR_PC_G1 62 #define R_ARM_LDR_PC_G2 63 #define R_ARM_LDRS_PC_G0 64 #define R_ARM_LDRS_PC_G1 65 #define R_ARM_LDRS_PC_G2 66 #define R_ARM_LDC_PC_G0 67 #define R_ARM_LDC_PC_G1 68 #define R_ARM_LDC_PC_G2 69 #define R_ARM_ALU_SB_G0_NC 70 #define R_ARM_ALU_SB_G0 71 #define R_ARM_ALU_SB_G1_NC 72 #define R_ARM_ALU_SB_G1 73 #define R_ARM_ALU_SB_G2 74 #define R_ARM_LDR_SB_G0 75 #define R_ARM_LDR_SB_G1 76 #define R_ARM_LDR_SB_G2 77 #define R_ARM_LDRS_SB_G0 78 #define R_ARM_LDRS_SB_G1 79 #define R_ARM_LDRS_SB_G2 80 #define R_ARM_LDC_SB_G0 81 #define R_ARM_LDC_SB_G1 82 #define R_ARM_LDC_SB_G2 83 #define R_ARM_MOVW_BREL_NC 84 #define R_ARM_MOVT_BREL 85 #define R_ARM_MOVW_BREL 86 #define R_ARM_THM_MOVW_BREL_NC 87 #define R_ARM_THM_MOVT_BREL 88 #define R_ARM_THM_MOVW_BREL 89 #define R_ARM_TLS_GOTDESC 90 #define R_ARM_TLS_CALL 91 #define R_ARM_TLS_DESCSEQ 92 #define R_ARM_THM_TLS_CALL 93 #define R_ARM_PLT32_ABS 94 #define R_ARM_GOT_ABS 95 #define R_ARM_GOT_PREL 96 #define R_ARM_GOT_BREL12 97 #define R_ARM_GOTOFF12 98 #define R_ARM_GOTRELAX 99 #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 #define R_ARM_THM_JUMP11 102 #define R_ARM_THM_JUMP8 103 #define R_ARM_TLS_GD32 104 #define R_ARM_TLS_LDM32 105 #define R_ARM_TLS_LDO32 106 #define R_ARM_TLS_IE32 107 #define R_ARM_TLS_LE32 108 #define R_ARM_TLS_LDO12 109 #define R_ARM_TLS_LE12 110 #define R_ARM_TLS_IE12GP 111 #define R_ARM_ME_TOO 128 #define R_ARM_THM_TLS_DESCSEQ16 129 #define R_ARM_THM_TLS_DESCSEQ32 130 #define R_ARM_RXPC25 249 #define R_ARM_RSBREL32 250 #define R_ARM_THM_RPC22 251 #define R_ARM_RREL32 252 #define R_ARM_RABS32 253 #define R_ARM_RPC24 254 #define R_ARM_RBASE 255 /* Keep this the last entry. */ #define R_ARM_NUM 256 #endif /* _WIN32 */ /* ARM relocations defined by the ABIs */ static const char *reloc_type_names_ARM[] = { "R_ARM_NONE", /* 00 */ "R_ARM_PC24", /* 01 */ "R_ARM_ABS32", /* 02 */ "R_ARM_REL32", /* 03 */ "R_ARM_LDR_PC_G0", /* 04 */ "R_ARM_ABS16", /* 05 */ "R_ARM_ABS12", /* 06 */ "R_ARM_THM_ABS5", /* 07 */ "R_ARM_ABS8", /* 08 */ "R_ARM_SBREL32", /* 09 */ "R_ARM_THM_CALL", /* 10 */ "R_ARM_THM_PC8", /* 11 */ "R_ARM_BREL_ADJ", /* 12 */ "R_ARM_TLS_DESC", /* 13 */ "R_ARM_THM_SWI8", /* 14 */ "R_ARM_XPC25", /* 15 */ "R_ARM_THM_XPC22", /* 16 */ "R_ARM_TLS_DTPMOD32", /* 17 */ "R_ARM_TLS_DTPOFF32", /* 18 */ "R_ARM_TLS_TPOFF32", /* 19 */ "R_ARM_COPY", /* 20 */ "R_ARM_GLOB_DAT", /* 21 */ "R_ARM_JUMP_SLOT", /* 22 */ "R_ARM_RELATIVE", /* 23 */ "R_ARM_GOTOFF32", /* 24 */ "R_ARM_BASE_PREL", /* 25 */ "R_ARM_GOT_BREL", /* 26 */ "R_ARM_PLT32", /* 27 */ "R_ARM_CALL", /* 28 */ "R_ARM_JUMP24", /* 29 */ "R_ARM_THM_JUMP24", /* 30 */ "R_ARM_BASE_ABS", /* 31 */ "R_ARM_ALU_PCREL_7_0", /* 32 */ "R_ARM_ALU_PCREL_15_8", /* 33 */ "R_ARM_ALU_PCREL_23_15", /* 34 */ "R_ARM_LDR_SBREL_11_0_NC", /* 35 */ "R_ARM_ALU_SBREL_19_12_NC", /* 36 */ "R_ARM_ALU_SBREL_27_20_CK", /* 37 */ "R_ARM_TARGET1", /* 38 */ "R_ARM_SBREL31", /* 39 */ "R_ARM_V4BX", /* 40 */ "R_ARM_TARGET2", /* 41 */ "R_ARM_PREL31", /* 42 */ "R_ARM_MOVW_ABS_NC", /* 43 */ "R_ARM_MOVT_ABS", /* 44 */ "R_ARM_MOVW_PREL_NC", /* 45 */ "R_ARM_MOVT_PREL", /* 46 */ "R_ARM_THM_MOVW_ABS_NC", /* 47 */ "R_ARM_THM_MOVT_ABS", /* 48 */ "R_ARM_THM_MOVW_PREL_NC", /* 49 */ "R_ARM_THM_MOVT_PREL", /* 50 */ "R_ARM_THM_JUMP19", /* 51 */ "R_ARM_THM_JUMP6", /* 52 */ "R_ARM_THM_ALU_PREL_11_0", /* 53 */ "R_ARM_THM_PC12", /* 54 */ "R_ARM_ABS32_NOI", /* 55 */ "R_ARM_REL32_NOI", /* 56 */ "R_ARM_ALU_PC_G0_NC", /* 57 */ "R_ARM_ALU_PC_G0", /* 58 */ "R_ARM_ALU_PC_G1_NC", /* 59 */ "R_ARM_ALU_PC_G1", /* 60 */ "R_ARM_ALU_PC_G2", /* 61 */ "R_ARM_LDR_PC_G1", /* 62 */ "R_ARM_LDR_PC_G2", /* 63 */ "R_ARM_LDRS_PC_G0", /* 64 */ "R_ARM_LDRS_PC_G1", /* 65 */ "R_ARM_LDRS_PC_G2", /* 66 */ "R_ARM_LDC_PC_G0", /* 67 */ "R_ARM_LDC_PC_G1", /* 68 */ "R_ARM_LDC_PC_G2", /* 69 */ "R_ARM_ALU_SB_G0_NC", /* 70 */ "R_ARM_ALU_SB_G0", /* 71 */ "R_ARM_ALU_SB_G1_NC", /* 72 */ "R_ARM_ALU_SB_G1", /* 73 */ "R_ARM_ALU_SB_G2", /* 74 */ "R_ARM_LDR_SB_G0", /* 75 */ "R_ARM_LDR_SB_G1", /* 76 */ "R_ARM_LDR_SB_G2", /* 77 */ "R_ARM_LDRS_SB_G0", /* 78 */ "R_ARM_LDRS_SB_G1", /* 79 */ "R_ARM_LDRS_SB_G2", /* 80 */ "R_ARM_LDC_SB_G0", /* 81 */ "R_ARM_LDC_SB_G1", /* 82 */ "R_ARM_LDC_SB_G2", /* 83 */ "R_ARM_MOVW_BREL_NC", /* 84 */ "R_ARM_MOVT_BREL", /* 85 */ "R_ARM_MOVW_BREL", /* 86 */ "R_ARM_THM_MOVW_BREL_NC", /* 87 */ "R_ARM_THM_MOVT_BREL", /* 88 */ "R_ARM_THM_MOVW_BREL", /* 89 */ "R_ARM_TLS_GOTDESC", /* 90 */ "R_ARM_TLS_CALL", /* 91 */ "R_ARM_TLS_DESCSEQ", /* 92 */ "R_ARM_THM_TLS_CALL", /* 93 */ "R_ARM_PLT32_ABS", /* 94 */ "R_ARM_GOT_ABS", /* 95 */ "R_ARM_GOT_PREL", /* 96 */ "R_ARM_GOT_BREL12", /* 97 */ "R_ARM_GOTOFF12", /* 98 */ "R_ARM_GOTRELAX", /* 99 */ "R_ARM_GNU_VTENTRY", /* 100 */ "R_ARM_GNU_VTINHERIT", /* 101 */ "R_ARM_THM_JUMP11", /* 102 */ "R_ARM_THM_JUMP8", /* 103 */ "R_ARM_TLS_GD32", /* 104 */ "R_ARM_TLS_LDM32", /* 105 */ "R_ARM_TLS_LDO32", /* 106 */ "R_ARM_TLS_IE32", /* 107 */ "R_ARM_TLS_LE32", /* 108 */ "R_ARM_TLS_LDO12", /* 109 */ "R_ARM_TLS_LE12", /* 110 */ "R_ARM_TLS_IE12GP", /* 111 */ "R_ARM_TLS_MOVT_TPOFF32", /* 112 */ /* "R_ARM_PRIVATE_0" */ "R_ARM_TLS_MOVW_TPOFF32", /* 113 */ /* "R_ARM_PRIVATE_1" */ "R_ARM_THM_TLS_MOVT_TPOFF32", /* 114 */ /* "R_ARM_PRIVATE_2" */ "R_ARM_THM_TLS_MOVT_TPOFF32", /* 115 */ /* "R_ARM_PRIVATE_3" */ "R_ARM_PRIVATE_4", /* 116 */ "R_ARM_PRIVATE_5", /* 117 */ "R_ARM_PRIVATE_6", /* 118 */ "R_ARM_PRIVATE_7", /* 119 */ "R_ARM_PRIVATE_8", /* 120 */ "R_ARM_PRIVATE_9", /* 121 */ "R_ARM_PRIVATE_10", /* 122 */ "R_ARM_PRIVATE_11", /* 123 */ "R_ARM_PRIVATE_12", /* 124 */ "R_ARM_PRIVATE_13", /* 125 */ "R_ARM_PRIVATE_14", /* 126 */ "R_ARM_PRIVATE_15", /* 127 */ "R_ARM_ME_TOO", /* 128 */ "R_ARM_THM_TLS_DESCSEQ16", /* 129 */ "R_ARM_THM_TLS_DESCSEQ32", /* 130 */ }; #ifndef R_AARCH64_ABS64 #define R_AARCH64_ABS64 0x101 #endif #ifndef R_AARCH64_ABS32 #define R_AARCH64_ABS32 0x102 #endif #endif /* DWARF_RELOC_ARM_H */ dwarfutils-20200114/libdwarf/dwarf_reloc_mips.h000066400000000000000000000110411361531463500214170ustar00rootroot00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_MIPS_H #define DWARF_RELOC_MIPS_H /* Definitions for MIPS */ #define DWARF_RELOC_MIPS /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for MIPS */ #define R_MIPS_NONE 0 #define R_MIPS_16 1 #define R_MIPS_32 2 #define R_MIPS_ADD R_MIPS_32 #define R_MIPS_REL 3 #define R_MIPS_REL32 R_MIPS_REL #define R_MIPS_26 4 #define R_MIPS_HI16 5 #define R_MIPS_LO16 6 #define R_MIPS_GPREL 7 #define R_MIPS_GPREL16 R_MIPS_GPREL #define R_MIPS_LITERAL 8 #define R_MIPS_GOT 9 #define R_MIPS_GOT16 R_MIPS_GOT #define R_MIPS_PC16 10 #define R_MIPS_CALL 11 #define R_MIPS_CALL16 R_MIPS_CALL #define R_MIPS_GPREL32 12 #define R_MIPS_UNUSED1 13 #define R_MIPS_UNUSED2 14 #define R_MIPS_UNUSED3 15 #define R_MIPS_SHIFT5 16 #define R_MIPS_SHIFT6 17 #define R_MIPS_64 18 #define R_MIPS_GOT_DISP 19 #define R_MIPS_GOT_PAGE 20 #define R_MIPS_GOT_OFST 21 #define R_MIPS_GOT_HI16 22 #define R_MIPS_GOT_LO16 23 #define R_MIPS_SUB 24 #define R_MIPS_INSERT_A 25 #define R_MIPS_INSERT_B 26 #define R_MIPS_DELETE 27 #define R_MIPS_HIGHER 28 #define R_MIPS_HIGHEST 29 #define R_MIPS_CALL_HI16 30 #define R_MIPS_CALL_LO16 31 #define R_MIPS_SCN_DISP 32 #define R_MIPS_REL16 33 #define R_MIPS_ADD_IMMEDIATE 34 /* Keep this the last entry. */ #define R_MIPS_NUM 35 #endif /* _WIN32 */ /* Relocation types for MIPS */ static const char *reloc_type_names_MIPS[] = { "R_MIPS_NONE", /* 00 */ "R_MIPS_16", /* 01 */ "R_MIPS_32", /* 02 */ "R_MIPS_REL32", /* 03 */ "R_MIPS_26", /* 04 */ "R_MIPS_HI16", /* 05 */ "R_MIPS_LO16", /* 06 */ "R_MIPS_GPREL16", /* 07 */ "R_MIPS_LITERAL", /* 08 */ "R_MIPS_GOT16", /* 09 */ "R_MIPS_PC16", /* 10 */ "R_MIPS_CALL16", /* 11 */ "R_MIPS_GPREL32", /* 12 */ "R_MIPS_UNUSED1", /* 13 */ "R_MIPS_UNUSED2", /* 14 */ "R_MIPS_UNUSED3", /* 15 */ "R_MIPS_SHIFT5", /* 16 */ "R_MIPS_SHIFT6", /* 17 */ "R_MIPS_64", /* 18 */ "R_MIPS_GOT_DISP", /* 19 */ "R_MIPS_GOT_PAGE", /* 20 */ "R_MIPS_GOT_OFST", /* 21 */ "R_MIPS_GOT_HI16", /* 22 */ "R_MIPS_GOT_LO16", /* 23 */ "R_MIPS_SUB", /* 24 */ "R_MIPS_INSERT_A", /* 25 */ "R_MIPS_INSERT_B", /* 26 */ "R_MIPS_DELETE", /* 27 */ "R_MIPS_HIGHER", /* 28 */ "R_MIPS_HIGHEST", /* 29 */ "R_MIPS_CALL_HI16", /* 30 */ "R_MIPS_CALL_LO16", /* 31 */ "R_MIPS_SCN_DISP", /* 32 */ "R_MIPS_REL16", /* 33 */ "R_MIPS_ADD_IMMEDIATE", /* 34 */ }; #endif /* DWARF_RELOC_MIPS_H */ dwarfutils-20200114/libdwarf/dwarf_reloc_ppc.h000066400000000000000000000253761361531463500212510ustar00rootroot00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DWARF_RELOC_PPC_H #define DWARF_RELOC_PPC_H /* Definitions for PPC */ #define DWARF_RELOC_PPC /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* PowerPC relocations defined by the ABIs */ #define R_PPC_NONE 0 #define R_PPC_ADDR32 1 /* 32bit absolute address */ #define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ #define R_PPC_ADDR16 3 /* 16bit absolute address */ #define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ #define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ #define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ #define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ #define R_PPC_ADDR14_BRTAKEN 8 #define R_PPC_ADDR14_BRNTAKEN 9 #define R_PPC_REL24 10 /* PC relative 26 bit */ #define R_PPC_REL14 11 /* PC relative 16 bit */ #define R_PPC_REL14_BRTAKEN 12 #define R_PPC_REL14_BRNTAKEN 13 #define R_PPC_GOT16 14 #define R_PPC_GOT16_LO 15 #define R_PPC_GOT16_HI 16 #define R_PPC_GOT16_HA 17 #define R_PPC_PLTREL24 18 #define R_PPC_COPY 19 #define R_PPC_GLOB_DAT 20 #define R_PPC_JMP_SLOT 21 #define R_PPC_RELATIVE 22 #define R_PPC_LOCAL24PC 23 #define R_PPC_UADDR32 24 #define R_PPC_UADDR16 25 #define R_PPC_REL32 26 #define R_PPC_PLT32 27 #define R_PPC_PLTREL32 28 #define R_PPC_PLT16_LO 29 #define R_PPC_PLT16_HI 30 #define R_PPC_PLT16_HA 31 #define R_PPC_SDAREL16 32 #define R_PPC_SECTOFF 33 #define R_PPC_SECTOFF_LO 34 #define R_PPC_SECTOFF_HI 35 #define R_PPC_SECTOFF_HA 36 /* Unused types */ #define R_PPC_37 37 #define R_PPC_38 38 #define R_PPC_39 39 #define R_PPC_40 40 #define R_PPC_41 41 #define R_PPC_42 42 #define R_PPC_43 43 #define R_PPC_44 44 #define R_PPC_45 45 #define R_PPC_46 46 #define R_PPC_47 47 #define R_PPC_48 48 #define R_PPC_49 49 #define R_PPC_50 50 #define R_PPC_51 51 #define R_PPC_52 52 #define R_PPC_53 53 #define R_PPC_54 54 #define R_PPC_55 55 /* Unused types */ #define R_PPC_56 56 #define R_PPC_57 57 #define R_PPC_58 58 #define R_PPC_59 59 #define R_PPC_60 60 #define R_PPC_61 61 #define R_PPC_62 62 #define R_PPC_63 63 #define R_PPC_64 64 #define R_PPC_65 65 #define R_PPC_66 66 /* PowerPC relocations defined for the TLS access ABI. */ #define R_PPC_TLS 67 /* none (sym+add)@tls */ #define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ #define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ #define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ #define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ #define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ #define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ #define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ #define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ #define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ #define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ #define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ #define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ #define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ #define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ #define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ #define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ #define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ #define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ #define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ #define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ #define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ #define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ #define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ #define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ #define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ #define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ #define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ /* Keep this the last entry. */ #define R_PPC_NUM 95 #endif /* _WIN32 */ /* PowerPC relocations defined by the ABIs */ static const char *reloc_type_names_PPC[] = { "R_PPC_NONE", /* 00 */ "R_PPC_ADDR32", /* 01 */ "R_PPC_ADDR24", /* 02 */ "R_PPC_ADDR16", /* 03 */ "R_PPC_ADDR16_LO", /* 04 */ "R_PPC_ADDR16_HI", /* 05 */ "R_PPC_ADDR16_HA", /* 06 */ "R_PPC_ADDR14", /* 07 */ "R_PPC_ADDR14_BRTAKEN", /* 08 */ "R_PPC_ADDR14_BRNTAKEN", /* 09 */ "R_PPC_REL24", /* 10 */ "R_PPC_REL14", /* 11 */ "R_PPC_REL14_BRTAKEN", /* 12 */ "R_PPC_REL14_BRNTAKEN", /* 13 */ "R_PPC_GOT16", /* 14 */ "R_PPC_GOT16_LO", /* 15 */ "R_PPC_GOT16_HI", /* 16 */ "R_PPC_GOT16_HA", /* 17 */ "R_PPC_PLTREL24", /* 18 */ "R_PPC_COPY", /* 19 */ "R_PPC_GLOB_DAT", /* 20 */ "R_PPC_JMP_SLOT", /* 21 */ "R_PPC_RELATIVE", /* 22 */ "R_PPC_LOCAL24PC", /* 23 */ "R_PPC_UADDR32", /* 24 */ "R_PPC_UADDR16", /* 25 */ "R_PPC_REL32", /* 26 */ "R_PPC_PLT32", /* 27 */ "R_PPC_PLTREL32", /* 28 */ "R_PPC_PLT16_LO", /* 29 */ "R_PPC_PLT16_HI", /* 30 */ "R_PPC_PLT16_HA", /* 31 */ "R_PPC_SDAREL16", /* 32 */ "R_PPC_SECTOFF", /* 33 */ "R_PPC_SECTOFF_LO", /* 34 */ "R_PPC_SECTOFF_HI", /* 35 */ "R_PPC_SECTOFF_HA", /* 36 */ "R_PPC_37", /* 37 */ "R_PPC_38", /* 38 */ "R_PPC_39", /* 39 */ "R_PPC_40", /* 40 */ "R_PPC_41", /* 41 */ "R_PPC_42", /* 42 */ "R_PPC_43", /* 43 */ "R_PPC_44", /* 44 */ "R_PPC_45", /* 45 */ "R_PPC_46", /* 46 */ "R_PPC_47", /* 47 */ "R_PPC_48", /* 48 */ "R_PPC_49", /* 49 */ "R_PPC_50", /* 50 */ "R_PPC_51", /* 51 */ "R_PPC_52", /* 52 */ "R_PPC_53", /* 53 */ "R_PPC_54", /* 54 */ "R_PPC_55", /* 55 */ "R_PPC_56", /* 56 */ "R_PPC_57", /* 57 */ "R_PPC_58", /* 58 */ "R_PPC_59", /* 59 */ "R_PPC_60", /* 60 */ "R_PPC_61", /* 61 */ "R_PPC_62", /* 62 */ "R_PPC_63", /* 63 */ "R_PPC_64", /* 64 */ "R_PPC_65", /* 65 */ "R_PPC_66", /* 66 */ "R_PPC_TLS", /* 67 */ "R_PPC_DTPMOD32", /* 68 */ "R_PPC_TPREL16", /* 69 */ "R_PPC_TPREL16_LO", /* 70 */ "R_PPC_TPREL16_HI", /* 71 */ "R_PPC_TPREL16_HA", /* 72 */ "R_PPC_TPREL32", /* 73 */ "R_PPC_DTPREL16", /* 74 */ "R_PPC_DTPREL16_LO", /* 75 */ "R_PPC_DTPREL16_HI", /* 76 */ "R_PPC_DTPREL16_HA", /* 77 */ "R_PPC_DTPREL64", /* 78 */ "R_PPC_GOT_TLSGD16", /* 79 */ "R_PPC_GOT_TLSGD16_LO", /* 80 */ "R_PPC_GOT_TLSGD16_HI", /* 81 */ "R_PPC_GOT_TLSGD16_HA", /* 82 */ "R_PPC_GOT_TLSLD16", /* 83 */ "R_PPC_GOT_TLSLD16_LO", /* 84 */ "R_PPC_GOT_TLSLD16_HI", /* 85 */ "R_PPC_GOT_TLSLD16_HA", /* 86 */ "R_PPC_GOT_TPREL16_DS", /* 87 */ "R_PPC_GOT_TPREL16_LO", /* 88 */ "R_PPC_GOT_TPREL16_HI", /* 89 */ "R_PPC_GOT_TPREL16_HA", /* 90 */ "R_PPC_GOT_DTPREL16", /* 91 */ "R_PPC_GOT_DTPREL16_LO", /* 92 */ "R_PPC_GOT_DTPREL16_HI", /* 93 */ "R_PPC_GOT_DTPREL16_HA", /* 94 */ }; #endif /* DWARF_RELOC_PPC_H */ dwarfutils-20200114/libdwarf/dwarf_reloc_ppc64.h000066400000000000000000000335061361531463500214150ustar00rootroot00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef DWARF_RELOC_PPC64_H #define DWARF_RELOC_PPC64_H /* Definitions for PPC64 */ #define DWARF_RELOC_PPC64 /* Include the definitions only in the case of Windows */ #ifdef _WIN32 #include "dwarf_reloc_ppc.h" /* PowerPC64 relocations defined by the ABIs */ #define R_PPC64_NONE R_PPC_NONE #define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address. */ #define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned. */ #define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address. */ #define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of abs. address. */ #define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of abs. address. */ #define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ #define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned. */ #define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN #define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN #define R_PPC64_REL24 R_PPC_REL24 /* PC relative 26 bit, word aligned. */ #define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit. */ #define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN #define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN #define R_PPC64_GOT16 R_PPC_GOT16 #define R_PPC64_GOT16_LO R_PPC_GOT16_LO #define R_PPC64_GOT16_HI R_PPC_GOT16_HI #define R_PPC64_GOT16_HA R_PPC_GOT16_HA #define R_PPC64_COPY R_PPC_COPY #define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT #define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT #define R_PPC64_RELATIVE R_PPC_RELATIVE #define R_PPC64_UADDR32 R_PPC_UADDR32 #define R_PPC64_UADDR16 R_PPC_UADDR16 #define R_PPC64_REL32 R_PPC_REL32 #define R_PPC64_PLT32 R_PPC_PLT32 #define R_PPC64_PLTREL32 R_PPC_PLTREL32 #define R_PPC64_PLT16_LO R_PPC_PLT16_LO #define R_PPC64_PLT16_HI R_PPC_PLT16_HI #define R_PPC64_PLT16_HA R_PPC_PLT16_HA #define R_PPC64_SECTOFF R_PPC_SECTOFF #define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO #define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI #define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA #define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2. */ #define R_PPC64_ADDR64 38 /* doubleword64 S + A. */ #define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A). */ #define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A). */ #define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A). */ #define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A). */ #define R_PPC64_UADDR64 43 /* doubleword64 S + A. */ #define R_PPC64_REL64 44 /* doubleword64 S + A - P. */ #define R_PPC64_PLT64 45 /* doubleword64 L + A. */ #define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P. */ #define R_PPC64_TOC16 47 /* half16* S + A - .TOC. */ #define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.). */ #define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.). */ #define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.). */ #define R_PPC64_TOC 51 /* doubleword64 .TOC. */ #define R_PPC64_PLTGOT16 52 /* half16* M + A. */ #define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A). */ #define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A). */ #define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A). */ #define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2. */ #define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2. */ #define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2. */ #define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2. */ #define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2. */ #define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2. */ #define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2. */ #define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2. */ #define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2. */ #define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2. */ #define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2. */ /* PowerPC64 relocations defined for the TLS access ABI. */ #define R_PPC64_TLS 67 /* none (sym+add)@tls */ #define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ #define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ #define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ #define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ #define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ #define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ #define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ #define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ #define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ #define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ #define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ #define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ #define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ #define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ #define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ #define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ #define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ #define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ #define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ #define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ #define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ #define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ #define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ #define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ #define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ #define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ #define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ #define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ #define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ #define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ #define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ #define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ #define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ #define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ #define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ #define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ /* Additional relocation types */ #define R_PPC64_TOC32 107 #define R_PPC64_DTPMOD32 108 #define R_PPC64_TPREL32 109 #define R_PPC64_DTPREL32 110 /* Keep this the last entry. */ #define R_PPC64_NUM 111 #endif /* _WIN32 */ /* PowerPC64 relocations defined by the ABIs */ static const char *reloc_type_names_PPC64[] = { "R_PPC64_NONE", /* 00 */ "R_PPC64_ADDR32", /* 01 */ "R_PPC64_ADDR24", /* 02 */ "R_PPC64_ADDR16", /* 03 */ "R_PPC64_ADDR16_LO", /* 04 */ "R_PPC64_ADDR16_HI", /* 05 */ "R_PPC64_ADDR16_HA", /* 06 */ "R_PPC64_ADDR14", /* 07 */ "R_PPC64_ADDR14_BRTAKEN", /* 08 */ "R_PPC64_ADDR14_BRNTAKEN", /* 09 */ "R_PPC64_REL24", /* 10 */ "R_PPC64_REL14", /* 11 */ "R_PPC64_REL14_BRTAKEN", /* 12 */ "R_PPC64_REL14_BRNTAKEN", /* 13 */ "R_PPC64_GOT16", /* 14 */ "R_PPC64_GOT16_LO", /* 15 */ "R_PPC64_GOT16_HI", /* 16 */ "R_PPC64_GOT16_HA", /* 17 */ "R_PPC64_PLTREL24", /* 18 */ "R_PPC64_COPY", /* 19 */ "R_PPC64_GLOB_DAT", /* 20 */ "R_PPC64_JMP_SLOT", /* 21 */ "R_PPC64_RELATIVE", /* 22 */ "R_PPC64_LOCAL24PC", /* 23 */ "R_PPC64_UADDR32", /* 24 */ "R_PPC64_UADDR16", /* 25 */ "R_PPC64_REL32", /* 26 */ "R_PPC64_PLT32", /* 27 */ "R_PPC64_PLTREL32", /* 28 */ "R_PPC64_PLT16_LO", /* 29 */ "R_PPC64_PLT16_HI", /* 30 */ "R_PPC64_PLT16_HA", /* 31 */ "R_PPC64_SDAREL16", /* 32 */ "R_PPC64_SECTOFF", /* 33 */ "R_PPC64_SECTOFF_LO", /* 34 */ "R_PPC64_SECTOFF_HI", /* 35 */ "R_PPC64_SECTOFF_HA", /* 36 */ "R_PPC64_REL30", /* 37 */ "R_PPC64_ADDR64", /* 38 */ "R_PPC64_ADDR16_HIGHER", /* 39 */ "R_PPC64_ADDR16_HIGHERA", /* 40 */ "R_PPC64_ADDR16_HIGHEST", /* 41 */ "R_PPC64_ADDR16_HIGHESTA", /* 42 */ "R_PPC64_UADDR64", /* 43 */ "R_PPC64_REL64", /* 44 */ "R_PPC64_PLT64", /* 45 */ "R_PPC64_PLTREL64", /* 46 */ "R_PPC64_TOC16", /* 47 */ "R_PPC64_TOC16_LO", /* 48 */ "R_PPC64_TOC16_HI", /* 49 */ "R_PPC64_TOC16_HA", /* 50 */ "R_PPC64_TOC", /* 51 */ "R_PPC64_PLTGOT16", /* 52 */ "R_PPC64_PLTGOT16_LO", /* 53 */ "R_PPC64_PLTGOT16_HI", /* 54 */ "R_PPC64_PLTGOT16_HA", /* 55 */ "R_PPC64_ADDR16_DS", /* 56 */ "R_PPC64_ADDR16_LO_DS", /* 57 */ "R_PPC64_GOT16_DS", /* 58 */ "R_PPC64_GOT16_LO_DS", /* 59 */ "R_PPC64_PLT16_LO_DS", /* 60 */ "R_PPC64_SECTOFF_DS", /* 61 */ "R_PPC64_SECTOFF_LO_DS", /* 62 */ "R_PPC64_TOC16_DS", /* 63 */ "R_PPC64_TOC16_LO_DS", /* 64 */ "R_PPC64_PLTGOT16_DS", /* 65 */ "R_PPC64_PLTGOT16_LO_DS", /* 66 */ "R_PPC64_TLS", /* 67 */ "R_PPC64_DTPMOD32", /* 68 */ "R_PPC64_TPREL16", /* 69 */ "R_PPC64_TPREL16_LO", /* 70 */ "R_PPC64_TPREL16_HI", /* 71 */ "R_PPC64_TPREL16_HA", /* 72 */ "R_PPC64_TPREL32", /* 73 */ "R_PPC64_DTPREL16", /* 74 */ "R_PPC64_DTPREL16_LO", /* 75 */ "R_PPC64_DTPREL16_HI", /* 76 */ "R_PPC64_DTPREL16_HA", /* 77 */ "R_PPC64_DTPREL64", /* 78 */ "R_PPC64_GOT_TLSGD16", /* 79 */ "R_PPC64_GOT_TLSGD16_LO", /* 80 */ "R_PPC64_GOT_TLSGD16_HI", /* 81 */ "R_PPC64_GOT_TLSGD16_HA", /* 82 */ "R_PPC64_GOT_TLSLD16", /* 83 */ "R_PPC64_GOT_TLSLD16_LO", /* 84 */ "R_PPC64_GOT_TLSLD16_HI", /* 85 */ "R_PPC64_GOT_TLSLD16_HA", /* 86 */ "R_PPC64_GOT_TPREL16_DS", /* 87 */ "R_PPC64_GOT_TPREL16_LO", /* 88 */ "R_PPC64_GOT_TPREL16_HI", /* 89 */ "R_PPC64_GOT_TPREL16_HA", /* 90 */ "R_PPC64_GOT_DTPREL16", /* 91 */ "R_PPC64_GOT_DTPREL16_LO", /* 92 */ "R_PPC64_GOT_DTPREL16_HI", /* 93 */ "R_PPC64_GOT_DTPREL16_HA", /* 94 */ "R_PPC64_TPREL16_DS", /* 95 */ "R_PPC64_TPREL16_LO_DS", /* 96 */ "R_PPC64_TPREL16_HIGHER", /* 97 */ "R_PPC64_TPREL16_HIGHERA", /* 98 */ "R_PPC64_TPREL16_HIGHEST", /* 99 */ "R_PPC64_TPREL16_HIGHESTA", /* 100 */ "R_PPC64_DTPREL16_DS", /* 101 */ "R_PPC64_DTPREL16_LO_DS", /* 102 */ "R_PPC64_DTPREL16_HIGHER", /* 103 */ "R_PPC64_DTPREL16_HIGHERA", /* 104 */ "R_PPC64_DTPREL16_HIGHEST", /* 105 */ "R_PPC64_DTPREL16_HIGHESTA", /* 106 */ "R_PPC64_TOC32", /* 107 */ "R_PPC64_DTPMOD32", /* 108 */ "R_PPC64_TPREL32", /* 109 */ "R_PPC64_DTPREL32", /* 110 */ }; #endif /* DWARF_RELOC_PPC64_H */ dwarfutils-20200114/libdwarf/dwarf_reloc_x86_64.h000066400000000000000000000141371361531463500214160ustar00rootroot00000000000000/* Copyright (C) 2007-2012 David Anderson. All Rights Reserved. Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The address of the Free Software Foundation is Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DWARF_RELOC_X86_64_H #define DWARF_RELOC_X86_64_H /* Definitions for X86_64 */ #define DWARF_RELOC_X86_64 /* Include the definitions only in the case of Windows */ #ifdef _WIN32 /* Relocation types for AMD x86-64 architecture */ #define R_X86_64_NONE 0 /* No reloc */ #define R_X86_64_64 1 /* Direct 64 bit */ #define R_X86_64_PC32 2 /* PC relative 32 bit signed */ #define R_X86_64_GOT32 3 /* 32 bit GOT entry */ #define R_X86_64_PLT32 4 /* 32 bit PLT address */ #define R_X86_64_COPY 5 /* Copy symbol at runtime */ #define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ #define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ #define R_X86_64_RELATIVE 8 /* Adjust by program base */ #define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative offset to GOT */ #define R_X86_64_32 10 /* Direct 32 bit zero extended */ #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ #define R_X86_64_16 12 /* Direct 16 bit zero extended */ #define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ #define R_X86_64_8 14 /* Direct 8 bit sign extended */ #define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ #define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ #define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ #define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ #define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset to two GOT entries for GD symbol */ #define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset to two GOT entries for LD symbol */ #define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ #define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset to GOT entry for IE symbol */ #define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ #define R_X86_64_PC64 24 /* PC relative 64 bit */ #define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ #define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative offset to GOT */ #define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ #define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset to GOT entry */ #define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ #define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ #define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset to PLT entry */ #define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ #define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ #define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor */ #define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS descriptor */ #define R_X86_64_TLSDESC 36 /* TLS descriptor */ #define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ #define R_X86_64_RELATIVE64 38 /* 64bit adjust by program base */ /* Keep this the last entry. */ #define R_X86_64_NUM 39 #endif /* _WIN32 */ /* Relocation types for X86_64 */ static const char *reloc_type_names_X86_64[] = { "R_X86_64_NONE", /* 00 */ "R_X86_64_64", /* 01 */ "R_X86_64_PC32", /* 02 */ "R_X86_64_GOT32", /* 03 */ "R_X86_64_PLT32", /* 04 */ "R_X86_64_COPY", /* 05 */ "R_X86_64_GLOB_DAT", /* 06 */ "R_X86_64_JUMP_SLOT", /* 07 */ "R_X86_64_RELATIVE", /* 08 */ "R_X86_64_GOTPCREL", /* 09 */ "R_X86_64_32", /* 10 */ "R_X86_64_32S", /* 11 */ "R_X86_64_16", /* 12 */ "R_X86_64_PC16", /* 13 */ "R_X86_64_8", /* 14 */ "R_X86_64_PC8", /* 15 */ "R_X86_64_DTPMOD64", /* 16 */ "R_X86_64_DTPOFF64", /* 17 */ "R_X86_64_TPOFF64", /* 18 */ "R_X86_64_TLSGD", /* 19 */ "R_X86_64_TLSLD", /* 20 */ "R_X86_64_DTPOFF32", /* 21 */ "R_X86_64_GOTTPOFF", /* 22 */ "R_X86_64_TPOFF32", /* 23 */ "R_X86_64_PC64", /* 24 */ "R_X86_64_GOTOFF64", /* 25 */ "R_X86_64_GOTPC32", /* 26 */ "R_X86_64_GOT64", /* 27 */ "R_X86_64_GOTPCREL64", /* 28 */ "R_X86_64_GOTPC64", /* 29 */ "R_X86_64_GOTPLT64", /* 30 */ "R_X86_64_PLTOFF64", /* 31 */ "R_X86_64_SIZE32", /* 32 */ "R_X86_64_SIZE64", /* 33 */ "R_X86_64_GOTPC32_TLSDESC", /* 34 */ "R_X86_64_TLSDESC_CALL", /* 35 */ "R_X86_64_TLSDESC", /* 36 */ "R_X86_64_IRELATIVE", /* 37 */ "R_X86_64_RELATIVE64", /* 38 */ }; #endif /* DWARF_RELOC_X86_64_H */ dwarfutils-20200114/libdwarf/dwarf_str_offsets.c000066400000000000000000000304331361531463500216250ustar00rootroot00000000000000/* Copyright (C) 2018-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_str_offsets.h" #define TRUE 1 #define FALSE 0 #define STR_OFFSETS_MAGIC 0x2feed2 #define VALIDATE_SOT(xsot) \ if (!xsot) { \ _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULLARGUMENT); \ return DW_DLV_ERROR; \ } \ if (!xsot->so_dbg) { \ _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULL_DBG); \ return DW_DLV_ERROR; \ } \ if (xsot->so_magic_value != STR_OFFSETS_MAGIC) { \ _dwarf_error(xsot->so_dbg,error,DW_DLE_STR_OFFSETS_NO_MAGIC); \ return DW_DLV_ERROR; \ } #if 0 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_open_str_offsets_table_access(Dwarf_Debug dbg, Dwarf_Str_Offsets_Table * table_data, Dwarf_Error * error) { int res = 0; Dwarf_Str_Offsets_Table local_table_data = 0; 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; \ } if (!table_data) { _dwarf_error(dbg,error,DW_DLE_STR_OFFSETS_NULLARGUMENT); \ return DW_DLV_ERROR; \ } /* Considered testing for *table_data being NULL, but not doing such a test. */ res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); if (res != DW_DLV_OK) { return res; } offsets_start_ptr = dbg->de_debug_str_offsets.dss_data; if (!offsets_start_ptr) { return DW_DLV_NO_ENTRY; } sec_size = dbg->de_debug_str_offsets.dss_size; local_table_data = (Dwarf_Str_Offsets_Table)_dwarf_get_alloc(dbg, DW_DLA_STR_OFFSETS,1); if(!local_table_data) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } local_table_data->so_dbg = dbg; local_table_data->so_magic_value = STR_OFFSETS_MAGIC; local_table_data->so_section_start_ptr = offsets_start_ptr; local_table_data->so_section_end_ptr = offsets_start_ptr +sec_size; local_table_data->so_section_size = sec_size; local_table_data->so_next_table_offset = 0; local_table_data->so_wasted_section_bytes = 0; /* get_alloc zeroed all the bits, no need to repeat that here. */ *table_data = local_table_data; return DW_DLV_OK; } int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table table_data, Dwarf_Error * error) { Dwarf_Debug dbg = 0; VALIDATE_SOT(table_data) dbg = table_data->so_dbg; table_data->so_magic_value = 0xdead; dwarf_dealloc(dbg,table_data, DW_DLA_STR_OFFSETS); return DW_DLV_OK; } int dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned index, Dwarf_Unsigned *stroffset, Dwarf_Error *error) { Dwarf_Small *entryptr = 0; Dwarf_Unsigned val = 0; VALIDATE_SOT(sot) if (index >= sot->so_array_entry_count) { _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG); return DW_DLV_ERROR; } entryptr = sot->so_array_ptr + (index * sot->so_array_entry_size); READ_UNALIGNED_CK(sot->so_dbg, val, Dwarf_Unsigned, entryptr, sot->so_array_entry_size,error,sot->so_end_cu_ptr); *stroffset = val; return DW_DLV_OK; } /* We are assuming we can look for a str_offsets table header on 32bit boundaries. Any non-zero value suggests we are at a table. So we assume it is a table. Later we'll check for validity. This is just so that unused zeroed 32bit words, if any, do not stop our processing. */ static int find_next_str_offsets_tab(Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned starting_offset, Dwarf_Unsigned *table_offset_out, Dwarf_Error *error) { Dwarf_Small *word_ptra = 0; Dwarf_Small *word_ptrb = 0; Dwarf_Unsigned offset = starting_offset; word_ptra = word_ptrb = sot->so_section_start_ptr +offset; for ( ; ; word_ptrb += DWARF_32BIT_SIZE) { Dwarf_Unsigned one32bit = 0; if (word_ptrb >= sot->so_section_end_ptr) { sot->so_wasted_section_bytes += (word_ptrb - word_ptra); return DW_DLV_NO_ENTRY; } READ_UNALIGNED_CK(sot->so_dbg, one32bit, Dwarf_Unsigned, word_ptrb, DWARF_32BIT_SIZE, error,sot->so_section_end_ptr); if (one32bit) { /* Found a value */ break; } offset += DWARF_32BIT_SIZE; } sot->so_wasted_section_bytes += (word_ptrb - word_ptra); *table_offset_out = offset; return DW_DLV_OK; } /* The minimum possible area .debug_str_offsets header . */ #define MIN_HEADER_LENGTH 8 /* New April 2018. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ int dwarf_next_str_offsets_table(Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned *unit_length_out, Dwarf_Unsigned *unit_length_offset_out, Dwarf_Unsigned *table_start_offset_out, Dwarf_Half *entry_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Unsigned *table_value_count_out, Dwarf_Error * error) { Dwarf_Small *table_start_ptr = 0; Dwarf_Small *table_end_ptr = 0; Dwarf_Unsigned table_offset = 0; Dwarf_Unsigned local_length_size = 0; UNUSEDARG Dwarf_Unsigned local_extension_size = 0; Dwarf_Unsigned length = 0; Dwarf_Half version = 0; Dwarf_Half padding = 0; int res = 0; VALIDATE_SOT(sot) res = find_next_str_offsets_tab(sot, sot->so_next_table_offset, &table_offset,error); if (res != DW_DLV_OK) { /* As a special case, if unused zero bytess at the end, count as wasted space. */ if (res == DW_DLV_NO_ENTRY) { if (table_offset > sot->so_next_table_offset) { sot->so_wasted_section_bytes += (table_offset - sot->so_next_table_offset); } } return res; } if (table_offset > sot->so_next_table_offset) { sot->so_wasted_section_bytes += (table_offset - sot->so_next_table_offset); } table_start_ptr = sot->so_section_start_ptr + table_offset; sot->so_header_ptr = table_start_ptr; if (table_start_ptr >= sot->so_section_end_ptr) { if (table_start_ptr == sot->so_section_end_ptr) { /* At end of section. Done. */ return DW_DLV_NO_ENTRY; } } if ((table_start_ptr + MIN_HEADER_LENGTH) > sot->so_section_end_ptr) { /* We have some nonsense non-zero extra bytes! Should we generate error? Or ignore? */ _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_EXTRA_BYTES); return DW_DLV_ERROR; } READ_AREA_LENGTH_CK(sot->so_dbg,length,Dwarf_Unsigned, table_start_ptr,local_length_size, local_extension_size,error, sot->so_section_size,sot->so_section_end_ptr); /* The 'length' part of any header is local_extension_size + local_length_size. Standard DWARF2 sums to 4. Standard DWARF3,4,5 sums to 4 or 12. Nonstandard SGI IRIX 64bit dwarf sums to 8 (SGI IRIX was all DWARF2 and could not have a .debug_str_offsets section). The header includes 2 bytes of version and two bytes of padding. */ /* table_start_ptr was incremented past the length data. */ table_end_ptr = table_start_ptr + length; READ_UNALIGNED_CK(sot->so_dbg, version, Dwarf_Half, table_start_ptr, DWARF_HALF_SIZE, error,sot->so_section_end_ptr); table_start_ptr += DWARF_HALF_SIZE; READ_UNALIGNED_CK(sot->so_dbg, padding, Dwarf_Half, table_start_ptr, DWARF_HALF_SIZE, error,sot->so_section_end_ptr); table_start_ptr += DWARF_HALF_SIZE; if (version != DW_STR_OFFSETS_VERSION5) { _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_VERSION_WRONG); return DW_DLV_ERROR; } /* So now table_start_ptr points to a table of local_length_size entries. Each entry in this table is local_length_size bytes long: 4 or 8. */ { Dwarf_Unsigned entrycount = 0; Dwarf_Unsigned entrybytes = 0; entrybytes = table_end_ptr - table_start_ptr; if (entrybytes % local_length_size) { _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_ARRAY_SIZE); return DW_DLV_ERROR; } entrycount = entrybytes/local_length_size; sot->so_next_table_offset = table_end_ptr - sot->so_section_start_ptr; sot->so_end_cu_ptr = table_end_ptr; sot->so_array_ptr = table_start_ptr; sot->so_table_start_offset = table_offset; sot->so_array_start_offset = table_start_ptr - sot->so_section_start_ptr; sot->so_array_entry_count = entrycount; sot->so_array_entry_size = local_length_size; sot->so_table_count += 1; /* The data length in bytes following the unit_length field of the header. */ *unit_length_out = length; /* Where the unit_length field starts in the section. */ *unit_length_offset_out = sot->so_table_start_offset; /* Where the table of offsets starts in the section. */ *table_start_offset_out = sot->so_array_start_offset; /* Entrysize: 4 or 8 */ *entry_size_out = local_length_size; /* Version is 5. */ *version_out = version; /* This is supposed to be zero. */ *padding_out = padding; /* How many entry_size entries are in the array. */ *table_value_count_out = entrycount; return DW_DLV_OK; } } /* Meant to be called after all tables accessed using dwarf_next_str_offsets_table(). */ int dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table table_data, Dwarf_Unsigned * wasted_byte_count, Dwarf_Unsigned * table_count, Dwarf_Error * error) { VALIDATE_SOT(table_data) if(wasted_byte_count) { *wasted_byte_count = table_data->so_wasted_section_bytes; } if(table_count) { *table_count = table_data->so_table_count; } return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_str_offsets.h000066400000000000000000000042771361531463500216410ustar00rootroot00000000000000#ifndef DWARF_STR_OFFSETS_H #define DWARF_STR_OFFSETS_H /* Copyright (C) 2018-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ struct Dwarf_Str_Offsets_Table_s { /* pointers are to dwarf-memory valid till Dwarf_Debug is closed.. None are to be deallocated. */ Dwarf_Unsigned so_magic_value; Dwarf_Debug so_dbg; /* Section data. */ Dwarf_Small *so_section_start_ptr; Dwarf_Small *so_section_end_ptr; Dwarf_Unsigned so_section_size; /* Overall data about wasted space in the section. */ Dwarf_Unsigned so_wasted_section_bytes; /* The number of tables processed in the section. */ Dwarf_Unsigned so_table_count; /* Used to iterate through the section getting to each table */ Dwarf_Unsigned so_next_table_offset; /* Per table (ie, a table is a header and array of offsets) inside the section. */ Dwarf_Small *so_header_ptr; Dwarf_Small *so_end_cu_ptr; Dwarf_Small *so_array_ptr; Dwarf_Unsigned so_table_start_offset; Dwarf_Unsigned so_array_start_offset; Dwarf_Unsigned so_array_entry_count; Dwarf_Half so_array_entry_size; }; #endif /* DWARF_STR_OFFSETS_H */ dwarfutils-20200114/libdwarf/dwarf_stringsection.c000066400000000000000000000051241361531463500221560ustar00rootroot00000000000000/* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_util.h" int dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, Dwarf_Signed * returned_str_len, Dwarf_Error * error) { int res = DW_DLV_ERROR; void *secptr = 0; void *begin = 0; void *end = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } 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). */ return DW_DLV_NO_ENTRY; } if (offset > dbg->de_debug_str.dss_size) { _dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD); return (DW_DLV_ERROR); } if (string == NULL) { _dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_str.dss_size) { return (DW_DLV_NO_ENTRY); } secptr =dbg->de_debug_str.dss_data; begin = (char *)secptr + offset; end = (char *)secptr + dbg->de_debug_str.dss_size; res = _dwarf_check_string_valid(dbg,secptr,begin,end, DW_DLE_DEBUG_STR_OFFSET_BAD,error); if (res != DW_DLV_OK) { return res; } *string = (char *) begin; *returned_str_len = strlen(*string); return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_test_errmsg_list.c000066400000000000000000000203331361531463500226530ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #include #ifdef HAVE_STDLIB_H #include /* For exit(), strtoul() declaration etc. */ #endif #include "dwarf_errmsg_list.h" #define FALSE 0 #define TRUE 1 /* This is just to help localize the error. */ static void printone(int i) { int arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); if ( i >= arraysize) { printf("%d is outside the array! Missing something!\n",i); } else { printf("%d is: %s\n",i,_dwarf_errmsgs[i]); } } /* Arbitrary. A much smaller max length value would work. */ #define MAX_NUM_LENGTH 12 /* return TRUE on error */ static int check_errnum_mismatches(unsigned i) { unsigned nextstop = 0; const char *sp = _dwarf_errmsgs[i]; const char *cp = sp; unsigned innit = FALSE; unsigned prevchar = 0; unsigned value = 0; for( ; *cp; cp++) { unsigned c = 0; c = 0xff & *cp; if ( c >= '0' && c <= '9' && !innit && prevchar != '(') { /* Skip. number part of macro name. */ prevchar = c; continue; } if ( c >= '0' && c <= '9') { value = value * 10; value += (c - '0'); nextstop++; if (nextstop > MAX_NUM_LENGTH) { break; } innit = TRUE; } else { if (innit) { break; } prevchar= c; } } if (innit) { if (i != value) { return TRUE; } return FALSE; } /* There is no number to check. Ignore it. */ printf("mismatch value %d has no errnum to check %s\n",i,_dwarf_errmsgs[i]); return TRUE; } /* We don't allow arbitrary DW_DLE line length. */ #define MAXDEFINELINE 200 static int splmatches(char *base, unsigned baselen,char *test) { if (baselen != strlen(test) ) { return FALSE; } for ( ; *test; ++test,++base) { if (*test != *base) { return FALSE; } } return TRUE; } static void check_dle_list(const char *path) { /* The format should be #definenamenumberoptional-c-comment and we are intentionally quite rigid about it all except that the number of spaces before any comment is allowed. */ char buffer[MAXDEFINELINE]; unsigned linenum = 0; unsigned long prevdefval = 0; unsigned foundlast = 0; unsigned foundlouser = 0; FILE*fin = 0; fin = fopen(path, "r"); if(!fin) { printf("Unable to open define list to read %s\n",path); exit(1); } for(;;++linenum) { char *line = 0; unsigned linelen = 0; char * curdefname = 0; char * pastname = 0; unsigned curdefname_len = 0; char *numstart = 0; char * endptr = 0; unsigned long v = 0; line = fgets(buffer,MAXDEFINELINE,fin); if(!line) { break; } linelen = strlen(line); if (linelen >= (unsigned)(MAXDEFINELINE-1)) { printf("define line %u is too long!\n",linenum); exit(1); } if(strncmp(line,"#define DW_DLE_",15)) { printf("define line %u has wrong leading chars!\n",linenum); exit(1); } curdefname = line+8; /* ASSERT: line ends with NUL byte. */ for( ; ; curdefname_len++) { if (foundlouser) { printf("define line %u has stuff after DW_DLE_LO_USER!\n", linenum); exit(1); } pastname = curdefname +curdefname_len; if (!*pastname) { /* At end of line. Missing value. */ printf("define line %u of %s: has no number value!\n", linenum,path); exit(1); } if (*pastname == ' ') { /* Ok. Now look for value. */ numstart = pastname + 1; break; } } /* strtoul skips leading whitespace. */ v = strtoul(numstart,&endptr,0); /* This test is a bit odd. But is valid till we decide it is inappropriate. */ if (v > DW_DLE_LO_USER) { printf("define line %u: number value unreasonable. %lu\n", linenum,v); exit(1); } if (v == 0 && endptr == numstart) { printf("define line %u of %s: number value missing.\n", linenum,path); printf("Leaving a space as in #define A B 3" " in libdwarf.h.in will cause this.\n"); exit(1); } if (*endptr != ' ' && *endptr != '\n') { printf("define line %u: number value terminates oddly\n", linenum); exit(1); } if (splmatches(curdefname,curdefname_len,"DW_DLE_LAST")) { if (foundlast) { printf("duplicated DW_DLE_LAST! line %u\n",linenum); exit(1); } foundlast = 1; if (v != prevdefval) { printf("Invalid: Last value mismatch! %lu vs %lu\n", v,prevdefval); } } else if (splmatches(curdefname,curdefname_len,"DW_DLE_LO_USER")) { if (!foundlast) { printf("error:expected DW_DLE_LO_USER after LAST! line %u\n", linenum); exit(1); } if (foundlouser) { printf("Error:duplicated DW_DLE_LO_USER! line %u\n", linenum); exit(1); } foundlouser = 1; continue; } else { if (linenum > 0) { if (v != prevdefval+1) { printf("Invalid: Missing value! %lu vs %lu\n", prevdefval,v); exit(1); } } prevdefval = v; } /* Ignoring rest of line for now. */ } fclose(fin); } int main(int argc, char **argv) { unsigned arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); unsigned i = 0; const char *path = 0; if (argc != 3) { printf("Expected -f of DW_DLE lines from libdwarf.h"); exit(1); } if (strcmp(argv[1],"-f")) { printf("Expected -f"); exit(1); } path = argv[2]; check_dle_list(path); if (arraysize != (DW_DLE_LAST + 1)) { printf("Missing or extra entry in dwarf error strings array" " %u expected DW_DLE_LAST+1 %d\n",arraysize, DW_DLE_LAST+1); printone(1); printone(100); printone(200); printone(250); printone(260); printone(262); printone(263); printone(264); printone(265); printone(273); printone(274); printone(275); printone(300); printone(328); exit(1); } for ( i = 0; i <= DW_DLE_LAST; ++i) { if(check_errnum_mismatches(i)) { printf("mismatch value %d is: %s\n",i,_dwarf_errmsgs[i]); exit(1); } } /* OK. */ exit(0); } dwarfutils-20200114/libdwarf/dwarf_tied.c000066400000000000000000000171031361531463500202100ustar00rootroot00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #ifdef HAVE_STDLIB_H #include /* for free(). */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include /* For debugging. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "dwarf_tied_decls.h" #define TRUE 1 #define FALSE 0 void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) { const char *sigv = 0; unsigned u = 0; printf("%s 0x",msg); sigv = &sig->signature[0]; for (u = 0; u < 8; u++) { printf("%02x",0xff&sigv[u]); } printf(" line %d\n",lineno); } void * _dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val) { struct Dwarf_Tied_Entry_s *e = 0; e = calloc(1,sizeof(struct Dwarf_Tied_Entry_s)); if(e) { e->dt_key = *key; e->dt_context = val; } return e; } /* Tied data Key is Dwarf_Sig8. A hash needed because we are using a hash search here. Would not be needed for the other tree searchs like balanced trees.. */ DW_TSHASHTYPE _dwarf_tied_data_hashfunc(const void *keyp) { const struct Dwarf_Tied_Entry_s * enp = keyp; DW_TSHASHTYPE hashv = 0; /* Just take some of the 8 bytes of the signature. */ memcpy(&hashv,enp->dt_key.signature,sizeof(hashv)); return hashv; } int _dwarf_tied_compare_function(const void *l, const void *r) { const struct Dwarf_Tied_Entry_s * lp = l; const struct Dwarf_Tied_Entry_s * rp = r; const char *lcp = (const char *)&lp->dt_key.signature; const char *rcp = (const char *)&rp->dt_key.signature; const char *lcpend = lcp + sizeof(Dwarf_Sig8); for(; lcp < lcpend; ++lcp,++rcp) { if (*lcp < *rcp) { return -1; } else if (*lcp > *rcp) { return 1; } } /* match. */ return 0; } void _dwarf_tied_destroy_free_node(void*nodep) { struct Dwarf_Tied_Entry_s * enp = nodep; free(enp); return; } /* This presumes only we are reading the debug_info CUs from tieddbg. That is a reasonable requirement, one hopes. Currently it reads all the tied CUs at once, unless there is an error.. */ int _dwarf_loop_reading_debug_info_for_cu( Dwarf_Debug tieddbg, Dwarf_Sig8 sig, Dwarf_Error *error) { unsigned loop_count = 0; /* We will not find tied signatures for .debug_addr (or line tables) in .debug_types. it seems. Those signatures point from 'normal' to 'dwo/dwp' (DWARF4) */ int is_info = TRUE; Dwarf_CU_Context startingcontext = 0; Dwarf_Unsigned next_cu_offset = 0; startingcontext = tieddbg->de_info_reading.de_cu_context; if (startingcontext) { next_cu_offset = startingcontext->cc_debug_offset + startingcontext->cc_length + startingcontext->cc_length_size + startingcontext->cc_extension_size; } for (;;++loop_count) { int sres = DW_DLV_OK; Dwarf_Half cu_type = 0; Dwarf_CU_Context latestcontext = 0; Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Half extension_size = 0; Dwarf_Half length_size = 0; Dwarf_Sig8 signature; Dwarf_Bool has_signature = FALSE; Dwarf_Unsigned typeoffset = 0; memset(&signature,0,sizeof(signature)); sres = _dwarf_next_cu_header_internal(tieddbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &length_size,&extension_size, &signature, &has_signature, &typeoffset, &next_cu_offset, &cu_type, error); if (sres == DW_DLV_NO_ENTRY) { break; } latestcontext = tieddbg->de_info_reading.de_cu_context; if (has_signature) { void *retval = 0; Dwarf_Sig8 consign = latestcontext->cc_signature; void *entry = _dwarf_tied_make_entry(&consign,latestcontext); if (!entry) { return DW_DLV_NO_ENTRY; } /* Insert this signature and context. */ retval = dwarf_tsearch(entry, &tieddbg->de_tied_data.td_tied_search, _dwarf_tied_compare_function); if (!retval) { /* FAILED might be out of memory.*/ return DW_DLV_NO_ENTRY; } #if 0 /* FIXME: do this? Not? */ /* This could be a compiler error. But let us not decide? FIXME */ if (!latestcontext->cc_addr_base_present) { } #endif if (!_dwarf_tied_compare_function(&sig,&consign) ) { /* Identical. We found the matching CU. */ return DW_DLV_OK; } } } /* Apparently we never found the sig we are looking for. Pretend ok. Caller will check for success. */ return DW_DLV_OK; } /* If out of memory just return DW_DLV_NO_ENTRY. */ int _dwarf_search_for_signature(Dwarf_Debug tieddbg, Dwarf_Sig8 sig, Dwarf_CU_Context *context_out, Dwarf_Error *error) { void *entry2 = 0; struct Dwarf_Tied_Entry_s entry; struct Dwarf_Tied_Data_s * tied = &tieddbg->de_tied_data; int res = 0; if (!tied->td_tied_search) { dwarf_initialize_search_hash(&tied->td_tied_search, _dwarf_tied_data_hashfunc,0); if (!tied->td_tied_search) { return DW_DLV_NO_ENTRY; } } entry.dt_key = sig; entry.dt_context = 0; entry2 = dwarf_tfind(&entry, &tied->td_tied_search, _dwarf_tied_compare_function); if (entry2) { struct Dwarf_Tied_Entry_s *e2 = *(struct Dwarf_Tied_Entry_s **)entry2; *context_out = e2->dt_context; return DW_DLV_OK; } /* We assume the caller is NOT doing info section read operations on the tieddbg. */ res = _dwarf_loop_reading_debug_info_for_cu( tieddbg,sig,error); if (res == DW_DLV_ERROR) { return res; } entry2 = dwarf_tfind(&entry, &tied->td_tied_search, _dwarf_tied_compare_function); if (entry2) { struct Dwarf_Tied_Entry_s *e2 = *(struct Dwarf_Tied_Entry_s **)entry2; *context_out = e2->dt_context; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } dwarfutils-20200114/libdwarf/dwarf_tied_decls.h000066400000000000000000000034341361531463500213710ustar00rootroot00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define HASHSEARCH #ifdef HASHSEARCH /* Only needed for hash based search in a tsearch style. */ #define INITTREE(x,y) x = dwarf_initialize_search_hash(&(x),(y),0) #else #define INITTREE(x,y) #endif /* HASHSEARCH */ /* Contexts are in a list in a dbg and do not move once established. So saving one is ok. as long as the dbg exists. */ struct Dwarf_Tied_Entry_s { Dwarf_Sig8 dt_key; Dwarf_CU_Context dt_context; }; int _dwarf_tied_compare_function(const void *l, const void *r); void * _dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val); DW_TSHASHTYPE _dwarf_tied_data_hashfunc(const void *keyp); int _dwarf_loop_reading_debug_info_for_cu( Dwarf_Debug tieddbg, Dwarf_Sig8 sig, Dwarf_Error *error); dwarfutils-20200114/libdwarf/dwarf_tied_test.c000066400000000000000000000134371361531463500212550ustar00rootroot00000000000000/* Copyright (C) 2015-2015 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" #ifdef HAVE_STDLIB_H #include /* for free(). */ #endif /* HAVE_STDLIB_H */ #include /* For debugging. */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "dwarf_tsearch.h" #include "dwarf_tied_decls.h" #define TRUE 1 #define FALSE 0 #define TRUE 1 #define FALSE 0 struct test_data_s { const char action; unsigned long val; } testdata[] = { {'a', 0x33c8}, {'a', 0x34d8}, {'a', 0x35c8}, {'a', 0x3640}, {'a', 0x3820}, {'a', 0x38d0}, {'a', 0x3958}, {'a', 0x39e8}, {'a', 0x3a78}, {'a', 0x3b08}, {'a', 0x3b98}, {'a', 0x3c28}, {'a', 0x3cb8}, {'d', 0x3c28}, {'a', 0x3d48}, {'d', 0x3cb8}, {'a', 0x3dd8}, {'d', 0x3d48}, {'a', 0x3e68}, {'d', 0x3dd8}, {'a', 0x3ef8}, {'a', 0x3f88}, {'d', 0x3e68}, {'a', 0x4018}, {'d', 0x3ef8}, {0,0} }; /* We don't test this here, referenced from dwarf_tied.c. */ int _dwarf_next_cu_header_internal( UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Bool is_info, UNUSEDARG Dwarf_Unsigned * cu_header_length, UNUSEDARG Dwarf_Half * version_stamp, UNUSEDARG Dwarf_Unsigned * abbrev_offset, UNUSEDARG Dwarf_Half * address_size, UNUSEDARG Dwarf_Half * offset_size, UNUSEDARG Dwarf_Half * extension_size, UNUSEDARG Dwarf_Sig8 * signature, UNUSEDARG Dwarf_Bool * has_signature, UNUSEDARG Dwarf_Unsigned *typeoffset, UNUSEDARG Dwarf_Unsigned * next_cu_offset, UNUSEDARG Dwarf_Half * header_cu_type, UNUSEDARG Dwarf_Error * error) { return DW_DLV_NO_ENTRY; } static struct Dwarf_Tied_Entry_s * makeentry(unsigned long instance, unsigned ct) { Dwarf_Sig8 s8; Dwarf_CU_Context context = 0; struct Dwarf_Tied_Entry_s * entry = 0; memset(&s8,0,sizeof(s8)); /* Silly, but just a test...*/ memcpy(&s8,&instance,sizeof(instance)); context = (Dwarf_CU_Context)instance; entry = (struct Dwarf_Tied_Entry_s *) _dwarf_tied_make_entry(&s8,context); if (!entry) { printf("Out of memory in test! %u\n",ct); exit(1); } return entry; } static int insone(void**tree,unsigned long instance, unsigned ct) { struct Dwarf_Tied_Entry_s * entry = 0; void *retval = 0; entry = makeentry(instance, ct); retval = dwarf_tsearch(entry,tree, _dwarf_tied_compare_function); if(retval == 0) { printf("FAIL ENOMEM in search on rec %u adr 0x%lu," " error in insone\n", ct,(unsigned long)instance); exit(1); } else { struct Dwarf_Tied_Entry_s *re = 0; re = *(struct Dwarf_Tied_Entry_s **)retval; if(re != entry) { /* Found existing, error. */ printf("insertone rec %u addr 0x%lu found record" " preexisting, error\n", ct,(unsigned long)instance); _dwarf_tied_destroy_free_node(entry); exit(1); } else { /* inserted new entry, make sure present. */ struct Dwarf_Tied_Entry_s * entry2 = 0; entry2 = makeentry(instance,ct); retval = dwarf_tfind(entry2,tree, _dwarf_tied_compare_function); _dwarf_tied_destroy_free_node(entry2); if(!retval) { printf("insertonebypointer record %d addr 0x%lu " "failed to add as desired," " error\n", ct,(unsigned long)instance); exit(1); } } } return 0; } static int delone(void**tree,unsigned long instance, unsigned ct) { struct Dwarf_Tied_Entry_s * entry = 0; void *r = 0; entry = makeentry(instance, ct); r = dwarf_tfind(entry,(void *const*)tree, _dwarf_tied_compare_function); if (r) { struct Dwarf_Tied_Entry_s *re3 = *(struct Dwarf_Tied_Entry_s **)r; re3 = *(struct Dwarf_Tied_Entry_s **)r; dwarf_tdelete(entry,tree,_dwarf_tied_compare_function); _dwarf_tied_destroy_free_node(entry); _dwarf_tied_destroy_free_node(re3); } else { printf("delone could not find rec %u ! error! addr" " 0x%lx\n", ct,(unsigned long)instance); exit(1) ; } return 0; } int main() { void *tied_data = 0; unsigned u = 0; INITTREE(tied_data,_dwarf_tied_data_hashfunc); for ( ; testdata[u].action; ++u) { char action = testdata[u].action; unsigned long v = testdata[u].val; if (action == 'a') { insone(&tied_data,v,u); } else if (action == 'd') { delone(&tied_data,v,u); } else { printf("FAIL testtied on action %u, " "not a or d\n",action); exit(1); } } printf("PASS tsearch works for Dwarf_Tied_Entry_s.\n"); return 0; } dwarfutils-20200114/libdwarf/dwarf_tsearch.h000066400000000000000000000104331361531463500207200ustar00rootroot00000000000000#ifndef DWARF_TSEARCH_H #define DWARF_TSEARCH_H /* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The following interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source code of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. See https://www.prevanders.net/tsearch.html and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional interface here, but to avoid interfering with libc implementations or code using libc implementations, we change all the names. */ /* configure/cmake ensure uintptr_t defined, but if not, possibly "-Duintptr_t=unsigned long" might help */ #ifndef DW_TSHASHTYPE #define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through the callback function in dwarf_twalk(); */ typedef enum { dwarf_preorder, dwarf_postorder, dwarf_endorder, dwarf_leaf } DW_VISIT; /* void * return values are actually void **key so you must dereference these once to get a key you passed in. */ /* We rename these so there is no conflict with another version of the tsearch sources, such as is used in dwarfdump. */ #define dwarf_tsearch _dwarf_tsearch #define dwarf_tfind _dwarf_tfind #define dwarf_tdelete _dwarf_tdelete #define dwarf_twalk _dwarf_twalk #define dwarf_tdestroy _dwarf_tdestroy #define dwarf_tdump _dwarf_tdump #define dwarf_initialize_search_hash _dwarf_initialize_search_hash void *dwarf_tsearch(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void *dwarf_tfind(const void * /*key*/, void *const * /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* dwarf_tdelete() returns NULL if it cannot delete anything or if the tree is now empty (if empty, *rootp is set NULL by dwarf_tdelete()). If the delete succeeds and the tree is non-empty returns a pointer to the parent node of the deleted item, unless the deleted item was at the root, in which case the returned pointer relates to the new root. */ void *dwarf_tdelete(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void dwarf_twalk(const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); /* dwarf_tdestroy() cannot set the root pointer NULL, you must do so on return from dwarf_tdestroy(). */ void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, char *(* /*keyprint*/)(const void *), const char *msg); /* Returns NULL and does nothing unless the implemenation used uses a hash tree. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); #endif /* DWARF_TSEARCH_H */ dwarfutils-20200114/libdwarf/dwarf_tsearchhash.c000066400000000000000000000467111361531463500215670ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch or any hashing code. An additional interface is added (compared to a real tsearch) to let the caller identify a 'hash' function with each hash table (called a tree below, but that is a misnomer). So read 'tree' below as hash table. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.4 This uses a hash based on the key. Collision resolution is by chaining. twalk() and tdestroy() walk in a random order. The 'preorder' etc labels mean nothing in a hash, so everything is called a leaf. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #ifdef HAVE_STDLIB_H #include "stdlib.h" /* for malloc, free() etc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include /* for printf() */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DUu "I64u" #else #define DW_PR_DUx "llx" #define DW_PR_DUu "llu" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* A table of primes used to size and resize the hash table. From public sources of prime numbers, arbitrarily chosen to approximately double in size at each step. */ static unsigned long primes[] = { #if 0 /* for testing only */ 5,11, 17,23, 31, 47, 53, #endif 79, 1009, 5591, 10007, 21839, 41413, 99907, 199967, 400009, 800029, 1600141, 3000089, 6000121, 12000257, 24000143, 48000203, 100000127, 200001611, 400000669, 800000573, 0 /* Here we are giving up */ }; static unsigned long allowed_fill_percent = 90; struct hs_base { unsigned long tablesize_; unsigned long tablesize_entry_index_; unsigned long allowed_fill_; /* Record_count means number of active records, counting all records on chains. When the record_count is > 90% of a full tablesize_ we redo the table before adding a new entry. */ unsigned long record_count_; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ struct ts_entry * hashtab_; DW_TSHASHTYPE (*hashfunc_)(const void *key); }; struct ts_entry { const void * keyptr; /* So that a keyptr of 0 (if added) is not confused with an empty hash slot, we must mark used slots as used in the hash tab */ unsigned char entryused; struct ts_entry *next; }; enum search_intent_t { want_insert, only_find, want_delete }; static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, struct ts_entry **parent_ptr); static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), int depth); /* A trivial integer-based percentage calculation. Percents >100 are reasonable for a hash-with-chains situation (even if they might not be the best choice for performance). */ static unsigned long calculate_allowed_fill(unsigned long fill_percent, unsigned long ct) { unsigned long v = 0; if(ct < 100000) { unsigned long v2 = (ct *fill_percent)/100; return v2; } v = (ct /100)*fill_percent; return v; } /* Initialize the hash and pass in the hash function. If the entry count needed is unknown, pass in 0 as a count estimate, but if the number of hash entries needed can be estimated, pass in the estimate (which need not be prime, we actually use the nearest higher prime from the above table). If the estimated count is Return the tree base, or return NULL if insufficient memory. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE(*hashfunc)(const void *key), unsigned long size_estimate) { unsigned long prime_to_use = primes[0]; unsigned entry_index = 0; unsigned k = 0; struct hs_base *base = 0; base = *(struct hs_base **)treeptr; if(base) { /* initalized already. */ return base ; } base = calloc(sizeof(struct hs_base),1); if(!base) { /* Out of memory. */ return NULL ; } prime_to_use = primes[0]; while(size_estimate && (size_estimate > prime_to_use)) { k = k +1; prime_to_use = primes[k]; if(prime_to_use == 0) { /* Oops. Too large. */ free(base); return NULL; } entry_index = k; } base->tablesize_ = prime_to_use; base->allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if( base->allowed_fill_< (base->tablesize_/2)) { free(base); /* Oops. We are in trouble. Coding mistake here. */ return NULL; } base->record_count_ = 0; base->tablesize_entry_index_ = entry_index; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ base->hashfunc_ = hashfunc; base->hashtab_ = calloc(sizeof(struct ts_entry),base->tablesize_); if(!base->hashtab_) { free(base); return NULL; } *treeptr = base; return base; } /* We don't really care whether hashpos or chainpos are 32 or 64 bits. 32 suffices. */ static void print_entry(struct ts_entry *t,const char *descr, char *(* keyprint)(const void *), unsigned long hashpos, unsigned long chainpos) { char *v = 0; if(!t->entryused) { return; } v = keyprint(t->keyptr); printf( "[%4lu.%02lu] 0x%08" DW_PR_DUx " %s\n", hashpos,chainpos, (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, v, descr); } /* For debugging */ static void dumptree_inner(const struct hs_base *h, char *(* keyprint)(const void *), const char *descr, int printdetails) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; unsigned long hashused = 0; unsigned long maxchainlength = 0; unsigned long chainsgt1 = 0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " size %" DW_PR_DUu " entries %" DW_PR_DUu " allowed %" DW_PR_DUu " %s\n", (Dwarf_Unsigned)(uintptr_t)h, (Dwarf_Unsigned)h->tablesize_, (Dwarf_Unsigned)h->record_count_, (Dwarf_Unsigned)h->allowed_fill_, descr); for( ; ix < tsize; ix++,p++) { unsigned long chainlength = 0; struct ts_entry*n = 0; int chainpos = 0; if(p->entryused) { ++hashused; chainlength = 1; if(printdetails) { print_entry(p,"head",keyprint,ix,chainpos); } } chainpos++; for(n = p->next; n ; n = n->next) { chainlength++; if(printdetails) { print_entry(n,"chain",keyprint,ix,chainpos); } } if(chainlength > maxchainlength) { maxchainlength = chainlength; } if (chainlength > 1) { chainsgt1++; } } printf("Hashtable: %lu of %lu hash entries used.\n",hashused,tsize); printf("Hashtable: %lu chains length longer than 1. \n",chainsgt1); printf("Hashtable: %lu is maximum chain length.\n",maxchainlength); } /* Dumping the tree. */ void dwarf_tdump(const void*headp_in, char *(* keyprint)(const void *), const char *msg) { const struct hs_base *head = (const struct hs_base *)headp_in; if(!head) { printf("dumptree null tree ptr : %s\n",msg); return; } dumptree_inner(head,keyprint,msg,1); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } e->keyptr = key; e->entryused = 1; e->next = 0; return e; } static void resize_table(struct hs_base *head, int (*compar)(const void *, const void *)) { struct hs_base newhead; unsigned new_entry_index = 0; unsigned long prime_to_use = 0; /* Copy the values we have. */ newhead = *head; /* But drop the hashtab_ from new. calloc below. */ newhead.hashtab_ = 0; newhead.record_count_ = 0; new_entry_index = head->tablesize_entry_index_ +1; prime_to_use = primes[new_entry_index]; if(prime_to_use == 0) { /* Oops, too large. Leave table size as is, though it will get slow as it overfills. */ return; } newhead.tablesize_ = prime_to_use; newhead.allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if( newhead.allowed_fill_< (newhead.tablesize_/2)) { /* Oops. We are in trouble. */ return; } newhead.tablesize_entry_index_ = new_entry_index; newhead.hashtab_ = calloc(sizeof(struct ts_entry),newhead.tablesize_); if(!newhead.hashtab_) { /* Oops, too large. Leave table size as is, though things will get slow as it overfills. */ free(newhead.hashtab_); return; } { /* Insert all the records from the old table into the new table. */ int fillnewfail = 0; unsigned long ix = 0; unsigned long tsize = head->tablesize_; struct ts_entry *p = &head->hashtab_[0]; for( ; ix < tsize; ix++,p++) { int inserted = 0; struct ts_entry*n = 0; if(fillnewfail) { break; } if(p->keyptr) { tsearch_inner(p->keyptr, &newhead,compar, want_insert, &inserted, 0); if(!inserted) { fillnewfail = 1; break; } } for(n = p->next; n ; n = n->next) { inserted = 0; tsearch_inner(n->keyptr, &newhead,compar, want_insert, &inserted, 0); if(!inserted) { fillnewfail = 1; break; } } } if(fillnewfail) { free(newhead.hashtab_); return; } } /* Now get rid of the chain entries of the old table. */ dwarf_tdestroy_inner(head,0,0); /* Now get rid of the old table itself. */ free(head->hashtab_); head->hashtab_ = 0; *head = newhead; return; } /* Inner search of the hash and synonym chains. */ static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, /* owner_ptr used for delete. Only set if the to-be-deleted item is on a chain, not in the hashtab. Points to the item pointing to the to-be-deleted-item.*/ struct ts_entry **owner_ptr) { struct ts_entry *s =0; struct ts_entry *c =0; struct ts_entry *q =0; int kc = 0; DW_TSHASHTYPE keyhash = 0; DW_TSHASHTYPE hindx = 0; struct ts_entry *chain_parent = 0; if(! head->hashfunc_) { /* Not fully initialized. */ return NULL; } keyhash = head->hashfunc_(key); if (intent == want_insert) { if( head->record_count_ > head->allowed_fill_) { resize_table(head,compar); } } hindx = keyhash%head->tablesize_; s = &head->hashtab_[hindx]; if(!s->entryused) { /* Not found. */ if(intent != want_insert) { return NULL; } /* Insert in the base hash table in an empty slot. */ *inserted = 1; head->record_count_++; s->keyptr = (const void *)key; s->entryused = 1; s->next = 0; return s; } kc = compar(key,s->keyptr); if(kc == 0 ) { /* found! */ if(want_delete) { *owner_ptr = 0; } return (void *)&(s->keyptr); } chain_parent = s; for(c = s->next; c; c = c->next) { kc = compar(key,c->keyptr); if(kc == 0 ) { /* found! */ if(want_delete) { *owner_ptr = chain_parent; } return (void *)&(c->keyptr); } chain_parent = c; } if(intent != want_insert) { return NULL; } /* Insert following head record of the chain. */ q = allocate_ts_entry(key); if (!q) { return q; } q->next = s->next; s->next = q; head->record_count_++; *inserted = 1; return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct hs_base **rootp = (struct hs_base **)headin; struct hs_base *head = *rootp; struct ts_entry *r = 0; int inserted = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!head) { /* something is wrong here, not initialized. */ return NULL; } r = tsearch_inner(key,head,compar,want_insert,&inserted,&nullme); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const *rootp, int (*compar)(const void *, const void *)) { /* Nothing will change, but we discard const so we can use tsearch_inner(). */ struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *r = 0; /* inserted flag won't be set. */ int inserted = 0; /* nullme won't be set. */ struct ts_entry * nullme = 0; /* Get to actual tree. */ if (!head) { return NULL; } r = tsearch_inner(key,head,compar,only_find,&inserted,&nullme); if(!r) { return NULL; } return (void *)(&(r->keyptr)); } /* Unlike the simple binary tree case, a fully-empty hash situation does not null the *rootp */ void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *found = 0; /* inserted flag won't be set. */ int inserted = 0; struct ts_entry * parentp = 0; if (!head) { return NULL; } found = tsearch_inner(key,head,compar,want_delete,&inserted, &parentp); if(found) { if(parentp) { /* Delete a chain entry. */ head->record_count_--; parentp->next = found->next; /* We free our storage. It would be up to caller to do a tfind to find a record and delete content if necessary. */ free(found); return (void *)&(parentp->keyptr); } /* So found is the head of a chain. */ if(found->next) { /* Delete a chain entry, pull up to hash tab, freeing up the chain entry. */ struct ts_entry *pullup = found->next; *found = *pullup; free(pullup); head->record_count_--; return (void *)&(found->keyptr); } else { /* Delete a main hash table entry. Problem: what the heck to return as a keyptr pointer? Well, we return NULL. As in the standard tsearch, returning NULL does not mean failure! Here it just means 'empty chain somewhere'. */ head->record_count_--; found->next = 0; found->keyptr = 0; found->entryused = 0; return NULL; } } return NULL; } static void dwarf_twalk_inner(const struct hs_base *h, struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth), UNUSEDARG unsigned level) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; for( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; if(p->keyptr) { action((void *)(&(p->keyptr)),dwarf_leaf,level); } for(n = p->next; n ; n = n->next) { action((void *)(&(n->keyptr)),dwarf_leaf,level); } } } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth)) { const struct hs_base *head = (const struct hs_base *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->hashtab_; /* Get to actual tree. */ dwarf_twalk_inner(head,root,action,0); } static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), UNUSEDARG int depth) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; for( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; struct ts_entry*prev = 0; if(p->keyptr && p->entryused) { if(free_node) { free_node((void *)(p->keyptr)); } --h->record_count_; } /* Now walk and free up the chain entries. */ for(n = p->next; n ; ) { if(free_node) { free_node((void *)(n->keyptr)); } --h->record_count_; prev = n; n = n->next; free(prev); } } } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct hs_base *head = (struct hs_base *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->hashtab_; dwarf_tdestroy_inner(head,free_node,0); free(root); free(head); } dwarfutils-20200114/libdwarf/dwarf_types.c000066400000000000000000000067151361531463500204360ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_types.h" #include "dwarf_global.h" int dwarf_get_types(Dwarf_Debug dbg, Dwarf_Type ** types, Dwarf_Signed * ret_type_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_typenames,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_typenames.dss_size) { return (DW_DLV_NO_ENTRY); } return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_typenames.dss_data, dbg->de_debug_typenames.dss_size, (Dwarf_Global **) types, /* type punning, Dwarf_Type is never a completed type */ ret_type_count, error, DW_DLA_TYPENAME_CONTEXT, DW_DLA_TYPENAME, DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD, DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_types_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_TYPENAME_CONTEXT, DW_DLA_TYPENAME, DW_DLA_LIST); return; } int dwarf_typename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; if (type == NULL) { _dwarf_error(NULL, error, DW_DLE_TYPE_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (type->gl_name); return DW_DLV_OK; } int dwarf_type_die_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_die_offset(type, ret_offset, error); } int dwarf_type_cu_offset(Dwarf_Type type_in, Dwarf_Off * ret_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_cu_offset(type, ret_offset, error); } int dwarf_type_name_offsets(Dwarf_Type type_in, char **returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_die_offset, Dwarf_Error * error) { Dwarf_Global type = (Dwarf_Global) type_in; return dwarf_global_name_offsets(type, returned_name, die_offset, cu_die_offset, error); } dwarfutils-20200114/libdwarf/dwarf_types.h000066400000000000000000000022521361531463500204330ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Type_Context_s *Dwarf_Type_Context; /* type never completed see dwarf_global.h */ dwarfutils-20200114/libdwarf/dwarf_util.c000066400000000000000000001252421361531463500202440ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include #ifdef HAVE_STDLIB_H #include /* For free() and emergency abort() */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_UNISTD_H #include #elif defined(_WIN32) && defined(_MSC_VER) #include #endif /* HAVE_UNISTD_H */ #include /* for open() */ #include /* for open() */ #include /* for open() */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_abbrev.h" #include "memcpy_swap.h" #include "dwarf_die_deliv.h" #include "pro_encode_nm.h" #ifndef O_BINARY #define O_BINARY 0 #endif /* O_BINARY */ #define MINBUFLEN 1000 #define TRUE 1 #define FALSE 0 #if _WIN32 #define NULL_DEVICE_NAME "NUL" #else #define NULL_DEVICE_NAME "/dev/null" #endif /* _WIN32 */ /* The function returned allows dwarfdump and other callers to do an endian-sensitive copy-word with a chosen source-length. */ typedef void (*endian_funcp_type)(void *, const void *,unsigned long); const char * dwarf_package_version(void) { return PACKAGE_VERSION; } #if 0 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 endian_funcp_type dwarf_get_endian_copy_function(Dwarf_Debug dbg) { if (dbg) { return dbg->de_copy_word; } return 0; } Dwarf_Bool _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg) { if(!dbg) { return FALSE; } if (dbg->de_cu_hashindex_data) { return TRUE; } return FALSE; } Dwarf_Bool _dwarf_file_has_debug_fission_tu_index(Dwarf_Debug dbg) { if(!dbg) { return FALSE; } if (dbg->de_tu_hashindex_data ) { return TRUE; } return FALSE; } Dwarf_Bool _dwarf_file_has_debug_fission_index(Dwarf_Debug dbg) { if(!dbg) { return FALSE; } if (dbg->de_cu_hashindex_data || dbg->de_tu_hashindex_data) { return 1; } return FALSE; } int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out, const char **compname_out, Dwarf_Error *error) { Dwarf_Attribute comp_dir_attr = 0; Dwarf_Attribute comp_name_attr = 0; int resattr = 0; Dwarf_Debug dbg = 0; dbg = die->di_cu_context->cc_dbg; resattr = dwarf_attr(die, DW_AT_name, &comp_name_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *name = 0; cres = dwarf_formstring(comp_name_attr, &name, error); if (cres == DW_DLV_ERROR) { dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR); return cres; } else if (cres == DW_DLV_OK) { *compname_out = (const char *)name; } else { /* FALL thru */ } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR); } resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *cdir = 0; cres = dwarf_formstring(comp_dir_attr, &cdir, error); if (cres == DW_DLV_ERROR) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); return cres; } else if (cres == DW_DLV_OK) { *compdir_out = (const char *) cdir; } else { /* FALL thru */ } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); } return resattr; } /* Given a form, and a pointer to the bytes encoding a value of that form, val_ptr, this function returns the length, in bytes, of a value of that form. When using this function, check for a return of 0 a recursive DW_FORM_INDIRECT value. */ int _dwarf_get_size_of_val(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Half cu_version, Dwarf_Half address_size, Dwarf_Small * val_ptr, int v_length_size, Dwarf_Unsigned *size_out, Dwarf_Small *section_end_ptr, Dwarf_Error*error) { Dwarf_Unsigned length = 0; Dwarf_Unsigned leb128_length = 0; Dwarf_Unsigned form_indirect = 0; Dwarf_Unsigned ret_value = 0; switch (form) { /* When we encounter a FORM here that we know about but forgot to enter here, we had better not just continue. Usually means we forgot to update this function when implementing form handling of a new FORM. Disaster results from using a bogus value, so generate error. */ default: _dwarf_error(dbg,error,DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE); return DW_DLV_ERROR; case 0: return DW_DLV_OK; case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: *size_out = v_length_size; return DW_DLV_OK; case DW_FORM_addr: if (address_size) { *size_out = address_size; } else { /* This should never happen, address_size should be set. */ *size_out = dbg->de_pointer_size; } return DW_DLV_OK; case DW_FORM_ref_sig8: *size_out = 8; /* sizeof Dwarf_Sig8 */ return DW_DLV_OK; /* DWARF2 was wrong on the size of the attribute for DW_FORM_ref_addr. We assume compilers are using the corrected DWARF3 text (for 32bit pointer target objects pointer and offsets are the same size anyway). It is clear (as of 2014) that for 64bit folks used the V2 spec in the way V2 was written, so the ref_addr has to account for that.*/ case DW_FORM_ref_addr: if (cu_version == DW_CU_VERSION2) { *size_out = address_size; } else { *size_out = v_length_size; } return DW_DLV_OK; case DW_FORM_block1: { ptrdiff_t sizeasptrdiff = 0; if (val_ptr >= section_end_ptr) { _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); return DW_DLV_ERROR; } ret_value = *(Dwarf_Small *) val_ptr; sizeasptrdiff = (ptrdiff_t)ret_value; if (sizeasptrdiff > (section_end_ptr - val_ptr) || sizeasptrdiff < 0) { _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); return DW_DLV_ERROR; } *size_out = ret_value +1; } return DW_DLV_OK; case DW_FORM_block2: { ptrdiff_t sizeasptrdiff = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, val_ptr, DWARF_HALF_SIZE,error,section_end_ptr); sizeasptrdiff = (ptrdiff_t)ret_value; if (sizeasptrdiff > (section_end_ptr - val_ptr) || sizeasptrdiff < 0) { _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); return DW_DLV_ERROR; } *size_out = ret_value + DWARF_HALF_SIZE; } return DW_DLV_OK; case DW_FORM_block4: { ptrdiff_t sizeasptrdiff = 0; READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, val_ptr, DWARF_32BIT_SIZE, error,section_end_ptr); sizeasptrdiff = (ptrdiff_t)ret_value; if (sizeasptrdiff > (section_end_ptr - val_ptr) || sizeasptrdiff < 0) { _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); return DW_DLV_ERROR; } *size_out = ret_value + DWARF_32BIT_SIZE; } return DW_DLV_OK; case DW_FORM_data1: *size_out = 1; return DW_DLV_OK; case DW_FORM_data2: *size_out = 2; return DW_DLV_OK; case DW_FORM_data4: *size_out = 4; return DW_DLV_OK; case DW_FORM_data8: *size_out = 8; return DW_DLV_OK; case DW_FORM_data16: *size_out = 16; return DW_DLV_OK; case DW_FORM_string: { int res = 0; res = _dwarf_check_string_valid(dbg,val_ptr, val_ptr, section_end_ptr, DW_DLE_FORM_STRING_BAD_STRING, error); if ( res != DW_DLV_OK) { return res; } } *size_out = strlen((char *) val_ptr) + 1; return DW_DLV_OK; case DW_FORM_block: case DW_FORM_exprloc: { DECODE_LEB128_UWORD_LEN_CK(val_ptr,length,leb128_length, dbg,error,section_end_ptr); *size_out = length + leb128_length; return DW_DLV_OK;; } case DW_FORM_flag_present: *size_out = 0; return DW_DLV_OK; case DW_FORM_flag: *size_out = 1; return DW_DLV_OK; case DW_FORM_sec_offset: /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */ *size_out = v_length_size; return DW_DLV_OK; case DW_FORM_ref_udata: { UNUSEDARG Dwarf_Unsigned v = 0; /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_UWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK;; } case DW_FORM_indirect: { Dwarf_Unsigned indir_len = 0; int res = 0; Dwarf_Unsigned info_data_len = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,form_indirect,indir_len, dbg,error,section_end_ptr); if (form_indirect == DW_FORM_indirect) { /* We are in big trouble: The true form of DW_FORM_indirect is DW_FORM_indirect? Nonsense. Should never happen. */ _dwarf_error(dbg,error,DW_DLE_NESTED_FORM_INDIRECT_ERROR); return DW_DLV_ERROR; } /* If form_indirect is DW_FORM_implicit_const then the following call will set info_data_len 0 */ res = _dwarf_get_size_of_val(dbg, form_indirect, cu_version, address_size, val_ptr + indir_len, v_length_size, &info_data_len, section_end_ptr, error); if(res != DW_DLV_OK) { return res; } *size_out = indir_len + info_data_len; return DW_DLV_OK; } case DW_FORM_ref1: *size_out = 1; return DW_DLV_OK; case DW_FORM_ref2: *size_out = 2; return DW_DLV_OK; case DW_FORM_ref4: *size_out = 4; return DW_DLV_OK; case DW_FORM_ref8: *size_out = 8; return DW_DLV_OK; /* DW_FORM_implicit_const is a value in the abbreviations, not in the DIEs and this functions measures DIE size. */ case DW_FORM_implicit_const: *size_out = 0; return DW_DLV_OK; case DW_FORM_sdata: { /* Discard the decoded value, we just want the length of the value. */ UNUSEDARG Dwarf_Signed v = 0; /* Discard the decoded value, we just want the length of the value. */ DECODE_LEB128_SWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK; } case DW_FORM_ref_sup4: *size_out = 4; return DW_DLV_OK; case DW_FORM_ref_sup8: *size_out = 8; return DW_DLV_OK; case DW_FORM_addrx1: *size_out = 1; return DW_DLV_OK; case DW_FORM_addrx2: *size_out = 2; return DW_DLV_OK; case DW_FORM_addrx3: *size_out = 4; return DW_DLV_OK; case DW_FORM_addrx4: *size_out = 4; return DW_DLV_OK; case DW_FORM_strx1: *size_out = 1; return DW_DLV_OK; case DW_FORM_strx2: *size_out = 2; return DW_DLV_OK; case DW_FORM_strx3: *size_out = 4; return DW_DLV_OK; case DW_FORM_strx4: *size_out = 4; return DW_DLV_OK; case DW_FORM_loclistx: case DW_FORM_rnglistx: case DW_FORM_addrx: case DW_FORM_GNU_addr_index: case DW_FORM_strx: case DW_FORM_GNU_str_index: { UNUSEDARG Dwarf_Unsigned v = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK; } case DW_FORM_line_strp: case DW_FORM_strp: *size_out = v_length_size; return DW_DLV_OK; case DW_FORM_udata: { /* Discard the decoded value, we just want the length of the value. */ UNUSEDARG Dwarf_Unsigned v = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,v,leb128_length, dbg,error,section_end_ptr); *size_out = leb128_length; return DW_DLV_OK; } } } /* We allow an arbitrary number of HT_MULTIPLE entries before resizing. It seems up to 20 or 30 would work nearly as well. We could have a different resize multiple than 'resize now' test multiple, but for now we don't do that. */ #define HT_MULTIPLE 8 /* Copy the old entries, updating each to be in a new list. Don't delete anything. Leave the htin with stale data. */ static void copy_abbrev_table_to_new_table(Dwarf_Hash_Table htin, Dwarf_Hash_Table htout) { Dwarf_Hash_Table_Entry entry_in = htin->tb_entries; unsigned entry_in_count = htin->tb_table_entry_count; Dwarf_Hash_Table_Entry entry_out = htout->tb_entries; unsigned entry_out_count = htout->tb_table_entry_count; unsigned k = 0; for (; k < entry_in_count; ++k,++entry_in) { Dwarf_Abbrev_List listent = entry_in->at_head; Dwarf_Abbrev_List nextlistent = 0; for (; listent ; listent = nextlistent) { unsigned newtmp = listent->abl_code; unsigned newhash = newtmp%entry_out_count; Dwarf_Hash_Table_Entry e; nextlistent = listent->abl_next; e = entry_out+newhash; /* Move_entry_to_new_hash. This reverses the order of the entries, effectively, but that does not seem significant. */ listent->abl_next = e->at_head; e->at_head = listent; htout->tb_total_abbrev_count++; } } } /* We allow zero form here, end of list. */ int _dwarf_valid_form_we_know(Dwarf_Unsigned at_form, Dwarf_Unsigned at_name) { if(at_form == 0 && at_name == 0) { return TRUE; } if (at_name == 0) { return FALSE; } if (at_form <= DW_FORM_addrx4 ) { return TRUE; } if (at_form == DW_FORM_GNU_addr_index || at_form == DW_FORM_GNU_str_index || at_form == DW_FORM_GNU_ref_alt || at_form == DW_FORM_GNU_strp_alt) { return TRUE; } return FALSE; } /* This function returns a pointer to a Dwarf_Abbrev_List_s struct for the abbrev with the given code. It puts the struct on the appropriate hash table. It also adds all the abbrev between the last abbrev added and this one to the hash table. In other words, the .debug_abbrev section is scanned sequentially from the top for an abbrev with the given code. All intervening abbrevs are also put into the hash table. This function hashes the given code, and checks the chain at that hash table entry to see if a Dwarf_Abbrev_List_s with the given code exists. If yes, it returns a pointer to that struct. Otherwise, it scans the .debug_abbrev section from the last byte scanned for that CU till either an abbrev with the given code is found, or an abbrev code of 0 is read. It puts Dwarf_Abbrev_List_s entries for all abbrev's read till that point into the hash table. The hash table contains both a head pointer and a tail pointer for each entry. While the lists can move and entries can be moved between lists on reallocation, any given Dwarf_Abbrev_list entry never moves once allocated, so the pointer is safe to return. See also dwarf_get_abbrev() in dwarf_abbrev.c. Returns DW_DLV_ERROR on error. */ int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, Dwarf_Abbrev_List *list_out, Dwarf_Error *error) { Dwarf_Debug dbg = cu_context->cc_dbg; Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table; Dwarf_Hash_Table_Entry entry_base = 0; Dwarf_Hash_Table_Entry entry_cur = 0; Dwarf_Unsigned hash_num = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned abbrev_tag = 0; Dwarf_Abbrev_List hash_abbrev_entry = 0; Dwarf_Abbrev_List inner_list_entry = 0; Dwarf_Hash_Table_Entry inner_hash_entry = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; Dwarf_Byte_Ptr end_abbrev_ptr = 0; unsigned hashable_val = 0; if (!hash_table_base->tb_entries) { hash_table_base->tb_table_entry_count = HT_MULTIPLE; hash_table_base->tb_total_abbrev_count= 0; hash_table_base->tb_entries = (struct Dwarf_Hash_Table_Entry_s *)_dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE_ENTRY, hash_table_base->tb_table_entry_count); if (!hash_table_base->tb_entries) { return DW_DLV_NO_ENTRY; } } else if (hash_table_base->tb_total_abbrev_count > ( hash_table_base->tb_table_entry_count * HT_MULTIPLE) ) { struct Dwarf_Hash_Table_s newht; /* Effectively multiplies by >= HT_MULTIPLE */ newht.tb_table_entry_count = hash_table_base->tb_total_abbrev_count; newht.tb_total_abbrev_count = 0; newht.tb_entries = (struct Dwarf_Hash_Table_Entry_s *)_dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE_ENTRY, newht.tb_table_entry_count); if (!newht.tb_entries) { return DW_DLV_NO_ENTRY; } /* Copy the existing entries to the new table, rehashing each. */ copy_abbrev_table_to_new_table(hash_table_base, &newht); /* Dealloc only the entries hash table array, not the lists of things pointed to by a hash table entry array. */ dwarf_dealloc(dbg, hash_table_base->tb_entries,DW_DLA_HASH_TABLE_ENTRY); hash_table_base->tb_entries = 0; /* Now overwrite the existing table descriptor with the new, newly valid, contents. */ *hash_table_base = newht; } /* Else is ok as is, add entry */ hashable_val = code; hash_num = hashable_val % hash_table_base->tb_table_entry_count; entry_base = hash_table_base->tb_entries; entry_cur = entry_base + hash_num; /* Determine if the 'code' is the list of synonyms already. */ for (hash_abbrev_entry = entry_cur->at_head; hash_abbrev_entry != NULL && hash_abbrev_entry->abl_code != code; hash_abbrev_entry = hash_abbrev_entry->abl_next); if (hash_abbrev_entry != NULL) { /* This returns a pointer to an abbrev list entry, not the list itself. */ *list_out = hash_abbrev_entry; return DW_DLV_OK; } if (cu_context->cc_last_abbrev_ptr) { abbrev_ptr = cu_context->cc_last_abbrev_ptr; end_abbrev_ptr = cu_context->cc_last_abbrev_endptr; } else { /* This is ok because cc_abbrev_offset includes DWP offset if appropriate. */ abbrev_ptr = dbg->de_debug_abbrev.dss_data + cu_context->cc_abbrev_offset; if (cu_context->cc_dwp_offsets.pcu_type) { /* In a DWP the abbrevs for this context are known quite precisely. */ Dwarf_Unsigned size = 0; /* Ignore the offset returned. Already in cc_abbrev_offset. */ _dwarf_get_dwp_extra_offset( &cu_context->cc_dwp_offsets, DW_SECT_ABBREV,&size); /* ASSERT: size != 0 */ end_abbrev_ptr = abbrev_ptr + size; } else { end_abbrev_ptr = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; } } /* End of abbrev's as we are past the end entirely. This can happen,though it seems wrong. Or we are at the end of the data block, which we also take as meaning done with abbrevs for this CU. An abbreviations table is supposed to end with a zero byte. Not ended by end of data block. But we are allowing what is possibly a bit more flexible end policy here. */ if (abbrev_ptr >= end_abbrev_ptr) { return DW_DLV_NO_ENTRY; } /* End of abbrev's for this cu, since abbrev code is 0. */ if (*abbrev_ptr == 0) { return DW_DLV_NO_ENTRY; } do { unsigned new_hashable_val = 0; Dwarf_Off abb_goff = 0; Dwarf_Unsigned atcount = 0; Dwarf_Byte_Ptr abbrev_ptr2 = 0; int res = 0; abb_goff = abbrev_ptr - dbg->de_debug_abbrev.dss_data; DECODE_LEB128_UWORD_CK(abbrev_ptr, abbrev_code, dbg,error,end_abbrev_ptr); DECODE_LEB128_UWORD_CK(abbrev_ptr, abbrev_tag, dbg,error,end_abbrev_ptr); if (abbrev_tag > DW_TAG_hi_user) { _dwarf_error(dbg, error,DW_DLE_TAG_CORRUPT); return DW_DLV_ERROR; } if (abbrev_ptr >= end_abbrev_ptr) { _dwarf_error(dbg, error, DW_DLE_ABBREV_OFF_END); return DW_DLV_ERROR; } inner_list_entry = (Dwarf_Abbrev_List) _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1); if (inner_list_entry == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_hashable_val = abbrev_code; hash_num = new_hashable_val % hash_table_base->tb_table_entry_count; inner_hash_entry = entry_base + hash_num; /* Move_entry_to_new_hash */ inner_list_entry->abl_next = inner_hash_entry->at_head; inner_hash_entry->at_head = inner_list_entry; hash_table_base->tb_total_abbrev_count++; inner_list_entry->abl_code = abbrev_code; inner_list_entry->abl_tag = abbrev_tag; inner_list_entry->abl_has_child = *(abbrev_ptr++); inner_list_entry->abl_abbrev_ptr = abbrev_ptr; inner_list_entry->abl_goffset = abb_goff; hash_table_base->tb_total_abbrev_count++; /* Cycle thru the abbrev content, ignoring the content except to find the end of the content. */ res = _dwarf_count_abbrev_entries(dbg,abbrev_ptr, end_abbrev_ptr,&atcount,&abbrev_ptr2,error); if (res != DW_DLV_OK) { return res; } abbrev_ptr = abbrev_ptr2; inner_list_entry->abl_count = atcount; } while ((abbrev_ptr < end_abbrev_ptr) && *abbrev_ptr != 0 && abbrev_code != code); cu_context->cc_last_abbrev_ptr = abbrev_ptr; cu_context->cc_last_abbrev_endptr = end_abbrev_ptr; if(abbrev_code == code) { *list_out = inner_list_entry; return DW_DLV_OK; } /* We cannot find an abbrev_code matching code. ERROR will be declared eventually. Might be better to declare specific errors here? */ return DW_DLV_NO_ENTRY; } /* We check that: areaptr <= strptr. a NUL byte (*p) exists at p < end. and return DW_DLV_ERROR if a check fails. de_assume_string_in_bounds */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *strptr, void *areaendptr, int suggested_error, Dwarf_Error*error) { Dwarf_Small *start = areaptr; Dwarf_Small *p = strptr; Dwarf_Small *end = areaendptr; if (p < start) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (p >= end) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (dbg->de_assume_string_in_bounds) { /* This NOT the default. But folks can choose to live dangerously and just assume strings ok. */ return DW_DLV_OK; } while (p < end) { if (*p == 0) { return DW_DLV_OK; } ++p; } _dwarf_error(dbg,error,DW_DLE_STRING_NOT_TERMINATED); return DW_DLV_ERROR; } /* Return non-zero if the start/end are not valid for the die's section. If pastend matches the dss_data+dss_size then pastend is a pointer that cannot be dereferenced. But we allow it as valid here, it is normal for a pointer to point one-past-end in various circumstances (one must avoid dereferencing it, of course). Return 0 if valid. Return 1 if invalid. */ int _dwarf_reference_outside_section(Dwarf_Die die, Dwarf_Small * startaddr, Dwarf_Small * pastend) { Dwarf_Debug dbg = 0; Dwarf_CU_Context contxt = 0; struct Dwarf_Section_s *sec = 0; contxt = die->di_cu_context; dbg = contxt->cc_dbg; if (die->di_is_info) { sec = &dbg->de_debug_info; } else { sec = &dbg->de_debug_types; } if (startaddr < sec->dss_data) { return 1; } if (pastend > (sec->dss_data + sec->dss_size)) { return 1; } return 0; } /* A byte-swapping version of memcpy for cross-endian use. Only 2,4,8 should be lengths passed in. */ void _dwarf_memcpy_noswap_bytes(void *s1, const void *s2, unsigned long len) { memcpy(s1,s2,(size_t)len); return; } void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len) { unsigned char *targ = (unsigned char *) s1; const unsigned char *src = (const unsigned char *) s2; if (len == 4) { targ[3] = src[0]; targ[2] = src[1]; targ[1] = src[2]; targ[0] = src[3]; } else if (len == 8) { targ[7] = src[0]; targ[6] = src[1]; targ[5] = src[2]; targ[4] = src[3]; targ[3] = src[4]; targ[2] = src[5]; targ[1] = src[6]; targ[0] = src[7]; } else if (len == 2) { targ[1] = src[0]; targ[0] = src[1]; } /* should NOT get below here: is not the intended use */ else if (len == 1) { targ[0] = src[0]; } else { memcpy(s1, s2, (size_t)len); } return; } /* This calculation used to be sprinkled all over. Now brought to one place. We try to accurately compute the size of a cu header given a known cu header location ( an offset in .debug_info or debug_types). */ /* ARGSUSED */ int _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Bool is_info, Dwarf_Unsigned *area_length_out, Dwarf_Error *error) { int local_length_size = 0; int local_extension_size = 0; Dwarf_Half version = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned final_size = 0; Dwarf_Small *section_start = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; Dwarf_Small *cuptr = section_start + offset; Dwarf_Unsigned section_length = is_info? dbg->de_debug_info.dss_size: dbg->de_debug_types.dss_size; Dwarf_Small * section_end_ptr = section_start + section_length; READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, cuptr, local_length_size, local_extension_size, error,section_length,section_end_ptr); READ_UNALIGNED_CK(dbg, version, Dwarf_Half, cuptr, DWARF_HALF_SIZE,error,section_end_ptr); cuptr += DWARF_HALF_SIZE; if (version == 5) { Dwarf_Ubyte unit_type = 0; READ_UNALIGNED_CK(dbg, unit_type, Dwarf_Ubyte, cuptr, sizeof(Dwarf_Ubyte),error,section_end_ptr); switch (unit_type) { case DW_UT_compile: final_size = local_extension_size + local_length_size + /* Size of cu length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ sizeof(Dwarf_Small)+ /* Size of unit type field. */ sizeof(Dwarf_Small)+ /* Size of address size field. */ local_length_size ; /* Size of abbrev offset field. */ break; case DW_UT_type: case DW_UT_partial: case DW_UT_skeleton: case DW_UT_split_compile: case DW_UT_split_type: default: _dwarf_error(dbg,error,DW_DLE_UNIT_TYPE_NOT_HANDLED); return DW_DLV_ERROR; } } else if (version == 4) { final_size = local_extension_size + local_length_size + /* Size of cu length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ local_length_size + /* Size of abbrev offset field. */ sizeof(Dwarf_Small); /* Size of address size field. */ if (!is_info) { final_size += /* type signature size */ sizeof (Dwarf_Sig8) + /* type offset size */ local_length_size; } } else if (version < 4) { final_size = local_extension_size + local_length_size + DWARF_HALF_SIZE + local_length_size + sizeof(Dwarf_Small); /* Size of address size field. */ } *area_length_out = final_size; return DW_DLV_OK; } /* Pretend we know nothing about the CU and just roughly compute the result. */ Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg, Dwarf_Bool dinfo) { Dwarf_Unsigned finalsize = 0; finalsize = dbg->de_length_size + /* Size of cu length field. */ DWARF_HALF_SIZE + /* Size of version stamp field. */ dbg->de_length_size + /* Size of abbrev offset field. */ sizeof(Dwarf_Small); /* Size of address size field. */ if (!dinfo) { finalsize += /* type signature size */ sizeof (Dwarf_Sig8) + /* type offset size */ dbg->de_length_size; } return finalsize; } /* Now that we delay loading .debug_info, we need to do the load in more places. So putting the load code in one place now instead of replicating it in multiple places. */ int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error) { int res = DW_DLV_ERROR; if (dbg->de_debug_info.dss_data) { return DW_DLV_OK; } res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_load_section(dbg, &dbg->de_debug_info, error); return res; } int _dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error * error) { int res = DW_DLV_ERROR; if (dbg->de_debug_types.dss_data) { return DW_DLV_OK; } res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error); if (res != DW_DLV_OK) { return res; } res = _dwarf_load_section(dbg, &dbg->de_debug_types, error); return res; } void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,Dwarf_Hash_Table hash_table) { /* A Hash Table is an array with tb_table_entry_count struct Dwarf_Hash_Table_s entries in the array. */ unsigned hashnum = 0; for (; hashnum < hash_table->tb_table_entry_count; ++hashnum) { struct Dwarf_Abbrev_List_s *abbrev = 0; struct Dwarf_Abbrev_List_s *nextabbrev = 0; struct Dwarf_Hash_Table_Entry_s *tb = &hash_table->tb_entries[hashnum]; abbrev = tb->at_head; for (; abbrev; abbrev = nextabbrev) { nextabbrev = abbrev->abl_next; abbrev->abl_next = 0; dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST); } tb->at_head = 0; } /* Frees all the entries at once: an array. */ dwarf_dealloc(dbg,hash_table->tb_entries,DW_DLA_HASH_TABLE_ENTRY); hash_table->tb_entries = 0; } /* If no die provided the size value returned might be wrong. If different compilation units have different address sizes this may not give the correct value in all contexts if the die pointer is NULL. If the Elf offset size != address_size (for example if address_size = 4 but recorded in elf64 object) this may not give the correct value in all contexts if the die pointer is NULL. If the die pointer is non-NULL (in which case it must point to a valid DIE) this will return the correct size. */ int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die) { Dwarf_CU_Context context = 0; Dwarf_Half addrsize = 0; if (!die) { return dbg->de_pointer_size; } context = die->di_cu_context; addrsize = context->cc_address_size; return addrsize; } /* Encode val as an unsigned LEB128. */ int dwarf_encode_leb128(Dwarf_Unsigned val, int *nbytes, char *space, int splen) { /* Encode val as an unsigned LEB128. */ return _dwarf_pro_encode_leb128_nm(val,nbytes,space,splen); } /* Encode val as a signed LEB128. */ int dwarf_encode_signed_leb128(Dwarf_Signed val, int *nbytes, char *space, int splen) { /* Encode val as a signed LEB128. */ return _dwarf_pro_encode_signed_leb128_nm(val,nbytes,space,splen); } struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback( Dwarf_Debug dbg, struct Dwarf_Printf_Callback_Info_s * newvalues) { struct Dwarf_Printf_Callback_Info_s oldval = dbg->de_printf_callback; if (!newvalues) { return oldval; } if( newvalues->dp_buffer_user_provided) { if( oldval.dp_buffer_user_provided) { /* User continues to control the buffer. */ dbg->de_printf_callback = *newvalues; }else { /* Switch from our control of buffer to user control. */ free(oldval.dp_buffer); oldval.dp_buffer = 0; dbg->de_printf_callback = *newvalues; } } else if (oldval.dp_buffer_user_provided){ /* Switch from user control to our control */ dbg->de_printf_callback = *newvalues; dbg->de_printf_callback.dp_buffer_len = 0; dbg->de_printf_callback.dp_buffer= 0; } else { /* User does not control the buffer. */ dbg->de_printf_callback = *newvalues; dbg->de_printf_callback.dp_buffer_len = oldval.dp_buffer_len; dbg->de_printf_callback.dp_buffer = oldval.dp_buffer; } return oldval; } /* Allocate a bigger buffer if necessary. Do not worry about previous content of the buffer. Return 0 if we fail here. Else return the requested len value. */ static unsigned buffersetsize(Dwarf_Debug dbg, struct Dwarf_Printf_Callback_Info_s *bufdata, int len) { char *space = 0; if (!dbg->de_printf_callback_null_device_handle) { FILE *de = fopen(NULL_DEVICE_NAME,"w"); if(!de) { return 0; } dbg->de_printf_callback_null_device_handle = de; } if (bufdata->dp_buffer_user_provided) { return bufdata->dp_buffer_len; } /* Make big enough for a trailing NUL char. */ space = (char *)malloc(len+1); if (!space) { /* Out of space, we cannot do anything. */ return 0; } free(bufdata->dp_buffer); bufdata->dp_buffer = space; bufdata->dp_buffer_len = len; return len; } /* We are only using C90 facilities, not C99, in libdwarf/dwarfdump. */ int dwarf_printf(Dwarf_Debug dbg, const char * format, ...) { va_list ap; unsigned bff = 0; struct Dwarf_Printf_Callback_Info_s *bufdata = &dbg->de_printf_callback; FILE * null_device_handle = 0; dwarf_printf_callback_function_type func = bufdata->dp_fptr; if (!func) { return 0; } null_device_handle = (FILE *) dbg->de_printf_callback_null_device_handle; if (!bufdata->dp_buffer || !null_device_handle) { /* Sets dbg device handle for later use if not set already. */ bff = buffersetsize(dbg,bufdata,MINBUFLEN); if (!bff) { /* Something is wrong. */ return 0; } if (!bufdata->dp_buffer) { /* Something is wrong. Possibly caller set up callback wrong. */ return 0; } } { int plen = 0; int nlen = 0; null_device_handle = (FILE *) dbg->de_printf_callback_null_device_handle; if (!null_device_handle) { /* Something is wrong. */ return 0; } va_start(ap,format); plen = vfprintf(null_device_handle,format,ap); va_end(ap); if (!bufdata->dp_buffer_user_provided) { if (plen >= (int)bufdata->dp_buffer_len) { bff = buffersetsize(dbg,bufdata,plen+2); if (!bff) { /* Something is wrong. */ return 0; } } } else { if (plen >= (int)bufdata->dp_buffer_len) { /* We are stuck! User did not give us space needed! */ return 0; } } va_start(ap,format); nlen = vsprintf(bufdata->dp_buffer, format,ap); va_end(ap); if ( nlen > plen) { /* Impossible. Memory is corrupted now */ fprintf(stderr,"\nlibdwarf impossible sprintf error %s %d\n", __FILE__,__LINE__); exit(1); } func(bufdata->dp_user_pointer,bufdata->dp_buffer); return nlen; } /* Not reached. */ return 0; } /* Often errs and errt point to the same Dwarf_Error, So exercise care. All the arguments MUST be non-null.*/ void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, Dwarf_Debug dbgt,Dwarf_Error *errt) { if (!errt || !errs) { return; } if (!dbgs || !dbgt) { return; } if(dbgs == dbgt) { if(errs != errt) { Dwarf_Error ers = *errs; *errs = 0; *errt = ers; } } else { /* Do not stomp on the system errno variable if there is one! */ int mydw_errno = dwarf_errno(*errs); dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR); *errs = 0; _dwarf_error(dbgt,errt, mydw_errno); } } static int inthissection(struct Dwarf_Section_s *sec,Dwarf_Small *ptr) { if (!sec->dss_data) { return FALSE; } if (ptr < sec->dss_data ) { return FALSE; } if (ptr >= (sec->dss_data + sec->dss_size) ) { return FALSE; } return TRUE; } #define FINDSEC(m_s,m_p,n,st,l,e) \ do { \ if (inthissection((m_s),(m_p))) { \ *(n) = (m_s)->dss_name; \ *(st)= (m_s)->dss_data; \ *(l) = (m_s)->dss_size; \ *(e) = (m_s)->dss_data + (m_s)->dss_size; \ return DW_DLV_OK; \ } \ } while (0) /* So we can know a section end even when we do not have the section info apriori It's only needed for a subset of sections. */ int _dwarf_what_section_are_we(Dwarf_Debug dbg, Dwarf_Small * our_pointer, const char ** section_name_out, Dwarf_Small ** sec_start_ptr_out, Dwarf_Unsigned * sec_len_out, Dwarf_Small ** sec_end_ptr_out, UNUSEDARG Dwarf_Error * error) { FINDSEC(&dbg->de_debug_info, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_loc, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_line, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_aranges, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_macro, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_ranges, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_str_offsets, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_addr, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_pubtypes, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_gdbindex, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_abbrev, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_cu_index, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_tu_index, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_line_str, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_types, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_sup, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_frame, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); FINDSEC(&dbg->de_debug_frame_eh_gnu, our_pointer, section_name_out, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); return DW_DLV_NO_ENTRY; } /* New September 2019. */ int dwarf_add_file_path( Dwarf_Debug dbg, const char * file_name, Dwarf_Error* error) { if(!dbg || !file_name) { /* Pretty much a disaster. Caller error. */ _dwarf_error(dbg,error,DW_DLE_NULL_ARGS_DWARF_ADD_PATH); return DW_DLV_ERROR; } if (!dbg->de_path) { dbg->de_path = strdup(file_name); } return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarf_util.h000066400000000000000000000506011361531463500202450ustar00rootroot00000000000000#ifndef DWARF_UTIL_H #define DWARF_UTIL_H /* Copyright (C) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2012 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 and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Decodes unsigned leb128 encoded numbers. Make sure ptr is a pointer to a 1-byte type. In 2003 and earlier this was a hand-inlined version of _dwarf_decode_u_leb128() which did not work correctly if Dwarf_Unsigned was 64 bits. April 2016: now uses a reader that is careful. 'return' only in case of error else falls through. */ #define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \ do { \ Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Unsigned lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ value = lu_local; \ ptr += lu_leblen; \ } while (0) #define DECODE_LEB128_UWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \ do { \ Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Unsigned lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ value = lu_local; \ ptr += lu_leblen; \ leblen = lu_leblen; \ } while (0) /* Decodes signed leb128 encoded numbers. Make sure ptr is a pointer to a 1-byte type. In 2003 and earlier this was a hand-inlined version of _dwarf_decode_s_leb128() which did not work correctly if Dwarf_Unsigned was 64 bits. */ #define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \ do { \ Dwarf_Unsigned uleblen = 0; \ Dwarf_Signed local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_s_leb128_chk(ptr,&uleblen,&local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ value = local; \ ptr += uleblen; \ } while (0) #define DECODE_LEB128_SWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \ do { \ Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Signed lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_s_leb128_chk(ptr,&lu_leblen,\ &lu_local,endptr); \ if (lu_res == DW_DLV_ERROR) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ leblen = lu_leblen; \ value = lu_local; \ ptr += lu_leblen; \ } while (0) /* Skips leb128_encoded numbers that are guaranteed to be no more than 4 bytes long. Same for both signed and unsigned numbers. These seem bogus as they assume 4 bytes get a 4 byte word. Wrong. FIXME 'return' only in case of error else falls through. */ #define SKIP_LEB128_WORD_CK(ptr,dbg,errptr,endptr) \ do { \ if ((*(ptr++) & 0x80) != 0) { \ if (ptr >= endptr) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ if ((*(ptr++) & 0x80) != 0) { \ if (ptr >= endptr) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ if ((*(ptr++) & 0x80) != 0) { \ if (ptr >= endptr) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ ptr++; \ if (ptr >= endptr) { \ _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ return DW_DLV_ERROR; \ } \ } \ } \ } \ } while (0) #define CHECK_DIE(die, error_ret_value) \ do { \ if (die == NULL) { \ _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \ return(error_ret_value); \ } \ if (die->di_cu_context == NULL) { \ _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \ return(error_ret_value); \ } \ if (die->di_cu_context->cc_dbg == NULL) { \ _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ return(error_ret_value); \ } \ } while (0) /* Reads 'source' for 'length' bytes from unaligned addr. Avoids any constant-in-conditional warnings and avoids a test in the generated code (for non-const cases, which are in the majority.) Uses a temp to avoid the test. The decl here should avoid any problem of size in the temp. This code is ENDIAN DEPENDENT The memcpy args are the endian issue. Does not update the 'source' field. for READ_UNALIGNED_CK the error code refers to host endianness. */ typedef Dwarf_Unsigned BIGGEST_UINT; #ifdef WORDS_BIGENDIAN #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \ do { \ BIGGEST_UINT _ltmp = 0; \ Dwarf_Byte_Ptr readend = source+length; \ if (readend < source) { \ _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \ return DW_DLV_ERROR; \ } \ if (readend > endptr) { \ _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \ return DW_DLV_ERROR; \ } \ dbg->de_copy_word( (((char *)(&_ltmp)) + \ sizeof(_ltmp) - length),source, length) ; \ dest = (desttype)_ltmp; \ } while (0) /* This macro sign-extends a variable depending on the length. It fills the bytes between the size of the destination and the length with appropriate padding. This code is ENDIAN DEPENDENT but dependent only on host endianness, not object file endianness. The memcpy args are the issue. */ #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + \ sizeof(dest) - length) < 0) { \ memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\ sizeof(dest) - length); \ } \ } while (0) #else /* LITTLE ENDIAN */ #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \ do { \ BIGGEST_UINT _ltmp = 0; \ Dwarf_Byte_Ptr readend = source+length; \ if (readend < source) { \ _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR);\ return DW_DLV_ERROR; \ } \ if (readend > endptr) { \ _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR);\ return DW_DLV_ERROR; \ } \ dbg->de_copy_word( (char *)(&_ltmp) , \ source, length) ; \ dest = (desttype)_ltmp; \ } while (0) /* This macro sign-extends a variable depending on the length. It fills the bytes between the size of the destination and the length with appropriate padding. This code is ENDIAN DEPENDENT but dependent only on host endianness, not object file endianness. The memcpy args are the issue. */ #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \ memcpy((char *)&dest+length, \ "\xff\xff\xff\xff\xff\xff\xff\xff", \ sizeof(dest) - length); \ } \ } while (0) #endif /* ! LITTLE_ENDIAN */ /* READ_AREA LENGTH reads the length (the older way of pure 32 or 64 bit or the dwarf v3 64bit-extension way) It reads the bits from where rw_src_data_p points to and updates the rw_src_data_p to point past what was just read. It updates w_length_size (to the size of an offset, either 4 or 8) and w_exten_size (set 0 unless this frame has the DWARF3 and later 64bit extension, in which case w_exten_size is set to 4). r_dbg is just the current dbg pointer. w_target is the output length field. r_targtype is the output type. Always Dwarf_Unsigned so far. */ /* This one handles the v3 64bit extension and 32bit (and SGI/MIPS fixed 64 bit via the dwarf_init-set r_dbg->de_length_size).. It does not recognize any but the one distingushed value (the only one with defined meaning). It assumes that no CU will have a length 0xffffffxx (32bit length) or 0xffffffxx xxxxxxxx (64bit length) which makes possible auto-detection of the extension. This depends on knowing that only a non-zero length is legitimate (AFAICT), and for IRIX non-standard -64 dwarf that the first 32 bits of the 64bit offset will be zero (because the compiler could not handle a truly large value as of Jan 2003 and because no app has that much debug info anyway, at least not in the IRIX case). At present not testing for '64bit elf' here as that does not seem necessary (none of the 64bit length seems appropriate unless it's ident[EI_CLASS] == ELFCLASS64). */ /* The w_target > r_sectionlen compare is done without adding in case the w_target value read is so large any addition would overflow. A basic value sanity check. */ #define READ_AREA_LENGTH_CK(r_dbg,w_target,r_targtype, \ rw_src_data_p,w_length_size,w_exten_size,w_error, \ r_sectionlen,r_endptr) \ do { \ READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \ rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE, \ w_error,r_endptr); \ if (w_target == DISTINGUISHED_VALUE) { \ /* dwarf3 64bit extension */ \ w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \ w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \ READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \ rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE,\ w_error,r_endptr); \ if (w_target > r_sectionlen) { \ _dwarf_error(r_dbg,w_error, \ DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE); \ return DW_DLV_ERROR; \ } \ rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ } else { \ if (w_target == 0 && r_dbg->de_big_endian_object) {\ /* Might be IRIX: We have to distinguish between */\ /* 32-bit DWARF format and IRIX 64-bit \ DWARF format. */ \ if (r_dbg->de_length_size == 8) { \ /* IRIX 64 bit, big endian. This test */ \ /* is not a truly precise test, a precise test*/ \ /* would check if the target was IRIX. */ \ READ_UNALIGNED_CK(r_dbg,w_target,r_targtype,\ rw_src_data_p, \ DISTINGUISHED_VALUE_OFFSET_SIZE, \ w_error,r_endptr); \ if (w_target > r_sectionlen) { \ _dwarf_error(r_dbg,w_error, \ DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\ return DW_DLV_ERROR; \ } \ w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE;\ rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;\ w_exten_size = 0; \ } else { \ /* 32 bit, big endian */ \ w_length_size = ORIGINAL_DWARF_OFFSET_SIZE;\ rw_src_data_p += w_length_size; \ w_exten_size = 0; \ } \ } else { \ if (w_target > r_sectionlen) { \ _dwarf_error(r_dbg,w_error, \ DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\ return DW_DLV_ERROR; \ } \ /* Standard 32 bit dwarf2/dwarf3 */ \ w_exten_size = 0; \ w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \ rw_src_data_p += w_length_size; \ } \ } \ } while (0) /* Fuller checking. Returns DW_DLV_ERROR or DW_DLV_OK Caller must set Dwarf_Error */ int _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr); int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Signed *outval, Dwarf_Byte_Ptr endptr); int _dwarf_get_size_of_val(Dwarf_Debug dbg, Dwarf_Unsigned form, Dwarf_Half cu_version, Dwarf_Half address_size, Dwarf_Small * val_ptr, int v_length_size, Dwarf_Unsigned *size_out, Dwarf_Small *section_end_ptr, Dwarf_Error *error); struct Dwarf_Hash_Table_Entry_s; /* This single struct is the base for the hash table. The intent is that once the total_abbrev_count across all the entries is greater than 10*current_table_entry_count one should build a new Dwarf_Hash_Table_Base_s, rehash all the existing entries, and delete the old table and entries. (10 is a heuristic, nothing magic about it, but once the count gets to 30 or 40 times current_table_entry_count things really slow down a lot. One (500MB) application had 127000 abbreviations in one compilation unit) The incoming 'code' is an abbrev number and those simply increase linearly so the hashing is perfect always. */ struct Dwarf_Hash_Table_s { unsigned long tb_table_entry_count; unsigned long tb_total_abbrev_count; /* Each table entry is a list of abbreviations. */ struct Dwarf_Hash_Table_Entry_s *tb_entries; }; /* This struct is used to build a hash table for the abbreviation codes for a compile-unit. */ struct Dwarf_Hash_Table_Entry_s { Dwarf_Abbrev_List at_head; }; int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, Dwarf_Abbrev_List *list_out,Dwarf_Error *error); /* return 1 if string ends before 'endptr' else ** return 0 meaning string is not properly terminated. ** Presumption is the 'endptr' pts to end of some dwarf section data. */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *startptr, void *endptr, int suggested_error, Dwarf_Error *error); int _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Bool is_info, Dwarf_Unsigned *area_length_out, Dwarf_Error *error); Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug,Dwarf_Bool dinfo); int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error); int _dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error *error); void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg, struct Dwarf_Hash_Table_s* hash_table); int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die); int _dwarf_reference_outside_section(Dwarf_Die die, Dwarf_Small * startaddr, Dwarf_Small * pastend); void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, Dwarf_Debug dbgt,Dwarf_Error *errt); int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out, const char **comp_name_out, Dwarf_Error *error); int _dwarf_what_section_are_we(Dwarf_Debug dbg, Dwarf_Small *our_pointer, const char ** section_name_out, Dwarf_Small **sec_start_ptr_out, Dwarf_Unsigned *sec_len_out, Dwarf_Small **sec_end_ptr_out, Dwarf_Error *error); #endif /* DWARF_UTIL_H */ dwarfutils-20200114/libdwarf/dwarf_vars.c000066400000000000000000000066651361531463500202510ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_vars.h" #include "dwarf_global.h" int dwarf_get_vars(Dwarf_Debug dbg, Dwarf_Var ** vars, Dwarf_Signed * ret_var_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_varnames,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_abbrev.dss_size) { return (DW_DLV_NO_ENTRY); } return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_varnames.dss_data, dbg->de_debug_varnames.dss_size, (Dwarf_Global **) vars, /* Type punning for sections with identical format. */ ret_var_count, error, DW_DLA_VAR_CONTEXT, DW_DLA_VAR, DW_DLE_DEBUG_VARNAMES_LENGTH_BAD, DW_DLE_DEBUG_VARNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_vars_dealloc(Dwarf_Debug dbg, Dwarf_Var * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_VAR_CONTEXT, DW_DLA_VAR, DW_DLA_LIST); return; } int dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; if (var == NULL) { _dwarf_error(NULL, error, DW_DLE_VAR_NULL); return (DW_DLV_ERROR); } *ret_varname = (char *) (var->gl_name); return DW_DLV_OK; } int dwarf_var_die_offset(Dwarf_Var var_in, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; return dwarf_global_die_offset(var, returned_offset, error); } int dwarf_var_cu_offset(Dwarf_Var var_in, Dwarf_Off * returned_offset, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; return dwarf_global_cu_offset(var, returned_offset, error); } int dwarf_var_name_offsets(Dwarf_Var var_in, char **returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error * error) { Dwarf_Global var = (Dwarf_Global) var_in; return dwarf_global_name_offsets(var, returned_name, die_offset, cu_offset, error); } dwarfutils-20200114/libdwarf/dwarf_vars.h000066400000000000000000000022501361531463500202400ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Var_Context_s *Dwarf_Var_Context; /* struct never completed: see dwarf_global.h */ dwarfutils-20200114/libdwarf/dwarf_weaks.c000066400000000000000000000066301361531463500204000ustar00rootroot00000000000000/* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include #include "dwarf_incl.h" #include "dwarf_error.h" #include "dwarf_weaks.h" #include "dwarf_global.h" int dwarf_get_weaks(Dwarf_Debug dbg, Dwarf_Weak ** weaks, Dwarf_Signed * ret_weak_count, Dwarf_Error * error) { int res = _dwarf_load_section(dbg, &dbg->de_debug_weaknames,error); if (res != DW_DLV_OK) { return res; } if (!dbg->de_debug_weaknames.dss_size) { return (DW_DLV_NO_ENTRY); } return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_weaknames.dss_data, dbg->de_debug_weaknames.dss_size, (Dwarf_Global **) weaks, /* Type punning for sections with identical format. */ ret_weak_count, error, DW_DLA_WEAK_CONTEXT, DW_DLA_WEAK, DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD, DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR); } /* Deallocating fully requires deallocating the list and all entries. But some internal data is not exposed, so we need a function with internal knowledge. */ void dwarf_weaks_dealloc(Dwarf_Debug dbg, Dwarf_Weak * dwgl, Dwarf_Signed count) { _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_WEAK_CONTEXT, DW_DLA_WEAK, DW_DLA_LIST); return; } int dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; if (weak == NULL) { _dwarf_error(NULL, error, DW_DLE_WEAK_NULL); return (DW_DLV_ERROR); } *ret_name = (char *) (weak->gl_name); return DW_DLV_OK; } int dwarf_weak_die_offset(Dwarf_Weak weak_in, Dwarf_Off * weak_off, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; return dwarf_global_die_offset(weak, weak_off, error); } int dwarf_weak_cu_offset(Dwarf_Weak weak_in, Dwarf_Off * weak_off, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; return dwarf_global_cu_offset(weak, weak_off, error); } int dwarf_weak_name_offsets(Dwarf_Weak weak_in, char **weak_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error * error) { Dwarf_Global weak = (Dwarf_Global) weak_in; return dwarf_global_name_offsets(weak, weak_name, die_offset, cu_offset, error); } dwarfutils-20200114/libdwarf/dwarf_weaks.h000066400000000000000000000022521361531463500204010ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ typedef struct Dwarf_Weak_Context_s *Dwarf_Weak_Context; /* struct never completed: see dwarf_global.h */ dwarfutils-20200114/libdwarf/dwarf_xu_index.c000066400000000000000000000527601361531463500211160ustar00rootroot00000000000000/* Copyright (C) 2014-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The file and functions have 'xu' because the .debug_cu_index and .debug_tu_index sections have the same layout and this deals with both. This is DebugFission, part of DWARF5. It allows fast section access in a .dwp object file with debug-information to locate offsets within and between sections. See the DWARF5 Standard: section 7.3.5 and examples in Appendix F.3. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarf_xu_index.h" #define HASHSIGNATURELEN 8 #define LEN32BIT 4 #define TRUE 1 #define FALSE 0 /* The following actually assumes (as used here) that t is 8 bytes (integer) while s is also 8 bytes (Dwarf_Sig8 struct). */ #ifdef WORDS_BIGENDIAN #define ASNAR(t,s,l) \ do { \ unsigned tbyte = sizeof(t) - l; \ if (sizeof(t) < l) { \ _dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \ return DW_DLV_ERROR; \ } \ t = 0; \ dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(t,s,l) \ do { \ t = 0; \ if (sizeof(t) < l) { \ _dwarf_error(dbg,error,DW_DLE_XU_HASH_INDEX_ERROR); \ return DW_DLV_ERROR; \ } \ dbg->de_copy_word(&t,&s[0],l); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ /* zerohashkey used as all-zero-bits for comparison. */ static Dwarf_Sig8 zerohashkey; #if 0 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 /* Read in a cu or tu section and return overview information. dwarf_init*() calls dwarf_get_xu_index_header() when the object file is opened, there is no need for users to do this. The loaded data is kept in Dwarf_Debug de_cu_hashindex_data/de_tu_hashindex_data. dwarf_finish() calls dwarf_xu_header_free() users should not. */ int dwarf_get_xu_index_header(Dwarf_Debug dbg, /* Pass in section_type "tu" or "cu" */ const char * section_type, Dwarf_Xu_Index_Header * xuptr, Dwarf_Unsigned * version, Dwarf_Unsigned * number_of_columns, /* L */ Dwarf_Unsigned * number_of_CUs, /* N */ Dwarf_Unsigned * number_of_slots, /* M */ const char ** section_name, Dwarf_Error * error) { Dwarf_Xu_Index_Header indexptr = 0; int res = DW_DLV_ERROR; struct Dwarf_Section_s *sect = 0; Dwarf_Unsigned local_version = 0; Dwarf_Unsigned num_col = 0; Dwarf_Unsigned num_CUs = 0; Dwarf_Unsigned num_slots = 0; Dwarf_Small *data = 0; Dwarf_Unsigned tables_end_offset = 0; Dwarf_Unsigned hash_tab_offset = 0; Dwarf_Unsigned indexes_tab_offset = 0; Dwarf_Unsigned section_offsets_tab_offset = 0; Dwarf_Unsigned section_sizes_tab_offset = 0; unsigned datalen32 = LEN32BIT; Dwarf_Small *section_end = 0; if (!strcmp(section_type,"cu") ) { sect = &dbg->de_debug_cu_index; } else if (!strcmp(section_type,"tu") ) { sect = &dbg->de_debug_tu_index; } else { _dwarf_error(dbg, error, DW_DLE_XU_TYPE_ARG_ERROR); return DW_DLV_ERROR; } if (!sect->dss_size) { return DW_DLV_NO_ENTRY; } if (!sect->dss_data) { res = _dwarf_load_section(dbg, sect,error); if (res != DW_DLV_OK) { return res; } } data = sect->dss_data; section_end = data + sect->dss_size; if (sect->dss_size < (4*datalen32) ) { _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg,local_version, Dwarf_Unsigned, data,datalen32, error,section_end); data += datalen32; READ_UNALIGNED_CK(dbg,num_col, Dwarf_Unsigned, data,datalen32, error,section_end); data += datalen32; READ_UNALIGNED_CK(dbg,num_CUs, Dwarf_Unsigned, data,datalen32, error,section_end); data += datalen32; READ_UNALIGNED_CK(dbg,num_slots, Dwarf_Unsigned, data,datalen32, error,section_end); hash_tab_offset = datalen32*4; indexes_tab_offset = hash_tab_offset + (num_slots * HASHSIGNATURELEN); /* Look for corrupt section data. */ if (num_slots > sect->dss_size) { _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } if ( (4*num_slots) > sect->dss_size) { _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } section_offsets_tab_offset = indexes_tab_offset + (num_slots *datalen32); if ( num_col > sect->dss_size) { /* Something is badly wrong here. */ _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } if ( (4*num_col) > sect->dss_size) { /* Something is badly wrong here. */ _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } section_sizes_tab_offset = section_offsets_tab_offset + ((num_CUs +1) *num_col* datalen32) ; tables_end_offset = section_sizes_tab_offset + ((num_CUs ) *num_col* datalen32); if ( tables_end_offset > sect->dss_size) { /* Something is badly wrong here. */ _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } indexptr = (Dwarf_Xu_Index_Header)_dwarf_get_alloc(dbg,DW_DLA_XU_INDEX,1); if (indexptr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } /* Only "cu" or "tu" allowed, that is checked above. But for safety we just copy the allowed bytes*/ indexptr->gx_type[0] = section_type[0]; indexptr->gx_type[1] = section_type[1]; indexptr->gx_type[2] = 0; indexptr->gx_dbg = dbg; indexptr->gx_section_length = sect->dss_size; indexptr->gx_section_data = sect->dss_data; indexptr->gx_section_name = sect->dss_name; indexptr->gx_version = local_version; indexptr->gx_column_count_sections = num_col; indexptr->gx_units_in_index = num_CUs; indexptr->gx_slots_in_hash = num_slots; indexptr->gx_hash_table_offset = hash_tab_offset; indexptr->gx_index_table_offset = indexes_tab_offset; indexptr->gx_section_offsets_offset = section_offsets_tab_offset; indexptr->gx_section_sizes_offset = section_sizes_tab_offset; *xuptr = indexptr; *version = indexptr->gx_version; *number_of_columns = indexptr->gx_column_count_sections; *number_of_CUs = indexptr->gx_units_in_index; *number_of_slots = indexptr->gx_slots_in_hash; *section_name = indexptr->gx_section_name; return DW_DLV_OK; } int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header xuhdr, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** typename, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** sectionname, UNUSEDARG Dwarf_Error * err) { *typename = &xuhdr->gx_type[0]; *sectionname = xuhdr->gx_section_name; return DW_DLV_OK; } /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned index, /* returns the hash value. 64 bits. */ Dwarf_Sig8 * hash_value, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * index_to_sections, Dwarf_Error * err) { Dwarf_Debug dbg = xuhdr->gx_dbg; Dwarf_Small *hashtab = xuhdr->gx_section_data + xuhdr->gx_hash_table_offset; Dwarf_Small *indextab = xuhdr->gx_section_data + xuhdr->gx_index_table_offset; Dwarf_Small *indexentry = 0; Dwarf_Small *hashentry = 0; Dwarf_Sig8 hashval; Dwarf_Unsigned indexval = 0; Dwarf_Small *section_end = xuhdr->gx_section_data + xuhdr->gx_section_length; memset(&hashval,0,sizeof(hashval)); if (xuhdr->gx_slots_in_hash > 0) { if (index >= xuhdr->gx_slots_in_hash) { _dwarf_error(dbg, err, DW_DLE_XU_HASH_ROW_ERROR); return DW_DLV_ERROR; } hashentry = hashtab + (index * HASHSIGNATURELEN); memcpy(&hashval,hashentry,sizeof(hashval)); } else { _dwarf_error(dbg, err, DW_DLE_XU_HASH_ROW_ERROR); return DW_DLV_ERROR; } indexentry = indextab + (index * LEN32BIT); memcpy(hash_value,&hashval,sizeof(hashval)); READ_UNALIGNED_CK(dbg,indexval,Dwarf_Unsigned, indexentry, LEN32BIT, err,section_end); if (indexval > xuhdr->gx_units_in_index) { _dwarf_error(dbg, err, DW_DLE_XU_HASH_INDEX_ERROR); return DW_DLV_ERROR; } *index_to_sections = indexval; return DW_DLV_OK; } static const char * dwp_secnames[] = { "No name for zero", "DW_SECT_INFO" /* 1 */ /*".debug_info.dwo"*/, "DW_SECT_TYPES" /* 2 */ /*".debug_types.dwo"*/, "DW_SECT_ABBREV" /* 3 */ /*".debug_abbrev.dwo"*/, "DW_SECT_LINE" /* 4 */ /*".debug_line.dwo"*/, "DW_SECT_LOC" /* 5 */ /*".debug_loc.dwo"*/, "DW_SECT_STR_OFFSETS" /* 6 */ /*".debug_str_offsets.dwo"*/, "DW_SECT_MACRO" /* 7 */ /*".debug_macro.dwo"*/, "DW_SECT_RNGLISTS" /* 8 */ /*".debug_rnglists.dwo"*/, "No name > 8", }; /* Row 0 of the Table of Section Offsets, columns 0 to L-1, are the section id's, and names, such as DW_SECT_INFO (ie, 1) */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned column_index, Dwarf_Unsigned* number, const char ** name, Dwarf_Error * err) { Dwarf_Unsigned sec_num = 0; Dwarf_Small *section_end = xuhdr->gx_section_data + xuhdr->gx_section_length; Dwarf_Debug dbg = xuhdr->gx_dbg; Dwarf_Small *namerow = xuhdr->gx_section_offsets_offset + xuhdr->gx_section_data; Dwarf_Small *nameloc = 0; if( column_index >= xuhdr->gx_column_count_sections) { _dwarf_error(dbg, err, DW_DLE_XU_NAME_COL_ERROR); return DW_DLV_ERROR; } nameloc = namerow + LEN32BIT *column_index; READ_UNALIGNED_CK(dbg,sec_num,Dwarf_Unsigned, nameloc, LEN32BIT, err,section_end); if (sec_num > DW_SECT_RNGLISTS) { _dwarf_error(dbg, err, DW_DLE_XU_NAME_COL_ERROR); return DW_DLV_ERROR; } if (sec_num < 1) { return DW_DLV_NO_ENTRY; } *number = sec_num; *name = dwp_secnames[sec_num]; return DW_DLV_OK; } /* Rows 1 to N col 0 to L-1 are section offset and length values from the Table of Section Offsets and Table of Section Sizes. */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned row_index, Dwarf_Unsigned column_index, Dwarf_Unsigned* sec_offset, Dwarf_Unsigned* sec_size, Dwarf_Error * err) { Dwarf_Debug dbg = xuhdr->gx_dbg; /* get to base of tables first. */ Dwarf_Small *offsetrow = xuhdr->gx_section_offsets_offset + xuhdr->gx_section_data; Dwarf_Small *sizerow = xuhdr->gx_section_sizes_offset + xuhdr->gx_section_data; Dwarf_Small *offsetentry = 0; Dwarf_Small *sizeentry = 0; Dwarf_Unsigned offset = 0; Dwarf_Unsigned size = 0; Dwarf_Unsigned column_count = xuhdr->gx_column_count_sections; Dwarf_Small *section_end = xuhdr->gx_section_data + xuhdr->gx_section_length; if( row_index > xuhdr->gx_units_in_index) { _dwarf_error(dbg, err, DW_DLE_XU_NAME_COL_ERROR); return DW_DLV_ERROR; } if( row_index < 1 ) { _dwarf_error(dbg, err, DW_DLE_XU_NAME_COL_ERROR); return DW_DLV_ERROR; } if( column_index >= xuhdr->gx_column_count_sections) { _dwarf_error(dbg, err, DW_DLE_XU_NAME_COL_ERROR); return DW_DLV_ERROR; } offsetrow = offsetrow + (row_index*column_count * LEN32BIT); offsetentry = offsetrow + (column_index * LEN32BIT); sizerow = sizerow + ((row_index-1)*column_count * LEN32BIT); sizeentry = sizerow + (column_index * LEN32BIT); READ_UNALIGNED_CK(dbg,offset,Dwarf_Unsigned, offsetentry, LEN32BIT,err,section_end); READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned, sizeentry, LEN32BIT,err,section_end); *sec_offset = offset; *sec_size = size; return DW_DLV_OK; } static int _dwarf_search_fission_for_key(UNUSEDARG Dwarf_Debug dbg, Dwarf_Xu_Index_Header xuhdr, Dwarf_Sig8 *key_in, Dwarf_Unsigned * percu_index_out, Dwarf_Error *error) { Dwarf_Unsigned key = 0; Dwarf_Unsigned primary_hash = 0; Dwarf_Unsigned hashprime = 0; Dwarf_Unsigned slots = xuhdr->gx_slots_in_hash; Dwarf_Unsigned mask = slots -1; Dwarf_Sig8 hashentry_key; Dwarf_Unsigned percu_index = 0; /* Look for corrupt section data. */ if (slots > xuhdr->gx_section_length) { /* Something is badly wrong here. */ _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } if ( (4*slots) > xuhdr->gx_section_length) { /* Something is badly wrong here. */ _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_XU_INDEX_SECTION); return (DW_DLV_ERROR); } if (sizeof (key) != sizeof(key_in)) { /* The hash won't work right in this case */ _dwarf_error(dbg, error, DW_DLE_XU_HASH_ROW_ERROR); } ASNAR(key,key_in,sizeof(*key_in)); primary_hash = key & mask; hashprime = (((key >>32) &mask) |1); while (1) { int res = 0; res = dwarf_get_xu_hash_entry(xuhdr, primary_hash,&hashentry_key, &percu_index,error); if (res != DW_DLV_OK) { return res; } if (percu_index == 0 && !memcmp(&hashentry_key,&zerohashkey,sizeof(Dwarf_Sig8))) { return DW_DLV_NO_ENTRY; } if (!memcmp(key_in,&hashentry_key,sizeof(Dwarf_Sig8))) { /* FOUND */ *percu_index_out = percu_index; return DW_DLV_OK; } primary_hash = (primary_hash + hashprime) % slots; } /* ASSERT: Cannot get here. */ return DW_DLV_NO_ENTRY; } /* Slow. Consider tsearch. */ /* For type units and for CUs. */ /* We're finding an index entry refers to a global offset in some CU and hence is unique in the target. */ static int _dwarf_search_fission_for_offset(Dwarf_Debug dbg, Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned offset, Dwarf_Unsigned dfp_sect_num, /* DW_SECT_INFO or TYPES */ Dwarf_Unsigned * percu_index_out, Dwarf_Sig8 * key_out, Dwarf_Error *error) { Dwarf_Unsigned i = 0; Dwarf_Unsigned m = 0; int secnum_index = -1; /* L index */ int res = 0; for ( i = 0; i< xuhdr->gx_column_count_sections; i++) { /* We could put the secnums array into xuhdr if looping here is too slow. */ const char *name = 0; Dwarf_Unsigned num = 0; res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error); if (res != DW_DLV_OK) { return res; } if (num == dfp_sect_num) { secnum_index = i; break; } } if (secnum_index == -1) { _dwarf_error(dbg,error,DW_DLE_FISSION_SECNUM_ERR); return DW_DLV_ERROR; } for ( m = 0; m < xuhdr->gx_slots_in_hash; ++m) { Dwarf_Sig8 hash; Dwarf_Unsigned indexn = 0; Dwarf_Unsigned sec_offset = 0; Dwarf_Unsigned sec_size = 0; res = dwarf_get_xu_hash_entry(xuhdr,m,&hash,&indexn,error); if (res != DW_DLV_OK) { return res; } if (indexn == 0 && !memcmp(&hash,&zerohashkey,sizeof(Dwarf_Sig8))) { /* Empty slot. */ continue; } res = dwarf_get_xu_section_offset(xuhdr, indexn,secnum_index,&sec_offset,&sec_size,error); if (res != DW_DLV_OK) { return res; } if (sec_offset != offset) { continue; } *percu_index_out = indexn; *key_out = hash; return DW_DLV_OK; } return DW_DLV_NO_ENTRY; } static int _dwarf_get_xuhdr(Dwarf_Debug dbg, const char *sigtype, Dwarf_Xu_Index_Header *xuout, Dwarf_Error *error) { if (!strcmp(sigtype,"tu")) { if (!dbg->de_tu_hashindex_data) { return DW_DLV_NO_ENTRY; } *xuout = dbg->de_tu_hashindex_data; } else if (!strcmp(sigtype,"cu")) { if (!dbg->de_cu_hashindex_data) { return DW_DLV_NO_ENTRY; } *xuout = dbg->de_cu_hashindex_data; } else { _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING); return DW_DLV_ERROR; } return DW_DLV_OK; } static int transform_xu_to_dfp(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned percu_index, Dwarf_Sig8 *key, const char *sig_type, Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error *error) { unsigned i = 0; unsigned l = 0; unsigned n = 1; unsigned max_cols = xuhdr->gx_column_count_sections; /* L */ unsigned secnums[DW_FISSION_SECT_COUNT]; int res; for ( i = 0; i< max_cols; i++) { /* We could put the secnums array into xuhdr if recreating it is too slow. */ const char *name = 0; Dwarf_Unsigned num = 0; res = dwarf_get_xu_section_names(xuhdr,i,&num,&name,error); if (res != DW_DLV_OK) { return res; } secnums[i] = num; } n = percu_index; for(l = 0; l < max_cols; ++l) { /* L */ Dwarf_Unsigned sec_off = 0; Dwarf_Unsigned sec_size = 0; unsigned l_as_sect = secnums[l]; res = dwarf_get_xu_section_offset(xuhdr,n,l, &sec_off,&sec_size,error); if (res != DW_DLV_OK) { return res; } percu_out->pcu_offset[l_as_sect] = sec_off; percu_out->pcu_size[l_as_sect] = sec_size; } percu_out->pcu_type = sig_type; percu_out->pcu_index = percu_index; percu_out->pcu_hash = *key; return DW_DLV_OK; } /* This should only be called for a CU, never a TU. For a TU the type hash is known while reading the TU Header. Not so for a CU. */ int _dwarf_get_debugfission_for_offset(Dwarf_Debug dbg, Dwarf_Off offset_wanted, const char * key_type, /* "cu" or "tu" */ struct Dwarf_Debug_Fission_Per_CU_s * percu_out, Dwarf_Error *error) { Dwarf_Xu_Index_Header xuhdr = 0; int sres = 0; Dwarf_Unsigned percu_index = 0; Dwarf_Unsigned sect_index_base = 0; Dwarf_Sig8 key; sect_index_base = DW_SECT_INFO; memset(&key,0,sizeof(key)); sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error); if (sres != DW_DLV_OK) { return sres; } sres = _dwarf_search_fission_for_offset(dbg, xuhdr,offset_wanted, sect_index_base, &percu_index, &key, error); if (sres != DW_DLV_OK) { return sres; } sres = transform_xu_to_dfp(xuhdr,percu_index,&key, key_type,percu_out, error); return sres; } int dwarf_get_debugfission_for_key(Dwarf_Debug dbg, Dwarf_Sig8 * key /* pointer to hash signature */, const char * key_type /* "cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error * error ) { Dwarf_Xu_Index_Header xuhdr = 0; int sres = 0; Dwarf_Unsigned percu_index = 0; sres = _dwarf_load_debug_info(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } sres = _dwarf_load_debug_types(dbg,error); if (sres == DW_DLV_ERROR) { return sres; } /* Returns already existing xuhdr */ sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error); if (sres != DW_DLV_OK) { return sres; } /* Search in that xu data. */ sres = _dwarf_search_fission_for_key(dbg, xuhdr,key,&percu_index,error); if (sres != DW_DLV_OK) { return sres; } sres = transform_xu_to_dfp(xuhdr,percu_index,key,key_type,percu_out,error); return sres; } void dwarf_xu_header_free(Dwarf_Xu_Index_Header indexptr) { if(indexptr) { Dwarf_Debug dbg = indexptr->gx_dbg; dwarf_dealloc(dbg,indexptr,DW_DLA_XU_INDEX); } } dwarfutils-20200114/libdwarf/dwarf_xu_index.h000066400000000000000000000037471361531463500211240ustar00rootroot00000000000000#ifndef DWARF_XU_INDEX_H #define DWARF_XU_INDEX_H /* Copyright (C) 2014-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The following is based on The gdb online documentation at https://gcc.gnu.org/wiki/DebugFissionDWP and the draft DWARF5 standard. */ struct Dwarf_Xu_Index_Header_s { Dwarf_Debug gx_dbg; Dwarf_Small * gx_section_data; Dwarf_Unsigned gx_section_length; Dwarf_Unsigned gx_version; Dwarf_Unsigned gx_column_count_sections; /* L */ Dwarf_Unsigned gx_units_in_index; /* N */ Dwarf_Unsigned gx_slots_in_hash; /* M */ Dwarf_Unsigned gx_hash_table_offset; Dwarf_Unsigned gx_index_table_offset; Dwarf_Unsigned gx_section_offsets_offset; Dwarf_Unsigned gx_section_sizes_offset; /* "tu" or "cu" without the quotes, of course. NUL terminated. */ char gx_type[4]; /* Do not free gx_section_name. */ const char * gx_section_name; }; #endif /* DWARF_XU_INDEX_H */ dwarfutils-20200114/libdwarf/dwarfstring.c000066400000000000000000000467171361531463500204470ustar00rootroot00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* A lighly generalized data buffer. Works for more than just strings, but has features (such as ensuring data always has a NUL byte following the data area used) most useful for C strings. */ #include "config.h" #include /* for malloc */ #ifdef HAVE_STDLIB_H #include /* for malloc */ #endif /* HAVE_STDLIB_H */ #include /* for strlen */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "dwarfstring.h" #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #ifndef FALSE #define FALSE 0 #endif /* FALSE */ #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #ifndef DW_DLV_OK /* DW_DLV_OK must match libdwarf.h */ /* DW_DLV_ERROR must match libdwarf.h */ /* DW_DLV_NO_ENTRY unused here */ #define DW_DLV_OK 0 #define DW_DLV_NO_ENTRY -1 #define DW_DLV_ERROR 1 #endif /* DW_DLV_OK */ static unsigned long minimumnewlen = 30; /* struct dwarfstring_s { char * s_data; unsigned long s_size; unsigned long s_avail; unsigned char s_malloc; }; */ int dwarfstring_constructor(struct dwarfstring_s *g) { g->s_data = ""; g->s_size = 0; g->s_avail = 0; g->s_malloc = FALSE; return TRUE; } static int dwarfstring_resize_to(struct dwarfstring_s *g,unsigned long newlen) { char *b = 0; unsigned long lastpos = g->s_size - g->s_avail; unsigned long malloclen = newlen+1; if(malloclen < minimumnewlen) { malloclen = minimumnewlen; } b = malloc(malloclen); if (!b) { return FALSE; } if (lastpos > 0) { memcpy(b,g->s_data,lastpos); } if (g->s_malloc) { free(g->s_data); g->s_data = 0; } g->s_data = b; g->s_data[lastpos] = 0; g->s_size = newlen; g->s_avail = newlen - lastpos; g->s_malloc = TRUE; return TRUE; } int dwarfstring_reset(struct dwarfstring_s *g) { if (!g->s_size) { /* In initial condition, nothing to do. */ return TRUE; } g->s_avail = g->s_size; g->s_data[0] = 0; return TRUE; } int dwarfstring_constructor_fixed(struct dwarfstring_s *g,unsigned long len) { int r = FALSE; dwarfstring_constructor(g); if (len == 0) { return TRUE; } r = dwarfstring_resize_to(g,len); if (!r) { return FALSE; } return TRUE; } int dwarfstring_constructor_static(struct dwarfstring_s *g, char * space, unsigned long len) { dwarfstring_constructor(g); g->s_data = space; g->s_data[0] = 0; g->s_size = len; g->s_avail = len; g->s_malloc = FALSE; return TRUE; } void dwarfstring_destructor(struct dwarfstring_s *g) { if (g->s_malloc) { free(g->s_data); g->s_data = 0; } dwarfstring_constructor(g); } /* For the case where one wants just the first 'len' characters of 'str'. NUL terminator provided for you in s_data. */ int dwarfstring_append_length(struct dwarfstring_s *g,char *str, unsigned long slen) { unsigned long lastpos = g->s_size - g->s_avail; int r = 0; if (!str || slen ==0) { return TRUE; } if (slen >= g->s_avail) { unsigned long newlen = 0; newlen = g->s_size + slen+2; r = dwarfstring_resize_to(g,newlen); if (!r) { return FALSE; } } memcpy(g->s_data + lastpos,str,slen); g->s_avail -= slen; g->s_data[g->s_size - g->s_avail] = 0; return TRUE; } int dwarfstring_append(struct dwarfstring_s *g,char *str) { unsigned long dlen = 0; if(!str) { return TRUE; } dlen = strlen(str); return dwarfstring_append_length(g,str,dlen); } char * dwarfstring_string(struct dwarfstring_s *g) { return g->s_data; } unsigned long dwarfstring_strlen(struct dwarfstring_s *g) { return g->s_size - g->s_avail; } static int _dwarfstring_append_spaces(dwarfstring *data, size_t count) { int res = 0; char spacebuf[] = {" "}; size_t charct = sizeof(spacebuf)-1; size_t l = count; while (l > charct) { res = dwarfstring_append_length(data,spacebuf,charct); l -= charct; if (res != DW_DLV_OK) { return res; } } /* ASSERT: l > 0 */ res = dwarfstring_append_length(data,spacebuf,l); return res; } static int _dwarfstring_append_zeros(dwarfstring *data, size_t l) { int res = 0; static char zeros[] = {"0000000000000000000000000000000000000000"}; size_t charct = sizeof(zeros)-1; while (l > charct) { res = dwarfstring_append_length(data,zeros,charct); l -= charct; if (res != DW_DLV_OK) { return res; } } /* ASSERT: l > 0 */ dwarfstring_append_length(data,zeros,l); return res; } int dwarfstring_append_printf_s(dwarfstring *data, char *format,char *s) { size_t stringlen = strlen(s); size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; /* was %[-]fixedlen. Zero means no len provided. */ size_t fixedlen = 0; /* was %-, nonzero means left-justify */ long leftjustify = 0; size_t prefixlen = 0; int res = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } if (prefixlen) { dwarfstring_append_length(data,format,prefixlen); } if (!format[next]) { return DW_DLV_OK; } next++; if (format[next] == '-') { leftjustify++; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); if (format[next] != 's') { return DW_DLV_ERROR; } next++; if (leftjustify) { if (fixedlen && fixedlen <= stringlen) { /* This lets us have fixedlen < stringlen */ dwarfstring_append_length(data,s,fixedlen); } else { dwarfstring_append_length(data,s,stringlen); if(fixedlen) { size_t trailingspaces = fixedlen - stringlen; _dwarfstring_append_spaces(data,trailingspaces); } } } else { if (fixedlen && fixedlen <= stringlen) { /* This lets us have fixedlen < stringlen */ dwarfstring_append_length(data,s,fixedlen); } else { if(fixedlen) { size_t leadingspaces = fixedlen - stringlen; size_t k = 0; for ( ; k < leadingspaces; ++k) { dwarfstring_append_length(data," ",1); } } dwarfstring_append_length(data,s,stringlen); } } if (!format[next]) { return DW_DLV_OK; } { char * startpt = format+next; size_t suffixlen = strlen(startpt); res = dwarfstring_append_length(data,startpt,suffixlen); } return res; } static char v32m[] = {"-2147483648"}; static char v64m[] = {"-9223372036854775808"}; static char dtable[10] = { '0','1','2','3','4','5','6','7','8','9' }; static char xtable[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; static char Xtable[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; /* We deal with formats like: %d %5d %05d %+d %+5d (and ld and lld too). */ int dwarfstring_append_printf_i(dwarfstring *data, char *format, dwarfstring_i v) { int res = DW_DLV_OK; size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int pluscount = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = dtable; size_t prefixlen = 0; int done = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } dwarfstring_append_length(data,format,prefixlen); if (format[next] != '%') { /* No % operator found, we are done */ return DW_DLV_OK; } next++; if (format[next] == '-') { /*ESBERR("ESBERR_printf_i - format not supported"); */ next++; } if (format[next] == '+') { pluscount++; next++; } if (format[next] == '0') { leadingzero = 1; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { /* ESBERR("ESBERR_pct_scount_in_i"); */ return DW_DLV_ERROR; } if (!dcount || (lcount >2) || (Xcount +xcount+dcount+ucount) > 1) { /* error */ /* ESBERR("ESBERR_xcount_etc_i"); */ return DW_DLV_ERROR; } { char digbuf[36]; char *digptr = digbuf+sizeof(digbuf) -1; size_t digcharlen = 0; dwarfstring_i remaining = v; int vissigned = 0; dwarfstring_i divisor = 10; *digptr = 0; --digptr; if (v < 0) { vissigned = 1; /* This test is for twos-complement machines and would be better done via configure with a compile-time check so we do not need a size test at runtime. */ if (sizeof(v) == 8) { dwarfstring_u vm = 0x7fffffffffffffffULL; if (vm == (dwarfstring_u)~v) { memcpy(digbuf,v64m,sizeof(v64m)); digcharlen = sizeof(v64m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } } else if (sizeof(v) == 4) { dwarfstring_u vm = 0x7fffffffL; if (vm == (dwarfstring_u)~v) { memcpy(digbuf,v32m,sizeof(v32m)); digcharlen = sizeof(v32m)-1; digptr = digbuf; done = 1; } else { remaining = -v; } }else { /* ESBERR("ESBERR_sizeof_v_i"); */ /* error */ return DW_DLV_ERROR; } } if(!done) { for ( ;; ) { dwarfstring_u dig = 0; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; digcharlen++; if (!remaining) { break; } --digptr; } if (vissigned) { --digptr; digcharlen++; *digptr = '-'; } else if (pluscount) { --digptr; digcharlen++; *digptr = '+'; } } if (fixedlen > 0) { if (fixedlen <= digcharlen) { dwarfstring_append_length(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; if (!leadingzero) { _dwarfstring_append_spaces(data,prefixcount); dwarfstring_append_length(data,digptr,digcharlen); } else { if (*digptr == '-') { dwarfstring_append_length(data,"-",1); _dwarfstring_append_zeros(data,prefixcount); digptr++; dwarfstring_append_length(data,digptr, digcharlen-1); } else if (*digptr == '+') { dwarfstring_append_length(data,"+",1); _dwarfstring_append_zeros(data,prefixcount); digptr++; dwarfstring_append_length(data,digptr, digcharlen-1); } else { _dwarfstring_append_zeros(data,prefixcount); dwarfstring_append_length(data,digptr, digcharlen); } } } } else { res = dwarfstring_append_length(data,digptr,digcharlen); } } if (format[next]) { size_t trailinglen = strlen(format+next); res = dwarfstring_append_length(data,format+next,trailinglen); } return res; } #if 0 /* Counts hex chars. divide by two to get bytes from input integer. */ static unsigned trimleadingzeros(char *ptr,unsigned digits,unsigned keepcount) { char *cp = ptr; unsigned leadzeroscount = 0; unsigned trimoff = 0; for(; *cp; ++cp) { if (*cp == '0') { leadzeroscount++; continue; } } trimoff = keepcount - digits; if (trimoff&1) { trimoff--; } return trimoff; } #endif /* 0 */ /* With gcc version 5.4.0 20160609 a version using const char *formatp instead of format[next] and deleting the 'next' variable is a few hundredths of a second slower, repeatably. We deal with formats like: %u %5u %05u (and ld and lld too). %x %5x %05x (and ld and lld too). */ int dwarfstring_append_printf_u(dwarfstring *data, char *format, dwarfstring_u v) { size_t next = 0; long val = 0; char *endptr = 0; const char *numptr = 0; size_t fixedlen = 0; int leadingzero = 0; int lcount = 0; int ucount = 0; int dcount = 0; int xcount = 0; int Xcount = 0; char *ctable = 0; size_t divisor = 0; size_t prefixlen = 0; while (format[next] && format[next] != '%') { ++next; ++prefixlen; } dwarfstring_append_length(data,format,prefixlen); if (format[next] != '%') { /* No % operator found, we are done */ /*ESBERR("ESBERR..esb_append_printf_u has no % operator"); */ return DW_DLV_OK; } next++; if (format[next] == '-') { /*ESBERR("ESBERR_printf_u - format not supported"); */ next++; } if (format[next] == '0') { leadingzero = 1; next++; } numptr = format+next; val = strtol(numptr,&endptr,10); if ( endptr != numptr) { fixedlen = val; } next = (endptr - format); /* Following is lx lu or u or llx llu , we take all this to mean 64 bits, */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) if (format[next] == 'I') { /*lcount++;*/ next++; } if (format[next] == '6') { /*lcount++;*/ next++; } if (format[next] == '4') { /*lcount++;*/ next++; } #endif /* HAVE_NONSTANDARD_PRINTF_64_FORMAT */ if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'l') { lcount++; next++; } if (format[next] == 'u') { ucount++; next++; } if (format[next] == 'd') { dcount++; next++; } if (format[next] == 'x') { xcount++; next++; } if (format[next] == 'X') { Xcount++; next++; } if (format[next] == 's') { /* ESBERR("ESBERR_pct_scount_in_u"); */ return DW_DLV_ERROR; } if ( (Xcount +xcount+dcount+ucount) > 1) { /* ESBERR("ESBERR_pct_xcount_etc_u"); */ return DW_DLV_ERROR; } if (lcount > 2) { /* ESBERR("ESBERR_pct_lcount_error_u"); */ /* error */ return DW_DLV_ERROR; } if (dcount > 0) { /*ESBERR("ESBERR_pct_dcount_error_u");*/ /* error */ return DW_DLV_ERROR; } if (ucount) { divisor = 10; ctable = dtable; } else { divisor = 16; if (xcount) { ctable = xtable; } else { ctable = Xtable; } } { char digbuf[36]; char *digptr = 0; unsigned digcharlen = 0; dwarfstring_u remaining = v; if (divisor == 16) { digptr = digbuf+sizeof(digbuf) -1; for ( ;; ) { dwarfstring_u dig; dig = remaining & 0xf; remaining = remaining >> 4; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } else { digptr = digbuf+sizeof(digbuf) -1; *digptr = 0; --digptr; for ( ;; ) { dwarfstring_u dig; dig = remaining % divisor; remaining /= divisor; *digptr = ctable[dig]; ++digcharlen; if (!remaining) { break; } --digptr; } } if (fixedlen <= digcharlen) { dwarfstring_append_length(data,digptr,digcharlen); } else { if (!leadingzero) { size_t justcount = fixedlen - digcharlen; _dwarfstring_append_spaces(data,justcount); dwarfstring_append_length(data,digptr,digcharlen); } else { size_t prefixcount = fixedlen - digcharlen; _dwarfstring_append_zeros(data,prefixcount); dwarfstring_append_length(data,digptr,digcharlen); } } } if (format[next]) { size_t trailinglen = strlen(format+next); dwarfstring_append_length(data,format+next,trailinglen); } return DW_DLV_OK; } dwarfutils-20200114/libdwarf/dwarfstring.h000066400000000000000000000053421361531463500204410ustar00rootroot00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* A lightly generalized string buffer for libdwarf. */ #ifndef DWARFSTRING_H #define DWARFSTRING_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct dwarfstring_s { char * s_data; unsigned long s_size; unsigned long s_avail; unsigned char s_malloc; }; typedef unsigned long long dwarfstring_u; typedef signed long long dwarfstring_i; typedef struct dwarfstring_s dwarfstring; int dwarfstring_constructor(struct dwarfstring_s *g); int dwarfstring_constructor_fixed(struct dwarfstring_s *g, unsigned long len); int dwarfstring_constructor_static(struct dwarfstring_s *g, char * space, unsigned long len); void dwarfstring_destructor(struct dwarfstring_s *g); int dwarfstring_reset(struct dwarfstring_s *g); int dwarfstring_append(struct dwarfstring_s *g,char *str); /* When one wants the first 'len' characters of str appended. NUL termination is provided by dwarfstrings. */ int dwarfstring_append_length(struct dwarfstring_s *g, char *str,unsigned long len); int dwarfstring_append_printf_s(dwarfstring *data, char *format,char *s); int dwarfstring_append_printf_i(dwarfstring *data, char *format,dwarfstring_i); int dwarfstring_append_printf_u(dwarfstring *data, char *format,dwarfstring_u); char * dwarfstring_string(struct dwarfstring_s *g); unsigned long dwarfstring_strlen(struct dwarfstring_s *g); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* DWARFSTRING_H */ dwarfutils-20200114/libdwarf/dwgetopt.c000066400000000000000000000260631361531463500177420ustar00rootroot00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). renamed to make it clear this is a private version. Oct 17 2017: Created dwgetopt_long(). See dwgetopt.h */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* This does not presently handle the option string leading + or leading - features. Such are not used by by libdwarfdump. Nor does it understand the GNU Env var POSIXLY_CORRECT . It does know of the leading ":" in the option string. See BADCH below. */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include /* For strchr */ #include "dwgetopt.h" #define STRIP_OFF_CONSTNESS(a) ((void *)(size_t)(const void *)(a)) int dwopterr = 1, /* if error message should be printed */ dwoptind = 1, /* index into parent argv vector */ dwoptopt, /* character checked for validity */ dwoptreset; /* reset getopt */ char *dwoptarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG "" #define TRUE 1 #define FALSE 0 #if 0 /* FOR DEBUGGING ONLY */ /* Use for testing dwgetopt only. Not a standard function. */ void dwgetoptresetfortestingonly(void) { dwopterr = 1; dwoptind = 1; dwoptopt = 0; dwoptreset = 0; dwoptarg = 0; } #endif /* FOR DEBUGGING ONLY */ static const char *place = EMSG;/* option letter processing */ /* Post Condition: if return FALSE then *argerr is set false. */ static int dwoptnamematches( const struct dwoption *dwlopt, const char *iplace, const char **argloc, int *argerr) { const char *eq = 0; size_t namelen = 0; size_t arglen = 0; int d = 0; for(eq = iplace; *eq; ++eq) { if (*eq != '=') { continue; } /* Found =, arg should follow */ namelen = (eq - iplace); if (namelen != (unsigned)strlen(dwlopt->name)) { return FALSE; } eq++; arglen = strlen(eq); break; } if (namelen) { d = strncmp(iplace,dwlopt->name,namelen); if (d) { return FALSE; } if (dwlopt->has_arg == 0) { *argerr = TRUE; return TRUE; } if (arglen) { /* Discarding const, avoiding warning. Data is in user space, so this is ok. */ dwoptarg = (char *)eq; *argloc = (const char *)eq; } else { /* Has arg = but arg is empty. */ dwoptarg = 0; } return TRUE; } else { d = strcmp(iplace,dwlopt->name); if (d) { return FALSE; } if (dwlopt->has_arg == 1) { *argerr = TRUE; return TRUE; } dwoptarg = 0; return TRUE; } } /* dwgetopt_long A reimplemenation of a portion of the getopt(3) GNU/Linux getopt_long(). See dwgetopt.h for more details. */ int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex) { char *lplace = 0; if (dwoptreset) { /* Not really supported. */ place = EMSG; return (-1); } if (*place) { int v = dwgetopt(nargc,nargv,ostr); return v; } /* Use local lplace in case we need to call getopt() just below. */ lplace = nargv[dwoptind]; if (dwoptind >= nargc || *lplace++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } if (*lplace != '-') { /* Notice place not disturbed. */ int v = dwgetopt(nargc,nargv,ostr); return v; } /* Starts with two dashes. Now we set the global place */ place = lplace+1; if (!*place) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } /* We think this is a longopt. */ { int lo_num = 0; for(;;lo_num++) { const struct dwoption *dwlopt = longopts +lo_num; const char * argloc = 0; int argerr = 0; int resmatch = 0; if (!dwlopt->name) { dwoptind++; (void)fprintf(stderr, "%s: invalid long option '--%s'\n", nargv[0]?nargv[0]:"", place); /* Leave longindex unchanged. */ place = EMSG; return (BADCH); } resmatch= dwoptnamematches(dwlopt,place, &argloc,&argerr); if (resmatch) { dwoptarg = 0; if (argloc) { /* Must drop const here. Ugh. */ dwoptarg = (char *)argloc; } } if (argerr) { /* resmatch == TRUE arg option missing if required, present but not allowed. GNU Behavior not well documented. Had to experiment. if argument-not-allowed, and we have one, do ??? If argument-required, then here GNU would take the next argv as the argument. we are not currently doing that. */ /**longindex = lo_num; */ if (dwlopt->has_arg) { /* Missing required arg, this does not match GNU getopt_long behavior of taking next argv as the arg value. and thus making getopt_long succeed. */ (void)fprintf(stderr, "%s: missing required long option argument '--%s'\n", nargv[0]?nargv[0]:"", place); } else { /* has arg but should not */ (void)fprintf(stderr, "%s: option '--%s' does not allow an argument\n", nargv[0]?nargv[0]:"", dwlopt->name); } dwoptind++; place = EMSG; return (BADCH); } if (resmatch) { *longindex = lo_num; place = EMSG; dwoptind++; return dwlopt->val; } } /* Can never get here */ place = EMSG; dwoptind++; return (-1); } } /* * getopt -- * Parse argc/argv argument vector. * a: means * -afoo * -a foo * and 'foo' is returned in dwoptarg * b:: means * -b * and dwoptarg is null * -bother * and dwoptarg is 'other' */ int dwgetopt(int nargc, char * const nargv[], const char *ostr) { char *oli; /* option letter list index */ if (dwoptreset || *place == 0) { /* update scanning pointer */ dwoptreset = 0; place = nargv[dwoptind]; if (dwoptind >= nargc || *place++ != '-') { /* Argument is absent or is not an option */ place = EMSG; return (-1); } dwoptopt = *place++; if (dwoptopt == '-' && *place == 0) { /* "--" => end of options */ ++dwoptind; place = EMSG; return (-1); } if (dwoptopt == 0) { /* Solitary '-', treat as a '-' option if the program (eg su) is looking for it. */ place = EMSG; if (strchr(ostr, '-') == NULL) { return -1; } dwoptopt = '-'; } } else { dwoptopt = *place++; } /* See if option letter is one the caller wanted... */ if (dwoptopt == ':' || (oli = strchr(ostr, dwoptopt)) == NULL) { if (*place == 0) { ++dwoptind; } if (dwopterr && *ostr != ':') { (void)fprintf(stderr, "%s: invalid option -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } /* Does this option need an argument? */ if (oli[1] != ':') { /* don't need argument */ dwoptarg = NULL; if (*place == 0) { ++dwoptind; } } else { int reqnextarg = 1; if (oli[1] && (oli[2] == ':')) { /* Pair of :: means special treatment of dwoptarg */ reqnextarg = 0; } /* Option-argument is either the rest of this argument or the entire next argument. */ if (*place ) { /* Whether : or :: */ dwoptarg = STRIP_OFF_CONSTNESS(place); } else if (reqnextarg) { /* ! *place */ if (nargc > (++dwoptind)) { dwoptarg = nargv[dwoptind]; } else { place=EMSG; /* Next arg required, but is missing */ if (*ostr == ':') { /* Leading : in ostr calls for BADARG return. */ return (BADARG); } if (dwopterr) { (void)fprintf(stderr, "%s: option requires an argument. -- '%c'\n", nargv[0]?nargv[0]:"", dwoptopt); } return (BADCH); } } else { /* ! *place */ /* The key part of :: treatment. */ dwoptarg = NULL; } place = EMSG; ++dwoptind; } return (dwoptopt); /* return option letter */ } dwarfutils-20200114/libdwarf/dwgetopt.h000066400000000000000000000062671361531463500177530ustar00rootroot00000000000000/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ /* Modified by David Anderson to work with GNU/Linux and freebsd. Added {} for clarity. Switched to standard dwarfdump formatting. Treatment of : modified so that :: gets dwoptarg NULL if space follows the letter (the dwoptarg is set to null). */ /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern int dwopterr; extern int dwoptind; extern int dwoptopt; extern int dwoptreset; extern char *dwoptarg; int dwgetopt(int nargc, char * const nargv[], const char *ostr); /* As of October 2017 it seems adviseable to allow long option names. So based on a reading of 'man 3 getopt' we reimplement a portion of GNU getopt_long(). It's a wonderfully sensible design and all the credit should go to the original designers. We are not implementing all the features of GNU/Linux getopt_long(), just the features we wish to use. Specifically, we require val be 0 and flag be NULL and ignore those fields. We do not implement GNU digit_optind at all. Within these restrictions the interface behaves the same as GNU getopt_long() (or so it appears from the getopt documentation: release 4.04 of the Linux man-pages project, GETOPT(3), http://www.kernel.org/doc/man-pages/). */ struct dwoption { const char *name; int has_arg; int *flag; int val; }; #define dwno_argument 0 #define dwrequired_argument 1 #define dwoptional_argument 2 int dwgetopt_long(int nargc, char *const nargv[], const char *ostr, const struct dwoption* longopts, int *longindex); #ifdef __cplusplus } #endif /* __cplusplus */ dwarfutils-20200114/libdwarf/generated_libdwarf.h.in000066400000000000000000005707041361531463500223350ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef _LIBDWARF_H #define _LIBDWARF_H #ifdef __cplusplus extern "C" { #endif /* libdwarf.h $Revision: #9 $ $Date: 2008/01/17 $ For libdwarf producers and consumers The interface is defined as having 8-byte signed and unsigned values so it can handle 64-or-32bit target on 64-or-32bit host. Dwarf_Ptr is the native size: it represents pointers on the host machine (not the target!). This contains declarations for types and all producer and consumer functions. Function declarations are written on a single line each here so one can use grep to each declaration in its entirety. The declarations are a little harder to read this way, but... The seeming duplication of the Elf typedef allows both verification we have the right struct name (when libelf.h included before this) and creation of a local handle so we have the struct pointer here (if libelf.h is not included before this file). */ typedef struct _Elf Elf; typedef struct _Elf* dwarf_elf_handle; /* To enable printing with printf regardless of the actual underlying data type, we define the DW_PR_xxx macros. To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want ensure the right DW_PR_XZEROS define is uncommented. */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" typedef unsigned long long Dwarf_Unsigned; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Addr; typedef int Dwarf_Bool; /* boolean type */ typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ /* If sizeof(Dwarf_Half) is greater than 2 we believe libdwarf still works properly. */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DSx "I64x" #define DW_PR_DUu "I64u" #define DW_PR_DSd "I64d" #else #define DW_PR_DUx "llx" #define DW_PR_DSx "llx" #define DW_PR_DUu "llu" #define DW_PR_DSd "lld" #endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ /* DWARF5: a container for a DW_FORM_data16 data item. We have no integer types suitable so this special struct is used instead. It is up to consumers/producers to deal with the contents. New October 18, 2017 . */ typedef struct Dwarf_Form_Data16_s { unsigned char fd_data[16]; } Dwarf_Form_Data16; /* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as Dwarf_Unsigned, but that is done inside libdwarf and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; }; typedef struct Dwarf_Sig8_s Dwarf_Sig8; /* Contains info on an uninterpreted block of data Used with certain frame information functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* 0 if location description, 1 if .debug_info loclist, 2 if .debug_info.dwo split dwarf loclist. */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; } Dwarf_Block; /* NEW October 2015. */ /* Dwarf_Loc_c_s,Dwarf_Locdesc_c_s, and Dwarf_Loc_Head_c_s are not defined publically. */ struct Dwarf_Loc_c_s; typedef struct Dwarf_Loc_c_s * Dwarf_Loc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Loc_c, a single location operator */ struct Dwarf_Locdesc_c_s; typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location list entry (or for a locexpr, the fake Loc_Head for the locexpr) */ struct Dwarf_Loc_Head_c_s; typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; /* NEW November 2015. For DWARF5 .debug_macro section */ struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; /* NEW September 2016. Allows easy access to DW_AT_discr_list array of discriminant values. Input in blockpointer is a block with a list of uleb or sleb numbers (all one or the other, lebunsignedflag instructs how to read the leb values properly) */ typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location operator extensions. */ typedef struct { Dwarf_Small lr_atom; /* location operation */ Dwarf_Unsigned lr_number; /* operand */ Dwarf_Unsigned lr_number2; /* for OP_BREGx and DW_OP_GNU_const_type*/ Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ } Dwarf_Loc; /* Location description. DWARF 2,3,4. When this is from a split-dwarf loclist (.debug_loc.dwo) and no tied object is present then ld_lowpc and ld_highpc are actually indices in the .debug_addr section of the tied object). If there is a tied object then these fields are actuall addresses and DW_AT_addr_base in the skeleton CU DIE applies to that .debug_addr. Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with extensions. If from DWARF2,3,4 non-split dwarf then things operate as in DWARF2. See dwarf_get_loclist_b() and the other related new functions that avoid using public structures Dwarf_Loc and Dwarf_Locdesc. */ typedef struct { /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_hipc; Dwarf_Half ld_cents; /* count of location records */ Dwarf_Loc* ld_s; /* pointer to list of same */ /* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */ Dwarf_Small ld_from_loclist; Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where loc-expr begins*/ } Dwarf_Locdesc; /* First appears in DWARF3, and only ranges entries exist. The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or both are zero (DW_RANGES_END). For DWARF5 each table starts with a header followed by range list entries defined as here. */ enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, DW_RANGES_ADDRESS_SELECTION, DW_RANGES_END }; typedef struct { Dwarf_Addr dwr_addr1; Dwarf_Addr dwr_addr2; enum Dwarf_Ranges_Entry_Type dwr_type; } Dwarf_Ranges; /* Frame description instructions expanded. */ typedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; /* Value may be signed, depends on op. Any applicable data_alignment_factor has not been applied, this is the raw offset. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h Preferably identical to DW_FRAME_LAST_REG_NUM. Ensure [0-DW_REG_TABLE_SIZE] does not overlap DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what is appropriate to your cpu. For various CPUs DW_FRAME_UNDEFINED_VAL is correct as the value for DW_FRAME_REG_INITIAL_VALUE. For consumer apps, this can be set dynamically: see dwarf_set_frame_rule_table_size(); */ #ifndef DW_REG_TABLE_SIZE #define DW_REG_TABLE_SIZE 66 #endif /* For MIPS, DW_FRAME_SAME_VAL is the correct default value for a frame register value. For other CPUS another value may be better, such as DW_FRAME_UNDEFINED_VAL. See dwarf_set_frame_rule_table_size */ #ifndef DW_FRAME_REG_INITIAL_VALUE #define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL #endif /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_SAME_VAL 1035 /* For DWARF3 consumer interfaces, make the CFA a column with no real table number. This is what should have been done for the DWARF2 interfaces. This actually works for both DWARF2 and DWARF3, but see the libdwarf documentation on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_all_regs3() Do NOT use this with the older dwarf_get_fde_info_for_reg() or dwarf_get_fde_info_for_all_regs() consumer interfaces. Must be higher than any register count for *any* ABI (ensures maximum applicability with minimum effort). Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). Only present at libdwarf runtime in the consumer interfaces. Never on disk. */ #define DW_FRAME_CFA_COL3 1436 /* The following are all needed to evaluate DWARF3 register rules. */ #define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ #define DW_EXPR_VAL_OFFSET 1 #define DW_EXPR_EXPRESSION 2 #define DW_EXPR_VAL_EXPRESSION 3 typedef struct Dwarf_Regtable_Entry_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(F) Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; /* For DWARF2, always 0 */ Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; /* The data type here should the larger of Dwarf_Addr and Dwarf_Unsigned and Dwarf_Signed. */ Dwarf_Addr dw_offset; } Dwarf_Regtable_Entry; typedef struct Dwarf_Regtable_s { struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; /* opaque type. Functional interface shown later. */ struct Dwarf_Reg_value3_s; typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; typedef struct Dwarf_Regtable_Entry3_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3 are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL and DW_FRAME_CFA_COL3 are definable at runtime consider the names symbolic in this comment, not absolute. Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: In a cfa-defining entry (rt3_cfa_rule) the regnum is the CFA 'register number'. Which is some 'normal' register, not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor DW_FRAME_UNDEFINED_VAL. If dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. So dw_offset_or_block_len is a signed value, really, and must be printed/evaluated as such. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(R) If dw_value_type == DW_EXPR_VAL_OFFSET the value of this register is CFA +N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. Rule: val_offset(N) If dw_value_type == DW_EXPR_EXPRESSION The value of the register is the value at the address computed by evaluating the DWARF expression E. Rule: expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. If dw_value_type == DW_EXPR_VAL_EXPRESSION The value of the register is the value computed by evaluating the DWARF expression E. Rule: val_expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; /* For the DWARF3 version, moved the DW_FRAME_CFA_COL out of the array and into its own struct. Having it part of the array is not very easy to work with from a portability point of view: changing the number for every architecture is a pain (if one fails to set it correctly a register rule gets clobbered when setting CFA). With MIPS it just happened to be easy to use DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...). rt3_rules and rt3_reg_table_size must be filled in before calling libdwarf. Filled in with a pointer to an array (pointer and array set up by the calling application) of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs. libdwarf does not allocate or deallocate space for the rules, you must do so. libdwarf will initialize the contents rules array, you do not need to do so (though if you choose to initialize the array somehow that is ok: libdwarf will overwrite your initializations with its own). */ typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3; /* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. Returns DW_DLV_OK if the value is available. If DW_DLV_OK returns the regnum and offset thru the pointers (which the consumer must use appropriately). */ int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Small *offset_relevant, Dwarf_Half *regnum_out, Dwarf_Signed *offset_out); /* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. Returns DW_DLV_OK if the value is available. The caller must pass in the address of a valid Dwarf_Block (the caller need not initialize it). */ int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Block *block_out); /* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller v2, adding drd_length: some relocations are 4 and some 8 bytes (pointers are 8, section offsets 4) in some dwarf environments. (MIPS relocations are all one size in any given ABI.) Changing drd_type to an unsigned char to keep struct size down. */ enum Dwarf_Rel_Type { dwarf_drt_none, /* Should not get to caller */ dwarf_drt_data_reloc, /* Simple normal relocation. */ dwarf_drt_segment_rel, /* Special reloc, exceptions. */ /* dwarf_drt_first_of_length_pair and drt_second are for for the .word end - begin case. */ dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; struct Dwarf_P_Marker_s { Dwarf_Unsigned ma_marker; Dwarf_Unsigned ma_offset; }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type to keep size small in struct. */ unsigned char drd_length; /* Length in bytes of data being relocated. 4 for 32bit data, 8 for 64bit data. */ Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */ Dwarf_Unsigned drd_symbol_index; }; typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; struct Dwarf_P_String_Attr_s { Dwarf_Unsigned sa_offset; /* Offset of string attribute data */ Dwarf_Unsigned sa_nbytes; }; /* Opaque types for Consumer Library. */ typedef struct Dwarf_Debug_s* Dwarf_Debug; typedef struct Dwarf_Die_s* Dwarf_Die; typedef struct Dwarf_Line_s* Dwarf_Line; typedef struct Dwarf_Global_s* Dwarf_Global; typedef struct Dwarf_Func_s* Dwarf_Func; typedef struct Dwarf_Type_s* Dwarf_Type; typedef struct Dwarf_Var_s* Dwarf_Var; typedef struct Dwarf_Weak_s* Dwarf_Weak; typedef struct Dwarf_Error_s* Dwarf_Error; typedef struct Dwarf_Attribute_s* Dwarf_Attribute; typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; typedef struct Dwarf_Fde_s* Dwarf_Fde; typedef struct Dwarf_Cie_s* Dwarf_Cie; typedef struct Dwarf_Arange_s* Dwarf_Arange; typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex; struct Dwarf_Xu_Index_Header_s; typedef struct Dwarf_Xu_Index_Header_s* Dwarf_Xu_Index_Header; struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; struct Dwarf_Dnames_Head_s; typedef struct Dwarf_Dnames_Head_s* Dwarf_Dnames_Head; /* Opaque types for Producer Library. */ typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; typedef struct Dwarf_P_Die_s* Dwarf_P_Die; typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; typedef Dwarf_Unsigned Dwarf_Tag; /* error handler function */ typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); /* Begin libdwarf Object File Interface declarations. As of February 2008 there are multiple dwarf_reader object access initialization methods available: The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish() which assume libelf and POSIX file access. An object-file and library agnostic dwarf_object_init() and dwarf_object_finish() which allow the coder to provide object access routines abstracting away the elf interface. So there is no dependence in the reader code on the object format and no dependence on libelf. See the code in dwarf_elf_access.c and dwarf_original_elf_init.c to see an example of initializing the structures mentioned below. Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. As of March 2017 additional functions dwarf_elf_init_b and dwarf_init_b and dwarf_object_init_b add a groupnumber argument so DWARF5 split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods; typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section; /* Used in the get_section interface function in Dwarf_Obj_Access_Section_s. Since libdwarf depends on standard DWARF section names an object format that has no such names (but has some method of setting up 'sections equivalents') must arrange to return standard DWARF section names in the 'name' field. libdwarf does not free the strings in 'name'. */ struct Dwarf_Obj_Access_Section_s { /* addr is the virtual address of the first byte of the section data. Usually zero when the address makes no sense for a given section. */ Dwarf_Addr addr; /* Section type. */ Dwarf_Unsigned type; /* Size in bytes of the section. */ Dwarf_Unsigned size; /* Having an accurate section name makes debugging of libdwarf easier. and is essential to find the .debug_ sections. */ const char* name; /* Set link to zero if it is meaningless. If non-zero it should be a link to a rela section or from symtab to strtab. In Elf it is sh_link. */ Dwarf_Unsigned link; /* The section header index of the section to which the relocation applies. In Elf it is sh_info. */ Dwarf_Unsigned info; /* Elf sections that are tables have a non-zero entrysize so the count of entries can be calculated even without the right structure definition. If your object format does not have this data leave this zero. */ Dwarf_Unsigned entrysize; }; /* Returned by the get_endianness function in Dwarf_Obj_Access_Methods_s. */ typedef enum { DW_OBJECT_MSB, DW_OBJECT_LSB } Dwarf_Endianness; /* The functions we need to access object data from libdwarf are declared here. In these function pointer declarations 'void *obj' is intended to be a pointer (the object field in Dwarf_Obj_Access_Interface_s) that hides the library-specific and object-specific data that makes it possible to handle multiple object formats and multiple libraries. It's not required that one handles multiple such in a single libdwarf archive/shared-library (but not ruled out either). See dwarf_elf_object_access_internals_t and dwarf_elf_access.c for an example. */ struct Dwarf_Obj_Access_Methods_s { /* get_section_info Get address, size, and name info about a section. Parameters section_index - Zero-based index. return_section - Pointer to a structure in which section info will be placed. Caller must provide a valid pointer to a structure area. The structure's contents will be overwritten by the call to get_section_info. error - A pointer to an integer in which an error code may be stored. Return DW_DLV_OK - Everything ok. DW_DLV_ERROR - Error occurred. Use 'error' to determine the libdwarf defined error. DW_DLV_NO_ENTRY - No such section. */ int (*get_section_info)(void* obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section* return_section, int* error); /* get_byte_order Get whether the object file represented by this interface is big-endian (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB). Parameters obj - Equivalent to 'this' in OO languages. Return Endianness of object. Cannot fail. */ Dwarf_Endianness (*get_byte_order)(void* obj); /* get_length_size Get the size of a length field in the underlying object file. libdwarf currently supports * 4 and 8 byte sizes, but may support larger in the future. Perhaps the return type should be an enumeration? Parameters obj - Equivalent to 'this' in OO languages. Return Size of length. Cannot fail. */ Dwarf_Small (*get_length_size)(void* obj); /* get_pointer_size Get the size of a pointer field in the underlying object file. libdwarf currently supports 4 and 8 byte sizes. Perhaps the return type should be an enumeration? Return Size of pointer. Cannot fail. */ Dwarf_Small (*get_pointer_size)(void* obj); /* get_section_count Get the number of sections in the object file. Parameters Return Number of sections */ Dwarf_Unsigned (*get_section_count)(void* obj); /* load_section Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index. return_data - The address of a pointer to which the section data block will be assigned. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*load_section)(void* obj, Dwarf_Half section_index, Dwarf_Small** return_data, int* error); /** relocate_a_section If relocations are not supported leave this pointer NULL. Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index of the section to be relocated. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*relocate_a_section)(void* obj, Dwarf_Half section_index, Dwarf_Debug dbg, int* error); }; /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface [dwarf_object_init and dwarf_object_finish)] directly. dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. */ struct Dwarf_Obj_Access_Interface_s { /* object is a void* as it hides the data the object access routines need (which varies by library in use and object format). */ void* object; const Dwarf_Obj_Access_Methods * methods; }; /* End libdwarf Object File Interface */ /* Dwarf_dealloc() alloc_type arguments. Argument points to: */ #define DW_DLA_STRING 0x01 /* char* */ #define DW_DLA_LOC 0x02 /* Dwarf_Loc */ #define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ #define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ #define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ #define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ #define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ #define DW_DLA_DIE 0x08 /* Dwarf_Die */ #define DW_DLA_LINE 0x09 /* Dwarf_Line */ #define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ #define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ #define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ #define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ #define DW_DLA_ERROR 0x0e /* Dwarf_Error */ #define DW_DLA_LIST 0x0f /* a list */ #define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ #define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ #define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ #define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ #define DW_DLA_CIE 0x14 /* Dwarf_Cie */ #define DW_DLA_FDE 0x15 /* Dwarf_Fde */ #define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */ #define DW_DLA_FRAME_BLOCK 0x17 /* Dwarf_Frame Block (not used) */ #define DW_DLA_FUNC 0x18 /* Dwarf_Func */ #define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ #define DW_DLA_VAR 0x1a /* Dwarf_Var */ #define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ #define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ #define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */ /* 0x1e (30) to 0x36 (54) reserved for internal to libdwarf types. */ #define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */ #define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */ #define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/ #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ /* 0x3d (61) is for libdwarf internal use. */ #define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ #define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ #define DW_DLA_STR_OFFSETS 0x40 /* struct Dwarf_Str_Offsets_Table_s */ /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" /* dwarf_init() access arguments */ #define DW_DLC_READ 0 /* read only access */ #define DW_DLC_WRITE 1 /* write only access */ #define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ /* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed. If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not set 32bit offset DWARF is assumed. Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS and handle the relocation creation for the target itself using the symbolic relocations to do so, those use the Dwarf_Rel_Type enum relocation indicators. */ /* The first three are traditional dwarf producer names. These names still work. Newer names below. */ /* 64-bit address-size target */ #define DW_DLC_SIZE_64 0x40000000 /* 32-bit address-size target */ #define DW_DLC_SIZE_32 0x20000000 /* 64-bit offset-size DWARF offsets (else 32bit) */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* 32-bit offset-size ELF object (ELFCLASS32) */ #define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* 64-bit offset-size ELF object (ELFCLASS64) */ #define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* dwarf_producer_init* access flag modifiers Some new April 2014. If DW_DLC_STREAM_RELOCATIONS is set the DW_DLC_ISA_* flags are ignored. See the Dwarf_Rel_Type enum. */ /* Old style Elf binary relocation (.rel) records. The default. */ #define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* use 32-bit sec offsets */ #define DW_DLC_OFFSET32 0x00010000 /* The following 3 are new sensible names. Old names above with same values. */ /* use 64-bit sec offsets in ELF */ #define DW_DLC_OFFSET64 0x10000000 /* use 4 for address_size */ #define DW_DLC_POINTER32 0x20000000 /* use 8 for address_size */ #define DW_DLC_POINTER64 0x40000000 /* Special for IRIX only */ /* use Elf 64bit offset headers and non-std IRIX 64bitoffset headers */ #define DW_DLC_IRIX_OFFSET64 0x00200000 /* Usable with assembly output because it is up to the producer to deal with locations in whatever manner the calling producer code wishes. For example, when the libdwarf caller wishes to produce relocations differently than the binary relocation bits that libdwarf Stream Relocations generate. */ #define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 #define DW_DLC_TARGET_BIGENDIAN 0x08000000 /* Big endian target */ #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* Little endian target */ /* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ #define DW_DLS_FORWARD 1 /* slide forward to find line */ /* libdwarf error numbers */ #define DW_DLE_NE 0 /* no error */ #define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ #define DW_DLE_MAP 2 /* memory map failure */ #define DW_DLE_LEE 3 /* libelf error */ #define DW_DLE_NDS 4 /* no debug section */ #define DW_DLE_NLS 5 /* no line section */ #define DW_DLE_ID 6 /* invalid descriptor for query */ #define DW_DLE_IOF 7 /* I/O failure */ #define DW_DLE_MAF 8 /* memory allocation failure */ #define DW_DLE_IA 9 /* invalid argument */ #define DW_DLE_MDE 10 /* mangled debugging entry */ #define DW_DLE_MLE 11 /* mangled line number entry */ #define DW_DLE_FNO 12 /* file not open */ #define DW_DLE_FNR 13 /* file not a regular file */ #define DW_DLE_FWA 14 /* file open with wrong access */ #define DW_DLE_NOB 15 /* not an object file */ #define DW_DLE_MOF 16 /* mangled object file header */ #define DW_DLE_EOLL 17 /* end of location list entries */ #define DW_DLE_NOLL 18 /* no location list section */ #define DW_DLE_BADOFF 19 /* Invalid offset */ #define DW_DLE_EOS 20 /* end of section */ #define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ #define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ /* It is not an allowed size (64 or 32) */ /* Error codes defined by the current Libdwarf Implementation. */ #define DW_DLE_DBG_ALLOC 23 #define DW_DLE_FSTAT_ERROR 24 #define DW_DLE_FSTAT_MODE_ERROR 25 #define DW_DLE_INIT_ACCESS_WRONG 26 #define DW_DLE_ELF_BEGIN_ERROR 27 #define DW_DLE_ELF_GETEHDR_ERROR 28 #define DW_DLE_ELF_GETSHDR_ERROR 29 #define DW_DLE_ELF_STRPTR_ERROR 30 #define DW_DLE_DEBUG_INFO_DUPLICATE 31 #define DW_DLE_DEBUG_INFO_NULL 32 #define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 #define DW_DLE_DEBUG_ABBREV_NULL 34 #define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 #define DW_DLE_DEBUG_ARANGES_NULL 36 #define DW_DLE_DEBUG_LINE_DUPLICATE 37 #define DW_DLE_DEBUG_LINE_NULL 38 #define DW_DLE_DEBUG_LOC_DUPLICATE 39 #define DW_DLE_DEBUG_LOC_NULL 40 #define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 #define DW_DLE_DEBUG_MACINFO_NULL 42 #define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 #define DW_DLE_DEBUG_PUBNAMES_NULL 44 #define DW_DLE_DEBUG_STR_DUPLICATE 45 #define DW_DLE_DEBUG_STR_NULL 46 #define DW_DLE_CU_LENGTH_ERROR 47 #define DW_DLE_VERSION_STAMP_ERROR 48 #define DW_DLE_ABBREV_OFFSET_ERROR 49 #define DW_DLE_ADDRESS_SIZE_ERROR 50 #define DW_DLE_DEBUG_INFO_PTR_NULL 51 #define DW_DLE_DIE_NULL 52 #define DW_DLE_STRING_OFFSET_BAD 53 #define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 #define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 #define DW_DLE_LINE_NUM_OPERANDS_BAD 56 #define DW_DLE_LINE_SET_ADDR_ERROR 57 /* No longer used. */ #define DW_DLE_LINE_EXT_OPCODE_BAD 58 #define DW_DLE_DWARF_LINE_NULL 59 #define DW_DLE_INCL_DIR_NUM_BAD 60 #define DW_DLE_LINE_FILE_NUM_BAD 61 #define DW_DLE_ALLOC_FAIL 62 #define DW_DLE_NO_CALLBACK_FUNC 63 #define DW_DLE_SECT_ALLOC 64 #define DW_DLE_FILE_ENTRY_ALLOC 65 #define DW_DLE_LINE_ALLOC 66 #define DW_DLE_FPGM_ALLOC 67 #define DW_DLE_INCDIR_ALLOC 68 #define DW_DLE_STRING_ALLOC 69 #define DW_DLE_CHUNK_ALLOC 70 #define DW_DLE_BYTEOFF_ERR 71 #define DW_DLE_CIE_ALLOC 72 #define DW_DLE_FDE_ALLOC 73 #define DW_DLE_REGNO_OVFL 74 #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 #define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 #define DW_DLE_DEBUGLINE_ERROR 82 #define DW_DLE_DEBUGFRAME_ERROR 83 #define DW_DLE_DEBUGINFO_ERROR 84 #define DW_DLE_ATTR_ALLOC 85 #define DW_DLE_ABBREV_ALLOC 86 #define DW_DLE_OFFSET_UFLW 87 #define DW_DLE_ELF_SECT_ERR 88 #define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 #define DW_DLE_FRAME_VERSION_BAD 90 #define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 #define DW_DLE_FDE_NULL 92 #define DW_DLE_FDE_DBG_NULL 93 #define DW_DLE_CIE_NULL 94 #define DW_DLE_CIE_DBG_NULL 95 #define DW_DLE_FRAME_TABLE_COL_BAD 96 #define DW_DLE_PC_NOT_IN_FDE_RANGE 97 #define DW_DLE_CIE_INSTR_EXEC_ERROR 98 #define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 #define DW_DLE_FDE_PTR_NULL 100 #define DW_DLE_RET_OP_LIST_NULL 101 #define DW_DLE_LINE_CONTEXT_NULL 102 #define DW_DLE_DBG_NO_CU_CONTEXT 103 #define DW_DLE_DIE_NO_CU_CONTEXT 104 #define DW_DLE_FIRST_DIE_NOT_CU 105 #define DW_DLE_NEXT_DIE_PTR_NULL 106 #define DW_DLE_DEBUG_FRAME_DUPLICATE 107 #define DW_DLE_DEBUG_FRAME_NULL 108 #define DW_DLE_ABBREV_DECODE_ERROR 109 #define DW_DLE_DWARF_ABBREV_NULL 110 #define DW_DLE_ATTR_NULL 111 #define DW_DLE_DIE_BAD 112 #define DW_DLE_DIE_ABBREV_BAD 113 #define DW_DLE_ATTR_FORM_BAD 114 #define DW_DLE_ATTR_NO_CU_CONTEXT 115 #define DW_DLE_ATTR_FORM_SIZE_BAD 116 #define DW_DLE_ATTR_DBG_NULL 117 #define DW_DLE_BAD_REF_FORM 118 #define DW_DLE_ATTR_FORM_OFFSET_BAD 119 #define DW_DLE_LINE_OFFSET_BAD 120 #define DW_DLE_DEBUG_STR_OFFSET_BAD 121 #define DW_DLE_STRING_PTR_NULL 122 #define DW_DLE_PUBNAMES_VERSION_ERROR 123 #define DW_DLE_PUBNAMES_LENGTH_BAD 124 #define DW_DLE_GLOBAL_NULL 125 #define DW_DLE_GLOBAL_CONTEXT_NULL 126 #define DW_DLE_DIR_INDEX_BAD 127 #define DW_DLE_LOC_EXPR_BAD 128 #define DW_DLE_DIE_LOC_EXPR_BAD 129 #define DW_DLE_ADDR_ALLOC 130 #define DW_DLE_OFFSET_BAD 131 #define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 #define DW_DLE_REL_ALLOC 133 #define DW_DLE_ARANGE_OFFSET_BAD 134 #define DW_DLE_SEGMENT_SIZE_BAD 135 #define DW_DLE_ARANGE_LENGTH_BAD 136 #define DW_DLE_ARANGE_DECODE_ERROR 137 #define DW_DLE_ARANGES_NULL 138 #define DW_DLE_ARANGE_NULL 139 #define DW_DLE_NO_FILE_NAME 140 #define DW_DLE_NO_COMP_DIR 141 #define DW_DLE_CU_ADDRESS_SIZE_BAD 142 #define DW_DLE_INPUT_ATTR_BAD 143 #define DW_DLE_EXPR_NULL 144 #define DW_DLE_BAD_EXPR_OPCODE 145 #define DW_DLE_EXPR_LENGTH_BAD 146 #define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 #define DW_DLE_ELF_GETIDENT_ERROR 148 #define DW_DLE_NO_AT_MIPS_FDE 149 #define DW_DLE_NO_CIE_FOR_FDE 150 #define DW_DLE_DIE_ABBREV_LIST_NULL 151 #define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 #define DW_DLE_DEBUG_FUNCNAMES_NULL 153 #define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 #define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 #define DW_DLE_FUNC_NULL 156 #define DW_DLE_FUNC_CONTEXT_NULL 157 #define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 #define DW_DLE_DEBUG_TYPENAMES_NULL 159 #define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 #define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 #define DW_DLE_TYPE_NULL 162 #define DW_DLE_TYPE_CONTEXT_NULL 163 #define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 #define DW_DLE_DEBUG_VARNAMES_NULL 165 #define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 #define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 #define DW_DLE_VAR_NULL 168 #define DW_DLE_VAR_CONTEXT_NULL 169 #define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 #define DW_DLE_DEBUG_WEAKNAMES_NULL 171 #define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 #define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 #define DW_DLE_WEAK_NULL 174 #define DW_DLE_WEAK_CONTEXT_NULL 175 #define DW_DLE_LOCDESC_COUNT_WRONG 176 #define DW_DLE_MACINFO_STRING_NULL 177 #define DW_DLE_MACINFO_STRING_EMPTY 178 #define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 #define DW_DLE_MACINFO_MALLOC_FAIL 180 #define DW_DLE_DEBUGMACINFO_ERROR 181 #define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 #define DW_DLE_DEBUG_MACRO_MAX_BAD 183 #define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 #define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 #define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 #define DW_DLE_DF_NO_CIE_AUGMENTATION 187 #define DW_DLE_DF_REG_NUM_TOO_HIGH 188 #define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 #define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 #define DW_DLE_DF_POP_EMPTY_STACK 191 #define DW_DLE_DF_ALLOC_FAIL 192 #define DW_DLE_DF_FRAME_DECODING_ERROR 193 #define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 #define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 #define DW_DLE_PUBTYPE_CONTEXT 196 /* Unused. */ #define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 #define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 #define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 #define DW_DLE_FRAME_CIE_DECODE_ERROR 200 #define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 #define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 #define DW_DLE_LINK_LOOP 203 #define DW_DLE_STRP_OFFSET_BAD 204 #define DW_DLE_DEBUG_RANGES_DUPLICATE 205 #define DW_DLE_DEBUG_RANGES_OFFSET_BAD 206 #define DW_DLE_DEBUG_RANGES_MISSING_END 207 #define DW_DLE_DEBUG_RANGES_OUT_OF_MEM 208 #define DW_DLE_DEBUG_SYMTAB_ERR 209 #define DW_DLE_DEBUG_STRTAB_ERR 210 #define DW_DLE_RELOC_MISMATCH_INDEX 211 #define DW_DLE_RELOC_MISMATCH_RELOC_INDEX 212 #define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX 213 #define DW_DLE_RELOC_SECTION_MISMATCH 214 #define DW_DLE_RELOC_SECTION_MISSING_INDEX 215 #define DW_DLE_RELOC_SECTION_LENGTH_ODD 216 #define DW_DLE_RELOC_SECTION_PTR_NULL 217 #define DW_DLE_RELOC_SECTION_MALLOC_FAIL 218 #define DW_DLE_NO_ELF64_SUPPORT 219 #define DW_DLE_MISSING_ELF64_SUPPORT 220 #define DW_DLE_ORPHAN_FDE 221 #define DW_DLE_DUPLICATE_INST_BLOCK 222 #define DW_DLE_BAD_REF_SIG8_FORM 223 #define DW_DLE_ATTR_EXPRLOC_FORM_BAD 224 #define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD 225 #define DW_DLE_NOT_REF_FORM 226 #define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227 #define DW_DLE_REF_SIG8_NOT_HANDLED 228 #define DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH 229 #define DW_DLE_LOC_BAD_TERMINATION 230 #define DW_DLE_SYMTAB_SECTION_LENGTH_ODD 231 #define DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD 232 #define DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN 233 #define DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO 234 #define DW_DLE_LINE_NUMBER_HEADER_ERROR 235 #define DW_DLE_DEBUG_TYPES_NULL 236 #define DW_DLE_DEBUG_TYPES_DUPLICATE 237 #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238 #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239 #define DW_DLE_GNU_OPCODE_ERROR 240 #define DW_DLE_DEBUGPUBTYPES_ERROR 241 #define DW_DLE_AT_FIXUP_NULL 242 #define DW_DLE_AT_FIXUP_DUP 243 #define DW_DLE_BAD_ABINAME 244 #define DW_DLE_TOO_MANY_DEBUG 245 #define DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE 246 #define DW_DLE_SECTION_DUPLICATION 247 #define DW_DLE_SECTION_ERROR 248 #define DW_DLE_DEBUG_ADDR_DUPLICATE 249 #define DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM 250 #define DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE 251 #define DW_DLE_NEXT_DIE_PAST_END 252 #define DW_DLE_NEXT_DIE_WRONG_FORM 253 #define DW_DLE_NEXT_DIE_NO_ABBREV_LIST 254 #define DW_DLE_NESTED_FORM_INDIRECT_ERROR 255 #define DW_DLE_CU_DIE_NO_ABBREV_LIST 256 #define DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 #define DW_DLE_ATTR_FORM_NOT_ADDR_INDEX 258 #define DW_DLE_ATTR_FORM_NOT_STR_INDEX 259 #define DW_DLE_DUPLICATE_GDB_INDEX 260 #define DW_DLE_ERRONEOUS_GDB_INDEX_SECTION 261 #define DW_DLE_GDB_INDEX_COUNT_ERROR 262 #define DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR 263 #define DW_DLE_GDB_INDEX_INDEX_ERROR 264 #define DW_DLE_GDB_INDEX_CUVEC_ERROR 265 #define DW_DLE_DUPLICATE_CU_INDEX 266 #define DW_DLE_DUPLICATE_TU_INDEX 267 #define DW_DLE_XU_TYPE_ARG_ERROR 268 #define DW_DLE_XU_IMPOSSIBLE_ERROR 269 #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 /* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 #define DW_DLE_FUNCNAMES_ERROR 276 #define DW_DLE_TYPENAMES_ERROR 277 #define DW_DLE_VARNAMES_ERROR 278 #define DW_DLE_WEAKNAMES_ERROR 279 #define DW_DLE_RELOCS_ERROR 280 #define DW_DLE_ATTR_OUTSIDE_SECTION 281 #define DW_DLE_FISSION_INDEX_WRONG 282 #define DW_DLE_FISSION_VERSION_ERROR 283 #define DW_DLE_NEXT_DIE_LOW_ERROR 284 #define DW_DLE_CU_UT_TYPE_ERROR 285 #define DW_DLE_NO_SUCH_SIGNATURE_FOUND 286 #define DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG 287 #define DW_DLE_ATTR_FORM_NOT_DATA8 288 #define DW_DLE_SIG_TYPE_WRONG_STRING 289 #define DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH 290 #define DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH 291 #define DW_DLE_DWP_MISSING_DWO_ID 292 #define DW_DLE_DWP_SIBLING_ERROR 293 #define DW_DLE_DEBUG_FISSION_INCOMPLETE 294 #define DW_DLE_FISSION_SECNUM_ERR 295 #define DW_DLE_DEBUG_MACRO_DUPLICATE 296 #define DW_DLE_DEBUG_NAMES_DUPLICATE 297 #define DW_DLE_DEBUG_LINE_STR_DUPLICATE 298 #define DW_DLE_DEBUG_SUP_DUPLICATE 299 #define DW_DLE_NO_SIGNATURE_TO_LOOKUP 300 #define DW_DLE_NO_TIED_ADDR_AVAILABLE 301 #define DW_DLE_NO_TIED_SIG_AVAILABLE 302 #define DW_DLE_STRING_NOT_TERMINATED 303 #define DW_DLE_BAD_LINE_TABLE_OPERATION 304 #define DW_DLE_LINE_CONTEXT_BOTCH 305 #define DW_DLE_LINE_CONTEXT_INDEX_WRONG 306 #define DW_DLE_NO_TIED_STRING_AVAILABLE 307 #define DW_DLE_NO_TIED_FILE_AVAILABLE 308 #define DW_DLE_CU_TYPE_MISSING 309 #define DW_DLE_LLE_CODE_UNKNOWN 310 #define DW_DLE_LOCLIST_INTERFACE_ERROR 311 #define DW_DLE_LOCLIST_INDEX_ERROR 312 #define DW_DLE_INTERFACE_NOT_SUPPORTED 313 #define DW_DLE_ZDEBUG_REQUIRES_ZLIB 314 #define DW_DLE_ZDEBUG_INPUT_FORMAT_ODD 315 #define DW_DLE_ZLIB_BUF_ERROR 316 #define DW_DLE_ZLIB_DATA_ERROR 317 #define DW_DLE_MACRO_OFFSET_BAD 318 #define DW_DLE_MACRO_OPCODE_BAD 319 #define DW_DLE_MACRO_OPCODE_FORM_BAD 320 #define DW_DLE_UNKNOWN_FORM 321 #define DW_DLE_BAD_MACRO_HEADER_POINTER 322 #define DW_DLE_BAD_MACRO_INDEX 323 #define DW_DLE_MACRO_OP_UNHANDLED 324 #define DW_DLE_MACRO_PAST_END 325 #define DW_DLE_LINE_STRP_OFFSET_BAD 326 #define DW_DLE_STRING_FORM_IMPROPER 327 #define DW_DLE_ELF_FLAGS_NOT_AVAILABLE 328 #define DW_DLE_LEB_IMPROPER 329 #define DW_DLE_DEBUG_LINE_RANGE_ZERO 330 #define DW_DLE_READ_LITTLEENDIAN_ERROR 331 #define DW_DLE_READ_BIGENDIAN_ERROR 332 #define DW_DLE_RELOC_INVALID 333 #define DW_DLE_INFO_HEADER_ERROR 334 #define DW_DLE_ARANGES_HEADER_ERROR 335 #define DW_DLE_LINE_OFFSET_WRONG_FORM 336 #define DW_DLE_FORM_BLOCK_LENGTH_ERROR 337 #define DW_DLE_ZLIB_SECTION_SHORT 338 #define DW_DLE_CIE_INSTR_PTR_ERROR 339 #define DW_DLE_FDE_INSTR_PTR_ERROR 340 #define DW_DLE_FISSION_ADDITION_ERROR 341 #define DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE 342 #define DW_DLE_LOCEXPR_OFF_SECTION_END 343 #define DW_DLE_POINTER_SECTION_UNKNOWN 344 #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 #define DW_DLE_SIZE_WRAPAROUND 348 #define DW_DLE_ILLOGICAL_TSEARCH 349 #define DW_DLE_BAD_STRING_FORM 350 #define DW_DLE_DEBUGSTR_ERROR 351 #define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 #define DW_DLE_DISCR_ARRAY_ERROR 353 #define DW_DLE_LEB_OUT_ERROR 354 #define DW_DLE_SIBLING_LIST_IMPROPER 355 #define DW_DLE_LOCLIST_OFFSET_BAD 356 #define DW_DLE_LINE_TABLE_BAD 357 #define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 #define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 #define DW_DLE_ABBREV_OFF_END 360 #define DW_DLE_FORM_STRING_BAD_STRING 361 #define DW_DLE_AUGMENTATION_STRING_OFF_END 362 #define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 #define DW_DLE_LINE_STRING_BAD 364 #define DW_DLE_DEFINE_FILE_STRING_BAD 365 #define DW_DLE_MACRO_STRING_BAD 366 #define DW_DLE_MACINFO_STRING_BAD 367 #define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 #define DW_DLE_IMPROPER_DWO_ID 369 #define DW_DLE_GROUPNUMBER_ERROR 370 #define DW_DLE_ADDRESS_SIZE_ZERO 371 #define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 #define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 #define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 #define DW_DLE_DEBUG_NAMES_OFF_END 375 #define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 #define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 #define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 #define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 #define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 #define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 #define DW_DLE_LNCT_CODE_UNKNOWN 382 #define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 #define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 #define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 #define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 #define DW_DLE_GROUP_MAP_ALLOC 387 #define DW_DLE_GROUP_MAP_DUPLICATE 388 #define DW_DLE_GROUP_COUNT_ERROR 389 #define DW_DLE_GROUP_INTERNAL_ERROR 390 #define DW_DLE_GROUP_LOAD_ERROR 391 #define DW_DLE_GROUP_LOAD_READ_ERROR 392 #define DW_DLE_AUG_DATA_LENGTH_BAD 393 #define DW_DLE_ABBREV_MISSING 394 #define DW_DLE_NO_TAG_FOR_DIE 395 #define DW_DLE_LOWPC_WRONG_CLASS 396 #define DW_DLE_HIGHPC_WRONG_FORM 397 #define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 #define DW_DLE_DATA16_OUTSIDE_SECTION 399 #define DW_DLE_LNCT_MD5_WRONG_FORM 400 #define DW_DLE_LINE_HEADER_CORRUPT 401 #define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 #define DW_DLE_STR_OFFSETS_NULL_DBG 403 #define DW_DLE_STR_OFFSETS_NO_MAGIC 404 #define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 #define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 #define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 #define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 #define DW_DLE_DUP_ATTR_ON_DIE 409 #define DW_DLE_SECTION_NAME_BIG 410 #define DW_DLE_FILE_UNAVAILABLE 411 #define DW_DLE_FILE_WRONG_TYPE 412 #define DW_DLE_SIBLING_OFFSET_WRONG 413 #define DW_DLE_OPEN_FAIL 414 #define DW_DLE_OFFSET_SIZE 415 #define DW_DLE_MACH_O_SEGOFFSET_BAD 416 #define DW_DLE_FILE_OFFSET_BAD 417 #define DW_DLE_SEEK_ERROR 418 #define DW_DLE_READ_ERROR 419 #define DW_DLE_ELF_CLASS_BAD 420 #define DW_DLE_ELF_ENDIAN_BAD 421 #define DW_DLE_ELF_VERSION_BAD 422 #define DW_DLE_FILE_TOO_SMALL 423 #define DW_DLE_PATH_SIZE_TOO_SMALL 424 #define DW_DLE_BAD_TYPE_SIZE 425 #define DW_DLE_PE_SIZE_SMALL 426 #define DW_DLE_PE_OFFSET_BAD 427 #define DW_DLE_PE_STRING_TOO_LONG 428 #define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 #define DW_DLE_LINE_TABLE_LINENO_ERROR 430 #define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 #define DW_DLE_NO_ELF_SUPPORT 432 #define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 #define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 #define DW_DLE_SECTION_SIZE_ERROR 435 #define DW_DLE_INTERNAL_NULL_POINTER 436 #define DW_DLE_SECTION_STRING_OFFSET_BAD 437 #define DW_DLE_SECTION_INDEX_BAD 438 #define DW_DLE_INTEGER_TOO_SMALL 439 #define DW_DLE_ELF_SECTION_LINK_ERROR 440 #define DW_DLE_ELF_SECTION_GROUP_ERROR 441 #define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 #define DW_DLE_ELF_STRING_SECTION_MISSING 443 #define DW_DLE_SEEK_OFF_END 444 #define DW_DLE_READ_OFF_END 445 #define DW_DLE_ELF_SECTION_ERROR 446 #define DW_DLE_ELF_STRING_SECTION_ERROR 447 #define DW_DLE_MIXING_SPLIT_DWARF_VERSIONS 448 #define DW_DLE_TAG_CORRUPT 449 #define DW_DLE_FORM_CORRUPT 450 #define DW_DLE_ATTR_CORRUPT 451 #define DW_DLE_ABBREV_ATTR_DUPLICATION 452 #define DW_DLE_DWP_SIGNATURE_MISMATCH 453 #define DW_DLE_CU_UT_TYPE_VALUE 454 #define DW_DLE_DUPLICATE_GNU_DEBUGLINK 455 #define DW_DLE_CORRUPT_GNU_DEBUGLINK 456 #define DW_DLE_CORRUPT_NOTE_GNU_DEBUGID 457 #define DW_DLE_CORRUPT_GNU_DEBUGID_SIZE 458 #define DW_DLE_CORRUPT_GNU_DEBUGID_STRING 459 #define DW_DLE_HEX_STRING_ERROR 460 #define DW_DLE_DECIMAL_STRING_ERROR 461 #define DW_DLE_PRO_INIT_EXTRAS_UNKNOWN 462 #define DW_DLE_PRO_INIT_EXTRAS_ERR 463 #define DW_DLE_NULL_ARGS_DWARF_ADD_PATH 464 #define DW_DLE_DWARF_INIT_DBG_NULL 465 /* LAST MUST EQUAL LAST ERROR NUMBER */ #define DW_DLE_LAST 465 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_SAME_VAL 1035 /* error return values */ #define DW_DLV_BADADDR (~(Dwarf_Addr)0) /* for functions returning target address */ #define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) /* for functions returning count */ #define DW_DLV_BADOFFSET (~(Dwarf_Off)0) /* for functions returning offset */ /* standard return values for functions */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 /* Special values for offset_into_exception_table field of dwarf fde's. */ /* The following value indicates that there is no Exception table offset associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer was unable to analyse the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) /* The dwarf specification separates FORMs into different classes. To do the seperation properly requires 4 pieces of data as of DWARF4 (thus the function arguments listed here). The DWARF4 specification class definition suffices to describe all DWARF versions. See section 7.5.4, Attribute Encodings. A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). DWARF5: DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST except that LOCLISTSPTR is aways a section offset, never an index, and LOCLISTSPTR is only referenced by DW_AT_loclists_base. Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish from DW_FORM_CLASS_LOCLISTPTR. DWARF5: DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST except that RNGLISTSPTR is aways a section offset, never an index. DW_FORM_CLASS_RNGLISTSPTR is only referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN, DW_FORM_CLASS_ADDRESS, DW_FORM_CLASS_BLOCK, DW_FORM_CLASS_CONSTANT, DW_FORM_CLASS_EXPRLOC, DW_FORM_CLASS_FLAG, DW_FORM_CLASS_LINEPTR, DW_FORM_CLASS_LOCLISTPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_MACPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_RANGELISTPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_REFERENCE, DW_FORM_CLASS_STRING, DW_FORM_CLASS_FRAMEPTR, /* MIPS/IRIX DWARF2 only */ DW_FORM_CLASS_MACROPTR, /* DWARF5 */ DW_FORM_CLASS_ADDRPTR, /* DWARF5 */ DW_FORM_CLASS_LOCLIST, /* DWARF5 */ DW_FORM_CLASS_LOCLISTSPTR, /* DWARF5 */ DW_FORM_CLASS_RNGLIST, /* DWARF5 */ DW_FORM_CLASS_RNGLISTSPTR, /* DWARF5 */ DW_FORM_CLASS_STROFFSETSPTR /* DWARF5 */ }; /* These support opening DWARF5 split dwarf objects. */ #define DW_GROUPNUMBER_ANY 0 #define DW_GROUPNUMBER_BASE 1 #define DW_GROUPNUMBER_DWO 2 /*===========================================================================*/ /* Dwarf consumer interface initialization and termination operations */ /* Initialization based on path. This is new October 2018. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. So consider the value put in true_path_out the actual file name. reserved1,2,3 should all be passed as zero. */ int dwarf_init_path(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* Initialization based on Unix(etc) open fd */ /* New March 2017 */ int dwarf_init_b(int /*fd*/, Dwarf_Unsigned /*access*/, unsigned /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* The dwarf_elf_init* functions continue to be supported, but should be considered deprecated as they can ONLY be used on Elf files. */ /* Initialization based on libelf/sgi-fastlibelf open pointer. */ /* New March 2017 */ int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, unsigned /*group_number*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* New September 2019. When using dwarf_elf_init[_b]() we still want the file path in the record. So we add it after the init phase. Path is needed for buildid and debuglink to fully work. */ int dwarf_add_file_path(Dwarf_Debug /*dbg*/, const char * /*file_name*/, Dwarf_Error* /*error*/); /* Undocumented function for memory allocator. */ void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); int dwarf_get_elf(Dwarf_Debug /*dbg*/, dwarf_elf_handle* /*return_elfptr*/, Dwarf_Error* /*error*/); int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* NEW March 2017. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, unsigned /*groupnumber*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_set_tied_dbg(Dwarf_Debug /*basedbg*/, Dwarf_Debug /*tied_dbg*/, Dwarf_Error* /*error*/); /* Likely not very useful.? */ int dwarf_get_tied_dbg(Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/); int dwarf_object_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns the version string. Example: "20190922" which is in ISO date format. */ const char * dwarf_package_version(void); /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, const char * /*std_section_name*/, const char ** /*actual_sec_name_out*/, Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ Dwarf_Unsigned * /*compressed_length*/, Dwarf_Unsigned * /*uncompressed_length*/, Dwarf_Error * /*error*/); /* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Half * /*header_cu_type*/, Dwarf_Error* /*error*/); /* Die traversal operations. dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* The following is obsolete, though supported. November 2009. */ int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); int dwarf_siblingof(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* dwarf_siblingof_b new October 2011. */ int dwarf_siblingof_b(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* New 27 April 2015. */ int dwarf_die_from_hash_signature(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*hash_sig*/, const char * /*sig_type: "tu" or "cu"*/, Dwarf_Die* /*returned_CU_die */, Dwarf_Error* /*error*/); int dwarf_child(Dwarf_Die /*die*/, Dwarf_Die* /*return_childdie*/, Dwarf_Error* /*error*/); /* Finding die given global (not CU-relative) offset. Applies only to debug_info. */ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* Returns the is_info flag through the pointer if the function returns DW_DLV_OK. Needed so client software knows if a DIE is in debug_info or debug_types. New October 2011. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die /*die*/); /* New March 2016. So we can associate a DIE's abbreviations with the contents the abbreviations section. */ int dwarf_die_abbrev_global_offset(Dwarf_Die /*die*/, Dwarf_Off * /*abbrev_offset*/, Dwarf_Unsigned * /*abbrev_count*/, Dwarf_Error* /*error*/); /* operations on DIEs */ int dwarf_tag(Dwarf_Die /*die*/, Dwarf_Half* /*return_tag*/, Dwarf_Error* /*error*/); /* dwarf_dieoffset returns the global debug_info section offset, not the CU relative offset. */ int dwarf_dieoffset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* NEW October 2015. DWARF5. The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr. This will look first for .debug_addr in the dbg object DIE and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given_die (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_die_CU_offset_range(Dwarf_Die /*die*/, Dwarf_Off* /*return_CU_header_offset*/, Dwarf_Off* /*return_CU_length_bytes*/, Dwarf_Error* /*error*/); int dwarf_attr (Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Attribute * /*returned_attr*/, Dwarf_Error* /*error*/); int dwarf_die_text(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, char ** /*ret_name*/, Dwarf_Error * /*error*/); int dwarf_diename(Dwarf_Die /*die*/, char ** /*diename*/, Dwarf_Error* /*error*/); /* Returns the abbrev code of the die. Cannot fail. */ int dwarf_die_abbrev_code(Dwarf_Die /*die */); /* Returns a flag through ab_has_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, Dwarf_Half * /*ab_has_child*/); /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/,Dwarf_Off* /*offset*/); /* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Off ** /*offbuf*/, Dwarf_Unsigned * /*offcnt*/, Dwarf_Error * /*error*/); /* BEGIN: loclist_c interfaces NEW October 2015. This works for any attribute that identifies a loclist or a locexpr. When the attribute is a locexpr a single loclist (created by libdwarf) is attached to loclist_head. */ int dwarf_get_loclist_c (Dwarf_Attribute /*attr*/, Dwarf_Loc_Head_c * /*loclist_head*/, Dwarf_Unsigned * /*locCount*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); int dwarf_get_location_op_value_c(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*address_size*/, Dwarf_Half /*offset_size*/, Dwarf_Small /*dwarf_version*/, Dwarf_Loc_Head_c* /*loc_head*/, Dwarf_Unsigned * /*listlen*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface is dwarf_get_loclist_c and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* The original interfaces. Please do not use this. */ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ Dwarf_Locdesc** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, Dwarf_Unsigned /* expression_length*/, Dwarf_Locdesc ** /* llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); /* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*addr_size*/, Dwarf_Locdesc ** /*llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); /* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for DW_OP_GNU_implicit_pointer. */ int dwarf_loclist_from_expr_b(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/ , Dwarf_Unsigned /*expression_length*/ , Dwarf_Half /*addr_size*/ , Dwarf_Half /*offset_size*/ , Dwarf_Small /*dwarf_version*/ , Dwarf_Locdesc ** /*llbuf*/ , Dwarf_Signed * /*listlen*/ , Dwarf_Error * /*error*/ ); int dwarf_lowpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* When the highpc attribute is of class 'constant' it is not an address, it is an offset from the base address (such as lowpc) of the function. This is therefore a required interface for DWARF4 style DW_AT_highpc. */ int dwarf_highpc_b(Dwarf_Die /*die*/, Dwarf_Addr * /*return_value*/, Dwarf_Half * /*return_form*/, enum Dwarf_Form_Class * /*return_class*/, Dwarf_Error * /*error*/); /* This works for DWARF2 and DWARF3 styles of DW_AT_highpc, but not for the DWARF4 class constant forms. If the FORM is of class constant this returns an error */ int dwarf_highpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* New January 2016. */ int dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/); int dwarf_bytesize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitsize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitoffset(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_offset*/, Dwarf_Error* /*error*/); int dwarf_srclang(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_lang*/, Dwarf_Error* /*error*/); int dwarf_arrayorder(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_order*/, Dwarf_Error* /*error*/); /* end of convenience function list */ /* this is the main interface to attributes of a DIE */ int dwarf_attrlist(Dwarf_Die /*die*/, Dwarf_Attribute** /*attrbuf*/, Dwarf_Signed * /*attrcount*/, Dwarf_Error* /*error*/); /* query operations for attributes */ int dwarf_hasform(Dwarf_Attribute /*attr*/, Dwarf_Half /*form*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_whatform(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_final_form*/, Dwarf_Error* /*error*/); int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_initial_form*/, Dwarf_Error* /*error*/); int dwarf_whatattr(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Error* /*error*/); /* The following are concerned with the Primary Interface: getting the actual data values. One function per 'kind' of FORM. */ /* dwarf_formref returns, thru return_offset, a CU-relative offset and does not allow DW_FORM_ref_addr*/ int dwarf_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_global_formref returns, thru return_offset, a debug_info-relative offset and does allow all reference forms*/ int dwarf_global_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8. Not a string. */ int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); /* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); int dwarf_formaddr(Dwarf_Attribute /*attr*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* Part of DebugFission. So a consumer can get the index when the object with the actual .debug_addr section is elsewhere. And so a print application can print the index. New May 2014*/ int dwarf_get_debug_addr_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_formdata16(Dwarf_Attribute /*attr*/, Dwarf_Form_Data16 * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formsdata(Dwarf_Attribute /*attr*/, Dwarf_Signed * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formblock(Dwarf_Attribute /*attr*/, Dwarf_Block ** /*returned_block*/, Dwarf_Error* /*error*/); int dwarf_formstring(Dwarf_Attribute /*attr*/, char ** /*returned_string*/, Dwarf_Error* /*error*/); /* DebugFission. So a DWARF print application can get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formexprloc(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_exprlen*/, Dwarf_Ptr * /*block_ptr*/, Dwarf_Error * /*error*/); /* end attribute query operations. */ /* Start line number operations */ /* dwarf_srclines is the original interface from 1993. */ int dwarf_srclines(Dwarf_Die /*die*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error* /*error*/); /* If we have two-level line tables, this will return the logicals table in linebuf and the actuals table in linebuf_actuals. For old-style (one-level) tables, it will return the single table through linebuf, and the value returned through linecount_actuals will be 0. The actual version number is returned through version. For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Line** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the appropriate method for deallocating what dwarf_srclines and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables user code should call dwarf_srclines_dealloc once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Line* /*linebuf*/, Dwarf_Signed /*count */); /* New October 2015, must be used to deallocating what is allocated by dwarf_srclines_b and dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. *is_single_table will be set zero for line sections with the two_level line table extension (which will have *version_out 0xf006). */ int dwarf_srclines_b(Dwarf_Die /*die*/, Dwarf_Unsigned * /* version_out*/, Dwarf_Small * /* table_count */, Dwarf_Line_Context * /* linecontext*/, Dwarf_Error * /* error*/); /* Functions passing in a Dwarf_Line_Context are only available if dwarf_srclines_b() was used to access line table information. */ /* New October 2015. Returns line details. Works for DWARF2,3,4,5. If linecount returned is zero this is a line table with no lines.*/ int dwarf_srclines_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error * /* error*/); /* New October 2015. Returns line details. Works for DWARF2,3,4,5 and for experimental two-level line tables. A single level table will have *linebuf_actuals and *linecount_actuals set to 0. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf */, Dwarf_Signed * /*linecount*/, Dwarf_Line ** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error * /* error*/); /* dwarf_srclines_dealloc_b(), created October 2015, is the appropriate method for deallocating everything and dwarf_srclines_from_linecontext(), dwarf_srclines_twolevel_from_linecontext(), and dwarf_srclines_b() allocate. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context /*line_context*/); /* New October 2015. */ /* The offset is in the relevent .debug_line or .debug_line.dwo section (and in a split dwarf package file includes) the base line table offset). */ int dwarf_srclines_table_offset(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Compilation Directory name for the current CU. section (and in a split dwarf package file includes) the base line table offset). Do not free() the string, it is in a dwarf section. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, const char ** /*compilation_directory*/, Dwarf_Error * /*error*/); /* New October 2015. Part of the two-level line table extension. */ /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*decl_file*/, Dwarf_Unsigned * /*decl_line*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Count is the real count of files array entries. This remains supported though it is pretty useless for DWARF5. To process DWARF5 as well as DWARF 2,3,4 (in a uniform fashion) use dwarf_srclines_files_indexes() instead. */ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New March 2018. */ /* Count is the real count of files array entries. Since DWARF 2,3,4 are zero origin indexes and DWARF5 and later are one origin, this function replaces dwarf_srclines_files_count(). */ int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*baseindex*/, Dwarf_Signed * /*count*/, Dwarf_Signed * /*endindex*/, Dwarf_Error * /*error*/); /* New March 2018. Same as dwarf_srclines_files_data, but adds the md5ptr field so cases where DW_LNCT_MD5 is present can return pointer to the MD5 value. With DWARF 5 index starts with 0. See dwarf_srclines_files_indexes() which makes indexing through the files easy. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5ptr, Dwarf_Error * error); /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. Index starts with 1, last is 'count' */ int dwarf_srclines_files_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*directory_index*/, Dwarf_Unsigned * /*last_mod_time*/, Dwarf_Unsigned * /*file_length*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Count is the real count of include array entries. */ int dwarf_srclines_include_dir_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_include_dir_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* The DWARF version number of this compile-unit in the .debug_lines section and the number of actual tables:0 (header with no lines), 1 (standard table), or 2 (experimental). */ int dwarf_srclines_version(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*version*/, Dwarf_Small * /*table_count*/, Dwarf_Error * /*error*/); int dwarf_get_line_section_name_from_die(Dwarf_Die /*die*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* While 'filecount' is signed, the value returned through the pointer is never negative. Original libdwarf from 199x. */ int dwarf_srcfiles(Dwarf_Die /*die*/, char*** /*srcfiles*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineendsequence(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error* /*error*/); int dwarf_line_srcfileno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_fileno*/, Dwarf_Error * /*error*/); /* Is the line address from DW_LNS_set_address? */ int dwarf_line_is_addr_set(Dwarf_Line /*line*/, Dwarf_Bool * /*is_addr_set*/, Dwarf_Error * /*error*/); int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); /* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineoffset*/, Dwarf_Error* /*error*/); int dwarf_linesrc(Dwarf_Line /*line*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_lineblock(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line /* line */, Dwarf_Bool * /*prologue_end*/, Dwarf_Bool * /*eplogue_begin*/, Dwarf_Unsigned * /* isa */, Dwarf_Unsigned * /* discriminator */, Dwarf_Error * /*error*/); /* End line table operations */ /* Two-level line tables: When reading from an actuals table, dwarf_line_logical() returns the logical row number for the line. */ int dwarf_linelogical(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_logical*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linecontext() returns the logical row number corresponding the the calling context for an inlined call. */ int dwarf_linecontext(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_context*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprogno() returns the index in the subprograms table of the inlined subprogram. */ int dwarf_line_subprogno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_subprogno*/, Dwarf_Error * /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprog() returns the name of the inlined subprogram, its declaration filename, and its declaration line number, if available. */ int dwarf_line_subprog(Dwarf_Line /*line*/, char ** /*returned_subprog_name*/, char ** /*returned_filename*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ /* .debug_names names table interfaces. DWARF5 */ /* New April 2017 */ int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, Dwarf_Dnames_Head * /*dn_out*/, /* *dn_count_out returns the number of name indexes in the .debug_names section */ Dwarf_Unsigned * /*dn_index_count_out*/, Dwarf_Error * /*error*/); /* Since there may be multiple name indexes in a .debug_names section we use index_number starting at 0 through dn_index_count_out-1. */ int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned * /*section_offset*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * /*comp_unit_count*/, Dwarf_Unsigned * /*local_type_unit_count*/, Dwarf_Unsigned * /*foreign_type_unit_count*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*name_count*/, /* The following are counted in bytes */ Dwarf_Unsigned * /*indextable_overall_length*/, Dwarf_Unsigned * /*abbrev_table_size*/, Dwarf_Unsigned * /*entry_pool_size*/, Dwarf_Unsigned * /*augmentation_string_size*/, Dwarf_Error * /*error*/); int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*sig_number*/, Dwarf_Unsigned * /*sig_mininum*/, Dwarf_Unsigned * /*sig_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Error * /*error*/); int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*bucket_number*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*index_of_name_entry*/, Dwarf_Error * /*error*/); int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*name_entry*/, Dwarf_Unsigned * /*names_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Unsigned * /*offset_to_debug_str*/, Dwarf_Unsigned * /*offset_in_entrypool*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * /*number_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * /*index_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry_index*/, Dwarf_Unsigned /*abbrev_form_index*/, Dwarf_Unsigned * /*name_index_attr*/, Dwarf_Unsigned * /*form*/, Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_in_entrypool*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Unsigned * /*index_of_abbrev*/, Dwarf_Unsigned * /*offset_of_initial_value*/, Dwarf_Error * /*error*/); /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*index_of_abbrev*/, Dwarf_Unsigned /*offset_in_entrypool_of_values*/, Dwarf_Unsigned * /*array_dw_idx_number*/, Dwarf_Unsigned * /*array_form*/, Dwarf_Unsigned * /*array_of_offsets*/, Dwarf_Sig8 * /*array_of_signatures*/, /* offset of the next entrypool entry. */ Dwarf_Unsigned * /*offset_of_next_entrypool*/, Dwarf_Error * /*error*/); /* FIXME: add interfaces for string search given hash and string */ /* end of .debug_names interfaces. */ /* New October 2019. Access to the GNU section named .gnu_debuglink and/or the section .note.gnu.build-id. See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html The dbg argument provides data access and relies on fields de_path,de_debuglink_globals, de_debuglink_globals_length If no debuglink then name_returned,crc_returned and debuglink_path_returned will get set 0 through the pointers. If no .note.gnu.build-id then buildid_length_returned, and buildid_returned will be set 0 through the pointers. See libdwarf2.1.mm for additional important details. see dwarf_add_file_path() and dwarf_add_debuglink_global_path(). */ int dwarf_gnu_debuglink(Dwarf_Debug /*dbg*/, char ** /*name_returned*/, unsigned char ** /*crc_returned from the debuglink section*/, char ** /*debuglink_path_returned*/, unsigned * /*debuglink_path_count_returned*/, unsigned * /*buildid_type_returned */, char ** /*buildid_owner_name_returned*/, unsigned char ** /*buildid_returned*/, unsigned * /*buildid_length_returned*/, char *** /*paths_returned*/, unsigned * /*paths_length_returned*/, Dwarf_Error* /*error*/); /* See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html and dwarf_gnu_debuglink() pathname is a path-prefix to be added to a list of path-prefixes, The default "/usr/lib/debug" is built-in and is the first such in the list held in dbg. The path prefix should start with / . It can just end or end with / , either choice will work. */ int dwarf_add_debuglink_global_path(Dwarf_Debug /*dbg*/, const char *pathname, Dwarf_Error* /*error*/); /* global name space operations (.debug_pubnames access) The pubnames and similar sections are rarely used. Few compilers emit them. They are DWARF 2,3,4 only., not DWARF 5. */ /* New March 2019. Mostly special for dwarfdump. */ int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, int /* flag */, Dwarf_Error* /*error*/); int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, Dwarf_Error* /*error*/); void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Global* /*globals*/, Dwarf_Signed /*number_of_globals*/); int dwarf_globname(Dwarf_Global /*glob*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_global_die_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error * /*error*/); /* This returns the CU die global offset if one knows the CU header global offset. See also dwarf_CU_dieoffset_given_die(). */ int dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); /* The _b form is new October 2011. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Bool /*is_info. True means look in debug_Info, false use debug_types.*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset #endif int dwarf_global_cu_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_global_name_offsets(Dwarf_Global /*global*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. */ int dwarf_get_globals_header(Dwarf_Global /*global*/, Dwarf_Off * /*offset_pub_header*/, Dwarf_Unsigned * /*length_size*/, Dwarf_Unsigned * /*length_pub*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*header_info_offset*/, Dwarf_Unsigned * /*info_length*/, Dwarf_Error* /*error*/); /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, Dwarf_Signed * /*number_of_funcs*/, Dwarf_Error* /*error*/); void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Func* /*funcs*/, Dwarf_Signed /*number_of_funcs*/); int dwarf_funcname(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_func_die_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_cu_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_name_offsets(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, SGI IRIX .debug_typenames section. Same content as DWARF3 .debug_pubtypes, but defined years before .debug_pubtypes was defined. SGI IRIX only. */ int dwarf_get_types(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*types*/, Dwarf_Signed /*number_of_types*/); int dwarf_typename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, DWARF3 .debug_pubtypes section. */ int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*pubtypes*/, Dwarf_Signed /*number_of_pubtypes*/); int dwarf_pubtypename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_pubtype_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* File-scope static variable name operations. */ int dwarf_get_vars(Dwarf_Debug /*dbg*/, Dwarf_Var** /*vars*/, Dwarf_Signed * /*number_of_vars*/, Dwarf_Error* /*error*/); void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Var* /*vars*/, Dwarf_Signed /*number_of_vars*/); int dwarf_varname(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_var_die_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_cu_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_name_offsets(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* weak name operations. */ int dwarf_get_weaks(Dwarf_Debug /*dbg*/, Dwarf_Weak** /*weaks*/, Dwarf_Signed * /*number_of_weaks*/, Dwarf_Error* /*error*/); void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Weak* /*weaks*/, Dwarf_Signed /*number_of_weaks*/); int dwarf_weakname(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* location list section operation. (.debug_loc access) */ int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Addr* /*hipc*/, Dwarf_Addr* /*lopc*/, Dwarf_Ptr* /*data*/, Dwarf_Unsigned* /*entry_len*/, Dwarf_Unsigned* /*next_entry*/, Dwarf_Error* /*error*/); /* abbreviation section operations */ int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Abbrev * /*returned_abbrev*/, Dwarf_Unsigned* /*length*/, Dwarf_Unsigned* /*attr_count*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, Dwarf_Half* /*return_tag_number*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned* /*return_code_number*/, Dwarf_Error* /*error*/); /* See comments in dwarf_abbrev.c. Not an entirely safe function. */ int dwarf_get_abbrev_count(Dwarf_Debug /*dbg*/); int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed* /*return_flag*/, Dwarf_Error* /*error*/); /* New August 2019. Most uses will call with filter_outliers non-zero. In that case impossible values return DW_DLV_ERROR. Those doing extra things (like dwarfdump) will call with filter_outliers zero to get the raw data (effectively); */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned indx, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implict_const, Dwarf_Off * offset, Dwarf_Error * error); /* Obsolete because it cannot return the DW_FORM_implicit_const value. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed /*index*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Signed* /*form*/, Dwarf_Off* /*offset*/, Dwarf_Error* /*error*/); int dwarf_get_string_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* consumer string section operation */ int dwarf_get_str(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, char** /*string*/, Dwarf_Signed * /*strlen_of_string*/, Dwarf_Error* /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* Consumer op on gnu .eh_frame info */ int dwarf_get_fde_list_eh( Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* consumer operations on frame info: .debug_frame */ int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* Release storage gotten by dwarf_get_fde_list_eh() or dwarf_get_fde_list() */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Cie * /*cie_data*/, Dwarf_Signed /*cie_element_count*/, Dwarf_Fde * /*fde_data*/, Dwarf_Signed /*fde_element_count*/); int dwarf_get_fde_range(Dwarf_Fde /*fde*/, Dwarf_Addr* /*low_pc*/, Dwarf_Unsigned* /*func_length*/, Dwarf_Ptr* /*fde_bytes*/, Dwarf_Unsigned* /*fde_byte_length*/, Dwarf_Off* /*cie_offset*/, Dwarf_Signed* /*cie_index*/, Dwarf_Off* /*fde_offset*/, Dwarf_Error* /*error*/); /* Useful for IRIX only: see dwarf_get_cie_augmentation_data() dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, Dwarf_Signed* /* offset_into_exception_tables */, Dwarf_Error* /*error*/); int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, Dwarf_Cie * /*cie_returned*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info_b(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Half* /*offset_size*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Error* /*error*/); /* dwarf_get_cie_index new September 2009. */ int dwarf_get_cie_index( Dwarf_Cie /*cie*/, Dwarf_Signed* /*index*/, Dwarf_Error* /*error*/ ); int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); 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*/); /* In this older interface DW_FRAME_CFA_COL is a meaningful column (which does not work well with DWARF3 or non-MIPS architectures). */ int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Signed* /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* See discussion of dw_value_type, libdwarf.h. Use of DW_FRAME_CFA_COL is not meaningful in this interface. See dwarf_get_fde_info_for_cfa_reg3(). */ /* dwarf_get_fde_info_for_reg3 is useful on a single column, but it is inefficient to iterate across all table_columns using this function. Instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error* /*error*/); /* Use this to get the cfa. Or the above function. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Error* /*error*/); int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, Dwarf_Die /*subr_die */, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, Dwarf_Unsigned /*fde_index*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, Dwarf_Addr /*pc_of_interest*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Addr* /*lopc*/, Dwarf_Addr* /*hipc*/, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, Dwarf_Ptr /*instruction*/, Dwarf_Unsigned /*i_length*/, Dwarf_Frame_Op** /*returned_op_list*/, Dwarf_Signed* /*op_count*/, Dwarf_Error* /*error*/); /* Operations on .debug_aranges. */ int dwarf_get_aranges(Dwarf_Debug /*dbg*/, Dwarf_Arange** /*aranges*/, Dwarf_Signed * /*arange_count*/, Dwarf_Error* /*error*/); int dwarf_get_ranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_aranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_arange( Dwarf_Arange* /*aranges*/, Dwarf_Unsigned /*arange_count*/, Dwarf_Addr /*address*/, Dwarf_Arange * /*returned_arange*/, Dwarf_Error* /*error*/); int dwarf_get_cu_die_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_get_arange_cu_header_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_cu_header_offset*/, Dwarf_Error* /*error*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_arange_cu_header_offset #endif /* DWARF2,3 interface. No longer really adequate (it was never right for segmented address spaces, please switch to using dwarf_get_arange_info_b instead. There is no effective difference between these functions if the address space of the target is not segmented. */ int dwarf_get_arange_info( Dwarf_Arange /*arange*/, Dwarf_Addr* /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off* /*cu_die_offset*/, Dwarf_Error* /*error*/ ); /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b( Dwarf_Arange /*arange*/, Dwarf_Unsigned* /*segment*/, Dwarf_Unsigned* /*segment_entry_size*/, Dwarf_Addr * /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off * /*cu_die_offset*/, Dwarf_Error * /*error*/ ); /* BEGIN: DWARF5 .debug_macro interfaces NEW November 2015. */ int dwarf_get_macro_context(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_unit_offset_out*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length_out*/, Dwarf_Error * /*error*/); /* Just like dwarf_get_macro_context, but instead of using DW_AT_macros or DW_AT_GNU_macros to get the offset we just take the offset given. */ int dwarf_get_macro_context_by_offset(Dwarf_Die /*die*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length*/, Dwarf_Error * /*error*/); void dwarf_dealloc_macro_context(Dwarf_Macro_Context /*mc*/); int dwarf_get_macro_section_name(Dwarf_Debug /*dbg*/, const char ** /*sec_name_out*/, Dwarf_Error * /*err*/); int dwarf_macro_context_head(Dwarf_Macro_Context /*head*/, Dwarf_Half * /*version*/, Dwarf_Unsigned * /*mac_offset*/, Dwarf_Unsigned * /*mac_len*/, Dwarf_Unsigned * /*mac_header_len*/, unsigned * /*flags*/, Dwarf_Bool * /*has_line_offset*/, Dwarf_Unsigned * /*line_offset*/, Dwarf_Bool * /*has_offset_size_64*/, Dwarf_Bool * /*has_operands_table*/, Dwarf_Half * /*opcode_count*/, Dwarf_Error * /*error*/); /* Returns data from the operands table in the macro unit header. */ int dwarf_macro_operands_table(Dwarf_Macro_Context /*head*/, Dwarf_Half /*index*/, /* 0 to opcode_count -1 */ Dwarf_Half * /*opcode_number*/, Dwarf_Half * /*operand_count*/, const Dwarf_Small ** /*operand_array*/, Dwarf_Error * /*error*/); /* Access to the macro operations, 0 to macro_ops_count_out-1 Where the last of these will have macro_operator 0 (which appears in the ops data and means end-of-ops). op_start_section_offset is the section offset of the macro operator (which is a single unsigned byte, and is followed by the macro operand data). */ int dwarf_get_macro_op(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*op_start_section_offset*/, Dwarf_Half * /*macro_operator*/, Dwarf_Half * /*forms_count*/, const Dwarf_Small ** /*formcode_array*/, Dwarf_Error * /*error*/); int dwarf_get_macro_defundef(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*index*/, Dwarf_Unsigned * /*offset*/, Dwarf_Half * /*forms_count*/, const char ** /*macro_string*/, Dwarf_Error * /*error*/); int dwarf_get_macro_startend_file(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*name_index_to_line_tab*/, const char ** /*src_file_name*/, Dwarf_Error * /*error*/); int dwarf_get_macro_import(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*target_offset*/, Dwarf_Error * /*error*/); /* END: DWARF5 .debug_macro interfaces. */ /* consumer .debug_macinfo information interface. */ struct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; /* offset, in the section, of this macro info */ Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ Dwarf_Signed dmd_lineno; /* the source line number where applicable and vend_def number if vendor_extension op */ Dwarf_Signed dmd_fileindex;/* the source file index: applies to define undef start_file */ char * dmd_macro; /* macro name (with value for defineop) string from vendor ext */ }; /* dwarf_print_lines is for use by dwarfdump: it prints line info to stdout. The _dwarf name is obsolete. Use dwarf_ instead. Added extra argnument 2/2009 for better checking. */ int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/); int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/, int * /*error_count_out */); /* As of August 2013, dwarf_print_lines() no longer uses printf. Instead it calls back to the application using a function pointer once per line-to-print. The lines passed back already have any needed newlines. The following struct is used to initialize the callback mechanism. Failing to call the dwarf_register_printf_callback() function will prevent the lines from being passed back but such omission is not an error. See libdwarf2.1.mm for further documentation. The return value is the previous set of callback values. */ typedef void (* dwarf_printf_callback_function_type) (void * /*user_pointer*/, const char * /*linecontent*/); struct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; /* If called with a NULL newvalues pointer, it simply returns the current set of values for this Dwarf_Debug. */ struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug /*dbg*/, struct Dwarf_Printf_Callback_Info_s * /*newvalues*/); /* dwarf_check_lineheader lets dwarfdump get detailed messages about some compiler errors we detect. We return the count of detected errors through the pointer. */ void dwarf_check_lineheader(Dwarf_Die /*cu_die*/,int *errcount_out); /* dwarf_ld_sort_lines helps SGI IRIX ld rearrange lines in .debug_line in a .o created with a text section per function. -OPT:procedure_reorder=ON where ld-cord (cord(1)ing by ld, not by cord(1)) may have changed the function order. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /* buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); int dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /*buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); /* Used by dwarfdump -v to print fde offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); int dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); /* Used by dwarfdump -v to print cie offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off */, Dwarf_Error * /*err*/); int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off /*macro_offset*/, Dwarf_Unsigned /*maximum_count*/, Dwarf_Signed * /*entry_count*/, Dwarf_Macro_Details ** /*details*/, Dwarf_Error * /*err*/); /* dwarf_get_offset_size() New October 2015 */ int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*offset_size*/, Dwarf_Error * /*error*/); int dwarf_get_address_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); int dwarf_get_die_address_size(Dwarf_Die /*die*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half /* dwversion */, Dwarf_Half /* attrnum */, Dwarf_Half /*offset_size */, Dwarf_Half /*form*/); /* BEGIN gdbindex operations interfaces. */ /* .gdb_index section operations. A GDB extension. The section is in some executables and if present is used to quickly map an address or name to a skeleton CU or TU. If present then there are .dwo or .dwp files somewhere to make detailed debugging possible (up to user code to find it/them and deal with them). Version 8 built by gdb, so type entries are ok as is. Version 7 built by the 'gold' linker and type index entries for a CU must be derived othewise, the type index is not correct... ? FIXME */ /* Creates a Dwarf_Gdbindex, returning it and its values through the pointers. */ int dwarf_gdbindex_header(Dwarf_Debug /*dbg*/, Dwarf_Gdbindex * /*gdbindexptr*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*cu_list_offset*/, Dwarf_Unsigned * /*types_cu_list_offset*/, Dwarf_Unsigned * /*address_area_offset*/, Dwarf_Unsigned * /*symbol_table_offset*/, Dwarf_Unsigned * /*constant_pool_offset*/, Dwarf_Unsigned * /*section_size*/, Dwarf_Unsigned * /*unused_reserved*/, const char ** /*section_name*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*cu_length*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to types_list_length -1 */ int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*tu_offset*/, Dwarf_Unsigned * /*type_signature*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*low_adddress*/, Dwarf_Unsigned * /*high_address*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*symtab_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*string_offset*/, Dwarf_Unsigned * /*cu_vector_offset*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned * /*innercount*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned /*innerindex*/, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, Dwarf_Unsigned * /*symbol_kind*/, Dwarf_Unsigned * /*is_static*/, Dwarf_Error * /*error*/); /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*stringoffset*/, const char ** /*string_ptr*/, Dwarf_Error * /*error*/); void dwarf_gdbindex_free(Dwarf_Gdbindex /*gdbindexptr*/); /* END gdbindex/debugfission operations. */ /* START debugfission dwp .debug_cu_index and .debug_tu_index operations. */ int dwarf_get_xu_index_header(Dwarf_Debug /*dbg*/, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * /*xuhdr*/, Dwarf_Unsigned * /*version_number*/, Dwarf_Unsigned * /*offsets_count L*/, Dwarf_Unsigned * /*units_count N*/, Dwarf_Unsigned * /*hash_slots_count M*/, const char ** /*sect_name*/, Dwarf_Error * /*err*/); int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header /*xuhdr*/, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** /*typename*/, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** /*sectionname*/, Dwarf_Error * /*err*/); /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*index*/, /* Returns the hash value. 64 bits. */ Dwarf_Sig8 * /*hash_value*/, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * /*index_to_sections*/, Dwarf_Error * /*err*/); /* Columns 0 to L-1, valid. */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header /*xuhdr*/, /* Row index defined to be row zero. */ Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*DW_SECT_ number*/, const char ** /*DW_SECT_ name*/, Dwarf_Error * /*err*/); /* Rows 1 to N col 0 to L-1 are valid */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*row_index*/, Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*sec_offset*/, Dwarf_Unsigned* /*sec_size*/, Dwarf_Error * /*err*/); void dwarf_xu_header_free(Dwarf_Xu_Index_Header /*xuhdr*/); /* Defined larger than necessary. This struct, being visible, will be difficult to change: binary compatibility. */ #define DW_FISSION_SECT_COUNT 12 /* User must allocate this struct, zero it, and pass a pointer to it into dwarf_get_debugfission_for_cu . */ struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; typedef struct Dwarf_Debug_Fission_Per_CU_s Dwarf_Debug_Fission_Per_CU ; /* For any Dwarf_Die in a compilation unit, return the debug fission table data through percu_out. Usually applications will pass in the CU die. Calling code should zero all of the struct Dwarf_Debug_Fission_Per_CU_s before calling this. If there is no debugfission data this returns DW_DLV_NO_ENTRY (only .dwp objects have debugfission data). */ int dwarf_get_debugfission_for_die(Dwarf_Die /* die */, Dwarf_Debug_Fission_Per_CU * /* percu_out */, Dwarf_Error * /* err */); /* Given a key (hash signature) from a .o, find the per-cu information for the CU with that key. */ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*key, hash signature */, const char * key_type /*"cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * /*percu_out */, Dwarf_Error * /*err */); /* END debugfission dwp .debug_cu_index and .debug_tu_index operations. */ /* Utility operations */ Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); /* stringcheck zero is default and means do all string length validity checks. Call with parameter value 1 to turn off many such checks (and increase performance). Call with zero for safest running. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_stringcheck(int /*stringcheck*/); /* 'apply' defaults to 1 and means do all 'rela' relocations on reading in a dwarf object section with such relocations. Call with parameter value 0 to turn off application of such relocations. Since the static linker leaves 'bogus' data in object sections with a 'rela' relocation section such data cannot be read sensibly without processing the relocations. Such relocations do not exist in executables and shared objects (.so), the relocations only exist in plain .o relocatable object files. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_reloc_application(int /*apply*/); /* Unimplemented */ Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); /* Unimplemented */ Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, Dwarf_Unsigned /*type*/); /* DWARF Producer Interface */ /* New form June, 2011. Adds user_data argument. */ typedef int (*Dwarf_Callback_Func)( const char* /*name*/, int /*size*/, Dwarf_Unsigned /*type*/, Dwarf_Unsigned /*flags*/, Dwarf_Unsigned /*link*/, Dwarf_Unsigned /*info*/, Dwarf_Unsigned* /*sect_name_index*/, void * /*user_data*/, int* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR and if DW_DLV_OK returns the Dwarf_P_Debug pointer through the dbg_returned argument. */ int dwarf_producer_init( Dwarf_Unsigned /*flags*/, Dwarf_Callback_Func /*func*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, void * /*user_data*/, const char *isa_name, /* See isa/abi names in pro_init.c */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR. The desired form must be DW_FORM_string (the default) or DW_FORM_strp. */ int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, int /*desired_form*/, Dwarf_Error* /*error*/); /* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New September 2016. The preferred interface. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*nbufs_out*/, Dwarf_Error* /*error*/); /* New September 2016. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Ptr * /*section_bytes*/, Dwarf_Error* /*error*/); /* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info_count( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*count_of_relocation_sections*/, int * /*drd_buffer_version*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info( Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*elf_section_index*/, Dwarf_Signed * /*elf_section_index_link*/, Dwarf_Unsigned * /*relocation_buffer_count*/, Dwarf_Relocation_Data * /*reldata_buffer*/, Dwarf_Error* /*error*/); /* v1: no drd_length field, enum explicit */ /* v2: has the drd_length field, enum value in uchar member */ #define DWARF_DRD_BUFFER_VERSION 2 /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); /* Preferred version December 2018. */ int dwarf_get_die_markers_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); int dwarf_get_string_attributes_info(Dwarf_P_Debug, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_P_String_Attr *, Dwarf_Error *); void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR */ int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* dwarf_add_AT_reference_b allows otherdie to be NULL with the assumption the caller will then later call dwarf_fixup_AT_reference_die() with a non-null target die. New 22 October, 2013 */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie after a single pass thru the DIE generation. Needed for forward-references. New 22 October, 2013. */ int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_string_a( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* October 2017 for DW_FORM_data16. Usable with any attribute, though it should only be in limited use. DWARF5 only. Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. Returns the new attribute pointer through *return_attr. */ int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Form_Data16 * /* pointstovalue */, Dwarf_P_Attribute * /* return_attr */, Dwarf_Error * /*error*/); /* November 2018. DW_AT_implicit const generation. */ int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Producer line creation functions (.debug_line) */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned * /*index_in_directories*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned * /*file_entry_count_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Unsigned * /*cie_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*corresponding subprogram die*/, Dwarf_Unsigned /*cie_to_use*/, Dwarf_Unsigned /*virt_addr_of_described_code*/, Dwarf_Unsigned /*length_of_code*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_fde_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Unsigned * /*index_to_fde*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_info_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Unsigned * /*fde_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); /* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_fde_inst_a( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*len*/, Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde * /*fde_out*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_fde_cfa_offset_a( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* die creation & addition routines dwarf_new_die_a() new September 2016. Preferred over dwarf_new_die(). */ int dwarf_new_die_a( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_P_Die * /*die_out*/, Dwarf_Error* /*error*/); Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* New September 2016. */ int dwarf_add_die_to_debug_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error); Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_get_die_marker_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* New September 2016. Preferred version */ int dwarf_die_link_a( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); void dwarf_dealloc_compressed_block( Dwarf_P_Debug, void * ); /* Call this passing in return value from dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); /* dwarf_compress_integer_block_a( new 11 February 2019. Like the earlier version this turns an array of signed integers into a block of sleb values (and if the values are small enough it might be a compression! Or it could be an expansion...). Return DW_DLV_OK on success. Supercedes dwarf_compress_integer_block(): as no ugly cast needed to know if dwarf_compress_integer_block_a() succeeds or not. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*input_array_length*/, Dwarf_Signed * /*input_array*/, Dwarf_Unsigned * /*output_block_len*/, void ** /*output_block_returned*/, Dwarf_Error * /*error */); /* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ Dwarf_Small, /*size of integer units: 8, 16, 32, 64*/ void*, /*data*/ Dwarf_Unsigned, /*number of elements*/ Dwarf_Unsigned*, /*number of bytes in output block*/ Dwarf_Error* /*error*/ ); /* New February 2019. On success returns DW_DLV_OK and creates an array of Dwarf_Signed values from the block of sleb numbers. This interface supercedes dwarf_uncompress_integer_block(). No ugly cast needed to know if dwarf_uncompress_integer_block_a() succeeds or not. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*input_length_in_bytes*/, void * /*input_block*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Signed ** /*value_array*/, Dwarf_Error * /*error*/); /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). Returns a DW_DLV_BADADDR on error. Otherwise returns a pointer to an array of 32bit integers. The signed argument must be non-zero (the decode assumes sleb integers in the input data) at this time. Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements of the array that the return value points to) thru the argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ Dwarf_Small, /*size of integer units: 8, 16, 32, 64 */ void*, /*input data */ Dwarf_Unsigned, /*number of bytes in input */ Dwarf_Unsigned*, /*number of units in output block */ Dwarf_Error* /*error */ ); /* Operations to create location expressions. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr * /*expr_out*/, Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_gen_a( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Unsigned * /*next_byte_offset*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_addr_c( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_current_offset_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_into_block_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Small ** /*start_address*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Signed /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_arange_c( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubtype_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_funcname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_typename_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_varname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); int dwarf_add_weakname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); /* .debug_names producer functions */ /* dwarf_force_debug_names forces creation of .debug_names (if DWARF5 being produced) even if empty. Only for testing libdwarf. */ int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, Dwarf_Error* /*error*/); /* Other debug_names functions are needed... FIXME */ /* end .debug_names producer functions */ /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. */ int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, with (arglist), no space before (*/, char * /*macvalue*/, Dwarf_Error* /*error*/); int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, no arglist, of course*/, Dwarf_Error* /*error*/); int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*fileindex*/, Dwarf_Unsigned /*linenumber*/, Dwarf_Error* /*error*/); int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*constant*/, char * /*string*/, Dwarf_Error* /*error*/); /* end macinfo producer functions */ int dwarf_attr_offset(Dwarf_Die /*die*/, Dwarf_Attribute /*attr of above die*/, Dwarf_Off * /*returns offset thru this ptr */, Dwarf_Error * /*error*/); /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); /* New October 2011., adds .debug_types section to the sizes returned. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/, Dwarf_Unsigned * /*debug_names_size*/, Dwarf_Unsigned * /*debug_loclists_size*/, Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ /* Multiple releases spelled 'initial' as 'inital' . The 'inital' spelling should not be used. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* Additional interface with correct 'initial' spelling. */ /* It is likely you will want to call the following 6 functions before accessing any frame information. All are useful to tailor handling of pseudo-registers needed to turn frame operation references into simpler forms and to reflect ABI specific data. Of course altering libdwarf.h and dwarf.h allow the same capabilities, but header changes in the distribution would require you re-integrate your libdwarf.h changes into the distributed libdwarf.h ... so use the following functions instead.*/ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* dwarf_set_default_address_size only sets 'value' if value is greater than zero. */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug /*dbg*/, Dwarf_Small /* value */); /* As of April 27, 2009, this version with no diepointer is obsolete though supported. Use dwarf_get_ranges_a() instead. */ int dwarf_get_ranges(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* This adds the address_size argument. New April 27, 2009 */ int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /* diepointer */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); /* New April 2018. Allows applications to print the .debug_str_offsets section. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ struct Dwarf_Str_Offsets_Table_s; typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; /* Allocates a struct Dwarf_Str_Offsets_Table_s for the section and returns DW_DLV_OK and sets a pointer to the struct through the table_data pointer if successful. If there is no such section it returns DW_DLV_NO_ENTRY. */ int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, Dwarf_Str_Offsets_Table * /*table_data*/, Dwarf_Error * /*error*/); /* Close access, free table_data. */ int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Error * /*error*/); /* Call till it returns DW_DLV_NO_ENTRY (normal end) or DW_DLV_ERROR (error) and stop. On successful call, call dwarf_str_offsets_table_entry() to get the individual table values on the now-active table. */ int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*unit_length*/, Dwarf_Unsigned * /*unit_length_offset*/, Dwarf_Unsigned * /*table_start_offset*/, Dwarf_Half * /*entry_size*/, Dwarf_Half * /*version*/, Dwarf_Half * /*padding*/, Dwarf_Unsigned * /*table_value_count*/, Dwarf_Error * /*error*/); /* Valid index values n: 0 <= n < table_entry_count for the active table */ int dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned /*index_to_entry*/, Dwarf_Unsigned * /*entry_value*/, Dwarf_Error * /*error*/); /* After all str_offsets read this reports final wasted-bytes count. */ int dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*wasted_byte_count*/, Dwarf_Unsigned * /*table_count*/, Dwarf_Error * /*error*/); /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 #define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). The pointers returned in the array of pointers are invalidated by ANY call to libdwarf. Use them before making another libdwarf call! The array of string pointers passed in always has a final null pointer, so if there are N pointers the and M actual strings, then MIN(M,N-1) pointers are set to point to error strings. The array of pointers to strings always terminates with a NULL pointer. If 'count' is passed in zero then errmsg_ptrs_array is not touched. The function returns DW_DLV_NO_ENTRY if no harmless errors were noted so far. Returns DW_DLV_OK if there are errors. Never returns DW_DLV_ERROR. Each call empties the error list (discarding all current entries). If newerr_count is non-NULL the count of harmless errors since the last call is returned through the pointer (some may have been discarded or not returned, it is a circular list...). If DW_DLV_NO_ENTRY is returned none of the arguments here are touched or used. */ int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/, unsigned /*count*/, const char ** /*errmsg_ptrs_array*/, unsigned * /*newerr_count*/); /* Insertion is only for testing the harmless error code, it is not necessarily useful otherwise. */ void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/, char * /*newerror*/); /* The size of the circular list of strings may be set and reset as needed. If it is shortened excess messages are simply dropped. It returns the previous size. If zero passed in the size is unchanged and it simply returns the current size */ unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, unsigned /*maxcount*/); /* The harmless error strings (if any) are freed when the dbg is dwarf_finish()ed. */ /* When the val_in is known these dwarf_get_TAG_name (etc) functions return the string corresponding to the val_in passed in through the pointer s_out and the value returned is DW_DLV_OK. The strings are in static storage and must not be freed. If DW_DLV_NO_ENTRY is returned the val_in is not known and *s_out is not set. DW_DLV_ERROR is never returned.*/ /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); /* dwarf_get_LLEX_name is likely just temporary. Not standard. */ extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); /* END FILE */ /* Convert local offset into global offset */ int dwarf_convert_to_global_offset(Dwarf_Attribute /*attr*/, Dwarf_Off /*offset*/, Dwarf_Off* /*ret_offset*/, Dwarf_Error* /*error*/); /* Get both offsets (local and global) */ int dwarf_die_offsets(Dwarf_Die /*die*/, Dwarf_Off* /*global_offset*/, Dwarf_Off* /*local_offset*/, Dwarf_Error* /*error*/); /* Giving a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug /*dbg*/, const char * /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Giving a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug /*dbg*/, int /*section_index*/, const char ** /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Get section count, of object file sections. */ int dwarf_get_section_count(Dwarf_Debug /*dbg*/); /* Get the version and offset size of a CU context. This is useful as a precursor to calling dwarf_get_form_class() at times. */ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); int dwarf_discr_list(Dwarf_Debug /*dbg*/, Dwarf_Small * /*blockpointer*/, Dwarf_Unsigned /*blocklen*/, Dwarf_Dsc_Head * /*dsc_head_out*/, Dwarf_Unsigned * /*dsc_array_length_out*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Unsigned * /*out_discr_low*/, Dwarf_Unsigned * /*out_discr_high*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Signed * /*out_discr_low*/, Dwarf_Signed * /*out_discr_high*/, Dwarf_Error * /*error*/); /* 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*/, Dwarf_Unsigned * /*section_count_out*/, Dwarf_Unsigned * /*group_count_out*/, Dwarf_Unsigned * /*selected_group_out*/, Dwarf_Unsigned * /*map_entry_count_out*/, Dwarf_Error * /*error*/); /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' 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*/, Dwarf_Unsigned /*map_entry_count*/, Dwarf_Unsigned * /*group_numbers_array*/, Dwarf_Unsigned * /*sec_numbers_array*/, const char ** /*sec_names_array*/, Dwarf_Error * /*error*/); /* dwarf_get_endian_copy_function new. December 2019. */ void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/))(void *, const void * /*src*/, unsigned long /*srclen*/); /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); int dwarf_encode_signed_leb128(Dwarf_Signed /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); /* Record some application command line options in libdwarf. This is not arc/argv processing, just precooked setting of a flag in libdwarf based on something the application wants. check_verbose_mode of TRUE means do more checking and sometimes print errors (from libdwarf). Not restricted to a single Dwarf_Debug, it applies to the libdwarf the executable is using. */ typedef struct { Dwarf_Bool check_verbose_mode; } Dwarf_Cmdline_Options; extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*str_count*/, Dwarf_Unsigned * /*str_total_length*/, Dwarf_Unsigned * /*count_debug_str*/, Dwarf_Unsigned * /*len_debug_str*/, Dwarf_Unsigned * /*reused_count*/, Dwarf_Unsigned * /*reused_len*/, Dwarf_Error * /*error*/); #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ #define DW_FTYPE_MACH_O 2 /* MacOS. */ #define DW_FTYPE_PE 3 /* Windows */ #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ int dwarf_object_detector_path(const char *path, char *outpath, unsigned long, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ dwarfutils-20200114/libdwarf/gennames.c000066400000000000000000000500721361531463500176770ustar00rootroot00000000000000/* Copyright 2009-2010 SN Systems Ltd. All rights reserved. Portions Copyright 2009-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #include /* For errno declaration. */ #include #include #include "dwgetopt.h" #include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ /* gennames.c Prints routines to return constant name for the associated value (such as the TAG name string for a particular tag). The input is dwarf.h For each set of names with a common prefix, we create a routine to return the name given the value. Also print header file that gives prototypes of routines. To handle cases where there are multiple names for a single value (DW_AT_* has some due to ambiguities in the DWARF2 spec) we take the first of a given value as the definitive name. TAGs, Attributes, etc are given distinct checks. There are multiple output files as some people find one form more pleasant than the other. The doprinting argument is so that when used by tag_tree.c, and tag_attr.c that we don't get irritating messages on stderr when those dwarfdump built-time applications are run. Some compilers generate better code for switch statements than others, so the -s and -t options let the user decide which is better for their compiler (when building dwarfdump): a simple switch or code doing binary search. This choice affects the runtime speed of dwarfdump. */ typedef int boolean; #define TRUE 1 #define FALSE 0 #define FAILED 1 static void OpenAllFiles(void); static void WriteFileTrailers(void); static void CloseAllFiles(void); static void GenerateInitialFileLines(void); static void GenerateOneSet(void); #ifdef TRACE_ARRAY static void PrintArray(void); #endif /* TRACE_ARRAY */ static boolean is_skippable_line(char *pLine); static void ParseDefinitionsAndWriteOutput(void); /* We don't need really long lines: the input file is simple. */ #define MAX_LINE_SIZE 1000 /* We don't need a variable array size, it just has to be big enough. */ #define ARRAY_SIZE 300 #define MAX_NAME_LEN 64 /* To store entries from dwarf.h */ typedef struct { char name[MAX_NAME_LEN]; /* short name */ unsigned value; /* value */ /* Original spot in array. Lets us guarantee a stable sort. */ unsigned original_position; } array_data; /* A group_array is a grouping from dwarf.h. All the TAGs are one group, all the FORMs are another group, and so on. */ static array_data group_array[ARRAY_SIZE]; static unsigned array_count = 0; typedef int (*compfn)(const void *,const void *); static int Compare(array_data *,array_data *); static const char *prefix_root = "DW_"; static const unsigned prefix_root_len = 3; /* f_dwarf_in is the input dwarf.h. The others are output files. */ static FILE *f_dwarf_in; static FILE *f_names_h; static FILE *f_names_c; static FILE *f_names_enum_h; static FILE *f_names_new_h; /* Size unchecked, but large enough. */ static char prefix[200] = ""; static const char *usage[] = { "Usage: gennames ", " -i input-table-path", " -o output-table-path", " -s use 'switch' in generation", " -t use 'tables' in generation", "", }; static void print_args(int argc, char *argv[]) { int index; printf("Arguments: "); for (index = 1; index < argc; ++index) { printf("%s ",argv[index]); } printf("\n"); } char *program_name = 0; static char *input_name = 0; static char *output_name = 0; static boolean use_switch = TRUE; static boolean use_tables = FALSE; static void print_version(const char * name) { #ifdef _DEBUG const char *acType = "Debug"; #else const char *acType = "Release"; #endif /* _DEBUG */ printf("%s [%s %s]\n",name,DW_VERSION_DATE_STR,acType); } static void print_usage_message(const char *options[]) { int index; for (index = 0; *options[index]; ++index) { printf("%s\n",options[index]); } } /* process arguments */ static void process_args(int argc, char *argv[]) { int c = 0; boolean usage_error = FALSE; program_name = argv[0]; while ((c = dwgetopt(argc, argv, "i:o:st")) != EOF) { switch (c) { case 'i': input_name = dwoptarg; break; case 'o': output_name = dwoptarg; break; case 's': use_switch = TRUE; use_tables = FALSE; break; case 't': use_switch = FALSE; use_tables = TRUE; break; default: usage_error = TRUE; break; } } if (usage_error || 1 == dwoptind || dwoptind != argc) { print_usage_message(usage); exit(FAILED); } } int main(int argc,char **argv) { print_version(argv[0]); print_args(argc,argv); process_args(argc,argv); OpenAllFiles(); GenerateInitialFileLines(); ParseDefinitionsAndWriteOutput(); WriteFileTrailers(); CloseAllFiles(); return 0; } /* Print the array used to hold the tags, attributes values */ #ifdef TRACE_ARRAY static void PrintArray(void) { int i; for (i = 0; i < array_count; ++i) { printf("%d: Name %s_%s, Value 0x%04x\n", i,prefix, array[i].name, array[i].value); } } #endif /* TRACE_ARRAY */ /* By including original position we force a stable sort */ static int Compare(array_data *elem1,array_data *elem2) { if (elem1->value < elem2->value) { return -1; } if (elem1->value > elem2->value) { return 1; } if (elem1->original_position < elem2->original_position) { return -1; } if (elem1->original_position > elem2->original_position) { return 1; } return 0; } static FILE * open_path(const char *base, const char *file, const char *direction) { FILE *f = 0; /* POSIX PATH_MAX would suffice, normally stdio BUFSIZ is larger than PATH_MAX */ static char path_name[BUFSIZ]; /* 2 == space for / and NUL */ size_t netlen = strlen(file) +strlen(base) + 2; if (netlen >= BUFSIZ) { printf("Error opening '%s/%s', name too long\n",base,file); exit(1); } strcpy(path_name,base); strcat(path_name,"/"); strcat(path_name,file); f = fopen(path_name,direction); if (!f) { printf("Error opening '%s'\n",path_name); exit(1); } return f; } /* Open files and write the basic headers */ static void OpenAllFiles(void) { const char *dwarf_h = "dwarf.h"; const char *names_h = "dwarf_names.h"; const char *names_c = "dwarf_names.c"; const char *names_enum_h = "dwarf_names_enum.h"; const char *names_new_h = "dwarf_names_new.h"; f_dwarf_in = open_path(input_name,dwarf_h,"r"); f_names_enum_h = open_path(output_name,names_enum_h,"w"); f_names_new_h = open_path(output_name,names_new_h,"w"); f_names_h = open_path(output_name,names_h,"w"); f_names_c = open_path(output_name,names_c,"w"); } static void GenerateInitialFileLines(void) { /* Generate entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"/* Automatically generated, do not edit. */\n"); fprintf(f_names_enum_h,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_enum_h,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_enum_h,"#ifndef __DWARF_NAMES_ENUM_H__\n"); fprintf(f_names_enum_h,"#define __DWARF_NAMES_ENUM_H__\n"); /* Generate entries for 'dwarf_names_new.h' */ fprintf(f_names_new_h,"/* Automatically generated, do not edit. */\n"); fprintf(f_names_new_h,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_new_h,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_new_h,"/* define DWARF_PRINT_PREFIX before this\n"); fprintf(f_names_new_h," point if you wish to. */\n"); fprintf(f_names_new_h,"#ifndef DWARF_PRINT_PREFIX\n"); fprintf(f_names_new_h,"#define DWARF_PRINT_PREFIX dwarf_\n"); fprintf(f_names_new_h,"#endif\n"); fprintf(f_names_new_h,"#define dw_glue(x,y) x##y\n"); fprintf(f_names_new_h,"#define dw_glue2(x,y) dw_glue(x,y)\n"); fprintf(f_names_new_h,"#define DWPREFIX(x) dw_glue2(DWARF_PRINT_PREFIX,x)\n"); /* Generate entries for 'dwarf_names.h' */ fprintf(f_names_h,"/* Generated routines, do not edit. */\n"); fprintf(f_names_h,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_h,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_h,"#ifndef DWARF_NAMES_H\n"); fprintf(f_names_h,"#define DWARF_NAMES_H\n\n"); fprintf(f_names_h,"#ifdef __cplusplus\n"); fprintf(f_names_h,"extern \"C\" {\n"); fprintf(f_names_h,"#endif /* __cplusplus */\n\n"); /* Generate entries for 'dwarf_names.c' */ fprintf(f_names_c,"/* Generated routines, do not edit. */\n"); fprintf(f_names_c,"/* Generated sourcedate %s */\n", DW_VERSION_DATE_STR); fprintf(f_names_c,"\n/* BEGIN FILE */\n\n"); fprintf(f_names_c,"#include \"dwarf.h\"\n\n"); fprintf(f_names_c,"#include \"libdwarf.h\"\n\n"); if (use_tables) { fprintf(f_names_c,"typedef struct Names_Data {\n"); fprintf(f_names_c," const char *l_name; \n"); fprintf(f_names_c," unsigned value; \n"); fprintf(f_names_c,"} Names_Data;\n\n"); /* Generate code to find an entry */ fprintf(f_names_c,"/* Use standard binary search to get entry */\n"); fprintf(f_names_c,"static int\nfind_entry(Names_Data *table," "const int last,unsigned value, const char **s_out)\n"); fprintf(f_names_c,"{\n"); fprintf(f_names_c," int low = 0;\n"); fprintf(f_names_c," int high = last;\n"); fprintf(f_names_c," int mid;\n"); fprintf(f_names_c," unsigned maxval = table[last-1].value;\n"); fprintf(f_names_c,"\n"); fprintf(f_names_c," if (value > maxval) {\n"); fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," while (low < high) {\n"); fprintf(f_names_c," mid = low + ((high - low) / 2);\n"); fprintf(f_names_c," if(mid == last) {\n"); fprintf(f_names_c," break;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," if (table[mid].value < value) {\n"); fprintf(f_names_c," low = mid + 1;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," else {\n"); fprintf(f_names_c," high = mid;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c,"\n"); fprintf(f_names_c," if (low < last && table[low].value == value) {\n"); fprintf(f_names_c," /* Found: low is the entry */\n"); fprintf(f_names_c," *s_out = table[low].l_name;\n"); fprintf(f_names_c," return DW_DLV_OK;\n"); fprintf(f_names_c," }\n"); fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); fprintf(f_names_c,"}\n"); fprintf(f_names_c,"\n"); } } /* Close files and write basic trailers */ static void WriteFileTrailers(void) { /* Generate entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"#endif /* __DWARF_NAMES_ENUM_H__ */\n"); fprintf(f_names_enum_h,"\n/* END FILE */\n"); /* Generate entries for 'dwarf_names_new.h' */ fprintf(f_names_new_h,"\n/* END FILE */\n"); /* Generate entries for 'dwarf_names.h' */ fprintf(f_names_h,"\n#ifdef __cplusplus\n"); fprintf(f_names_h,"}\n"); fprintf(f_names_h,"#endif /* __cplusplus */\n\n"); fprintf(f_names_h,"#endif /* DWARF_NAMES_H */\n"); fprintf(f_names_h,"\n/* END FILE */\n"); /* Generate entries for 'dwarf_names.c' */ fprintf(f_names_c,"\n/* END FILE */\n"); } static void CloseAllFiles(void) { fclose(f_dwarf_in); fclose(f_names_enum_h); fclose(f_names_new_h); fclose(f_names_h); fclose(f_names_c); } /* Write the table and code for a common set of names */ static void GenerateOneSet(void) { unsigned u; unsigned prev_value = 0; size_t len; char *prefix_id = prefix + prefix_root_len; unsigned actual_array_count = 0; #ifdef TRACE_ARRAY printf("List before sorting:\n"); PrintArray(); #endif /* TRACE_ARRAY */ /* Sort the array, because the values in 'libdwarf.h' are not in ascending order; if we use '-t' we must be sure the values are sorted, for the binary search to work properly. We want a stable sort, hence mergesort. */ qsort((void *)&group_array,array_count,sizeof(array_data),(compfn)Compare); #ifdef TRACE_ARRAY printf("\nList after sorting:\n"); PrintArray(); #endif /* TRACE_ARRAY */ /* Generate entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"\nenum Dwarf_%s_e {\n",prefix_id); /* Generate entries for 'dwarf_names_new.h' */ fprintf(f_names_new_h,"int DWPREFIX(get_%s_name) (unsigned int, const char **);\n",prefix_id); /* Generate entries for 'dwarf_names.h' and libdwarf.h */ fprintf(f_names_h,"extern int dwarf_get_%s_name(unsigned int /*val_in*/, const char ** /*s_out */);\n",prefix_id); /* Generate code for 'dwarf_names.c' */ fprintf(f_names_c,"/* ARGSUSED */\n"); fprintf(f_names_c,"int\n"); fprintf(f_names_c,"dwarf_get_%s_name (unsigned int val,const char ** s_out)\n",prefix_id); fprintf(f_names_c,"{\n"); if (use_tables) { fprintf(f_names_c," static Names_Data Dwarf_%s_n[] = {\n",prefix_id); } else { fprintf(f_names_c," switch (val) {\n"); } for (u = 0; u < array_count; ++u) { /* Check if value already dumped */ if (u > 0 && group_array[u].value == prev_value) { fprintf(f_names_c, " /* Skipping alternate spelling of value 0x%x. %s_%s */\n", (unsigned)prev_value, prefix, group_array[u].name); continue; } prev_value = group_array[u].value; /* Generate entries for 'dwarf_names_enum.h'. The 39 just makes nice formatting in the output. */ len = 39 - strlen(prefix); fprintf(f_names_enum_h," %s_%-*s = 0x%04x", prefix,(int)len,group_array[u].name,group_array[u].value); fprintf(f_names_enum_h,(u + 1 < array_count) ? ",\n" : "\n"); /* Generate entries for 'dwarf_names.c' */ if (use_tables) { fprintf(f_names_c," {/* %3u */ \"%s_%s\", ", actual_array_count,prefix,group_array[u].name); fprintf(f_names_c," %s_%s}", prefix,group_array[u].name); fprintf(f_names_c,(u + 1 < array_count) ? ",\n" : "\n"); } else { fprintf(f_names_c," case %s_%s:\n", prefix,group_array[u].name); fprintf(f_names_c," *s_out = \"%s_%s\";\n", prefix,group_array[u].name); fprintf(f_names_c," return DW_DLV_OK;\n"); } ++actual_array_count; } /* Closing entries for 'dwarf_names_enum.h' */ fprintf(f_names_enum_h,"};\n"); if (use_tables) { /* Closing entries for 'dwarf_names.c' */ fprintf(f_names_c," };\n\n"); /* Closing code for 'dwarf_names.c' */ fprintf(f_names_c," const int last_entry = %d;\n",actual_array_count); fprintf(f_names_c," /* find the entry */\n"); fprintf(f_names_c," int r = find_entry(Dwarf_%s_n,last_entry,val,s_out);\n",prefix_id); fprintf(f_names_c," return r;\n"); fprintf(f_names_c,"}\n"); } else { fprintf(f_names_c," }\n"); fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); fprintf(f_names_c,"}\n"); } /* Mark the group_array as empty */ array_count = 0; } /* Detect empty lines (and other lines we do not want to read) */ static boolean is_skippable_line(char *pLine) { boolean empty = TRUE; for (; *pLine && empty; ++pLine) { empty = isspace(*pLine); } return empty; } static void safe_strncpy(char *out, unsigned out_len, char *in,unsigned in_len) { if(in_len >= out_len) { fprintf(stderr,"Impossible input line from dwarf.h. Giving up. \n"); fprintf(stderr,"Length %u is too large, limited to %u.\n", in_len,out_len); exit(1); } strncpy(out,in,in_len); } /* Parse the 'dwarf.h' file and generate the tables */ static void ParseDefinitionsAndWriteOutput(void) { char new_prefix[64]; char *second_underscore = NULL; char type[1000]; char name[1000]; char value[1000]; char extra[1000]; char line_in[MAX_LINE_SIZE]; int pending = FALSE; int prefix_len = 0; /* Process each line from 'dwarf.h' */ while (!feof(f_dwarf_in)) { /* errno is cleared here so printing errno after the fgets is showing errno as set by fgets. */ char *fgbad = 0; errno = 0; fgbad = fgets(line_in,sizeof(line_in),f_dwarf_in); if(!fgbad) { if(feof(f_dwarf_in)) { break; } /* Is error. errno must be set. */ fprintf(stderr,"Error reading dwarf.h!. Errno %d\n",errno); exit(1); } if (is_skippable_line(line_in)) { continue; } sscanf(line_in,"%s %s %s %s",type,name,value,extra); if (strcmp(type,"#define") || strncmp(name,prefix_root,prefix_root_len)) { continue; } second_underscore = strchr(name + prefix_root_len,'_'); prefix_len = (int)(second_underscore - name); safe_strncpy(new_prefix,sizeof(new_prefix),name,prefix_len); new_prefix[prefix_len] = 0; /* Check for new prefix set */ if (strcmp(prefix,new_prefix)) { if (pending) { /* Generate current prefix set */ GenerateOneSet(); } pending = TRUE; strcpy(prefix,new_prefix); } /* Be sure we have a valid entry */ if (array_count >= ARRAY_SIZE) { printf("Too many entries for current group_array size of %d",ARRAY_SIZE); exit(1); } /* Move past the second underscore */ ++second_underscore; { unsigned long v = strtoul(value,NULL,16); /* Some values are duplicated, that is ok. After the sort we will weed out the duplicate values, see GenerateOneSet(). */ /* Record current entry */ if (strlen(second_underscore) >= MAX_NAME_LEN) { printf("Too long a name %s for max len %d\n", second_underscore,MAX_NAME_LEN); exit(1); } strcpy(group_array[array_count].name,second_underscore); group_array[array_count].value = v; group_array[array_count].original_position = array_count; ++array_count; } } if (pending) { /* Generate final prefix set */ GenerateOneSet(); } } dwarfutils-20200114/libdwarf/libdwarf.h000066400000000000000000005707021361531463500177100ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef _LIBDWARF_H #define _LIBDWARF_H #ifdef __cplusplus extern "C" { #endif /* libdwarf.h $Revision: #9 $ $Date: 2008/01/17 $ For libdwarf producers and consumers The interface is defined as having 8-byte signed and unsigned values so it can handle 64-or-32bit target on 64-or-32bit host. Dwarf_Ptr is the native size: it represents pointers on the host machine (not the target!). This contains declarations for types and all producer and consumer functions. Function declarations are written on a single line each here so one can use grep to each declaration in its entirety. The declarations are a little harder to read this way, but... The seeming duplication of the Elf typedef allows both verification we have the right struct name (when libelf.h included before this) and creation of a local handle so we have the struct pointer here (if libelf.h is not included before this file). */ typedef struct Elf Elf; typedef struct Elf* dwarf_elf_handle; /* To enable printing with printf regardless of the actual underlying data type, we define the DW_PR_xxx macros. To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want ensure the right DW_PR_XZEROS define is uncommented. */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" typedef unsigned long long Dwarf_Unsigned; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Addr; typedef int Dwarf_Bool; /* boolean type */ typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ /* If sizeof(Dwarf_Half) is greater than 2 we believe libdwarf still works properly. */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DSx "I64x" #define DW_PR_DUu "I64u" #define DW_PR_DSd "I64d" #else #define DW_PR_DUx "llx" #define DW_PR_DSx "llx" #define DW_PR_DUu "llu" #define DW_PR_DSd "lld" #endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ /* DWARF5: a container for a DW_FORM_data16 data item. We have no integer types suitable so this special struct is used instead. It is up to consumers/producers to deal with the contents. New October 18, 2017 . */ typedef struct Dwarf_Form_Data16_s { unsigned char fd_data[16]; } Dwarf_Form_Data16; /* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as Dwarf_Unsigned, but that is done inside libdwarf and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; }; typedef struct Dwarf_Sig8_s Dwarf_Sig8; /* Contains info on an uninterpreted block of data Used with certain frame information functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* 0 if location description, 1 if .debug_info loclist, 2 if .debug_info.dwo split dwarf loclist. */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; } Dwarf_Block; /* NEW October 2015. */ /* Dwarf_Loc_c_s,Dwarf_Locdesc_c_s, and Dwarf_Loc_Head_c_s are not defined publically. */ struct Dwarf_Loc_c_s; typedef struct Dwarf_Loc_c_s * Dwarf_Loc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Loc_c, a single location operator */ struct Dwarf_Locdesc_c_s; typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location list entry (or for a locexpr, the fake Loc_Head for the locexpr) */ struct Dwarf_Loc_Head_c_s; typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; /* NEW November 2015. For DWARF5 .debug_macro section */ struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; /* NEW September 2016. Allows easy access to DW_AT_discr_list array of discriminant values. Input in blockpointer is a block with a list of uleb or sleb numbers (all one or the other, lebunsignedflag instructs how to read the leb values properly) */ typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location operator extensions. */ typedef struct { Dwarf_Small lr_atom; /* location operation */ Dwarf_Unsigned lr_number; /* operand */ Dwarf_Unsigned lr_number2; /* for OP_BREGx and DW_OP_GNU_const_type*/ Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ } Dwarf_Loc; /* Location description. DWARF 2,3,4. When this is from a split-dwarf loclist (.debug_loc.dwo) and no tied object is present then ld_lowpc and ld_highpc are actually indices in the .debug_addr section of the tied object). If there is a tied object then these fields are actuall addresses and DW_AT_addr_base in the skeleton CU DIE applies to that .debug_addr. Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with extensions. If from DWARF2,3,4 non-split dwarf then things operate as in DWARF2. See dwarf_get_loclist_b() and the other related new functions that avoid using public structures Dwarf_Loc and Dwarf_Locdesc. */ typedef struct { /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_hipc; Dwarf_Half ld_cents; /* count of location records */ Dwarf_Loc* ld_s; /* pointer to list of same */ /* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */ Dwarf_Small ld_from_loclist; Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where loc-expr begins*/ } Dwarf_Locdesc; /* First appears in DWARF3, and only ranges entries exist. The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or both are zero (DW_RANGES_END). For DWARF5 each table starts with a header followed by range list entries defined as here. */ enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, DW_RANGES_ADDRESS_SELECTION, DW_RANGES_END }; typedef struct { Dwarf_Addr dwr_addr1; Dwarf_Addr dwr_addr2; enum Dwarf_Ranges_Entry_Type dwr_type; } Dwarf_Ranges; /* Frame description instructions expanded. */ typedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; /* Value may be signed, depends on op. Any applicable data_alignment_factor has not been applied, this is the raw offset. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h Preferably identical to DW_FRAME_LAST_REG_NUM. Ensure [0-DW_REG_TABLE_SIZE] does not overlap DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what is appropriate to your cpu. For various CPUs DW_FRAME_UNDEFINED_VAL is correct as the value for DW_FRAME_REG_INITIAL_VALUE. For consumer apps, this can be set dynamically: see dwarf_set_frame_rule_table_size(); */ #ifndef DW_REG_TABLE_SIZE #define DW_REG_TABLE_SIZE 66 #endif /* For MIPS, DW_FRAME_SAME_VAL is the correct default value for a frame register value. For other CPUS another value may be better, such as DW_FRAME_UNDEFINED_VAL. See dwarf_set_frame_rule_table_size */ #ifndef DW_FRAME_REG_INITIAL_VALUE #define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL #endif /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_SAME_VAL 1035 /* For DWARF3 consumer interfaces, make the CFA a column with no real table number. This is what should have been done for the DWARF2 interfaces. This actually works for both DWARF2 and DWARF3, but see the libdwarf documentation on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_all_regs3() Do NOT use this with the older dwarf_get_fde_info_for_reg() or dwarf_get_fde_info_for_all_regs() consumer interfaces. Must be higher than any register count for *any* ABI (ensures maximum applicability with minimum effort). Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). Only present at libdwarf runtime in the consumer interfaces. Never on disk. */ #define DW_FRAME_CFA_COL3 1436 /* The following are all needed to evaluate DWARF3 register rules. */ #define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ #define DW_EXPR_VAL_OFFSET 1 #define DW_EXPR_EXPRESSION 2 #define DW_EXPR_VAL_EXPRESSION 3 typedef struct Dwarf_Regtable_Entry_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(F) Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; /* For DWARF2, always 0 */ Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; /* The data type here should the larger of Dwarf_Addr and Dwarf_Unsigned and Dwarf_Signed. */ Dwarf_Addr dw_offset; } Dwarf_Regtable_Entry; typedef struct Dwarf_Regtable_s { struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; /* opaque type. Functional interface shown later. */ struct Dwarf_Reg_value3_s; typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; typedef struct Dwarf_Regtable_Entry3_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3 are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL and DW_FRAME_CFA_COL3 are definable at runtime consider the names symbolic in this comment, not absolute. Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: In a cfa-defining entry (rt3_cfa_rule) the regnum is the CFA 'register number'. Which is some 'normal' register, not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor DW_FRAME_UNDEFINED_VAL. If dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. So dw_offset_or_block_len is a signed value, really, and must be printed/evaluated as such. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(R) If dw_value_type == DW_EXPR_VAL_OFFSET the value of this register is CFA +N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. Rule: val_offset(N) If dw_value_type == DW_EXPR_EXPRESSION The value of the register is the value at the address computed by evaluating the DWARF expression E. Rule: expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. If dw_value_type == DW_EXPR_VAL_EXPRESSION The value of the register is the value computed by evaluating the DWARF expression E. Rule: val_expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; /* For the DWARF3 version, moved the DW_FRAME_CFA_COL out of the array and into its own struct. Having it part of the array is not very easy to work with from a portability point of view: changing the number for every architecture is a pain (if one fails to set it correctly a register rule gets clobbered when setting CFA). With MIPS it just happened to be easy to use DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...). rt3_rules and rt3_reg_table_size must be filled in before calling libdwarf. Filled in with a pointer to an array (pointer and array set up by the calling application) of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs. libdwarf does not allocate or deallocate space for the rules, you must do so. libdwarf will initialize the contents rules array, you do not need to do so (though if you choose to initialize the array somehow that is ok: libdwarf will overwrite your initializations with its own). */ typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3; /* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. Returns DW_DLV_OK if the value is available. If DW_DLV_OK returns the regnum and offset thru the pointers (which the consumer must use appropriately). */ int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Small *offset_relevant, Dwarf_Half *regnum_out, Dwarf_Signed *offset_out); /* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. Returns DW_DLV_OK if the value is available. The caller must pass in the address of a valid Dwarf_Block (the caller need not initialize it). */ int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Block *block_out); /* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller v2, adding drd_length: some relocations are 4 and some 8 bytes (pointers are 8, section offsets 4) in some dwarf environments. (MIPS relocations are all one size in any given ABI.) Changing drd_type to an unsigned char to keep struct size down. */ enum Dwarf_Rel_Type { dwarf_drt_none, /* Should not get to caller */ dwarf_drt_data_reloc, /* Simple normal relocation. */ dwarf_drt_segment_rel, /* Special reloc, exceptions. */ /* dwarf_drt_first_of_length_pair and drt_second are for for the .word end - begin case. */ dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; struct Dwarf_P_Marker_s { Dwarf_Unsigned ma_marker; Dwarf_Unsigned ma_offset; }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type to keep size small in struct. */ unsigned char drd_length; /* Length in bytes of data being relocated. 4 for 32bit data, 8 for 64bit data. */ Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */ Dwarf_Unsigned drd_symbol_index; }; typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; struct Dwarf_P_String_Attr_s { Dwarf_Unsigned sa_offset; /* Offset of string attribute data */ Dwarf_Unsigned sa_nbytes; }; /* Opaque types for Consumer Library. */ typedef struct Dwarf_Debug_s* Dwarf_Debug; typedef struct Dwarf_Die_s* Dwarf_Die; typedef struct Dwarf_Line_s* Dwarf_Line; typedef struct Dwarf_Global_s* Dwarf_Global; typedef struct Dwarf_Func_s* Dwarf_Func; typedef struct Dwarf_Type_s* Dwarf_Type; typedef struct Dwarf_Var_s* Dwarf_Var; typedef struct Dwarf_Weak_s* Dwarf_Weak; typedef struct Dwarf_Error_s* Dwarf_Error; typedef struct Dwarf_Attribute_s* Dwarf_Attribute; typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; typedef struct Dwarf_Fde_s* Dwarf_Fde; typedef struct Dwarf_Cie_s* Dwarf_Cie; typedef struct Dwarf_Arange_s* Dwarf_Arange; typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex; struct Dwarf_Xu_Index_Header_s; typedef struct Dwarf_Xu_Index_Header_s* Dwarf_Xu_Index_Header; struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; struct Dwarf_Dnames_Head_s; typedef struct Dwarf_Dnames_Head_s* Dwarf_Dnames_Head; /* Opaque types for Producer Library. */ typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; typedef struct Dwarf_P_Die_s* Dwarf_P_Die; typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; typedef Dwarf_Unsigned Dwarf_Tag; /* error handler function */ typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); /* Begin libdwarf Object File Interface declarations. As of February 2008 there are multiple dwarf_reader object access initialization methods available: The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish() which assume libelf and POSIX file access. An object-file and library agnostic dwarf_object_init() and dwarf_object_finish() which allow the coder to provide object access routines abstracting away the elf interface. So there is no dependence in the reader code on the object format and no dependence on libelf. See the code in dwarf_elf_access.c and dwarf_original_elf_init.c to see an example of initializing the structures mentioned below. Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. As of March 2017 additional functions dwarf_elf_init_b and dwarf_init_b and dwarf_object_init_b add a groupnumber argument so DWARF5 split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods; typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section; /* Used in the get_section interface function in Dwarf_Obj_Access_Section_s. Since libdwarf depends on standard DWARF section names an object format that has no such names (but has some method of setting up 'sections equivalents') must arrange to return standard DWARF section names in the 'name' field. libdwarf does not free the strings in 'name'. */ struct Dwarf_Obj_Access_Section_s { /* addr is the virtual address of the first byte of the section data. Usually zero when the address makes no sense for a given section. */ Dwarf_Addr addr; /* Section type. */ Dwarf_Unsigned type; /* Size in bytes of the section. */ Dwarf_Unsigned size; /* Having an accurate section name makes debugging of libdwarf easier. and is essential to find the .debug_ sections. */ const char* name; /* Set link to zero if it is meaningless. If non-zero it should be a link to a rela section or from symtab to strtab. In Elf it is sh_link. */ Dwarf_Unsigned link; /* The section header index of the section to which the relocation applies. In Elf it is sh_info. */ Dwarf_Unsigned info; /* Elf sections that are tables have a non-zero entrysize so the count of entries can be calculated even without the right structure definition. If your object format does not have this data leave this zero. */ Dwarf_Unsigned entrysize; }; /* Returned by the get_endianness function in Dwarf_Obj_Access_Methods_s. */ typedef enum { DW_OBJECT_MSB, DW_OBJECT_LSB } Dwarf_Endianness; /* The functions we need to access object data from libdwarf are declared here. In these function pointer declarations 'void *obj' is intended to be a pointer (the object field in Dwarf_Obj_Access_Interface_s) that hides the library-specific and object-specific data that makes it possible to handle multiple object formats and multiple libraries. It's not required that one handles multiple such in a single libdwarf archive/shared-library (but not ruled out either). See dwarf_elf_object_access_internals_t and dwarf_elf_access.c for an example. */ struct Dwarf_Obj_Access_Methods_s { /* get_section_info Get address, size, and name info about a section. Parameters section_index - Zero-based index. return_section - Pointer to a structure in which section info will be placed. Caller must provide a valid pointer to a structure area. The structure's contents will be overwritten by the call to get_section_info. error - A pointer to an integer in which an error code may be stored. Return DW_DLV_OK - Everything ok. DW_DLV_ERROR - Error occurred. Use 'error' to determine the libdwarf defined error. DW_DLV_NO_ENTRY - No such section. */ int (*get_section_info)(void* obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section* return_section, int* error); /* get_byte_order Get whether the object file represented by this interface is big-endian (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB). Parameters obj - Equivalent to 'this' in OO languages. Return Endianness of object. Cannot fail. */ Dwarf_Endianness (*get_byte_order)(void* obj); /* get_length_size Get the size of a length field in the underlying object file. libdwarf currently supports * 4 and 8 byte sizes, but may support larger in the future. Perhaps the return type should be an enumeration? Parameters obj - Equivalent to 'this' in OO languages. Return Size of length. Cannot fail. */ Dwarf_Small (*get_length_size)(void* obj); /* get_pointer_size Get the size of a pointer field in the underlying object file. libdwarf currently supports 4 and 8 byte sizes. Perhaps the return type should be an enumeration? Return Size of pointer. Cannot fail. */ Dwarf_Small (*get_pointer_size)(void* obj); /* get_section_count Get the number of sections in the object file. Parameters Return Number of sections */ Dwarf_Unsigned (*get_section_count)(void* obj); /* load_section Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index. return_data - The address of a pointer to which the section data block will be assigned. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*load_section)(void* obj, Dwarf_Half section_index, Dwarf_Small** return_data, int* error); /** relocate_a_section If relocations are not supported leave this pointer NULL. Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index of the section to be relocated. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*relocate_a_section)(void* obj, Dwarf_Half section_index, Dwarf_Debug dbg, int* error); }; /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface [dwarf_object_init and dwarf_object_finish)] directly. dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. */ struct Dwarf_Obj_Access_Interface_s { /* object is a void* as it hides the data the object access routines need (which varies by library in use and object format). */ void* object; const Dwarf_Obj_Access_Methods * methods; }; /* End libdwarf Object File Interface */ /* Dwarf_dealloc() alloc_type arguments. Argument points to: */ #define DW_DLA_STRING 0x01 /* char* */ #define DW_DLA_LOC 0x02 /* Dwarf_Loc */ #define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ #define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ #define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ #define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ #define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ #define DW_DLA_DIE 0x08 /* Dwarf_Die */ #define DW_DLA_LINE 0x09 /* Dwarf_Line */ #define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ #define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ #define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ #define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ #define DW_DLA_ERROR 0x0e /* Dwarf_Error */ #define DW_DLA_LIST 0x0f /* a list */ #define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ #define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ #define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ #define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ #define DW_DLA_CIE 0x14 /* Dwarf_Cie */ #define DW_DLA_FDE 0x15 /* Dwarf_Fde */ #define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */ #define DW_DLA_FRAME_BLOCK 0x17 /* Dwarf_Frame Block (not used) */ #define DW_DLA_FUNC 0x18 /* Dwarf_Func */ #define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ #define DW_DLA_VAR 0x1a /* Dwarf_Var */ #define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ #define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ #define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */ /* 0x1e (30) to 0x36 (54) reserved for internal to libdwarf types. */ #define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */ #define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */ #define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/ #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ /* 0x3d (61) is for libdwarf internal use. */ #define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ #define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ #define DW_DLA_STR_OFFSETS 0x40 /* struct Dwarf_Str_Offsets_Table_s */ /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" /* dwarf_init() access arguments */ #define DW_DLC_READ 0 /* read only access */ #define DW_DLC_WRITE 1 /* write only access */ #define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ /* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed. If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not set 32bit offset DWARF is assumed. Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS and handle the relocation creation for the target itself using the symbolic relocations to do so, those use the Dwarf_Rel_Type enum relocation indicators. */ /* The first three are traditional dwarf producer names. These names still work. Newer names below. */ /* 64-bit address-size target */ #define DW_DLC_SIZE_64 0x40000000 /* 32-bit address-size target */ #define DW_DLC_SIZE_32 0x20000000 /* 64-bit offset-size DWARF offsets (else 32bit) */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* 32-bit offset-size ELF object (ELFCLASS32) */ #define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* 64-bit offset-size ELF object (ELFCLASS64) */ #define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* dwarf_producer_init* access flag modifiers Some new April 2014. If DW_DLC_STREAM_RELOCATIONS is set the DW_DLC_ISA_* flags are ignored. See the Dwarf_Rel_Type enum. */ /* Old style Elf binary relocation (.rel) records. The default. */ #define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* use 32-bit sec offsets */ #define DW_DLC_OFFSET32 0x00010000 /* The following 3 are new sensible names. Old names above with same values. */ /* use 64-bit sec offsets in ELF */ #define DW_DLC_OFFSET64 0x10000000 /* use 4 for address_size */ #define DW_DLC_POINTER32 0x20000000 /* use 8 for address_size */ #define DW_DLC_POINTER64 0x40000000 /* Special for IRIX only */ /* use Elf 64bit offset headers and non-std IRIX 64bitoffset headers */ #define DW_DLC_IRIX_OFFSET64 0x00200000 /* Usable with assembly output because it is up to the producer to deal with locations in whatever manner the calling producer code wishes. For example, when the libdwarf caller wishes to produce relocations differently than the binary relocation bits that libdwarf Stream Relocations generate. */ #define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 #define DW_DLC_TARGET_BIGENDIAN 0x08000000 /* Big endian target */ #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* Little endian target */ /* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ #define DW_DLS_FORWARD 1 /* slide forward to find line */ /* libdwarf error numbers */ #define DW_DLE_NE 0 /* no error */ #define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ #define DW_DLE_MAP 2 /* memory map failure */ #define DW_DLE_LEE 3 /* libelf error */ #define DW_DLE_NDS 4 /* no debug section */ #define DW_DLE_NLS 5 /* no line section */ #define DW_DLE_ID 6 /* invalid descriptor for query */ #define DW_DLE_IOF 7 /* I/O failure */ #define DW_DLE_MAF 8 /* memory allocation failure */ #define DW_DLE_IA 9 /* invalid argument */ #define DW_DLE_MDE 10 /* mangled debugging entry */ #define DW_DLE_MLE 11 /* mangled line number entry */ #define DW_DLE_FNO 12 /* file not open */ #define DW_DLE_FNR 13 /* file not a regular file */ #define DW_DLE_FWA 14 /* file open with wrong access */ #define DW_DLE_NOB 15 /* not an object file */ #define DW_DLE_MOF 16 /* mangled object file header */ #define DW_DLE_EOLL 17 /* end of location list entries */ #define DW_DLE_NOLL 18 /* no location list section */ #define DW_DLE_BADOFF 19 /* Invalid offset */ #define DW_DLE_EOS 20 /* end of section */ #define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ #define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ /* It is not an allowed size (64 or 32) */ /* Error codes defined by the current Libdwarf Implementation. */ #define DW_DLE_DBG_ALLOC 23 #define DW_DLE_FSTAT_ERROR 24 #define DW_DLE_FSTAT_MODE_ERROR 25 #define DW_DLE_INIT_ACCESS_WRONG 26 #define DW_DLE_ELF_BEGIN_ERROR 27 #define DW_DLE_ELF_GETEHDR_ERROR 28 #define DW_DLE_ELF_GETSHDR_ERROR 29 #define DW_DLE_ELF_STRPTR_ERROR 30 #define DW_DLE_DEBUG_INFO_DUPLICATE 31 #define DW_DLE_DEBUG_INFO_NULL 32 #define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 #define DW_DLE_DEBUG_ABBREV_NULL 34 #define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 #define DW_DLE_DEBUG_ARANGES_NULL 36 #define DW_DLE_DEBUG_LINE_DUPLICATE 37 #define DW_DLE_DEBUG_LINE_NULL 38 #define DW_DLE_DEBUG_LOC_DUPLICATE 39 #define DW_DLE_DEBUG_LOC_NULL 40 #define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 #define DW_DLE_DEBUG_MACINFO_NULL 42 #define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 #define DW_DLE_DEBUG_PUBNAMES_NULL 44 #define DW_DLE_DEBUG_STR_DUPLICATE 45 #define DW_DLE_DEBUG_STR_NULL 46 #define DW_DLE_CU_LENGTH_ERROR 47 #define DW_DLE_VERSION_STAMP_ERROR 48 #define DW_DLE_ABBREV_OFFSET_ERROR 49 #define DW_DLE_ADDRESS_SIZE_ERROR 50 #define DW_DLE_DEBUG_INFO_PTR_NULL 51 #define DW_DLE_DIE_NULL 52 #define DW_DLE_STRING_OFFSET_BAD 53 #define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 #define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 #define DW_DLE_LINE_NUM_OPERANDS_BAD 56 #define DW_DLE_LINE_SET_ADDR_ERROR 57 /* No longer used. */ #define DW_DLE_LINE_EXT_OPCODE_BAD 58 #define DW_DLE_DWARF_LINE_NULL 59 #define DW_DLE_INCL_DIR_NUM_BAD 60 #define DW_DLE_LINE_FILE_NUM_BAD 61 #define DW_DLE_ALLOC_FAIL 62 #define DW_DLE_NO_CALLBACK_FUNC 63 #define DW_DLE_SECT_ALLOC 64 #define DW_DLE_FILE_ENTRY_ALLOC 65 #define DW_DLE_LINE_ALLOC 66 #define DW_DLE_FPGM_ALLOC 67 #define DW_DLE_INCDIR_ALLOC 68 #define DW_DLE_STRING_ALLOC 69 #define DW_DLE_CHUNK_ALLOC 70 #define DW_DLE_BYTEOFF_ERR 71 #define DW_DLE_CIE_ALLOC 72 #define DW_DLE_FDE_ALLOC 73 #define DW_DLE_REGNO_OVFL 74 #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 #define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 #define DW_DLE_DEBUGLINE_ERROR 82 #define DW_DLE_DEBUGFRAME_ERROR 83 #define DW_DLE_DEBUGINFO_ERROR 84 #define DW_DLE_ATTR_ALLOC 85 #define DW_DLE_ABBREV_ALLOC 86 #define DW_DLE_OFFSET_UFLW 87 #define DW_DLE_ELF_SECT_ERR 88 #define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 #define DW_DLE_FRAME_VERSION_BAD 90 #define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 #define DW_DLE_FDE_NULL 92 #define DW_DLE_FDE_DBG_NULL 93 #define DW_DLE_CIE_NULL 94 #define DW_DLE_CIE_DBG_NULL 95 #define DW_DLE_FRAME_TABLE_COL_BAD 96 #define DW_DLE_PC_NOT_IN_FDE_RANGE 97 #define DW_DLE_CIE_INSTR_EXEC_ERROR 98 #define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 #define DW_DLE_FDE_PTR_NULL 100 #define DW_DLE_RET_OP_LIST_NULL 101 #define DW_DLE_LINE_CONTEXT_NULL 102 #define DW_DLE_DBG_NO_CU_CONTEXT 103 #define DW_DLE_DIE_NO_CU_CONTEXT 104 #define DW_DLE_FIRST_DIE_NOT_CU 105 #define DW_DLE_NEXT_DIE_PTR_NULL 106 #define DW_DLE_DEBUG_FRAME_DUPLICATE 107 #define DW_DLE_DEBUG_FRAME_NULL 108 #define DW_DLE_ABBREV_DECODE_ERROR 109 #define DW_DLE_DWARF_ABBREV_NULL 110 #define DW_DLE_ATTR_NULL 111 #define DW_DLE_DIE_BAD 112 #define DW_DLE_DIE_ABBREV_BAD 113 #define DW_DLE_ATTR_FORM_BAD 114 #define DW_DLE_ATTR_NO_CU_CONTEXT 115 #define DW_DLE_ATTR_FORM_SIZE_BAD 116 #define DW_DLE_ATTR_DBG_NULL 117 #define DW_DLE_BAD_REF_FORM 118 #define DW_DLE_ATTR_FORM_OFFSET_BAD 119 #define DW_DLE_LINE_OFFSET_BAD 120 #define DW_DLE_DEBUG_STR_OFFSET_BAD 121 #define DW_DLE_STRING_PTR_NULL 122 #define DW_DLE_PUBNAMES_VERSION_ERROR 123 #define DW_DLE_PUBNAMES_LENGTH_BAD 124 #define DW_DLE_GLOBAL_NULL 125 #define DW_DLE_GLOBAL_CONTEXT_NULL 126 #define DW_DLE_DIR_INDEX_BAD 127 #define DW_DLE_LOC_EXPR_BAD 128 #define DW_DLE_DIE_LOC_EXPR_BAD 129 #define DW_DLE_ADDR_ALLOC 130 #define DW_DLE_OFFSET_BAD 131 #define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 #define DW_DLE_REL_ALLOC 133 #define DW_DLE_ARANGE_OFFSET_BAD 134 #define DW_DLE_SEGMENT_SIZE_BAD 135 #define DW_DLE_ARANGE_LENGTH_BAD 136 #define DW_DLE_ARANGE_DECODE_ERROR 137 #define DW_DLE_ARANGES_NULL 138 #define DW_DLE_ARANGE_NULL 139 #define DW_DLE_NO_FILE_NAME 140 #define DW_DLE_NO_COMP_DIR 141 #define DW_DLE_CU_ADDRESS_SIZE_BAD 142 #define DW_DLE_INPUT_ATTR_BAD 143 #define DW_DLE_EXPR_NULL 144 #define DW_DLE_BAD_EXPR_OPCODE 145 #define DW_DLE_EXPR_LENGTH_BAD 146 #define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 #define DW_DLE_ELF_GETIDENT_ERROR 148 #define DW_DLE_NO_AT_MIPS_FDE 149 #define DW_DLE_NO_CIE_FOR_FDE 150 #define DW_DLE_DIE_ABBREV_LIST_NULL 151 #define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 #define DW_DLE_DEBUG_FUNCNAMES_NULL 153 #define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 #define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 #define DW_DLE_FUNC_NULL 156 #define DW_DLE_FUNC_CONTEXT_NULL 157 #define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 #define DW_DLE_DEBUG_TYPENAMES_NULL 159 #define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 #define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 #define DW_DLE_TYPE_NULL 162 #define DW_DLE_TYPE_CONTEXT_NULL 163 #define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 #define DW_DLE_DEBUG_VARNAMES_NULL 165 #define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 #define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 #define DW_DLE_VAR_NULL 168 #define DW_DLE_VAR_CONTEXT_NULL 169 #define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 #define DW_DLE_DEBUG_WEAKNAMES_NULL 171 #define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 #define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 #define DW_DLE_WEAK_NULL 174 #define DW_DLE_WEAK_CONTEXT_NULL 175 #define DW_DLE_LOCDESC_COUNT_WRONG 176 #define DW_DLE_MACINFO_STRING_NULL 177 #define DW_DLE_MACINFO_STRING_EMPTY 178 #define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 #define DW_DLE_MACINFO_MALLOC_FAIL 180 #define DW_DLE_DEBUGMACINFO_ERROR 181 #define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 #define DW_DLE_DEBUG_MACRO_MAX_BAD 183 #define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 #define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 #define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 #define DW_DLE_DF_NO_CIE_AUGMENTATION 187 #define DW_DLE_DF_REG_NUM_TOO_HIGH 188 #define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 #define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 #define DW_DLE_DF_POP_EMPTY_STACK 191 #define DW_DLE_DF_ALLOC_FAIL 192 #define DW_DLE_DF_FRAME_DECODING_ERROR 193 #define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 #define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 #define DW_DLE_PUBTYPE_CONTEXT 196 /* Unused. */ #define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 #define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 #define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 #define DW_DLE_FRAME_CIE_DECODE_ERROR 200 #define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 #define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 #define DW_DLE_LINK_LOOP 203 #define DW_DLE_STRP_OFFSET_BAD 204 #define DW_DLE_DEBUG_RANGES_DUPLICATE 205 #define DW_DLE_DEBUG_RANGES_OFFSET_BAD 206 #define DW_DLE_DEBUG_RANGES_MISSING_END 207 #define DW_DLE_DEBUG_RANGES_OUT_OF_MEM 208 #define DW_DLE_DEBUG_SYMTAB_ERR 209 #define DW_DLE_DEBUG_STRTAB_ERR 210 #define DW_DLE_RELOC_MISMATCH_INDEX 211 #define DW_DLE_RELOC_MISMATCH_RELOC_INDEX 212 #define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX 213 #define DW_DLE_RELOC_SECTION_MISMATCH 214 #define DW_DLE_RELOC_SECTION_MISSING_INDEX 215 #define DW_DLE_RELOC_SECTION_LENGTH_ODD 216 #define DW_DLE_RELOC_SECTION_PTR_NULL 217 #define DW_DLE_RELOC_SECTION_MALLOC_FAIL 218 #define DW_DLE_NO_ELF64_SUPPORT 219 #define DW_DLE_MISSING_ELF64_SUPPORT 220 #define DW_DLE_ORPHAN_FDE 221 #define DW_DLE_DUPLICATE_INST_BLOCK 222 #define DW_DLE_BAD_REF_SIG8_FORM 223 #define DW_DLE_ATTR_EXPRLOC_FORM_BAD 224 #define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD 225 #define DW_DLE_NOT_REF_FORM 226 #define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227 #define DW_DLE_REF_SIG8_NOT_HANDLED 228 #define DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH 229 #define DW_DLE_LOC_BAD_TERMINATION 230 #define DW_DLE_SYMTAB_SECTION_LENGTH_ODD 231 #define DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD 232 #define DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN 233 #define DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO 234 #define DW_DLE_LINE_NUMBER_HEADER_ERROR 235 #define DW_DLE_DEBUG_TYPES_NULL 236 #define DW_DLE_DEBUG_TYPES_DUPLICATE 237 #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238 #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239 #define DW_DLE_GNU_OPCODE_ERROR 240 #define DW_DLE_DEBUGPUBTYPES_ERROR 241 #define DW_DLE_AT_FIXUP_NULL 242 #define DW_DLE_AT_FIXUP_DUP 243 #define DW_DLE_BAD_ABINAME 244 #define DW_DLE_TOO_MANY_DEBUG 245 #define DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE 246 #define DW_DLE_SECTION_DUPLICATION 247 #define DW_DLE_SECTION_ERROR 248 #define DW_DLE_DEBUG_ADDR_DUPLICATE 249 #define DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM 250 #define DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE 251 #define DW_DLE_NEXT_DIE_PAST_END 252 #define DW_DLE_NEXT_DIE_WRONG_FORM 253 #define DW_DLE_NEXT_DIE_NO_ABBREV_LIST 254 #define DW_DLE_NESTED_FORM_INDIRECT_ERROR 255 #define DW_DLE_CU_DIE_NO_ABBREV_LIST 256 #define DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 #define DW_DLE_ATTR_FORM_NOT_ADDR_INDEX 258 #define DW_DLE_ATTR_FORM_NOT_STR_INDEX 259 #define DW_DLE_DUPLICATE_GDB_INDEX 260 #define DW_DLE_ERRONEOUS_GDB_INDEX_SECTION 261 #define DW_DLE_GDB_INDEX_COUNT_ERROR 262 #define DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR 263 #define DW_DLE_GDB_INDEX_INDEX_ERROR 264 #define DW_DLE_GDB_INDEX_CUVEC_ERROR 265 #define DW_DLE_DUPLICATE_CU_INDEX 266 #define DW_DLE_DUPLICATE_TU_INDEX 267 #define DW_DLE_XU_TYPE_ARG_ERROR 268 #define DW_DLE_XU_IMPOSSIBLE_ERROR 269 #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 /* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 #define DW_DLE_FUNCNAMES_ERROR 276 #define DW_DLE_TYPENAMES_ERROR 277 #define DW_DLE_VARNAMES_ERROR 278 #define DW_DLE_WEAKNAMES_ERROR 279 #define DW_DLE_RELOCS_ERROR 280 #define DW_DLE_ATTR_OUTSIDE_SECTION 281 #define DW_DLE_FISSION_INDEX_WRONG 282 #define DW_DLE_FISSION_VERSION_ERROR 283 #define DW_DLE_NEXT_DIE_LOW_ERROR 284 #define DW_DLE_CU_UT_TYPE_ERROR 285 #define DW_DLE_NO_SUCH_SIGNATURE_FOUND 286 #define DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG 287 #define DW_DLE_ATTR_FORM_NOT_DATA8 288 #define DW_DLE_SIG_TYPE_WRONG_STRING 289 #define DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH 290 #define DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH 291 #define DW_DLE_DWP_MISSING_DWO_ID 292 #define DW_DLE_DWP_SIBLING_ERROR 293 #define DW_DLE_DEBUG_FISSION_INCOMPLETE 294 #define DW_DLE_FISSION_SECNUM_ERR 295 #define DW_DLE_DEBUG_MACRO_DUPLICATE 296 #define DW_DLE_DEBUG_NAMES_DUPLICATE 297 #define DW_DLE_DEBUG_LINE_STR_DUPLICATE 298 #define DW_DLE_DEBUG_SUP_DUPLICATE 299 #define DW_DLE_NO_SIGNATURE_TO_LOOKUP 300 #define DW_DLE_NO_TIED_ADDR_AVAILABLE 301 #define DW_DLE_NO_TIED_SIG_AVAILABLE 302 #define DW_DLE_STRING_NOT_TERMINATED 303 #define DW_DLE_BAD_LINE_TABLE_OPERATION 304 #define DW_DLE_LINE_CONTEXT_BOTCH 305 #define DW_DLE_LINE_CONTEXT_INDEX_WRONG 306 #define DW_DLE_NO_TIED_STRING_AVAILABLE 307 #define DW_DLE_NO_TIED_FILE_AVAILABLE 308 #define DW_DLE_CU_TYPE_MISSING 309 #define DW_DLE_LLE_CODE_UNKNOWN 310 #define DW_DLE_LOCLIST_INTERFACE_ERROR 311 #define DW_DLE_LOCLIST_INDEX_ERROR 312 #define DW_DLE_INTERFACE_NOT_SUPPORTED 313 #define DW_DLE_ZDEBUG_REQUIRES_ZLIB 314 #define DW_DLE_ZDEBUG_INPUT_FORMAT_ODD 315 #define DW_DLE_ZLIB_BUF_ERROR 316 #define DW_DLE_ZLIB_DATA_ERROR 317 #define DW_DLE_MACRO_OFFSET_BAD 318 #define DW_DLE_MACRO_OPCODE_BAD 319 #define DW_DLE_MACRO_OPCODE_FORM_BAD 320 #define DW_DLE_UNKNOWN_FORM 321 #define DW_DLE_BAD_MACRO_HEADER_POINTER 322 #define DW_DLE_BAD_MACRO_INDEX 323 #define DW_DLE_MACRO_OP_UNHANDLED 324 #define DW_DLE_MACRO_PAST_END 325 #define DW_DLE_LINE_STRP_OFFSET_BAD 326 #define DW_DLE_STRING_FORM_IMPROPER 327 #define DW_DLE_ELF_FLAGS_NOT_AVAILABLE 328 #define DW_DLE_LEB_IMPROPER 329 #define DW_DLE_DEBUG_LINE_RANGE_ZERO 330 #define DW_DLE_READ_LITTLEENDIAN_ERROR 331 #define DW_DLE_READ_BIGENDIAN_ERROR 332 #define DW_DLE_RELOC_INVALID 333 #define DW_DLE_INFO_HEADER_ERROR 334 #define DW_DLE_ARANGES_HEADER_ERROR 335 #define DW_DLE_LINE_OFFSET_WRONG_FORM 336 #define DW_DLE_FORM_BLOCK_LENGTH_ERROR 337 #define DW_DLE_ZLIB_SECTION_SHORT 338 #define DW_DLE_CIE_INSTR_PTR_ERROR 339 #define DW_DLE_FDE_INSTR_PTR_ERROR 340 #define DW_DLE_FISSION_ADDITION_ERROR 341 #define DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE 342 #define DW_DLE_LOCEXPR_OFF_SECTION_END 343 #define DW_DLE_POINTER_SECTION_UNKNOWN 344 #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 #define DW_DLE_SIZE_WRAPAROUND 348 #define DW_DLE_ILLOGICAL_TSEARCH 349 #define DW_DLE_BAD_STRING_FORM 350 #define DW_DLE_DEBUGSTR_ERROR 351 #define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 #define DW_DLE_DISCR_ARRAY_ERROR 353 #define DW_DLE_LEB_OUT_ERROR 354 #define DW_DLE_SIBLING_LIST_IMPROPER 355 #define DW_DLE_LOCLIST_OFFSET_BAD 356 #define DW_DLE_LINE_TABLE_BAD 357 #define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 #define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 #define DW_DLE_ABBREV_OFF_END 360 #define DW_DLE_FORM_STRING_BAD_STRING 361 #define DW_DLE_AUGMENTATION_STRING_OFF_END 362 #define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 #define DW_DLE_LINE_STRING_BAD 364 #define DW_DLE_DEFINE_FILE_STRING_BAD 365 #define DW_DLE_MACRO_STRING_BAD 366 #define DW_DLE_MACINFO_STRING_BAD 367 #define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 #define DW_DLE_IMPROPER_DWO_ID 369 #define DW_DLE_GROUPNUMBER_ERROR 370 #define DW_DLE_ADDRESS_SIZE_ZERO 371 #define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 #define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 #define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 #define DW_DLE_DEBUG_NAMES_OFF_END 375 #define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 #define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 #define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 #define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 #define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 #define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 #define DW_DLE_LNCT_CODE_UNKNOWN 382 #define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 #define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 #define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 #define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 #define DW_DLE_GROUP_MAP_ALLOC 387 #define DW_DLE_GROUP_MAP_DUPLICATE 388 #define DW_DLE_GROUP_COUNT_ERROR 389 #define DW_DLE_GROUP_INTERNAL_ERROR 390 #define DW_DLE_GROUP_LOAD_ERROR 391 #define DW_DLE_GROUP_LOAD_READ_ERROR 392 #define DW_DLE_AUG_DATA_LENGTH_BAD 393 #define DW_DLE_ABBREV_MISSING 394 #define DW_DLE_NO_TAG_FOR_DIE 395 #define DW_DLE_LOWPC_WRONG_CLASS 396 #define DW_DLE_HIGHPC_WRONG_FORM 397 #define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 #define DW_DLE_DATA16_OUTSIDE_SECTION 399 #define DW_DLE_LNCT_MD5_WRONG_FORM 400 #define DW_DLE_LINE_HEADER_CORRUPT 401 #define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 #define DW_DLE_STR_OFFSETS_NULL_DBG 403 #define DW_DLE_STR_OFFSETS_NO_MAGIC 404 #define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 #define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 #define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 #define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 #define DW_DLE_DUP_ATTR_ON_DIE 409 #define DW_DLE_SECTION_NAME_BIG 410 #define DW_DLE_FILE_UNAVAILABLE 411 #define DW_DLE_FILE_WRONG_TYPE 412 #define DW_DLE_SIBLING_OFFSET_WRONG 413 #define DW_DLE_OPEN_FAIL 414 #define DW_DLE_OFFSET_SIZE 415 #define DW_DLE_MACH_O_SEGOFFSET_BAD 416 #define DW_DLE_FILE_OFFSET_BAD 417 #define DW_DLE_SEEK_ERROR 418 #define DW_DLE_READ_ERROR 419 #define DW_DLE_ELF_CLASS_BAD 420 #define DW_DLE_ELF_ENDIAN_BAD 421 #define DW_DLE_ELF_VERSION_BAD 422 #define DW_DLE_FILE_TOO_SMALL 423 #define DW_DLE_PATH_SIZE_TOO_SMALL 424 #define DW_DLE_BAD_TYPE_SIZE 425 #define DW_DLE_PE_SIZE_SMALL 426 #define DW_DLE_PE_OFFSET_BAD 427 #define DW_DLE_PE_STRING_TOO_LONG 428 #define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 #define DW_DLE_LINE_TABLE_LINENO_ERROR 430 #define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 #define DW_DLE_NO_ELF_SUPPORT 432 #define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 #define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 #define DW_DLE_SECTION_SIZE_ERROR 435 #define DW_DLE_INTERNAL_NULL_POINTER 436 #define DW_DLE_SECTION_STRING_OFFSET_BAD 437 #define DW_DLE_SECTION_INDEX_BAD 438 #define DW_DLE_INTEGER_TOO_SMALL 439 #define DW_DLE_ELF_SECTION_LINK_ERROR 440 #define DW_DLE_ELF_SECTION_GROUP_ERROR 441 #define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 #define DW_DLE_ELF_STRING_SECTION_MISSING 443 #define DW_DLE_SEEK_OFF_END 444 #define DW_DLE_READ_OFF_END 445 #define DW_DLE_ELF_SECTION_ERROR 446 #define DW_DLE_ELF_STRING_SECTION_ERROR 447 #define DW_DLE_MIXING_SPLIT_DWARF_VERSIONS 448 #define DW_DLE_TAG_CORRUPT 449 #define DW_DLE_FORM_CORRUPT 450 #define DW_DLE_ATTR_CORRUPT 451 #define DW_DLE_ABBREV_ATTR_DUPLICATION 452 #define DW_DLE_DWP_SIGNATURE_MISMATCH 453 #define DW_DLE_CU_UT_TYPE_VALUE 454 #define DW_DLE_DUPLICATE_GNU_DEBUGLINK 455 #define DW_DLE_CORRUPT_GNU_DEBUGLINK 456 #define DW_DLE_CORRUPT_NOTE_GNU_DEBUGID 457 #define DW_DLE_CORRUPT_GNU_DEBUGID_SIZE 458 #define DW_DLE_CORRUPT_GNU_DEBUGID_STRING 459 #define DW_DLE_HEX_STRING_ERROR 460 #define DW_DLE_DECIMAL_STRING_ERROR 461 #define DW_DLE_PRO_INIT_EXTRAS_UNKNOWN 462 #define DW_DLE_PRO_INIT_EXTRAS_ERR 463 #define DW_DLE_NULL_ARGS_DWARF_ADD_PATH 464 #define DW_DLE_DWARF_INIT_DBG_NULL 465 /* LAST MUST EQUAL LAST ERROR NUMBER */ #define DW_DLE_LAST 465 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_SAME_VAL 1035 /* error return values */ #define DW_DLV_BADADDR (~(Dwarf_Addr)0) /* for functions returning target address */ #define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) /* for functions returning count */ #define DW_DLV_BADOFFSET (~(Dwarf_Off)0) /* for functions returning offset */ /* standard return values for functions */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 /* Special values for offset_into_exception_table field of dwarf fde's. */ /* The following value indicates that there is no Exception table offset associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer was unable to analyse the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) /* The dwarf specification separates FORMs into different classes. To do the seperation properly requires 4 pieces of data as of DWARF4 (thus the function arguments listed here). The DWARF4 specification class definition suffices to describe all DWARF versions. See section 7.5.4, Attribute Encodings. A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). DWARF5: DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST except that LOCLISTSPTR is aways a section offset, never an index, and LOCLISTSPTR is only referenced by DW_AT_loclists_base. Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish from DW_FORM_CLASS_LOCLISTPTR. DWARF5: DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST except that RNGLISTSPTR is aways a section offset, never an index. DW_FORM_CLASS_RNGLISTSPTR is only referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN, DW_FORM_CLASS_ADDRESS, DW_FORM_CLASS_BLOCK, DW_FORM_CLASS_CONSTANT, DW_FORM_CLASS_EXPRLOC, DW_FORM_CLASS_FLAG, DW_FORM_CLASS_LINEPTR, DW_FORM_CLASS_LOCLISTPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_MACPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_RANGELISTPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_REFERENCE, DW_FORM_CLASS_STRING, DW_FORM_CLASS_FRAMEPTR, /* MIPS/IRIX DWARF2 only */ DW_FORM_CLASS_MACROPTR, /* DWARF5 */ DW_FORM_CLASS_ADDRPTR, /* DWARF5 */ DW_FORM_CLASS_LOCLIST, /* DWARF5 */ DW_FORM_CLASS_LOCLISTSPTR, /* DWARF5 */ DW_FORM_CLASS_RNGLIST, /* DWARF5 */ DW_FORM_CLASS_RNGLISTSPTR, /* DWARF5 */ DW_FORM_CLASS_STROFFSETSPTR /* DWARF5 */ }; /* These support opening DWARF5 split dwarf objects. */ #define DW_GROUPNUMBER_ANY 0 #define DW_GROUPNUMBER_BASE 1 #define DW_GROUPNUMBER_DWO 2 /*===========================================================================*/ /* Dwarf consumer interface initialization and termination operations */ /* Initialization based on path. This is new October 2018. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. So consider the value put in true_path_out the actual file name. reserved1,2,3 should all be passed as zero. */ int dwarf_init_path(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* Initialization based on Unix(etc) open fd */ /* New March 2017 */ int dwarf_init_b(int /*fd*/, Dwarf_Unsigned /*access*/, unsigned /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* The dwarf_elf_init* functions continue to be supported, but should be considered deprecated as they can ONLY be used on Elf files. */ /* Initialization based on libelf/sgi-fastlibelf open pointer. */ /* New March 2017 */ int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, unsigned /*group_number*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* New September 2019. When using dwarf_elf_init[_b]() we still want the file path in the record. So we add it after the init phase. Path is needed for buildid and debuglink to fully work. */ int dwarf_add_file_path(Dwarf_Debug /*dbg*/, const char * /*file_name*/, Dwarf_Error* /*error*/); /* Undocumented function for memory allocator. */ void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); int dwarf_get_elf(Dwarf_Debug /*dbg*/, dwarf_elf_handle* /*return_elfptr*/, Dwarf_Error* /*error*/); int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* NEW March 2017. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, unsigned /*groupnumber*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_set_tied_dbg(Dwarf_Debug /*basedbg*/, Dwarf_Debug /*tied_dbg*/, Dwarf_Error* /*error*/); /* Likely not very useful.? */ int dwarf_get_tied_dbg(Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/); int dwarf_object_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns the version string. Example: "20190922" which is in ISO date format. */ const char * dwarf_package_version(void); /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, const char * /*std_section_name*/, const char ** /*actual_sec_name_out*/, Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ Dwarf_Unsigned * /*compressed_length*/, Dwarf_Unsigned * /*uncompressed_length*/, Dwarf_Error * /*error*/); /* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Half * /*header_cu_type*/, Dwarf_Error* /*error*/); /* Die traversal operations. dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* The following is obsolete, though supported. November 2009. */ int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); int dwarf_siblingof(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* dwarf_siblingof_b new October 2011. */ int dwarf_siblingof_b(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* New 27 April 2015. */ int dwarf_die_from_hash_signature(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*hash_sig*/, const char * /*sig_type: "tu" or "cu"*/, Dwarf_Die* /*returned_CU_die */, Dwarf_Error* /*error*/); int dwarf_child(Dwarf_Die /*die*/, Dwarf_Die* /*return_childdie*/, Dwarf_Error* /*error*/); /* Finding die given global (not CU-relative) offset. Applies only to debug_info. */ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* Returns the is_info flag through the pointer if the function returns DW_DLV_OK. Needed so client software knows if a DIE is in debug_info or debug_types. New October 2011. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die /*die*/); /* New March 2016. So we can associate a DIE's abbreviations with the contents the abbreviations section. */ int dwarf_die_abbrev_global_offset(Dwarf_Die /*die*/, Dwarf_Off * /*abbrev_offset*/, Dwarf_Unsigned * /*abbrev_count*/, Dwarf_Error* /*error*/); /* operations on DIEs */ int dwarf_tag(Dwarf_Die /*die*/, Dwarf_Half* /*return_tag*/, Dwarf_Error* /*error*/); /* dwarf_dieoffset returns the global debug_info section offset, not the CU relative offset. */ int dwarf_dieoffset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* NEW October 2015. DWARF5. The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr. This will look first for .debug_addr in the dbg object DIE and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given_die (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_die_CU_offset_range(Dwarf_Die /*die*/, Dwarf_Off* /*return_CU_header_offset*/, Dwarf_Off* /*return_CU_length_bytes*/, Dwarf_Error* /*error*/); int dwarf_attr (Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Attribute * /*returned_attr*/, Dwarf_Error* /*error*/); int dwarf_die_text(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, char ** /*ret_name*/, Dwarf_Error * /*error*/); int dwarf_diename(Dwarf_Die /*die*/, char ** /*diename*/, Dwarf_Error* /*error*/); /* Returns the abbrev code of the die. Cannot fail. */ int dwarf_die_abbrev_code(Dwarf_Die /*die */); /* Returns a flag through ab_has_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, Dwarf_Half * /*ab_has_child*/); /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/,Dwarf_Off* /*offset*/); /* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Off ** /*offbuf*/, Dwarf_Unsigned * /*offcnt*/, Dwarf_Error * /*error*/); /* BEGIN: loclist_c interfaces NEW October 2015. This works for any attribute that identifies a loclist or a locexpr. When the attribute is a locexpr a single loclist (created by libdwarf) is attached to loclist_head. */ int dwarf_get_loclist_c (Dwarf_Attribute /*attr*/, Dwarf_Loc_Head_c * /*loclist_head*/, Dwarf_Unsigned * /*locCount*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); int dwarf_get_location_op_value_c(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*address_size*/, Dwarf_Half /*offset_size*/, Dwarf_Small /*dwarf_version*/, Dwarf_Loc_Head_c* /*loc_head*/, Dwarf_Unsigned * /*listlen*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface is dwarf_get_loclist_c and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* The original interfaces. Please do not use this. */ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ Dwarf_Locdesc** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, Dwarf_Unsigned /* expression_length*/, Dwarf_Locdesc ** /* llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); /* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*addr_size*/, Dwarf_Locdesc ** /*llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); /* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for DW_OP_GNU_implicit_pointer. */ int dwarf_loclist_from_expr_b(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/ , Dwarf_Unsigned /*expression_length*/ , Dwarf_Half /*addr_size*/ , Dwarf_Half /*offset_size*/ , Dwarf_Small /*dwarf_version*/ , Dwarf_Locdesc ** /*llbuf*/ , Dwarf_Signed * /*listlen*/ , Dwarf_Error * /*error*/ ); int dwarf_lowpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* When the highpc attribute is of class 'constant' it is not an address, it is an offset from the base address (such as lowpc) of the function. This is therefore a required interface for DWARF4 style DW_AT_highpc. */ int dwarf_highpc_b(Dwarf_Die /*die*/, Dwarf_Addr * /*return_value*/, Dwarf_Half * /*return_form*/, enum Dwarf_Form_Class * /*return_class*/, Dwarf_Error * /*error*/); /* This works for DWARF2 and DWARF3 styles of DW_AT_highpc, but not for the DWARF4 class constant forms. If the FORM is of class constant this returns an error */ int dwarf_highpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* New January 2016. */ int dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/); int dwarf_bytesize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitsize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitoffset(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_offset*/, Dwarf_Error* /*error*/); int dwarf_srclang(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_lang*/, Dwarf_Error* /*error*/); int dwarf_arrayorder(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_order*/, Dwarf_Error* /*error*/); /* end of convenience function list */ /* this is the main interface to attributes of a DIE */ int dwarf_attrlist(Dwarf_Die /*die*/, Dwarf_Attribute** /*attrbuf*/, Dwarf_Signed * /*attrcount*/, Dwarf_Error* /*error*/); /* query operations for attributes */ int dwarf_hasform(Dwarf_Attribute /*attr*/, Dwarf_Half /*form*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_whatform(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_final_form*/, Dwarf_Error* /*error*/); int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_initial_form*/, Dwarf_Error* /*error*/); int dwarf_whatattr(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Error* /*error*/); /* The following are concerned with the Primary Interface: getting the actual data values. One function per 'kind' of FORM. */ /* dwarf_formref returns, thru return_offset, a CU-relative offset and does not allow DW_FORM_ref_addr*/ int dwarf_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_global_formref returns, thru return_offset, a debug_info-relative offset and does allow all reference forms*/ int dwarf_global_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8. Not a string. */ int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); /* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); int dwarf_formaddr(Dwarf_Attribute /*attr*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* Part of DebugFission. So a consumer can get the index when the object with the actual .debug_addr section is elsewhere. And so a print application can print the index. New May 2014*/ int dwarf_get_debug_addr_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_formdata16(Dwarf_Attribute /*attr*/, Dwarf_Form_Data16 * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formsdata(Dwarf_Attribute /*attr*/, Dwarf_Signed * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formblock(Dwarf_Attribute /*attr*/, Dwarf_Block ** /*returned_block*/, Dwarf_Error* /*error*/); int dwarf_formstring(Dwarf_Attribute /*attr*/, char ** /*returned_string*/, Dwarf_Error* /*error*/); /* DebugFission. So a DWARF print application can get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formexprloc(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_exprlen*/, Dwarf_Ptr * /*block_ptr*/, Dwarf_Error * /*error*/); /* end attribute query operations. */ /* Start line number operations */ /* dwarf_srclines is the original interface from 1993. */ int dwarf_srclines(Dwarf_Die /*die*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error* /*error*/); /* If we have two-level line tables, this will return the logicals table in linebuf and the actuals table in linebuf_actuals. For old-style (one-level) tables, it will return the single table through linebuf, and the value returned through linecount_actuals will be 0. The actual version number is returned through version. For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Line** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the appropriate method for deallocating what dwarf_srclines and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables user code should call dwarf_srclines_dealloc once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Line* /*linebuf*/, Dwarf_Signed /*count */); /* New October 2015, must be used to deallocating what is allocated by dwarf_srclines_b and dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. *is_single_table will be set zero for line sections with the two_level line table extension (which will have *version_out 0xf006). */ int dwarf_srclines_b(Dwarf_Die /*die*/, Dwarf_Unsigned * /* version_out*/, Dwarf_Small * /* table_count */, Dwarf_Line_Context * /* linecontext*/, Dwarf_Error * /* error*/); /* Functions passing in a Dwarf_Line_Context are only available if dwarf_srclines_b() was used to access line table information. */ /* New October 2015. Returns line details. Works for DWARF2,3,4,5. If linecount returned is zero this is a line table with no lines.*/ int dwarf_srclines_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error * /* error*/); /* New October 2015. Returns line details. Works for DWARF2,3,4,5 and for experimental two-level line tables. A single level table will have *linebuf_actuals and *linecount_actuals set to 0. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf */, Dwarf_Signed * /*linecount*/, Dwarf_Line ** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error * /* error*/); /* dwarf_srclines_dealloc_b(), created October 2015, is the appropriate method for deallocating everything and dwarf_srclines_from_linecontext(), dwarf_srclines_twolevel_from_linecontext(), and dwarf_srclines_b() allocate. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context /*line_context*/); /* New October 2015. */ /* The offset is in the relevent .debug_line or .debug_line.dwo section (and in a split dwarf package file includes) the base line table offset). */ int dwarf_srclines_table_offset(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Compilation Directory name for the current CU. section (and in a split dwarf package file includes) the base line table offset). Do not free() the string, it is in a dwarf section. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, const char ** /*compilation_directory*/, Dwarf_Error * /*error*/); /* New October 2015. Part of the two-level line table extension. */ /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*decl_file*/, Dwarf_Unsigned * /*decl_line*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Count is the real count of files array entries. This remains supported though it is pretty useless for DWARF5. To process DWARF5 as well as DWARF 2,3,4 (in a uniform fashion) use dwarf_srclines_files_indexes() instead. */ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New March 2018. */ /* Count is the real count of files array entries. Since DWARF 2,3,4 are zero origin indexes and DWARF5 and later are one origin, this function replaces dwarf_srclines_files_count(). */ int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*baseindex*/, Dwarf_Signed * /*count*/, Dwarf_Signed * /*endindex*/, Dwarf_Error * /*error*/); /* New March 2018. Same as dwarf_srclines_files_data, but adds the md5ptr field so cases where DW_LNCT_MD5 is present can return pointer to the MD5 value. With DWARF 5 index starts with 0. See dwarf_srclines_files_indexes() which makes indexing through the files easy. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5ptr, Dwarf_Error * error); /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. Index starts with 1, last is 'count' */ int dwarf_srclines_files_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*directory_index*/, Dwarf_Unsigned * /*last_mod_time*/, Dwarf_Unsigned * /*file_length*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Count is the real count of include array entries. */ int dwarf_srclines_include_dir_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_include_dir_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* The DWARF version number of this compile-unit in the .debug_lines section and the number of actual tables:0 (header with no lines), 1 (standard table), or 2 (experimental). */ int dwarf_srclines_version(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*version*/, Dwarf_Small * /*table_count*/, Dwarf_Error * /*error*/); int dwarf_get_line_section_name_from_die(Dwarf_Die /*die*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* While 'filecount' is signed, the value returned through the pointer is never negative. Original libdwarf from 199x. */ int dwarf_srcfiles(Dwarf_Die /*die*/, char*** /*srcfiles*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineendsequence(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error* /*error*/); int dwarf_line_srcfileno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_fileno*/, Dwarf_Error * /*error*/); /* Is the line address from DW_LNS_set_address? */ int dwarf_line_is_addr_set(Dwarf_Line /*line*/, Dwarf_Bool * /*is_addr_set*/, Dwarf_Error * /*error*/); int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); /* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineoffset*/, Dwarf_Error* /*error*/); int dwarf_linesrc(Dwarf_Line /*line*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_lineblock(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line /* line */, Dwarf_Bool * /*prologue_end*/, Dwarf_Bool * /*eplogue_begin*/, Dwarf_Unsigned * /* isa */, Dwarf_Unsigned * /* discriminator */, Dwarf_Error * /*error*/); /* End line table operations */ /* Two-level line tables: When reading from an actuals table, dwarf_line_logical() returns the logical row number for the line. */ int dwarf_linelogical(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_logical*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linecontext() returns the logical row number corresponding the the calling context for an inlined call. */ int dwarf_linecontext(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_context*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprogno() returns the index in the subprograms table of the inlined subprogram. */ int dwarf_line_subprogno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_subprogno*/, Dwarf_Error * /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprog() returns the name of the inlined subprogram, its declaration filename, and its declaration line number, if available. */ int dwarf_line_subprog(Dwarf_Line /*line*/, char ** /*returned_subprog_name*/, char ** /*returned_filename*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ /* .debug_names names table interfaces. DWARF5 */ /* New April 2017 */ int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, Dwarf_Dnames_Head * /*dn_out*/, /* *dn_count_out returns the number of name indexes in the .debug_names section */ Dwarf_Unsigned * /*dn_index_count_out*/, Dwarf_Error * /*error*/); /* Since there may be multiple name indexes in a .debug_names section we use index_number starting at 0 through dn_index_count_out-1. */ int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned * /*section_offset*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * /*comp_unit_count*/, Dwarf_Unsigned * /*local_type_unit_count*/, Dwarf_Unsigned * /*foreign_type_unit_count*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*name_count*/, /* The following are counted in bytes */ Dwarf_Unsigned * /*indextable_overall_length*/, Dwarf_Unsigned * /*abbrev_table_size*/, Dwarf_Unsigned * /*entry_pool_size*/, Dwarf_Unsigned * /*augmentation_string_size*/, Dwarf_Error * /*error*/); int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*sig_number*/, Dwarf_Unsigned * /*sig_mininum*/, Dwarf_Unsigned * /*sig_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Error * /*error*/); int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*bucket_number*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*index_of_name_entry*/, Dwarf_Error * /*error*/); int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*name_entry*/, Dwarf_Unsigned * /*names_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Unsigned * /*offset_to_debug_str*/, Dwarf_Unsigned * /*offset_in_entrypool*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * /*number_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * /*index_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry_index*/, Dwarf_Unsigned /*abbrev_form_index*/, Dwarf_Unsigned * /*name_index_attr*/, Dwarf_Unsigned * /*form*/, Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_in_entrypool*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Unsigned * /*index_of_abbrev*/, Dwarf_Unsigned * /*offset_of_initial_value*/, Dwarf_Error * /*error*/); /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*index_of_abbrev*/, Dwarf_Unsigned /*offset_in_entrypool_of_values*/, Dwarf_Unsigned * /*array_dw_idx_number*/, Dwarf_Unsigned * /*array_form*/, Dwarf_Unsigned * /*array_of_offsets*/, Dwarf_Sig8 * /*array_of_signatures*/, /* offset of the next entrypool entry. */ Dwarf_Unsigned * /*offset_of_next_entrypool*/, Dwarf_Error * /*error*/); /* FIXME: add interfaces for string search given hash and string */ /* end of .debug_names interfaces. */ /* New October 2019. Access to the GNU section named .gnu_debuglink and/or the section .note.gnu.build-id. See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html The dbg argument provides data access and relies on fields de_path,de_debuglink_globals, de_debuglink_globals_length If no debuglink then name_returned,crc_returned and debuglink_path_returned will get set 0 through the pointers. If no .note.gnu.build-id then buildid_length_returned, and buildid_returned will be set 0 through the pointers. See libdwarf2.1.mm for additional important details. see dwarf_add_file_path() and dwarf_add_debuglink_global_path(). */ int dwarf_gnu_debuglink(Dwarf_Debug /*dbg*/, char ** /*name_returned*/, unsigned char ** /*crc_returned from the debuglink section*/, char ** /*debuglink_path_returned*/, unsigned * /*debuglink_path_count_returned*/, unsigned * /*buildid_type_returned */, char ** /*buildid_owner_name_returned*/, unsigned char ** /*buildid_returned*/, unsigned * /*buildid_length_returned*/, char *** /*paths_returned*/, unsigned * /*paths_length_returned*/, Dwarf_Error* /*error*/); /* See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html and dwarf_gnu_debuglink() pathname is a path-prefix to be added to a list of path-prefixes, The default "/usr/lib/debug" is built-in and is the first such in the list held in dbg. The path prefix should start with / . It can just end or end with / , either choice will work. */ int dwarf_add_debuglink_global_path(Dwarf_Debug /*dbg*/, const char *pathname, Dwarf_Error* /*error*/); /* global name space operations (.debug_pubnames access) The pubnames and similar sections are rarely used. Few compilers emit them. They are DWARF 2,3,4 only., not DWARF 5. */ /* New March 2019. Mostly special for dwarfdump. */ int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, int /* flag */, Dwarf_Error* /*error*/); int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, Dwarf_Error* /*error*/); void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Global* /*globals*/, Dwarf_Signed /*number_of_globals*/); int dwarf_globname(Dwarf_Global /*glob*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_global_die_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error * /*error*/); /* This returns the CU die global offset if one knows the CU header global offset. See also dwarf_CU_dieoffset_given_die(). */ int dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); /* The _b form is new October 2011. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Bool /*is_info. True means look in debug_Info, false use debug_types.*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset #endif int dwarf_global_cu_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_global_name_offsets(Dwarf_Global /*global*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. */ int dwarf_get_globals_header(Dwarf_Global /*global*/, Dwarf_Off * /*offset_pub_header*/, Dwarf_Unsigned * /*length_size*/, Dwarf_Unsigned * /*length_pub*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*header_info_offset*/, Dwarf_Unsigned * /*info_length*/, Dwarf_Error* /*error*/); /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, Dwarf_Signed * /*number_of_funcs*/, Dwarf_Error* /*error*/); void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Func* /*funcs*/, Dwarf_Signed /*number_of_funcs*/); int dwarf_funcname(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_func_die_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_cu_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_name_offsets(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, SGI IRIX .debug_typenames section. Same content as DWARF3 .debug_pubtypes, but defined years before .debug_pubtypes was defined. SGI IRIX only. */ int dwarf_get_types(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*types*/, Dwarf_Signed /*number_of_types*/); int dwarf_typename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, DWARF3 .debug_pubtypes section. */ int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*pubtypes*/, Dwarf_Signed /*number_of_pubtypes*/); int dwarf_pubtypename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_pubtype_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* File-scope static variable name operations. */ int dwarf_get_vars(Dwarf_Debug /*dbg*/, Dwarf_Var** /*vars*/, Dwarf_Signed * /*number_of_vars*/, Dwarf_Error* /*error*/); void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Var* /*vars*/, Dwarf_Signed /*number_of_vars*/); int dwarf_varname(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_var_die_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_cu_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_name_offsets(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* weak name operations. */ int dwarf_get_weaks(Dwarf_Debug /*dbg*/, Dwarf_Weak** /*weaks*/, Dwarf_Signed * /*number_of_weaks*/, Dwarf_Error* /*error*/); void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Weak* /*weaks*/, Dwarf_Signed /*number_of_weaks*/); int dwarf_weakname(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* location list section operation. (.debug_loc access) */ int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Addr* /*hipc*/, Dwarf_Addr* /*lopc*/, Dwarf_Ptr* /*data*/, Dwarf_Unsigned* /*entry_len*/, Dwarf_Unsigned* /*next_entry*/, Dwarf_Error* /*error*/); /* abbreviation section operations */ int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Abbrev * /*returned_abbrev*/, Dwarf_Unsigned* /*length*/, Dwarf_Unsigned* /*attr_count*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, Dwarf_Half* /*return_tag_number*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned* /*return_code_number*/, Dwarf_Error* /*error*/); /* See comments in dwarf_abbrev.c. Not an entirely safe function. */ int dwarf_get_abbrev_count(Dwarf_Debug /*dbg*/); int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed* /*return_flag*/, Dwarf_Error* /*error*/); /* New August 2019. Most uses will call with filter_outliers non-zero. In that case impossible values return DW_DLV_ERROR. Those doing extra things (like dwarfdump) will call with filter_outliers zero to get the raw data (effectively); */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned indx, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implict_const, Dwarf_Off * offset, Dwarf_Error * error); /* Obsolete because it cannot return the DW_FORM_implicit_const value. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed /*index*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Signed* /*form*/, Dwarf_Off* /*offset*/, Dwarf_Error* /*error*/); int dwarf_get_string_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* consumer string section operation */ int dwarf_get_str(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, char** /*string*/, Dwarf_Signed * /*strlen_of_string*/, Dwarf_Error* /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* Consumer op on gnu .eh_frame info */ int dwarf_get_fde_list_eh( Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* consumer operations on frame info: .debug_frame */ int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* Release storage gotten by dwarf_get_fde_list_eh() or dwarf_get_fde_list() */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Cie * /*cie_data*/, Dwarf_Signed /*cie_element_count*/, Dwarf_Fde * /*fde_data*/, Dwarf_Signed /*fde_element_count*/); int dwarf_get_fde_range(Dwarf_Fde /*fde*/, Dwarf_Addr* /*low_pc*/, Dwarf_Unsigned* /*func_length*/, Dwarf_Ptr* /*fde_bytes*/, Dwarf_Unsigned* /*fde_byte_length*/, Dwarf_Off* /*cie_offset*/, Dwarf_Signed* /*cie_index*/, Dwarf_Off* /*fde_offset*/, Dwarf_Error* /*error*/); /* Useful for IRIX only: see dwarf_get_cie_augmentation_data() dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, Dwarf_Signed* /* offset_into_exception_tables */, Dwarf_Error* /*error*/); int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, Dwarf_Cie * /*cie_returned*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info_b(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Half* /*offset_size*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Error* /*error*/); /* dwarf_get_cie_index new September 2009. */ int dwarf_get_cie_index( Dwarf_Cie /*cie*/, Dwarf_Signed* /*index*/, Dwarf_Error* /*error*/ ); int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); 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*/); /* In this older interface DW_FRAME_CFA_COL is a meaningful column (which does not work well with DWARF3 or non-MIPS architectures). */ int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Signed* /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* See discussion of dw_value_type, libdwarf.h. Use of DW_FRAME_CFA_COL is not meaningful in this interface. See dwarf_get_fde_info_for_cfa_reg3(). */ /* dwarf_get_fde_info_for_reg3 is useful on a single column, but it is inefficient to iterate across all table_columns using this function. Instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error* /*error*/); /* Use this to get the cfa. Or the above function. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Error* /*error*/); int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, Dwarf_Die /*subr_die */, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, Dwarf_Unsigned /*fde_index*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, Dwarf_Addr /*pc_of_interest*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Addr* /*lopc*/, Dwarf_Addr* /*hipc*/, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, Dwarf_Ptr /*instruction*/, Dwarf_Unsigned /*i_length*/, Dwarf_Frame_Op** /*returned_op_list*/, Dwarf_Signed* /*op_count*/, Dwarf_Error* /*error*/); /* Operations on .debug_aranges. */ int dwarf_get_aranges(Dwarf_Debug /*dbg*/, Dwarf_Arange** /*aranges*/, Dwarf_Signed * /*arange_count*/, Dwarf_Error* /*error*/); int dwarf_get_ranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_aranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_arange( Dwarf_Arange* /*aranges*/, Dwarf_Unsigned /*arange_count*/, Dwarf_Addr /*address*/, Dwarf_Arange * /*returned_arange*/, Dwarf_Error* /*error*/); int dwarf_get_cu_die_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_get_arange_cu_header_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_cu_header_offset*/, Dwarf_Error* /*error*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_arange_cu_header_offset #endif /* DWARF2,3 interface. No longer really adequate (it was never right for segmented address spaces, please switch to using dwarf_get_arange_info_b instead. There is no effective difference between these functions if the address space of the target is not segmented. */ int dwarf_get_arange_info( Dwarf_Arange /*arange*/, Dwarf_Addr* /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off* /*cu_die_offset*/, Dwarf_Error* /*error*/ ); /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b( Dwarf_Arange /*arange*/, Dwarf_Unsigned* /*segment*/, Dwarf_Unsigned* /*segment_entry_size*/, Dwarf_Addr * /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off * /*cu_die_offset*/, Dwarf_Error * /*error*/ ); /* BEGIN: DWARF5 .debug_macro interfaces NEW November 2015. */ int dwarf_get_macro_context(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_unit_offset_out*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length_out*/, Dwarf_Error * /*error*/); /* Just like dwarf_get_macro_context, but instead of using DW_AT_macros or DW_AT_GNU_macros to get the offset we just take the offset given. */ int dwarf_get_macro_context_by_offset(Dwarf_Die /*die*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length*/, Dwarf_Error * /*error*/); void dwarf_dealloc_macro_context(Dwarf_Macro_Context /*mc*/); int dwarf_get_macro_section_name(Dwarf_Debug /*dbg*/, const char ** /*sec_name_out*/, Dwarf_Error * /*err*/); int dwarf_macro_context_head(Dwarf_Macro_Context /*head*/, Dwarf_Half * /*version*/, Dwarf_Unsigned * /*mac_offset*/, Dwarf_Unsigned * /*mac_len*/, Dwarf_Unsigned * /*mac_header_len*/, unsigned * /*flags*/, Dwarf_Bool * /*has_line_offset*/, Dwarf_Unsigned * /*line_offset*/, Dwarf_Bool * /*has_offset_size_64*/, Dwarf_Bool * /*has_operands_table*/, Dwarf_Half * /*opcode_count*/, Dwarf_Error * /*error*/); /* Returns data from the operands table in the macro unit header. */ int dwarf_macro_operands_table(Dwarf_Macro_Context /*head*/, Dwarf_Half /*index*/, /* 0 to opcode_count -1 */ Dwarf_Half * /*opcode_number*/, Dwarf_Half * /*operand_count*/, const Dwarf_Small ** /*operand_array*/, Dwarf_Error * /*error*/); /* Access to the macro operations, 0 to macro_ops_count_out-1 Where the last of these will have macro_operator 0 (which appears in the ops data and means end-of-ops). op_start_section_offset is the section offset of the macro operator (which is a single unsigned byte, and is followed by the macro operand data). */ int dwarf_get_macro_op(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*op_start_section_offset*/, Dwarf_Half * /*macro_operator*/, Dwarf_Half * /*forms_count*/, const Dwarf_Small ** /*formcode_array*/, Dwarf_Error * /*error*/); int dwarf_get_macro_defundef(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*index*/, Dwarf_Unsigned * /*offset*/, Dwarf_Half * /*forms_count*/, const char ** /*macro_string*/, Dwarf_Error * /*error*/); int dwarf_get_macro_startend_file(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*name_index_to_line_tab*/, const char ** /*src_file_name*/, Dwarf_Error * /*error*/); int dwarf_get_macro_import(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*target_offset*/, Dwarf_Error * /*error*/); /* END: DWARF5 .debug_macro interfaces. */ /* consumer .debug_macinfo information interface. */ struct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; /* offset, in the section, of this macro info */ Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ Dwarf_Signed dmd_lineno; /* the source line number where applicable and vend_def number if vendor_extension op */ Dwarf_Signed dmd_fileindex;/* the source file index: applies to define undef start_file */ char * dmd_macro; /* macro name (with value for defineop) string from vendor ext */ }; /* dwarf_print_lines is for use by dwarfdump: it prints line info to stdout. The _dwarf name is obsolete. Use dwarf_ instead. Added extra argnument 2/2009 for better checking. */ int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/); int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/, int * /*error_count_out */); /* As of August 2013, dwarf_print_lines() no longer uses printf. Instead it calls back to the application using a function pointer once per line-to-print. The lines passed back already have any needed newlines. The following struct is used to initialize the callback mechanism. Failing to call the dwarf_register_printf_callback() function will prevent the lines from being passed back but such omission is not an error. See libdwarf2.1.mm for further documentation. The return value is the previous set of callback values. */ typedef void (* dwarf_printf_callback_function_type) (void * /*user_pointer*/, const char * /*linecontent*/); struct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; /* If called with a NULL newvalues pointer, it simply returns the current set of values for this Dwarf_Debug. */ struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug /*dbg*/, struct Dwarf_Printf_Callback_Info_s * /*newvalues*/); /* dwarf_check_lineheader lets dwarfdump get detailed messages about some compiler errors we detect. We return the count of detected errors through the pointer. */ void dwarf_check_lineheader(Dwarf_Die /*cu_die*/,int *errcount_out); /* dwarf_ld_sort_lines helps SGI IRIX ld rearrange lines in .debug_line in a .o created with a text section per function. -OPT:procedure_reorder=ON where ld-cord (cord(1)ing by ld, not by cord(1)) may have changed the function order. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /* buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); int dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /*buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); /* Used by dwarfdump -v to print fde offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); int dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); /* Used by dwarfdump -v to print cie offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off */, Dwarf_Error * /*err*/); int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off /*macro_offset*/, Dwarf_Unsigned /*maximum_count*/, Dwarf_Signed * /*entry_count*/, Dwarf_Macro_Details ** /*details*/, Dwarf_Error * /*err*/); /* dwarf_get_offset_size() New October 2015 */ int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*offset_size*/, Dwarf_Error * /*error*/); int dwarf_get_address_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); int dwarf_get_die_address_size(Dwarf_Die /*die*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half /* dwversion */, Dwarf_Half /* attrnum */, Dwarf_Half /*offset_size */, Dwarf_Half /*form*/); /* BEGIN gdbindex operations interfaces. */ /* .gdb_index section operations. A GDB extension. The section is in some executables and if present is used to quickly map an address or name to a skeleton CU or TU. If present then there are .dwo or .dwp files somewhere to make detailed debugging possible (up to user code to find it/them and deal with them). Version 8 built by gdb, so type entries are ok as is. Version 7 built by the 'gold' linker and type index entries for a CU must be derived othewise, the type index is not correct... ? FIXME */ /* Creates a Dwarf_Gdbindex, returning it and its values through the pointers. */ int dwarf_gdbindex_header(Dwarf_Debug /*dbg*/, Dwarf_Gdbindex * /*gdbindexptr*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*cu_list_offset*/, Dwarf_Unsigned * /*types_cu_list_offset*/, Dwarf_Unsigned * /*address_area_offset*/, Dwarf_Unsigned * /*symbol_table_offset*/, Dwarf_Unsigned * /*constant_pool_offset*/, Dwarf_Unsigned * /*section_size*/, Dwarf_Unsigned * /*unused_reserved*/, const char ** /*section_name*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*cu_length*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to types_list_length -1 */ int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*tu_offset*/, Dwarf_Unsigned * /*type_signature*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*low_adddress*/, Dwarf_Unsigned * /*high_address*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*symtab_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*string_offset*/, Dwarf_Unsigned * /*cu_vector_offset*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned * /*innercount*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned /*innerindex*/, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, Dwarf_Unsigned * /*symbol_kind*/, Dwarf_Unsigned * /*is_static*/, Dwarf_Error * /*error*/); /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*stringoffset*/, const char ** /*string_ptr*/, Dwarf_Error * /*error*/); void dwarf_gdbindex_free(Dwarf_Gdbindex /*gdbindexptr*/); /* END gdbindex/debugfission operations. */ /* START debugfission dwp .debug_cu_index and .debug_tu_index operations. */ int dwarf_get_xu_index_header(Dwarf_Debug /*dbg*/, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * /*xuhdr*/, Dwarf_Unsigned * /*version_number*/, Dwarf_Unsigned * /*offsets_count L*/, Dwarf_Unsigned * /*units_count N*/, Dwarf_Unsigned * /*hash_slots_count M*/, const char ** /*sect_name*/, Dwarf_Error * /*err*/); int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header /*xuhdr*/, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** /*typename*/, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** /*sectionname*/, Dwarf_Error * /*err*/); /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*index*/, /* Returns the hash value. 64 bits. */ Dwarf_Sig8 * /*hash_value*/, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * /*index_to_sections*/, Dwarf_Error * /*err*/); /* Columns 0 to L-1, valid. */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header /*xuhdr*/, /* Row index defined to be row zero. */ Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*DW_SECT_ number*/, const char ** /*DW_SECT_ name*/, Dwarf_Error * /*err*/); /* Rows 1 to N col 0 to L-1 are valid */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*row_index*/, Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*sec_offset*/, Dwarf_Unsigned* /*sec_size*/, Dwarf_Error * /*err*/); void dwarf_xu_header_free(Dwarf_Xu_Index_Header /*xuhdr*/); /* Defined larger than necessary. This struct, being visible, will be difficult to change: binary compatibility. */ #define DW_FISSION_SECT_COUNT 12 /* User must allocate this struct, zero it, and pass a pointer to it into dwarf_get_debugfission_for_cu . */ struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; typedef struct Dwarf_Debug_Fission_Per_CU_s Dwarf_Debug_Fission_Per_CU ; /* For any Dwarf_Die in a compilation unit, return the debug fission table data through percu_out. Usually applications will pass in the CU die. Calling code should zero all of the struct Dwarf_Debug_Fission_Per_CU_s before calling this. If there is no debugfission data this returns DW_DLV_NO_ENTRY (only .dwp objects have debugfission data). */ int dwarf_get_debugfission_for_die(Dwarf_Die /* die */, Dwarf_Debug_Fission_Per_CU * /* percu_out */, Dwarf_Error * /* err */); /* Given a key (hash signature) from a .o, find the per-cu information for the CU with that key. */ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*key, hash signature */, const char * key_type /*"cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * /*percu_out */, Dwarf_Error * /*err */); /* END debugfission dwp .debug_cu_index and .debug_tu_index operations. */ /* Utility operations */ Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); /* stringcheck zero is default and means do all string length validity checks. Call with parameter value 1 to turn off many such checks (and increase performance). Call with zero for safest running. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_stringcheck(int /*stringcheck*/); /* 'apply' defaults to 1 and means do all 'rela' relocations on reading in a dwarf object section with such relocations. Call with parameter value 0 to turn off application of such relocations. Since the static linker leaves 'bogus' data in object sections with a 'rela' relocation section such data cannot be read sensibly without processing the relocations. Such relocations do not exist in executables and shared objects (.so), the relocations only exist in plain .o relocatable object files. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_reloc_application(int /*apply*/); /* Unimplemented */ Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); /* Unimplemented */ Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, Dwarf_Unsigned /*type*/); /* DWARF Producer Interface */ /* New form June, 2011. Adds user_data argument. */ typedef int (*Dwarf_Callback_Func)( const char* /*name*/, int /*size*/, Dwarf_Unsigned /*type*/, Dwarf_Unsigned /*flags*/, Dwarf_Unsigned /*link*/, Dwarf_Unsigned /*info*/, Dwarf_Unsigned* /*sect_name_index*/, void * /*user_data*/, int* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR and if DW_DLV_OK returns the Dwarf_P_Debug pointer through the dbg_returned argument. */ int dwarf_producer_init( Dwarf_Unsigned /*flags*/, Dwarf_Callback_Func /*func*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, void * /*user_data*/, const char *isa_name, /* See isa/abi names in pro_init.c */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR. The desired form must be DW_FORM_string (the default) or DW_FORM_strp. */ int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, int /*desired_form*/, Dwarf_Error* /*error*/); /* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New September 2016. The preferred interface. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*nbufs_out*/, Dwarf_Error* /*error*/); /* New September 2016. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Ptr * /*section_bytes*/, Dwarf_Error* /*error*/); /* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info_count( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*count_of_relocation_sections*/, int * /*drd_buffer_version*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info( Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*elf_section_index*/, Dwarf_Signed * /*elf_section_index_link*/, Dwarf_Unsigned * /*relocation_buffer_count*/, Dwarf_Relocation_Data * /*reldata_buffer*/, Dwarf_Error* /*error*/); /* v1: no drd_length field, enum explicit */ /* v2: has the drd_length field, enum value in uchar member */ #define DWARF_DRD_BUFFER_VERSION 2 /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); /* Preferred version December 2018. */ int dwarf_get_die_markers_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); int dwarf_get_string_attributes_info(Dwarf_P_Debug, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_P_String_Attr *, Dwarf_Error *); void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR */ int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* dwarf_add_AT_reference_b allows otherdie to be NULL with the assumption the caller will then later call dwarf_fixup_AT_reference_die() with a non-null target die. New 22 October, 2013 */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie after a single pass thru the DIE generation. Needed for forward-references. New 22 October, 2013. */ int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_string_a( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* October 2017 for DW_FORM_data16. Usable with any attribute, though it should only be in limited use. DWARF5 only. Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. Returns the new attribute pointer through *return_attr. */ int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Form_Data16 * /* pointstovalue */, Dwarf_P_Attribute * /* return_attr */, Dwarf_Error * /*error*/); /* November 2018. DW_AT_implicit const generation. */ int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Producer line creation functions (.debug_line) */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned * /*index_in_directories*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned * /*file_entry_count_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Unsigned * /*cie_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*corresponding subprogram die*/, Dwarf_Unsigned /*cie_to_use*/, Dwarf_Unsigned /*virt_addr_of_described_code*/, Dwarf_Unsigned /*length_of_code*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_fde_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Unsigned * /*index_to_fde*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_info_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Unsigned * /*fde_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); /* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_fde_inst_a( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*len*/, Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde * /*fde_out*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_fde_cfa_offset_a( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* die creation & addition routines dwarf_new_die_a() new September 2016. Preferred over dwarf_new_die(). */ int dwarf_new_die_a( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_P_Die * /*die_out*/, Dwarf_Error* /*error*/); Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* New September 2016. */ int dwarf_add_die_to_debug_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error); Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_get_die_marker_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* New September 2016. Preferred version */ int dwarf_die_link_a( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); void dwarf_dealloc_compressed_block( Dwarf_P_Debug, void * ); /* Call this passing in return value from dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); /* dwarf_compress_integer_block_a( new 11 February 2019. Like the earlier version this turns an array of signed integers into a block of sleb values (and if the values are small enough it might be a compression! Or it could be an expansion...). Return DW_DLV_OK on success. Supercedes dwarf_compress_integer_block(): as no ugly cast needed to know if dwarf_compress_integer_block_a() succeeds or not. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*input_array_length*/, Dwarf_Signed * /*input_array*/, Dwarf_Unsigned * /*output_block_len*/, void ** /*output_block_returned*/, Dwarf_Error * /*error */); /* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ Dwarf_Small, /*size of integer units: 8, 16, 32, 64*/ void*, /*data*/ Dwarf_Unsigned, /*number of elements*/ Dwarf_Unsigned*, /*number of bytes in output block*/ Dwarf_Error* /*error*/ ); /* New February 2019. On success returns DW_DLV_OK and creates an array of Dwarf_Signed values from the block of sleb numbers. This interface supercedes dwarf_uncompress_integer_block(). No ugly cast needed to know if dwarf_uncompress_integer_block_a() succeeds or not. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*input_length_in_bytes*/, void * /*input_block*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Signed ** /*value_array*/, Dwarf_Error * /*error*/); /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). Returns a DW_DLV_BADADDR on error. Otherwise returns a pointer to an array of 32bit integers. The signed argument must be non-zero (the decode assumes sleb integers in the input data) at this time. Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements of the array that the return value points to) thru the argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ Dwarf_Small, /*size of integer units: 8, 16, 32, 64 */ void*, /*input data */ Dwarf_Unsigned, /*number of bytes in input */ Dwarf_Unsigned*, /*number of units in output block */ Dwarf_Error* /*error */ ); /* Operations to create location expressions. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr * /*expr_out*/, Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_gen_a( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Unsigned * /*next_byte_offset*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_addr_c( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_current_offset_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_into_block_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Small ** /*start_address*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Signed /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_arange_c( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubtype_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_funcname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_typename_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_varname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); int dwarf_add_weakname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); /* .debug_names producer functions */ /* dwarf_force_debug_names forces creation of .debug_names (if DWARF5 being produced) even if empty. Only for testing libdwarf. */ int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, Dwarf_Error* /*error*/); /* Other debug_names functions are needed... FIXME */ /* end .debug_names producer functions */ /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. */ int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, with (arglist), no space before (*/, char * /*macvalue*/, Dwarf_Error* /*error*/); int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, no arglist, of course*/, Dwarf_Error* /*error*/); int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*fileindex*/, Dwarf_Unsigned /*linenumber*/, Dwarf_Error* /*error*/); int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*constant*/, char * /*string*/, Dwarf_Error* /*error*/); /* end macinfo producer functions */ int dwarf_attr_offset(Dwarf_Die /*die*/, Dwarf_Attribute /*attr of above die*/, Dwarf_Off * /*returns offset thru this ptr */, Dwarf_Error * /*error*/); /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); /* New October 2011., adds .debug_types section to the sizes returned. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/, Dwarf_Unsigned * /*debug_names_size*/, Dwarf_Unsigned * /*debug_loclists_size*/, Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ /* Multiple releases spelled 'initial' as 'inital' . The 'inital' spelling should not be used. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* Additional interface with correct 'initial' spelling. */ /* It is likely you will want to call the following 6 functions before accessing any frame information. All are useful to tailor handling of pseudo-registers needed to turn frame operation references into simpler forms and to reflect ABI specific data. Of course altering libdwarf.h and dwarf.h allow the same capabilities, but header changes in the distribution would require you re-integrate your libdwarf.h changes into the distributed libdwarf.h ... so use the following functions instead.*/ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* dwarf_set_default_address_size only sets 'value' if value is greater than zero. */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug /*dbg*/, Dwarf_Small /* value */); /* As of April 27, 2009, this version with no diepointer is obsolete though supported. Use dwarf_get_ranges_a() instead. */ int dwarf_get_ranges(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* This adds the address_size argument. New April 27, 2009 */ int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /* diepointer */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); /* New April 2018. Allows applications to print the .debug_str_offsets section. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ struct Dwarf_Str_Offsets_Table_s; typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; /* Allocates a struct Dwarf_Str_Offsets_Table_s for the section and returns DW_DLV_OK and sets a pointer to the struct through the table_data pointer if successful. If there is no such section it returns DW_DLV_NO_ENTRY. */ int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, Dwarf_Str_Offsets_Table * /*table_data*/, Dwarf_Error * /*error*/); /* Close access, free table_data. */ int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Error * /*error*/); /* Call till it returns DW_DLV_NO_ENTRY (normal end) or DW_DLV_ERROR (error) and stop. On successful call, call dwarf_str_offsets_table_entry() to get the individual table values on the now-active table. */ int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*unit_length*/, Dwarf_Unsigned * /*unit_length_offset*/, Dwarf_Unsigned * /*table_start_offset*/, Dwarf_Half * /*entry_size*/, Dwarf_Half * /*version*/, Dwarf_Half * /*padding*/, Dwarf_Unsigned * /*table_value_count*/, Dwarf_Error * /*error*/); /* Valid index values n: 0 <= n < table_entry_count for the active table */ int dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned /*index_to_entry*/, Dwarf_Unsigned * /*entry_value*/, Dwarf_Error * /*error*/); /* After all str_offsets read this reports final wasted-bytes count. */ int dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*wasted_byte_count*/, Dwarf_Unsigned * /*table_count*/, Dwarf_Error * /*error*/); /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 #define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). The pointers returned in the array of pointers are invalidated by ANY call to libdwarf. Use them before making another libdwarf call! The array of string pointers passed in always has a final null pointer, so if there are N pointers the and M actual strings, then MIN(M,N-1) pointers are set to point to error strings. The array of pointers to strings always terminates with a NULL pointer. If 'count' is passed in zero then errmsg_ptrs_array is not touched. The function returns DW_DLV_NO_ENTRY if no harmless errors were noted so far. Returns DW_DLV_OK if there are errors. Never returns DW_DLV_ERROR. Each call empties the error list (discarding all current entries). If newerr_count is non-NULL the count of harmless errors since the last call is returned through the pointer (some may have been discarded or not returned, it is a circular list...). If DW_DLV_NO_ENTRY is returned none of the arguments here are touched or used. */ int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/, unsigned /*count*/, const char ** /*errmsg_ptrs_array*/, unsigned * /*newerr_count*/); /* Insertion is only for testing the harmless error code, it is not necessarily useful otherwise. */ void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/, char * /*newerror*/); /* The size of the circular list of strings may be set and reset as needed. If it is shortened excess messages are simply dropped. It returns the previous size. If zero passed in the size is unchanged and it simply returns the current size */ unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, unsigned /*maxcount*/); /* The harmless error strings (if any) are freed when the dbg is dwarf_finish()ed. */ /* When the val_in is known these dwarf_get_TAG_name (etc) functions return the string corresponding to the val_in passed in through the pointer s_out and the value returned is DW_DLV_OK. The strings are in static storage and must not be freed. If DW_DLV_NO_ENTRY is returned the val_in is not known and *s_out is not set. DW_DLV_ERROR is never returned.*/ /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); /* dwarf_get_LLEX_name is likely just temporary. Not standard. */ extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); /* END FILE */ /* Convert local offset into global offset */ int dwarf_convert_to_global_offset(Dwarf_Attribute /*attr*/, Dwarf_Off /*offset*/, Dwarf_Off* /*ret_offset*/, Dwarf_Error* /*error*/); /* Get both offsets (local and global) */ int dwarf_die_offsets(Dwarf_Die /*die*/, Dwarf_Off* /*global_offset*/, Dwarf_Off* /*local_offset*/, Dwarf_Error* /*error*/); /* Giving a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug /*dbg*/, const char * /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Giving a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug /*dbg*/, int /*section_index*/, const char ** /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Get section count, of object file sections. */ int dwarf_get_section_count(Dwarf_Debug /*dbg*/); /* Get the version and offset size of a CU context. This is useful as a precursor to calling dwarf_get_form_class() at times. */ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); int dwarf_discr_list(Dwarf_Debug /*dbg*/, Dwarf_Small * /*blockpointer*/, Dwarf_Unsigned /*blocklen*/, Dwarf_Dsc_Head * /*dsc_head_out*/, Dwarf_Unsigned * /*dsc_array_length_out*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Unsigned * /*out_discr_low*/, Dwarf_Unsigned * /*out_discr_high*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Signed * /*out_discr_low*/, Dwarf_Signed * /*out_discr_high*/, Dwarf_Error * /*error*/); /* 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*/, Dwarf_Unsigned * /*section_count_out*/, Dwarf_Unsigned * /*group_count_out*/, Dwarf_Unsigned * /*selected_group_out*/, Dwarf_Unsigned * /*map_entry_count_out*/, Dwarf_Error * /*error*/); /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' 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*/, Dwarf_Unsigned /*map_entry_count*/, Dwarf_Unsigned * /*group_numbers_array*/, Dwarf_Unsigned * /*sec_numbers_array*/, const char ** /*sec_names_array*/, Dwarf_Error * /*error*/); /* dwarf_get_endian_copy_function new. December 2019. */ void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/))(void *, const void * /*src*/, unsigned long /*srclen*/); /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); int dwarf_encode_signed_leb128(Dwarf_Signed /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); /* Record some application command line options in libdwarf. This is not arc/argv processing, just precooked setting of a flag in libdwarf based on something the application wants. check_verbose_mode of TRUE means do more checking and sometimes print errors (from libdwarf). Not restricted to a single Dwarf_Debug, it applies to the libdwarf the executable is using. */ typedef struct { Dwarf_Bool check_verbose_mode; } Dwarf_Cmdline_Options; extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*str_count*/, Dwarf_Unsigned * /*str_total_length*/, Dwarf_Unsigned * /*count_debug_str*/, Dwarf_Unsigned * /*len_debug_str*/, Dwarf_Unsigned * /*reused_count*/, Dwarf_Unsigned * /*reused_len*/, Dwarf_Error * /*error*/); #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ #define DW_FTYPE_MACH_O 2 /* MacOS. */ #define DW_FTYPE_PE 3 /* Windows */ #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ int dwarf_object_detector_path(const char *path, char *outpath, unsigned long, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ dwarfutils-20200114/libdwarf/libdwarf.h.in000066400000000000000000005707021361531463500203150ustar00rootroot00000000000000/* Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef _LIBDWARF_H #define _LIBDWARF_H #ifdef __cplusplus extern "C" { #endif /* libdwarf.h $Revision: #9 $ $Date: 2008/01/17 $ For libdwarf producers and consumers The interface is defined as having 8-byte signed and unsigned values so it can handle 64-or-32bit target on 64-or-32bit host. Dwarf_Ptr is the native size: it represents pointers on the host machine (not the target!). This contains declarations for types and all producer and consumer functions. Function declarations are written on a single line each here so one can use grep to each declaration in its entirety. The declarations are a little harder to read this way, but... The seeming duplication of the Elf typedef allows both verification we have the right struct name (when libelf.h included before this) and creation of a local handle so we have the struct pointer here (if libelf.h is not included before this file). */ typedef struct Elf Elf; typedef struct Elf* dwarf_elf_handle; /* To enable printing with printf regardless of the actual underlying data type, we define the DW_PR_xxx macros. To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want ensure the right DW_PR_XZEROS define is uncommented. */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" typedef unsigned long long Dwarf_Unsigned; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Addr; typedef int Dwarf_Bool; /* boolean type */ typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ /* If sizeof(Dwarf_Half) is greater than 2 we believe libdwarf still works properly. */ #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DSx "I64x" #define DW_PR_DUu "I64u" #define DW_PR_DSd "I64d" #else #define DW_PR_DUx "llx" #define DW_PR_DSx "llx" #define DW_PR_DUu "llu" #define DW_PR_DSd "lld" #endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ /* DWARF5: a container for a DW_FORM_data16 data item. We have no integer types suitable so this special struct is used instead. It is up to consumers/producers to deal with the contents. New October 18, 2017 . */ typedef struct Dwarf_Form_Data16_s { unsigned char fd_data[16]; } Dwarf_Form_Data16; /* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as Dwarf_Unsigned, but that is done inside libdwarf and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; }; typedef struct Dwarf_Sig8_s Dwarf_Sig8; /* Contains info on an uninterpreted block of data Used with certain frame information functions. */ typedef struct { Dwarf_Unsigned bl_len; /* length of block bl_data points at */ Dwarf_Ptr bl_data; /* uninterpreted data */ /* 0 if location description, 1 if .debug_info loclist, 2 if .debug_info.dwo split dwarf loclist. */ Dwarf_Small bl_from_loclist; /* Section (not CU) offset which 'data' comes from. */ Dwarf_Unsigned bl_section_offset; } Dwarf_Block; /* NEW October 2015. */ /* Dwarf_Loc_c_s,Dwarf_Locdesc_c_s, and Dwarf_Loc_Head_c_s are not defined publically. */ struct Dwarf_Loc_c_s; typedef struct Dwarf_Loc_c_s * Dwarf_Loc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Loc_c, a single location operator */ struct Dwarf_Locdesc_c_s; typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c; /* NEW October 2015. */ /* This provides access to Dwarf_Locdesc_c, a single location list entry (or for a locexpr, the fake Loc_Head for the locexpr) */ struct Dwarf_Loc_Head_c_s; typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; /* NEW November 2015. For DWARF5 .debug_macro section */ struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; /* NEW September 2016. Allows easy access to DW_AT_discr_list array of discriminant values. Input in blockpointer is a block with a list of uleb or sleb numbers (all one or the other, lebunsignedflag instructs how to read the leb values properly) */ typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location operator extensions. */ typedef struct { Dwarf_Small lr_atom; /* location operation */ Dwarf_Unsigned lr_number; /* operand */ Dwarf_Unsigned lr_number2; /* for OP_BREGx and DW_OP_GNU_const_type*/ Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */ } Dwarf_Loc; /* Location description. DWARF 2,3,4. When this is from a split-dwarf loclist (.debug_loc.dwo) and no tied object is present then ld_lowpc and ld_highpc are actually indices in the .debug_addr section of the tied object). If there is a tied object then these fields are actuall addresses and DW_AT_addr_base in the skeleton CU DIE applies to that .debug_addr. Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with extensions. If from DWARF2,3,4 non-split dwarf then things operate as in DWARF2. See dwarf_get_loclist_b() and the other related new functions that avoid using public structures Dwarf_Loc and Dwarf_Locdesc. */ typedef struct { /* Beginning of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_lopc; /* End of active range. This is actually an offset of an applicable base address, not a pc value. */ Dwarf_Addr ld_hipc; Dwarf_Half ld_cents; /* count of location records */ Dwarf_Loc* ld_s; /* pointer to list of same */ /* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */ Dwarf_Small ld_from_loclist; Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset where loc-expr begins*/ } Dwarf_Locdesc; /* First appears in DWARF3, and only ranges entries exist. The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or both are zero (DW_RANGES_END). For DWARF5 each table starts with a header followed by range list entries defined as here. */ enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY, DW_RANGES_ADDRESS_SELECTION, DW_RANGES_END }; typedef struct { Dwarf_Addr dwr_addr1; Dwarf_Addr dwr_addr2; enum Dwarf_Ranges_Entry_Type dwr_type; } Dwarf_Ranges; /* Frame description instructions expanded. */ typedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; /* Value may be signed, depends on op. Any applicable data_alignment_factor has not been applied, this is the raw offset. */ Dwarf_Unsigned fp_offset; Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h Preferably identical to DW_FRAME_LAST_REG_NUM. Ensure [0-DW_REG_TABLE_SIZE] does not overlap DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what is appropriate to your cpu. For various CPUs DW_FRAME_UNDEFINED_VAL is correct as the value for DW_FRAME_REG_INITIAL_VALUE. For consumer apps, this can be set dynamically: see dwarf_set_frame_rule_table_size(); */ #ifndef DW_REG_TABLE_SIZE #define DW_REG_TABLE_SIZE 66 #endif /* For MIPS, DW_FRAME_SAME_VAL is the correct default value for a frame register value. For other CPUS another value may be better, such as DW_FRAME_UNDEFINED_VAL. See dwarf_set_frame_rule_table_size */ #ifndef DW_FRAME_REG_INITIAL_VALUE #define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL #endif /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number. Only present at libdwarf runtime in the consumer interfaces. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). */ #define DW_FRAME_SAME_VAL 1035 /* For DWARF3 consumer interfaces, make the CFA a column with no real table number. This is what should have been done for the DWARF2 interfaces. This actually works for both DWARF2 and DWARF3, but see the libdwarf documentation on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_all_regs3() Do NOT use this with the older dwarf_get_fde_info_for_reg() or dwarf_get_fde_info_for_all_regs() consumer interfaces. Must be higher than any register count for *any* ABI (ensures maximum applicability with minimum effort). Ensure this is > DW_REG_TABLE_SIZE (the reg table size is changeable at runtime with the *reg3() interfaces, and this value must be greater than the reg table size). Only present at libdwarf runtime in the consumer interfaces. Never on disk. */ #define DW_FRAME_CFA_COL3 1436 /* The following are all needed to evaluate DWARF3 register rules. */ #define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */ #define DW_EXPR_VAL_OFFSET 1 #define DW_EXPR_EXPRESSION 2 #define DW_EXPR_VAL_EXPRESSION 3 typedef struct Dwarf_Regtable_Entry_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(F) Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; /* For DWARF2, always 0 */ Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; /* The data type here should the larger of Dwarf_Addr and Dwarf_Unsigned and Dwarf_Signed. */ Dwarf_Addr dw_offset; } Dwarf_Regtable_Entry; typedef struct Dwarf_Regtable_s { struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; /* opaque type. Functional interface shown later. */ struct Dwarf_Reg_value3_s; typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; typedef struct Dwarf_Regtable_Entry3_s { /* For each index i (naming a hardware register with dwarf number i) the following is true and defines the value of that register: If dw_regnum is Register DW_FRAME_UNDEFINED_VAL it is not DWARF register number but a place holder indicating the register has no defined value. If dw_regnum is Register DW_FRAME_SAME_VAL it is not DWARF register number but a place holder indicating the register has the same value in the previous frame. DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and DW_FRAME_CFA_COL3 are only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL and DW_FRAME_CFA_COL3 are definable at runtime consider the names symbolic in this comment, not absolute. Otherwise: the register number is a DWARF register number (see ABI documents for how this translates to hardware/ software register numbers in the machine hardware) and the following applies: In a cfa-defining entry (rt3_cfa_rule) the regnum is the CFA 'register number'. Which is some 'normal' register, not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor DW_FRAME_UNDEFINED_VAL. If dw_value_type == DW_EXPR_OFFSET (the only possible case for dwarf2): If dw_offset_relevant is non-zero, then the value is stored at at the address CFA+N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. So dw_offset_or_block_len is a signed value, really, and must be printed/evaluated as such. Rule: Offset(N) If dw_offset_relevant is zero, then the value of the register is the value of (DWARF) register number dw_regnum. Rule: register(R) If dw_value_type == DW_EXPR_VAL_OFFSET the value of this register is CFA +N where N is a signed offset. dw_regnum is the cfa register rule which means one ignores dw_regnum and uses the CFA appropriately. Rule: val_offset(N) If dw_value_type == DW_EXPR_EXPRESSION The value of the register is the value at the address computed by evaluating the DWARF expression E. Rule: expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. If dw_value_type == DW_EXPR_VAL_EXPRESSION The value of the register is the value computed by evaluating the DWARF expression E. Rule: val_expression(E) The expression E byte stream is pointed to by dw_block_ptr. The expression length in bytes is given by dw_offset_or_block_len. Other values of dw_value_type are an error. */ Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; /* For the DWARF3 version, moved the DW_FRAME_CFA_COL out of the array and into its own struct. Having it part of the array is not very easy to work with from a portability point of view: changing the number for every architecture is a pain (if one fails to set it correctly a register rule gets clobbered when setting CFA). With MIPS it just happened to be easy to use DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...). rt3_rules and rt3_reg_table_size must be filled in before calling libdwarf. Filled in with a pointer to an array (pointer and array set up by the calling application) of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs. libdwarf does not allocate or deallocate space for the rules, you must do so. libdwarf will initialize the contents rules array, you do not need to do so (though if you choose to initialize the array somehow that is ok: libdwarf will overwrite your initializations with its own). */ typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3; /* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. Returns DW_DLV_OK if the value is available. If DW_DLV_OK returns the regnum and offset thru the pointers (which the consumer must use appropriately). */ int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Small *offset_relevant, Dwarf_Half *regnum_out, Dwarf_Signed *offset_out); /* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION. Returns DW_DLV_OK if the value is available. The caller must pass in the address of a valid Dwarf_Block (the caller need not initialize it). */ int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in, Dwarf_Block *block_out); /* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller v2, adding drd_length: some relocations are 4 and some 8 bytes (pointers are 8, section offsets 4) in some dwarf environments. (MIPS relocations are all one size in any given ABI.) Changing drd_type to an unsigned char to keep struct size down. */ enum Dwarf_Rel_Type { dwarf_drt_none, /* Should not get to caller */ dwarf_drt_data_reloc, /* Simple normal relocation. */ dwarf_drt_segment_rel, /* Special reloc, exceptions. */ /* dwarf_drt_first_of_length_pair and drt_second are for for the .word end - begin case. */ dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker; struct Dwarf_P_Marker_s { Dwarf_Unsigned ma_marker; Dwarf_Unsigned ma_offset; }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type to keep size small in struct. */ unsigned char drd_length; /* Length in bytes of data being relocated. 4 for 32bit data, 8 for 64bit data. */ Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */ Dwarf_Unsigned drd_symbol_index; }; typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr; struct Dwarf_P_String_Attr_s { Dwarf_Unsigned sa_offset; /* Offset of string attribute data */ Dwarf_Unsigned sa_nbytes; }; /* Opaque types for Consumer Library. */ typedef struct Dwarf_Debug_s* Dwarf_Debug; typedef struct Dwarf_Die_s* Dwarf_Die; typedef struct Dwarf_Line_s* Dwarf_Line; typedef struct Dwarf_Global_s* Dwarf_Global; typedef struct Dwarf_Func_s* Dwarf_Func; typedef struct Dwarf_Type_s* Dwarf_Type; typedef struct Dwarf_Var_s* Dwarf_Var; typedef struct Dwarf_Weak_s* Dwarf_Weak; typedef struct Dwarf_Error_s* Dwarf_Error; typedef struct Dwarf_Attribute_s* Dwarf_Attribute; typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev; typedef struct Dwarf_Fde_s* Dwarf_Fde; typedef struct Dwarf_Cie_s* Dwarf_Cie; typedef struct Dwarf_Arange_s* Dwarf_Arange; typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex; struct Dwarf_Xu_Index_Header_s; typedef struct Dwarf_Xu_Index_Header_s* Dwarf_Xu_Index_Header; struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; struct Dwarf_Dnames_Head_s; typedef struct Dwarf_Dnames_Head_s* Dwarf_Dnames_Head; /* Opaque types for Producer Library. */ typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug; typedef struct Dwarf_P_Die_s* Dwarf_P_Die; typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute; typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde; typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr; typedef Dwarf_Unsigned Dwarf_Tag; /* error handler function */ typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); /* Begin libdwarf Object File Interface declarations. As of February 2008 there are multiple dwarf_reader object access initialization methods available: The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish() which assume libelf and POSIX file access. An object-file and library agnostic dwarf_object_init() and dwarf_object_finish() which allow the coder to provide object access routines abstracting away the elf interface. So there is no dependence in the reader code on the object format and no dependence on libelf. See the code in dwarf_elf_access.c and dwarf_original_elf_init.c to see an example of initializing the structures mentioned below. Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. As of March 2017 additional functions dwarf_elf_init_b and dwarf_init_b and dwarf_object_init_b add a groupnumber argument so DWARF5 split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods; typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section; /* Used in the get_section interface function in Dwarf_Obj_Access_Section_s. Since libdwarf depends on standard DWARF section names an object format that has no such names (but has some method of setting up 'sections equivalents') must arrange to return standard DWARF section names in the 'name' field. libdwarf does not free the strings in 'name'. */ struct Dwarf_Obj_Access_Section_s { /* addr is the virtual address of the first byte of the section data. Usually zero when the address makes no sense for a given section. */ Dwarf_Addr addr; /* Section type. */ Dwarf_Unsigned type; /* Size in bytes of the section. */ Dwarf_Unsigned size; /* Having an accurate section name makes debugging of libdwarf easier. and is essential to find the .debug_ sections. */ const char* name; /* Set link to zero if it is meaningless. If non-zero it should be a link to a rela section or from symtab to strtab. In Elf it is sh_link. */ Dwarf_Unsigned link; /* The section header index of the section to which the relocation applies. In Elf it is sh_info. */ Dwarf_Unsigned info; /* Elf sections that are tables have a non-zero entrysize so the count of entries can be calculated even without the right structure definition. If your object format does not have this data leave this zero. */ Dwarf_Unsigned entrysize; }; /* Returned by the get_endianness function in Dwarf_Obj_Access_Methods_s. */ typedef enum { DW_OBJECT_MSB, DW_OBJECT_LSB } Dwarf_Endianness; /* The functions we need to access object data from libdwarf are declared here. In these function pointer declarations 'void *obj' is intended to be a pointer (the object field in Dwarf_Obj_Access_Interface_s) that hides the library-specific and object-specific data that makes it possible to handle multiple object formats and multiple libraries. It's not required that one handles multiple such in a single libdwarf archive/shared-library (but not ruled out either). See dwarf_elf_object_access_internals_t and dwarf_elf_access.c for an example. */ struct Dwarf_Obj_Access_Methods_s { /* get_section_info Get address, size, and name info about a section. Parameters section_index - Zero-based index. return_section - Pointer to a structure in which section info will be placed. Caller must provide a valid pointer to a structure area. The structure's contents will be overwritten by the call to get_section_info. error - A pointer to an integer in which an error code may be stored. Return DW_DLV_OK - Everything ok. DW_DLV_ERROR - Error occurred. Use 'error' to determine the libdwarf defined error. DW_DLV_NO_ENTRY - No such section. */ int (*get_section_info)(void* obj, Dwarf_Half section_index, Dwarf_Obj_Access_Section* return_section, int* error); /* get_byte_order Get whether the object file represented by this interface is big-endian (DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB). Parameters obj - Equivalent to 'this' in OO languages. Return Endianness of object. Cannot fail. */ Dwarf_Endianness (*get_byte_order)(void* obj); /* get_length_size Get the size of a length field in the underlying object file. libdwarf currently supports * 4 and 8 byte sizes, but may support larger in the future. Perhaps the return type should be an enumeration? Parameters obj - Equivalent to 'this' in OO languages. Return Size of length. Cannot fail. */ Dwarf_Small (*get_length_size)(void* obj); /* get_pointer_size Get the size of a pointer field in the underlying object file. libdwarf currently supports 4 and 8 byte sizes. Perhaps the return type should be an enumeration? Return Size of pointer. Cannot fail. */ Dwarf_Small (*get_pointer_size)(void* obj); /* get_section_count Get the number of sections in the object file. Parameters Return Number of sections */ Dwarf_Unsigned (*get_section_count)(void* obj); /* load_section Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index. return_data - The address of a pointer to which the section data block will be assigned. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*load_section)(void* obj, Dwarf_Half section_index, Dwarf_Small** return_data, int* error); /** relocate_a_section If relocations are not supported leave this pointer NULL. Get a pointer to an array of bytes that represent the section. Parameters section_index - Zero-based index of the section to be relocated. error - Pointer to an integer for returning libdwarf-defined error numbers. Return DW_DLV_OK - No error. DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined error number. DW_DLV_NO_ENTRY - No such section. */ int (*relocate_a_section)(void* obj, Dwarf_Half section_index, Dwarf_Debug dbg, int* error); }; /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface [dwarf_object_init and dwarf_object_finish)] directly. dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. */ struct Dwarf_Obj_Access_Interface_s { /* object is a void* as it hides the data the object access routines need (which varies by library in use and object format). */ void* object; const Dwarf_Obj_Access_Methods * methods; }; /* End libdwarf Object File Interface */ /* Dwarf_dealloc() alloc_type arguments. Argument points to: */ #define DW_DLA_STRING 0x01 /* char* */ #define DW_DLA_LOC 0x02 /* Dwarf_Loc */ #define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */ #define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/ #define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */ #define DW_DLA_BLOCK 0x06 /* Dwarf_Block */ #define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */ #define DW_DLA_DIE 0x08 /* Dwarf_Die */ #define DW_DLA_LINE 0x09 /* Dwarf_Line */ #define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */ #define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */ #define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */ #define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */ #define DW_DLA_ERROR 0x0e /* Dwarf_Error */ #define DW_DLA_LIST 0x0f /* a list */ #define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */ #define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */ #define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */ #define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */ #define DW_DLA_CIE 0x14 /* Dwarf_Cie */ #define DW_DLA_FDE 0x15 /* Dwarf_Fde */ #define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */ #define DW_DLA_FRAME_BLOCK 0x17 /* Dwarf_Frame Block (not used) */ #define DW_DLA_FUNC 0x18 /* Dwarf_Func */ #define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */ #define DW_DLA_VAR 0x1a /* Dwarf_Var */ #define DW_DLA_WEAK 0x1b /* Dwarf_Weak */ #define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */ #define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */ /* 0x1e (30) to 0x36 (54) reserved for internal to libdwarf types. */ #define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */ #define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */ #define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/ #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ /* 0x3d (61) is for libdwarf internal use. */ #define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ #define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ #define DW_DLA_STR_OFFSETS 0x40 /* struct Dwarf_Str_Offsets_Table_s */ /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" /* dwarf_init() access arguments */ #define DW_DLC_READ 0 /* read only access */ #define DW_DLC_WRITE 1 /* write only access */ #define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ /* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed. If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not set 32bit offset DWARF is assumed. Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS and handle the relocation creation for the target itself using the symbolic relocations to do so, those use the Dwarf_Rel_Type enum relocation indicators. */ /* The first three are traditional dwarf producer names. These names still work. Newer names below. */ /* 64-bit address-size target */ #define DW_DLC_SIZE_64 0x40000000 /* 32-bit address-size target */ #define DW_DLC_SIZE_32 0x20000000 /* 64-bit offset-size DWARF offsets (else 32bit) */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* 32-bit offset-size ELF object (ELFCLASS32) */ #define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* 64-bit offset-size ELF object (ELFCLASS64) */ #define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* dwarf_producer_init* access flag modifiers Some new April 2014. If DW_DLC_STREAM_RELOCATIONS is set the DW_DLC_ISA_* flags are ignored. See the Dwarf_Rel_Type enum. */ /* Old style Elf binary relocation (.rel) records. The default. */ #define DW_DLC_STREAM_RELOCATIONS 0x02000000 /* use 32-bit sec offsets */ #define DW_DLC_OFFSET32 0x00010000 /* The following 3 are new sensible names. Old names above with same values. */ /* use 64-bit sec offsets in ELF */ #define DW_DLC_OFFSET64 0x10000000 /* use 4 for address_size */ #define DW_DLC_POINTER32 0x20000000 /* use 8 for address_size */ #define DW_DLC_POINTER64 0x40000000 /* Special for IRIX only */ /* use Elf 64bit offset headers and non-std IRIX 64bitoffset headers */ #define DW_DLC_IRIX_OFFSET64 0x00200000 /* Usable with assembly output because it is up to the producer to deal with locations in whatever manner the calling producer code wishes. For example, when the libdwarf caller wishes to produce relocations differently than the binary relocation bits that libdwarf Stream Relocations generate. */ #define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 #define DW_DLC_TARGET_BIGENDIAN 0x08000000 /* Big endian target */ #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* Little endian target */ /* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ #define DW_DLS_FORWARD 1 /* slide forward to find line */ /* libdwarf error numbers */ #define DW_DLE_NE 0 /* no error */ #define DW_DLE_VMM 1 /* dwarf format/library version mismatch */ #define DW_DLE_MAP 2 /* memory map failure */ #define DW_DLE_LEE 3 /* libelf error */ #define DW_DLE_NDS 4 /* no debug section */ #define DW_DLE_NLS 5 /* no line section */ #define DW_DLE_ID 6 /* invalid descriptor for query */ #define DW_DLE_IOF 7 /* I/O failure */ #define DW_DLE_MAF 8 /* memory allocation failure */ #define DW_DLE_IA 9 /* invalid argument */ #define DW_DLE_MDE 10 /* mangled debugging entry */ #define DW_DLE_MLE 11 /* mangled line number entry */ #define DW_DLE_FNO 12 /* file not open */ #define DW_DLE_FNR 13 /* file not a regular file */ #define DW_DLE_FWA 14 /* file open with wrong access */ #define DW_DLE_NOB 15 /* not an object file */ #define DW_DLE_MOF 16 /* mangled object file header */ #define DW_DLE_EOLL 17 /* end of location list entries */ #define DW_DLE_NOLL 18 /* no location list section */ #define DW_DLE_BADOFF 19 /* Invalid offset */ #define DW_DLE_EOS 20 /* end of section */ #define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/ #define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/ /* It is not an allowed size (64 or 32) */ /* Error codes defined by the current Libdwarf Implementation. */ #define DW_DLE_DBG_ALLOC 23 #define DW_DLE_FSTAT_ERROR 24 #define DW_DLE_FSTAT_MODE_ERROR 25 #define DW_DLE_INIT_ACCESS_WRONG 26 #define DW_DLE_ELF_BEGIN_ERROR 27 #define DW_DLE_ELF_GETEHDR_ERROR 28 #define DW_DLE_ELF_GETSHDR_ERROR 29 #define DW_DLE_ELF_STRPTR_ERROR 30 #define DW_DLE_DEBUG_INFO_DUPLICATE 31 #define DW_DLE_DEBUG_INFO_NULL 32 #define DW_DLE_DEBUG_ABBREV_DUPLICATE 33 #define DW_DLE_DEBUG_ABBREV_NULL 34 #define DW_DLE_DEBUG_ARANGES_DUPLICATE 35 #define DW_DLE_DEBUG_ARANGES_NULL 36 #define DW_DLE_DEBUG_LINE_DUPLICATE 37 #define DW_DLE_DEBUG_LINE_NULL 38 #define DW_DLE_DEBUG_LOC_DUPLICATE 39 #define DW_DLE_DEBUG_LOC_NULL 40 #define DW_DLE_DEBUG_MACINFO_DUPLICATE 41 #define DW_DLE_DEBUG_MACINFO_NULL 42 #define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43 #define DW_DLE_DEBUG_PUBNAMES_NULL 44 #define DW_DLE_DEBUG_STR_DUPLICATE 45 #define DW_DLE_DEBUG_STR_NULL 46 #define DW_DLE_CU_LENGTH_ERROR 47 #define DW_DLE_VERSION_STAMP_ERROR 48 #define DW_DLE_ABBREV_OFFSET_ERROR 49 #define DW_DLE_ADDRESS_SIZE_ERROR 50 #define DW_DLE_DEBUG_INFO_PTR_NULL 51 #define DW_DLE_DIE_NULL 52 #define DW_DLE_STRING_OFFSET_BAD 53 #define DW_DLE_DEBUG_LINE_LENGTH_BAD 54 #define DW_DLE_LINE_PROLOG_LENGTH_BAD 55 #define DW_DLE_LINE_NUM_OPERANDS_BAD 56 #define DW_DLE_LINE_SET_ADDR_ERROR 57 /* No longer used. */ #define DW_DLE_LINE_EXT_OPCODE_BAD 58 #define DW_DLE_DWARF_LINE_NULL 59 #define DW_DLE_INCL_DIR_NUM_BAD 60 #define DW_DLE_LINE_FILE_NUM_BAD 61 #define DW_DLE_ALLOC_FAIL 62 #define DW_DLE_NO_CALLBACK_FUNC 63 #define DW_DLE_SECT_ALLOC 64 #define DW_DLE_FILE_ENTRY_ALLOC 65 #define DW_DLE_LINE_ALLOC 66 #define DW_DLE_FPGM_ALLOC 67 #define DW_DLE_INCDIR_ALLOC 68 #define DW_DLE_STRING_ALLOC 69 #define DW_DLE_CHUNK_ALLOC 70 #define DW_DLE_BYTEOFF_ERR 71 #define DW_DLE_CIE_ALLOC 72 #define DW_DLE_FDE_ALLOC 73 #define DW_DLE_REGNO_OVFL 74 #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 #define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 #define DW_DLE_DEBUGLINE_ERROR 82 #define DW_DLE_DEBUGFRAME_ERROR 83 #define DW_DLE_DEBUGINFO_ERROR 84 #define DW_DLE_ATTR_ALLOC 85 #define DW_DLE_ABBREV_ALLOC 86 #define DW_DLE_OFFSET_UFLW 87 #define DW_DLE_ELF_SECT_ERR 88 #define DW_DLE_DEBUG_FRAME_LENGTH_BAD 89 #define DW_DLE_FRAME_VERSION_BAD 90 #define DW_DLE_CIE_RET_ADDR_REG_ERROR 91 #define DW_DLE_FDE_NULL 92 #define DW_DLE_FDE_DBG_NULL 93 #define DW_DLE_CIE_NULL 94 #define DW_DLE_CIE_DBG_NULL 95 #define DW_DLE_FRAME_TABLE_COL_BAD 96 #define DW_DLE_PC_NOT_IN_FDE_RANGE 97 #define DW_DLE_CIE_INSTR_EXEC_ERROR 98 #define DW_DLE_FRAME_INSTR_EXEC_ERROR 99 #define DW_DLE_FDE_PTR_NULL 100 #define DW_DLE_RET_OP_LIST_NULL 101 #define DW_DLE_LINE_CONTEXT_NULL 102 #define DW_DLE_DBG_NO_CU_CONTEXT 103 #define DW_DLE_DIE_NO_CU_CONTEXT 104 #define DW_DLE_FIRST_DIE_NOT_CU 105 #define DW_DLE_NEXT_DIE_PTR_NULL 106 #define DW_DLE_DEBUG_FRAME_DUPLICATE 107 #define DW_DLE_DEBUG_FRAME_NULL 108 #define DW_DLE_ABBREV_DECODE_ERROR 109 #define DW_DLE_DWARF_ABBREV_NULL 110 #define DW_DLE_ATTR_NULL 111 #define DW_DLE_DIE_BAD 112 #define DW_DLE_DIE_ABBREV_BAD 113 #define DW_DLE_ATTR_FORM_BAD 114 #define DW_DLE_ATTR_NO_CU_CONTEXT 115 #define DW_DLE_ATTR_FORM_SIZE_BAD 116 #define DW_DLE_ATTR_DBG_NULL 117 #define DW_DLE_BAD_REF_FORM 118 #define DW_DLE_ATTR_FORM_OFFSET_BAD 119 #define DW_DLE_LINE_OFFSET_BAD 120 #define DW_DLE_DEBUG_STR_OFFSET_BAD 121 #define DW_DLE_STRING_PTR_NULL 122 #define DW_DLE_PUBNAMES_VERSION_ERROR 123 #define DW_DLE_PUBNAMES_LENGTH_BAD 124 #define DW_DLE_GLOBAL_NULL 125 #define DW_DLE_GLOBAL_CONTEXT_NULL 126 #define DW_DLE_DIR_INDEX_BAD 127 #define DW_DLE_LOC_EXPR_BAD 128 #define DW_DLE_DIE_LOC_EXPR_BAD 129 #define DW_DLE_ADDR_ALLOC 130 #define DW_DLE_OFFSET_BAD 131 #define DW_DLE_MAKE_CU_CONTEXT_FAIL 132 #define DW_DLE_REL_ALLOC 133 #define DW_DLE_ARANGE_OFFSET_BAD 134 #define DW_DLE_SEGMENT_SIZE_BAD 135 #define DW_DLE_ARANGE_LENGTH_BAD 136 #define DW_DLE_ARANGE_DECODE_ERROR 137 #define DW_DLE_ARANGES_NULL 138 #define DW_DLE_ARANGE_NULL 139 #define DW_DLE_NO_FILE_NAME 140 #define DW_DLE_NO_COMP_DIR 141 #define DW_DLE_CU_ADDRESS_SIZE_BAD 142 #define DW_DLE_INPUT_ATTR_BAD 143 #define DW_DLE_EXPR_NULL 144 #define DW_DLE_BAD_EXPR_OPCODE 145 #define DW_DLE_EXPR_LENGTH_BAD 146 #define DW_DLE_MULTIPLE_RELOC_IN_EXPR 147 #define DW_DLE_ELF_GETIDENT_ERROR 148 #define DW_DLE_NO_AT_MIPS_FDE 149 #define DW_DLE_NO_CIE_FOR_FDE 150 #define DW_DLE_DIE_ABBREV_LIST_NULL 151 #define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE 152 #define DW_DLE_DEBUG_FUNCNAMES_NULL 153 #define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR 154 #define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD 155 #define DW_DLE_FUNC_NULL 156 #define DW_DLE_FUNC_CONTEXT_NULL 157 #define DW_DLE_DEBUG_TYPENAMES_DUPLICATE 158 #define DW_DLE_DEBUG_TYPENAMES_NULL 159 #define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR 160 #define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD 161 #define DW_DLE_TYPE_NULL 162 #define DW_DLE_TYPE_CONTEXT_NULL 163 #define DW_DLE_DEBUG_VARNAMES_DUPLICATE 164 #define DW_DLE_DEBUG_VARNAMES_NULL 165 #define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR 166 #define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD 167 #define DW_DLE_VAR_NULL 168 #define DW_DLE_VAR_CONTEXT_NULL 169 #define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE 170 #define DW_DLE_DEBUG_WEAKNAMES_NULL 171 #define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR 172 #define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD 173 #define DW_DLE_WEAK_NULL 174 #define DW_DLE_WEAK_CONTEXT_NULL 175 #define DW_DLE_LOCDESC_COUNT_WRONG 176 #define DW_DLE_MACINFO_STRING_NULL 177 #define DW_DLE_MACINFO_STRING_EMPTY 178 #define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE 179 #define DW_DLE_MACINFO_MALLOC_FAIL 180 #define DW_DLE_DEBUGMACINFO_ERROR 181 #define DW_DLE_DEBUG_MACRO_LENGTH_BAD 182 #define DW_DLE_DEBUG_MACRO_MAX_BAD 183 #define DW_DLE_DEBUG_MACRO_INTERNAL_ERR 184 #define DW_DLE_DEBUG_MACRO_MALLOC_SPACE 185 #define DW_DLE_DEBUG_MACRO_INCONSISTENT 186 #define DW_DLE_DF_NO_CIE_AUGMENTATION 187 #define DW_DLE_DF_REG_NUM_TOO_HIGH 188 #define DW_DLE_DF_MAKE_INSTR_NO_INIT 189 #define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC 190 #define DW_DLE_DF_POP_EMPTY_STACK 191 #define DW_DLE_DF_ALLOC_FAIL 192 #define DW_DLE_DF_FRAME_DECODING_ERROR 193 #define DW_DLE_DEBUG_LOC_SECTION_SHORT 194 #define DW_DLE_FRAME_AUGMENTATION_UNKNOWN 195 #define DW_DLE_PUBTYPE_CONTEXT 196 /* Unused. */ #define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD 197 #define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR 198 #define DW_DLE_DEBUG_PUBTYPES_DUPLICATE 199 #define DW_DLE_FRAME_CIE_DECODE_ERROR 200 #define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE 201 #define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH 202 #define DW_DLE_LINK_LOOP 203 #define DW_DLE_STRP_OFFSET_BAD 204 #define DW_DLE_DEBUG_RANGES_DUPLICATE 205 #define DW_DLE_DEBUG_RANGES_OFFSET_BAD 206 #define DW_DLE_DEBUG_RANGES_MISSING_END 207 #define DW_DLE_DEBUG_RANGES_OUT_OF_MEM 208 #define DW_DLE_DEBUG_SYMTAB_ERR 209 #define DW_DLE_DEBUG_STRTAB_ERR 210 #define DW_DLE_RELOC_MISMATCH_INDEX 211 #define DW_DLE_RELOC_MISMATCH_RELOC_INDEX 212 #define DW_DLE_RELOC_MISMATCH_STRTAB_INDEX 213 #define DW_DLE_RELOC_SECTION_MISMATCH 214 #define DW_DLE_RELOC_SECTION_MISSING_INDEX 215 #define DW_DLE_RELOC_SECTION_LENGTH_ODD 216 #define DW_DLE_RELOC_SECTION_PTR_NULL 217 #define DW_DLE_RELOC_SECTION_MALLOC_FAIL 218 #define DW_DLE_NO_ELF64_SUPPORT 219 #define DW_DLE_MISSING_ELF64_SUPPORT 220 #define DW_DLE_ORPHAN_FDE 221 #define DW_DLE_DUPLICATE_INST_BLOCK 222 #define DW_DLE_BAD_REF_SIG8_FORM 223 #define DW_DLE_ATTR_EXPRLOC_FORM_BAD 224 #define DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD 225 #define DW_DLE_NOT_REF_FORM 226 #define DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE 227 #define DW_DLE_REF_SIG8_NOT_HANDLED 228 #define DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH 229 #define DW_DLE_LOC_BAD_TERMINATION 230 #define DW_DLE_SYMTAB_SECTION_LENGTH_ODD 231 #define DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD 232 #define DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN 233 #define DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO 234 #define DW_DLE_LINE_NUMBER_HEADER_ERROR 235 #define DW_DLE_DEBUG_TYPES_NULL 236 #define DW_DLE_DEBUG_TYPES_DUPLICATE 237 #define DW_DLE_DEBUG_TYPES_ONLY_DWARF4 238 #define DW_DLE_DEBUG_TYPEOFFSET_BAD 239 #define DW_DLE_GNU_OPCODE_ERROR 240 #define DW_DLE_DEBUGPUBTYPES_ERROR 241 #define DW_DLE_AT_FIXUP_NULL 242 #define DW_DLE_AT_FIXUP_DUP 243 #define DW_DLE_BAD_ABINAME 244 #define DW_DLE_TOO_MANY_DEBUG 245 #define DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE 246 #define DW_DLE_SECTION_DUPLICATION 247 #define DW_DLE_SECTION_ERROR 248 #define DW_DLE_DEBUG_ADDR_DUPLICATE 249 #define DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM 250 #define DW_DLE_DEBUG_FORM_HANDLING_INCOMPLETE 251 #define DW_DLE_NEXT_DIE_PAST_END 252 #define DW_DLE_NEXT_DIE_WRONG_FORM 253 #define DW_DLE_NEXT_DIE_NO_ABBREV_LIST 254 #define DW_DLE_NESTED_FORM_INDIRECT_ERROR 255 #define DW_DLE_CU_DIE_NO_ABBREV_LIST 256 #define DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION 257 #define DW_DLE_ATTR_FORM_NOT_ADDR_INDEX 258 #define DW_DLE_ATTR_FORM_NOT_STR_INDEX 259 #define DW_DLE_DUPLICATE_GDB_INDEX 260 #define DW_DLE_ERRONEOUS_GDB_INDEX_SECTION 261 #define DW_DLE_GDB_INDEX_COUNT_ERROR 262 #define DW_DLE_GDB_INDEX_COUNT_ADDR_ERROR 263 #define DW_DLE_GDB_INDEX_INDEX_ERROR 264 #define DW_DLE_GDB_INDEX_CUVEC_ERROR 265 #define DW_DLE_DUPLICATE_CU_INDEX 266 #define DW_DLE_DUPLICATE_TU_INDEX 267 #define DW_DLE_XU_TYPE_ARG_ERROR 268 #define DW_DLE_XU_IMPOSSIBLE_ERROR 269 #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 /* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 #define DW_DLE_FUNCNAMES_ERROR 276 #define DW_DLE_TYPENAMES_ERROR 277 #define DW_DLE_VARNAMES_ERROR 278 #define DW_DLE_WEAKNAMES_ERROR 279 #define DW_DLE_RELOCS_ERROR 280 #define DW_DLE_ATTR_OUTSIDE_SECTION 281 #define DW_DLE_FISSION_INDEX_WRONG 282 #define DW_DLE_FISSION_VERSION_ERROR 283 #define DW_DLE_NEXT_DIE_LOW_ERROR 284 #define DW_DLE_CU_UT_TYPE_ERROR 285 #define DW_DLE_NO_SUCH_SIGNATURE_FOUND 286 #define DW_DLE_SIGNATURE_SECTION_NUMBER_WRONG 287 #define DW_DLE_ATTR_FORM_NOT_DATA8 288 #define DW_DLE_SIG_TYPE_WRONG_STRING 289 #define DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH 290 #define DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH 291 #define DW_DLE_DWP_MISSING_DWO_ID 292 #define DW_DLE_DWP_SIBLING_ERROR 293 #define DW_DLE_DEBUG_FISSION_INCOMPLETE 294 #define DW_DLE_FISSION_SECNUM_ERR 295 #define DW_DLE_DEBUG_MACRO_DUPLICATE 296 #define DW_DLE_DEBUG_NAMES_DUPLICATE 297 #define DW_DLE_DEBUG_LINE_STR_DUPLICATE 298 #define DW_DLE_DEBUG_SUP_DUPLICATE 299 #define DW_DLE_NO_SIGNATURE_TO_LOOKUP 300 #define DW_DLE_NO_TIED_ADDR_AVAILABLE 301 #define DW_DLE_NO_TIED_SIG_AVAILABLE 302 #define DW_DLE_STRING_NOT_TERMINATED 303 #define DW_DLE_BAD_LINE_TABLE_OPERATION 304 #define DW_DLE_LINE_CONTEXT_BOTCH 305 #define DW_DLE_LINE_CONTEXT_INDEX_WRONG 306 #define DW_DLE_NO_TIED_STRING_AVAILABLE 307 #define DW_DLE_NO_TIED_FILE_AVAILABLE 308 #define DW_DLE_CU_TYPE_MISSING 309 #define DW_DLE_LLE_CODE_UNKNOWN 310 #define DW_DLE_LOCLIST_INTERFACE_ERROR 311 #define DW_DLE_LOCLIST_INDEX_ERROR 312 #define DW_DLE_INTERFACE_NOT_SUPPORTED 313 #define DW_DLE_ZDEBUG_REQUIRES_ZLIB 314 #define DW_DLE_ZDEBUG_INPUT_FORMAT_ODD 315 #define DW_DLE_ZLIB_BUF_ERROR 316 #define DW_DLE_ZLIB_DATA_ERROR 317 #define DW_DLE_MACRO_OFFSET_BAD 318 #define DW_DLE_MACRO_OPCODE_BAD 319 #define DW_DLE_MACRO_OPCODE_FORM_BAD 320 #define DW_DLE_UNKNOWN_FORM 321 #define DW_DLE_BAD_MACRO_HEADER_POINTER 322 #define DW_DLE_BAD_MACRO_INDEX 323 #define DW_DLE_MACRO_OP_UNHANDLED 324 #define DW_DLE_MACRO_PAST_END 325 #define DW_DLE_LINE_STRP_OFFSET_BAD 326 #define DW_DLE_STRING_FORM_IMPROPER 327 #define DW_DLE_ELF_FLAGS_NOT_AVAILABLE 328 #define DW_DLE_LEB_IMPROPER 329 #define DW_DLE_DEBUG_LINE_RANGE_ZERO 330 #define DW_DLE_READ_LITTLEENDIAN_ERROR 331 #define DW_DLE_READ_BIGENDIAN_ERROR 332 #define DW_DLE_RELOC_INVALID 333 #define DW_DLE_INFO_HEADER_ERROR 334 #define DW_DLE_ARANGES_HEADER_ERROR 335 #define DW_DLE_LINE_OFFSET_WRONG_FORM 336 #define DW_DLE_FORM_BLOCK_LENGTH_ERROR 337 #define DW_DLE_ZLIB_SECTION_SHORT 338 #define DW_DLE_CIE_INSTR_PTR_ERROR 339 #define DW_DLE_FDE_INSTR_PTR_ERROR 340 #define DW_DLE_FISSION_ADDITION_ERROR 341 #define DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE 342 #define DW_DLE_LOCEXPR_OFF_SECTION_END 343 #define DW_DLE_POINTER_SECTION_UNKNOWN 344 #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 #define DW_DLE_SIZE_WRAPAROUND 348 #define DW_DLE_ILLOGICAL_TSEARCH 349 #define DW_DLE_BAD_STRING_FORM 350 #define DW_DLE_DEBUGSTR_ERROR 351 #define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 #define DW_DLE_DISCR_ARRAY_ERROR 353 #define DW_DLE_LEB_OUT_ERROR 354 #define DW_DLE_SIBLING_LIST_IMPROPER 355 #define DW_DLE_LOCLIST_OFFSET_BAD 356 #define DW_DLE_LINE_TABLE_BAD 357 #define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 #define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 #define DW_DLE_ABBREV_OFF_END 360 #define DW_DLE_FORM_STRING_BAD_STRING 361 #define DW_DLE_AUGMENTATION_STRING_OFF_END 362 #define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 #define DW_DLE_LINE_STRING_BAD 364 #define DW_DLE_DEFINE_FILE_STRING_BAD 365 #define DW_DLE_MACRO_STRING_BAD 366 #define DW_DLE_MACINFO_STRING_BAD 367 #define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 #define DW_DLE_IMPROPER_DWO_ID 369 #define DW_DLE_GROUPNUMBER_ERROR 370 #define DW_DLE_ADDRESS_SIZE_ZERO 371 #define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 #define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 #define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 #define DW_DLE_DEBUG_NAMES_OFF_END 375 #define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 #define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 #define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 #define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 #define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 #define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 #define DW_DLE_LNCT_CODE_UNKNOWN 382 #define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 #define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 #define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 #define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 #define DW_DLE_GROUP_MAP_ALLOC 387 #define DW_DLE_GROUP_MAP_DUPLICATE 388 #define DW_DLE_GROUP_COUNT_ERROR 389 #define DW_DLE_GROUP_INTERNAL_ERROR 390 #define DW_DLE_GROUP_LOAD_ERROR 391 #define DW_DLE_GROUP_LOAD_READ_ERROR 392 #define DW_DLE_AUG_DATA_LENGTH_BAD 393 #define DW_DLE_ABBREV_MISSING 394 #define DW_DLE_NO_TAG_FOR_DIE 395 #define DW_DLE_LOWPC_WRONG_CLASS 396 #define DW_DLE_HIGHPC_WRONG_FORM 397 #define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 #define DW_DLE_DATA16_OUTSIDE_SECTION 399 #define DW_DLE_LNCT_MD5_WRONG_FORM 400 #define DW_DLE_LINE_HEADER_CORRUPT 401 #define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 #define DW_DLE_STR_OFFSETS_NULL_DBG 403 #define DW_DLE_STR_OFFSETS_NO_MAGIC 404 #define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 #define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 #define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 #define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 #define DW_DLE_DUP_ATTR_ON_DIE 409 #define DW_DLE_SECTION_NAME_BIG 410 #define DW_DLE_FILE_UNAVAILABLE 411 #define DW_DLE_FILE_WRONG_TYPE 412 #define DW_DLE_SIBLING_OFFSET_WRONG 413 #define DW_DLE_OPEN_FAIL 414 #define DW_DLE_OFFSET_SIZE 415 #define DW_DLE_MACH_O_SEGOFFSET_BAD 416 #define DW_DLE_FILE_OFFSET_BAD 417 #define DW_DLE_SEEK_ERROR 418 #define DW_DLE_READ_ERROR 419 #define DW_DLE_ELF_CLASS_BAD 420 #define DW_DLE_ELF_ENDIAN_BAD 421 #define DW_DLE_ELF_VERSION_BAD 422 #define DW_DLE_FILE_TOO_SMALL 423 #define DW_DLE_PATH_SIZE_TOO_SMALL 424 #define DW_DLE_BAD_TYPE_SIZE 425 #define DW_DLE_PE_SIZE_SMALL 426 #define DW_DLE_PE_OFFSET_BAD 427 #define DW_DLE_PE_STRING_TOO_LONG 428 #define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 #define DW_DLE_LINE_TABLE_LINENO_ERROR 430 #define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 #define DW_DLE_NO_ELF_SUPPORT 432 #define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 #define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 #define DW_DLE_SECTION_SIZE_ERROR 435 #define DW_DLE_INTERNAL_NULL_POINTER 436 #define DW_DLE_SECTION_STRING_OFFSET_BAD 437 #define DW_DLE_SECTION_INDEX_BAD 438 #define DW_DLE_INTEGER_TOO_SMALL 439 #define DW_DLE_ELF_SECTION_LINK_ERROR 440 #define DW_DLE_ELF_SECTION_GROUP_ERROR 441 #define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 #define DW_DLE_ELF_STRING_SECTION_MISSING 443 #define DW_DLE_SEEK_OFF_END 444 #define DW_DLE_READ_OFF_END 445 #define DW_DLE_ELF_SECTION_ERROR 446 #define DW_DLE_ELF_STRING_SECTION_ERROR 447 #define DW_DLE_MIXING_SPLIT_DWARF_VERSIONS 448 #define DW_DLE_TAG_CORRUPT 449 #define DW_DLE_FORM_CORRUPT 450 #define DW_DLE_ATTR_CORRUPT 451 #define DW_DLE_ABBREV_ATTR_DUPLICATION 452 #define DW_DLE_DWP_SIGNATURE_MISMATCH 453 #define DW_DLE_CU_UT_TYPE_VALUE 454 #define DW_DLE_DUPLICATE_GNU_DEBUGLINK 455 #define DW_DLE_CORRUPT_GNU_DEBUGLINK 456 #define DW_DLE_CORRUPT_NOTE_GNU_DEBUGID 457 #define DW_DLE_CORRUPT_GNU_DEBUGID_SIZE 458 #define DW_DLE_CORRUPT_GNU_DEBUGID_STRING 459 #define DW_DLE_HEX_STRING_ERROR 460 #define DW_DLE_DECIMAL_STRING_ERROR 461 #define DW_DLE_PRO_INIT_EXTRAS_UNKNOWN 462 #define DW_DLE_PRO_INIT_EXTRAS_ERR 463 #define DW_DLE_NULL_ARGS_DWARF_ADD_PATH 464 #define DW_DLE_DWARF_INIT_DBG_NULL 465 /* LAST MUST EQUAL LAST ERROR NUMBER */ #define DW_DLE_LAST 465 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not a column or register number. Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_UNDEFINED_VAL 1034 /* Taken as meaning 'same value' as caller had, not a column or register number Only present at libdwarf runtime. Never on disk. DW_FRAME_* Values present on disk are in dwarf.h */ #define DW_FRAME_SAME_VAL 1035 /* error return values */ #define DW_DLV_BADADDR (~(Dwarf_Addr)0) /* for functions returning target address */ #define DW_DLV_NOCOUNT ((Dwarf_Signed)-1) /* for functions returning count */ #define DW_DLV_BADOFFSET (~(Dwarf_Off)0) /* for functions returning offset */ /* standard return values for functions */ #define DW_DLV_NO_ENTRY -1 #define DW_DLV_OK 0 #define DW_DLV_ERROR 1 /* Special values for offset_into_exception_table field of dwarf fde's. */ /* The following value indicates that there is no Exception table offset associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer was unable to analyse the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) /* The dwarf specification separates FORMs into different classes. To do the seperation properly requires 4 pieces of data as of DWARF4 (thus the function arguments listed here). The DWARF4 specification class definition suffices to describe all DWARF versions. See section 7.5.4, Attribute Encodings. A return of DW_FORM_CLASS_UNKNOWN means we could not properly figure out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). DWARF5: DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST except that LOCLISTSPTR is aways a section offset, never an index, and LOCLISTSPTR is only referenced by DW_AT_loclists_base. Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish from DW_FORM_CLASS_LOCLISTPTR. DWARF5: DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST except that RNGLISTSPTR is aways a section offset, never an index. DW_FORM_CLASS_RNGLISTSPTR is only referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN, DW_FORM_CLASS_ADDRESS, DW_FORM_CLASS_BLOCK, DW_FORM_CLASS_CONSTANT, DW_FORM_CLASS_EXPRLOC, DW_FORM_CLASS_FLAG, DW_FORM_CLASS_LINEPTR, DW_FORM_CLASS_LOCLISTPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_MACPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_RANGELISTPTR, /* DWARF2,3,4 only */ DW_FORM_CLASS_REFERENCE, DW_FORM_CLASS_STRING, DW_FORM_CLASS_FRAMEPTR, /* MIPS/IRIX DWARF2 only */ DW_FORM_CLASS_MACROPTR, /* DWARF5 */ DW_FORM_CLASS_ADDRPTR, /* DWARF5 */ DW_FORM_CLASS_LOCLIST, /* DWARF5 */ DW_FORM_CLASS_LOCLISTSPTR, /* DWARF5 */ DW_FORM_CLASS_RNGLIST, /* DWARF5 */ DW_FORM_CLASS_RNGLISTSPTR, /* DWARF5 */ DW_FORM_CLASS_STROFFSETSPTR /* DWARF5 */ }; /* These support opening DWARF5 split dwarf objects. */ #define DW_GROUPNUMBER_ANY 0 #define DW_GROUPNUMBER_BASE 1 #define DW_GROUPNUMBER_DWO 2 /*===========================================================================*/ /* Dwarf consumer interface initialization and termination operations */ /* Initialization based on path. This is new October 2018. The path actually used is copied to true_path_out and in the case of MacOS dSYM may not match path. So consider the value put in true_path_out the actual file name. reserved1,2,3 should all be passed as zero. */ int dwarf_init_path(const char * /*path*/, char * /*true_path_out_buffer*/, unsigned /*true_path_bufferlen*/, Dwarf_Unsigned /*access*/, unsigned /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, const char * /* reserved1 */, Dwarf_Unsigned /* reserved2 */, Dwarf_Unsigned * /* reserved3 */, Dwarf_Error* /*error*/); /* Initialization based on Unix(etc) open fd */ /* New March 2017 */ int dwarf_init_b(int /*fd*/, Dwarf_Unsigned /*access*/, unsigned /*groupnumber*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* The dwarf_elf_init* functions continue to be supported, but should be considered deprecated as they can ONLY be used on Elf files. */ /* Initialization based on libelf/sgi-fastlibelf open pointer. */ /* New March 2017 */ int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, unsigned /*group_number*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); /* New September 2019. When using dwarf_elf_init[_b]() we still want the file path in the record. So we add it after the init phase. Path is needed for buildid and debuglink to fully work. */ int dwarf_add_file_path(Dwarf_Debug /*dbg*/, const char * /*file_name*/, Dwarf_Error* /*error*/); /* Undocumented function for memory allocator. */ void dwarf_print_memory_stats(Dwarf_Debug /*dbg*/); int dwarf_get_elf(Dwarf_Debug /*dbg*/, dwarf_elf_handle* /*return_elfptr*/, Dwarf_Error* /*error*/); int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* NEW March 2017. */ int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, unsigned /*groupnumber*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); int dwarf_set_tied_dbg(Dwarf_Debug /*basedbg*/, Dwarf_Debug /*tied_dbg*/, Dwarf_Error* /*error*/); /* Likely not very useful.? */ int dwarf_get_tied_dbg(Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/); int dwarf_object_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns the version string. Example: "20190922" which is in ISO date format. */ const char * dwarf_package_version(void); /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, const char * /*std_section_name*/, const char ** /*actual_sec_name_out*/, Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ Dwarf_Unsigned * /*compressed_length*/, Dwarf_Unsigned * /*uncompressed_length*/, Dwarf_Error * /*error*/); /* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Half * /*header_cu_type*/, Dwarf_Error* /*error*/); /* Die traversal operations. dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Half* /*length_size*/, Dwarf_Half* /*extension_size*/, Dwarf_Sig8* /*type signature*/, Dwarf_Unsigned* /*typeoffset*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); /* The following is obsolete, though supported. November 2009. */ int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*cu_header_length*/, Dwarf_Half* /*version_stamp*/, Dwarf_Off* /*abbrev_offset*/, Dwarf_Half* /*address_size*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); int dwarf_siblingof(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* dwarf_siblingof_b new October 2011. */ int dwarf_siblingof_b(Dwarf_Debug /*dbg*/, Dwarf_Die /*die*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_siblingdie*/, Dwarf_Error* /*error*/); /* New 27 April 2015. */ int dwarf_die_from_hash_signature(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*hash_sig*/, const char * /*sig_type: "tu" or "cu"*/, Dwarf_Die* /*returned_CU_die */, Dwarf_Error* /*error*/); int dwarf_child(Dwarf_Die /*die*/, Dwarf_Die* /*return_childdie*/, Dwarf_Error* /*error*/); /* Finding die given global (not CU-relative) offset. Applies only to debug_info. */ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); /* Returns the is_info flag through the pointer if the function returns DW_DLV_OK. Needed so client software knows if a DIE is in debug_info or debug_types. New October 2011. */ Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die /*die*/); /* New March 2016. So we can associate a DIE's abbreviations with the contents the abbreviations section. */ int dwarf_die_abbrev_global_offset(Dwarf_Die /*die*/, Dwarf_Off * /*abbrev_offset*/, Dwarf_Unsigned * /*abbrev_count*/, Dwarf_Error* /*error*/); /* operations on DIEs */ int dwarf_tag(Dwarf_Die /*die*/, Dwarf_Half* /*return_tag*/, Dwarf_Error* /*error*/); /* dwarf_dieoffset returns the global debug_info section offset, not the CU relative offset. */ int dwarf_dieoffset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* NEW October 2015. DWARF5. The DIE here can be any DIE in the relevant CU. index is an index into .debug_addr. This will look first for .debug_addr in the dbg object DIE and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); /* dwarf_CU_dieoffset_given_die returns the global debug_info section offset of the CU die that is the CU containing the given_die (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_die_CU_offset_range(Dwarf_Die /*die*/, Dwarf_Off* /*return_CU_header_offset*/, Dwarf_Off* /*return_CU_length_bytes*/, Dwarf_Error* /*error*/); int dwarf_attr (Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Attribute * /*returned_attr*/, Dwarf_Error* /*error*/); int dwarf_die_text(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, char ** /*ret_name*/, Dwarf_Error * /*error*/); int dwarf_diename(Dwarf_Die /*die*/, char ** /*diename*/, Dwarf_Error* /*error*/); /* Returns the abbrev code of the die. Cannot fail. */ int dwarf_die_abbrev_code(Dwarf_Die /*die */); /* Returns a flag through ab_has_child. Non-zero if the DIE has children, zero if it does not. */ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, Dwarf_Half * /*ab_has_child*/); /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. In case we return DW_DLV_ERROR, the global offset of the last DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/,Dwarf_Off* /*offset*/); /* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* Returns the children offsets for the given offset */ int dwarf_offset_list(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, Dwarf_Bool /*is_info*/, Dwarf_Off ** /*offbuf*/, Dwarf_Unsigned * /*offcnt*/, Dwarf_Error * /*error*/); /* BEGIN: loclist_c interfaces NEW October 2015. This works for any attribute that identifies a loclist or a locexpr. When the attribute is a locexpr a single loclist (created by libdwarf) is attached to loclist_head. */ int dwarf_get_loclist_c (Dwarf_Attribute /*attr*/, Dwarf_Loc_Head_c * /*loclist_head*/, Dwarf_Unsigned * /*locCount*/, Dwarf_Error * /*error*/); int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); int dwarf_get_location_op_value_c(Dwarf_Locdesc_c /*locdesc*/, Dwarf_Unsigned /*index*/, Dwarf_Small * /*atom_out*/, Dwarf_Unsigned * /*operand1*/, Dwarf_Unsigned * /*operand2*/, Dwarf_Unsigned * /*operand3*/, Dwarf_Unsigned * /*offset_for_branch*/, Dwarf_Error* /*error*/); int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*address_size*/, Dwarf_Half /*offset_size*/, Dwarf_Small /*dwarf_version*/, Dwarf_Loc_Head_c* /*loc_head*/, Dwarf_Unsigned * /*listlen*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface is dwarf_get_loclist_c and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* The original interfaces. Please do not use this. */ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ Dwarf_Locdesc** /*llbuf*/, Dwarf_Signed * /*locCount*/, Dwarf_Error* /*error*/); /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, Dwarf_Unsigned /* expression_length*/, Dwarf_Locdesc ** /* llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); /* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, Dwarf_Unsigned /*expression_length*/, Dwarf_Half /*addr_size*/, Dwarf_Locdesc ** /*llbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); /* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for DW_OP_GNU_implicit_pointer. */ int dwarf_loclist_from_expr_b(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/ , Dwarf_Unsigned /*expression_length*/ , Dwarf_Half /*addr_size*/ , Dwarf_Half /*offset_size*/ , Dwarf_Small /*dwarf_version*/ , Dwarf_Locdesc ** /*llbuf*/ , Dwarf_Signed * /*listlen*/ , Dwarf_Error * /*error*/ ); int dwarf_lowpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* When the highpc attribute is of class 'constant' it is not an address, it is an offset from the base address (such as lowpc) of the function. This is therefore a required interface for DWARF4 style DW_AT_highpc. */ int dwarf_highpc_b(Dwarf_Die /*die*/, Dwarf_Addr * /*return_value*/, Dwarf_Half * /*return_form*/, enum Dwarf_Form_Class * /*return_class*/, Dwarf_Error * /*error*/); /* This works for DWARF2 and DWARF3 styles of DW_AT_highpc, but not for the DWARF4 class constant forms. If the FORM is of class constant this returns an error */ int dwarf_highpc(Dwarf_Die /*die*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* New January 2016. */ int dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/); int dwarf_bytesize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitsize(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_size*/, Dwarf_Error* /*error*/); int dwarf_bitoffset(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_offset*/, Dwarf_Error* /*error*/); int dwarf_srclang(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_lang*/, Dwarf_Error* /*error*/); int dwarf_arrayorder(Dwarf_Die /*die*/, Dwarf_Unsigned * /*returned_order*/, Dwarf_Error* /*error*/); /* end of convenience function list */ /* this is the main interface to attributes of a DIE */ int dwarf_attrlist(Dwarf_Die /*die*/, Dwarf_Attribute** /*attrbuf*/, Dwarf_Signed * /*attrcount*/, Dwarf_Error* /*error*/); /* query operations for attributes */ int dwarf_hasform(Dwarf_Attribute /*attr*/, Dwarf_Half /*form*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_whatform(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_final_form*/, Dwarf_Error* /*error*/); int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_initial_form*/, Dwarf_Error* /*error*/); int dwarf_whatattr(Dwarf_Attribute /*attr*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Error* /*error*/); /* The following are concerned with the Primary Interface: getting the actual data values. One function per 'kind' of FORM. */ /* dwarf_formref returns, thru return_offset, a CU-relative offset and does not allow DW_FORM_ref_addr*/ int dwarf_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_global_formref returns, thru return_offset, a debug_info-relative offset and does allow all reference forms*/ int dwarf_global_formref(Dwarf_Attribute /*attr*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_formsig8 returns in the caller-provided 8 byte area the 8 bytes of a DW_FORM_ref_sig8. Not a string. */ int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); /* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); int dwarf_formaddr(Dwarf_Attribute /*attr*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* Part of DebugFission. So a consumer can get the index when the object with the actual .debug_addr section is elsewhere. And so a print application can print the index. New May 2014*/ int dwarf_get_debug_addr_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_formdata16(Dwarf_Attribute /*attr*/, Dwarf_Form_Data16 * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formsdata(Dwarf_Attribute /*attr*/, Dwarf_Signed * /*returned_val*/, Dwarf_Error* /*error*/); int dwarf_formblock(Dwarf_Attribute /*attr*/, Dwarf_Block ** /*returned_block*/, Dwarf_Error* /*error*/); int dwarf_formstring(Dwarf_Attribute /*attr*/, char ** /*returned_string*/, Dwarf_Error* /*error*/); /* DebugFission. So a DWARF print application can get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); int dwarf_formexprloc(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_exprlen*/, Dwarf_Ptr * /*block_ptr*/, Dwarf_Error * /*error*/); /* end attribute query operations. */ /* Start line number operations */ /* dwarf_srclines is the original interface from 1993. */ int dwarf_srclines(Dwarf_Die /*die*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error* /*error*/); /* If we have two-level line tables, this will return the logicals table in linebuf and the actuals table in linebuf_actuals. For old-style (one-level) tables, it will return the single table through linebuf, and the value returned through linecount_actuals will be 0. The actual version number is returned through version. For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Line** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the appropriate method for deallocating what dwarf_srclines and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables user code should call dwarf_srclines_dealloc once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Line* /*linebuf*/, Dwarf_Signed /*count */); /* New October 2015, must be used to deallocating what is allocated by dwarf_srclines_b and dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. *is_single_table will be set zero for line sections with the two_level line table extension (which will have *version_out 0xf006). */ int dwarf_srclines_b(Dwarf_Die /*die*/, Dwarf_Unsigned * /* version_out*/, Dwarf_Small * /* table_count */, Dwarf_Line_Context * /* linecontext*/, Dwarf_Error * /* error*/); /* Functions passing in a Dwarf_Line_Context are only available if dwarf_srclines_b() was used to access line table information. */ /* New October 2015. Returns line details. Works for DWARF2,3,4,5. If linecount returned is zero this is a line table with no lines.*/ int dwarf_srclines_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf*/, Dwarf_Signed * /*linecount*/, Dwarf_Error * /* error*/); /* New October 2015. Returns line details. Works for DWARF2,3,4,5 and for experimental two-level line tables. A single level table will have *linebuf_actuals and *linecount_actuals set to 0. */ int dwarf_srclines_two_level_from_linecontext( Dwarf_Line_Context /*line_context*/, Dwarf_Line ** /*linebuf */, Dwarf_Signed * /*linecount*/, Dwarf_Line ** /*linebuf_actuals*/, Dwarf_Signed * /*linecount_actuals*/, Dwarf_Error * /* error*/); /* dwarf_srclines_dealloc_b(), created October 2015, is the appropriate method for deallocating everything and dwarf_srclines_from_linecontext(), dwarf_srclines_twolevel_from_linecontext(), and dwarf_srclines_b() allocate. */ void dwarf_srclines_dealloc_b(Dwarf_Line_Context /*line_context*/); /* New October 2015. */ /* The offset is in the relevent .debug_line or .debug_line.dwo section (and in a split dwarf package file includes) the base line table offset). */ int dwarf_srclines_table_offset(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Compilation Directory name for the current CU. section (and in a split dwarf package file includes) the base line table offset). Do not free() the string, it is in a dwarf section. */ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, const char ** /*compilation_directory*/, Dwarf_Error * /*error*/); /* New October 2015. Part of the two-level line table extension. */ /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*decl_file*/, Dwarf_Unsigned * /*decl_line*/, Dwarf_Error * /*error*/); /* New October 2015. */ /* Count is the real count of files array entries. This remains supported though it is pretty useless for DWARF5. To process DWARF5 as well as DWARF 2,3,4 (in a uniform fashion) use dwarf_srclines_files_indexes() instead. */ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); /* New March 2018. */ /* Count is the real count of files array entries. Since DWARF 2,3,4 are zero origin indexes and DWARF5 and later are one origin, this function replaces dwarf_srclines_files_count(). */ int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*baseindex*/, Dwarf_Signed * /*count*/, Dwarf_Signed * /*endindex*/, Dwarf_Error * /*error*/); /* New March 2018. Same as dwarf_srclines_files_data, but adds the md5ptr field so cases where DW_LNCT_MD5 is present can return pointer to the MD5 value. With DWARF 5 index starts with 0. See dwarf_srclines_files_indexes() which makes indexing through the files easy. */ int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index_in, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5ptr, Dwarf_Error * error); /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. Index starts with 1, last is 'count' */ int dwarf_srclines_files_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Unsigned * /*directory_index*/, Dwarf_Unsigned * /*last_mod_time*/, Dwarf_Unsigned * /*file_length*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Count is the real count of include array entries. */ int dwarf_srclines_include_dir_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ int dwarf_srclines_include_dir_data(Dwarf_Line_Context /*line_context*/, Dwarf_Signed /*index*/, const char ** /*name*/, Dwarf_Error * /* error*/); /* New October 2015. */ /* The DWARF version number of this compile-unit in the .debug_lines section and the number of actual tables:0 (header with no lines), 1 (standard table), or 2 (experimental). */ int dwarf_srclines_version(Dwarf_Line_Context /*line_context*/, Dwarf_Unsigned * /*version*/, Dwarf_Small * /*table_count*/, Dwarf_Error * /*error*/); int dwarf_get_line_section_name_from_die(Dwarf_Die /*die*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* While 'filecount' is signed, the value returned through the pointer is never negative. Original libdwarf from 199x. */ int dwarf_srcfiles(Dwarf_Die /*die*/, char*** /*srcfiles*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineendsequence(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); int dwarf_lineno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error* /*error*/); int dwarf_line_srcfileno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_fileno*/, Dwarf_Error * /*error*/); /* Is the line address from DW_LNS_set_address? */ int dwarf_line_is_addr_set(Dwarf_Line /*line*/, Dwarf_Bool * /*is_addr_set*/, Dwarf_Error * /*error*/); int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); /* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); /* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_lineoffset*/, Dwarf_Error* /*error*/); int dwarf_linesrc(Dwarf_Line /*line*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_lineblock(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); /* We gather these into one call as it's likely one will want all or none of them. */ int dwarf_prologue_end_etc(Dwarf_Line /* line */, Dwarf_Bool * /*prologue_end*/, Dwarf_Bool * /*eplogue_begin*/, Dwarf_Unsigned * /* isa */, Dwarf_Unsigned * /* discriminator */, Dwarf_Error * /*error*/); /* End line table operations */ /* Two-level line tables: When reading from an actuals table, dwarf_line_logical() returns the logical row number for the line. */ int dwarf_linelogical(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_logical*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linecontext() returns the logical row number corresponding the the calling context for an inlined call. */ int dwarf_linecontext(Dwarf_Line /*line*/, Dwarf_Unsigned * /*returned_context*/, Dwarf_Error* /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprogno() returns the index in the subprograms table of the inlined subprogram. */ int dwarf_line_subprogno(Dwarf_Line /*line*/, Dwarf_Unsigned * /*ret_subprogno*/, Dwarf_Error * /*error*/); /* Two-level line tables: When reading from a logicals table, dwarf_linesubprog() returns the name of the inlined subprogram, its declaration filename, and its declaration line number, if available. */ int dwarf_line_subprog(Dwarf_Line /*line*/, char ** /*returned_subprog_name*/, char ** /*returned_filename*/, Dwarf_Unsigned * /*returned_lineno*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ /* .debug_names names table interfaces. DWARF5 */ /* New April 2017 */ int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, Dwarf_Dnames_Head * /*dn_out*/, /* *dn_count_out returns the number of name indexes in the .debug_names section */ Dwarf_Unsigned * /*dn_index_count_out*/, Dwarf_Error * /*error*/); /* Since there may be multiple name indexes in a .debug_names section we use index_number starting at 0 through dn_index_count_out-1. */ int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned * /*section_offset*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * /*comp_unit_count*/, Dwarf_Unsigned * /*local_type_unit_count*/, Dwarf_Unsigned * /*foreign_type_unit_count*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*name_count*/, /* The following are counted in bytes */ Dwarf_Unsigned * /*indextable_overall_length*/, Dwarf_Unsigned * /*abbrev_table_size*/, Dwarf_Unsigned * /*entry_pool_size*/, Dwarf_Unsigned * /*augmentation_string_size*/, Dwarf_Error * /*error*/); int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_number*/, Dwarf_Unsigned * /*offset_count*/, Dwarf_Unsigned * /*offset*/, Dwarf_Error * /*error*/); int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*sig_number*/, Dwarf_Unsigned * /*sig_mininum*/, Dwarf_Unsigned * /*sig_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Error * /*error*/); int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*bucket_number*/, Dwarf_Unsigned * /*bucket_count*/, Dwarf_Unsigned * /*index_of_name_entry*/, Dwarf_Error * /*error*/); int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*name_entry*/, Dwarf_Unsigned * /*names_count*/, Dwarf_Sig8 * /*signature*/, Dwarf_Unsigned * /*offset_to_debug_str*/, Dwarf_Unsigned * /*offset_in_entrypool*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 */ Dwarf_Unsigned * /*number_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, /* The number of this code/tag as an array index. */ Dwarf_Unsigned * /*index_of_abbrev*/, /* The number of attr/form pairs, not counting the trailing 0,0 pair. */ Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*abbrev_entry_index*/, Dwarf_Unsigned /*abbrev_form_index*/, Dwarf_Unsigned * /*name_index_attr*/, Dwarf_Unsigned * /*form*/, Dwarf_Unsigned * /*number_of_attr_form_entries*/, Dwarf_Error * /*error*/); /* This, combined with dwarf_debugnames_entrypool_values(), lets one examine as much or as little of an entrypool as one wants to by alternately calling these two functions. */ int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*offset_in_entrypool*/, Dwarf_Unsigned * /*abbrev_code*/, Dwarf_Unsigned * /*tag*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Unsigned * /*index_of_abbrev*/, Dwarf_Unsigned * /*offset_of_initial_value*/, Dwarf_Error * /*error*/); /* Caller, knowing array size needed, passes in arrays it allocates of for idx, form, offset-size-values, and signature values. Caller must examine idx-number and form to decide, for each array element, whether the offset or the signature contains the value. So this returns all the values for the abbrev code. And points via offset_of_next to the next abbrev code. */ int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, Dwarf_Unsigned /*index_number*/, Dwarf_Unsigned /*index_of_abbrev*/, Dwarf_Unsigned /*offset_in_entrypool_of_values*/, Dwarf_Unsigned * /*array_dw_idx_number*/, Dwarf_Unsigned * /*array_form*/, Dwarf_Unsigned * /*array_of_offsets*/, Dwarf_Sig8 * /*array_of_signatures*/, /* offset of the next entrypool entry. */ Dwarf_Unsigned * /*offset_of_next_entrypool*/, Dwarf_Error * /*error*/); /* FIXME: add interfaces for string search given hash and string */ /* end of .debug_names interfaces. */ /* New October 2019. Access to the GNU section named .gnu_debuglink and/or the section .note.gnu.build-id. See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html The dbg argument provides data access and relies on fields de_path,de_debuglink_globals, de_debuglink_globals_length If no debuglink then name_returned,crc_returned and debuglink_path_returned will get set 0 through the pointers. If no .note.gnu.build-id then buildid_length_returned, and buildid_returned will be set 0 through the pointers. See libdwarf2.1.mm for additional important details. see dwarf_add_file_path() and dwarf_add_debuglink_global_path(). */ int dwarf_gnu_debuglink(Dwarf_Debug /*dbg*/, char ** /*name_returned*/, unsigned char ** /*crc_returned from the debuglink section*/, char ** /*debuglink_path_returned*/, unsigned * /*debuglink_path_count_returned*/, unsigned * /*buildid_type_returned */, char ** /*buildid_owner_name_returned*/, unsigned char ** /*buildid_returned*/, unsigned * /*buildid_length_returned*/, char *** /*paths_returned*/, unsigned * /*paths_length_returned*/, Dwarf_Error* /*error*/); /* See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html and dwarf_gnu_debuglink() pathname is a path-prefix to be added to a list of path-prefixes, The default "/usr/lib/debug" is built-in and is the first such in the list held in dbg. The path prefix should start with / . It can just end or end with / , either choice will work. */ int dwarf_add_debuglink_global_path(Dwarf_Debug /*dbg*/, const char *pathname, Dwarf_Error* /*error*/); /* global name space operations (.debug_pubnames access) The pubnames and similar sections are rarely used. Few compilers emit them. They are DWARF 2,3,4 only., not DWARF 5. */ /* New March 2019. Mostly special for dwarfdump. */ int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, int /* flag */, Dwarf_Error* /*error*/); int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, Dwarf_Error* /*error*/); void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Global* /*globals*/, Dwarf_Signed /*number_of_globals*/); int dwarf_globname(Dwarf_Global /*glob*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_global_die_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error * /*error*/); /* This returns the CU die global offset if one knows the CU header global offset. See also dwarf_CU_dieoffset_given_die(). */ int dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); /* The _b form is new October 2011. */ int dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug /*dbg*/, Dwarf_Off /*in_cu_header_offset*/, Dwarf_Bool /*is_info. True means look in debug_Info, false use debug_types.*/, Dwarf_Off * /*out_cu_die_offset*/, Dwarf_Error * /*err*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_cu_die_offset_given_cu_header_offset #endif int dwarf_global_cu_offset(Dwarf_Global /*global*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_global_name_offsets(Dwarf_Global /*global*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. */ int dwarf_get_globals_header(Dwarf_Global /*global*/, Dwarf_Off * /*offset_pub_header*/, Dwarf_Unsigned * /*length_size*/, Dwarf_Unsigned * /*length_pub*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*header_info_offset*/, Dwarf_Unsigned * /*info_length*/, Dwarf_Error* /*error*/); /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, Dwarf_Signed * /*number_of_funcs*/, Dwarf_Error* /*error*/); void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Func* /*funcs*/, Dwarf_Signed /*number_of_funcs*/); int dwarf_funcname(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_func_die_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_cu_offset(Dwarf_Func /*func*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_func_name_offsets(Dwarf_Func /*func*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, SGI IRIX .debug_typenames section. Same content as DWARF3 .debug_pubtypes, but defined years before .debug_pubtypes was defined. SGI IRIX only. */ int dwarf_get_types(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_types_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*types*/, Dwarf_Signed /*number_of_types*/); int dwarf_typename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_type_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* User-defined type name operations, DWARF3 .debug_pubtypes section. */ int dwarf_get_pubtypes(Dwarf_Debug /*dbg*/, Dwarf_Type** /*types*/, Dwarf_Signed * /*number_of_types*/, Dwarf_Error* /*error*/); void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Type* /*pubtypes*/, Dwarf_Signed /*number_of_pubtypes*/); int dwarf_pubtypename(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_pubtype_type_die_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_pubtype_name_offsets(Dwarf_Type /*type*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* File-scope static variable name operations. */ int dwarf_get_vars(Dwarf_Debug /*dbg*/, Dwarf_Var** /*vars*/, Dwarf_Signed * /*number_of_vars*/, Dwarf_Error* /*error*/); void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Var* /*vars*/, Dwarf_Signed /*number_of_vars*/); int dwarf_varname(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_var_die_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_cu_offset(Dwarf_Var /*var*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_var_name_offsets(Dwarf_Var /*var*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* weak name operations. */ int dwarf_get_weaks(Dwarf_Debug /*dbg*/, Dwarf_Weak** /*weaks*/, Dwarf_Signed * /*number_of_weaks*/, Dwarf_Error* /*error*/); void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Weak* /*weaks*/, Dwarf_Signed /*number_of_weaks*/); int dwarf_weakname(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Error* /*error*/); int dwarf_weak_die_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_weak_name_offsets(Dwarf_Weak /*weak*/, char ** /*returned_name*/, Dwarf_Off* /*die_offset*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); /* location list section operation. (.debug_loc access) */ int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Addr* /*hipc*/, Dwarf_Addr* /*lopc*/, Dwarf_Ptr* /*data*/, Dwarf_Unsigned* /*entry_len*/, Dwarf_Unsigned* /*next_entry*/, Dwarf_Error* /*error*/); /* abbreviation section operations */ int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Abbrev * /*returned_abbrev*/, Dwarf_Unsigned* /*length*/, Dwarf_Unsigned* /*attr_count*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, Dwarf_Half* /*return_tag_number*/, Dwarf_Error* /*error*/); int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, Dwarf_Unsigned* /*return_code_number*/, Dwarf_Error* /*error*/); /* See comments in dwarf_abbrev.c. Not an entirely safe function. */ int dwarf_get_abbrev_count(Dwarf_Debug /*dbg*/); int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed* /*return_flag*/, Dwarf_Error* /*error*/); /* New August 2019. Most uses will call with filter_outliers non-zero. In that case impossible values return DW_DLV_ERROR. Those doing extra things (like dwarfdump) will call with filter_outliers zero to get the raw data (effectively); */ int dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned indx, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implict_const, Dwarf_Off * offset, Dwarf_Error * error); /* Obsolete because it cannot return the DW_FORM_implicit_const value. */ int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, Dwarf_Signed /*index*/, Dwarf_Half * /*returned_attr_num*/, Dwarf_Signed* /*form*/, Dwarf_Off* /*offset*/, Dwarf_Error* /*error*/); int dwarf_get_string_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* consumer string section operation */ int dwarf_get_str(Dwarf_Debug /*dbg*/, Dwarf_Off /*offset*/, char** /*string*/, Dwarf_Signed * /*strlen_of_string*/, Dwarf_Error* /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* New November 2015 */ int dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); /* Consumer op on gnu .eh_frame info */ int dwarf_get_fde_list_eh( Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* consumer operations on frame info: .debug_frame */ int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, Dwarf_Cie** /*cie_data*/, Dwarf_Signed* /*cie_element_count*/, Dwarf_Fde** /*fde_data*/, Dwarf_Signed* /*fde_element_count*/, Dwarf_Error* /*error*/); /* Release storage gotten by dwarf_get_fde_list_eh() or dwarf_get_fde_list() */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Cie * /*cie_data*/, Dwarf_Signed /*cie_element_count*/, Dwarf_Fde * /*fde_data*/, Dwarf_Signed /*fde_element_count*/); int dwarf_get_fde_range(Dwarf_Fde /*fde*/, Dwarf_Addr* /*low_pc*/, Dwarf_Unsigned* /*func_length*/, Dwarf_Ptr* /*fde_bytes*/, Dwarf_Unsigned* /*fde_byte_length*/, Dwarf_Off* /*cie_offset*/, Dwarf_Signed* /*cie_index*/, Dwarf_Off* /*fde_offset*/, Dwarf_Error* /*error*/); /* Useful for IRIX only: see dwarf_get_cie_augmentation_data() dwarf_get_fde_augmentation_data() for GNU .eh_frame. */ int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/, Dwarf_Signed* /* offset_into_exception_tables */, Dwarf_Error* /*error*/); int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/, Dwarf_Cie * /*cie_returned*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info_b(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Half* /*offset_size*/, Dwarf_Error* /*error*/); int dwarf_get_cie_info(Dwarf_Cie /*cie*/, Dwarf_Unsigned * /*bytes_in_cie*/, Dwarf_Small* /*version*/, char ** /*augmenter*/, Dwarf_Unsigned* /*code_alignment_factor*/, Dwarf_Signed* /*data_alignment_factor*/, Dwarf_Half* /*return_address_register_rule*/, Dwarf_Ptr* /*initial_instructions*/, Dwarf_Unsigned* /*initial_instructions_length*/, Dwarf_Error* /*error*/); /* dwarf_get_cie_index new September 2009. */ int dwarf_get_cie_index( Dwarf_Cie /*cie*/, Dwarf_Signed* /*index*/, Dwarf_Error* /*error*/ ); int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Regtable* /*reg_table*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); 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*/); /* In this older interface DW_FRAME_CFA_COL is a meaningful column (which does not work well with DWARF3 or non-MIPS architectures). */ int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Signed* /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset*/, Dwarf_Addr* /*row_pc*/, Dwarf_Error* /*error*/); /* See discussion of dw_value_type, libdwarf.h. Use of DW_FRAME_CFA_COL is not meaningful in this interface. See dwarf_get_fde_info_for_cfa_reg3(). */ /* dwarf_get_fde_info_for_reg3 is useful on a single column, but it is inefficient to iterate across all table_columns using this function. Instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. */ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Error * /*error*/); int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Half /*table_column*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed * /*register*/, Dwarf_Signed * /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr * /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Bool * /* has_more_rows */, Dwarf_Addr * /* subsequent_pc */, Dwarf_Error* /*error*/); /* Use this to get the cfa. Or the above function. */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, Dwarf_Signed* /*register*/, Dwarf_Signed* /*offset_or_block_len*/, Dwarf_Ptr * /*block_ptr */, Dwarf_Addr* /*row_pc_out*/, Dwarf_Error* /*error*/); int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, Dwarf_Die /*subr_die */, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, Dwarf_Unsigned /*fde_index*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Error* /*error*/); int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, Dwarf_Addr /*pc_of_interest*/, Dwarf_Fde * /*returned_fde*/, Dwarf_Addr* /*lopc*/, Dwarf_Addr* /*hipc*/, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); /* GNU .eh_frame augmentation information, raw form, see Linux Standard Base Core Specification version 3.0 . */ int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/, Dwarf_Small ** /* augdata */, Dwarf_Unsigned * /* augdata_len */, Dwarf_Error* /*error*/); int dwarf_expand_frame_instructions(Dwarf_Cie /*cie*/, Dwarf_Ptr /*instruction*/, Dwarf_Unsigned /*i_length*/, Dwarf_Frame_Op** /*returned_op_list*/, Dwarf_Signed* /*op_count*/, Dwarf_Error* /*error*/); /* Operations on .debug_aranges. */ int dwarf_get_aranges(Dwarf_Debug /*dbg*/, Dwarf_Arange** /*aranges*/, Dwarf_Signed * /*arange_count*/, Dwarf_Error* /*error*/); int dwarf_get_ranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_aranges_section_name(Dwarf_Debug /*dbg*/, const char ** /*section_name_out*/, Dwarf_Error * /*error*/); int dwarf_get_arange( Dwarf_Arange* /*aranges*/, Dwarf_Unsigned /*arange_count*/, Dwarf_Addr /*address*/, Dwarf_Arange * /*returned_arange*/, Dwarf_Error* /*error*/); int dwarf_get_cu_die_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); int dwarf_get_arange_cu_header_offset( Dwarf_Arange /*arange*/, Dwarf_Off* /*return_cu_header_offset*/, Dwarf_Error* /*error*/); #ifdef __sgi /* pragma is sgi MIPS only */ #pragma optional dwarf_get_arange_cu_header_offset #endif /* DWARF2,3 interface. No longer really adequate (it was never right for segmented address spaces, please switch to using dwarf_get_arange_info_b instead. There is no effective difference between these functions if the address space of the target is not segmented. */ int dwarf_get_arange_info( Dwarf_Arange /*arange*/, Dwarf_Addr* /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off* /*cu_die_offset*/, Dwarf_Error* /*error*/ ); /* New for DWARF4, entries may have segment information. *segment is only meaningful if *segment_entry_size is non-zero. */ int dwarf_get_arange_info_b( Dwarf_Arange /*arange*/, Dwarf_Unsigned* /*segment*/, Dwarf_Unsigned* /*segment_entry_size*/, Dwarf_Addr * /*start*/, Dwarf_Unsigned* /*length*/, Dwarf_Off * /*cu_die_offset*/, Dwarf_Error * /*error*/ ); /* BEGIN: DWARF5 .debug_macro interfaces NEW November 2015. */ int dwarf_get_macro_context(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_unit_offset_out*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length_out*/, Dwarf_Error * /*error*/); /* Just like dwarf_get_macro_context, but instead of using DW_AT_macros or DW_AT_GNU_macros to get the offset we just take the offset given. */ int dwarf_get_macro_context_by_offset(Dwarf_Die /*die*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned * /*version_out*/, Dwarf_Macro_Context * /*macro_context*/, Dwarf_Unsigned * /*macro_ops_count_out*/, Dwarf_Unsigned * /*macro_ops_data_length*/, Dwarf_Error * /*error*/); void dwarf_dealloc_macro_context(Dwarf_Macro_Context /*mc*/); int dwarf_get_macro_section_name(Dwarf_Debug /*dbg*/, const char ** /*sec_name_out*/, Dwarf_Error * /*err*/); int dwarf_macro_context_head(Dwarf_Macro_Context /*head*/, Dwarf_Half * /*version*/, Dwarf_Unsigned * /*mac_offset*/, Dwarf_Unsigned * /*mac_len*/, Dwarf_Unsigned * /*mac_header_len*/, unsigned * /*flags*/, Dwarf_Bool * /*has_line_offset*/, Dwarf_Unsigned * /*line_offset*/, Dwarf_Bool * /*has_offset_size_64*/, Dwarf_Bool * /*has_operands_table*/, Dwarf_Half * /*opcode_count*/, Dwarf_Error * /*error*/); /* Returns data from the operands table in the macro unit header. */ int dwarf_macro_operands_table(Dwarf_Macro_Context /*head*/, Dwarf_Half /*index*/, /* 0 to opcode_count -1 */ Dwarf_Half * /*opcode_number*/, Dwarf_Half * /*operand_count*/, const Dwarf_Small ** /*operand_array*/, Dwarf_Error * /*error*/); /* Access to the macro operations, 0 to macro_ops_count_out-1 Where the last of these will have macro_operator 0 (which appears in the ops data and means end-of-ops). op_start_section_offset is the section offset of the macro operator (which is a single unsigned byte, and is followed by the macro operand data). */ int dwarf_get_macro_op(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*op_start_section_offset*/, Dwarf_Half * /*macro_operator*/, Dwarf_Half * /*forms_count*/, const Dwarf_Small ** /*formcode_array*/, Dwarf_Error * /*error*/); int dwarf_get_macro_defundef(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*index*/, Dwarf_Unsigned * /*offset*/, Dwarf_Half * /*forms_count*/, const char ** /*macro_string*/, Dwarf_Error * /*error*/); int dwarf_get_macro_startend_file(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*line_number*/, Dwarf_Unsigned * /*name_index_to_line_tab*/, const char ** /*src_file_name*/, Dwarf_Error * /*error*/); int dwarf_get_macro_import(Dwarf_Macro_Context /*macro_context*/, Dwarf_Unsigned /*op_number*/, Dwarf_Unsigned * /*target_offset*/, Dwarf_Error * /*error*/); /* END: DWARF5 .debug_macro interfaces. */ /* consumer .debug_macinfo information interface. */ struct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; /* offset, in the section, of this macro info */ Dwarf_Small dmd_type; /* the type, DW_MACINFO_define etc*/ Dwarf_Signed dmd_lineno; /* the source line number where applicable and vend_def number if vendor_extension op */ Dwarf_Signed dmd_fileindex;/* the source file index: applies to define undef start_file */ char * dmd_macro; /* macro name (with value for defineop) string from vendor ext */ }; /* dwarf_print_lines is for use by dwarfdump: it prints line info to stdout. The _dwarf name is obsolete. Use dwarf_ instead. Added extra argnument 2/2009 for better checking. */ int _dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/); int dwarf_print_lines(Dwarf_Die /*cu_die*/,Dwarf_Error * /*error*/, int * /*error_count_out */); /* As of August 2013, dwarf_print_lines() no longer uses printf. Instead it calls back to the application using a function pointer once per line-to-print. The lines passed back already have any needed newlines. The following struct is used to initialize the callback mechanism. Failing to call the dwarf_register_printf_callback() function will prevent the lines from being passed back but such omission is not an error. See libdwarf2.1.mm for further documentation. The return value is the previous set of callback values. */ typedef void (* dwarf_printf_callback_function_type) (void * /*user_pointer*/, const char * /*linecontent*/); struct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; /* If called with a NULL newvalues pointer, it simply returns the current set of values for this Dwarf_Debug. */ struct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug /*dbg*/, struct Dwarf_Printf_Callback_Info_s * /*newvalues*/); /* dwarf_check_lineheader lets dwarfdump get detailed messages about some compiler errors we detect. We return the count of detected errors through the pointer. */ void dwarf_check_lineheader(Dwarf_Die /*cu_die*/,int *errcount_out); /* dwarf_ld_sort_lines helps SGI IRIX ld rearrange lines in .debug_line in a .o created with a text section per function. -OPT:procedure_reorder=ON where ld-cord (cord(1)ing by ld, not by cord(1)) may have changed the function order. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /* buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); int dwarf_ld_sort_lines( void * /*orig_buffer*/, unsigned long /*buffer_len*/, int /*is_64_bit*/, int * /*any_change*/, int * /*err_code*/); /* Used by dwarfdump -v to print fde offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int _dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); int dwarf_fde_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); /* Used by dwarfdump -v to print cie offsets from debugging info. The _dwarf name is obsolete. Use dwarf_ instead. */ int dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off */, Dwarf_Error * /*err*/); int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off /*macro_offset*/, Dwarf_Unsigned /*maximum_count*/, Dwarf_Signed * /*entry_count*/, Dwarf_Macro_Details ** /*details*/, Dwarf_Error * /*err*/); /* dwarf_get_offset_size() New October 2015 */ int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*offset_size*/, Dwarf_Error * /*error*/); int dwarf_get_address_size(Dwarf_Debug /*dbg*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); int dwarf_get_die_address_size(Dwarf_Die /*die*/, Dwarf_Half * /*addr_size*/, Dwarf_Error * /*error*/); enum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half /* dwversion */, Dwarf_Half /* attrnum */, Dwarf_Half /*offset_size */, Dwarf_Half /*form*/); /* BEGIN gdbindex operations interfaces. */ /* .gdb_index section operations. A GDB extension. The section is in some executables and if present is used to quickly map an address or name to a skeleton CU or TU. If present then there are .dwo or .dwp files somewhere to make detailed debugging possible (up to user code to find it/them and deal with them). Version 8 built by gdb, so type entries are ok as is. Version 7 built by the 'gold' linker and type index entries for a CU must be derived othewise, the type index is not correct... ? FIXME */ /* Creates a Dwarf_Gdbindex, returning it and its values through the pointers. */ int dwarf_gdbindex_header(Dwarf_Debug /*dbg*/, Dwarf_Gdbindex * /*gdbindexptr*/, Dwarf_Unsigned * /*version*/, Dwarf_Unsigned * /*cu_list_offset*/, Dwarf_Unsigned * /*types_cu_list_offset*/, Dwarf_Unsigned * /*address_area_offset*/, Dwarf_Unsigned * /*symbol_table_offset*/, Dwarf_Unsigned * /*constant_pool_offset*/, Dwarf_Unsigned * /*section_size*/, Dwarf_Unsigned * /*unused_reserved*/, const char ** /*section_name*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to list_length-1 */ int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*cu_length*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to types_list_length -1 */ int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*cu_offset*/, Dwarf_Unsigned * /*tu_offset*/, Dwarf_Unsigned * /*type_signature*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to addressarea_list_length-1 */ int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*low_adddress*/, Dwarf_Unsigned * /*high_address*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*symtab_list_length*/, Dwarf_Error * /*error*/); /* entryindex: 0 to symtab_list_length-1 */ int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*entryindex*/, Dwarf_Unsigned * /*string_offset*/, Dwarf_Unsigned * /*cu_vector_offset*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_length(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned * /*innercount*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*cuvector_offset*/, Dwarf_Unsigned /*innerindex*/, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, Dwarf_Unsigned * /*symbol_kind*/, Dwarf_Unsigned * /*is_static*/, Dwarf_Error * /*error*/); /* The strings in the pool follow (in memory) the cu index set and are NUL terminated. */ int dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned /*stringoffset*/, const char ** /*string_ptr*/, Dwarf_Error * /*error*/); void dwarf_gdbindex_free(Dwarf_Gdbindex /*gdbindexptr*/); /* END gdbindex/debugfission operations. */ /* START debugfission dwp .debug_cu_index and .debug_tu_index operations. */ int dwarf_get_xu_index_header(Dwarf_Debug /*dbg*/, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * /*xuhdr*/, Dwarf_Unsigned * /*version_number*/, Dwarf_Unsigned * /*offsets_count L*/, Dwarf_Unsigned * /*units_count N*/, Dwarf_Unsigned * /*hash_slots_count M*/, const char ** /*sect_name*/, Dwarf_Error * /*err*/); int dwarf_get_xu_index_section_type(Dwarf_Xu_Index_Header /*xuhdr*/, /* the function returns a pointer to the immutable string "tu" or "cu" via this arg. Do not free. */ const char ** /*typename*/, /* the function returns a pointer to the immutable section name. Do not free. .debug_cu_index or .debug_tu_index */ const char ** /*sectionname*/, Dwarf_Error * /*err*/); /* Index values 0 to M-1 are valid. */ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*index*/, /* Returns the hash value. 64 bits. */ Dwarf_Sig8 * /*hash_value*/, /* returns the index into rows of offset/size tables. */ Dwarf_Unsigned * /*index_to_sections*/, Dwarf_Error * /*err*/); /* Columns 0 to L-1, valid. */ int dwarf_get_xu_section_names(Dwarf_Xu_Index_Header /*xuhdr*/, /* Row index defined to be row zero. */ Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*DW_SECT_ number*/, const char ** /*DW_SECT_ name*/, Dwarf_Error * /*err*/); /* Rows 1 to N col 0 to L-1 are valid */ int dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header /*xuhdr*/, Dwarf_Unsigned /*row_index*/, Dwarf_Unsigned /*column_index*/, Dwarf_Unsigned* /*sec_offset*/, Dwarf_Unsigned* /*sec_size*/, Dwarf_Error * /*err*/); void dwarf_xu_header_free(Dwarf_Xu_Index_Header /*xuhdr*/); /* Defined larger than necessary. This struct, being visible, will be difficult to change: binary compatibility. */ #define DW_FISSION_SECT_COUNT 12 /* User must allocate this struct, zero it, and pass a pointer to it into dwarf_get_debugfission_for_cu . */ struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; typedef struct Dwarf_Debug_Fission_Per_CU_s Dwarf_Debug_Fission_Per_CU ; /* For any Dwarf_Die in a compilation unit, return the debug fission table data through percu_out. Usually applications will pass in the CU die. Calling code should zero all of the struct Dwarf_Debug_Fission_Per_CU_s before calling this. If there is no debugfission data this returns DW_DLV_NO_ENTRY (only .dwp objects have debugfission data). */ int dwarf_get_debugfission_for_die(Dwarf_Die /* die */, Dwarf_Debug_Fission_Per_CU * /* percu_out */, Dwarf_Error * /* err */); /* Given a key (hash signature) from a .o, find the per-cu information for the CU with that key. */ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Sig8 * /*key, hash signature */, const char * key_type /*"cu" or "tu" */, Dwarf_Debug_Fission_Per_CU * /*percu_out */, Dwarf_Error * /*err */); /* END debugfission dwp .debug_cu_index and .debug_tu_index operations. */ /* Utility operations */ Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); /* stringcheck zero is default and means do all string length validity checks. Call with parameter value 1 to turn off many such checks (and increase performance). Call with zero for safest running. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_stringcheck(int /*stringcheck*/); /* 'apply' defaults to 1 and means do all 'rela' relocations on reading in a dwarf object section with such relocations. Call with parameter value 0 to turn off application of such relocations. Since the static linker leaves 'bogus' data in object sections with a 'rela' relocation section such data cannot be read sensibly without processing the relocations. Such relocations do not exist in executables and shared objects (.so), the relocations only exist in plain .o relocatable object files. Actual value saved and returned is only 8 bits! Upper bits ignored by libdwarf (and zero on return). Returns previous value. */ int dwarf_set_reloc_application(int /*apply*/); /* Unimplemented */ Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/); /* Unimplemented */ Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/); void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, Dwarf_Unsigned /*type*/); /* DWARF Producer Interface */ /* New form June, 2011. Adds user_data argument. */ typedef int (*Dwarf_Callback_Func)( const char* /*name*/, int /*size*/, Dwarf_Unsigned /*type*/, Dwarf_Unsigned /*flags*/, Dwarf_Unsigned /*link*/, Dwarf_Unsigned /*info*/, Dwarf_Unsigned* /*sect_name_index*/, void * /*user_data*/, int* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR and if DW_DLV_OK returns the Dwarf_P_Debug pointer through the dbg_returned argument. */ int dwarf_producer_init( Dwarf_Unsigned /*flags*/, Dwarf_Callback_Func /*func*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, void * /*user_data*/, const char *isa_name, /* See isa/abi names in pro_init.c */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR. The desired form must be DW_FORM_string (the default) or DW_FORM_strp. */ int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, int /*desired_form*/, Dwarf_Error* /*error*/); /* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New September 2016. The preferred interface. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*nbufs_out*/, Dwarf_Error* /*error*/); /* New September 2016. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Ptr * /*section_bytes*/, Dwarf_Error* /*error*/); /* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info_count( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*count_of_relocation_sections*/, int * /*drd_buffer_version*/, Dwarf_Error* /*error*/); int dwarf_get_relocation_info( Dwarf_P_Debug /*dbg*/, Dwarf_Signed * /*elf_section_index*/, Dwarf_Signed * /*elf_section_index_link*/, Dwarf_Unsigned * /*relocation_buffer_count*/, Dwarf_Relocation_Data * /*reldata_buffer*/, Dwarf_Error* /*error*/); /* v1: no drd_length field, enum explicit */ /* v2: has the drd_length field, enum value in uchar member */ #define DWARF_DRD_BUFFER_VERSION 2 /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); /* Preferred version December 2018. */ int dwarf_get_die_markers_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Marker * /*marker_list*/, Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, Dwarf_Error *); int dwarf_get_string_attributes_info(Dwarf_P_Debug, Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_P_String_Attr *, Dwarf_Error *); void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Returns DW_DLV_OK or DW_DLV_ERROR */ int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small* /*block_data*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* dwarf_add_AT_reference_b allows otherdie to be NULL with the assumption the caller will then later call dwarf_fixup_AT_reference_die() with a non-null target die. New 22 October, 2013 */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Die /*otherdie*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie after a single pass thru the DIE generation. Needed for forward-references. New 22 October, 2013. */ int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pcvalue*/, Dwarf_Unsigned /*sym_index*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_string_a( Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); /* October 2017 for DW_FORM_data16. Usable with any attribute, though it should only be in limited use. DWARF5 only. Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. Returns the new attribute pointer through *return_attr. */ int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Form_Data16 * /* pointstovalue */, Dwarf_P_Attribute * /* return_attr */, Dwarf_Error * /*error*/); /* November 2018. DW_AT_implicit const generation. */ int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); /* Preferred as of December 2018. */ int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); /* Producer line creation functions (.debug_line) */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned * /*index_in_directories*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, Dwarf_Unsigned /*time_last_modified*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned * /*file_entry_count_out*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Bool /*is_epilogue_begin*/, Dwarf_Bool /*is_prologue_end*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, Dwarf_Unsigned /*lineno*/, Dwarf_Signed /*column_number*/, Dwarf_Bool /*is_source_stmt_begin*/, Dwarf_Bool /*is_basic_block_begin*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*offset*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, Dwarf_Small /*code_alignment_factor*/, Dwarf_Small /*data_alignment_factor*/, Dwarf_Small /*return_address_reg*/, Dwarf_Ptr /*initialization_bytes*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Unsigned * /*cie_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*corresponding subprogram die*/, Dwarf_Unsigned /*cie_to_use*/, Dwarf_Unsigned /*virt_addr_of_described_code*/, Dwarf_Unsigned /*length_of_code*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_fde_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*sym_idx*/, Dwarf_Unsigned /*sym_idx_of_end*/, Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Unsigned * /*index_to_fde*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_frame_info_c( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Unsigned * /*fde_index_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Unsigned /*end_symbol */, Dwarf_Addr /*offset_from_end_symbol */, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*cie*/, Dwarf_Addr /*virt_addr*/, Dwarf_Unsigned /*code_len*/, Dwarf_Unsigned /*symidx*/, Dwarf_Signed /*offset_into_exception_tables*/, Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); /* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_fde_inst_a( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*len*/, Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde * /*fde_out*/, Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_fde_cfa_offset_a( Dwarf_P_Fde /*fde*/, Dwarf_Unsigned /*register_number*/, Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); /* die creation & addition routines dwarf_new_die_a() new September 2016. Preferred over dwarf_new_die(). */ int dwarf_new_die_a( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_P_Die * /*die_out*/, Dwarf_Error* /*error*/); Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left */, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* New September 2016. */ int dwarf_add_die_to_debug_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Error* /*error*/); /* Markers are not written to DWARF2/3/4, they are user defined and may be used for any purpose. */ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error); Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* Preferred version, new December 2018. */ int dwarf_get_die_marker_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); /* New September 2016. Preferred version */ int dwarf_die_link_a( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); /* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, Dwarf_P_Die /*child*/, Dwarf_P_Die /*left*/, Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); void dwarf_dealloc_compressed_block( Dwarf_P_Debug, void * ); /* Call this passing in return value from dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); /* dwarf_compress_integer_block_a( new 11 February 2019. Like the earlier version this turns an array of signed integers into a block of sleb values (and if the values are small enough it might be a compression! Or it could be an expansion...). Return DW_DLV_OK on success. Supercedes dwarf_compress_integer_block(): as no ugly cast needed to know if dwarf_compress_integer_block_a() succeeds or not. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*input_array_length*/, Dwarf_Signed * /*input_array*/, Dwarf_Unsigned * /*output_block_len*/, void ** /*output_block_returned*/, Dwarf_Error * /*error */); /* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ Dwarf_Small, /*size of integer units: 8, 16, 32, 64*/ void*, /*data*/ Dwarf_Unsigned, /*number of elements*/ Dwarf_Unsigned*, /*number of bytes in output block*/ Dwarf_Error* /*error*/ ); /* New February 2019. On success returns DW_DLV_OK and creates an array of Dwarf_Signed values from the block of sleb numbers. This interface supercedes dwarf_uncompress_integer_block(). No ugly cast needed to know if dwarf_uncompress_integer_block_a() succeeds or not. */ int dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, Dwarf_Unsigned /*input_length_in_bytes*/, void * /*input_block*/, Dwarf_Unsigned * /*value_count*/, Dwarf_Signed ** /*value_array*/, Dwarf_Error * /*error*/); /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). Returns a DW_DLV_BADADDR on error. Otherwise returns a pointer to an array of 32bit integers. The signed argument must be non-zero (the decode assumes sleb integers in the input data) at this time. Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements of the array that the return value points to) thru the argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ Dwarf_Small, /*size of integer units: 8, 16, 32, 64 */ void*, /*input data */ Dwarf_Unsigned, /*number of bytes in input */ Dwarf_Unsigned*, /*number of units in output block */ Dwarf_Error* /*error */ ); /* Operations to create location expressions. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr * /*expr_out*/, Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_gen_a( Dwarf_P_Expr /*expr*/, Dwarf_Small /*opcode*/, Dwarf_Unsigned /*val1*/, Dwarf_Unsigned /*val2*/, Dwarf_Unsigned * /*next_byte_offset*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_expr_addr_c( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_current_offset_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned * /*next_byte_offset_out*/, Dwarf_Error* /*error*/); Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_expr_into_block_a( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Small ** /*start_address*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Signed /*symbol_index*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_arange_c( Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Unsigned /*end_symbol_index*/, Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_pubtype_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubtype_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_funcname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*func_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_typename_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); /* New December 2018. Preferred version. */ int dwarf_add_varname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); int dwarf_add_weakname_a( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); /* .debug_names producer functions */ /* dwarf_force_debug_names forces creation of .debug_names (if DWARF5 being produced) even if empty. Only for testing libdwarf. */ int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, Dwarf_Error* /*error*/); /* Other debug_names functions are needed... FIXME */ /* end .debug_names producer functions */ /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. */ int dwarf_def_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, with (arglist), no space before (*/, char * /*macvalue*/, Dwarf_Error* /*error*/); int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*line*/, char * /*macname, no arglist, of course*/, Dwarf_Error* /*error*/); int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*fileindex*/, Dwarf_Unsigned /*linenumber*/, Dwarf_Error* /*error*/); int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*constant*/, char * /*string*/, Dwarf_Error* /*error*/); /* end macinfo producer functions */ int dwarf_attr_offset(Dwarf_Die /*die*/, Dwarf_Attribute /*attr of above die*/, Dwarf_Off * /*returns offset thru this ptr */, Dwarf_Error * /*error*/); /* This is a hack so clients can verify offsets. Added April 2005 so that debugger can detect broken offsets (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); /* New October 2011., adds .debug_types section to the sizes returned. */ int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/, Dwarf_Unsigned * /*debug_macro_size*/, Dwarf_Unsigned * /*debug_str_offsets_size*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/, Dwarf_Unsigned * /*debug_names_size*/, Dwarf_Unsigned * /*debug_loclists_size*/, Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ /* Multiple releases spelled 'initial' as 'inital' . The 'inital' spelling should not be used. */ Dwarf_Half dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* Additional interface with correct 'initial' spelling. */ /* It is likely you will want to call the following 6 functions before accessing any frame information. All are useful to tailor handling of pseudo-registers needed to turn frame operation references into simpler forms and to reflect ABI specific data. Of course altering libdwarf.h and dwarf.h allow the same capabilities, but header changes in the distribution would require you re-integrate your libdwarf.h changes into the distributed libdwarf.h ... so use the following functions instead.*/ Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug /*dbg*/, Dwarf_Half /*value*/); /* dwarf_set_default_address_size only sets 'value' if value is greater than zero. */ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug /*dbg*/, Dwarf_Small /* value */); /* As of April 27, 2009, this version with no diepointer is obsolete though supported. Use dwarf_get_ranges_a() instead. */ int dwarf_get_ranges(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); /* This adds the address_size argument. New April 27, 2009 */ int dwarf_get_ranges_a(Dwarf_Debug /*dbg*/, Dwarf_Off /*rangesoffset*/, Dwarf_Die /* diepointer */, Dwarf_Ranges ** /*rangesbuf*/, Dwarf_Signed * /*listlen*/, Dwarf_Unsigned * /*bytecount*/, Dwarf_Error * /*error*/); void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); /* New April 2018. Allows applications to print the .debug_str_offsets section. Beginning at starting_offset zero, returns data about the first table found. The value *next_table_offset is the value of the next table (if any), one byte past the end of the table whose data is returned.. Returns DW_DLV_NO_ENTRY if the starting offset is past the end of valid data. There is no guarantee that there are no non-0 nonsense bytes in the section outside of useful tables, so this can fail and return nonsense or DW_DLV_ERROR if such garbage exists. */ struct Dwarf_Str_Offsets_Table_s; typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; /* Allocates a struct Dwarf_Str_Offsets_Table_s for the section and returns DW_DLV_OK and sets a pointer to the struct through the table_data pointer if successful. If there is no such section it returns DW_DLV_NO_ENTRY. */ int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, Dwarf_Str_Offsets_Table * /*table_data*/, Dwarf_Error * /*error*/); /* Close access, free table_data. */ int dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Error * /*error*/); /* Call till it returns DW_DLV_NO_ENTRY (normal end) or DW_DLV_ERROR (error) and stop. On successful call, call dwarf_str_offsets_table_entry() to get the individual table values on the now-active table. */ int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*unit_length*/, Dwarf_Unsigned * /*unit_length_offset*/, Dwarf_Unsigned * /*table_start_offset*/, Dwarf_Half * /*entry_size*/, Dwarf_Half * /*version*/, Dwarf_Half * /*padding*/, Dwarf_Unsigned * /*table_value_count*/, Dwarf_Error * /*error*/); /* Valid index values n: 0 <= n < table_entry_count for the active table */ int dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned /*index_to_entry*/, Dwarf_Unsigned * /*entry_value*/, Dwarf_Error * /*error*/); /* After all str_offsets read this reports final wasted-bytes count. */ int dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table /*table_data*/, Dwarf_Unsigned * /*wasted_byte_count*/, Dwarf_Unsigned * /*table_count*/, Dwarf_Error * /*error*/); /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 #define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). The pointers returned in the array of pointers are invalidated by ANY call to libdwarf. Use them before making another libdwarf call! The array of string pointers passed in always has a final null pointer, so if there are N pointers the and M actual strings, then MIN(M,N-1) pointers are set to point to error strings. The array of pointers to strings always terminates with a NULL pointer. If 'count' is passed in zero then errmsg_ptrs_array is not touched. The function returns DW_DLV_NO_ENTRY if no harmless errors were noted so far. Returns DW_DLV_OK if there are errors. Never returns DW_DLV_ERROR. Each call empties the error list (discarding all current entries). If newerr_count is non-NULL the count of harmless errors since the last call is returned through the pointer (some may have been discarded or not returned, it is a circular list...). If DW_DLV_NO_ENTRY is returned none of the arguments here are touched or used. */ int dwarf_get_harmless_error_list(Dwarf_Debug /*dbg*/, unsigned /*count*/, const char ** /*errmsg_ptrs_array*/, unsigned * /*newerr_count*/); /* Insertion is only for testing the harmless error code, it is not necessarily useful otherwise. */ void dwarf_insert_harmless_error(Dwarf_Debug /*dbg*/, char * /*newerror*/); /* The size of the circular list of strings may be set and reset as needed. If it is shortened excess messages are simply dropped. It returns the previous size. If zero passed in the size is unchanged and it simply returns the current size */ unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, unsigned /*maxcount*/); /* The harmless error strings (if any) are freed when the dbg is dwarf_finish()ed. */ /* When the val_in is known these dwarf_get_TAG_name (etc) functions return the string corresponding to the val_in passed in through the pointer s_out and the value returned is DW_DLV_OK. The strings are in static storage and must not be freed. If DW_DLV_NO_ENTRY is returned the val_in is not known and *s_out is not set. DW_DLV_ERROR is never returned.*/ /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); /* dwarf_get_LLEX_name is likely just temporary. Not standard. */ extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); /* END FILE */ /* Convert local offset into global offset */ int dwarf_convert_to_global_offset(Dwarf_Attribute /*attr*/, Dwarf_Off /*offset*/, Dwarf_Off* /*ret_offset*/, Dwarf_Error* /*error*/); /* Get both offsets (local and global) */ int dwarf_die_offsets(Dwarf_Die /*die*/, Dwarf_Off* /*global_offset*/, Dwarf_Off* /*local_offset*/, Dwarf_Error* /*error*/); /* Giving a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug /*dbg*/, const char * /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Giving a section index, get its size and address */ int dwarf_get_section_info_by_index(Dwarf_Debug /*dbg*/, int /*section_index*/, const char ** /*section_name*/, Dwarf_Addr* /*section_addr*/, Dwarf_Unsigned* /*section_size*/, Dwarf_Error* /*error*/); /* Get section count, of object file sections. */ int dwarf_get_section_count(Dwarf_Debug /*dbg*/); /* Get the version and offset size of a CU context. This is useful as a precursor to calling dwarf_get_form_class() at times. */ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); int dwarf_discr_list(Dwarf_Debug /*dbg*/, Dwarf_Small * /*blockpointer*/, Dwarf_Unsigned /*blocklen*/, Dwarf_Dsc_Head * /*dsc_head_out*/, Dwarf_Unsigned * /*dsc_array_length_out*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. Callers must know which is the appropriate one of the following two interfaces, though both will work. */ int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Unsigned * /*out_discr_low*/, Dwarf_Unsigned * /*out_discr_high*/, Dwarf_Error * /*error*/); /* NEW September 2016. Allows easy access to DW_AT_discr_list entry. */ int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, Dwarf_Unsigned /*entrynum*/, Dwarf_Half * /*out_type*/, Dwarf_Signed * /*out_discr_low*/, Dwarf_Signed * /*out_discr_high*/, Dwarf_Error * /*error*/); /* 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*/, Dwarf_Unsigned * /*section_count_out*/, Dwarf_Unsigned * /*group_count_out*/, Dwarf_Unsigned * /*selected_group_out*/, Dwarf_Unsigned * /*map_entry_count_out*/, Dwarf_Error * /*error*/); /* New May 2017. Reveals the map between group numbers and section numbers. Caller must allocate the arrays with space for 'map_entry_count' 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*/, Dwarf_Unsigned /*map_entry_count*/, Dwarf_Unsigned * /*group_numbers_array*/, Dwarf_Unsigned * /*sec_numbers_array*/, const char ** /*sec_names_array*/, Dwarf_Error * /*error*/); /* dwarf_get_endian_copy_function new. December 2019. */ void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/))(void *, const void * /*src*/, unsigned long /*srclen*/); /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); int dwarf_encode_signed_leb128(Dwarf_Signed /*val*/, int * /*nbytes*/, char * /*space*/, int /*splen*/); /* Record some application command line options in libdwarf. This is not arc/argv processing, just precooked setting of a flag in libdwarf based on something the application wants. check_verbose_mode of TRUE means do more checking and sometimes print errors (from libdwarf). Not restricted to a single Dwarf_Debug, it applies to the libdwarf the executable is using. */ typedef struct { Dwarf_Bool check_verbose_mode; } Dwarf_Cmdline_Options; extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned * /*str_count*/, Dwarf_Unsigned * /*str_total_length*/, Dwarf_Unsigned * /*count_debug_str*/, Dwarf_Unsigned * /*len_debug_str*/, Dwarf_Unsigned * /*reused_count*/, Dwarf_Unsigned * /*reused_len*/, Dwarf_Error * /*error*/); #ifndef DW_FTYPE_UNKNOWN #define DW_FTYPE_UNKNOWN 0 #define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ #define DW_FTYPE_MACH_O 2 /* MacOS. */ #define DW_FTYPE_PE 3 /* Windows */ #define DW_FTYPE_ARCHIVE 4 /* unix archive */ #define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ #endif /* DW_FTYPE_UNKNOWN */ #ifndef DW_ENDIAN_UNKNOWN #define DW_ENDIAN_UNKNOWN 0 #define DW_ENDIAN_BIG 1 #define DW_ENDIAN_LITTLE 2 #endif /* DW_ENDIAN_UNKNOWN */ int dwarf_object_detector_path(const char *path, char *outpath, unsigned long, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); int dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode); #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ dwarfutils-20200114/libdwarf/libdwarf2.1.mm000066400000000000000000014601301361531463500203050ustar00rootroot00000000000000e." \." the following line may be removed if the \." ff ligature works on your machine .lg 0 \." set up heading formats .ds HF 3 3 3 3 3 2 2 .ds HP +2 +2 +1 +0 +0 .nr Hs 5 .nr Hb 5 \." Increment body point size .S +2 \." ============================================== \." Put current date in the following at each rev .ds vE Rev 2.86, 6 January 2020 \." ============================================== \." ============================================== .ds | | .ds ~ ~ .ds ' ' .if t .ds Cw \&\f(CW .if n .ds Cw \fB .de Cf \" Place every other arg in Cw font, beginning with first .if \\n(.$=1 \&\*(Cw\\$1\fP .if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 .if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP .if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 .if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP .if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 .if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP .if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 .if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ *(Cw .. .nr Cl 4 .SA 1 .TL A Consumer Library Interface to DWARF .AF "" .AU "David Anderson" .PF "'\*(vE'- \\\\nP -''" .AS 1 This document describes an interface to a library of functions .FS UNIX is a registered trademark of UNIX System Laboratories, Inc. in the United States and other countries. .FE to access DWARF debugging information entries and DWARF line number information (and other DWARF2/3/4/5 information). It does not make recommendations as to how the functions described in this document should be implemented nor does it suggest possible optimizations. .P The document is oriented to reading DWARF version 2 and later. There are certain sections which are SGI-specific (those are clearly identified in the document). .P \*(vE .AE .MT 4 .H 1 "INTRODUCTION" This document describes an interface to \fIlibdwarf\fP, a library of functions to provide access to DWARF debugging information records, DWARF line number information, DWARF address range and global names information, weak names information, DWARF frame description information, DWARF static function names, DWARF static variables, and DWARF type information. .P The document has long mentioned the "Unix International Programming Languages Special Interest Group" (PLSIG), under whose auspices the DWARF committee was formed around 1991. "Unix International" was disbanded in the 1990s and no longer exists. .P The DWARF committee published DWARF2 July 27, 1993. .P In the mid 1990s this document and the library it describes (which the committee never endorsed, having decided not to endorse or approve any particular library interface) was made available on the internet by Silicon Graphics, Inc. .P In 2005 the DWARF committee began an affiliation with FreeStandards.org. In 2007 FreeStandards.org merged with The Linux Foundation. The DWARF committee dropped its affiliation with FreeStandards.org in 2007 and established the dwarfstd.org website. See "http://www.dwarfstd.org" for current information on standardization activities and a copy of the standard. .H 2 "Copyright" Copyright 1993-2006 Silicon Graphics, Inc. Copyright 2007-2019 David Anderson. Permission is hereby granted to copy or republish or use any or all of this document without restriction except that when publishing more than a small amount of the document please acknowledge Silicon Graphics, Inc and David Anderson. This document is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .H 2 "Purpose and Scope" The purpose of this document is to document a library of functions to access DWARF debugging information. There is no effort made in this document to address the creation of these records as those issues are addressed separately (see "A Producer Library Interface to DWARF"). .P Additionally, the focus of this document is the functional interface, and as such, implementation as well as optimization issues are intentionally ignored. .H 2 "Document History" .P A document was written about 1991 which had similar layout and interfaces. Written by people from Hal Corporation, That document described a library for reading DWARF1. The authors distributed paper copies to the committee with the clearly expressed intent to propose the document as a supported interface definition. The committee decided not to pursue a library definition. .P SGI wrote the document you are now reading in 1993 with a similar layout and content and organization, but it was complete document rewrite with the intent to read DWARF2 (the DWARF version then in existence). The intent was (and is) to also cover future revisions of DWARF. All the function interfaces were changed in 1994 to uniformly return a simple integer success-code (see DW_DLV_OK etc), generally following the recommendations in the chapter titled "Candy Machine Interfaces" of "Writing Solid Code", a book by Steve Maguire (published by Microsoft Press). .H 2 "Definitions" DWARF debugging information entries (DIEs) are the segments of information placed in the \f(CW.debug_*\fP sections by compilers, assemblers, and linkage editors that, in conjunction with line number entries, are necessary for symbolic source-level debugging. Refer to the latest "\fIDWARF Debugging Information Format\fP" from www.dwarfstd.org for a more complete description of these entries. .P This document adopts all the terms and definitions in "\fIDWARF Debugging Information Format\fP" versions 2,3,4, and 5. It originally focused on the implementation at Silicon Graphics, Inc., but now attempts to be more generally useful. .H 2 "Overview" The remaining sections of this document describe the proposed interface to \f(CWlibdwarf\fP, first by describing the purpose of additional types defined by the interface, followed by descriptions of the available operations. This document assumes you are thoroughly familiar with the information contained in the \fIDWARF Debugging Information Format\fP document. .P We separate the functions into several categories to emphasize that not all consumers want to use all the functions. We call the categories Debugger, Internal-level, High-level, and Miscellaneous not because one is more important than another but as a way of making the rather large set of function calls easier to understand. .P Unless otherwise specified, all functions and structures should be taken as being designed for Debugger consumers. .P The Debugger Interface of this library is intended to be used by debuggers. The interface is low-level (close to dwarf) but suppresses irrelevant detail. A debugger will want to absorb all of some sections at startup and will want to see little or nothing of some sections except at need. And even then will probably want to absorb only the information in a single compilation unit at a time. A debugger does not care about implementation details of the library. .P The Internal-level Interface is for a DWARF prettyprinter and checker. A thorough prettyprinter will want to know all kinds of internal things (like actual FORM numbers and actual offsets) so it can check for appropriate structure in the DWARF data and print (on request) all that internal information for human users and libdwarf authors and compiler-writers. Calls in this interface provide data a debugger does not normally care about. .P The High-level Interface is for higher level access (it is not really a high level interface!). Programs such as disassemblers will want to be able to display relevant information about functions and line numbers without having to invest too much effort in looking at DWARF. .P The miscellaneous interface is just what is left over: the error handler functions. .P The following is a brief mention of the changes in this libdwarf from the libdwarf draft for DWARF Version 1 and recent changes. .H 2 "Items Changed" .P Now we document here that if one uses dwarf_init() or dwarf_init_b() or dwarf_init_path() that the function dwarf_get_elf() cannot succeed as there is no longer any Elf pointer (from libelf) to return. (November 26, 2019) .P New function dwarf_gnu_debuglink() allow callers to access fields that GNU compilers create and use to link an executable to its separate DWARF debugging content object file. (September 9, 2019, updated October 2019) .P dwarf_next_cu_header_d() (and the other earlier versions of this) now allow a null in place of a pointer for next_cu_offset. dwarf_hipc_b() now allows a null in place of the return_form and/or return_class arguments. Unless you know a sufficiently recent libdwarf is to be used it is not safe to pass those arguments as null pointers. This allowance of null is because we've become aware that the relevant NetBSD man pages on these functions incorrectly specified that null was allowed. (April 22,2019) .P The dwarf_elf_init() and dwarf_elf_init_b() are now deprecated as they require the use of elf.h and libelf.h and libelf. Use dwarf_init_path() or dwarf_init_b() instead. The new non-libelf reader code checks elf header values more thoroughly than libelf and detects corrupted Elf earlier and in more cases than libelf. Since the reports of elf corruption from libdwarf/dwarfdump are not detailed we suggest one use an object dumper to check the object file in question. Two useful object dumpers are GNU readelf (part of GNU binutils) and readelfobj (part of the readelfobj project on sourceforge.net). readelfobj uses essentially the same algorithms as libdwarf does and should report something meaningful. (April 20,2019) .P Added support for MacOS dSYM objects and PE object files as well as an initialization function allowing a path instead of a Posix/Unix fd or a libelf Elf*. (January 2019) .P Added a libdwarf interface dwarf_errmsg_by_number() so that places in the code that can have errors but do not want the Dwarf_Error complexities can report more details than just an error number. (December 19, 2018) .P Now Mach-o dSYM files containing dwarf are readable by libdwarf and their DWARF dumped by dwarfdump. There are no new options or choices, libdwarf and dwarfdump notice which kind of object they are processing. New functions added to libdwarf.h.in: dwarf_init_path(),dwarf_object_detector_path(), and dwarf_object_detector_fd(). (October 24, 2018) .P All references to Dwarf_Frame_Op3 have been removed as that struct was never created or available. The new function dwarf_get_fde_info_for_reg3_b() is documented. (May 12, 2018) .P With DWARF5 it became harder to use dwarf_srclines_data_b() as DWARF5 changed each line table header file table to zero-based indexing from one-based (and made the primary file index zero). So a new function dwarf_srclines_file_indexes() returns values that make it easy to step through and call dwarf_srclines_data_b() sensibly whether the line table is DWARF2,3,4, or 5. (March 23, 2018) .P Added COMDAT support. Recent compilers generate COMDAT sections (for some DWARF information) routinely so this became important recently. The new libdwarf COMDAT support extends the groupnumber idea as suggested just below. (May 17, 2017) .P Adding dwarf_init_b() and dwarf_elf_init_b() and dwarf_object_init_b() with a groupnumber option added. DWARF5 adds split-dwarf and we call original sections like .debug_info group one and new sections like .debug_info.dwo group two. It has not escaped our attention that this numbering can be extended to deal with Elf COMDAT section groups of DWARF information, though COMDAT groups are not currently supported. (April 02, 2017) .P Adding support for DWARF5 .debug_loc.dwo and split dwarf range tables. Added dwarf_get_offset_size(). (November 08, 2015) .P Adding support for reading DWARF5 line tables and GNU two-level line tables. The function dwarf_srclines() still works but those using DWARF4 or DWARF5 are advised to switch to dwarf_srclines_b(). dwarf_srclines() cannot handle skeleton line tables sensibly and a new interface was needed for two-level line tables so the new approach satisfies both. (October 5,2015) .P Adding support for Package Files (DWARF5) to enable access of address data using DW_FORM_addrx. See dwarf_set_tied_dbg(). (September 13, 2015) .P Adding some DWARF5 support and improved DWP Package File support, using dwarf_next_cu_header_d(). .P Added a note about dwarf_errmsg(): the string pointer returned should be considered ephemeral, not a string which remains valid permanently. User code should print it or copy it before calling other libdwarf functions on the specific Dwarf_Debug instance. (May 15, 2014) .P Added a printf-callback so libdwarf will not actually print to stdout. Added dwarf_highpc_b() so return of a DWARF4 DW_AT_high_pc of class constant can be returned properly. (August 15 2013) .P Defined how the new operator DW_OP_GNU_const_type is handled. (January 26 2013) .P Added dwarf_loclist_from_expr_b() function which adds arguments of the DWARF version (2 for DWARF2, etc) and the offset size to the dwarf_loclist_from_expr_a() function. Because the DW_OP_GNU_implicit_pointer opcode is defined differently for DWARF2 than for later versions. (November 2012) .P Added new functions (some for libdwarf client code) and internal logic support for the DWARF4 .debug_types section. The new functions are dwarf_next_cu_header_c(), dwarf_siblingof_b(), dwarf_offdie_b(), dwarf_get_cu_die_offset_given_cu_header_offset_b(), dwarf_get_die_infotypes_flag(), dwarf_get_section_max_offsets_b(). .P New functions and logic support additional detailed error reporting so that more compiler bugs can be reported sensibly by consumer code (as opposed to having libdwarf just assume things are ok and blindly continuing on with erroneous data). November 20, 2010 .P It seems impossible to default to both DW_FRAME_CFA_COL and DW_FRAME_CFA_COL3 in a single build of libdwarf, so the default is now unambiguously DW_FRAME_CFA_COL3 unless the configure option --enable-oldframecol is specified at configure time. The function dwarf_set_frame_cfa_value() may be used to override the default : using that function gives consumer applications full control (its use is highly recommended). (January 17,2010) .P Added dwarf_set_reloc_application() and the default automatic application of Elf 'rela' relocations to DWARF sections (such rela sections appear in .o files, not in executables or shared objects, in general). The dwarf_set_reloc_application() routine lets a consumer turn off the automatic application of 'rela' relocations if desired (it is not clear why anyone would really want to do that, but possibly a consumer could write its own relocation application). An example application that traverses a set of DIEs was added to the new dwarfexample directory (not in this libdwarf directory, but in parallel to it). (July 10, 2009) .P Added dwarf_get_TAG_name() (and the FORM AT and so on) interface functions so applications can get the string of the TAG, Attribute, etc as needed. (June 2009) .P Added dwarf_get_ranges_a() and dwarf_loclist_from_expr_a() functions which add arguments allowing a correct address_size when the address_size varies by compilation unit (a varying address_size is quite rare as of May 2009). (May 2009) .P Added dwarf_set_frame_same_value(), and dwarf_set_frame_undefined_value() to complete the set of frame-information functions needed to allow an application get all frame information returned correctly (meaning that it can be correctly interpreted) for all ABIs. Documented dwarf_set_frame_cfa_value(). Corrected spelling to dwarf_set_frame_rule_initial_value(). (April 2009). .P Added support for various DWARF3 features, but primarily a new frame-information interface tailorable at run-time to more than a single ABI. See dwarf_set_frame_rule_initial_value(), dwarf_set_frame_rule_table_size(), dwarf_set_frame_cfa_value(). See also dwarf_get_fde_info_for_reg3() and dwarf_get_fde_info_for_cfa_reg3(). (April 2006) .P Added support for DWARF3 .debug_pubtypes section. Corrected various leaks (revising dealloc() calls, adding new functions) and corrected dwarf_formstring() documentation. .P Added dwarf_srclines_dealloc() as the previous deallocation method documented for data returned by dwarf_srclines() was incapable of freeing all the allocated storage (14 July 2005). .P dwarf_nextglob(), dwarf_globname(), and dwarf_globdie() were all changed to operate on the items in the .debug_pubnames section. .P All functions were modified to return solely an error code. Data is returned through pointer arguments. This makes writing safe and correct library-using-code far easier. For justification for this approach, see the chapter titled "Candy Machine Interfaces" in the book "Writing Solid Code" by Steve Maguire. .H 2 "Items Removed" .P Dwarf_Type was removed since types are no longer special. .P dwarf_typeof() was removed since types are no longer special. .P Dwarf_Ellist was removed since element lists no longer are a special format. .P Dwarf_Bounds was removed since bounds have been generalized. .P dwarf_nextdie() was replaced by dwarf_next_cu_header() to reflect the real way DWARF is organized. The dwarf_nextdie() was only useful for getting to compilation unit beginnings, so it does not seem harmful to remove it in favor of a more direct function. .P dwarf_childcnt() is removed on grounds that no good use was apparent. .P dwarf_prevline() and dwarf_nextline() were removed on grounds this is better left to a debugger to do. Similarly, dwarf_dieline() was removed. .P dwarf_is1stline() was removed as it was not meaningful for the revised DWARF line operations. .P Any libdwarf implementation might well decide to support all the removed functionality and to retain the DWARF Version 1 meanings of that functionality. This would be difficult because the original libdwarf draft specification used traditional C library interfaces which confuse the values returned by successful calls with exceptional conditions like failures and 'no more data' indications. .H 2 "Revision History" .VL 15 .LI "January 2019" Added support for reading DWARF in PE object files. .LI "October 2018" Added support for reading MacOS dSYM object files. .LI "2017" Added support for nearly all of DWARF5. .LI "July 2014" Added support for the .gdb_index section and started support for the .debug_cu_index and .debug_tu_index sections. .LI "October 2011" DWARF4 support for reading .debug_types added. .LI "March 93" Work on DWARF2 SGI draft begins .LI "June 94" The function returns are changed to return an error/success code only. .LI "April 2006: Support for DWARF3 consumer operations is close to completion. .LI "November 2010: Added various new functions and improved error checking. .LI "March 2017: Adding support for DWARF5 split dwarf. .LE .H 1 "Types Definitions" .H 2 "General Description" The \fIlibdwarf.h\fP header file contains typedefs and preprocessor definitions of types and symbolic names used to reference objects of \fIlibdwarf\fP. The types defined by typedefs contained in \fIlibdwarf.h\fP all use the convention of adding \f(CWDwarf_\fP as a prefix and can be placed in three categories: .BL .LI Scalar types : The scalar types defined in \fIlibdwarf.h\fP are defined primarily for notational convenience and identification. Depending on the individual definition, they are interpreted as a value, a pointer, or as a flag. .LI Aggregate types : Some values can not be represented by a single scalar type; they must be represented by a collection of, or as a union of, scalar and/or aggregate types. .LI Opaque types : The complete definition of these types is intentionally omitted; their use is as handles for query operations, which will yield either an instance of another opaque type to be used in another query, or an instance of a scalar or aggregate type, which is the actual result. .P .H 2 "Scalar Types" The following are the defined by \fIlibdwarf.h\fP: .DS \f(CW typedef int Dwarf_Bool; typedef unsigned long long Dwarf_Off; typedef unsigned long long Dwarf_Unsigned; typedef unsigned short Dwarf_Half; typedef unsigned char Dwarf_Small; typedef signed long long Dwarf_Signed; typedef unsigned long long Dwarf_Addr; typedef void *Dwarf_Ptr; typedef void (*Dwarf_Handler)(Dwarf_Error error, Dwarf_Ptr errarg); .DE .nr aX \n(Fg+1 Dwarf_Ptr is an address for use by the host program calling the library, not for representing pc-values/addresses within the target object file. Dwarf_Addr is for pc-values within the target object file. The sample scalar type assignments above are for a \fIlibdwarf.h\fP that can read and write 32-bit or 64-bit binaries on a 32-bit or 64-bit host machine. The types must be defined appropriately for each implementation of libdwarf. A description of these scalar types in the SGI/MIPS environment is given in Figure \n(aX. .DS .TS center box, tab(:); lfB lfB lfB lfB l c c l. NAME:SIZE:ALIGNMENT:PURPOSE _ Dwarf_Bool:4:4:Boolean states Dwarf_Off:8:8:Unsigned file offset Dwarf_Unsigned:8:8:Unsigned large integer Dwarf_Half:2:2:Unsigned medium integer Dwarf_Small:1:1:Unsigned small integer Dwarf_Signed:8:8:Signed large integer Dwarf_Addr:8:8:Program address :::(target program) Dwarf_Ptr:4|8:4|8:Dwarf section pointer :::(host program) Dwarf_Handler:4|8:4|8:Pointer to :::error handler function .TE .FG "Scalar Types" .DE .H 2 "Aggregate Types" The following aggregate types are defined by \fIlibdwarf.h\fP: \f(CWDwarf_Loc\fP, \f(CWDwarf_Locdesc\fP, \f(CWDwarf_Block\fP, \f(CWDwarf_Frame_Op\fP. \f(CWDwarf_Regtable\fP. \f(CWDwarf_Regtable3\fP. While most of \f(CWlibdwarf\fP acts on or returns simple values or opaque pointer types, this small set of structures seems useful. Yet, at the same time, these public structures are inflexible as any change in format or content breaks binary (and possibly source in some cases) compatibility. .H 3 "Location Record" The \f(CWDwarf_Loc\fP type identifies a single atom of a location description or a location expression. .DS \f(CWtypedef struct { Dwarf_Small lr_atom; Dwarf_Unsigned lr_number; Dwarf_Unsigned lr_number2; Dwarf_Unsigned lr_offset; } Dwarf_Loc;\fP .DE The \f(CWlr_atom\fP identifies the atom corresponding to the \f(CWDW_OP_*\fP definition in \fIdwarf.h\fP and it represents the operation to be performed in order to locate the item in question. .P The \f(CWlr_number\fP field is the operand to be used in the calculation specified by the \f(CWlr_atom\fP field; not all atoms use this field. Some atom operations imply signed numbers so it is necessary to cast this to a \f(CWDwarf_Signed\fP type for those operations. .P The \f(CWlr_number2\fP field is the second operand specified by the \f(CWlr_atom\fP field; only \f(CWDW_OP_BREGX\fP has this field. Some atom operations imply signed numbers so it may be necessary to cast this to a \f(CWDwarf_Signed\fP type for those operations. .P For a \f(CWDW_OP_implicit_value\fP operator the \f(CWlr_number2\fP field is a pointer to the bytes of the value. The field pointed to is \f(CWlr_number\fP bytes long. There is no explicit terminator. Do not attempt to \f(CWfree\fP the bytes which \f(CWlr_number2\fP points at and do not alter those bytes. The pointer value remains valid till the open Dwarf_Debug is closed. This is a rather ugly use of a host integer to hold a pointer. You will normally have to do a 'cast' operation to use the value. .P For a \f(CWDW_OP_GNU_const_type\fP operator the \f(CWlr_number2\fP field is a pointer to a block with an initial unsigned byte giving the number of bytes following, followed immediately that number of const value bytes. There is no explicit terminator. Do not attempt to \f(CWfree\fP the bytes which \f(CWlr_number2\fP points at and do not alter those bytes. The pointer value remains valid till the open Dwarf_Debug is closed. This is a rather ugly use of a host integer to hold a pointer. You will normally have to do a 'cast' operation to use the value. .P The \f(CWlr_offset\fP field is the byte offset (within the block the location record came from) of the atom specified by the \f(CWlr_atom\fP field. This is set on all atoms. This is useful for operations \f(CWDW_OP_SKIP\fP and \f(CWDW_OP_BRA\fP. .H 3 "Location Description" The \f(CWDwarf_Locdesc\fP type represents an ordered list of \f(CWDwarf_Loc\fP records used in the calculation to locate an item. Note that in many cases, the location can only be calculated at runtime of the associated program. .DS \f(CWtypedef struct { Dwarf_Addr ld_lopc; Dwarf_Addr ld_hipc; Dwarf_Unsigned ld_cents; Dwarf_Loc* ld_s; } Dwarf_Locdesc;\fP .DE The \f(CWld_lopc\fP and \f(CWld_hipc\fP fields provide an address range for which this location descriptor is valid. Both of these fields are set to \fIzero\fP if the location descriptor is valid throughout the scope of the item it is associated with. These addresses are virtual memory addresses, not offsets-from-something. The virtual memory addresses do not account for dso movement (none of the pc values from libdwarf do that, it is up to the consumer to do that). .P The \f(CWld_cents\fP field contains a count of the number of \f(CWDwarf_Loc\fP entries pointed to by the \f(CWld_s\fP field. .P The \f(CWld_s\fP field points to an array of \f(CWDwarf_Loc\fP records. .H 3 "Data Block" .SP The \f(CWDwarf_Block\fP type is used to contain the value of an attribute whose form is either \f(CWDW_FORM_block1\fP, \f(CWDW_FORM_block2\fP, \f(CWDW_FORM_block4\fP, \f(CWDW_FORM_block8\fP, or \f(CWDW_FORM_block\fP. Its intended use is to deliver the value for an attribute of any of these forms. .DS \f(CWtypedef struct { Dwarf_Unsigned bl_len; Dwarf_Ptr bl_data; } Dwarf_Block;\fP .DE .P The \f(CWbl_len\fP field contains the length in bytes of the data pointed to by the \f(CWbl_data\fP field. .P The \f(CWbl_data\fP field contains a pointer to the uninterpreted data. Since we use a \f(CWDwarf_Ptr\fP here one must copy the pointer to some other type (typically an \f(CWunsigned char *\fP) so one can add increments to index through the data. The data pointed to by \f(CWbl_data\fP is not necessarily at any useful alignment. .H 3 "Frame Operation Codes: DWARF 2" This interface is adequate for DWARF2 but not entirely suitable for DWARF3 or later. A new (functional) interface is needed. This DWARF2 interface is not sufficient but at present is the only available interface. .P See also the section "Low Level Frame Operations" below. .P The DWARF2 \f(CWDwarf_Frame_Op\fP type is used to contain the data of a single instruction of an instruction-sequence of low-level information from the section containing frame information. This is ordinarily used by Internal-level Consumers trying to print everything in detail. .DS \f(CWtypedef struct { Dwarf_Small fp_base_op; Dwarf_Small fp_extended_op; Dwarf_Half fp_register; Dwarf_Signed fp_offset; Dwarf_Offset fp_instr_offset; } Dwarf_Frame_Op; .DE \f(CWfp_base_op\fP is the 2-bit basic op code. \f(CWfp_extended_op\fP is the 6-bit extended opcode (if \f(CWfp_base_op\fP indicated there was an extended op code) and is zero otherwise. .P \f(CWfp_register\fP is any (or the first) register value as defined in the \f(CWCall frame instruction encodings\fP in the \f(CWdwarf\fP document (in DWARF3 see Figure 40,in DWARF5 see table 7.29). If not used with the operation it is 0. .P \f(CWfp_offset\fP is the address, delta, offset, or second register as defined in the \f(CWCall frame instruction encodings\fP documentation. If this is an \f(CWaddress\fP then the value should be cast to \f(CW(Dwarf_Addr)\fP before being used. In any implementation this field *must* be as large as the largest of Dwarf_Ptr, Dwarf_Signed, and Dwarf_Addr for this to work properly. If not used with the op it is 0. If the fp_extended_op is \f(CWDW_CFA_def_cfa\fP or \f(CWDW_CFA_val_expression\fP or \f(CWDW_CFA_expression\fP then \f(CWfp_offset\fP is a pointer to an expression block in the in-memory copy of the frame section. .P \f(CWfp_instr_offset\fP is the byte_offset (within the instruction stream of the frame instructions) of this operation. It starts at 0 for a given frame descriptor. .H 3 "Frame Regtable: DWARF 2" This interface is adequate for DWARF2 and MIPS but not for DWARF3 or later. A separate and preferred interface usable for DWARF3 and for DWARF2 is described below. See also the section "Low Level Frame Operations" below. .P The \f(CWDwarf_Regtable\fP type is used to contain the register-restore information for all registers at a given PC value. Normally used by debuggers. If you wish to default to this interface and to the use of DW_FRAME_CFA_COL, specify --enable_oldframecol at libdwarf configure time. Or add a call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL) after your dwarf_init_b() call, this call replaces the default libdwarf-compile-time value with DW_FRAME_CFA_COL. .DS /* DW_REG_TABLE_SIZE must reflect the number of registers *(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h */ #define DW_REG_TABLE_SIZE \f(CWtypedef struct { struct { Dwarf_Small dw_offset_relevant; Dwarf_Half dw_regnum; Dwarf_Addr dw_offset; } rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable;\fP .DE .P The array is indexed by register number. The field values for each index are described next. For clarity we describe the field values for index rules[M] (M being any legal array element index). .P \f(CWdw_offset_relevant\fP is non-zero to indicate the \f(CWdw_offset\fP field is meaningful. If zero then the \f(CWdw_offset\fP is zero and should be ignored. .P \f(CWdw_regnum \fPis the register number applicable. If \f(CWdw_offset_relevant\fP is zero, then this is the register number of the register containing the value for register M. If \f(CWdw_offset_relevant\fP is non-zero, then this is the register number of the register to use as a base (M may be DW_FRAME_CFA_COL, for example) and the \f(CWdw_offset\fP value applies. The value of register M is therefore the value of register \f(CWdw_regnum\fP. .P \f(CWdw_offset\fP should be ignored if \f(CWdw_offset_relevant\fP is zero. If \f(CWdw_offset_relevant\fP is non-zero, then the consumer code should add the value to the value of the register \f(CWdw_regnum\fP to produce the value. .H 3 "Frame Operation Codes: DWARF 3 (for DWARF2 and later ) This interface was intended to be adequate for DWARF3 and for DWARF2 (and DWARF4) but was never implemented. .H 3 "Frame Regtable: DWARF 3 (for DWARF2 and later)" This interface is adequate for DWARF2 and later versions. It is new in libdwarf as of April 2006. The default configure of libdwarf inserts DW_FRAME_CFA_COL3 as the default CFA column. Or add a call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL3) after your dwarf_init_b() call, this call replaces the default libdwarf-compile-time value with DW_FRAME_CFA_COL3. .P The \f(CWDwarf_Regtable3\fP type is used to contain the register-restore information for all registers at a given PC value. Normally used by debuggers. .DS \f(CWtypedef struct Dwarf_Regtable_Entry3_s { Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; }Dwarf_Regtable_Entry3; typedef struct Dwarf_Regtable3_s { struct Dwarf_Regtable_Entry3_s rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; struct Dwarf_Regtable_Entry3_s * rt3_rules; } Dwarf_Regtable3;\fP .DE .P The array is indexed by register number. The field values for each index are described next. For clarity we describe the field values for index rules[M] (M being any legal array element index). (DW_FRAME_CFA_COL3 DW_FRAME_SAME_VAL, DW_FRAME_UNDEFINED_VAL are not legal array indexes, nor is any index < 0 or >= rt3_reg_table_size); The caller of routines using this struct must create data space for rt3_reg_table_size entries of struct Dwarf_Regtable_Entry3_s and arrange that rt3_rules points to that space and that rt3_reg_table_size is set correctly. The caller need not (but may) initialize the contents of the rt3_cfa_rule or the rt3_rules array. The following applies to each rt3_rules rule M: .P .in +4 \f(CWdw_regnum\fP is the register number applicable. If \f(CWdw_regnum\fP is DW_FRAME_UNDEFINED_VAL, then the register I has undefined value. If \f(CWdw_regnum\fP is DW_FRAME_SAME_VAL, then the register I has the same value as in the previous frame. .P If \f(CWdw_regnum\fP is neither of these two, then the following apply: .P .P \f(CWdw_value_type\fP determines the meaning of the other fields. It is one of DW_EXPR_OFFSET (0), DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or DW_EXPR_VAL_EXPRESSION(3). .P If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (0) then this is as in DWARF2 and the offset(N) rule or the register(R) rule of the DWARF3 and DWARF2 document applies. The value is either: .in +4 If \f(CWdw_offset_relevant\fP is non-zero, then \f(CWdw_regnum\fP is effectively ignored but must be identical to DW_FRAME_CFA_COL3 (and the \f(CWdw_offset\fP value applies. The value of register M is therefore the value of CFA plus the value of \f(CWdw_offset\fP. The result of the calculation is the address in memory where the value of register M resides. This is the offset(N) rule of the DWARF2 and DWARF3 documents. .P \f(CWdw_offset_relevant\fP is zero it indicates the \f(CWdw_offset\fP field is not meaningful. The value of register M is the value currently in register \f(CWdw_regnum\fP (the value DW_FRAME_CFA_COL3 must not appear, only real registers). This is the register(R) rule of the DWARF3 spec. .in -4 .P If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (1) then this is the the val_offset(N) rule of the DWARF3 spec applies. The calculation is identical to that of DW_EXPR_OFFSET (0) but the value is interpreted as the value of register M (rather than the address where register M's value is stored). .P If \f(CWdw_value_type\fP is DW_EXPR_EXPRESSION (2) then this is the the expression(E) rule of the DWARF3 document. .P .in +4 \f(CWdw_offset_or_block_len\fP is the length in bytes of the in-memory block pointed at by \f(CWdw_block_ptr\fP. \f(CWdw_block_ptr\fP is a DWARF expression. Evaluate that expression and the result is the address where the previous value of register M is found. .in -4 .P If \f(CWdw_value_type\fP is DW_EXPR_VAL_EXPRESSION (3) then this is the the val_expression(E) rule of the DWARF3 spec. .P .in +4 \f(CWdw_offset_or_block_len\fP is the length in bytes of the in-memory block pointed at by \f(CWdw_block_ptr\fP. \f(CWdw_block_ptr\fP is a DWARF expression. Evaluate that expression and the result is the previous value of register M. .in -4 .P The rule \f(CWrt3_cfa_rule\fP is the current value of the CFA. It is interpreted exactly like any register M rule (as described just above) except that \f(CWdw_regnum\fP cannot be CW_FRAME_CFA_REG3 or DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL but must be a real register number. .in -4 .H 3 "Macro Details Record" The \f(CWDwarf_Macro_Details\fP type gives information about a single entry in the .debug.macinfo section (DWARF2, DWARF3, and DWARF4). It is not useful for DWARF 5 .debug_macro section data. .DS \f(CWstruct Dwarf_Macro_Details_s { Dwarf_Off dmd_offset; Dwarf_Small dmd_type; Dwarf_Signed dmd_lineno; Dwarf_Signed dmd_fileindex; char * dmd_macro; }; typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; .DE .P \f(CWdmd_offset\fP is the byte offset, within the .debug_macinfo section, of this macro information. .P \f(CWdmd_type\fP is the type code of this macro info entry (or 0, the type code indicating that this is the end of macro information entries for a compilation unit. See \f(CWDW_MACINFO_define\fP, etc in the DWARF document. .P \f(CWdmd_lineno\fP is the line number where this entry was found, or 0 if there is no applicable line number. .P \f(CWdmd_fileindex\fP is the file index of the file involved. This is only guaranteed meaningful on a \f(CWDW_MACINFO_start_file\fP \f(CWdmd_type\fP. Set to -1 if unknown (see the functional interface for more details). .P \f(CWdmd_macro\fP is the applicable string. For a \f(CWDW_MACINFO_define\fP this is the macro name and value. For a \f(CWDW_MACINFO_undef\fP, or this is the macro name. For a \f(CWDW_MACINFO_vendor_ext\fP this is the vendor-defined string value. For other \f(CWdmd_type\fPs this is 0. .H 2 "Opaque Types" The opaque types declared in \fIlibdwarf.h\fP are used as descriptors for queries against DWARF information stored in various debugging sections. Each time an instance of an opaque type is returned as a result of a \fIlibdwarf\fP operation (\f(CWDwarf_Debug\fP excepted), it should be freed, using \f(CWdwarf_dealloc()\fP when it is no longer of use (read the following documentation for details, as in at least one case there is a special routine provided for deallocation and \f(CWdwarf_dealloc()\fP is not directly called: see \f(CWdwarf_srclines()\fP). Some functions return a number of instances of an opaque type in a block, by means of a pointer to the block and a count of the number of opaque descriptors in the block: see the function description for deallocation rules for such functions. The list of opaque types defined in \fIlibdwarf.h\fP that are pertinent to the Consumer Library, and their intended use is described below. .DS \f(CWtypedef struct Dwarf_Debug_s* Dwarf_Debug;\fP .DE An instance of the \f(CWDwarf_Debug\fP type is created as a result of a successful call to \f(CWdwarf_init_b()\fP, or \f(CWdwarf_elf_init_b()\fP, and is used as a descriptor for subsequent access to most \f(CWlibdwarf\fP functions on that object. The storage pointed to by this descriptor should be not be freed, using the \f(CWdwarf_dealloc()\fP function. Instead free it with \f(CWdwarf_finish()\fP. .P .DS \f(CWtypedef struct Dwarf_Die_s* Dwarf_Die;\fP .DE An instance of a \f(CWDwarf_Die\fP type is returned from a successful call to the \f(CWdwarf_siblingof()\fP, \f(CWdwarf_child\fP, or \f(CWdwarf_offdie_b()\fP function, and is used as a descriptor for queries about information related to that DIE. The storage pointed to by this descriptor should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_DIE\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Line_s* Dwarf_Line;\fP .DE Instances of \f(CWDwarf_Line\fP type are returned from a successful call to the \f(CWdwarf_srclines()\fP function, and are used as descriptors for queries about source lines. The storage pointed to by these descriptors should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LINE\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Global_s* Dwarf_Global;\fP .DE Instances of \f(CWDwarf_Global\fP type are returned from a successful call to the \f(CWdwarf_get_globals()\fP function, and are used as descriptors for queries about global names (pubnames). .DS \f(CWtypedef struct Dwarf_Weak_s* Dwarf_Weak;\fP .DE Instances of \f(CWDwarf_Weak\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_weaks()\fP function, and are used as descriptors for queries about weak names. The storage pointed to by these descriptors should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_WEAK_CONTEXT\fP (or \f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility) when no longer needed. .DS \f(CWtypedef struct Dwarf_Func_s* Dwarf_Func;\fP .DE Instances of \f(CWDwarf_Func\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_funcs()\fP function, and are used as descriptors for queries about static function names. .DS \f(CWtypedef struct Dwarf_Type_s* Dwarf_Type;\fP .DE Instances of \f(CWDwarf_Type\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_types()\fP function, and are used as descriptors for queries about user defined types. .DS \f(CWtypedef struct Dwarf_Var_s* Dwarf_Var;\fP .DE Instances of \f(CWDwarf_Var\fP type are returned from a successful call to the SGI-specific \f(CWdwarf_get_vars()\fP function, and are used as descriptors for queries about static variables. .DS \f(CWtypedef struct Dwarf_Error_s* Dwarf_Error;\fP .DE This descriptor points to a structure that provides detailed information about errors detected by \f(CWlibdwarf\fP. Users typically provide a location for \f(CWlibdwarf\fP to store this descriptor for the user to obtain more information about the error. The storage pointed to by this descriptor should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ERROR\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Attribute_s* Dwarf_Attribute;\fP .DE Instances of \f(CWDwarf_Attribute\fP type are returned from a successful call to the \f(CWdwarf_attrlist()\fP, or \f(CWdwarf_attr()\fP functions, and are used as descriptors for queries about attribute values. The storage pointed to by this descriptor should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Abbrev_s* Dwarf_Abbrev;\fP .DE An instance of a \f(CWDwarf_Abbrev\fP type is returned from a successful call to \f(CWdwarf_get_abbrev()\fP, and is used as a descriptor for queries about abbreviations in the .debug_abbrev section. The storage pointed to by this descriptor should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Fde_s* Dwarf_Fde;\fP .DE Instances of \f(CWDwarf_Fde\fP type are returned from a successful call to the \f(CWdwarf_get_fde_list()\fP, \f(CWdwarf_get_fde_for_die()\fP, or \f(CWdwarf_get_fde_at_pc()\fP functions, and are used as descriptors for queries about frames descriptors. .DS \f(CWtypedef struct Dwarf_Cie_s* Dwarf_Cie;\fP .DE Instances of \f(CWDwarf_Cie\fP type are returned from a successful call to the \f(CWdwarf_get_fde_list()\fP function, and are used as descriptors for queries about information that is common to several frames. .DS \f(CWtypedef struct Dwarf_Arange_s* Dwarf_Arange;\fP .DE Instances of \f(CWDwarf_Arange\fP type are returned from successful calls to the \f(CWdwarf_get_aranges()\fP, or \f(CWdwarf_get_arange()\fP functions, and are used as descriptors for queries about address ranges. The storage pointed to by this descriptor should be individually freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ARANGE\fP when no longer needed. .DS \f(CWtypedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex;\fP .DE Instances of \f(CWDwarf_Gdbindex\fP type are returned from successful calls to the \f(CWdwarf_gdbindex_header()\fP function and are used to extract information from a .gdb_index section. This section is a gcc/gdb extension and is designed to allow a debugger fast access to data in .debug_info. The storage pointed to by this descriptor should be freed using a call to \f(CWdwarf_gdbindex_free()\fP with a valid \f(CWDwarf_Gdbindex\fP pointer as the argument. .DS \f(CWtypedef struct Dwarf_Xu_Index_Header_s* Dwarf_Xu_Index_header;\fP .DE Instances of \f(CWDwarf_Xu_Index_Header_s\fP type are returned from successful calls to the \f(CWdwarf_get_xu_index_header()\fP function and are used to extract information from a .debug_cu_index or .debug_tu_index section. These sections are used to make possible access to .dwo sections gathered into a .dwp object as part of the DebugFission (ie Split Dwarf) project allowing separation of an executable from most of its DWARF debugging information. As of May 2015 these sections are accepted into DWARF5 but the standard has not been released. The storage pointed to by this descriptor should be freed using a call to \f(CWdwarf_xh_header_free()\fP with a valid \f(CWDwarf_XuIndexHeader\fP pointer as the argument. .DS \f(CWtypedef struct Dwarf_Line_Context_s * Dwarf_Line_Context;\fP .DE \f(CWdwarf_srclines_b()\fP returns a Dwarf_Line_Context through an argument and the new structure pointer lets us access line header information conveniently. .DS \f(CWtypedef struct Dwarf_Loc_c_s * Dwarf_Loc_c;\fP \f(CWtypedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c;\fP \f(CWtypedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c;\fP .DE \f(CWDwarf_Loc*\fP are involved in the DWARF5 interfaces to location lists. The new interfaces are all functional and contents of the above types are not exposed. .DS \f(CWtypedef struct Dwarf_Macro_Context_s * Dwarf_Macro_Context;\fP .DE \f(CWdwarf_get_macro_context()\fP and \f(CWdwarf_get_macro_context_by_offset()\fP return a Dwarf_Line_Context through an argument and the new structure pointer lets us access macro data from the .debug_macro section. .DS \f(CWtypedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head;\fP .DE \f(CWdwarf_discr_list()\fP returns a Dwarf_Dsc_Head through an argument and the new structure pointer lets us access macro data from a \f(CWDW_AT_discr_list\fP attribute. .H 1 "UTF-8 strings" \fIlibdwarf\fP is defined, at various points, to return string pointers or to copy strings into string areas you define. DWARF allows the use of \f(CWDW_AT_use_UTF8\fP (DWARF3 and later) \f(CWDW_ATE_UTF\fP (DWARF4 and later) to specify that the strings returned are actually in UTF-8 format. What this means is that if UTF-8 is specfied on a particular object it is up to callers that wish to print all the characters properly to use language-appropriate functions to print Unicode strings appropriately. All ASCII characters in the strings will print properly whether printed as wide characters or not. The methods to convert UTF-8 strings so they will print correctly for all such strings is beyond the scope of this document. .P If UTF-8 is not specified then one is probably safe in assuming the strings are iso_8859-15 and normal C printf() will work fine.. .P In either case one should be wary of corrupted (accidentally or intentionally) strings with ASCII control characters in the text. Such can cause bad effects if simply printed to a device (such as a terminal). .H 1 "Error Handling" The method for detection and disposition of error conditions that arise during access of debugging information via \fIlibdwarf\fP is consistent across all \fIlibdwarf\fP functions that are capable of producing an error. This section describes the method used by \fIlibdwarf\fP in notifying client programs of error conditions. .P Most functions within \fIlibdwarf\fP accept as an argument a pointer to a \f(CWDwarf_Error\fP descriptor where a \f(CWDwarf_Error\fP descriptor is stored if an error is detected by the function. Routines in the client program that provide this argument can query the \f(CWDwarf_Error\fP descriptor to determine the nature of the error and perform appropriate processing. The intent is that clients do the appropriate processing immediately on encountering an error and then the client calls \f(CWdwarf_dealloc\fP to free the descriptor. .P In the rare case where the malloc arena is exhausted when trying to create a Dwarf_Error descriptor a pointer to a statically allocated descriptor will be returned. This static descriptor is new in December 2014. A call to \f(CWdwarf_dealloc()\fP to free the statically allocated descriptor is harmless (it sets the error value in the descriptor to DW_DLE_FAILSAFE_ERRVAL). The possible conflation of errors when the arena is exhausted (and a dwarf_error descriptor is saved past the next reader call in any thread) is considered better than having \fIlibdwarf\fP call \f(CWabort()\fP (as earlier \fIlibdwarf\fP did). .P A client program can also specify a function to be invoked upon detection of an error at the time the library is initialized (see \f(CWdwarf_init_b()\fP). When a \fIlibdwarf\fP routine detects an error, this function is called with two arguments: a code indicating the nature of the error and a pointer provided by the client at initialization (again see \f(CWdwarf_init_b()\fP). This pointer argument can be used to relay information between the error handler and other routines of the client program. A client program can specify or change both the error handling function and the pointer argument after initialization using \f(CWdwarf_seterrhand()\fP and \f(CWdwarf_seterrarg()\fP. .P In the case where \fIlibdwarf\fP functions are not provided a pointer to a \f(CWDwarf_Error\fP descriptor, and no error handling function was provided at initialization, \fIlibdwarf\fP functions print a short message to stdout and terminate exectution with \f(CWabort()\fP. .P Before March 2016 \fIlibdwarf\fP gave up when there was no error handling by emitting a short message on \f(CWstderr\fP calling \f(CWabort(3C)\fP. .P The following lists the processing steps taken upon detection of an error: .AL 1 .LI Check the \f(CWerror\fP argument; if not a \fINULL\fP pointer, allocate and initialize a \f(CWDwarf_Error\fP descriptor with information describing the error, place this descriptor in the area pointed to by \f(CWerror\fP, and return a value indicating an error condition. .LI If an \f(CWerrhand\fP argument was provided to \f(CWdwarf_init_b()\fP at initialization, call \f(CWerrhand()\fP passing it the error descriptor and the value of the \f(CWerrarg\fP argument provided to \f(CWdwarf_init_b()\fP. If the error handling function returns, return \f(CWDW_DLV_ERROR\fP indicating an error condition. .LI If neither the \f(CWerror\fP argument nor an \f(CWerrhand\fP argument was provided Terminate program execution by calling \f(CWabort(3C)\fP. .LE .SP In all cases, it is clear from the value returned from a function that an error occurred in executing the function, since DW_DLV_ERROR is returned. .P As can be seen from the above steps, the client program can provide an error handler at initialization, and still provide an \f(CWerror\fP argument to \fIlibdwarf\fP functions when it is not desired to have the error handler invoked. .P If a \f(CWlibdwarf\fP function is called with invalid arguments, the behavior is undefined. In particular, supplying a \f(CWNULL\fP pointer to a \f(CWlibdwarf\fP function (except where explicitly permitted), or pointers to invalid addresses or uninitialized data causes undefined behavior; the return value in such cases is undefined, and the function may fail to invoke the caller supplied error handler or to return a meaningful error number. Implementations also may abort execution for such cases. .P Some errors are so inconsequential that it does not warrant rejecting an object or returning an error. An example would be a frame length not being a multiple of an address-size (right now this is the only such inconsequential error). To make it possible for a client to report such errors the function \f(CWdwarf_get_harmless_error_list\fP returns strings with error text in them. This function may be ignored if client code does not want to bother with such error reporting. See \f(CWDW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE\fP in the libdwarf source code. .P .H 2 "Returned values in the functional interface" Values returned by \f(CWlibdwarf\fP functions to indicate success and errors .nr aX \n(Fg+1 are enumerated in Figure \n(aX. The \f(CWDW_DLV_NO_ENTRY\fP case is useful for functions need to indicate that while there was no data to return there was no error either. For example, \f(CWdwarf_siblingof()\fP may return \f(CWDW_DLV_NO_ENTRY\fP to indicate that that there was no sibling to return. .DS .TS center box, tab(:); lfB cfB lfB l c l. SYMBOLIC NAME:VALUE:MEANING _ DW_DLV_ERROR:1:Error DW_DLV_OK:0:Successful call DW_DLV_NO_ENTRY:-1:No applicable value .TE .FG "Error Indications" .DE .P Each function in the interface that returns a value returns one of the integers in the above figure. .P If \f(CWDW_DLV_ERROR\fP is returned and a pointer to a \f(CWDwarf_Error\fP pointer is passed to the function, then a Dwarf_Error handle is returned through the pointer. No other pointer value in the interface returns a value. After the \f(CWDwarf_Error\fP is no longer of interest, a \f(CWdwarf_dealloc(dbg,dw_err,DW_DLA_ERROR)\fP on the error pointer is appropriate to free any space used by the error information. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned no pointer value in the interface returns a value. .P If \f(CWDW_DLV_OK\fP is returned, the \f(CWDwarf_Error\fP pointer, if supplied, is not touched, but any other values to be returned through pointers are returned. In this case calls (depending on the exact function returning the error) to \f(CWdwarf_dealloc()\fP may be appropriate once the particular pointer returned is no longer of interest. .P Pointers passed to allow values to be returned through them are uniformly the last pointers in each argument list. .P All the interface functions are defined from the point of view of the writer-of-the-library (as is traditional for UN*X library documentation), not from the point of view of the user of the library. The caller might code: .P .DS \f(CWDwarf_Line line; Dwarf_Signed ret_loff; Dwarf_Error err; int retval = dwarf_lineoff(line,&ret_loff,&err);\fP .DE for the function defined as .P .DS \f(CWint dwarf_lineoff(Dwarf_Line line,Dwarf_Signed *return_lineoff, Dwarf_Error* err);\fP .DE and this document refers to the function as returning the value through *err or *return_lineoff or uses the phrase "returns in the location pointed to by err". Sometimes other similar phrases are used. .H 1 "Memory Management" Several of the functions that comprise \fIlibdwarf\fP return pointers (opaque descriptors) to structures that have been dynamically allocated by the library. To manage dynamic memory the function \f(CWdwarf_dealloc()\fP is provided to free storage allocated as a result of a call to a \fIlibdwarf\fP function. Some additional functions (described later) are provided to free storage in particular circumstances. This section describes the general strategy that should be taken by a client program in managing dynamic storage. .H 2 "Read-only Properties" All pointers (opaque descriptors) returned by or as a result of a \fIlibdwarf Consumer Library\fP call should be assumed to point to read-only memory. The results are undefined for \fIlibdwarf\fP clients that attempt to write to a region pointed to by a value returned by a \fIlibdwarf Consumer Library\fP call. .H 2 "Storage Deallocation" See the section "Returned values in the functional interface", above, for the general rules where calls to \f(CWdwarf_dealloc()\fP is appropriate. .P In some cases the pointers returned by a \fIlibdwarf\fP call are pointers to data which is not freeable. The library knows from the allocation type provided to it whether the space is freeable or not and will not free inappropriately when \f(CWdwarf_dealloc()\fP is called. So it is vital that \f(CWdwarf_dealloc()\fP be called with the proper allocation type. .P For most storage allocated by \fIlibdwarf\fP, the client can free the storage for reuse by calling \f(CWdwarf_dealloc()\fP, providing it with the \f(CWDwarf_Debug\fP descriptor specifying the object for which the storage was allocated, a pointer to the area to be free-ed, and an identifier that specifies what the pointer points to (the allocation type). For example, to free a \f(CWDwarf_Die die\fP belonging the the object represented by \f(CWDwarf_Debug dbg\fP, allocated by a call to \f(CWdwarf_siblingof()\fP, the call to \f(CWdwarf_dealloc()\fP would be: .DS \f(CWdwarf_dealloc(dbg, die, DW_DLA_DIE);\fP .DE To free storage allocated in the form of a list of pointers (opaque descriptors), each member of the list should be deallocated, followed by deallocation of the actual list itself. The following code fragment uses an invocation of \f(CWdwarf_attrlist()\fP as an example to illustrate a technique that can be used to free storage from any \fIlibdwarf\fP routine that returns a list: .DS .FG "Example1 dwarf_attrlist()" \f(CW void example1(Dwarf_Die somedie) { Dwarf_Debug dbg = 0; Dwarf_Signed atcount; Dwarf_Attribute *atlist; Dwarf_Error error = 0; Dwarf_Signed i = 0; int errv; errv = dwarf_attrlist(somedie, &atlist,&atcount, &error); if (errv == DW_DLV_OK) { for (i = 0; i < atcount; ++i) { /* use atlist[i] */ dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } } \fP .DE The \f(CWDwarf_Debug\fP returned from \f(CWdwarf_init_b()\fP or \f(CWdwarf_elf_init_b()\fP cannot be freed using \f(CWdwarf_dealloc()\fP. The function \f(CWdwarf_finish()\fP will deallocate all dynamic storage associated with an instance of a \f(CWDwarf_Debug\fP type. In particular, it will deallocate all dynamically allocated space associated with the \f(CWDwarf_Debug\fP descriptor, and finally make the descriptor invalid. An \f(CWDwarf_Error\fP returned from \f(CWdwarf_init_b()\fP or \f(CWdwarf_elf_init_b()\fP in case of a failure cannot be freed using \f(CWdwarf_dealloc()\fP. The only way to free the \f(CWDwarf_Error\fP from either of those calls is to use \f2free(3)\fP directly. Every \f(CWDwarf_Error\fP must be freed by \f(CWdwarf_dealloc()\fP except those returned by \f(CWdwarf_init_b()\fP or \f(CWdwarf_elf_init_b()\fP. .P The codes that identify the storage pointed to in calls to .nr aX \n(Fg+1 \f(CWdwarf_dealloc()\fP are described in figure \n(aX. .DS .TS center box, tab(:); lfB lfB l l. IDENTIFIER:USED TO FREE _ DW_DLA_STRING : char* DW_DLA_LOC : Dwarf_Loc DW_DLA_LOCDESC : Dwarf_Locdesc DW_DLA_ELLIST : Dwarf_Ellist (not used) DW_DLA_BOUNDS : Dwarf_Bounds (not used) DW_DLA_BLOCK : Dwarf_Block DW_DLA_DEBUG : Dwarf_Debug (do not use) DW_DLA_DIE : Dwarf_Die DW_DLA_LINE : Dwarf_Line DW_DLA_ATTR : Dwarf_Attribute DW_DLA_TYPE : Dwarf_Type (not used) DW_DLA_SUBSCR : Dwarf_Subscr (not used) DW_DLA_GLOBAL_CONTEXT : Dwarf_Global DW_DLA_ERROR : Dwarf_Error DW_DLA_LIST : a list of opaque descriptors DW_DLA_LINEBUF : Dwarf_Line* (not used) DW_DLA_ARANGE : Dwarf_Arange DW_DLA_ABBREV : Dwarf_Abbrev DW_DLA_FRAME_OP : Dwarf_Frame_Op DW_DLA_CIE : Dwarf_Cie DW_DLA_FDE : Dwarf_Fde DW_DLA_LOC_BLOCK : Dwarf_Loc Block DW_DLA_FRAME_BLOCK : Dwarf_Frame Block (not used) DW_DLA_FUNC_CONTEXT : Dwarf_Func DW_DLA_TYPENAME_CONTEXT : Dwarf_Type DW_DLA_VAR_CONTEXT : Dwarf_Var DW_DLA_WEAK_CONTEXT : Dwarf_Weak DW_DLA_PUBTYPES_CONTEXT : Dwarf_Type .TE .FG "Allocation/Deallocation Identifiers" .DE .P .H 1 "Functional Interface" This section describes the functions available in the \fIlibdwarf\fP library. Each function description includes its definition, followed by one or more paragraph describing the function's operation. .P The following sections describe these functions. .H 2 "Initialization Operations" These functions are concerned with preparing an object file for subsequent access by the functions in \fIlibdwarf\fP and with releasing allocated resources when access is complete. .H 3 "dwarf_init_path()" .DS \f(CWint dwarf_init_path( const char * path, char * true_path_out_buffer, unsigned true_path_bufferlen, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* dbg, const char * reserved1, Dwarf_Unsigned * reserved2, Dwarf_Unsigned * reserved3, Dwarf_Error* * error); .DE On success the function returns \f(CWDW_DLV_OK\fP, and returns a pointer to an initialized Dwarf_Debug through the dbg argument. All this work identically across all supported object file types. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned there is no such file and nothing else is done or returned. .P If \f(CWDW_DLV_ERROR\fP is returned a Dwarf_Error is returned through the error pointer. and nothing else is done or returned. .P Now we turn to the arguments. .P Pass in the name of the object file via the \f(CWpath\fP argument. .P For MacOS pass in a pointer to \f(CWtrue_path_out_buffer\fP big pointing to a buffer large enough to hold the passed-in path if that were doubled plus adding 100 characters. Then pass that length in the \f(CWtrue_path_bufferlen\fP argument. If a file is found (the dSYM path or if not that the original path) the final path is copied into \f(CWtrue_path_out_buffer\fP. In any case, This is harmless with non-MacOS executables, but for non-MacOS \f(CWtrue_path_out_buffer\fP will just match \f(CWpath\fP. .P When you know you won't be reading MacOS executables you could skip the MacOS special treatment by passing 0 as arguments to \f(CWtrue_path_out_buffer\fP and \f(CWtrue_path_bufferlen\fP. Or use \f(CWdwarf_init_b()\fP instead of \f(CWdwarf_init_path()\fP .P Pass in the usual DW_DLC_READ (which only ever applied to libelf) to \f(CWaccess\fP. Currently no other value is allowed. Non-elf objects currently ignore this field. .P The \f(CWgroupnumber\fP argument indicates which group is to be accessed Group one is normal dwarf sections such as \f(CW.debug_info\fP. Group two is DWARF5 dwo split-dwarf dwarf sections such as .debug_info.dwo. Groups three and higher are for COMDAT groups. If an object file has only sections from one of the groups then passing zero will access that group. Otherwise passing zero will access only group one. See \f(CWdwarf_sec_group_sizes()\fP and \f(CWdwarf_sec_group_map()\fP for more group information. Typically pass in DW_GROUPNUMBER_ANY to \f(CWgroupnumber\fP. Non-elf objects do not use this field. .P The \f(CWerrhand\fP argument is a pointer to a function that will be invoked whenever an error is detected as a result of a \fIlibdwarf\fP operation. The \f(CWerrarg\fP argument is passed as an argument to the \f(CWerrhand\fP function. .P \f(CWdbg\fP. .P \f(CWreserved1\fP, \f(CWreserved2\fP, and \f(CWreserved3\fP are currently unused, pass 0 in to all three. .P Pass in 0 (null) or a pointer to a Dwarf_Error to the \f(CWerror\fP argument if you wish libdwarf to return an error code. .H 3 "dwarf_init_b()" .DS \f(CWint dwarf_init_b( int fd, Dwarf_Unsigned access, unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_init_b()\fP returns through \f(CWdbg\fP a \f(CWDwarf_Debug\fP descriptor that represents a handle for accessing debugging records associated with the open file descriptor \f(CWfd\fP. \f(CWDW_DLV_NO_ENTRY\fP is returned if the object does not contain DWARF debugging information. \f(CWDW_DLV_ERROR\fP is returned if an error occurred. .P The \f(CWaccess\fP argument indicates what access is allowed for the section. The \f(CWDW_DLC_READ\fP parameter is valid for read access (only read access is defined or discussed in this document). .P The \f(CWgroupnumber\fP argument indicates which group is to be accessed Group one is normal dwarf sections such as \f(CW.debug_info\fP. Group two is DWARF5 dwo split-dwarf dwarf sections such as .debug_info.dwo. Groups three and higher are for COMDAT groups. If an object file has only sections from one of the groups then passing zero will access that group. Otherwise passing zero will access only group one. See \f(CWdwarf_sec_group_sizes()\fP and \f(CWdwarf_sec_group_map()\fP for more group information. .P The \f(CWerrhand\fP argument is a pointer to a function that will be invoked whenever an error is detected as a result of a \fIlibdwarf\fP operation. The \f(CWerrarg\fP argument is passed as an argument to the \f(CWerrhand\fP function. .P The file descriptor associated with the \f(CWfd\fP argument must refer to an ordinary file (i.e. not a pipe, socket, device, /proc entry, etc.), be opened with the at least as much permission as specified by the \f(CWaccess\fP argument, and cannot be closed or used as an argument to any system calls by the client until after \f(CWdwarf_finish()\fP is called. The seek position of the file associated with \f(CWfd\fP is undefined upon return of \f(CWdwarf_init()\fP. .P Historical Note: With SGI IRIX, by default it was allowed that the app \f(CWclose()\fP \f(CWfd\fP immediately after calling \f(CWdwarf_init()\fP, but that is not a portable approach (that it worked was an accidental side effect of the fact that SGI IRIX used \f(CWELF_C_READ_MMAP\fP in its hidden internal call to \f(CWelf_begin()\fP). The portable approach is to consider that \f(CWfd\fP must be left open till after the corresponding dwarf_finish() call has returned. .P Since \f(CWdwarf_init()\fP uses the same error handling processing as other \fIlibdwarf\fP functions (see \fIError Handling\fP above), client programs will generally supply an \f(CWerror\fP parameter to bypass the default actions during initialization unless the default actions are appropriate. .H 3 "dwarf_init()" .DS \f(CWint dwarf_init( int fd, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE \f(CWdwarf_init()\fP is identical to \f(CWdwarf_init_b()\fP except that \f(CWdwarf_init()\fP is missing the groupnumber argument so access to an object file containing both dwo and non-dwo DWARF5 object sections will access only group one (and will ignore the dwo sections). .P The \f(CWdwarf_get_elf()\fP function cannot succeed when using \f(CWdwarf_init()\fP or \f(CWdwarf_init_b()\fP or \f(CWdwarf_init_path()\fP to open an object file. .H 3 "Dwarf_Handler function" This is an example of a valid error handler function. A pointer to this (or another like it) may be passed to \f(CWdwarf_elf_init_b()\fP or \f(CWdwarf_init_b()\fP. .DS \f(CWstatic void simple_error_handler(Dwarf_Error error, Dwarf_Ptr errarg) { printf("libdwarf error: %d %s\\n", dwarf_errno(error), dwarf_errmsg(error)); exit(1); }\fP .DE .P This will only be called if an error is detected inside libdwarf and the Dwarf_Error argument passed to libdwarf is NULL. A Dwarf_Error will be created with the error number assigned by the library and passed to the error handler. .P The second argument is a copy of the value passed in to \f(CWdwarf_elf_init_b()\fP or \f(CWdwarf_init()\fP as the \f(CWerrarg()\fP argument. Typically the init function would be passed a pointer to an application-created struct containing the data the application needs to do what it wants to do in the error handler. .P In a language with exceptions or exception-like features an exception could be thrown here. Or the application could simply give up and call \f(CWexit()\fP as in the sample given above. .H 3 "dwarf_elf_init_b() [deprecated 2019]" .DS \f(CWint dwarf_elf_init_b( Elf * elf_file_pointer, Dwarf_Unsigned access, unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE We recommend you change to calling \f(CWdwarf_init_b()\fP or \f(CWdwarf_init_path()\fP instead. The \f(CW dwarf_elf_init() \fP and \f(CW dwarf_elf_init_b() \fP interfaces give no benefit over the other interfaces (other than allowing \f(CWdwarf_get_elf()\fP to succeed). .P The function \f(CWdwarf_elf_init_b()\fP is similar to \f(CWdwarf_init_b()\fP but an open \f(CWElf *\fP pointer is passed instead of a file descriptor so \f(CWdwarf_get_elf()\fP can succeed. .P The client is allowed to use the \f(CWElf *\fP pointer for its own purposes without restriction during the time the \f(CWDwarf_Debug\fP is open, except that the client should not \f(CWelf_end()\fP the pointer till after \f(CWdwarf_finish\fP is called. .H 3 "dwarf_elf_init() [deprecated 2019]" .DS \f(CWint dwarf_elf_init( Elf * elf_file_pointer, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_elf_init()\fP is identical to \f(CWdwarf_init[_b]()\fP except an open \f(CWElf *\fP pointer is passed instead of a file descriptor so \f(CWdwarf_get_elf()\fP can succeed. .P Code using \f(CWdwarf_elf_init[_b]()\fP should be switched to calling \f(CWdwarf_init_b()\fP. .H 3 "dwarf_get_elf()" .DS \f(CWint dwarf_get_elf( Dwarf_Debug dbg, Elf ** elf, Dwarf_Error *error)\fP .DE .P The function \f(CWdwarf_get_elf()\fP is only meaningful if a \f(CWdwarf_elf_init[_b]()\fP function was used to initialize the pointer \f(CWdbg\fP. None of the other dwarf*init*() functions here ever use libelf, so there is no elf pointer to return through the pointer, so and the call will return \f(CWDW_DLV_NO_ENTRY\fP. In addition, this function is also not meaningful for an object file that is not in the Elf format. .P When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_get_elf()\fP returns through the pointer \f(CWelf\fP the \f(CWElf *\fP handle used to access the object represented by the \f(CWDwarf_Debug\fP descriptor \f(CWdbg\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_set_tied_dbg()" .DS \f(CWint dwarf_set_tied_dbg( Dwarf_Debug dbg, Dwarf_Debug tieddbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_set_tied_dbg()\fP enables cross-object access of DWARF data. If a DWARF5 Package object has \f(CWDW_FORM_addrx\fP or \f(CWDW_FORM_GNU_addr_index\fP in an address attribute one needs both the Package file and the executable to extract the actual address with \f(CWdwarf_formaddr()\fP. So one does a normal \f(CWdwarf_elf_init_b()\fP or \f(CWdwarf_init()_b\fP on each object and then tie the two together with a call such as: .in +2 .DS .FG "Example2 dwarf_set_died_dbg()" \f(CW void example2(Dwarf_Debug dbg, Dwarf_Debug tieddbg) { Dwarf_Error error = 0; int res = 0; /* Do the dwarf_init_b() or dwarf_elf_init_b() calls to set dbg, tieddbg at this point. Then: */ res = dwarf_set_tied_dbg(dbg,tieddbg,&error); if (res != DW_DLV_OK) { /* Something went wrong*/ } } \fP .DE .in -2 When done with both dbg and tieddbg do the normal finishing operations on both in any order. It is possible to undo the tieing operation with .in +2 .FG "Example3 dwarf_set_tied_dbg() obsolete" .DS \f(CW void example3(Dwarf_Debug dbg) { Dwarf_Error error = 0; int res = 0; res = dwarf_set_tied_dbg(dbg,NULL,&error); if (res != DW_DLV_OK) { /* Something went wrong*/ } } \fP .DE .in -2 .P It is not necessary to undo the tieing operation before finishing on the dbg and tieddbg. .H 3 "dwarf_get_tied_dbg()" .DS \f(CWint dwarf_get_tied_dbg( Dwarf_Debug /*dbg*/, Dwarf_Debug * /*tieddbg_out*/, Dwarf_Error * /*error*/)\fP .DE \f(CWdwarf_get_tied_dbg\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWtieddbg_out\fP to the pointer to the 'tied' Dwarf_Debug. If there is no 'tied' object \f(CWtieddbg_out\fP is set to NULL. .P On error it returns \f(CWDW_DLV_ERROR\fP. .P It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_finish()" .DS \f(CWint dwarf_finish( Dwarf_Debug dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_finish()\fP releases all \fILibdwarf\fP internal resources associated with the descriptor \f(CWdbg\fP, and invalidates \f(CWdbg\fP. It returns \f(CWDW_DLV_ERROR\fP if there is an error during the finishing operation. It returns \f(CWDW_DLV_OK\fP for a successful operation. Because \f(CWint dwarf_init()\fP opens an Elf descriptor on its fd and \f(CWdwarf_finish()\fP does not close that descriptor, an app should use \f(CWdwarf_get_elf\fP and should call \f(CWelf_end\fP with the pointer returned through the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP. .H 3 "dwarf_set_stringcheck()" .DS \f(CWint dwarf_set_stringcheck( int stringcheck)\fP .DE The function \f(CWint dwarf_set_stringcheck()\fP sets a global flag and returns the previous value of the global flag. If the stringcheck global flag is zero (the default) libdwarf does string length validity checks (the checks do slow libdwarf down very slightly). If the stringcheck global flag is non-zero libdwarf does not do string length validity checks. The global flag is really just 8 bits long, upperbits are not noticed or recorded. .H 3 "dwarf_set_reloc_application()" .DS \f(CWint dwarf_set_reloc_application( int apply)\fP .DE The function \f(CWint dwarf_set_reloc_application()\fP sets a global flag and returns the previous value of the global flag. If the reloc_application global flag is non-zero (the default) then the applicable .rela section (if one exists) will be processed and applied to any DWARF section when it is read in. If the reloc_application global flag is zero no such relocation-application is attempted. Not all machine types (elf header e_machine) or all relocations are supported, but then very few relocation types apply to DWARF debug sections. The global flag is really just 8 bits long, upperbits are not noticed or recorded. It seems unlikely anyone will need to call this function. .H 3 "dwarf_record_cmdline_options()" .DS \f(CWint dwarf_record_cmdline_options( Dwarf_Cmdline_Options options)\fP .DE The function \f(CWint dwarf_record_cmdline_options()\fP copies a Dwarf_Cmdline_Options structure from consumer code to libdwarf. The structure is defined in \f(CWlibdwarf.h\fP. The initial version of this structure has a single field \f(CWcheck_verbose_mode\fP which, if non-zero, tells libdwarf to print some detailed messages to stdout in case certain errors are detected. The default for this value is FALSE (0) so the extra messages are off by default. .H 3 "dwarf_object_init_b()" .DS \f(CWint dwarf_object_init_b( Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, unsigned groupnumber, Dwarf_Debug* dbg, Dwarf_Error* error)\fP .DE The function \f(CWint dwarf_object_init_b()\fP enables access to non-Elf object files by allowing the caller to then provide function pointers to code (user-written, not part of libdwarf) that will look, to libdwarf, as if libdwarf was reading Elf. .P See \f(CWint dwarf_init_b()\fP for additional information on the arguments passed in (the \f(CWobj\fP argument here is a set of function pointers and describing how to access non-Elf files is beyond the scope of this document. .P As a hint, note that the source files with dwarf_elf_init_file_ownership() (dwarf_original_elf_init.c) and dwarf_elf_object_access_init() (dwarf_elf_access.c) are the only sources that would need replacement for a different object format. The replacement would need to emulate certain conventions of Elf objects, (mainly that section index 0 is an empty section) but the rest of libdwarf uses what these two source files set up without knowing how to operate on Elf. .P Writing the functions needed to support non-Elf will require study of Elf and of the object format involved. The topic is beyond the scope of this document. .H 3 "dwarf_object_init()" .DS \f(CWint dwarf_object_init( Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* dbg, Dwarf_Error* error)\fP .DE The function \f(CWint dwarf_object_init()\fP is the same as \f(CWint dwarf_object_init_b()\fP except \f(CWint dwarf_object_init()\fP is missing the groupnumber argument so DWARF5 split dwarf objects cannot be fully handled. .H 3 "dwarf_get_real_section_name()" .DS \f(CWint dwarf_get_real_section_name( Dwarf_Debug dbg, const char * std_section_name, const char ** actual_sec_name_out, Dwarf_Small * marked_compressed, Dwarf_Small * marked_zlib_compressed, Dwarf_Small * marked_shf_compressed, Dwarf_Unsigned * compressed_length, Dwarf_Unsigned * uncompressed_length, Dwarf_Error * error); .DE Elf sections are sometimes compressed to reduce the disk footprint of the sections. It's sometimes interesting to library users what the real name was in the object file and whether it was compressed. Libdwarf uncompresses such sections automatically. It's not usually necessary to know the true name or anything about compression. .P \f(CW \fP The caller passes in a \f(CWDwarf_Debug\fP pointer and a standard section name such as ".debug_info" . On success the function returns (through the other arguments) the true section name and a flag which, if non-zero means the section was compressed and a flag which, if non-zero means the section had the Elf section flag SHF_COMPRESSED set. The caller must ensure that the memory pointed to by \f(CWactual_sec_name_out\fP, \f(CWmarked_zcompressed\fP, and \f(CWmarked_zlib_compressed\fP, \f(CWmarked_shf_compressed\fP, \f(CWcompressed_length\fP, \f(CWuncompressed_length\fP, is zero at the point of call. .P The flag \f(CW*marked_compressed\fP, if non-zero, means the section name started with .zdebug (indicating compression was done). .P The flag \f(CWmarked_zlib_compressed\fP, if non-zero means the initial bytes of the section starte with the ASCII characters ZLIB and the section was compressed. .P The flag \f(CWmarked_shf_compressed\fP if non-zero means the Elf section sh_flag SHF_COMPRESSED is set and the section was compressed.. The flag value in an elf section header is (1<<11) (0x800). .P The value \f(CWcompressed_length\fP is passed back through the pointer if and only if the section is compressed and the pointer is non-null. .P The value \f(CWuncompressed_length\fP is passed back through the pointer if and only if the section is compressed and the pointer is non-null. .P If the section name passed in is not used by libdwarf for this object file the function returns \f(CWDW_DLV_NO_ENTRY\fP .P On error the function returns \f(CWDW_DLV_ERROR\fP. .P The string pointed to by \f(CW*actual_sec_name_out\fP must not be free()d. .H 3 "dwarf_package_version()" .DS \f(CWconst char * dwarf_package_version(void); \fP .DE The package version is set in config.h (from its value in configure.ac and in CMakeLists.txt in the source tree) at the build time of the library. A pointer to a static string is returned by this function. The format is standard ISO date format. For example "20180718". It's not entirely clear how this actually helps. But there is a request for this and we provide it as of 23 October 2019. .H 2 "Object Type Detectors" These are used by \f(CWlibdwarf\fP and may be of use generally. They have no connection to any Dwarf_Debug data as you see from the arguments passed in. .H 3 "dwarf_object_detector_path()" .DS \f(CWint dwarf_object_detector_path(const char *path, char *outpath, unsigned long outpath_len, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode);\fP .DE On success the function returns \f(CWDW_DLV_OK\fP, and returns various data through the arguments (described just below). This works identically across all supported object file types. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned there is no such file and nothing else is done or returned. .P If \f(CWDW_DLV_ERROR\fP is returned a Dwarf_Error is returned through the error pointer. and nothing else is done or returned. .P Now we turn to the arguments. Pass in the name of the object file via the \f(CWpath\fP argument. .P To \f(CWoutpath\fP pass in a pointer big enough to hold the passed-in path if that were doubled plus adding 100 characters. Then pass that length in the \f(CWoutpath_len\fP argument. The path will be copied to outpath. In the case of certain MacOS dSYM object files the final outpath of the dSYM file (with MacOS conventional directories added) is copied into \f(CWoutpath\fP. Where the MacOS local directory tree is missing or incomplete \f(CWoutpath\fP will be left as a zero-lengh string. .P To entirely skip the MacOS special treatment pass 0 as arguments to \f(CWoutpath\fP and \f(CWoutpath_len\fP. .P The \f(CWftype\fP pointer argument returns \f(CWDW_FTYPE_ELF\fP, \f(CWDW_FTYPE_MACH_O\fP , \f(CWDW_FTYPE_PE\fP , \f(CWDW_FTYPE_ARCHIVE\fP or \f(CWDW_FTYPE_UNKNOWN\fP to the caller. The \f(CWDW_FTYPE_ARCHIVE\fP value says nothing whatever about the contents of the archive. .P The \f(CWendian\fP pointer argument returns \f(CWDW_ENDIAN_BIG\fP, \f(CWDW_ENDIAN_LITTLE\fP , \f(CWDW_ENDIAN_SAME\fP , \f(CWDW_ENDIAN_OPPOSITE\fP or \f(CWDW_ENDIAN_UNKNOWN\fP to the caller. .P The \f(CWoffsetsize\fP pointer argument returns a size value from the object file. If the object file uses 32-bit offsets it returns 32, and if 64-bit offsets it returns 64. Each object type uses such values but the ways the value is used varies. .P The \f(CWfilesize\fP pointer argument returns the size, in bytes, of the object file. This is essentially useless for \f(CWDW_FTYPE_ARCHIVE\fP files, one thinks. .P The \f(CWerrcode\fP pointer argument returns (if and only if DW_DLV_ERROR is returned by the function) an integer error code. At this time there is no handy function to turn that error code into a string. In the libdwarf source you will find that code in the DW_DLE_* error list. .H 3 "dwarf_object_detector_fd()" .DS \f(CWint dwarf_object_detector_fd(int fd, unsigned *ftype, unsigned *endian, unsigned *offsetsize, Dwarf_Unsigned *filesize, int * errcode);\fP .DE \f(CWdwarf_object_detector_fd()\fP is the same as \f(CWdwarf_object_detector_path()\fP except that no path strings apply to \f(CWdwarf_object_detector_fd()\fP. .H 2 "Section Group Operations" The section group data is essential information when processing an object with COMDAT section group DWARF sections or with both split-dwarf (.dwo sections) and non-split dwarf sections. .P It relies on Elf section groups, whereas some compilers rely instead on relocation information to identify section groups. These relocation-specified groupings are not understood at this time. .P A standard DWARF2 or DWARF3 or DWARF4 object (Old Standard Object, or OSO) will not contain any of those new sections. The DWARF4 standard, Appendix E.1 "Using Compilation Units" offers an overview of COMDAT section groups. \f(CWlibdwarf\fP assigns the group number one(1) to OSO DWARF. Any sections that are split dwarf (section name ending in .dwo or one of the two special DWP index sections) are assigned group number two(2) by libdwarf. COMDAT section groups are assigned groups numbers 3 and higher as needed. .P The COMDAT section group uses are not well defined, but popular compilations systems are using such sections. There is no meaningful documentation that we can find (so far) on how the COMDAT section groups are used, so \f(CWlibdwarf\fP is based on observations of what compilers generate. .H 3 "dwarf_sec_group_sizes()" .DS \f(CW int dwarf_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) \fP .DE The function \f(CWdwarf_sec_group_sizes()\fP may be called on any open \f(CWDwarf_Debug\fP. It returns \f(CWDW_DLV_OK\fP on success and returns values via the pointer arguments. .P Once the \f(CWDwarf_Debug\fP is open the group information is set and it will not change for the life of this \f(CWDwarf_Debug\fP. .P The \f(CW*section_count_out\fP is set to the number of sections in the object. Many of the sections will be irrelevant to \f(CWlibdwarf\fP. .P The \f(CW*group_count_out\fP is set to the number of groups in the object (as \f(CWlibdwarf\fP counts them). An OSO will have exactly one group. A DWP object will have exactly one group. If is more than one group consumer code will likely want to open additional \f(CWDwarf_Debug\fP objects and request relevant information to process the DWARF contents. An executable or a DWP object will always have a \f(CW*group_count_out\fP of one(1). An executable or a shared library cannot have any COMDAT section groups as the linker will have dealt with them. .P The \f(CW*selected_group_out\fP is set to the group number that this \f(CWDwarf_Debug\fP will focus on. See \f(CWdwarf_sec_group_map()\fP for additional details on how \f(CW*selected_group_out\fP is interpreted. .P The \f(CW*map_entry_count_out\fP is set to the number of entries in the map. See \f(CWdwarf_sec_group_map()\fP. .P On failure it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP .P The initial implementation never returns \f(CWDW_DLV_ERROR\fP or \f(CWDW_DLV_NO_ENTRY\fP but callers should allow for that possibility. .H 3 " dwarf_sec_group_map()" .DS \f(CW int dwarf_sec_group_map( Dwarf_Debug dbg, Dwarf_Unsigned map_entry_count, Dwarf_Unsigned * group_numbers_array, Dwarf_Unsigned * section_numbers_array, const char ** sec_names_array, Dwarf_Error * error) \fP .DE The function \f(CWdwarf_sec_group_map()\fP may be called on any open \f(CWDwarf_Debug\fP. .P The caller must allocate \f(CWmap_entry_count\fP arrays used in the following three arguments the and pass the appropriate pointer into the function as well as passing in \f(CWmap_entry_count\fP itself. .P The map entries returned cover all the DWARF related sections in the object though the \f(CWselected_group\fP value will dictate which of the sections in the \f(CWDwarf_Debug\fP will actually be accessed via the usual \f(CWlibdwarf\fP functions. That is, only sections in the selected group may be directly accessed though libdwarf may indirectly access sections in section group one(1) so relevant details can be accessed, such as abbreviation tables etc. Describing the details of this access outside the current \f(CWselected_group\fP goes beyond what this document covers (as of this writing). .P It returns \f(CWDW_DLV_OK\fP on success and sets values into the user-allocated array elements (sorted by section number): .in +2 .DS \f(CW group_numbers_array[0]... group_numbers_array[map_entry_count-1] section_numbers_array[0]... section_numbers_array[map_entry_count-1] sec_names_array[0]... sec_names_array[map_entry_count-1] \fP .DE .in -2 .P \f(CWgroup_numbers_array[0]\fP for example is set to a group number. One(1), or two(2) or if there are COMDAT groups it will be three(3) or higher. .P \f(CWsection_numbers_array[0]\fP for example is set to a valid Elf section number relevant to \f(CWDWARF\fP (each section number shown will be greater than zero). .P \f(CWsec_names_array[0]\fP for example is set to a pointer to a string containing the Elf section name of the Elf section number in \f(CWsections_number_array[0]\fP. .P On error the function will return \f(CWDW_DLV_ERROR\fP or \f(CWDW_DLV_NO_ENTRY\fP which indicates a serious problem with this object. .P Here is an example of use of these functions. .in +2 .DS \f(CW void examplesecgroup(Dwarf_Debug dbg) { int res = 0; Dwarf_Unsigned section_count = 0; Dwarf_Unsigned group_count; Dwarf_Unsigned selected_group = 0; Dwarf_Unsigned group_map_entry_count = 0; Dwarf_Unsigned *sec_nums = 0; Dwarf_Unsigned *group_nums = 0; const char ** sec_names = 0; Dwarf_Error error = 0; Dwarf_Unsigned i = 0; res = dwarf_sec_group_sizes(dbg,§ion_count, &group_count,&selected_group, &group_map_entry_count, &error); if(res != DW_DLV_OK) { /* Something is badly wrong*/ return; } /* In an object without split-dwarf sections or COMDAT sections we now have selected_group == 1. */ sec_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if(!sec_nums) { /* FAIL. out of memory */ return; } group_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); if(!group_nums) { free(group_nums); /* FAIL. out of memory */ return; } sec_names = calloc(group_map_entry_count,sizeof(char*)); if(!sec_names) { free(group_nums); free(sec_nums); /* FAIL. out of memory */ return; } res = dwarf_sec_group_map(dbg,group_map_entry_count, group_nums,sec_nums,sec_names,&error); if(res != DW_DLV_OK) { /* FAIL. Something badly wrong. */ } for( i = 0; i < group_map_entry_count; ++i) { /* Now do something with group_nums[i],sec_nums[i],sec_names[i] */ } free(group_nums); free(sec_nums); /* The strings are in Elf data. Do not free() the strings themselves.*/ free(sec_names); } \fP .DE .in -2 .H 2 "Section size operations" .P These operations are informative but not normally needed. .H 3 "dwarf_get_section_max_offsets_b()" .DS \f(CWint dwarf_get_section_max_offsets_b(Dwarf_debug dbg, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); .DE .P The function \f(CWdwarf_get_section_max_offsets_b()\fP an open Dwarf_Dbg and reports on the section sizes by pushing section size values back through the pointers. Created in October 2011. .H 3 "dwarf_get_section_max_offsets()" .DS \f(CWint dwarf_get_section_max_offsets(Dwarf_debug dbg, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, Dwarf_Unsigned * /*debug_loc_size*/, Dwarf_Unsigned * /*debug_aranges_size*/, Dwarf_Unsigned * /*debug_macinfo_size*/, Dwarf_Unsigned * /*debug_pubnames_size*/, Dwarf_Unsigned * /*debug_str_size*/, Dwarf_Unsigned * /*debug_frame_size*/, Dwarf_Unsigned * /*debug_ranges_size*/, Dwarf_Unsigned * /*debug_pubtypes_size*/); .DE .P The function is the same as \f(CWdwarf_get_section_max_offsets_b()\fP except it is missing the \f(CWdebug_types_size()\fP argument. Though obsolete it is still supported. .H 2 "Printf Callbacks" .P This is new in August 2013. .P The \f(CWdwarf_print_lines()\fP function is intended as a helper to programs like \f(CWdwarfdump\fP and show some line internal details in a way only the interals of libdwarf can show these details. But using printf directly in libdwarf means the caller has limited control of where the output appears. So now the 'printf' output is passed back to the caller through a callback function whose implementation is provided by the caller. .P Any code calling libdwarf can ignore the functions described in this section completely. If the functions are ignored the messages (if any) from libdwarf will simply not appear anywhere. .P The \f(CWlibdwarf.h\fP header file defines \f(CWstruct Dwarf_Printf_Callback_Info_s\fP and \f(CWdwarf_register_printf_callback\fP for those libdwarf callers wishing to implement the callback. In this section we describe how one uses that interface. The applications \f(CWdwarfdump\fP and \f(CWdwarfdump2\fP are examples of how these may be used. .H 3 "dwarf_register_printf_callback" .DS \f(CWstruct Dwarf_Printf_Callback_Info_s dwarf_register_printf_callback(Dwarf_Debug dbg, struct Dwarf_Printf_Callback_Info_s * newvalues); .DE .P The \f(CWdwarf_register_printf_callback()\fP function can only be called after the Dwarf_Debug instance has been initialized, the call makes no sense at other times. The function returns the current value of the structure. If \f(CWnewvalues\fP is non-null then the passed-in values are used to initialize the libdwarf internal callback data (the values returned are the values before the \f(CWnewvalues\fP are recorded). If \f(CWnewvalues\fP is null no change is made to the libdwarf internal callback data. .H 3 "Dwarf_Printf_Callback_Info_s" .DS \f(CWstruct Dwarf_Printf_Callback_Info_s { void * dp_user_pointer; dwarf_printf_callback_function_type dp_fptr; char * dp_buffer; unsigned int dp_buffer_len; int dp_buffer_user_provided; void * dp_reserved; }; .DE .P First we describe the fields as applicable in setting up for a call to \f(CWdwarf_register_printf_callback()\fP. .P The field \f(CWdp_user_pointer\fP is remembered by libdwarf and passed back in any call libdwarf makes to the user's callback function. It is otherwise ignored by libdwarf. .P The field \f(CWdp_fptr\fP is either NULL or a pointer to a user-implemented function. .P If the field \f(CWdp_buffer_user_provided\fP is non-zero then \f(CWdp_buffer_len\fP and \f(CWdp_buffer\fP must be set by the user and libdwarf will use that buffer without doing any malloc of space. If the field \f(CWdp_buffer_user_provided\fP is zero then the input fields \f(CWdp_buffer_len\fP and \f(CWdp_buffer\fP are ignored by libdwarf and space is malloc'd as needed. .P The field \f(CWdp_reserved\fP is ignored, it is reserved for future use. .P When the structure is returned by \f(CWdwarf_register_printf_callback()\fP the values of the fields before the \f(CWdwarf_register_printf_callback()\fP call are returned. .H 3 "dwarf_printf_callback_function_type" .DS \f(CWtypedef void (* dwarf_printf_callback_function_type)(void * user_pointer, const char * linecontent); .DE .P Any application using the callbacks needs to use the function \f(CWdwarf_register_printf_callback()\fP and supply a function matching the above function prototype from libdwarf.h. .H 3 "Example of printf callback use in a C++ application using libdwarf" .DS \f(CWstruct Dwarf_Printf_Callback_Info_s printfcallbackdata; memset(&printfcallbackdata,0,sizeof(printfcallbackdata)); printfcallbackdata.dp_fptr = printf_callback_for_libdwarf; dwarf_register_printf_callback(dbg,&printfcallbackdata); Assuming the user implements something like the following function in her application: void printf_callback_for_libdwarf(void *userdata,const char *data) { cout << data; } .DE .P It is crucial that the user's callback function copies or prints the data immediately. Once the user callback function returns the \f(CWdata\fP pointer may change or become stale without warning. .H 2 "Debugging Information Entry Delivery Operations" These functions are concerned with accessing debugging information entries, whether from a .debug_info, .debug_types, .debug_info.dwo, or .debug_types.dwo . .P Since all such sections use similar formats, one set of functions suffices. .H 3 "dwarf_get_die_section_name()" .DS int dwarf_get_die_section_name(Dwarf_Debug dbg, Dwarf_Bool is_info, const char ** sec_name, Dwarf_Error * error); .DE \f(CWdwarf_get_die_section_name()\fP lets consumers access the object section name when no specific DIE is at hand. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_die_section_name_b()\fP. .P The function \f(CWdwarf_get_die_section_name()\fP operates on the either the .debug_info[.dwo] section (if \f(CWis_info\fP is non-zero) or .debug_types[.dwo] section (if \f(CWis_info\fP is zero). .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_die_section_name_b()" .DS int dwarf_get_die_section_name_b(Dwarf_Die die, const char ** sec_name, Dwarf_Error * error); .DE \f(CWdwarf_get_die_section_name_b()\fP lets consumers access the object section name when one has a DIE. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_die_section_name()\fP. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_next_cu_header_d()" .DS \f(CWint dwarf_next_cu_header_d( Dwarf_debug dbg, Dwarf_Bool is_info, 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_header, Dwarf_Half *header_cu_type, Dwarf_Error *error); .DE The function \f(CWdwarf_next_cu_header_d()\fP operates on the either the .debug_info section (if \f(CWis_info\fP is non-zero) or .debug_types section (if \f(CWis_info\fP is zero). It returns \f(CWDW_DLV_ERROR\fP if it fails, and \f(CWDW_DLV_OK\fP if it succeeds. .P If it succeeds, \f(CW*next_cu_header\fP is set to the offset in the .debug_info section of the next compilation-unit header if it succeeds. On reading the last compilation-unit header in the .debug_info section it contains the size of the .debug_info or debug_types section. Beginning 22 April 2019 \f(CWnext_cu_header\fP will not be used to return the offset if \f(CWnext_cu_header\fP is null. Be cautious using a null argument unless you know that only a suitably recent version of libdwarf will be used. .P The next call to \f(CWdwarf_next_cu_header_b()\fP returns \f(CWDW_DLV_NO_ENTRY\fP without reading a compilation-unit or setting \f(CW*next_cu_header\fP. Subsequent calls to \f(CWdwarf_next_cu_header()\fP repeat the cycle by reading the first compilation-unit and so on. .P The other values returned through pointers are the values in the compilation-unit header. If any of \f(CWcu_header_length\fP, \f(CWversion_stamp\fP, \f(CWabbrev_offset\fP, \f(CWaddress_size\fP, \f(CWoffset_size\fP, \f(CWextension_size\fP, \f(CWsignature\fP, or \f(CWtypeoffset\fP, is \f(CWNULL\fP, the argument is ignored (meaning it is not an error to provide a \f(CWNULL\fP pointer for any or all of these arguments). .P \f(CWcu_header_length\fP returns the length in bytes of the compilation unit header. .P \f(CWversion_stamp\fP returns the section version, which would be (for .debug_info) 2 for DWARF2, 3 for DWARF3, 4 for DWARF4, or 5 for DWARF5.. .P \f(CWabbrev_offset\fP returns the .debug_abbrev section offset of the abbreviations for this compilation unit. .P \f(CWaddress_size\fP returns the size of an address in this compilation unit. Which is usually 4 or 8. .P \f(CWoffset_size\fP returns the size in bytes of an offset for the compilation unit. The offset size is 4 for 32bit dwarf and 8 for 64bit dwarf. This is the offset size in dwarf data, not the address size inside the executable code. The offset size can be 4 even if embedded in a 64bit elf file (which is normal for 64bit elf), and can be 8 even in a 32bit elf file (which probably will never be seen in practice). .P The \f(CWextension_size\fP pointer is only relevant if the \f(CWoffset_size\fP pointer returns 8. The value is not normally useful but is returned through the pointer for completeness. The pointer \f(CWextension_size\fP returns 0 if the CU is MIPS/IRIX non-standard 64bit dwarf (MIPS/IRIX 64bit dwarf was created years before DWARF3 defined 64bit dwarf) and returns 4 if the dwarf uses the standard 64bit extension (the 4 is the size in bytes of the 0xffffffff in the initial length field which indicates the following 8 bytes in the .debug_info section are the real length). See the DWARF3 or DWARF4 standard, section 7.4. .P The \f(CWsignature\fP pointer is only relevant if the CU has a type signature, and if relevant the 8 byte type signature of the .debug_types CU header is assigned through the pointer. .P The \f(CWtypeoffset\fP pointer is only relevant the CU has a type signature if relevant the local offset within the CU of the the type offset the .debug_types entry represents is assigned through the pointer. The \f(CWtypeoffset\fP matters because a DW_AT_type referencing the type unit may reference an inner type, such as a C++ class in a C++ namespace, but the type itself has the enclosing namespace in the .debug_type type_unit. .P The \f(CWheader_cu_type\fP pointer is applicable to all CU headers. The value returned through the pointer is either \f(CWDW_UT_compile\fP \f(CWDW_UT_partial\fP \f(CWDW_UT_type\fP and identifies the header type of this CU. In \f(CWDWARF4\fP a \f(CWDW_UT_type\fP will be in \f(CW.debug_types\fP, but in \f(CWDWARF5\fP these compilation units are in \f(CW.debug_info\fP and the Debug Fission (ie Split Dwarf) \f(CW.debug_info.dwo\fP sections . .H 3 "dwarf_next_cu_header_c()" .DS \f(CWint dwarf_next_cu_header_c( Dwarf_debug dbg, Dwarf_Bool is_info, 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_header, Dwarf_Error *error); .DE The function \f(CWdwarf_next_cu_header_c()\fP operates on the either the .debug_info section (if \f(CWis_info\fP is non-zero) or .debug_types section (if \f(CWis_info\fP is zero). .P It operates exactly like \f(CWdwarf_next_cu_header_d()\fP but is missing the \f(CWheader_type\fP field. This is kept for compatibility. All code using this should be changed to use \f(CWdwarf_next_cu_header_d()\fP .H 3 "dwarf_next_cu_header_b()" .DS \f(CWint dwarf_next_cu_header_b( Dwarf_debug dbg, 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_Unsigned *next_cu_header, Dwarf_Error *error); .DE .P This is obsolete as of October 2011 though supported. .P The function \f(CWdwarf_next_cu_header_b()\fP operates on the .debug_info section. It operates exactly like \f(CWdwarf_next_cu_header_c()\fP but is missing the \f(CWsignature\fP, and \f(CWtypeoffset\fP fields. This is kept for compatibility. All code using this should be changed to use \f(CWdwarf_next_cu_header_c()\fP .H 3 "dwarf_next_cu_header()" .P The following is the original form, missing the \f(CWoffset_size\fP, \f(CWextension_size\fP, \f(CWsignature\fP, and \f(CWtypeoffset\fP fields in \f(CWdwarf_next_cu_header_c()\fP. This is kept for compatibility. All code using this should be changed to use \f(CWdwarf_next_cu_header_c()\fP .DS \f(CWint dwarf_next_cu_header( Dwarf_debug dbg, Dwarf_Unsigned *cu_header_length, Dwarf_Half *version_stamp, Dwarf_Unsigned *abbrev_offset, Dwarf_Half *address_size, Dwarf_Unsigned *next_cu_header, Dwarf_Error *error); .DE .H 3 "dwarf_siblingof_b()" .DS \f(CWint dwarf_siblingof_b( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Bool is_info, Dwarf_Die *return_sib, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_siblingof_b()\fP returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP pointer on error. If there is no sibling it returns \f(CWDW_DLV_NO_ENTRY\fP. When it succeeds, \f(CWdwarf_siblingof_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_sib\fP to the \f(CWDwarf_Die\fP descriptor of the sibling of \f(CWdie\fP. If \f(CWis_info\fP is non-zero then the \f(CWdie\fP is assumed to refer to a .debug_info DIE. If \f(CWis_info\fP is zero then the \f(CWdie\fP is assumed to refer to a .debug_types DIE. Note that the first call (the call that gets the compilation-unit DIE in a compilation unit) passes in a NULL \f(CWdie\fP so having the caller pass in \f(CWis_info\fP is essential. And if \f(CWdie\fP is non-NULL it is still essential for the call to pass in \f(CWis_info\fP set properly to reflect the section the DIE came from. The function \f(CWdwarf_get_die_infotypes_flag()\fP is of interest as it returns the proper is_info value from any non-NULL \f(CWdie\fP pointer. If \f(CWdie\fP is \fINULL\fP, the \f(CWDwarf_Die\fP descriptor of the first die in the compilation-unit is returned. This die has the \f(CWDW_TAG_compile_unit\fP, \f(CWDW_TAG_partial_unit\fP, or \f(CWDW_TAG_type_unit\fP tag. .in +2 .FG "Example4 dwarf_siblingof()" .DS \f(CW void example4(Dwarf_Debug dbg,Dwarf_Die in_die,Dwarf_Bool is_info) { Dwarf_Die return_sib = 0; Dwarf_Error error = 0; int res = 0; /* in_die might be NULL or a valid Dwarf_Die */ res = dwarf_siblingof_b(dbg,in_die,is_info,&return_sib, &error); if (res == DW_DLV_OK) { /* Use return_sib here. */ dwarf_dealloc(dbg, return_sib, DW_DLA_DIE); /* return_sib is no longer usable for anything, we ensure we do not use it accidentally with: */ return_sib = 0; } } \fP .DE .in -2 .H 3 "dwarf_siblingof()" .DS \f(CWint dwarf_siblingof( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *return_sib, Dwarf_Error *error)\fP .DE .P \f(CWint dwarf_siblingof()\fP operates exactly the same as \f(CWint dwarf_siblingof_b()\fP, but \f(CWint dwarf_siblingof()\fP refers only to .debug_info DIEs. .H 3 "dwarf_child()" .DS \f(CWint dwarf_child( Dwarf_Die die, Dwarf_Die *return_kid, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_child()\fP returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error. If there is no child it returns \f(CWDW_DLV_NO_ENTRY\fP. When it succeeds, \f(CWdwarf_child()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_kid\fP to the \f(CWDwarf_Die\fP descriptor of the first child of \f(CWdie\fP. The function \f(CWdwarf_siblingof()\fP can be used with the return value of \f(CWdwarf_child()\fP to access the other children of \f(CWdie\fP. .in +2 .FG "Example5 dwarf_child()" .DS \f(CW void example5(Dwarf_Debug dbg,Dwarf_Die in_die) { Dwarf_Die return_kid = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_child(in_die,&return_kid, &error); if (res == DW_DLV_OK) { /* Use return_kid here. */ dwarf_dealloc(dbg, return_kid, DW_DLA_DIE); /* return_die is no longer usable for anything, we ensure we do not use it accidentally with: */ return_kid = 0; } } \fP .DE .in -2 .H 3 "dwarf_offdie_b()" .DS \f(CWint dwarf_offdie_b( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Die *return_die, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_offdie_b()\fP returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error. When it succeeds, \f(CWdwarf_offdie_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_die\fP to the the \f(CWDwarf_Die\fP descriptor of the debugging information entry at \f(CWoffset\fP in the section containing debugging information entries i.e the .debug_info section. A return of \f(CWDW_DLV_NO_ENTRY\fP means that the \f(CWoffset\fP in the section is of a byte containing all 0 bits, indicating that there is no abbreviation code. Meaning this 'die offset' is not the offset of a real die, but is instead an offset of a null die, a padding die, or of some random zero byte: this should not be returned in normal use. .P It is the user's responsibility to make sure that \f(CWoffset\fP is the start of a valid debugging information entry. The result of passing it an invalid offset could be chaos. .P If \f(CWis_info\fP is non-zero the \f(CWoffset\fP must refer to a .debug_info section offset. If \f(CWis_info\fP zero the \f(CWoffset\fP must refer to a .debug_types section offset. Error returns or misleading values may result if the \f(CWis_info\fP flag or the \f(CWoffset\fP value are incorrect. .in +2 .FG "Example6 dwarf_offdie_b()" .DS \f(CW void example6(Dwarf_Debug dbg,Dwarf_Off die_offset,Dwarf_Bool is_info) { Dwarf_Error error = 0; Dwarf_Die return_die = 0; int res = 0; res = dwarf_offdie_b(dbg,die_offset,is_info,&return_die, &error); if (res == DW_DLV_OK) { /* Use return_die here. */ dwarf_dealloc(dbg, return_die, DW_DLA_DIE); /* return_die is no longer usable for anything, we ensure we do not use it accidentally with: */ return_die = 0; } else { /* res could be NO ENTRY or ERROR, so no dealloc necessary. */ } } \fP .DE .in -2 .H 3 "dwarf_offdie()" .DS \f(CWint dwarf_offdie( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *return_die, Dwarf_Error *error)\fP .DE .P The function \f(CWdwarf_offdie()\fP is obsolete, use \f(CWdwarf_offdie_b()\fP instead. The function is still supported in the library, but only references the .debug_info section. .H 3 "dwarf_validate_die_sibling()" .DS \f(CWint validate_die_sibling( Dwarf_Die sibling, Dwarf_Off *offset)\fP .DE When used correctly in a depth-first walk of a DIE tree this function validates that any DW_AT_sibling attribute gives the same offset as the direct tree walk. That is the only purpose of this function. The function \f(CWdwarf_validate_die_sibling()\fP returns \f(CWDW_DLV_OK\fP if the last die processed in a depth-first DIE tree walk was the same offset as generated by a call to \f(CWdwarf_siblingof()\fP. Meaning that the DW_AT_sibling attribute value, if any, was correct. If the conditions are not met then DW_DLV_ERROR is returned and \f(CW*offset\fP is set to the offset in the .debug_info section of the last DIE processed. If the application prints the offset a knowledgeable user may be able to figure out what the compiler did wrong. .H 2 "Debugging Information Entry Query Operations" These queries return specific information about debugging information entries or a descriptor that can be used on subsequent queries when given a \f(CWDwarf_Die\fP descriptor. Note that some operations are specific to debugging information entries that are represented by a \f(CWDwarf_Die\fP descriptor of a specific type. For example, not all debugging information entries contain an attribute having a name, so consequently, a call to \f(CWdwarf_diename()\fP using a \f(CWDwarf_Die\fP descriptor that does not have a name attribute will return \f(CWDW_DLV_NO_ENTRY\fP. This is not an error, i.e. calling a function that needs a specific attribute is not an error for a die that does not contain that specific attribute. .P There are several methods that can be used to obtain the value of an attribute in a given die: .AL 1 .LI Call \f(CWdwarf_hasattr()\fP to determine if the debugging information entry has the attribute of interest prior to issuing the query for information about the attribute. .LI Supply an \f(CWerror\fP argument, and check its value after the call to a query indicates an unsuccessful return, to determine the nature of the problem. The \f(CWerror\fP argument will indicate whether an error occurred, or the specific attribute needed was missing in that die. .LI Arrange to have an error handling function invoked upon detection of an error (see \f(CWdwarf_init()\fP). .LI Call \f(CWdwarf_attrlist()\fP and iterate through the returned list of attributes, dealing with each one as appropriate. .LE .P .H 3 "dwarf_get_die_infotypes_flag()" .DS \f(CWDwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die die)\fP .DE .P The function \f(CWdwarf_tag()\fP returns the section flag indicating which section the DIE originates from. If the returned value is non-zero the DIE originates from the .debug_info section. If the returned value is zero the DIE originates from the .debug_types section. .H 3 "dwarf_tag()" .DS \f(CWint dwarf_tag( Dwarf_Die die, Dwarf_Half *tagval, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_tag()\fP returns the \f(CWtag\fP of \f(CWdie\fP through the pointer \f(CWtagval\fP if it succeeds. It returns \f(CWDW_DLV_OK\fP if it succeeds. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_dieoffset()" .DS \f(CWint dwarf_dieoffset( Dwarf_Die die, Dwarf_Off * return_offset, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_dieoffset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the position of \f(CWdie\fP in the section containing debugging information entries (the \f(CWreturn_offset\fP is a section-relative offset). In other words, it sets \f(CWreturn_offset\fP to the offset of the start of the debugging information entry described by \f(CWdie\fP in the section containing dies i.e .debug_info. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_debug_addr_index_to_addr()" .DS int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned index, Dwarf_Addr * return_addr, Dwarf_Error * error); .DE Attributes with form DW_FORM_addrx, the operation DW_OP_addrx, or certain of the split-dwarf location list entries give an index value to a machine address in the .debug_addr section (which is always in .debug_addr even when the form/operation are in a split dwarf .dwo section). .P On successful return this function turns such an index into a target address value through the pointer \f(CWreturn_addr\fP . .P If there is an error this may return DW_ \f(CWDW_DLV_ERROR\fP and it will have returned an error through \f(CW*error\fP. .P If there is no available .debug_addr section this may return \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_die_CU_offset()" .DS \f(CWint dwarf_die_CU_offset( Dwarf_Die die, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_die_CU_offset()\fP is similar to \f(CWdwarf_dieoffset()\fP, except that it puts the offset of the DIE represented by the \f(CWDwarf_Die\fP \f(CWdie\fP, from the start of the compilation-unit that it belongs to rather than the start of .debug_info (the \f(CWreturn_offset\fP is a CU-relative offset). .H 3 "dwarf_die_offsets()" .DS \f(CWint dwarf_die_offsets( Dwarf_Die die, Dwarf_Off *global_off, Dwarf_Off *cu_off, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_die_offsets()\fP is a combination of \f(CWdwarf_dieoffset()\fP and \f(CWdwarf_die_cu_offset()\fP in that it returns both the global .debug_info offset and the CU-relative offset of the \f(CWdie\fP in a single call. .H 3 "dwarf_ptr_CU_offset()" .DS \f(CWint dwarf_ptr_CU_offset( Dwarf_CU_Context cu_context, Dwarf_Byte_ptr di_ptr , Dwarf_Off *cu_off)\fP .DE Given a valid CU context pointer and a pointer into that CU context, the function \f(CWdwarf_ptr_CU_offset()\fP returns DW_DLV_OK and sets \f(CW*cu_off\fP to the CU-relative (local) offset in that CU. .H 3 "dwarf_CU_dieoffset_given_die()" .DS \f(CWint dwarf_CU_dieoffset_given_die( Dwarf_Die given_die, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_CU_dieoffset_given_die()\fP is similar to \f(CWdwarf_die_CU_offset()\fP, except that it puts the global offset of the CU DIE owning \f(CWgiven_die\fP of .debug_info (the \f(CWreturn_offset\fP is a global section offset). .P This is useful when processing a DIE tree and encountering an error or other surprise in a DIE, as the \f(CWreturn_offset\fP can be passed to \f(CWdwarf_offdie_b()\fP to return a pointer to the CU die of the CU owning the \f(CWgiven_die\fP passed to \f(CWdwarf_CU_dieoffset_given_die()\fP. The consumer can extract information from the CU die and the \f(CWgiven_die\fP (in the normal way) and print it. An example (a snippet) of code using this function follows. It assumes that \f(CWin_die\fP is a DIE in .debug_info that, for some reason, you have decided needs CU context printed (assuming \f(CWprint_die_data\fP does some reasonable printing). .in +2 .FG "Example7 dwarf_CU_dieoffset_given_die()" .DS \f(CW void example7(Dwarf_Debug dbg, Dwarf_Die in_die,Dwarf_Bool is_info) { int res = 0; Dwarf_Off cudieoff = 0; Dwarf_Die cudie = 0; Dwarf_Error error = 0; res = dwarf_CU_dieoffset_given_die(in_die,&cudieoff,&error); if(res != DW_DLV_OK) { /* FAIL */ return; } res = dwarf_offdie_b(dbg,cudieoff,is_info,&cudie,&error); if(res != DW_DLV_OK) { /* FAIL */ return; } /* do something with cu_die */ dwarf_dealloc(dbg,cudie, DW_DLA_DIE); } \fPy .DE .in -2 .H 3 "dwarf_die_CU_offset_range()" .DS \f(CWint dwarf_die_CU_offset_range( Dwarf_Die die, Dwarf_Off *cu_global_offset, Dwarf_Off *cu_length, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_die_CU_offset_range()\fP returns the offset of the beginning of the CU and the length of the CU. The offset and length are of the entire CU that this DIE is a part of. It is used by dwarfdump (for example) to check the validity of offsets. Most applications will have no reason to call this function. .H 3 "dwarf_diename()" .DS \f(CWint dwarf_diename( Dwarf_Die die, char ** return_name, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_diename()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string of characters that represents the name attribute (\f(CWDW_AT_name\fP) of \f(CWdie\fP. .P The storage pointed to by a successful return of \f(CWdwarf_diename()\fP should be freed using the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest (see \f(CWdwarf_dealloc()\fP). .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have a name attribute. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_die_text()" .DS \f(CWint dwarf_die_text( Dwarf_Die die, Dwarf_Half attrnum, char ** return_name, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_die_text()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string of characters that represents a string-value attribute of \f(CWdie\fP if an attribute \f(CWattrnum\fP is present. .P The storage pointed to by a successful return of \f(CWdwarf_die_text()\fP should be freed using the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest (see \f(CWdwarf_dealloc()\fP). .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have the attribute \f(CWattrnum\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_die_abbrev_code()" .DS \f(CWint dwarf_die_abbrev_code( Dwarf_Die die)\fP .DE The function returns the abbreviation code of the DIE. That is, it returns the abbreviation "index" into the abbreviation table for the compilation unit of which the DIE is a part. It cannot fail. No errors are possible. The pointer \f(CWdie()\fP must not be NULL. .H 3 "dwarf_die_abbrev_children_flag()" .DS \f(CWint dwarf_die_abbrev_children_flag( Dwarf_Die die, Dwarf_Half *has_child)\fP .DE The function returns the has-children flag of the \f(CWdie\fP passed in through the \f(CW*has_child\fP passed in and returns \f(CWDW_DLV_OK\fP on success. A non-zero value of \f(CW*has_child\fP means the \f(CWdie\fP has children. On failure it returns \f(CWDW_DLV_ERROR\fP. The function was developed to let consumer code do better error reporting in some circumstances, it is not generally needed. .H 3 "dwarf_die_abbrev_global_offset()" .DS \f(CWint dwarf_die_abbrev_global_offset(Dwarf_Die die, Dwarf_Off * abbrev_offset, Dwarf_Unsigned * abbrev_count, Dwarf_Error* error);\fP .DE The function allows more detailed printing of abbreviation data. It is handy for analyzing abbreviations but is not normally needed by applications. The function first appears in March 2016. .P On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CW*abbrev_offset\fP to the global offset in the \f(CW.debug_abbrev\fP section of the abbreviation. It also sets \f(CW*abbrev_count\fP to the number of attribute/form pairs in the abbreviation entry. It is possible, though unusual, for the count to be zero (meaning there is abbreviation instance and a TAG instance which have no attributes). .P On failure it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP .P It should never return \f(CWDW_DLV_NO_ENTRY\fP, but callers should allow for that possibility.. .H 3 "dwarf_get_version_of_die()" .DS \f(CWint dwarf_get_version_of_die(Dwarf_Die die, Dwarf_Half *version, Dwarf_Half *offset_size)\fP .DE The function returns the CU context version through \f(CW*version\fP and the CU context offset-size through \f(CW*offset_size\fP and returns \f(CWDW_DLV_OK\fP on success. In case of error, the only errors possible involve an inappropriate NULL \f(CWdie\fP pointer so no Dwarf_Debug pointer is available. Therefore setting a Dwarf_Error would not be very meaningful (there is no Dwarf_Debug to attach it to). The function returns DW_DLV_ERROR on error. The values returned through the pointers are the values two arguments to dwarf_get_form_class() requires. .H 3 "dwarf_attrlist()" .DS \f(CWint dwarf_attrlist( Dwarf_Die die, Dwarf_Attribute** attrbuf, Dwarf_Signed *attrcount, Dwarf_Error *error)\fP .DE When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_attrlist()\fP sets \f(CWattrbuf\fP to point to an array of \f(CWDwarf_Attribute\fP descriptors corresponding to each of the attributes in die, and returns the number of elements in the array through \f(CWattrcount\fP. \f(CWDW_DLV_NO_ENTRY\fP is returned if the count is zero (no \f(CWattrbuf\fP is allocated in this case). \f(CWDW_DLV_ERROR\fP is returned on error. On a successful return from \f(CWdwarf_attrlist()\fP, each of the \f(CWDwarf_Attribute\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP, followed by free-ing the list pointed to by \f(CW*attrbuf\fP using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP, when no longer of interest (see \f(CWdwarf_dealloc()\fP). Freeing the attrlist: .in +2 .FG "Example8 dwarf_attrlist() free" .DS \f(CW void example8(Dwarf_Debug dbg, Dwarf_Die somedie) { Dwarf_Signed atcount = 0; Dwarf_Attribute *atlist = 0; Dwarf_Error error = 0; int errv = 0; errv = dwarf_attrlist(somedie, &atlist,&atcount, &error); if (errv == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < atcount; ++i) { /* use atlist[i] */ dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); } dwarf_dealloc(dbg, atlist, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_hasattr()" .DS \f(CWint dwarf_hasattr( Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE When it succeeds, the function \f(CWdwarf_hasattr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to \fInon-zero\fP if \f(CWdie\fP has the attribute \f(CWattr\fP and \fIzero\fP otherwise. If it fails, it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_attr()" .DS \f(CWint dwarf_attr( Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *return_attr, Dwarf_Error *error)\fP .DE .P When it returns \f(CWDW_DLV_OK\fP, the function \f(CWdwarf_attr()\fP sets \f(CW*return_attr\fP to the \f(CWDwarf_Attribute\fP descriptor of \f(CWdie\fP having the attribute \f(CWattr\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWattr\fP is not contained in \f(CWdie\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_lowpc()" .DS \f(CWint dwarf_lowpc( Dwarf_Die die, Dwarf_Addr * return_lowpc, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_lowpc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lowpc\fP to the low program counter value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP represents a debugging information entry with the \f(CWDW_AT_low_pc\fP attribute. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this attribute. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_highpc_b()" .DS \f(CWint dwarf_highpc_b( Dwarf_Die die, Dwarf_Addr * return_highpc, Dwarf_Half * return_form*/, enum Dwarf_Form_Class * return_class*/, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_highpc_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP to the value of the \f(CWDW_AT_high_pc\fP attribute. It also sets \f(CW*return_form\fP to the FORM of the attribute. Beginning 22 April 2019 \f(CWreturn_form\fP will not be used to return the form class if \f(CWreturn_form\fP is null. Be cautious using a null argument unless you know that only a suitably recent version of libdwarf will be used. It sets \f(CW*return_class\fP to the form class of the attribute. Beginning 22 April 2019 \f(CWreturn_class\fP will not be used to return the form class if \f(CWreturn_class\fP is null. Be cautious using a null argument unless you know that only a suitably recent version of libdwarf will be used. If the form class returned is \f(CWDW_FORM_CLASS_ADDRESS\fP the \f(CWreturn_highpc\fP is an actual pc address (1 higher than the address of the last pc in the address range).. If the form class returned is \f(CWDW_FORM_CLASS_CONSTANT\fP the \f(CWreturn_highpc\fP is an offset from the value of the the DIE's low PC address (see DWARF4 section 2.17.2 Contiguous Address Range). It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have the \f(CWDW_AT_high_pc\fP attribute. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_highpc()" .DS \f(CWint dwarf_highpc( Dwarf_Die die, Dwarf_Addr * return_highpc, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_highpc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP the high program counter value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP represents a debugging information entry with the \f(CWDW_AT_high_pc attribute\fP and the form is \f(CWDW_FORM_addr\fP (meaning the form is of class address). .P This function is useless for a \f(CWDW_AT_high_pc\fP which is encoded as a constant (which was first possible in DWARF4). .P It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this attribute. .P It returns \f(CWDW_DLV_ERROR\fP if an error occurred or if the form is not of class address. .H 3 "dwarf_dietype_offset()" .DS \f(CWint dwarf_dietype_offset(Dwarf_Die /*die*/, Dwarf_Off * /*return_off*/, Dwarf_Error * /*error*/);\fP .DE On success the function \f(CWdwarf_dietype_offset()\fP returns the offset referred to by \f(CWDW_AT_type\fP attribute of \f(CWdie\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is returned if the \f(CWdie\fP has no \f(CWDW_AT_type\fP attribute. .P \f(CWDW_DLV_ERROR\fP is returned if an error is detected. .P This feature was introduced in February 2016. .H 3 "dwarf_offset_list()" .DS \f(CWint dwarf_offset_list(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, Dwarf_Off ** offbuf, Dwarf_Unsigned * offcnt, Dwarf_Error * error); .DE On success The function \f(CWdwarf_offset_list()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*offbuf\fP to point to an array of the offsets of the direct children of the die at \f(CWoffset\fP. It sets \f(CW*offcnt\fP to point to the count of entries in the \f(CWoffset\fP array .P In case of error it returns \f(CWDW_DLV_OK\fP. .P It does not return \f(CWDW_DLV_NO_ENTRY\fP but callers should allow for that possibility anyway. .P This feature was introduced in March 2016. .P Freeing the offset_list is done as follows.: .in +2 .FG "Exampleoffset_list dwarf_offset_list() free" .DS \f(CW void exampleoffset_list(Dwarf_Debug dbg, Dwarf_Off dieoffset, Dwarf_Bool is_info) { Dwarf_Unsigned offcnt = 0; Dwarf_Off *offbuf = 0; Dwarf_Error error = 0; int errv = 0; errv = dwarf_offset_list(dbg,dieoffset, is_info, &offbuf,&offcnt, &error); if (errv == DW_DLV_OK) { Dwarf_Unsigned i = 0; for (i = 0; i < offcnt; ++i) { /* use offbuf[i] */ } dwarf_dealloc(dbg, offbuf, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_bytesize()" .DS \f(CWDwarf_Signed dwarf_bytesize( Dwarf_Die die, Dwarf_Unsigned *return_size, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_bytesize()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP to the number of bytes needed to contain an instance of the aggregate debugging information entry represented by \f(CWdie\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the byte size attribute \f(CWDW_AT_byte_size\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_bitsize()" .DS \f(CWint dwarf_bitsize( Dwarf_Die die, Dwarf_Unsigned *return_size, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_bitsize()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP to the number of bits occupied by the bit field value that is an attribute of the given die. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the bit size attribute \f(CWDW_AT_bit_size\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_bitoffset()" .DS \f(CWint dwarf_bitoffset( Dwarf_Die die, Dwarf_Unsigned *return_size, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_bitoffset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP to the number of bits to the left of the most significant bit of the bit field value. This bit offset is not necessarily the net bit offset within the structure or class , since \f(CWDW_AT_data_member_location\fP may give a byte offset to this \f(CWDIE\fP and the bit offset returned through the pointer does not include the bits in the byte offset. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the bit offset attribute \f(CWDW_AT_bit_offset\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_srclang()" .DS \f(CWint dwarf_srclang( Dwarf_Die die, Dwarf_Unsigned *return_lang, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_srclang()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lang\fP to a code indicating the source language of the compilation unit represented by the descriptor \f(CWdie\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not represent a source file debugging information entry (i.e. contain the attribute \f(CWDW_AT_language\fP). It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 3 "dwarf_arrayorder()" .DS \f(CWint dwarf_arrayorder( Dwarf_Die die, Dwarf_Unsigned *return_order, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_arrayorder()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_order\fP a code indicating the ordering of the array represented by the descriptor \f(CWdie\fP. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the array order attribute \f(CWDW_AT_ordering\fP. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .H 2 "Attribute Queries" Based on the attributes form, these operations are concerned with returning uninterpreted attribute data. Since it is not always obvious from the return value of these functions if an error occurred, one should always supply an \f(CWerror\fP parameter or have arranged to have an error handling function invoked (see \f(CWdwarf_init()\fP ) to determine the validity of the returned value and the nature of any errors that may have occurred. A \f(CWDwarf_Attribute\fP descriptor describes an attribute of a specific die. Thus, each \f(CWDwarf_Attribute\fP descriptor is implicitly associated with a specific die. .H 3 "dwarf_hasform()" .DS \f(CWint dwarf_hasform( Dwarf_Attribute attr, Dwarf_Half form, Dwarf_Bool *return_hasform, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_hasform()\fP returns \f(CWDW_DLV_OK\fP and and puts a \fInon-zero\fP value in the \f(CW*return_hasform\fP boolean if the attribute represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP has the attribute form \f(CWform\fP. If the attribute does not have that form \fIzero\fP is put into \f(CW*return_hasform\fP. \f(CWDW_DLV_ERROR\fP is returned on error. .H 3 "dwarf_whatform()" .DS \f(CWint dwarf_whatform( Dwarf_Attribute attr, Dwarf_Half *return_form, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_whatform()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP to the attribute form code of the attribute represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. It returns \f(CWDW_DLV_ERROR\fP on error. An attribute using DW_FORM_indirect effectively has two forms. This function returns the 'final' form for \f(CWDW_FORM_indirect\fP, not the \f(CWDW_FORM_indirect\fP itself. This function is what most applications will want to call. .H 3 "dwarf_whatform_direct()" .DS \f(CWint dwarf_whatform_direct( Dwarf_Attribute attr, Dwarf_Half *return_form, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_whatform_direct()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP to the attribute form code of the attribute represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. It returns \f(CWDW_DLV_ERROR\fP on error. An attribute using \f(CWDW_FORM_indirect\fP effectively has two forms. This returns the form 'directly' in the initial form field. That is, it returns the 'initial' form of the attribute. .P So when the form field is \f(CWDW_FORM_indirect\fP this call returns the \f(CWDW_FORM_indirect\fP form, which is sometimes useful for dump utilities. .P It is confusing that the _direct() function returns DW_FORM_indirect if an indirect form is involved. Just think of this as returning the initial form the first form value seen for the attribute, which is also the final form unless the initial form is \f(CWDW_FORM_indirect\fP. .H 3 "dwarf_whatattr()" .DS \f(CWint dwarf_whatattr( Dwarf_Attribute attr, Dwarf_Half *return_attr, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_whatattr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_attr\fP to the attribute code represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_formref()" .DS \f(CWint dwarf_formref( Dwarf_Attribute attr, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_formref()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the CU-relative offset represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWREFERENCE\fP class. \f(CWattr\fP must be a CU-local reference, not form \f(CWDW_FORM_ref_addr\fP and not \f(CWDW_FORM_sec_offset\fP . It is an error for the form to not belong to the \f(CWREFERENCE\fP class. It returns \f(CWDW_DLV_ERROR\fP on error. Beginning November 2010: All \f(CWDW_DLV_ERROR\fP returns set \f(CW*return_offset\fP. Most errors set \f(CW*return_offset\fP to zero, but for error \f(CWDW_DLE_ATTR_FORM_OFFSET_BAD\fP the function sets \f(CW*return_offset\fP to the invalid offset (which allows the caller to print a more detailed error message). See also \f(CWdwarf_global_formref\fP below. .H 3 "dwarf_global_formref()" .DS \f(CWint dwarf_global_formref( Dwarf_Attribute attr, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_global_formref()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the section-relative offset represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWREFERENCE\fP or other section-references classes. .P \f(CWattr\fP can be any legal \f(CWREFERENCE\fP class form plus \f(CWDW_FORM_ref_addr\fP or \f(CWDW_FORM_sec_offset\fP. It is an error for the form to not belong to one of the reference classes. It returns \f(CWDW_DLV_ERROR\fP on error. See also \f(CWdwarf_formref\fP above. .P The caller must determine which section the offset returned applies to. The function \f(CWdwarf_get_form_class()\fP is useful to determine the applicable section. .P The function converts CU relative offsets from forms such as DW_FORM_ref4 into global section offsets. .H 3 "dwarf_convert_to_global_offset()" .DS \f(CWint dwarf_convert_to_global_offset( Dwarf_Attribute attr, Dwarf_Off offset, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_convert_to_global_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the section-relative offset represented by the cu-relative offset \f(CWoffset\fP if the form of the attribute belongs to the \f(CWREFERENCE\fP class. \f(CWattr\fP must be a CU-local reference (DWARF class REFERENCE) or form \f(CWDW_FORM_ref_addr\fP and the \f(CWattr\fP must be directly relevant for the calculated \f(CW*return_offset\fP to mean anything. The function returns \f(CWDW_DLV_ERROR\fP on error. The function is not strictly necessary but may be a convenience for attribute printing in case of error. .H 3 "dwarf_formaddr()" .DS \f(CWint dwarf_formaddr( Dwarf_Attribute attr, Dwarf_Addr * return_addr, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_formaddr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_addr\fP to the address represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWADDRESS\fP class. It is an error for the form to not belong to this class. It returns \f(CWDW_DLV_ERROR\fP on error. One possible error that can arise (in a .dwo object file or a .dwp package file) is \f(CWDW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION\fP. Such an error means that the .dwo or .dwp file is missing the \f(CW.debug_addr\fP section. When opening a .dwo object file or a .dwp package file one should also open the corresponding executable and use \f(CWdwarf_set_tied_dbg()\fP to associate the objects before calling dwarf_formaddr(). H 3 "dwarf_get_debug_addr_index()" .DS \f(CWint dwarf_get_debug_addr_index( Dwarf_Attribute attr, Dwarf_Unsigned * return_index, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_debug_addr_index()\fP is only valid on attributes with form \f(CWDW_FORM_GNU_addr_index\fP or \f(CWDW_FORM_addrx\fP. The function makes it possible to print the index from a dwarf dumper program. When it succeeds, \f(CWdwarf_get_debug_addr_index()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_index\fP to the attribute's index (into the \f(CW.debug_addr\fP section). It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_debug_str_index()" .DS \f(CWint dwarf_get_debug_str_index( Dwarf_Attribute attr, Dwarf_Unsigned * return_index, Dwarf_Error * error);\fP .DE .P For an attribute with form \f(CWDW_FORM_strx\fP or \f(CWDW_FORM_GNU_str_index\fP this function retrieves the index (which refers to a .debug_str_offsets section in this .dwo). .P If successful, the function \f(CWdwarf_get_debug_str_index()\fP returns \f(CWDW_DLV_OK\fP and returns the index through the \f(CWreturn_index()\fP pointer. .P If the passed in attribute does not have this form or there is no valid compilation unit context for the attribute the function returns \f(CWDW_DLV_ERROR\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .H 3 "dwarf_formflag()" .DS \f(CWint dwarf_formflag( Dwarf_Attribute attr, Dwarf_Bool * return_bool, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_formflag()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to the (one unsigned byte) flag value. Any non-zero value means true. A zero value means false. Before 29 November 2012 this would only return 1 or zero through the pointer, but that was always a strange thing to do. The DWARF specification has always been clear that any non-zero value means true. The function should report the value found truthfully, and now it does. It returns \f(CWDW_DLV_ERROR\fP on error or if the \f(CWattr\fP does not have form flag. .H 3 "dwarf_formudata()" .DS \f(CWint dwarf_formudata( Dwarf_Attribute attr, Dwarf_Unsigned * return_uvalue, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formudata()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_uvalue\fP to the \f(CWDwarf_Unsigned\fP value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWCONSTANT\fP class. It is an error for the form to not belong to this class. It returns \f(CWDW_DLV_ERROR\fP on error. Never returns \f(CWDW_DLV_NO_ENTRY\fP. For DWARF2 and DWARF3, \f(CWDW_FORM_data4\fP and \f(CWDW_FORM_data8\fP are possibly class \f(CWCONSTANT\fP, and for DWARF4 and later they are definitely class \f(CWCONSTANT\fP. .H 3 "dwarf_formsdata()" .DS \f(CWint dwarf_formsdata( Dwarf_Attribute attr, Dwarf_Signed * return_svalue, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_formsdata()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_svalue\fP to the \f(CWDwarf_Signed\fP value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWCONSTANT\fP class. It is an error for the form to not belong to this class. If the size of the data attribute referenced is smaller than the size of the \f(CWDwarf_Signed\fP type, its value is sign extended. It returns \f(CWDW_DLV_ERROR\fP on error. Never returns \f(CWDW_DLV_NO_ENTRY\fP. For DWARF2 and DWARF3, \f(CWDW_FORM_data4\fP and \f(CWDW_FORM_data8\fP are possibly class \f(CWCONSTANT\fP, and for DWARF4 and later they are definitely class \f(CWCONSTANT\fP. .H 3 "dwarf_formblock()" .DS \f(CWint dwarf_formblock( Dwarf_Attribute attr, Dwarf_Block ** return_block, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formblock()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_block\fP to a pointer to a \f(CWDwarf_Block\fP structure containing the value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWBLOCK\fP class. It is an error for the form to not belong to this class. The storage pointed to by a successful return of \f(CWdwarf_formblock()\fP should be freed using the allocation type \f(CWDW_DLA_BLOCK\fP, when no longer of interest (see \f(CWdwarf_dealloc()\fP). It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_formstring()" .DS \f(CWint dwarf_formstring( Dwarf_Attribute attr, char ** return_string, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_string\fP to a pointer to a null-terminated string containing the value of the attribute represented by the descriptor \f(CWattr\fP if the form of the attribute belongs to the \f(CWSTRING\fP class. It is an error for the form to not belong to this class. The storage pointed to by a successful return of \f(CWdwarf_formstring()\fP should not be freed. The pointer points into existing DWARF memory and the pointer becomes stale/invalid after a call to \f(CWdwarf_finish\fP. \f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_formsig8()" .DS \f(CWint dwarf_formsig8( Dwarf_Attribute attr, Dwarf_Sig8 * return_sig8, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formsig8()\fP returns \f(CWDW_DLV_OK\fP and copies the 8 byte signature to a \f(CWDwarf_Sig8\fP structure provided by the caller if the form of the attribute is of form \f(CWDW_FORM_ref_sig8\fP ( a member of the \f(CWREFERENCE\fP class). It is an error for the form to be anything but \f(CWDW_FORM_ref_sig8\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .P This form is used to refer to a type unit. .H 3 "dwarf_formexprloc()" .DS \f(CWint dwarf_formexprloc( Dwarf_Attribute attr, Dwarf_Unsigned * return_exprlen, Dwarf_Ptr * block_ptr, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_formexprloc()\fP returns \f(CWDW_DLV_OK\fP and sets the two values thru the pointers to the length and bytes of the DW_FORM_exprloc entry if the form of the attribute is of form \f(CWDW_FORM_experloc\fP. It is an error for the form to be anything but \f(CWDW_FORM_exprloc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. .P On success the value set through the \f(CWreturn_exprlen\fP pointer is the length of the location expression. On success the value set through the \f(CWblock_ptr\fP pointer is a pointer to the bytes of the location expression itself. .H 3 "dwarf_get_form_class()" .DS \f(CWenum Dwarf_Form_Class dwarf_get_form_class( Dwarf_Half dwversion, Dwarf_Half attrnum, Dwarf_Half offset_size, Dwarf_Half form)\fP .DE .P The function is just for the convenience of libdwarf clients that might wish to categorize the FORM of a particular attribute. The DWARF specification divides FORMs into classes in Chapter 7 and this function figures out the correct class for a form. .P The \f(CWdwversion\fP passed in shall be the dwarf version of the compilation unit involved (2 for DWARF2, 3 for DWARF3, 4 for DWARF 4). The \f(CWattrnum\fP passed in shall be the attribute number of the attribute involved (for example, \f(CWDW_AT_name\fP ). The \f(CWoffset_size\fP passed in shall be the length of an offset in the current compilation unit (4 for 32bit dwarf or 8 for 64bit dwarf). The \f(CWform\fP passed in shall be the attribute form number. If \f(CWform\fP \f(CWDW_FORM_indirect\fP is passed in \f(CWDW_FORM_CLASS_UNKNOWN\fP will be returned as this form has no defined 'class'. .P When it returns \f(CWDW_FORM_CLASS_UNKNOWN\fP the function is simply saying it could not determine the correct class given the arguments presented. Some user-defined attributes might have this problem. The function \f(CWdwarf_get_version_of_die()\fP may be helpful in filling out arguments for a call to \f(CWdwarf_get_form_class()\fP. .H 3 "dwarf_discr_list()" .DS \f(CWint dwarf_discr_list( Dwarf_Debug dbg, Dwarf_Small * blockpointer, Dwarf_Unsigned blocklen, Dwarf_Dsc_Head * dsc_head_out, Dwarf_Unsigned * dsc_array_length_out, Dwarf_Error * error) Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_discr_list()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*dsc_head_out\fP to a pointer to the discriminant information for the discriminant list and sets \f(CW*dsc_array_length_out\fP to the count of discriminant entries. The only current applicability is the block value of a \f(CWDW_AT_discr_list\fP attribute. .P Those values are useful for calls to \f(CWdwarf_discr_entry_u()\fP or \f(CWdwarf_discr_entry_s()\fP to get the actual discriminant values. See the example below. It returns \f(CWDW_DLV_NO_ENTRY\fP if the block is empty. It returns \f(CWDW_DLV_ERROR\fP if an error occurred. .P When the call was successful and the \f(CWDwarf_Dsc_Head\fP is no longer needed, call \f(CWdwarf_dealloc()\fP to free all the space related to this. .DS void example_discr_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Half attrnum, Dwarf_Bool isunsigned, Dwarf_Half theform, Dwarf_Error *err) { /* The example here assumes that attribute attr is a DW_AT_discr_list. isunsigned should be set from the signedness of the parent of 'die' per DWARF rules for DW_AT_discr_list. */ enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN; Dwarf_Half version = 0; Dwarf_Half offset_size = 0; int wres = 0; wres = dwarf_get_version_of_die(die,&version,&offset_size); if (wres != DW_DLV_OK) { /* FAIL */ return; } fc = dwarf_get_form_class(version,attrnum,offset_size,theform); if (fc == DW_FORM_CLASS_BLOCK) { int fres = 0; Dwarf_Block *tempb = 0; fres = dwarf_formblock(attr, &tempb, err); if (fres == DW_DLV_OK) { Dwarf_Dsc_Head h = 0; Dwarf_Unsigned u = 0; Dwarf_Unsigned arraycount = 0; int sres = 0; sres = dwarf_discr_list(dbg, (Dwarf_Small *)tempb->bl_data, tempb->bl_len, &h,&arraycount,err); if (sres == DW_DLV_NO_ENTRY) { /* Nothing here. */ dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } if (sres == DW_DLV_ERROR) { /* FAIL . */ dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } for(u = 0; u < arraycount; u++) { int u2res = 0; Dwarf_Half dtype = 0; Dwarf_Signed dlow = 0; Dwarf_Signed dhigh = 0; Dwarf_Unsigned ulow = 0; Dwarf_Unsigned uhigh = 0; if (isunsigned) { u2res = dwarf_discr_entry_u(h,u, &dtype,&ulow,&uhigh,err); } else { u2res = dwarf_discr_entry_s(h,u, &dtype,&dlow,&dhigh,err); } if( u2res == DW_DLV_ERROR) { /* Something wrong */ dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } if( u2res == DW_DLV_NO_ENTRY) { /* Impossible. u < arraycount. */ dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); return; } /* Do something with dtype, and whichever of ulow, uhigh,dlow,dhigh got set. Probably save the values somewhere. Simple casting of dlow to ulow (or vice versa) will not get the right value due to the nature of LEB values. Similarly for uhigh, dhigh. One must use the right call. */ } dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); } } } .DE .H 3 "dwarf_discr_entry_u()" .DS \f(CWint dwarf_discr_entry_u( Dwarf_Dsc_Head dsc_head, Dwarf_Unsigned dsc_array_index, Dwarf_Half *dsc_type, Dwarf_Unsigned *dsc_low, Dwarf_Unsigned *dsc_high, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_discr_entry_u()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*dsc_type\fP, \f(CW*dsc_low\fP, and \f(CW*dsc_high\fP to the discriminent values for that index. Valid \f(CWdsc_array_index\fP values are zero to \f(CW(dsc_array_length_out -1)\fP from a \f(CWdwarf_discr_list()\fP call. .P If \f(CW*dsc_type\fP is \f(CWDW_DSC_label\fP \f(CW*dsc_low\fP is set to the discriminant value and \f(CW*dsc_high\fP is set to zero. .P If \f(CW*dsc_type\fP is \f(CWDW_DSC_range\fP \f(CW*dsc_low\fP is set to the low end of the discriminant range and and \f(CW*dsc_high\fP is set to the high end of the discriminant range. .P Due to the nature of the LEB numbers in the discriminant representation in DWARF one must call the correct one of \f(CWdwarf_discr_entry_u()\fP or \f(CWdwarf_discr_entry_s()\fP based on whether the discriminant is signed or unsigned. Casting an unsigned to signed is not always going to get the right value. .P If \f(CWdsc_array_index\fP is outside the range of valid indexes the function returns \f(CWDW_DLV_NO_ENTRY\fP. On error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to an error pointer. .H 3 "dwarf_discr_entry_s()" .DS \f(CWint dwarf_discr_entry_s( Dwarf_Dsc_Head dsc_head, Dwarf_Unsigned dsc_array_index, Dwarf_Half *dsc_type, Dwarf_Signed *dsc_low, Dwarf_Signed *dsc_high, Dwarf_Error *error)\fP .DE This is identical to \f(CWdwarf_discr_entry_u()\fP except that the discriminant values are signed values in this interface. Callers must check the discriminant type and call the correct function. .H 2 "Location List operations" .H 3 "dwarf_get_loclist_c()" .DS int dwarf_get_loclist_c (Dwarf_Attribute attr, Dwarf_Loc_Head_c * loclist_head, Dwarf_Unsigned * locCount, Dwarf_Error * error); .DE This function returns a pointer that is, in turn, used to make possible calls to return the details of the location list. .P The incoming argument \f(CWattr\fP should have one of the FORMs of a location expression or location list. .P On success this returns \f(CWDW_DLV_OK\fP and sets \f(CW*loclist_head\fP to a pointer used in further calls (see the example and descriptions that follow it). \f(CWlocCount\fP is set to the number of entries in the location list (or if the FORM is of a location expression the \f(CWlocCount\fP will be set to one). At this point one cannot yet tell if it was a location list or a location expression (see . \f(CWdwarf_get_locdesc_entry_c{}\fP). .P In case of error \f(CWDW_DLV_ERROR\fP is returned and \f(CW*error\fP is set to an error designation. .P A return of \f(CWDW_DLV_NO_ENTRY\fP may be possible but is a bit odd. .DS \f(CW void example_loclistc(Dwarf_Debug dbg,Dwarf_Attribute someattr) { Dwarf_Unsigned lcount = 0; Dwarf_Loc_Head_c loclist_head = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_get_loclist_c(someattr,&loclist_head,&lcount,&error); if (lres == DW_DLV_OK) { Dwarf_Unsigned i = 0; /* Before any return remember to call dwarf_loc_head_c_dealloc(loclist_head); */ for (i = 0; i < lcount; ++i) { Dwarf_Small loclist_source = 0; Dwarf_Small lle_value = 0; /* DWARF5 */ Dwarf_Addr lopc = 0; Dwarf_Addr hipc = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Locdesc_c locentry = 0; /* section_offset is the section offset of the expression, not the location description prefix. */ Dwarf_Unsigned section_offset = 0; /* locdesc_offset is the section offset of the location description prefix. */ Dwarf_Unsigned locdesc_offset = 0; lres = dwarf_get_locdesc_entry_c(loclist_head, i, &lle_value,&lopc,&hipc, &ulocentry_count, &locentry, &loclist_source, §ion_offset, &locdesc_offset, &error); if (lres == DW_DLV_OK) { /* Here, use loclist_source and lle_value to determine what sort of loclist it is and what to do with the values. locentry_count will only be more than zero if there is a set of location operators. One must use lle_value to determine how to interpret lopc,hipc as sometimes they are a target address and sometimes an index into .debug_addr or even a length. */ Dwarf_Unsigned j = 0; int opres = 0; Dwarf_Small op = 0; for (j = 0; j < ulocentry_count; ++j) { Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned offsetforbranch = 0; opres = dwarf_get_location_op_value_c(locentry, j,&op,&opd1, &opd2,&opd3,&offsetforbranch, &error); if (opres == DW_DLV_OK) { /* Do something with the operators. */ } else { /*Something is wrong. */ } } } else { /* Something is wrong. Do something. */ } } /* In case of error or any other situation where one is giving up one can call dwarf_loc_head_c_dealloc() to free all the memory associated with loclist_head. */ dwarf_loc_head_c_dealloc(loclist_head); loclist_head = 0; } } \fP .DE .H 3 "dwarf_get_locdesc_entry_c()" .DS int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/, Dwarf_Unsigned /*index*/, /* identifies type of locdesc entry*/ Dwarf_Small * /*lle_value_out*/, Dwarf_Addr * /*lowpc_out*/, Dwarf_Addr * /*hipc_out*/, Dwarf_Unsigned * /*loclist_count_out*/, /* Returns pointer to specific Locdesc index refers to */ Dwarf_Locdesc_c * /*locentry_out*/, Dwarf_Small * /*loclist_source_out*/, /* 0,1, or 2 */ Dwarf_Unsigned * /*expression_offset_out*/, Dwarf_Unsigned * /*locdesc_offset_out*/, Dwarf_Error * /*error*/); .DE This function returns overall information about a location list or location description. Details about location operators are retrieved by a call to \f(CWdwarf_get_location_op_value_c()\fP (described below). The values returned here have been unified, hiding irrelevant differences between DWARF2 location expressions/lists and DWARF5 split-dwarf location expressions/lists. .P In case of success \f(CWDW_DLV_OK\fP is returned and arguments are set through the pointers to return values to the caller. Now we describe each argument. .P Return value \f(CW*loclist_source_out\fP is critical as it identifies the sort of entry we have. If its value is zero (0) it identifies the location description is a location expression. In that case \f(CW*lle_value_out\fP, \f(CW*lowpc_out\fP, and \f(CW*hipc_out\fP are not really interesting. And because it is a location expression the \f(CWindex\fP has to have been zero as there is no real list, just an expression made to look like a list entry. .P If \f(CW*loclist_source_out\fP is one (1) then this is a location list entry in DWARF2,3,4 loclist form. Here the \f(CW*lle_value_out\fP has been created by libdwarf to match the split-dwarf \f(CWDW_LLE_\fP value that the standard loclist entry represents ( \f(CWDW_LLE_end_of_list_entry\fP, \f(CWDW_LLE_base_address_selection_entry\fP, or \f(CWDW_LLE_offset_pair_entry\fP ). .P If \f(CW*loclist_source_out\fP is two (2) then this is a location list entry in DWARF5 split-dwarf (.dwo) location-entry-form. \f(CW*lle_value_out\fP is set to the \f(CWDW_LLE_\fP value that the split-dwarf loclist entry contains. .P The \f(CWDW_LLE_\fP value determines how one is to interpret \f(CWlopc_out\fP and \f(CWhipc_out\fP. See the DWARF5 standard. .P The argument \f(CWloclist_count_out\fP returns the number of operators in the location expression involved (which may be zero). .P The argument \f(CWlocentry_out\fP returns an identifier used in calls to \f(CWdwarf_get_location_op_value_c()\fP. .P The argument \f(CWexpression_offset_out\fP returns the offset (in the .debug_loc(.dso) or .debug_info(.dwo) of the location expression itself (possibly useful for debugging). .P The argument \f(CWlocdesc_offset_out\fP returns the offset (in the .debug_loc(.dso) of the location list entry itself (possibly useful for debugging). .P In case of error \f(CWDW_DLV_ERROR\fP is returned and \f(CW*error\fP is set to an error designation. .P A return of \f(CWDW_DLV_NO_ENTRY\fP may be possible but is a bit odd. .H 3 "dwarf_get_location_op_value_c()" .DS int dwarf_get_location_op_value_c(Dwarf_Locdesc_c locdesc, Dwarf_Unsigned index, Dwarf_Small * atom_out, Dwarf_Unsigned * operand1, Dwarf_Unsigned * operand2, Dwarf_Unsigned * operand3, Dwarf_Unsigned * offset_for_branch, Dwarf_Error* error); .DE On sucess The function \f(CWdwarf_get_location_op_value_c()\fP returns the information for the single operator number \f(CWindex\fP from the location expression \f(CWlocdesc\fP. It sets the following values. .P \f(CWatom_out\fP is set to the applicable operator code, for example \f(CWDW_OP_reg5\fP. .P \f(CWoperand1\fP, \f(CWoperand2\fP, and \f(CWoperand3\fP are set to the operator operands as applicable (see DWARF documents on the operands for each operator). \f(CWoperand3\fP is new as of DWARF5. .P When a DWARF operand is not of a size fixed by dwarf, or is possibly too large for a dwarf stack entry, libdwarf will insert a pointer (to memory in the dwarf data somewhere) as the operand value. \f(CWDW_OP_implicit_value operand 2\fP, \f(CWDW_OP_[GNU_]entry_value operand 2\fP, and \f(CWDW_OP_[GNU_]const_type operand 3\fP are instances of this. .P \f(CWoffset_for_branch\fP is set to the offset (in bytes) in this expression of this operator. The value makes it possible for callers to implement the operator branch operators. .P In case of an error, the function returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to an error value. .P \f(CWDW_DLV_NO_ENTRY\fP is probably not a possible return value, but please test for it anyway. .H 3 "dwarf_loclist_from_expr_c()" .DS int dwarf_loclist_from_expr_c(Dwarf_Debug dbg, Dwarf_Ptr expression_in, Dwarf_Unsigned expression_length, Dwarf_Half address_size, Dwarf_Half offset_size, Dwarf_Small dwarf_version, Dwarf_Loc_Head_c* loc_head, Dwarf_Unsigned * listlen, Dwarf_Error * error); .DE Frame operators such as DW_CFA_def_cfa_expression have a location expression and the location_expression is accessed with this function. .P On success it returns \f(CWDW_DLV_OK\fP and sets the two return arguments (explained a few lines later here). .P The \f(CWexpression_in\fP argument must contain a valid pointer to location expression bytes. The \f(CWexpression_length\fP argument must contain the length of that location expression in bytes. .P The \f(CWaddress_size\fP argument must contain the size of an address on the target machine for this expression (normally 4 or 8). The \f(CWoffset_size\fP argument must contain the size of an offset in the expression (normally 4, sometimes 8). The \f(CWversion\fP argument must contain the dwarf_version of the expression (2,3,4, or 5). .P The returned value \f(CW*loc_head\fP is used to actually access the location expression details (see the example following). .P The returned value \f(CW*listlen\fP is the number of location expressions (ie 1) in the location list (for uniformity of access we make it look like a single-entry location list). .P On error the function returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to reflect the error. .P A return of \f(CWDW_DLV_NO_ENTRY\fP is probably impossible, but callers should assume it is possible. No return arguments are set in this case. .DS void example_locexprc(Dwarf_Debug dbg,Dwarf_Ptr expr_bytes, Dwarf_Unsigned expr_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version) { Dwarf_Loc_Head_c head = 0; Dwarf_Locdesc_c locentry = 0; int res2 = 0; Dwarf_Unsigned lopc = 0; Dwarf_Unsigned hipc = 0; Dwarf_Unsigned ulistlen = 0; Dwarf_Unsigned ulocentry_count = 0; Dwarf_Unsigned section_offset = 0; Dwarf_Unsigned locdesc_offset = 0; Dwarf_Small lle_value = 0; Dwarf_Small loclist_source = 0; Dwarf_Unsigned i = 0; Dwarf_Error error = 0; res2 = dwarf_loclist_from_expr_c(dbg, expr_bytes,expr_len, addr_size, offset_size, version, &head, &ulistlen, &error); if(res2 == DW_DLV_NO_ENTRY) { return; } if(res2 == DW_DLV_ERROR) { return; } /* These are a location expression, not loclist. So we just need the 0th entry. */ res2 = dwarf_get_locdesc_entry_c(head, 0, /* Data from 0th LocDesc */ &lle_value, &lopc, &hipc, &ulocentry_count, &locentry, &loclist_source, §ion_offset, &locdesc_offset, &error); if (res2 == DW_DLV_ERROR) { dwarf_loc_head_c_dealloc(head); return; } else if (res2 == DW_DLV_NO_ENTRY) { dwarf_loc_head_c_dealloc(head); return; } /* ASSERT: ulistlen == 1 */ for (i = 0; i < ulocentry_count;++i) { Dwarf_Small op = 0; Dwarf_Unsigned opd1 = 0; Dwarf_Unsigned opd2 = 0; Dwarf_Unsigned opd3 = 0; Dwarf_Unsigned offsetforbranch = 0; res2 = dwarf_get_location_op_value_c(locentry, i, &op,&opd1,&opd2,&opd3,&offsetforbranch, &error); /* Do something with the expression operator and operands */ if (res2 != DW_DLV_OK) { dwarf_loc_head_c_dealloc(head); return; } } dwarf_loc_head_c_dealloc(head); } .DE .H 3 "dwarf_loc_head_c_dealloc()" .DS void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head); .DE This function frees all the memory associated with the \f(CWloclist_head\fP. There is no return value. .H 3 "dwarf_loclist_n()" .DS \f(CWint dwarf_loclist_n( Dwarf_Attribute attr, Dwarf_Locdesc ***llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE This interface cannot handle DWARF5 or Split Dwarf. Use \f(CWdwarf_get_loclist_c()\fP and related functions instead (as of November 2015). The function \f(CWdwarf_loclist_n()\fP sets \f(CW*llbuf\fP to point to an array of \f(CWDwarf_Locdesc\fP pointers corresponding to each of the location expressions in a location list, and sets \f(CW*listlen\fP to the number of elements in the array and returns \f(CWDW_DLV_OK\fP if the attribute is appropriate. .P This is the preferred function for Dwarf_Locdesc as it is the interface allowing access to an entire loclist. (use of \f(CWdwarf_loclist_n()\fP is suggested as the better interface, though \f(CWdwarf_loclist()\fP is still supported.) .P If the attribute is a reference to a location list (DW_FORM_data4 or DW_FORM_data8) the location list entries are used to fill in all the fields of the \f(CWDwarf_Locdesc\fP(s) returned. .P If the attribute is a location description (DW_FORM_block2 or DW_FORM_block4) then some of the \f(CWDwarf_Locdesc\fP values of the single \f(CWDwarf_Locdesc\fP record are set to 'sensible' but arbitrary values. Specifically, ld_lopc is set to 0 and ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1. .P If the attribute is a reference to a location expression (DW_FORM_locexper) then some of the \f(CWDwarf_Locdesc\fP values of the single \f(CWDwarf_Locdesc\fP record are set to 'sensible' but arbitrary values. Specifically, ld_lopc is set to 0 and ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1. .P It returns \f(CWDW_DLV_ERROR\fP on error. .P \f(CWdwarf_loclist_n()\fP works on \f(CWDW_AT_location\fP, \f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP, \f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and \f(CWDW_AT_return_addr\fP attributes. .P If the attribute is \f(CWDW_AT_data_member_location\fP the value may be of class CONSTANT. \f(CWdwarf_loclist_n()\fP is unable to read class CONSTANT, so you need to first determine the class using \f(CWdwarf_get_form_class()\fP and if it is class CONSTANT call \f(CWdwarf_formsdata()\fP or \f(CWdwarf_formudata()\fP to get the constant value (you may need to call both as DWARF4 does not define the signedness of the constant value). .P Storage allocated by a successful call of \f(CWdwarf_loclist_n()\fP should be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP field of each \f(CWDwarf_Locdesc\fP structure should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. and the \f(CWllbuf[]\fP space pointed to should be deallocated with allocation type \f(CWDW_DLA_LOCDESC\fP. This should be followed by deallocation of the \f(CWllbuf\fP using the allocation type \f(CWDW_DLA_LIST\fP. .in +2 .DS \f(CW void example9(Dwarf_Debug dbg,Dwarf_Attribute someattr) { Dwarf_Signed lcount = 0; Dwarf_Locdesc **llbuf = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_loclist_n(someattr, &llbuf,&lcount,&error); if (lres == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < lcount; ++i) { /* Use llbuf[i]. Both Dwarf_Locdesc and the array of Dwarf_Loc it points to are defined in libdwarf.h: they are not opaque structs. */ dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg,llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_loclist()" .DS \f(CWint dwarf_loclist( Dwarf_Attribute attr, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE Use \f(CWdwarf_get_loclist_c()\fP and related functions instead (as of November 2015). The function \f(CWdwarf_loclist()\fP sets \f(CW*llbuf\fP to point to a \f(CWDwarf_Locdesc\fP pointer for the single location expression it can return. It sets \f(CW*listlen\fP to 1. and returns \f(CWDW_DLV_OK\fP if the attribute is appropriate. .P It is less flexible than \f(CWdwarf_loclist_n()\fP in that \f(CWdwarf_loclist()\fP can handle a maximum of one location expression, not a full location list. If a location-list is present it returns only the first location-list entry location description. Use \f(CWdwarf_loclist_n()\fP instead. .P It returns \f(CWDW_DLV_ERROR\fP on error. \f(CWdwarf_loclist()\fP works on \f(CWDW_AT_location\fP, \f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP, \f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and \f(CWDW_AT_return_addr\fP attributes. .P Storage allocated by a successful call of \f(CWdwarf_loclist()\fP should be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP field of each \f(CWDwarf_Locdesc\fP structure should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. This should be followed by deallocation of the \f(CWllbuf\fP using the allocation type \f(CWDW_DLA_LOCDESC\fP. .in +2 .FG "Examplea dwarf_loclist()" .DS \f(CW void examplea(Dwarf_Debug dbg,Dwarf_Attribute someattr) { Dwarf_Signed lcount = 0; Dwarf_Locdesc *llbuf = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_loclist(someattr, &llbuf,&lcount,&error); if (lres == DW_DLV_OK) { /* lcount is always 1, (and has always been 1) */ /* Use llbuf here. */ dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); } } \fP .DE .in -2 .P .H 3 "dwarf_loclist_from_expr()" .DS \f(CWint dwarf_loclist_from_expr( Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE Use \f(CWdwarf_loclist_from_expr_b()\fP instead. This function is obsolete. .P The function \f(CWdwarf_loclist_from_expr()\fP sets \f(CW*llbuf\fP to point to a \f(CWDwarf_Locdesc\fP pointer for the single location expression which is pointed to by \f(CW*bytes_in\fP (whose length is \f(CW*bytes_len\fP). It sets \f(CW*listlen\fP to 1. and returns \f(CWDW_DLV_OK\fP if decoding is successful. Some sources of bytes of expressions are dwarf expressions in frame operations like \f(CWDW_CFA_def_cfa_expression\fP, \f(CWDW_CFA_expression\fP, and \f(CWDW_CFA_val_expression\fP. .P Any address_size data in the location expression is assumed to be the same size as the default address_size for the object being read (normally 4 or 8). .P It returns \f(CWDW_DLV_ERROR\fP on error. .P Storage allocated by a successful call of \f(CWdwarf_loclist_from_expr()\fP should be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP). The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP field of each \f(CWDwarf_Locdesc\fP structure should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. This should be followed by deallocation of the \f(CWllbuf\fP using the allocation type \f(CWDW_DLA_LOCDESC\fP. .in +2 .FG "Exampleb dwarf_loclist_from_expr()" .DS \f(CW void exampleb(Dwarf_Debug dbg,Dwarf_Ptr data, Dwarf_Unsigned len) { Dwarf_Signed lcount = 0; Dwarf_Locdesc *llbuf = 0; Dwarf_Error error = 0; int lres = 0; lres = dwarf_loclist_from_expr(dbg,data,len, &llbuf,&lcount, &error); if (lres == DW_DLV_OK) { /* lcount is always 1 */ /* Use llbuf here.*/ dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); } } \fP .DE .in -2 .P .H 3 "dwarf_loclist_from_expr_b()" .DS \f(CWint dwarf_loclist_from_expr_a( Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Half version_stamp, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_loclist_from_expr_b()\fP is identical to \f(CWdwarf_loclist_from_expr_a()\fP in every way except that the caller passes an additional argument \f(CWversion_stamp\fP containing the version stamp (2 for DWARF2, etc) of the CU using this location expression and an additional argument of the offset size of the CU using this location expression. The DW_OP_GNU_implicit_pointer operation requires this version and offset information to be correctly processed. .P The \f(CWaddr_size\fP argument (from 27April2009) is needed to correctly interpret frame information as different compilation units can have different address sizes. DWARF4 adds address_size to the CIE header. .P .H 3 "dwarf_loclist_from_expr_a()" .DS \f(CWint dwarf_loclist_from_expr_a( Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error)\fP .DE Use \f(CWdwarf_loclist_from_expr_b()\fP instead. This function is obsolete. .P The function \f(CWdwarf_loclist_from_expr_a()\fP is identical to \f(CWdwarf_loclist_from_expr()\fP in every way except that the caller passes the additional argument \f(CWaddr_size\fP containing the address size (normally 4 or 8) applying this location expression. .P The \f(CWaddr_size\fP argument (added 27April2009) is needed to correctly interpret frame information as different compilation units can have different address sizes. DWARF4 adds address_size to the CIE header. .P .H 2 "Line Number Operations" These functions are concerned with accessing line number entries, mapping debugging information entry objects to their corresponding source lines, and providing a mechanism for obtaining information about line number entries. Although, the interface talks of "lines" what is really meant is "statements". In case there is more than one statement on the same line, there will be at least one descriptor per statement, all with the same line number. If column number is also being represented they will have the column numbers of the start of the statements also represented. .P There can also be more than one Dwarf_Line per statement. For example, if a file is preprocessed by a language translator, this could result in translator output showing 2 or more sets of line numbers per translated line of output. .P \f(CW \fP As of October 2015 there are two sets of overall access and release functions. The older set of functions is \f(CWdwarf_srclines()\fP with \f(CWdwarf_srclines_dealloc()\fP. This set does not handle line table headers with no lines. .P A newer set is \f(CWdwarf_srclines_b()\fP with \f(CWdwarf_srclines_from_linecontext()\fP and \f(CWdwarf_srclines_dealloc_b()\fP. These functions provide for handling both DWARF2 through DWARF5 details and give access to line header information even if there are no lines in a particular compilation unit's line table. .P .H 3 "Get A Set of Lines (including skeleton line tables)" This set of functions works on any DWARF version. DWARF2,3,4,5 and the DWARF4 based experimental two-level line tables are all supported. What was once done by dwarf_srclines() alone is now done with two calls as described here. .P The interfaces support reading GNU two-level line tables. The format of such tables is a topic beyond the scope of this document. .P .H 3 "dwarf_srclines_b()" This is the .DS \f(CWint dwarf_srclines_b( Dwarf_Die die, Dwarf_Unsigned *version_out, Dwarf_Bool *is_single_table, Dwarf_Line_Context *context_out, Dwarf_Error *error)\fP .DE \f(CWdwarf_srclines_b()\fP takes a single argument as input, a pointer to a compilation-unit (CU) DIE. The other arguments are used to return values to the caller. On success \f(CWDW_DLV_OK\fP is returned and values are returned through the pointers. If there is no line table \f(CWDW_DLV_NO_ENTRY\fP is returned and no values are returned though the pointers. If \f(CWDW_DLV_ERROR\fP is returned the involved is returned through the \f(CWerror\fP pointer. .P The values returned on success are: .P \f(CW*version_out()\fP is set to the version number from the line table header for this CU. The experimental two-level line table value is 0xf006. Standard numbers are 2,3,4 and 5. .P \f(CW*is_single_table()\fP is set to non-zero if the line table is an ordinary single line table. If the line table is anything else (either a line table header with no lines or an experimental two-level line table) it is set to zero. .P \f(CW*context_out()\fP is set to an opaque pointer to a \f(CWDwarf_Line_Context\fP record which in turn is used to get other data from this line table. See below. .P See \f(CW*dwarf_srclines_dealloc_b()\fP for examples showing correct use. .H 3 "dwarf_get_line_section_name_from_die()" .DS \f(CWint dwarf_get_line_section_name_from_die( Dwarf_Die die, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CW*dwarf_get_line_section_name_from_die()\fP retrieves the object file section name of the applicable line section. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_srclines_from_linecontext()" .DS \f(CWint dwarf_srclines_from_linecontext( Dwarf_Line_Context line_context, Dwarf_Line ** linebuf, Dwarf_Signed *linecount, Dwarf_Error *error)\fP .DE \f(CW*dwarf_srclines_from_linecontext()\fP gives access to the line tables. On success it returns \f(CWDW_DLV_OK\fP and passes back line tables through the pointers. .P Though \f(CWDW_DLV_OK\fP will not be returned callers should assume it is possible. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error code set through the \f(CWerror\fP pointer. .P On success: .P \f(CW*linebuf\fP is set to an array of Dwarf_Line pointers. .P \f(CW*linecount\fP is set to the number of pointers in the array. .P .H 3 "dwarf_srclines_two_levelfrom_linecontext()" .DS \f(CWint dwarf_srclines_from_linecontext( Dwarf_Line_Context line_context, Dwarf_Line ** linebuf, Dwarf_Signed *linecount, Dwarf_Line ** linebuf_actuals, Dwarf_Signed *linecount_actuals, Dwarf_Error *error)\fP .DE \f(CW*dwarf_srclines_two_levelfrom_linecontext()\fP gives access to the line tables. On success it returns \f(CWDW_DLV_OK\fP and passes back line tables through the pointers. .P Though \f(CWDW_DLV_OK\fP will not be returned callers should assume it is possible. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error code set through the \f(CWerror\fP pointer. .P On success: .P \f(CW*linebuf\fP is set to an array of Dwarf_Line pointers. .P \f(CW*linecount\fP is set to the number of pointers in the array. .P If one is not intending that the experimental two-level line tables are of interest then pass NULL for \f(CW*linebuf_actuals\fP and \f(CW*linecount_actuals\fP. The NULL pointers notify the library that the second table is not to be passed back. .P If a line table is actually a two-level tables \f(CW*linebuf\fP is set to point to an array of Logicals lines. \f(CW*linecount\fP is set to the number of Logicals. \f(CW*linebuf_actals\fP is set to point to an array of Actuals lines. \f(CW*linecount_actuals\fP is set to the number of Actuals. .H 3 "dwarf_srclines_dealloc_b()" .DS \f(CWvoid dwarf_srclines_dealloc_b( Dwarf_Line_Context line_context, Dwarf_Error *error)\fP .DE This does a complete deallocation of the memory of the \f(CWDwarf_Line_Context\fP and the \f(CWDwarf_Line\fP array (or arrays) that came from the \f(CWDwarf_Line_Context\fP. On return you should set any local pointers to these buffers to NULL as a reminder that any use of the local pointers would be to stale memory. .in +2 .FG "Examplec dwarf_srclines_b()" .DS \f(CW void examplec(Dwarf_Die cu_die) { /* EXAMPLE: DWARF5 style access. */ Dwarf_Line *linebuf = 0; Dwarf_Signed linecount = 0; Dwarf_Line *linebuf_actuals = 0; Dwarf_Signed linecount_actuals = 0; Dwarf_Line_Context line_context = 0; Dwarf_Signed linecount_total = 0; Dwarf_Small table_count = 0; Dwarf_Unsigned lineversion = 0; Dwarf_Error err = 0; int sres = 0; /* ... */ /* we use 'return' here to signify we can do nothing more at this point in the code. */ sres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context,&err); if (sres != DW_DLV_OK) { /* Handle the DW_DLV_NO_ENTRY or DW_DLV_ERROR No memory was allocated so there nothing to dealloc. */ return; } if (table_count == 0) { /* A line table with no actual lines. This occurs in a DWARF5 or DWARF5 DW_TAG_type_unit as such has no lines of code but needs data for DW_AT_decl_file attributes. */ /*...do something, see dwarf_srclines_files_count() etc below. */ dwarf_srclines_dealloc_b(line_context); /* All the memory is released, the line_context and linebuf zeroed now as a reminder they are stale. */ linebuf = 0; line_context = 0; } else if (table_count == 1) { Dwarf_Signed i = 0; Dwarf_Signed baseindex = 0; Dwarf_Signed file_count = 0; Dwarf_Signed endindex = 0; /* Standard dwarf 2,3,4, or 5 line table */ /* Do something. */ /* First let us index through all the files listed in the line table header. */ sres = dwarf_srclines_files_indexes(line_context, &baseindex,&file_count,&endindex,&err); if (sres != DW_DLV_OK) { /* Something badly wrong! */ return; } /* Works for DWARF2,3,4 (one-based index) and DWARF5 (zero-based index) */ for (i = baseindex; i < endindex; i++) { Dwarf_Unsigned dirindex = 0; Dwarf_Unsigned modtime = 0; Dwarf_Unsigned flength = 0; Dwarf_Form_Data16 *md5data = 0; int vres = 0; const char *name = 0; vres = dwarf_srclines_files_data_b(line_context,i, &name,&dirindex, &modtime,&flength, &md5data,&err); if (vres != DW_DLV_OK) { /* something very wrong. */ return; } /* Do something. */ } /* For this case where we have a line table we will likely wish to get the line details: */ sres = dwarf_srclines_from_linecontext(line_context, &linebuf,&linecount, &err); if (sres != DW_DLV_OK) { /* Error. Clean up the context information. */ dwarf_srclines_dealloc_b(line_context); return; } /* The lines are normal line table lines. */ for (i = 0; i < linecount; ++i) { /* use linebuf[i] */ } dwarf_srclines_dealloc_b(line_context); /* All the memory is released, the line_context and linebuf zeroed now as a reminder they are stale */ linebuf = 0; line_context = 0; linecount = 0; } else { Dwarf_Signed i = 0; /* ASSERT: table_count == 2, Experimental two-level line table. Version 0xf006 We do not define the meaning of this non-standard set of tables here. */ /* For 'something C' (two-level line tables) one codes something like this Note that we do not define the meaning or use of two-level line tables as these are experimental, not standard DWARF. */ sres = dwarf_srclines_two_level_from_linecontext(line_context, &linebuf,&linecount, &linebuf_actuals,&linecount_actuals, &err); if (sres == DW_DLV_OK) { for (i = 0; i < linecount; ++i) { /* use linebuf[i], these are the 'logicals' entries. */ } for (i = 0; i < linecount_actuals; ++i) { /* use linebuf_actuals[i], these are the actuals entries */ } dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } else if (sres == DW_DLV_NO_ENTRY) { /* This should be impossible, but do something. */ /* Then Free the line_context */ dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } else { /* ERROR, show the error or something. Free the line_context. */ dwarf_srclines_dealloc_b(line_context); line_context = 0; linebuf = 0; linecount = 0; linebuf_actuals = 0; linecount_actuals = 0; } } } \fP .DE .in -2 .H 2 "Line Context Details (DWARF5 style)" New in October 2015. When a \f(CW Dwarf_Line_Context \fP has been returned by \f(CWdwarf_srclines_b()\fP that line context data's details can be retrieved with the following set of calls. .H 3 "dwarf_srclines_table_offset()" .DS \f(CW int dwarf_srclines_table_offset(Dwarf_Line_Context line_context, Dwarf_Unsigned * offset, Dwarf_Error * error); \fP .DE On success, this function returns the offset (in the object file line section) of the actual line data (i.e. after the line header for this compilation unit) through the \f(CWoffset\fP pointer. The offset is probably only of interest when printing detailed information about a line table header. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_version()" .DS \f(CW int dwarf_srclines_version(Dwarf_Line_Context line_context, Dwarf_Unsigned * version, Dwarf_Error * error); \fP .DE On success \f(CWDW_DLV_OK\fP is returned and the line table version number is returned through the \f(CWversion\fP pointer. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_comp_dir()" .DS \f(CW int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context, const char ** compilation_directory, Dwarf_Error * error); \fP .DE On success this returns a pointer to the compilation directory string for this line table in \f(CW*compilation_directory\fP. That compilation string may be NULL or the empty string. The string pointer is valid until the \f(CWline_context\fP has been deallocated. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_indexes()" .DS \f(CW int dwarf_srclines_files_indexes(Dwarf_Line_Context line_context, Dwarf_Signed * baseindex, Dwarf_Signed * count, Dwarf_Signed * endindex, Dwarf_Error * error); \fP .DE With DWARF5 the base file number index in the line table changed from zero (DWARF2,3,4) to one (DWARF5). Which meant iterating through the valid source file indexes became messy if one used the older \f(CWdwarf_srclines_files_count()\fP function (zero-based and one-based indexing being incompatible). See Figure "Examplec dwarf_srclines_b()" above for use of this function in accessing file names. .P The base index of files in the files list of a line table header will be returned through \f(CWbaseindex\fP. .P The number of files in the files list of a line table header will be returned through \f(CWcount\fP. .P The end index of files in the files list of a line table header will be returned through \f(CWendindex\fP. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_count()" .DS \f(CW int dwarf_srclines_files_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error); \fP .DE On success, the number of files in the files list of a line table header will be returned through \f(CWcount\fP. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_data_b()" This supplants \f(CWdwarf_srclines_files_data()\fP as of March 2018 to allow access to the md5 value in DWARF5. The function \f(CWdwarf_srclines_files_data()\fP continues to be supported. .DS \f(CW int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Form_Data16 ** md5_value, Dwarf_Error * error); \fP .DE On success, data about a single file in the files list will be returned through the pointers. See DWARF documentation for the meaning of these fields. \f(CWcount\fP. Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF2,3,4. For a dwarf5 line table index values 0...count-1 are legal. This is certainly awkward. .P If \f(CWmd5_value\fP is non-null it is used to pass a back a pointer to a \f(CWDwarf_Form_Data16\fP md5 value if the md5 value is present. Otherwise a zero value is passed back to indicate there was no such field. The 16-byte value pointed to is inside the line_context, so if you want to keep the value you should probably copy it to storage you control. .P This returns the raw files data from the line table header. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_files_data()" This interface was created in October 2015. It cannot return the DWARF5 MD5 value. See the newer dwarf_srclines_files_data_b(). .DS \f(CW int dwarf_srclines_files_data(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Unsigned * directory_index, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Error * error); \fP .DE On success, data about a single file in the files list will be returned through the pointers. See DWARF documentation for the meaning of these fields. \f(CWcount\fP. Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF2,3,4. For a dwarf5 line table index values 0...count-1 are legal. This is certainly awkward. .P This returns the raw files data from the line table header. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_include_dir_count()" .DS \f(CW int dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error); \fP .DE On success, the number of files in the includes list of a line table header will be returned through \f(CWcount\fP. .P Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF 2,3 and 4. For a dwarf5 line table index values 0...count-1 are legal. This is certainly awkward. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_include_dir_data()" .DS \f(CW int dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Error * error); \fP .DE On success, data about a single file in the include files list will be returned through the pointers. See DWARF documentation for the meaning of these fields. .P Valid \f(CWindex\fP. values are 1 through \f(CWcount\fP, reflecting the way the table is defined by DWARF. .P In case of error, \f(CWDW_DLV_ERROR\fP is returned and the error is set through the \f(CWerror\fP pointer. \f(CWDW_DLV_NO_ENTRY\fP will not be returned. .H 3 "dwarf_srclines_subprog_count()" \f(CW int dwarf_srclines_subprog_count(Dwarf_Line_Context line_context, Dwarf_Signed * count, Dwarf_Error * error); \fP This is only useful with experimental two-level line tables. .H 3 "dwarf_srclines_subprog_data()" \f(CW int dwarf_srclines_subprog_data(Dwarf_Line_Context line_context, Dwarf_Signed index, const char ** name, Dwarf_Unsigned * decl_file, Dwarf_Unsigned * decl_line, Dwarf_Error * error); \fP This is only useful with experimental two-level line tables. .H 2 "Get A Set of Lines (DWARF2,3,4 style)" The function returns information about every source line for a particular compilation-unit. The compilation-unit is specified by the corresponding die. It does not support line tables with no lines very well nor does it support experimental two-level linetables. .H 3 "dwarf_srclines()" .DS \f(CWint dwarf_srclines( Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, Dwarf_Error *error)\fP .DE This function is not useful for DWARF5 skeleton line tables nor for two-level line tables. It works for DWARF2,3,4,5 ordinary single line tables. The function \f(CWdwarf_srclines()\fP places all line number descriptors for a single compilation unit into a single block, sets \f(CW*linebuf\fP to point to that block, sets \f(CW*linecount\fP to the number of descriptors in this block and returns \f(CWDW_DLV_OK\fP. .in +2 .P To get a more detailed view of the contents of a dwarf line table header see \f(CWdwarf_srclines_b()\fP and the routines that use the Dwarf_Line_Context information, such as \f(CWdwarf_srcfiles_comp_dir()\fP, \f(CWdwarf_srclines_files_count()\fP, \f(CWdwarf_srclines_include_dir_count()\fP and similar functions. .in -2 .P The compilation-unit is indicated by the given \f(CWdie\fP which must be a compilation-unit die. It returns \f(CWDW_DLV_ERROR\fP on error. On successful return, line number information should be freed using \f(CWdwarf_srclines_dealloc()\fP when no longer of interest. .P .in +2 .FG "Exampled dwarf_srclines()" .DS \f(CW /* dwarf_srclines_b() should be used instead. */ void exampled(Dwarf_Debug dbg,Dwarf_Die somedie) { Dwarf_Signed count = 0; Dwarf_Line *linebuf = 0; Dwarf_Signed i = 0; Dwarf_Error error = 0; int sres = 0; sres = dwarf_srclines(somedie, &linebuf,&count, &error); if (sres == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use linebuf[i] */ } dwarf_srclines_dealloc(dbg, linebuf, count); } } \fP .DE .in -2 .P An alternative using \f(CWdwarf_dealloc()\fP directly is no longer (as of 2015) described here. It works as well as ever, but it has been obsolete since 2005. still works, but does not completely free all data allocated. The \f(CWdwarf_srclines_dealloc()\fP routine was created to fix the problem of incomplete deallocation. .H 2 "Get the set of Source File Names" The function returns the names of the source files that have contributed to the compilation-unit represented by the given DIE. Only the source files named in the statement program prologue are returned. .H 3 dwarf_srcfiles() This works for for all line tables. .DS \f(CWint dwarf_srcfiles( Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, Dwarf_Error *error)\fP .DE When it succeeds \f(CWdwarf_srcfiles()\fP returns \f(CWDW_DLV_OK\fP and puts the number of source files named in the statement program prologue indicated by the given \f(CWdie\fP into \f(CW*srccount\fP. Source files defined in the statement program are ignored. The given \f(CWdie\fP should have the tag \f(CWDW_TAG_compile_unit\fP, \f(CWDW_TAG_partial_unit\fP, or \f(CWDW_TAG_type_unit\fP . The location pointed to by \f(CWsrcfiles\fP is set to point to a list of pointers to null-terminated strings that name the source files. .P On a successful return from \f(CWdwarf_srcfiles()\fP each of the strings returned should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. This should be followed by free-ing the list using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no corresponding statement program (i.e., if there is no line information). .in +2 .FG "Exampled dwarf_srcfiles()" .DS \f(CW void examplee(Dwarf_Debug dbg,Dwarf_Die somedie) { Dwarf_Signed count = 0; char **srcfiles = 0; Dwarf_Signed i = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_srcfiles(somedie, &srcfiles,&count,&error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use srcfiles[i] */ dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); } dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); } } \fP .DE .in -2 .H 2 "Get Information About a Single Line Table Line" The following functions can be used on the \f(CWDwarf_Line\fP descriptors returned by \f(CWdwarf_srclines()\fP or \f(CWdwarf_srclines_from_linecontext()\fP to obtain information about the source lines. .H 3 "dwarf_linebeginstatement()" .DS \f(CWint dwarf_linebeginstatement( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_linebeginstatement()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to \fInon-zero\fP (if \f(CWline\fP represents a line number entry that is marked as beginning a statement). or \fIzero\fP ((if \f(CWline\fP represents a line number entry that is not marked as beginning a statement). It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineendsequence()" .DS \f(CWint dwarf_lineendsequence( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineendsequence()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP \fInon-zero\fP (in which case \f(CWline\fP represents a line number entry that is marked as ending a text sequence) or \fIzero\fP (in which case \f(CWline\fP represents a line number entry that is not marked as ending a text sequence). A line number entry that is marked as ending a text sequence is an entry with an address one beyond the highest address used by the current sequence of line table entries (that is, the table entry is a DW_LNE_end_sequence entry (see the DWARF specification)). .P The function \f(CWdwarf_lineendsequence()\fP returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineno()" .DS \f(CWint dwarf_lineno( Dwarf_Line line, Dwarf_Unsigned * returned_lineno, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_lineno()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lineno\fP to the source statement line number corresponding to the descriptor \f(CWline\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_line_srcfileno()" .DS \f(CWint dwarf_line_srcfileno( Dwarf_Line line, Dwarf_Unsigned * returned_fileno, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_fileno\fP to the source statement line number corresponding to the descriptor \f(CWfile number\fP. When the number returned through \f(CW*returned_fileno\fP is zero it means the file name is unknown (see the DWARF2/3 line table specification). When the number returned through \f(CW*returned_fileno\fP is non-zero it is a file number: subtract 1 from this file number to get an index into the array of strings returned by \f(CWdwarf_srcfiles()\fP (verify the resulting index is in range for the array of strings before indexing into the array of strings). The file number may exceed the size of the array of strings returned by \f(CWdwarf_srcfiles()\fP because \f(CWdwarf_srcfiles()\fP does not return files names defined with the \f(CWDW_DLE_define_file\fP operator. The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineaddr()" .DS \f(CWint dwarf_lineaddr( Dwarf_Line line, Dwarf_Addr *return_lineaddr, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineaddr()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lineaddr\fP to the address associated with the descriptor \f(CWline\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P .H 3 "dwarf_lineoff()" .DS \f(CWint dwarf_lineoff( Dwarf_Line line, Dwarf_Signed * return_lineoff, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineoff()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_lineoff\fP to the column number at which the statement represented by \f(CWline\fP begins. .P It sets \f(CWreturn_lineoff\fP to zero if the column number of the statement is not represented (meaning the producer library call was given zero as the column number). Zero is the correct value meaning "left edge" as defined in the DWARF2/3/4 specication (section 6.2.2). .P Before December 2011 zero was not returned through the \f(CWreturn_lineoff\fP pointer, -1 was returned through the pointer. The reason for this oddity is unclear, lost in history. But there is no good reason for -1. .P The type of \f(CWreturn_lineoff\fP is a pointer-to-signed, but there is no good reason for the value to be signed, the DWARF specification does not deal with negative column numbers. However, changing the declaration would cause compilation errors for little benefit, so the pointer-to-signed is left unchanged. .P On error it returns \f(CWDW_DLV_ERROR\fP. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_lineoff_b()" .DS \f(CWint dwarf_lineoff_b( Dwarf_Line line, Dwarf_Unsigned * return_lineoff, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineoff_b()\fP returns exactly the same as \f(CWdwarf_lineoff()\fP except the line offset returned through \f(CWreturn_lineoff()\fP is an unsigned value. The signed return offset never made much sense but was harmless since line lengths are limited by most language standards. .H 3 "dwarf_linesrc()" .DS \f(CWint dwarf_linesrc( Dwarf_Line line, char ** return_linesrc, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_linesrc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to a pointer to a null-terminated string of characters that represents the name of the source-file where \f(CWline\fP occurs. It returns \f(CWDW_DLV_ERROR\fP on error. .P If the applicable file name in the line table Statement Program Prolog does not start with a '/' character the string in \f(CWDW_AT_comp_dir\fP (if applicable and present) or the applicable directory name from the line Statement Program Prolog is prepended to the file name in the line table Statement Program Prolog to make a full path. .P The storage pointed to by a successful return of \f(CWdwarf_linesrc()\fP should be freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_lineblock()" .DS \f(CWint dwarf_lineblock( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lineblock()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to non-zero (i.e. true)(if the line is marked as beginning a basic block) or zero (i.e. false) (if the line is marked as not beginning a basic block). It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_is_addr_set()" .DS \f(CWint dwarf_line_is_addr_set( Dwarf_Line line, Dwarf_Bool *return_bool, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_line_is_addr_set()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to non-zero (i.e. true)(if the line is marked as being a DW_LNE_set_address operation) or zero (i.e. false) (if the line is marked as not being a DW_LNE_set_address operation). It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. This is intended to allow consumers to do a more useful job printing and analyzing DWARF data, it is not strictly necessary. .H 3 "dwarf_prologue_end_etc()" .DS \f(CWint dwarf_prologue_end_etc(Dwarf_Line line, Dwarf_Bool * prologue_end, Dwarf_Bool * epilogue_begin, Dwarf_Unsigned * isa, Dwarf_Unsigned * discriminator, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_prologue_end_etc()\fP returns \f(CWDW_DLV_OK\fP and sets the returned fields to values currently set. While it is pretty safe to assume that the \f(CWisa\fP and \f(CWdiscriminator\fP values returned are very small integers, there is no restriction in the standard. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. This function is new in December 2011. .H 2 "Accelerated Access By Name operations" These operations operate on the .debug_pubnames section as well as all the other sections with this specific format and purpose: .debug_pubtypes, .debug_typenames, .debug_varnames, .debug_funcnames, and .debug_weaknames. The first in the list is generic DWARF 2,3,4. The second in the list is generic DWARF 3,4. The rest are SGI specific and rarely used. .P The interface types are Dwarf_Global Dwarf_Type,Dwarf_Weak,Dwarf_Func, and Dwarf_Var. Only Dwarf_Global is a real type. The others are opaque pointers with no actual definition or instantiation and can be converted to Dwarf_Global with a simple cast. .P In hindsight it would have been simpler to write a single set of interfaces for Accelerated Access By Name. .H 3 "Fine Tuning Accelerated Access" By default the various dwarf_get*() functions here return an array of pointers to opaque records with a .debug_info DIE offset and a string (the fields are accessible by function calls). While the actual .debug_pubnames (etc) section contains CU-local DIE offsets for the named things the accelerated access functions below return a .debug_info (or .debug_types) global section offset. .P .H 4 "dwarf_return_empty_pubnames" New March 2019. Mostly special for dwarfdump. If called with a flag value of one (1) it tells libdwarf, for any pubnames(etc) section list returned to add to the list an entry with a global-DIE-offset of zero (0) for any section Compilation Unit entry with no pubnames(etc) name( ie, an empty list for the Compilation Unit). .P If called with a value of zero(0) (zero is the default set by any \f(CWdwarf_init*()\fP call) it causes such empty lists to be omitted from the array of pointers returned, which is the standard behavior of libdwarf since libdwarf was first written. .P Since zero is never a valid DIE offset in .debug_info (or .debug_types) consumers requesting such can detect the special Dwarf_Global entries. .P For example, calling \f(CW dwarf_global_name_offsets()\fP on one of the special global records sets \f(CW*die_offset\fP to 0, \f(CW*return_name\fP to a pointer to an empty string, and \f(CW*cu_offset\fP to the offset of the compilation unit die in the .debug_info (or .debug_types if applicable) section. .DS \f(CWint dwarf_return_empty_pubnames(Dwarf_Debug dbg, int flag , Dwarf_Error* error)\fP .DE Callers should pass in one (1) or zero(0), no other value. On success it returns DW_DLV_OK. On failure it returns DW_DLV_ERROR; .P The assumption is that programs calling this with value one (1) will be calling dwarf_get_globals_header() to retrieve the relevant pubnames(etc) section Compilation Unit header. .H 4 "dwarf_get_globals_header" New February 2019. For more complete dwarfdump printing. For each CU represented in .debug_pubnames, etc, there is a .debug_pubnames header. For any given Dwarf_Global this returns the content of the applicable header. .P This allows dwarfdump, or any DWARF dumper, to print pubnames(etc) specific CU header data. .DS \f(CWint dwarf_get_globals_header(Dwarf_Global global, Dwarf_Off * offset_pub_header, Dwarf_Unsigned * length_size, Dwarf_Unsigned * length_pub, Dwarf_Unsigned * version, Dwarf_Unsigned * header_info_offset, Dwarf_Unsigned * info_length, Dwarf_Error* error)\fP .DE On success it returns DW_DLV_OK and it returns the header data (and calculated values) though the pointers. Casting Dwarf_Type (etc) to Dwarf_Global for a call to this function allows this to be used for any of these accelerated-access types. .H 3 "Accelerated Access Pubnames" .H 4 "dwarf_get_globals()" This is .debug_pubnames and is standard DWARF2, DWARF3, and DWARF4. .DS \f(CWint dwarf_get_globals( Dwarf_Debug dbg, Dwarf_Global **globals, Dwarf_Signed * return_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_globals()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_count\fP to the count of pubnames represented in the section containing pubnames i.e. .debug_pubnames. It also stores at \f(CW*globals\fP, a pointer to a list of \f(CWDwarf_Global\fP descriptors, one for each of the pubnames in the .debug_pubnames section. The returned results are for the entire section. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubnames section does not exist. .P On a successful return from \f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP descriptors should be freed using \f(CWdwarf_globals_dealloc()\fP. \f(CWdwarf_globals_dealloc()\fP is new as of July 15, 2005 and is the preferred approach to freeing this memory.. .P Global names refer exclusively to names and offsets in the .debug_info section. See section 6.1.1 "Lookup by Name" in the dwarf standard. .in +2 .FG "Exampled dwarf_get_globals()" .DS \f(CW void examplef(Dwarf_Debug dbg) { Dwarf_Signed count = 0; Dwarf_Global *globs = 0; Dwarf_Signed i = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_get_globals(dbg, &globs,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use globs[i] */ } dwarf_globals_dealloc(dbg, globs, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_GLOBAL_CONTEXT\fP, (or \f(CWDW_DLA_GLOBAL\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .DS \f(CWDwarf_Signed cnt; Dwarf_Global *globs; int res; res = dwarf_get_globals(dbg, &globs,&cnt, &error); if (res == DW_DLV_OK) { /* OBSOLETE: DO NOT USE to deallocate*/ for (i = 0; i < cnt; ++i) { /* use globs[i] */ dwarf_dealloc(dbg, globs[i], DW_DLA_GLOBAL_CONTEXT); } dwarf_dealloc(dbg, globs, DW_DLA_LIST); }\fP .DE .in -2 .H 4 "dwarf_globname()" .DS \f(CWint dwarf_globname( Dwarf_Global global, char ** return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_globname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the pubname represented by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP. It returns \f(CWDW_DLV_ERROR\fP on error. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_global_die_offset()" .DS \f(CWint dwarf_global_die_offset( Dwarf_Global global, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_global_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the pubname that is described by the \f(CWDwarf_Global\fP descriptor, \f(CWglob\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_global_cu_offset()" .DS \f(CWint dwarf_global_cu_offset( Dwarf_Global global, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_global_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the pubname described by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()" .DS \f(CWint dwarf_get_cu_die_offset_given_cu_header_offset_b( Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, Dwarf_Off * out_cu_die_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*out_cu_die_offset\fP to the offset of the compilation-unit DIE given the offset \f(CWin_cu_header_offset\fP of a compilation-unit header. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .P If \f(CWis_info\fP is non-zero the \f(CWin_cu_header_offset\fP must refer to a .debug_info section offset. If \f(CWis_info\fP zero the \f(CWin_cu_header_offset\fP must refer to a .debug_types section offset. Chaos may result if the \f(CWis_info\fP flag is incorrect. This effectively turns a compilation-unit-header offset into a compilation-unit DIE offset (by adding the size of the applicable CU header). This function is also sometimes useful with the \f(CWdwarf_weak_cu_offset()\fP, \f(CWdwarf_func_cu_offset()\fP, \f(CWdwarf_type_cu_offset()\fP, and \f(CWint dwarf_var_cu_offset()\fP functions, though for those functions the data is only in .debug_info by definition. .H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()" .DS \f(CWint dwarf_get_cu_die_offset_given_cu_header_offset( Dwarf_Debug dbg, Dwarf_Off in_cu_header_offset, Dwarf_Off * out_cu_die_offset, Dwarf_Error *error)\fP .DE This function is superseded by \f(CWdwarf_get_cu_die_offset_given_cu_header_offset_b()\fP, a function which is still supported thought it refers only to the .debug_info section. .P \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP added Rev 1.45, June, 2001. .P This function was declared as 'optional' in libdwarf.h on IRIX systems so the _MIPS_SYMBOL_PRESENT predicate could be used at run time to determine if the version of libdwarf linked into an application has this function. .H 4 "dwarf_global_name_offsets()" .DS \f(CWint dwarf_global_name_offsets( Dwarf_Global global, char **return_name, Dwarf_Off *die_offset, Dwarf_Off *cu_die_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_global_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that gives the name of the pubname described by the \f(CWDwarf_Global\fP descriptor \f(CWglobal\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the global offset of the DIE representing the pubname, and the offset of the DIE representing the compilation-unit containing the pubname, respectively. On a successful return from \f(CWdwarf_global_name_offsets()\fP the storage pointed to by \f(CWreturn_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .P If a portion of .debug_pubnames ( or .debug_types etc) represents a compilation unit with no names there is a .debug_pubnames header there with no content. In that case a single Dwarf_Global record is created with the value of *die_offset zero and the name-pointer returned points to the empty string. A zero is never a valid DIE offset, so zero always means this is an uninteresting (Dwarf_Global). .H 3 "Accelerated Access Pubtypes" Section ".debug_pubtypes" is in DWARF3 and DWARF4. .P These functions operate on the .debug_pubtypes section of the debugging information. The .debug_pubtypes section contains the names of file-scope user-defined types, the offsets of the \f(CWDIE\fPs that represent the definitions of those types, and the offsets of the compilation-units that contain the definitions of those types. .H 4 "dwarf_get_pubtypes()" This is standard DWARF3 and DWARF4. .DS \f(CWint dwarf_get_pubtypes( Dwarf_Debug dbg, Dwarf_Type **types, Dwarf_Signed *typecount, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_pubtypes()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to the count of user-defined type names represented in the section containing user-defined type names, i.e. .debug_pubtypes. It also stores at \f(CW*types\fP, a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the user-defined type names in the .debug_pubtypes section. The returned results are for the entire section. It returns \f(CWDW_DLV_NOCOUNT\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubtypes section does not exist. .P On a successful return from \f(CWdwarf_get_pubtypes()\fP, the \f(CWDwarf_Type\fP descriptors should be freed using \f(CWdwarf_types_dealloc()\fP. \f(CWdwarf_types_dealloc()\fP is used for both \f(CWdwarf_get_pubtypes()\fP and \f(CWdwarf_get_types()\fP as the data types are the same. .P Global type names refer exclusively to names and offsets in the .debug_info section. See section 6.1.1 "Lookup by Name" in the dwarf standard. .in +2 .FG "Exampled dwarf_get_pubtypes()" .DS \f(CW Avoid exampleg(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Type *types = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_pubtypes(dbg, &types,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use types[i] */ } dwarf_types_dealloc(dbg, types, count); } } \fP .DE .in -2 .H 4 "dwarf_pubtypename()" .DS \f(CWint dwarf_pubtypename( Dwarf_Type type, char **return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtypename()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the user-defined type represented by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_pubtype_type_die_offset()" .DS \f(CWint dwarf_pubtype_type_die_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtype_type_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the user-defined type that is described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_pubtype_cu_offset()" .DS \f(CWint dwarf_pubtype_cu_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtype_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the user-defined type described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_pubtype_name_offsets()" .DS \f(CWint dwarf_pubtype_name_offsets( Dwarf_Type type, char ** returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_pubtype_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that gives the name of the user-defined type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the user-defined type, and the DIE representing the compilation-unit containing the user-defined type, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_pubtype_name_offsets()\fP the storage pointed to by \f(CWreturned_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access Weaknames" This section is SGI specific and is not part of standard DWARF. .P These functions operate on the .debug_varnames section of the debugging information. The .debug_varnames section contains the names of file-scope static variables, the offsets of the \f(CWDIE\fPs that represent the definitions of those variables, and the offsets of the compilation-units that contain the definitions of those variables. .P These operations operate on the .debug_weaknames section of the debugging information. .H 4 "dwarf_get_weaks()" .DS \f(CWint dwarf_get_weaks( Dwarf_Debug dbg, Dwarf_Weak **weaks, Dwarf_Signed *weak_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_weaks()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*weak_count\fP to the count of weak names represented in the section containing weak names i.e. .debug_weaknames. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the section does not exist. It also stores in \f(CW*weaks\fP, a pointer to a list of \f(CWDwarf_Weak\fP descriptors, one for each of the weak names in the .debug_weaknames section. The returned results are for the entire section. .P On a successful return from this function, the \f(CWDwarf_Weak\fP descriptors should be freed using \f(CWdwarf_weaks_dealloc()\fP when the data is no longer of interest. \f(CWdwarf_weaks_dealloc()\fPis new as of July 15, 2005. .in +2 .FG "Exampleh dwarf_get_weaks()" .DS \f(CW void exampleh(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Weak *weaks = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_weaks(dbg, &weaks, &count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use weaks[i] */ } dwarf_weaks_dealloc(dbg, weaks, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_weaks()\fP the \f(CWDwarf_Weak\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_WEAK_CONTEXT\fP, (or \f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Examplei dwarf_get_weaks() obsolete" .DS \f(CW void examplei(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Weak *weaks = 0; Dwarf_Signed i = 0; int res = 0; /* Obsolete, see exampleh instead */ res = dwarf_get_weaks(dbg, &weaks, &count, &error); if (res == DW_DLV_OK) { /* OBSOLETE: do not use dealloc for this. See above */ for (i = 0; i < count; ++i) { /* use weaks[i] */ dwarf_dealloc(dbg, weaks[i], DW_DLA_WEAK); } dwarf_dealloc(dbg, weaks, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_weakname()" .DS \f(CWint dwarf_weakname( Dwarf_Weak weak, char ** return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weakname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the weak name represented by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .DS \f(CWint dwarf_weak_die_offset( Dwarf_Weak weak, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weak_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the weak name that is described by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_weak_cu_offset()" .DS \f(CWint dwarf_weak_cu_offset( Dwarf_Weak weak, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weak_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the weak name described by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_weak_name_offsets()" .DS \f(CWint dwarf_weak_name_offsets( Dwarf_Weak weak, char ** weak_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_weak_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*weak_name\fP to a pointer to a null-terminated string that gives the name of the weak name described by the \f(CWDwarf_Weak\fP descriptor \f(CWweak\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the weakname, and the DIE representing the compilation-unit containing the weakname, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_weak_name_offsets()\fP the storage pointed to by \f(CWweak_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access Funcnames" This section is SGI specific and is not part of standard DWARF. .P These function operate on the .debug_funcnames section of the debugging information. The .debug_funcnames section contains the names of static functions defined in the object, the offsets of the \f(CWDIE\fPs that represent the definitions of the corresponding functions, and the offsets of the start of the compilation-units that contain the definitions of those functions. .H 4 "dwarf_get_funcs()" .DS \f(CWint dwarf_get_funcs( Dwarf_Debug dbg, Dwarf_Func **funcs, Dwarf_Signed *func_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_funcs()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*func_count\fP to the count of static function names represented in the section containing static function names, i.e. .debug_funcnames. It also stores, at \f(CW*funcs\fP, a pointer to a list of \f(CWDwarf_Func\fP descriptors, one for each of the static functions in the .debug_funcnames section. The returned results are for the entire section. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_funcnames section does not exist. .P On a successful return from \f(CWdwarf_get_funcs()\fP, the \f(CWDwarf_Func\fP descriptors should be freed using \f(CWdwarf_funcs_dealloc()\fP. \f(CWdwarf_funcs_dealloc()\fP is new as of July 15, 2005. .in +2 .FG "Examplej dwarf_get_funcs()" .DS \f(CW void examplej(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Func *funcs = 0; Dwarf_Signed i = 0; int fres = 0; fres = dwarf_get_funcs(dbg, &funcs, &count, &error); if (fres == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use funcs[i] */ } dwarf_funcs_dealloc(dbg, funcs, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_funcs()\fP, the \f(CWDwarf_Func\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FUNC_CONTEXT\fP, (or \f(CWDW_DLA_FUNC\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Examplek dwarf_get_funcs() obsolete" .DS \f(CW void examplek(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Func *funcs = 0; Dwarf_Signed count = 0; Dwarf_Signed i = 0; int fres = 0; fres = dwarf_get_funcs(dbg, &funcs,&count, &error); if (fres == DW_DLV_OK) { /* OBSOLETE: see dwarf_funcs_dealloc() above */ for (i = 0; i < count; ++i) { /* use funcs[i] */ dwarf_dealloc(dbg, funcs[i], DW_DLA_FUNC); } dwarf_dealloc(dbg, funcs, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_funcname()" .DS \f(CWint dwarf_funcname( Dwarf_Func func, char ** return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_funcname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the static function represented by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_func_die_offset()" .DS \f(CWint dwarf_func_die_offset( Dwarf_Func func, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_func_die_offset()\fP, returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the static function that is described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_func_cu_offset()" .DS \f(CWint dwarf_func_cu_offset( Dwarf_Func func, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_func_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the static function described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_func_name_offsets()" .DS \f(CWint dwarf_func_name_offsets( Dwarf_Func func, char **func_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_func_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*func_name\fP to a pointer to a null-terminated string that gives the name of the static function described by the \f(CWDwarf_Func\fP descriptor \f(CWfunc\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the static function, and the DIE representing the compilation-unit containing the static function, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_func_name_offsets()\fP the storage pointed to by \f(CWfunc_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access Typenames" Section "debug_typenames" is SGI specific and is not part of standard DWARF. (However, an identical section is part of DWARF version 3 named ".debug_pubtypes", see \f(CWdwarf_get_pubtypes()\fP above.) .P These functions operate on the .debug_typenames section of the debugging information. The .debug_typenames section contains the names of file-scope user-defined types, the offsets of the \f(CWDIE\fPs that represent the definitions of those types, and the offsets of the compilation-units that contain the definitions of those types. .H 4 "dwarf_get_types()" .DS \f(CWint dwarf_get_types( Dwarf_Debug dbg, Dwarf_Type **types, Dwarf_Signed *typecount, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_types()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to the count of user-defined type names represented in the section containing user-defined type names, i.e. .debug_typenames. It also stores at \f(CW*types\fP, a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the user-defined type names in the .debug_typenames section. The returned results are for the entire section. It returns \f(CWDW_DLV_NOCOUNT\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_typenames section does not exist. .P On a successful return from \f(CWdwarf_get_types()\fP, the \f(CWDwarf_Type\fP descriptors should be freed using \f(CWdwarf_types_dealloc()\fP. \f(CWdwarf_types_dealloc()\fP is new as of July 15, 2005 and frees all memory allocated by \f(CWdwarf_get_types()\fP. .in +2 .FG "Examplel dwarf_get_types()" .DS \f(CW void examplel(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Type *types = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_types(dbg, &types,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use types[i] */ } dwarf_types_dealloc(dbg, types, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_types()\fP, the \f(CWDwarf_Type\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_TYPENAME_CONTEXT\fP, (or \f(CWDW_DLA_TYPENAME\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Examplel dwarf_get_types() obsolete" .DS \f(CW void examplem(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Type *types = 0; Dwarf_Signed i = 0; int res = 0; /* OBSOLETE: see dwarf_types_dealloc() above */ res = dwarf_get_types(dbg, &types,&count, &error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use types[i] */ dwarf_dealloc(dbg, types[i], DW_DLA_TYPENAME); } dwarf_dealloc(dbg, types, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_typename()" .DS \f(CWint dwarf_typename( Dwarf_Type type, char **return_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_typename()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to a pointer to a null-terminated string that names the user-defined type represented by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_type_die_offset()" .DS \f(CWint dwarf_type_die_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_type_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the user-defined type that is described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_type_cu_offset()" .DS \f(CWint dwarf_type_cu_offset( Dwarf_Type type, Dwarf_Off *return_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_type_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the user-defined type described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_type_name_offsets()" .DS \f(CWint dwarf_type_name_offsets( Dwarf_Type type, char ** returned_name, Dwarf_Off * die_offset, Dwarf_Off * cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_type_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that gives the name of the user-defined type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the user-defined type, and the DIE representing the compilation-unit containing the user-defined type, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_type_name_offsets()\fP the storage pointed to by \f(CWreturned_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 3 "Accelerated Access varnames" This section is SGI specific and is not part of standard DWARF. .P These functions operate on the .debug_varnames section of the debugging information. The .debug_varnames section contains the names of file-scope static variables, the offsets of the \f(CWDIE\fPs that represent the definitions of those variables, and the offsets of the compilation-units that contain the definitions of those variables. .H 4 "dwarf_get_vars()" .DS \f(CWint dwarf_get_vars( Dwarf_Debug dbg, Dwarf_Var **vars, Dwarf_Signed *var_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_vars()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*var_count\fP to the count of file-scope static variable names represented in the section containing file-scope static variable names, i.e. .debug_varnames. It also stores, at \f(CW*vars\fP, a pointer to a list of \f(CWDwarf_Var\fP descriptors, one for each of the file-scope static variable names in the .debug_varnames section. The returned results are for the entire section. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_varnames section does not exist. .P The following is new as of July 15, 2005. On a successful return from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be freed using \f(CWdwarf_vars_dealloc()\fP. .in +2 .FG "Examplen dwarf_get_vars()" .DS \f(CW void examplen(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Var *vars = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_vars(dbg, &vars,&count,&error); if (res == DW_DLV_OK) { for (i = 0; i < count; ++i) { /* use vars[i] */ } dwarf_vars_dealloc(dbg, vars, count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. On a successful return from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be individually freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_VAR_CONTEXT\fP, (or \f(CWDW_DLA_VAR\fP, an older name, supported for compatibility) followed by the deallocation of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest. .in +2 .FG "Exampleo dwarf_get_vars() obsolete" .DS \f(CW void exampleo(Dwarf_Debug dbg) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Var *vars = 0; Dwarf_Signed i = 0; int res = 0; res = dwarf_get_vars(dbg, &vars,&count,&error); if (res == DW_DLV_OK) { /* DO NOT USE: see dwarf_vars_dealloc() above */ for (i = 0; i < count; ++i) { /* use vars[i] */ dwarf_dealloc(dbg, vars[i], DW_DLA_VAR); } dwarf_dealloc(dbg, vars, DW_DLA_LIST); } } \fP .DE .in -2 .H 4 "dwarf_varname()" .DS \f(CWint dwarf_varname( Dwarf_Var var, char ** returned_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_varname()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that names the file-scope static variable represented by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from this function, the string should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 4 "dwarf_var_die_offset()" .DS \f(CWint dwarf_var_die_offset( Dwarf_Var var, Dwarf_Off *returned_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_var_die_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the DIE representing the file-scope static variable that is described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_var_cu_offset()" .DS \f(CWint dwarf_var_cu_offset( Dwarf_Var var, Dwarf_Off *returned_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_var_cu_offset()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to the offset in the section containing DIEs, i.e. .debug_info, of the compilation-unit header of the compilation-unit that contains the file-scope static variable described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 4 "dwarf_var_name_offsets()" .DS \f(CWint dwarf_var_name_offsets( Dwarf_Var var, char **returned_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_var_name_offsets()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to a pointer to a null-terminated string that gives the name of the file-scope static variable described by the \f(CWDwarf_Var\fP descriptor \f(CWvar\fP. It also returns in the locations pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets of the DIE representing the representing the compilation-unit containing the file-scope static variable, respectively. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. On a successful return from \f(CWdwarf_var_name_offsets()\fP the storage pointed to by \f(CWreturned_name\fP should be freed using \f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest. .H 2 "Names Fast Access (DWARF5) .debug_names" The section \f(CW.debug_names\fP section is new in DWARF5 so a new set of functions is defined to access this section. This section replaces \f(CW.debug_pubnames\fP and \f(CW.debug_pubtypes\fP as those older sections were not found to be useful in practice. .H 3 "dwarf_debugnames_header()" .DS \f(CWint dwarf_debugnames_header( Dwarf_Debug dbg, Dwarf_Dnames_Head * dn_out, Dwarf_Unsigned * dn_index_count_out, Dwarf_Error *error)\fP .DE .P The function \f(CWdwarf_debugnames_header()\fP allocates an opaque data structure used in all the other debugnames calls. .P Many of the function calls here let one extract the entire content of the section, which is useful if one wishes to dump the section or to use its data to create one's own internal data structures. .P To free space allocated when one has finished with these data structures, call .DS Debug_Dnames_Head dn /* Assume set somehow */; ... dwarf_dealloc(dbg,dn,DW_DLA_DNAMES_HEAD); .DE which will free up all data allocated for \f(CWdwarf_debugnames_header()\fP. .P FIXME describe arguments. .in +2 .DS \f(CW void exampledebugnames(Dwarf_Debug dbg) { FIXME need extended example of debugnames use. } \fP .DE .in -2 FIXME .H 3 " dwarf_debugnames_sizes()" .DS \f(CW int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned * section_offsets, Dwarf_Unsigned * version, Dwarf_Unsigned * offset_size, /* The counts are entry counts, not byte sizes. */ Dwarf_Unsigned * comp_unit_count, Dwarf_Unsigned * local_type_unit_count, Dwarf_Unsigned * foreign_type_unit_count, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * name_count, /* The following are counted in bytes */ Dwarf_Unsigned * indextable_overall_length, Dwarf_Unsigned * abbrev_table_size, Dwarf_Unsigned * entry_pool_size, Dwarf_Unsigned * augmentation_string_size, Dwarf_Error * error*/)\fP .DE .P Allows access to fields in a .debug_names DWARF5 header record. FIXME .H 3 " dwarf_debugnames_cu_entry()" .DS \f(CW int dwarf_debugnames_cu_entry( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error)\fP .DE Allows access to fields in cu entry from a .debug_names DWARF5 compilation unit entry. FIXME .H 3 " dwarf_debugnames_local_tu_entry()" .DS \f(CW int dwarf_debugnames_local_tu_entry( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_number, Dwarf_Unsigned * offset_count, Dwarf_Unsigned * offset, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_foreign_tu_entry()" .DS \f(CW int dwarf_debugnames_foreign_tu_entry( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned sig_number, Dwarf_Unsigned * sig_minimum, Dwarf_Unsigned * sig_count, Dwarf_Sig8 * signature, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_bucket()" .DS \f(CW int dwarf_debugnames_bucket( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned bucket_number, Dwarf_Unsigned * bucket_count, Dwarf_Unsigned * index_of_name_entry, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_name()" .DS \f(CW int dwarf_debugnames_bucket( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned name_entry, Dwarf_Unsigned * names_count, Dwarf_Sig8 * signature, Dwarf_Unsigned * offset_to_debug_str, Dwarf_Unsigned * offset_in_entrypool, Dwarf_Error * error) \fP .DE FIXME .H 3" dwarf_debugnames_abbrev_by_index()" .DS \f(CW int dwarf_debugnames_abbrev_by_index( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * number_of_abbrev, Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_abbrev_by_code()" .DS \f(CW int dwarf_debugnames_abbrev_by_code( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * index_of_attr_form_entries, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_form_by_index()" .DS \f(CW int dwarf_debugnames_form_by_index( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned abbrev_entry_index, Dwarf_Unsigned abbrev_form_index, Dwarf_Unsigned * name_attr_index, Dwarf_Unsigned * form, Dwarf_Unsigned * number_of_attr_form_entries, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_entrypool()" .DS \f(CW int dwarf_debugnames_entrypool( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned offset_in_entrypool, Dwarf_Unsigned * abbrev_code, Dwarf_Unsigned * tag, Dwarf_Unsigned * value_count, Dwarf_Unsigned * index_of_abbrev, Dwarf_Unsigned * offset_of_initial_value, Dwarf_Error * error) \fP .DE FIXME .H 3 " dwarf_debugnames_entrypool_values()" .DS \f(CW int dwarf_debugnames_entrypool_values( Dwarf_Dnames_Head dn, Dwarf_Unsigned index_number, Dwarf_Unsigned index_of_abbrev, Dwarf_Unsigned offset_in_entrypool_of_values, Dwarf_Unsigned * array_dw_idx_number, Dwarf_Unsigned * array_form, Dwarf_Unsigned * array_of_offsets, Dwarf_Sig8 * array_of_signatures, Dwarf_Error * error) \fP .DE FIXME .H 2 "Macro Information Operations (DWARF4, DWARF5)" This section refers to DWARF4 and later macro information from the .debug_macro section (for DWARF 4 some producers generated .debug_macro before its formal standardization in DWARF 5). While standard operations are supported there is as yet no support for implementation-defined extensions. Once someone has defined such things it will make sense to design an interface for extensions. .H 3 "Getting access" The opaque struct pointer Dwarf_Macro_Context is allocated by either \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP and once the context is no longer needed one frees up all its storage by \f(CWdwarf_dealloc_macro_context()\fP. .H 4 "dwarf_get_macro_context()" .DS \f(CWint dwarf_get_macro_context(Dwarf_Die die, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_unit_offset_out, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_data_length_out, Dwarf_Error * error);\fP .DE Given a Compilation Unit (CU) die, on success \f(CWdwarf_get_macro_context()\fP opens a \f(CWDwarf_Macro_Context\fP and returns a pointer to it and some data from the macro unit for that CU. The \f(CWDwarf_Macro_Context\fP is used to get at the details of the macros. .P The value \f(CWversion_out\fP is set to the DWARF version number of the macro data. Version 5 means DWARF5 version information. Version 4 means the DWARF5 format macro data is present as an extension of DWARF4. .P The value \f(CWmacro_unit_offset_out\fP is set to the offset in the .debug_macro section of the first byte of macro data for this CU. .P The value \f(CWmacro_ops_count_out\fP is set to the number of macro entries in the macro data data for this CU. The count includes the final zero entry (which is not really a macro, it is a terminator, a zero byte ending the macro unit). .P The value \f(CWmacro_ops_data_length_out\fP is set to the number of bytes of data in the macro unit, including the macro unit header. .P If \f(CWDW_DLV_NO_ENTRY\fP is returned the CU has no macro data attribute or there is no .debug_macro section present. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_context_by_offset()" .DS \f(CWint dwarf_get_macro_context_by_offset(Dwarf_Die die, Dwarf_Unsigned offset, Dwarf_Unsigned * version_out, Dwarf_Macro_Context * macro_context, Dwarf_Unsigned * macro_ops_count_out, Dwarf_Unsigned * macro_ops_total_byte_len, Dwarf_Error * error);\fP .DE Given a Compilation Unit (CU) die and the offset of an imported macro unit \f(CWdwarf_get_macro_context_by_offset()\fP opens a \f(CWDwarf_Macro_Context\fP and returns a pointer to it and some data from the macro unit for that CU on success. .P On success the function produces the same output values as \f(CWdwarf_get_macro_context()\fP except there is no offset returned ( the caller provides it). .P If \f(CWDW_DLV_NO_ENTRY\fP is returned there is no .debug_macro section present. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_dealloc_macro_context()" .DS \f(CWvoid dwarf_dealloc_macro_context(Dwarf_Macro_Context macro_context);\fP .DE The function \f(CWdwarf_dealloc_macro_context()\fP cleans up memory allocated by a successful call to \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP. .in +2 .FG "Examplep5 dwarf_dealloc_macro_context()" .DS \f(CW /* This builds an list or some other data structure (not defined) to give an import somewhere to list the import offset and then later to enquire if the list has unexamined offsets. A candidate set of hypothetical functions that callers would write: has_unchecked_import_in_list() get_next_import_from_list() mark_this_offset_as_examined(macro_unit_offset); add_offset_to_list(offset); */ void examplep5(Dwarf_Debug dbg, Dwarf_Die cu_die) { int lres = 0; Dwarf_Unsigned version = 0; Dwarf_Macro_Context macro_context = 0; Dwarf_Unsigned macro_unit_offset = 0; Dwarf_Unsigned number_of_ops = 0; Dwarf_Unsigned ops_total_byte_len = 0; Dwarf_Bool is_primary = TRUE; unsigned k = 0; Dwarf_Error err = 0; for(;;) { if (is_primary) { lres = dwarf_get_macro_context(cu_die, &version,¯o_context, ¯o_unit_offset, &number_of_ops, &ops_total_byte_len, &err); is_primary = FALSE; } else { if (has_unchecked_import_in_list()) { macro_unit_offset = get_next_import_from_list(); } else { /* We are done */ break; } lres = dwarf_get_macro_context_by_offset(cu_die, macro_unit_offset, &version, ¯o_context, &number_of_ops, &ops_total_byte_len, &err); mark_this_offset_as_examined(macro_unit_offset); } if (lres == DW_DLV_ERROR) { /* Something is wrong. */ return; } if (lres == DW_DLV_NO_ENTRY) { /* We are done. */ break; } /* lres == DW_DLV_OK) */ for (k = 0; k < number_of_ops; ++k) { Dwarf_Unsigned section_offset = 0; Dwarf_Half macro_operator = 0; Dwarf_Half forms_count = 0; const Dwarf_Small *formcode_array = 0; Dwarf_Unsigned line_number = 0; Dwarf_Unsigned index = 0; Dwarf_Unsigned offset =0; const char * macro_string =0; int lres = 0; lres = dwarf_get_macro_op(macro_context, k, §ion_offset,¯o_operator, &forms_count, &formcode_array,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_op()", lres,err); dwarf_dealloc_macro_context(macro_context); return; } switch(macro_operator) { case 0: /* Nothing to do. */ break; case DW_MACRO_end_file: /* Do something */ break; case DW_MACRO_define: case DW_MACRO_undef: case DW_MACRO_define_strp: case DW_MACRO_undef_strp: case DW_MACRO_define_strx: case DW_MACRO_undef_strx: case DW_MACRO_define_sup: case DW_MACRO_undef_sup: { lres = dwarf_get_macro_defundef(macro_context, k, &line_number, &index, &offset, &forms_count, ¯o_string, &err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from sup dwarf_get_macro_defundef()", lres,err); dwarf_dealloc_macro_context(macro_context); return; } /* do something */ } break; case DW_MACRO_start_file: { lres = dwarf_get_macro_startend_file(macro_context, k,&line_number, &index, ¯o_string,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_startend_file()(sup)", lres,err); dwarf_dealloc_macro_context(macro_context); return; } /* do something */ } break; case DW_MACRO_import: { lres = dwarf_get_macro_import(macro_context, k,&offset,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_import()(sup)", lres,err); dwarf_dealloc_macro_context(macro_context); return; } add_offset_to_list(offset); } break; case DW_MACRO_import_sup: { lres = dwarf_get_macro_import(macro_context, k,&offset,&err); if (lres != DW_DLV_OK) { print_error(dbg, "ERROR from dwarf_get_macro_import()(sup)", lres,err); dwarf_dealloc_macro_context(macro_context); return; } /* do something */ } break; } } dwarf_dealloc_macro_context(macro_context); macro_context = 0; } } \fP .DE .in -2 .H 3 "Getting Macro Unit Header Data" .H 4 "dwarf_macro_context_head()" .DS \f(CWint dwarf_macro_context_head(Dwarf_Macro_Context macro_context, Dwarf_Half * version, Dwarf_Unsigned * mac_offset, Dwarf_Unsigned * mac_len, Dwarf_Unsigned * mac_header_len, unsigned * flags, Dwarf_Bool * has_line_offset, Dwarf_Unsigned * line_offset, Dwarf_Bool * has_offset_size_64, Dwarf_Bool * has_operands_table, Dwarf_Half * opcode_count, Dwarf_Error * error); \fP .DE Given a \f(CWDwarf_Macro_Context\fP pointer this function returns the basic fields of a macro unit header (Macro Information Header) on success. .P The value \f(CWversion\fP is set to the DWARF version number of the macro unit header. Version 5 means DWARF5 version information. Version 4 means the DWARF5 format macro data is present as an extension of DWARF4. .P The value \f(CWmac_offset\fP is set to the offset in the .debug_macro section of the first byte of macro data for this CU. .P The value \f(CWmac_len\fP is set to the number of bytes of data in the macro unit, including the macro unit header. .P The value \f(CWmac_header_len\fP is set to the number of bytes in the macro unit header (not a field that is generally useful). .P The value \f(CWflags\fP is set to the value of the \f(CWflags\fP field of the macro unit header. .P The value \f(CWhas_line_offset\fP is set to non-zero if the \f(CWdebug_line_offset_flag\fP bit is set in the \f(CWflags\fP field of the macro unit header. If \f(CWhas_line_offset\fP is set then \f(CWline_offset\fP is set to the value of the \f(CWdebug_line_offset\fP field in the macro unit header. If \f(CWhas_line_offset\fP is not set there is no \f(CWdebug_line_offset\fP field present in the macro unit header. .P The value \f(CWhas_offset_size_64\fP is set non-zero if the \f(CWoffset_size_flag\fP bit is set in the \f(CWflags\fP field of the macro unit header and in this case offset fields in this macro unit are 64 bits. If \f(CWhas_offset_size_64\fP is not set then offset fields in this macro unit are 32 bits. .P The value \f(CWhas_operands_table\fP is set to non-zero if the \f(CWopcod_operands_table_flag\fP bit is set in the \f(CWflags\fP field of the macro unit header. .P If \f(CWhas_operands_table\fP is set non-zero then The value \f(CWopcode_count\fP is set to the number of opcodes in the macro unit header \f(CWopcode_operands_table\fP. See \f(CWdwarf_get_macro_op()\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_macro_operands_table()" .DS \f(CWint dwarf_macro_operands_table(Dwarf_Macro_Context macro_context, Dwarf_Half index, /* 0 to opcode_count -1 */ Dwarf_Half * opcode_number, Dwarf_Half * operand_count, const Dwarf_Small ** operand_array, Dwarf_Error * error); \fP .DE \f(CWdwarf_macro_operands_table()\fP is used to index through the operands table in a macro unit header if the operands table exists in the macro unit header. The operands table provides the mechanism for implementations to add extensions to the macro operations while allowing clients to skip macro operations the client code does not recognize. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWindex\fP field passed in identifies which macro operand to look at. Valid index values are zero through the \f(CWopcode_count\fP-1 (returned by \f(CWdwarf_macro_context_head()\fP). .P The \f(CWopcode_number\fP value returned through the pointer is the the macro operation code. The operation code could be one of the standard codes or if there are user extensions there would be an extension code in the \f(CWDW_MACRO_lo_user\fP to \f(CWDW_MACRO_hi_user\fP range. .P The \f(CWoperand_count\fP returned is the number of form codes in the form codes array of unsigned bytes \f(CWoperand_array\fP. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 3 "Getting Individual Macro Operations Data" .H 4 "dwarf_get_macro_op()" .DS \f(CWint dwarf_get_macro_op(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * op_start_section_offset, Dwarf_Half * macro_operator, Dwarf_Half * forms_count, const Dwarf_Small ** formcode_array, Dwarf_Error * error);\fP .DE Use \f(CWdwarf_get_macro_op()\fP to access the macro operations of this macro unit. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP) .P On success the function returns values through the pointers. .P The \f(CWop_start_section_offset\fP returned is useful for debugging but otherwise is not normally useful. It is the byte offset of the beginning of this macro operator's data. .P The \f(CWmacro_operator\fP returned is one of the defined macro operations such as \f(CWDW_MACRO_define\fP. This is the field you will use to choose what call to use to get the data for a macro operator. For example, for \f(CWDW_MACRO_undef\fP one would call \f(CWdwarf_get_macro_defundef()\fP (see below) to get the details about the undefine. .P The \f(CWforms_count\fP returned is useful for debugging but otherwise is not normally useful. It is the number of bytes of form numbers in the \f(CWformcode_array\fP of this macro operator's applicable forms. .P \f(CWDW_DLV_NO_ENTRY\fP is not returned. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_defundef()" .DS \f(CWint dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * index, Dwarf_Unsigned * offset, Dwarf_Half * forms_count, const char ** macro_string, Dwarf_Error * error);\fP .DE Call \f(CWdwarf_get_macro_defundef\fP for any of the macro define/undefine operators. Which fields are set through the pointers depends on the particular operator. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP). .P The \f(CWline_number\fP field is set with the source line number of the macro. .P The \f(CWindex\fP field only set meaningfully if the macro operator is \f(CWDW_MACRO_define_strx\fP or \f(CWDW_MACRO_undef_strx\fP. If set it is an index into an array of offsets in the .debug_str_offsets section. .P The \f(CWoffset\fP field only set meaningfully if the macro operator is \f(CWDW_MACRO_define_strx\fP, \f(CWDW_MACRO_undef_strx\fP \f(CWDW_MACRO_define_strp\fP, or \f(CWDW_MACRO_undef_strp\fP If set it is an offset of a string in the .debug_str section. .P The \f(CWforms_count\fP is set to the number of forms that apply to the macro operator. .P The \f(CWmacro_string\fP pointer is used to return a pointer to the macro string. If the actual string cannot be found (as when section with the string is in a different object, see \f(CWset_tied_dbg()\fP) the string returned may be "<:No string available>" or "<.debug_str_offsets not available>" (without the quotes). .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the macro operation is not one of the define/undef operations. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_startend_file()" .DS \f(CWint dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * line_number, Dwarf_Unsigned * name_index_to_line_tab, const char ** src_file_name, Dwarf_Error * error);\fP .DE Call \f(CWdwarf_get_macro_startend_file\fP for operators \f(CWDW_MACRO_start_file\fP or \f(CWDW_MACRO_end_file\fP. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. .P The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP) .P For \f(CWDW_MACRO_end_file\fP none of the following fields are set on successful return, they are only set for. \f(CWDW_MACRO_start_file\fP .P The \f(CWline_number\fP field is set with the source line number of the macro. .P .P The \f(CWname_index_to_line_tab\fP field is set with the index into the file name table of the line table section. For DWARF2, DWARF3, DWARF4 line tables the index value assumes DWARF2 line table header rules (identical to DWARF3, DWARF4 line table header rules). For DWARF5 the index value assumes DWARF5 line table header rules. The \f(CWsrc_file_name\fP is set with the source file name. If the index seems wrong or the line table is unavailable the name returned is ""); .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the macro operation is not one of the start/end operations. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 4 "dwarf_get_macro_import()" .DS \f(CWint dwarf_get_macro_import(Dwarf_Macro_Context macro_context, Dwarf_Unsigned op_number, Dwarf_Unsigned * target_offset, Dwarf_Error * error);\fP .DE Call \f(CWdwarf_get_macro_import\fP for operators \f(CWDW_MACRO_import\fP or \f(CWDW_MACRO_import_sup\fP. .P The \f(CWmacro_context\fP field passed in identifies the macro unit involved. The \f(CWop_number\fP field passed in identifies which macro operand to look at. Valid index values are zero through \f(CWmacro_ops_count_out\fP-1 (field returned by \f(CWdwarf_get_macro_context()\fP or \f(CWdwarf_get_macro_context_by_offset()\fP) .P On success the \f(CWtarget_offset\fP field is set to the offset in the referenced section. For DW_MACRO_import the referenced section is the same section as the macro operation referenced here. For DW_MACRO_import_sup the referenced section is in a supplementary object. .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the macro operation is not one of the import operations. .P On error \f(CWDW_DLV_ERROR\fP is returned and the error details are returned through the pointer \f(CWerror\fP. .H 2 "Macro Information Operations (DWARF2, DWARF3, DWARF4)" This section refers to DWARF2,DWARF3,and DWARF4 macro information from the .debug_macinfo section. These do not apply to DWARF5 macro data. .H 3 "General Macro Operations" .H 4 "dwarf_find_macro_value_start()" .DS \f(CWchar *dwarf_find_macro_value_start(char * macro_string);\fP .DE Given a macro string in the standard form defined in the DWARF document ("name value" or "name(args)value") this returns a pointer to the first byte of the macro value. It does not alter the string pointed to by macro_string or copy the string: it returns a pointer into the string whose address was passed in. .H 3 "Debugger Interface Macro Operations" Macro information is accessed from the .debug_info section via the DW_AT_macro_info attribute (whose value is an offset into .debug_macinfo). .P No Functions yet defined. .H 3 "Low Level Macro Information Operations" .H 4 "dwarf_get_macro_details()" .DS \f(CWint dwarf_get_macro_details(Dwarf_Debug /*dbg*/, Dwarf_Off macro_offset, Dwarf_Unsigned maximum_count, Dwarf_Signed * entry_count, Dwarf_Macro_Details ** details, Dwarf_Error * err);\fP .DE \f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWentry_count\fP to the number of \f(CWdetails\fP records returned through the \f(CWdetails\fP pointer. The data returned through \f(CWdetails\fP should be freed by a call to \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_STRING\fP. If \f(CWDW_DLV_OK\fP is returned, the \f(CWentry_count\fP will be at least 1, since a compilation unit with macro information but no macros will have at least one macro data byte of 0. .P \f(CWdwarf_get_macro_details()\fP begins at the \f(CWmacro_offset\fP offset you supply and ends at the end of a compilation unit or at \f(CWmaximum_count\fP detail records (whichever comes first). If \f(CWmaximum_count\fP is 0, it is treated as if it were the maximum possible unsigned integer. .P \f(CWdwarf_get_macro_details()\fP attempts to set \f(CWdmd_fileindex\fP to the correct file in every \f(CWdetails\fP record. If it is unable to do so (or whenever the current file index is unknown, it sets \f(CWdmd_fileindex\fP to -1. .P \f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no more macro information at that \f(CWmacro_offset\fP. If \f(CWmacro_offset\fP is passed in as 0, a \f(CWDW_DLV_NO_ENTRY\fP return means there is no macro information. .P .in +2 .FG "Examplep2 dwarf_get_macro_details()" .DS \f(CW void examplep2(Dwarf_Debug dbg, Dwarf_Off cur_off) { Dwarf_Error error = 0; Dwarf_Signed count = 0; Dwarf_Macro_Details *maclist = 0; Dwarf_Signed i = 0; Dwarf_Unsigned max = 500000; /* sanity limit */ int errv = 0; /* Given an offset from a compilation unit, start at that offset (from DW_AT_macroinfo) and get its macro details. */ errv = dwarf_get_macro_details(dbg, cur_off,max, &count,&maclist,&error); if (errv == DW_DLV_OK) { for (i = 0; i < count; ++i) { Dwarf_Macro_Details * mdp = maclist +i; /* example of use */ Dwarf_Signed lineno = mdp->dmd_lineno; } dwarf_dealloc(dbg, maclist, DW_DLA_STRING); } /* Loop through all the compilation units macro info from zero. This is not guaranteed to work because DWARF does not guarantee every byte in the section is meaningful: there can be garbage between the macro info for CUs. But this loop will sometimes work. */ cur_off = 0; while((errv = dwarf_get_macro_details(dbg, cur_off,max, &count,&maclist,&error))== DW_DLV_OK) { for (i = 0; i < count; ++i) { Dwarf_Macro_Details * mdp = maclist +i; /* example of use */ Dwarf_Signed lineno = mdp->dmd_lineno; } cur_off = maclist[count-1].dmd_offset + 1; dwarf_dealloc(dbg, maclist, DW_DLA_STRING); } } \fP .DE .in -2 .H 2 "Low Level Frame Operations" These functions provide information about stack frames to be used to perform stack traces. The information is an abstraction of a table with a row per instruction and a column per register and a column for the canonical frame address (CFA, which corresponds to the notion of a frame pointer), as well as a column for the return address. .P From 1993-2006 the interface we'll here refer to as DWARF2 made the CFA be a column in the matrix, but left DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL out of the matrix (giving them high numbers). As of the DWARF3 interfaces introduced in this document in April 2006, there are *two* interfaces (the original set and a new set). Several frame functions work transparently for either set, we will focus on the ones that are not equally suitable now. .P The original DWARF2 interface set still exists (dwarf_get_fde_info_for_reg(), dwarf_get_fde_info_for_cfa_reg(), and dwarf_get_fde_info_for_all_regs()) and works adequately for MIPS/IRIX DWARF2 and ABI/ISA sets that are sufficiently similar to MIPS. These functions not a good choice for non-MIPS architectures nor were they a good design for MIPS either. It's better to switch entirely to the new functions mentioned in the next paragraph. This DWARF2 interface set assumes and uses DW_FRAME_CFA_COL and that is assumed when libdwarf is configured with --enable-oldframecol . .P A new DWARF3 interface set of dwarf_get_fde_info_for_reg3(), dwarf_get_fde_info_for_cfa_reg3(), dwarf_get_fde_info_for_all_regs3(), dwarf_set_frame_rule_table_size() dwarf_set_frame_cfa_value(), dwarf_set_frame_same_value(), dwarf_set_frame_undefined_value(), and dwarf_set_frame_rule_initial_value() is more flexible and will work for many more architectures. It is also entirely suitable for use with DWARF2 and DWARF4. The setting of the 'frame cfa column number' defaults to DW_FRAME_CFA_COL3 and it can be set at runtime with dwarf_set_frame_cfa_value(). .P Mixing use of the DWARF2 interface set with use of the new DWARF3 interface set on a single open Dwarf_Debug instance is a mistake. Do not do it. .P We will pretend, from here on unless otherwise specified, that DW_FRAME_CFA_COL3, DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL are the synthetic column numbers. These columns may be user-chosen by calls of dwarf_set_frame_cfa_value() dwarf_set_frame_undefined_value(), and dwarf_set_frame_same_value() respectively. .P Each cell in the table contains one of the following: .AL .LI A register + offset(a)(b) .LI A register(c)(d) .LI A marker (DW_FRAME_UNDEFINED_VAL) meaning \fIregister value undefined\fP .LI A marker (DW_FRAME_SAME_VAL) meaning \fIregister value same as in caller\fP .LE .P (a old DWARF2 interface) When the column is DW_FRAME_CFA_COL: the register number is a real hardware register, not a reference to DW_FRAME_CFA_COL, not DW_FRAME_UNDEFINED_VAL, and not DW_FRAME_SAME_VAL. The CFA rule value should be the stack pointer plus offset 0 when no other value makes sense. A value of DW_FRAME_SAME_VAL would be semi-logical, but since the CFA is not a real register, not really correct. A value of DW_FRAME_UNDEFINED_VAL would imply the CFA is undefined -- this seems to be a useless notion, as the CFA is a means to finding real registers, so those real registers should be marked DW_FRAME_UNDEFINED_VAL, and the CFA column content (whatever register it specifies) becomes unreferenced by anything. .P (a new April 2006 DWARF2/3 interface): The CFA is separately accessible and not part of the table. The 'rule number' for the CFA is a number outside the table. So the CFA is a marker, not a register number. See DW_FRAME_CFA_COL3 in libdwarf.h and dwarf_get_fde_info_for_cfa_reg3() and dwarf_set_frame_rule_cfa_value(). .P (b) When the column is not DW_FRAME_CFA_COL3, the 'register' will and must be DW_FRAME_CFA_COL3(COL), implying that to get the final location for the column one must add the offset here plus the DW_FRAME_CFA_COL3 rule value. .P (c) When the column is DW_FRAME_CFA_COL3, then the 'register' number is (must be) a real hardware register . (This paragraph does not apply to the April 2006 new interface). If it were DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL it would be a marker, not a register number. .P (d) When the column is not DW_FRAME_CFA_COL3, the register may be a hardware register. It will not be DW_FRAME_CFA_COL3. .P There is no 'column' for DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. Nor for DW_FRAME_CFA_COL3. Figure \n(aX is machine dependent and represents MIPS CPU register assignments. The DW_FRAME_CFA_COL define in dwarf.h is historical and really belongs in libdwarf.h, not dwarf.h. .DS .TS center box, tab(:); lfB lfB lfB l c l. NAME:value:PURPOSE _ DW_FRAME_CFA_COL:0:column used for CFA DW_FRAME_REG1:1:integer register 1 DW_FRAME_REG2:2:integer register 2 ---::obvious names and values here DW_FRAME_REG30:30:integer register 30 DW_FRAME_REG31:31:integer register 31 DW_FRAME_FREG0:32:floating point register 0 DW_FRAME_FREG1:33:floating point register 1 ---::obvious names and values here DW_FRAME_FREG30:62:floating point register 30 DW_FRAME_FREG31:63:floating point register 31 DW_FRAME_RA_COL:64:column recording ra DW_FRAME_UNDEFINED_VAL:1034:register val undefined DW_FRAME_SAME_VAL:1035:register same as in caller .TE .FG "Frame Information Rule Assignments MIPS" .DE .P The following table shows SGI/MIPS specific special cell values: these values mean that the cell has the value \fIundefined\fP or \fIsame value\fP respectively, rather than containing a \fIregister\fP or \fIregister+offset\fP. It assumes DW_FRAME_CFA_COL is a table rule, which is not readily accomplished or even sensible for some architectures. .P .DS .TS center box, tab(:); lfB lfB lfB l c l. NAME:value:PURPOSE _ DW_FRAME_UNDEFINED_VAL:1034:means undefined value. ::Not a column or register value DW_FRAME_SAME_VAL:1035:means 'same value' as ::caller had. Not a column or ::register value DW_FRAME_CFA_COL:0:means register zero is ::usurped by the CFA column. :: .TE .FG "Frame Information Special Values any architecture" .DE .P The following table shows more general special cell values. These values mean that the cell register-number refers to the \fIcfa-register\fP or \fIundefined-value\fP or \fIsame-value\fP respectively, rather than referring to a \fIregister in the table\fP. The generality arises from making DW_FRAME_CFA_COL3 be outside the set of registers and making the cfa rule accessible from outside the rule-table. .P .DS .TS center box, tab(:); lfB lfB lfB l c l. NAME:value:PURPOSE _ DW_FRAME_UNDEFINED_VAL:1034:means undefined ::value. Not a column or register value DW_FRAME_SAME_VAL:1035:means 'same value' as ::caller had. Not a column or ::register value DW_FRAME_CFA_COL3:1436:means 'cfa register' ::is referred to, not a real register, not ::a column, but the cfa (the cfa does have ::a value, but in the DWARF3 libdwarf interface ::it does not have a 'real register number'). .TE .DE .P .H 3 "dwarf_get_frame_section_name()" .DS \f(CWint dwarf_get_frame_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_string_section_name()\fP lets consumers access the object string section name. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_frame_section_name_eh_gnu()\fP. .P The function \f(CWdwarf_get_frame_section_name()\fP operates on the the .debug_frame section. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_frame_section_name_eh_gnu()" .DS \f(CWint dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_frame_section_name_eh_gnu()\fP lets consumers access the object string section name. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_frame_section_name()\fP. .P The function \f(CWdwarf_get_frame_section_name_eh_ghu()\fP operates on the the .eh_frame section. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_fde_list()" .DS \f(CWint dwarf_get_fde_list( Dwarf_Debug dbg, Dwarf_Cie **cie_data, Dwarf_Signed *cie_element_count, Dwarf_Fde **fde_data, Dwarf_Signed *fde_element_count, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_list()\fP stores a pointer to a list of \f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the count of the number of descriptors in \f(CW*cie_element_count\fP. There is a descriptor for each CIE in the .debug_frame section. Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP descriptors in \f(CW*fde_data\fP, and the count of the number of descriptors in \f(CW*fde_element_count\fP. There is one descriptor per FDE in the .debug_frame section. \f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find frame entries. It returns \f(CWDW_DLV_OK\fP on a successful return. .P On successful return, structures pointed to by a descriptor should be freed using \f(CWdwarf_fde_cie_list_dealloc()\fP. This dealloc approach is new as of July 15, 2005. .in +2 .FG "Exampleq dwarf_get_fde_list()" .DS \f(CW void exampleq(Dwarf_Debug dbg) { Dwarf_Cie *cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde *fde_data = 0; Dwarf_Signed fde_count = 0; Dwarf_Error error = 0; int fres = 0; fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, &fde_data,&fde_count,&error); if (fres == DW_DLV_OK) { dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, fde_data,fde_count); } } \fP .DE .in -2 .P The following code is deprecated as of July 15, 2005 as it does not free all relevant memory. This approach still works as well as it ever did. .in +2 .FG "Exampleqb dwarf_get_fde_list() obsolete" .DS \f(CW /* OBSOLETE EXAMPLE */ void exampleqb(Dwarf_Debug dbg) { Dwarf_Cie *cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde *fde_data = 0; Dwarf_Signed fde_count = 0; Dwarf_Error error = 0; Dwarf_Signed i = 0; int fres = 0; fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, &fde_data,&fde_count,&error); if (fres == DW_DLV_OK) { for (i = 0; i < cie_count; ++i) { /* use cie[i] */ dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); } for (i = 0; i < fde_count; ++i) { /* use fde[i] */ dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); } dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); } } \fP .DE .in -2 .P .H 3 "dwarf_get_fde_list_eh()" .DS \f(CWint dwarf_get_fde_list_eh( Dwarf_Debug dbg, Dwarf_Cie **cie_data, Dwarf_Signed *cie_element_count, Dwarf_Fde **fde_data, Dwarf_Signed *fde_element_count, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_list_eh()\fP is identical to \f(CWdwarf_get_fde_list()\fP except that \f(CWdwarf_get_fde_list_eh()\fP reads the GNU gcc section named .eh_frame (C++ exception handling information). \f(CWdwarf_get_fde_list_eh()\fP stores a pointer to a list of \f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the count of the number of descriptors in \f(CW*cie_element_count\fP. There is a descriptor for each CIE in the .debug_frame section. Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP descriptors in \f(CW*fde_data\fP, and the count of the number of descriptors in \f(CW*fde_element_count\fP. There is one descriptor per FDE in the .debug_frame section. \f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find exception handling entries. It returns \f(CWDW_DLV_OK\fP on a successful return. .P On successful return, structures pointed to by a descriptor should be freed using \f(CWdwarf_fde_cie_list_dealloc()\fP. This dealloc approach is new as of July 15, 2005. .in +2 .FG "Exampler dwarf_get_fde_list_eh()" .DS \f(CW void exampler(Dwarf_Debug dbg,Dwarf_Addr mypcval) { /* Given a pc value for a function find the FDE and CIE data for the function. Example shows basic access to FDE/CIE plus one way to access details given a PC value. dwarf_get_fde_n() allows accessing all FDE/CIE data so one could build up an application-specific table of information if that is more useful. */ Dwarf_Signed count = 0; Dwarf_Cie *cie_data = 0; Dwarf_Signed cie_count = 0; Dwarf_Fde *fde_data = 0; Dwarf_Signed fde_count = 0; Dwarf_Error error = 0; int fres = 0; fres = dwarf_get_fde_list_eh(dbg,&cie_data,&cie_count, &fde_data,&fde_count,&error); if (fres == DW_DLV_OK) { Dwarf_Fde myfde = 0; Dwarf_Addr low_pc = 0; Dwarf_Addr high_pc = 0; fres = dwarf_get_fde_at_pc(fde_data,mypcval, &myfde,&low_pc,&high_pc, &error); if (fres == DW_DLV_OK) { Dwarf_Cie mycie = 0; fres = dwarf_get_cie_of_fde(myfde,&mycie,&error); if (fres == DW_DLV_OK) { /* Now we can access a range of information about the fde and cie applicable. */ } } dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, fde_data,fde_count); } /* ERROR or NO ENTRY. Do something */ } \fP .DE .in -2 .P .H 3 "dwarf_get_cie_of_fde()" .DS \f(CWint dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *cie_returned, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_cie_of_fde()\fP stores a \f(CWDwarf_Cie\fP into the \f(CWDwarf_Cie\fP that \f(CWcie_returned\fP points at. If one has called \f(CWdwarf_get_fde_list()\fP must avoid dwarf_dealloc-ing the FDEs and the CIEs for those FDEs individually (see its documentation here). Failing to observe this restriction will cause the FDE(s) not dealloc'd to become invalid: an FDE contains (hidden in it) a CIE pointer which will be be invalid (stale, pointing to freed memory) if the CIE is dealloc'd. The invalid CIE pointer internal to the FDE cannot be detected as invalid by libdwarf. If one later passes an FDE with a stale internal CIE pointer to one of the routines taking an FDE as input the result will be failure of the call (returning DW_DLV_ERROR) at best and it is possible a coredump or worse will happen (eventually). \f(CWdwarf_get_cie_of_fde()\fP returns \f(CWDW_DLV_OK\fP if it is successful (it will be unless fde is the NULL pointer). It returns \f(CWDW_DLV_ERROR\fP if the fde is invalid (NULL). .P Each \f(CWDwarf_Fde\fP descriptor describes information about the frame for a particular subroutine or function. \f(CWint dwarf_get_fde_for_die\fP is SGI/MIPS specific. .H 3 "dwarf_get_fde_for_die()" .DS \f(CWint dwarf_get_fde_for_die( Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Fde * return_fde, Dwarf_Error *error)\fP .DE When it succeeds, \f(CWdwarf_get_fde_for_die()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_fde\fP to a \f(CWDwarf_Fde\fP descriptor representing frame information for the given \f(CWdie\fP. It looks for the \f(CWDW_AT_MIPS_fde\fP attribute in the given \f(CWdie\fP. If it finds it, is uses the value of the attribute as the offset in the .debug_frame section where the FDE begins. If there is no \f(CWDW_AT_MIPS_fde\fP it returns \f(CWDW_DLV_NO_ENTRY\fP. If there is an error it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_get_fde_range()" .DS \f(CWint dwarf_get_fde_range( Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_length, Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_length, Dwarf_Off *cie_offset, Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error);\fP .DE On success, \f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_OK\fP. The location pointed to by \f(CWlow_pc\fP is set to the low pc value for this function. The location pointed to by \f(CWfunc_length\fP is set to the length of the function in bytes. This is essentially the length of the text section for the function. The location pointed to by \f(CWfde_bytes\fP is set to the address where the FDE begins in the .debug_frame section. The location pointed to by \f(CWfde_byte_length\fP is set to the length in bytes of the portion of .debug_frame for this FDE. This is the same as the value returned by \f(CWdwarf_get_fde_range\fP. The location pointed to by \f(CWcie_offset\fP is set to the offset in the .debug_frame section of the CIE used by this FDE. The location pointed to by \f(CWcie_index\fP is set to the index of the CIE used by this FDE. The index is the index of the CIE in the list pointed to by \f(CWcie_data\fP as set by the function \f(CWdwarf_get_fde_list()\fP. However, if the function \f(CWdwarf_get_fde_for_die()\fP was used to obtain the given \f(CWfde\fP, this index may not be correct. The location pointed to by \f(CWfde_offset\fP is set to the offset of the start of this FDE in the .debug_frame section. \f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_cie_info()" .DS \f(CWint dwarf_get_cie_info( Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie, Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *code_alignment_factor, Dwarf_Signed *data_alignment_factor, Dwarf_Half *return_address_register_rule, Dwarf_Ptr *initial_instructions, Dwarf_Unsigned *initial_instructions_length, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_cie_info()\fP is primarily for Internal-level Interface consumers. If successful, it returns \f(CWDW_DLV_OK\fP and sets \f(CW*bytes_in_cie\fP to the number of bytes in the portion of the frames section for the CIE represented by the given \f(CWDwarf_Cie\fP descriptor, \f(CWcie\fP. The other fields are directly taken from the cie and returned, via the pointers to the caller. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_cie_index()" .DS \f(CWint dwarf_get_cie_index( Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error);\fP .DE On success, \f(CWdwarf_get_cie_index()\fP returns \f(CWDW_DLV_OK\fP. On error this function returns \f(CWDW_DLV_ERROR\fP. The location pointed to by \f(CWcie_index\fP is set to the index of the CIE of this FDE. The index is the index of the CIE in the list pointed to by \f(CWcie_data\fP as set by the function \f(CWdwarf_get_fde_list()\fP. So one must have used \f(CWdwarf_get_fde_list()\fP or \f(CWdwarf_get_fde_list_eh()\fP to get a cie list before this is meaningful. This function is occasionally useful, but is little used. .H 3 "dwarf_get_fde_instr_bytes()" .DS \f(CWint dwarf_get_fde_instr_bytes( Dwarf_Fde fde, Dwarf_Ptr *outinstrs, Dwarf_Unsigned *outlen, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_instr_bytes()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*outinstrs\fP to a pointer to a set of bytes which are the actual frame instructions for this fde. It also sets \f(CW*outlen\fP to the length, in bytes, of the frame instructions. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. The intent is to allow low-level consumers like a dwarf-dumper to print the bytes in some fashion. The memory pointed to by \f(CWoutinstrs\fP must not be changed and there is nothing to free. .H 3 "dwarf_get_fde_info_for_reg()" This interface is suitable for DWARF2 but is not sufficient for DWARF3. See \f(CWint dwarf_get_fde_info_for_reg3\fP. .DS \f(CWint dwarf_get_fde_info_for_reg( Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_info_for_reg()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*offset_relevant\fP to non-zero if the offset is relevant for the row specified by \f(CWpc_requested\fP and column specified by \f(CWtable_column\fP, for the FDE specified by \f(CWfde\fP. The intent is to return the rule for the given pc value and register. The location pointed to by \f(CWregister_num\fP is set to the register value for the rule. The location pointed to by \f(CWoffset\fP is set to the offset value for the rule. If offset is not relevant for this rule, \f(CW*offset_relevant\fP is set to zero. Since more than one pc value will have rows with identical entries, the user may want to know the earliest pc value after which the rules for all the columns remained unchanged. Recall that in the virtual table that the frame information represents there may be one or more table rows with identical data (each such table row at a different pc value). Given a \f(CWpc_requested\fP which refers to a pc in such a group of identical rows, the location pointed to by \f(CWrow_pc\fP is set to the lowest pc value within the group of identical rows. The value put in \f(CW*register_num\fP any of the \f(CWDW_FRAME_*\fP table columns values specified in \f(CWlibdwarf.h\fP or \f(CWdwarf.h\fP. \f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. It is usable with either \f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP. \f(CWdwarf_get_fde_info_for_reg()\fP is tailored to MIPS, please use \f(CWdwarf_get_fde_info_for_reg3()\fP instead for all architectures. .H 3 "dwarf_get_fde_info_for_all_regs()" .DS \f(CWint dwarf_get_fde_info_for_all_regs( Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error);\fP .DE \f(CWdwarf_get_fde_info_for_all_regs()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by \f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. .P The intent is to return the rules for decoding all the registers, given a pc value. \f(CWreg_table\fP is an array of rules, one for each register specified in \f(CWdwarf.h\fP. The rule for each register contains three items - \f(CWdw_regnum\fP which denotes the register value for that rule, \f(CWdw_offset\fP which denotes the offset value for that rule and \f(CWdw_offset_relevant\fP which is set to zero if offset is not relevant for that rule. See \f(CWdwarf_get_fde_info_for_reg()\fP for a description of \f(CWrow_pc\fP. .P \f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. .P \f(CWint dwarf_get_fde_info_for_all_regs\fP is tailored to SGI/MIPS, please use dwarf_get_fde_info_for_all_regs3() instead for all architectures. .H 3 "dwarf_fde_section_offset()" .DS \f(CWint dwarf_fde_section_offset( Dwarf_Debug /*dbg*/, Dwarf_Fde /*in_fde*/, Dwarf_Off * /*fde_off*/, Dwarf_Off * /*cie_off*/, Dwarf_Error *error);\fP .DE On success \f(CWdwarf_fde_section_offset()\fP returns the .dwarf_line section offset of the fde passed in and also the offset of its CIE. .P It returns \f(CWDW_DLV_ERROR\fP if there is an error. .P It returns \f(CWDW_DLV_ERROR\fP if there is an error. .P It is intended to be used by applications like dwarfdump when such want to print the offsets of CIEs and FDEs. .H 3 "dwarf_cie_section_offset()" .DS \f(CWint dwarf_cie_section_offset( Dwarf_Debug /*dbg*/, Dwarf_Cie /*in_cie*/, Dwarf_Off * /*cie_off*/, Dwarf_Error * /*err*/); Dwarf_Error *error);\fP .DE On success \f(CWdwarf_cie_section_offset()\fP returns the .dwarf_line section offset of the cie passed in. .P It returns \f(CWDW_DLV_ERROR\fP if there is an error. .P It is intended to be used by applications like dwarfdump when such want to print the offsets of CIEs. .H 3 "dwarf_set_frame_rule_table_size()" .P This allows consumers to set the size of the (internal to libdwarf) rule table when using the 'reg3' interfaces (these interfaces are strongly preferred over the older 'reg' interfaces). It should be at least as large as the number of real registers in the ABI which is to be read in for the dwarf_get_fde_info_for_reg3() or dwarf_get_fde_info_for_all_regs3() functions to work properly. The frame rule table size must be less than the marker values DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL, DW_FRAME_CFA_COL3 (dwarf_set_frame_rule_undefined_value() dwarf_set_frame_same_value() dwarf_set_frame_cfa_value() effectively set these markers so the frame rule table size can actually be any value regardless of the macro values in libdwarf.h as long as the table size does not overlap these markers). .P .DS \f(CWDwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_table_size()\fP sets the value \f(CWvalue\fP as the size of libdwarf-internal rules tables of \f(CWdbg\fP. .P The function returns the previous value of the rules table size setting (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_rule_initial_value()" This allows consumers to set the initial value for rows in the frame tables. By default it is taken from libdwarf.h and is DW_FRAME_REG_INITIAL_VALUE (which itself is either DW_FRAME_SAME_VAL or DW_FRAME_UNDEFINED_VAL). The MIPS/IRIX default is DW_FRAME_SAME_VAL. Consumer code should set this appropriately and for many architectures (but probably not MIPS) DW_FRAME_UNDEFINED_VAL is an appropriate setting. Note: an earlier spelling of dwarf_set_frame_rule_inital_value() is still supported as an interface, but please change to use the new correctly spelled name. .DS \f(CWDwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_initial_value()\fP sets the value \f(CWvalue\fP as the initial value for this \f(CWdbg\fP when initializing rules tables. .P The function returns the previous value of initial value (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_cfa_value()" This allows consumers to set the number of the CFA register for rows in the frame tables. By default it is taken from libdwarf.h and is \f(CWDW_FRAME_CFA_COL\fP. Consumer code should set this appropriately and for nearly all architectures \f(CWDW_FRAME_CFA_COL3\fP is an appropriate setting. .DS \f(CWDwarf_Half dwarf_set_frame_rule_cfa_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_cfa_value()\fP sets the value \f(CWvalue\fP as the number of the cfa 'register rule' for this \f(CWdbg\fP when initializing rules tables. .P The function returns the previous value of the pseudo-register (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_same_value()" This allows consumers to set the number of the pseudo-register when DW_CFA_same_value is the operation. By default it is taken from libdwarf.h and is \f(CWDW_FRAME_SAME_VAL\fP. Consumer code should set this appropriately, though for many architectures \f(CWDW_FRAME_SAME_VAL\fP is an appropriate setting. .DS \f(CWDwarf_Half dwarf_set_frame_rule_same_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_same_value()\fP sets the value \f(CWvalue\fP as the number of the register that is the pseudo-register set by the DW_CFA_same_value frame operation. .P The function returns the previous value of the pseudo-register (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_frame_undefined_value()" This allows consumers to set the number of the pseudo-register when DW_CFA_undefined_value is the operation. By default it is taken from libdwarf.h and is \f(CWDW_FRAME_UNDEFINED_VAL\fP. Consumer code should set this appropriately, though for many architectures \f(CWDW_FRAME_UNDEFINED_VAL\fP is an appropriate setting. .DS \f(CWDwarf_Half dwarf_set_frame_rule_undefined_value(Dwarf_Debug dbg, Dwarf_Half value);\fP .DE \f(CWdwarf_set_frame_rule_undefined_value()\fP sets the value \f(CWvalue\fP as the number of the register that is the pseudo-register set by the DW_CFA_undefined_value frame operation. .P The function returns the previous value of the pseudo-register (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_set_default_address_size()" This allows consumers to set a default address size. When one has an object where the default address_size does not match the frame address size where there is no debug_info available to get a frame-specific address-size, this function is useful. For example, if an Elf64 object has a .debug_frame whose real address_size is 4 (32 bits). This a very rare situation. .DS \f(CWDwarf_Small dwarf_set_default_address_size(Dwarf_Debug dbg, Dwarf_Small value);\fP .DE \f(CWdwarf_set_default_address_size()\fP sets the value \f(CWvalue\fP as the default address size for this activation of the reader, but only if \f(CWvalue\fP is greater than zero (otherwise the default address size is not changed). .P The function returns the previous value of the default address size (taken from the \f(CWdbg\fP structure). .H 3 "dwarf_get_fde_info_for_reg3()" This interface is suitable for DWARF2 and later. It returns the values for a particular real register (Not for the CFA virtual register, see dwarf_get_fde_info_for_cfa_reg3() below). If the application is going to retrieve the value for more than a few \f(CWtable_column\fP values at this \f(CWpc_requested\fP (by calling this function multiple times) it is much more efficient to call dwarf_get_fde_info_for_all_regs3() (in spite of the additional setup that requires of the caller). .DS \f(CWint dwarf_get_fde_info_for_reg3( Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error);\fP .DE See also the nearly identical function \f(CWdwarf_get_fde_info_for_reg3_b()\fP. .P \f(CWdwarf_get_fde_info_for_reg3()\fP returns \f(CWDW_DLV_OK\fP on success. It sets \f(CW*value_type\fP to one of DW_EXPR_OFFSET (0), DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or DW_EXPR_VAL_EXPRESSION(3). On call, \f(CWtable_column\fP must be set to the register number of a real register. Not the cfa 'register' or DW_FRAME_SAME_VALUE or DW_FRAME_UNDEFINED_VALUE. if \f(CW*value_type\fP has the value DW_EXPR_OFFSET (0) then: .in +4 .P It sets \f(CW*offset_relevant\fP to non-zero if the offset is relevant for the row specified by \f(CWpc_requested\fP and column specified by \f(CWtable_column\fP or, for the FDE specified by \f(CWfde\fP. In this case the \f(CW*register_num\fP will be set to DW_FRAME_CFA_COL3 (. This is an offset(N) rule as specified in the DWARF3/2 documents. .P Adding the value of \f(CW*offset_or_block_len\fP to the value of the CFA register gives the address of a location holding the previous value of register \f(CWtable_column\fP. .P If offset is not relevant for this rule, \f(CW*offset_relevant\fP is set to zero. \f(CW*register_num\fP will be set to the number of the real register holding the value of the \f(CWtable_column\fP register. This is the register(R) rule as specified in DWARF3/2 documents. .P The intent is to return the rule for the given pc value and register. The location pointed to by \f(CWregister_num\fP is set to the register value for the rule. The location pointed to by \f(CWoffset\fP is set to the offset value for the rule. Since more than one pc value will have rows with identical entries, the user may want to know the earliest pc value after which the rules for all the columns remained unchanged. Recall that in the virtual table that the frame information represents there may be one or more table rows with identical data (each such table row at a different pc value). Given a \f(CWpc_requested\fP which refers to a pc in such a group of identical rows, the location pointed to by \f(CWrow_pc\fP is set to the lowest pc value within the group of identical rows. .in -4 .P If \f(CW*value_type\fP has the value DW_EXPR_VAL_OFFSET (1) then: .in +4 This will be a val_offset(N) rule as specified in the DWARF3/2 documents so \f(CW*offset_relevant\fP will be non zero. The calculation is identical to the DW_EXPR_OFFSET (0) calculation with \f(CW*offset_relevant\fP non-zero, but the value resulting is the actual \f(CWtable_column\fP value (rather than the address where the value may be found). .in -4 .P If \f(CW*value_type\fP has the value DW_EXPR_EXPRESSION (1) then: .in +4 \f(CW*offset_or_block_len\fP is set to the length in bytes of a block of memory with a DWARF expression in the block. \f(CW*block_ptr\fP is set to point at the block of memory. The consumer code should evaluate the block as a DWARF-expression. The result is the address where the previous value of the register may be found. This is a DWARF3/2 expression(E) rule. .in -4 .P If \f(CW*value_type\fP has the value DW_EXPR_VAL_EXPRESSION (1) then: .in +4 The calculation is exactly as for DW_EXPR_EXPRESSION (1) but the result of the DWARF-expression evaluation is the value of the \f(CWtable_column\fP (not the address of the value). This is a DWARF3/2 val_expression(E) rule. .in -4 \f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error and if there is an error only the \f(CWerror\fP pointer is set, none of the other output arguments are touched. It is usable with either \f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP. .H 3 "dwarf_get_fde_info_for_reg3_b()" This interface is suitable for DWARF2 and later. It returns the values for a particular real register (Not for the CFA virtual register, see dwarf_get_fde_info_for_cfa_reg3_b() below). If the application is going to retrieve the value for more than a few \f(CWtable_column\fP values at this \f(CWpc_requested\fP (by calling this function multiple times) it is much more efficient to call dwarf_get_fde_info_for_all_regs3() (in spite of the additional setup that requires of the caller). .DS \f(CWint dwarf_get_fde_info_for_reg3_b( Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Bool *has_more_rows, Dwarf_Addr *subsequent_pc, Dwarf_Error *error);\fP .DE .P This is identical to \f(CWdwarf_get_fde_info_for_reg3()\fP except for the new arguments \f(CWhas_more_rows\fP and \f(CWsubsequent_pc\fP which allow the caller to know if there are more rows in the frame table and what the next pc value in the frame table for this fde is. The two new arguments may be passed in as NULL if their values are not needed by the caller. .H 3 "dwarf_get_fde_info_for_cfa_reg3()" .DS \f(CWint dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed* offset_relevant, Dwarf_Signed* register_num, Dwarf_Signed* offset_or_block_len, Dwarf_Ptr * block_ptr , Dwarf_Addr * row_pc_out, Dwarf_Error * error)\fP .DE .P This is identical to \f(CWdwarf_get_fde_info_for_reg3()\fP except the returned values are for the CFA rule. So register number \f(CW*register_num\fP will be set to a real register, not one of the pseudo registers (which are usually DW_FRAME_CFA_COL3, DW_FRAME_SAME_VALUE, or DW_FRAME_UNDEFINED_VALUE). .P Applications like dwarfdump which access the register rules for every pc value in a function may find the following function a slight performance improvement if the new arguments are used appropriately. See \f(CWdwarfdump\fP for an example of use. .H 3 "dwarf_get_fde_info_for_cfa_reg3_b()" .DS \f(CWint dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Small * value_type, Dwarf_Signed* offset_relevant, Dwarf_Signed* register_num, Dwarf_Signed* offset_or_block_len, Dwarf_Ptr * block_ptr , Dwarf_Addr * row_pc_out, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error)\fP .DE .P This is identical to \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP except for the new arguments \f(CWhas_more_rows\fP and \f(CWsubsequent_pc\fP which allow the caller to know if there are more rows in the frame table and what the next pc value is. The two new arguments may be passed in as NULL if their values are not needed by the caller. .P For a tool just wanting the frame information for a single pc_value this interface is no more useful nore more efficient than \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP. .P The essential difference is that when using \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP for all pc values for a function the caller has no idea what is the next pc value that might have new frame data and iterating through pc values (calling \f(CWdwarf_get_fde_info_for_cfa_reg3()\fP on each) is a waste of cpu cycles. With \f(CWdwarf_get_fde_info_for_cfa_reg3_b()\fP the \f(CWhas_more_rows\fP and \f(CWsubsequent_pc\fP arguments let the caller know whether there are further changes and if so at what pc value. .P If \f(CWhas_more_rows\fP is non-null then 0 is returned through the pointer if, for the \f(CWpc_requested\fP there is frame data for addresses after \f(CWpc_requested\fP in the frame. And if there are no more rows in the frame data then 1 is set through the \f(CWhas_more_rows\fP pointer. .P If \f(CWsubsequent_pc\fP is non-null then the pc-value which has the next frame operator is returned through the pointer. If no more rows are present zero is returned through the pointer, but please use \f(CWhas_more_rows\fP to determine if there are more rows. .H 3 "dwarf_get_fde_info_for_all_regs3()" .DS \f(CWint 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)\fP .DE \f(CWdwarf_get_fde_info_for_all_regs3()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by \f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. The intent is to return the rules for decoding all the registers, given a pc value. \f(CWreg_table\fP is an array of rules, the array size specified by the caller. plus a rule for the CFA. The rule for the cfa returned in \f(CW*reg_table\fP defines the CFA value at \f(CWpc_requested\fP The rule for each register contains several values that enable the consumer to determine the previous value of the register (see the earlier documentation of Dwarf_Regtable3). \f(CWdwarf_get_fde_info_for_reg3()\fP and the Dwarf_Regtable3 documentation above for a description of the values for each row. \f(CWdwarf_get_fde_info_for_all_regs3\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. It is up to the caller to allocate space for \f(CW*reg_table\fP and initialize it properly. .H 3 "dwarf_get_fde_n()" .DS \f(CWint dwarf_get_fde_n( Dwarf_Fde *fde_data, Dwarf_Unsigned fde_index, Dwarf_Fde *returned_fde Dwarf_Error *error)\fP .DE \f(CWdwarf_get_fde_n()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to the \f(CWDwarf_Fde\fP descriptor whose index is \f(CWfde_index\fP in the table of \f(CWDwarf_Fde\fP descriptors pointed to by \fPfde_data\fP. The index starts with 0. The table pointed to by fde_data is required to contain at least one entry. If the table has no entries at all the error checks may refer to uninitialized memory. Returns \f(CWDW_DLV_NO_ENTRY\fP if the index does not exist in the table of \f(CWDwarf_Fde\fP descriptors. Returns \f(CWDW_DLV_ERROR\fP if there is an error. This function cannot be used unless the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to \f(CWdwarf_get_fde_list()\fP. .H 3 "dwarf_get_fde_at_pc()" .DS \f(CWint dwarf_get_fde_at_pc( Dwarf_Fde *fde_data, Dwarf_Addr pc_of_interest, Dwarf_Fde *returned_fde, Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_fde_at_pc()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to a \f(CWDwarf_Fde\fP descriptor for a function which contains the pc value specified by \f(CWpc_of_interest\fP. In addition, it sets the locations pointed to by \f(CWlopc\fP and \f(CWhipc\fP to the low address and the high address covered by this FDE, respectively. The table pointed to by fde_data is required to contain at least one entry. If the table has no entries at all the error checks may refer to uninitialized memory. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWpc_of_interest\fP is not in any of the FDEs represented by the block of \f(CWDwarf_Fde\fP descriptors pointed to by \f(CWfde_data\fP. This function cannot be used unless the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to \f(CWdwarf_get_fde_list()\fP. .H 3 "dwarf_expand_frame_instructions()" .DS \f(CWint dwarf_expand_frame_instructions( Dwarf_Cie cie, Dwarf_Ptr instruction, Dwarf_Unsigned i_length, Dwarf_Frame_Op **returned_op_list, Dwarf_Signed * returned_op_count, Dwarf_Error *error);\fP .DE \f(CWdwarf_expand_frame_instructions()\fP is a High-level interface function which expands a frame instruction byte stream into an array of \f(CWDwarf_Frame_Op\fP structures. To indicate success, it returns \f(CWDW_DLV_OK\fP. The address where the byte stream begins is specified by \f(CWinstruction\fP, and the length of the byte stream is specified by \f(CWi_length\fP. The location pointed to by \f(CWreturned_op_list\fP is set to point to a table of \f(CWreturned_op_count\fP pointers to \f(CWDwarf_Frame_Op\fP which contain the frame instructions in the byte stream. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. After a successful return, the array of structures should be freed using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FRAME_BLOCK\fP (when they are no longer of interest). .P Not all CIEs have the same address-size, so it is crucial that a CIE pointer to the frame's CIE be passed in. .in +2 .FG "Examples dwarf_expand_frame_instructions()" .DS \f(CW void examples(Dwarf_Debug dbg,Dwarf_Cie cie, Dwarf_Ptr instruction,Dwarf_Unsigned len) { Dwarf_Signed count = 0; Dwarf_Frame_Op *frameops = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_expand_frame_instructions(cie,instruction,len, &frameops,&count, &error); if (res == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < count; ++i) { /* use frameops[i] */ } dwarf_dealloc(dbg, frameops, DW_DLA_FRAME_BLOCK); } } \fP .DE .in -2 .H 3 "dwarf_get_fde_exception_info()" .DS \f(CWint dwarf_get_fde_exception_info( Dwarf_Fde fde, Dwarf_Signed * offset_into_exception_tables, Dwarf_Error * error); .DE \f(CWdwarf_get_fde_exception_info()\fP is an IRIX specific function which returns an exception table signed offset through \f(CWoffset_into_exception_tables\fP. The function never returns \f(CWDW_DLV_NO_ENTRY\fP. If \f(CWDW_DLV_NO_ENTRY\fP is NULL the function returns \f(CWDW_DLV_ERROR\fP. For non-IRIX objects the offset returned will always be zero. For non-C++ objects the offset returned will always be zero. The meaning of the offset and the content of the tables is not defined in this document. The applicable CIE augmentation string (see above) determines whether the value returned has meaning. .H 2 "Location Expression Evaluation" An "interpreter" which evaluates a location expression is required in any debugger. There is no interface defined here at this time. .P One problem with defining an interface is that operations are machine dependent: they depend on the interpretation of register numbers and the methods of getting values from the environment the expression is applied to. .P It would be desirable to specify an interface. .H 3 "Location List Internal-level Interface" .H 4 "dwarf_get_loclist_entry()" .DS \f(CWint dwarf_get_loclist_entry( Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Addr *hipc_offset, Dwarf_Addr *lopc_offset, Dwarf_Ptr *data, Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, Dwarf_Error *error)\fP .DE This function is ill suited to use with 21st century DWARF as there is just not enough data provided in the interface. Do not use this interface. .P The function reads a location list entry starting at \f(CWoffset\fP and returns through pointers (when successful) the high pc \f(CWhipc_offset\fP, low pc \f(CWlopc_offset\fP, a pointer to the location description data \f(CWdata\fP, the length of the location description data \f(CWentry_len\fP, and the offset of the next location description entry \f(CWnext_entry\fP. .P This function will often work correctly (meaning with most objects compiled for DWARF3 or DWARF3) but will not work correctly (and can crash an application calling it) if either some location list applies to a compilation unit with an address_size different from the overall address_size of the object file being read or if the .debug_loc section being read has random padding bytes between loclists. Neither of these characteristics necessarily represents a bug in the compiler/linker toolset that produced the object file being read. The DWARF standard allows both characteristics. .P \f(CWdwarf_dwarf_get_loclist_entry()\fP returns \f(CWDW_DLV_OK\fP if successful. \f(CWDW_DLV_NO_ENTRY\fP is returned when the offset passed in is beyond the end of the .debug_loc section (expected if you start at offset zero and proceed through all the entries). \f(CWDW_DLV_ERROR\fP is returned on error. .P The \f(CWhipc_offset\fP, low pc \f(CWlopc_offset\fP are offsets from the beginning of the current procedure, not genuine pc values. .in +2 .FG "Examples dwarf_get_loclist_entry()" .DS \f(CW void examplet(Dwarf_Debug dbg,Dwarf_Unsigned offset) { /* Looping through the dwarf_loc section finding loclists: an example. */ int res; Dwarf_Unsigned next_entry = 0; Dwarf_Addr hipc_off = 0; Dwarf_Addr lowpc_off = 0; Dwarf_Ptr data = 0; Dwarf_Unsigned entry_len = 0; Dwarf_Error err = 0; for(;;) { res = dwarf_get_loclist_entry(dbg,offset,&hipc_off, &lowpc_off, &data, &entry_len,&next_entry,&err); if (res == DW_DLV_OK) { /* A valid entry. */ offset = next_entry; continue; } else if (res ==DW_DLV_NO_ENTRY) { /* Done! */ break; } else { /* Error! */ break; } } } \fP .DE .in -2 .H 2 "Abbreviations access" These are Internal-level Interface functions. Debuggers can ignore this. .H 3 "dwarf_get_abbrev()" .DS \f(CWint dwarf_get_abbrev( Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Abbrev *returned_abbrev, Dwarf_Unsigned *length, Dwarf_Unsigned *attr_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_abbrev\fP to \f(CWDwarf_Abbrev\fP descriptor for an abbreviation at offset \f(CW*offset\fP in the abbreviations section (i.e .debug_abbrev) on success. The user is responsible for making sure that a valid abbreviation begins at \f(CWoffset\fP in the abbreviations section. The location pointed to by \f(CWlength\fP is set to the length in bytes of the abbreviation in the abbreviations section. The location pointed to by \f(CWattr_count\fP is set to the number of attributes in the abbreviation. An abbreviation entry with a length of 1 is the 0 byte of the last abbreviation entry of a compilation unit. .P \f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_ERROR\fP on error. If the call succeeds, the storage pointed to by \f(CW*returned_abbrev\fP should be freed, using \f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed. .H 3 "dwarf_get_abbrev_tag()" .DS \f(CWint dwarf_get_abbrev_tag( Dwarf_abbrev abbrev, Dwarf_Half *return_tag, Dwarf_Error *error);\fP .DE If successful, \f(CWdwarf_get_abbrev_tag()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_tag\fP to the \fItag\fP of the given abbreviation. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_get_abbrev_code()" .DS \f(CWint dwarf_get_abbrev_code( Dwarf_abbrev abbrev, Dwarf_Unsigned *return_code, Dwarf_Error *error);\fP .DE If successful, \f(CWdwarf_get_abbrev_code()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*return_code\fP to the abbreviation code of the given abbreviation. It returns \f(CWDW_DLV_ERROR\fP on error. It never returns \f(CWDW_DLV_NO_ENTRY\fP. .H 3 "dwarf_get_abbrev_children_flag()" .DS \f(CWint dwarf_get_abbrev_children_flag( Dwarf_Abbrev abbrev, Dwarf_Signed *returned_flag, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_abbrev_children_flag()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CWreturned_flag\fP to \f(CWDW_children_no\fP (if the given abbreviation indicates that a die with that abbreviation has no children) or \f(CWDW_children_yes\fP (if the given abbreviation indicates that a die with that abbreviation has a child). It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_abbrev_entry_b()" .DS \f(CWint dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, Dwarf_Unsigned index, Dwarf_Bool filter_outliers, Dwarf_Unsigned * returned_attr_num, Dwarf_Unsigned * returned_form, Dwarf_Signed * returned_implict_const, Dwarf_Off * offset, Dwarf_Error * error)\fP .DE \f(CWdwarf_get_abbrev_entry_b()\fP is new in August 2019. It should be used in place of \f(CWdwarf_get_abbrev_entry()\fP as \f(CWdwarf_get_abbrev_entry()\fP cannot return the DWARF5 implicit const value and and \f(CWdwarf_get_abbrev_entry()\fP can hide some instances of corrupt uleb abbreviation values. .P While the \f(CWreturned_attr_num\fP and and \f(CWreturned_form\fP are only correct if they each fit in a \f(CWDwarf_Half\fP value, we return larger values in certain cases (see next paragraph). .P If \f(CWfilter_outliers\fP is passed in zero then erroneous \f(CWreturned_attr_num\fP or and \f(CWreturned_form\fP are returned whether their values are sensible or not and \f(CWDW_DLV_OK\fP is the returned value. This is useful for dwarfdump as dwarfdump checks abbreviation values quite thoroughly and reports errors in detail (dwarfdump -kb). .P If \f(CWfilter_outliers\fP is passed in non-zero then \f(CWDW_DLV_OK\fP is returned only if \f(CWreturned_attr_num\fP and and \f(CWreturned_form\fP are both legitmate values. .P If successful, \f(CWdwarf_get_abbrev_entry_b()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of the attribute whose index is specified by \f(CWindex\fP in the given abbreviation. .P The index starts at 0. .P The location pointed to by \f(CWreturned_attr_num\fP is set to the attribute number (example: \f(CWDW_AT_name\fP). The location pointed to by \f(CWreturned_form\fP is set to the form of the attribute (example: \f(CWDW_FORM_string\fP). The location pointed to by \f(CWreturned_implict_const\fP is set to the implicit const value if and only if the FORM returned is \f(CWDW_FORM_implicit_const\fP The location pointed to by \f(CWoffset\fP is set to the byte offset of the attribute in the abbreviations section. .P The function returns \f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside the range of attributes in this abbreviation. .P The function returns \f(CWDW_DLV_ERROR\fP on error and sets \f(CW*error\fP to an error value instance. .H 3 "dwarf_get_abbrev_entry()" .DS \f(CWint dwarf_get_abbrev_entry( Dwarf_Abbrev abbrev, Dwarf_Signed index, Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset, Dwarf_Error *error)\fP .DE .P This function cannot return DW_FORM_implicit_const const values. When convenient all callers should switch to using the \f(CWdwarf_get_abbrev_entry_b()\fP function. .P If successful, \f(CWdwarf_get_abbrev_entry()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of the attribute whose index is specified by \f(CWindex\fP in the given abbreviation. The index starts at 0. The location pointed to by \f(CWform\fP is set to the form of the attribute. The location pointed to by \f(CWoffset\fP is set to the byte offset of the attribute in the abbreviations section. .P It returns \f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside the range of attributes in this abbreviation. .P It returns \f(CWDW_DLV_ERROR\fP on error. .H 2 "String Section Operations" The .debug_str section contains only strings. Debuggers need never use this interface: it is only for debugging problems with the string section itself. .H 3 "dwarf_get_string_section_name()" .DS \f(CWint dwarf_get_string_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CWdwarf_get_string_section_name()\fP lets consumers access the object string section name. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. See also \f(CWdwarf_get_die_section_name_b()\fP. .P The function \f(CWdwarf_get_string_section_name()\fP operates on the the .debug_string[.dwo] section. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_str()" .DS \f(CWint dwarf_get_str( Dwarf_Debug dbg, Dwarf_Off offset, char **string, Dwarf_Signed *returned_str_len, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_str()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_str_len\fP to the length of the string, not counting the null terminator, that begins at the offset specified by \f(CWoffset\fP in the .debug_str section. The location pointed to by \f(CWstring\fP is set to a pointer to this string. The next string in the .debug_str section begins at the previous \f(CWoffset\fP + 1 + \f(CW*returned_str_len\fP. A zero-length string is NOT the end of the section. If there is no .debug_str section, \f(CWDW_DLV_NO_ENTRY\fP is returned. If there is an error, \f(CWDW_DLV_ERROR\fP is returned. If we are at the end of the section (that is, \f(CWoffset\fP is one past the end of the section) \f(CWDW_DLV_NO_ENTRY\fP is returned. If the \f(CWoffset\fP is some other too-large value then \f(CWDW_DLV_ERROR\fP is returned. .H 2 "String Offsets Section Operations" The .debug_str_offsets section contains only table arrays (with headers) and Debuggers should never need to use this interface. The normal string access functions use the section tables transparently. The functions here are only intended to allow dwarfdump (or the like) print the section completely and to help compiler developers look for bugs in the section. .in +2 .FG "examplestringoffsets dwarf_open_str_offsets_table_access() etc" .DS \f(CW void examplestringoffsets(Dwarf_Debug dbg) { int res = 0; Dwarf_Str_Offsets_Table sot = 0; Dwarf_Unsigned wasted_byte_count = 0; Dwarf_Unsigned table_count = 0; Dwarf_Error error = 0; res = dwarf_open_str_offsets_table_access(dbg, &sot,&error); if(res == DW_DLV_NO_ENTRY) { /* No such table */ return; } if(res == DW_DLV_ERROR) { /* Something is very wrong. Print the error? */ return; } for(;;) { Dwarf_Unsigned unit_length =0; Dwarf_Unsigned unit_length_offset =0; Dwarf_Unsigned table_start_offset =0; Dwarf_Half entry_size = 0; Dwarf_Half version =0; Dwarf_Half padding =0; Dwarf_Unsigned table_value_count =0; Dwarf_Unsigned i = 0; Dwarf_Unsigned table_entry_value = 0; res = dwarf_next_str_offsets_table(sot, &unit_length, &unit_length_offset, &table_start_offset, &entry_size,&version,&padding, &table_value_count,&error); if (res == DW_DLV_NO_ENTRY) { /* We have dealt with all tables */ break; } if (res == DW_DLV_ERROR) { /* Something badly wrong. Do something. */ return; } /* One could call dwarf_str_offsets_statistics to get the wasted bytes so far, but we do not do that in this example. */ /* Possibly print the various table-related values returned just above. */ for (i=0; i < table_value_count; ++i) { res = dwarf_str_offsets_value_by_index(sot,i, &table_entry_value,&error); if (res != DW_DLV_OK) { /* Something is badly wrong. Do something. */ return; } /* Do something with the table_entry_value at this index. Maybe just print it. It is an offset in .debug_str. */ } } res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, &table_count,&error); if (res == DW_DLV_OK) { /* The wasted byte count is set. Print it or something. One hopes zero bytes are wasted. Print the table count if one is interested. */ } res = dwarf_close_str_offsets_table_access(sot,&error); /* There is little point in checking the return value as little can be done about any error. */ sot = 0; } \fP .DE .in -2 .H 3 "dwarf_open_str_offsets_table_access()" .DS \f(CWint dwarf_open_str_offsets_table_access( Dwarf_Debug dbg, Dwarf_Str_Offsets_Table * table_data, Dwarf_Error * error);\fP .DE \f(CWdwarf_open_str_offsets_table_access()\fP creates an opaque struct and returns a pointer to it on success. That struct pointer is used in all subsequent operations on the table. Through the function \f(CWdwarf_next_str_offsets_table()\fP the caller can iterate through each of the per-CU offset tables. .P If there is no such section, or if the section is empty the function returns DW_DLV_NO_ENTRY. .P If there is an error (such as out-of-memory) the function returns DW_DLV_ERROR and sets an error value through the \f(CWerror\fP pointer. .H 3 "dwarf_close_str_offsets_table_access()" .DS \f(CWint dwarf_close_str_offsets_table_access( Dwarf_Str_Offsets_Table table_data, Dwarf_Error * error);\fP .DE On success, \f(CWdwarf_close_str_offsets_table_access()\fP frees any allocated data associated with the struct pointed to by \f(CWtable_data\fP and returns DW_DLV_OK. It is up to the caller to set the \f(CWtable_data\fP pointer to NULL if desired. The pointer is unusable at that point and any other calls to libdwarf using that pointer will fail. .P It returns DW_DLV_OK on error. Any error suggests there is memory corruption or an error in the call. Something serious happened. .P It never returns DW_DLV_NO_ENTRY, but if it did there would be nothing the caller could do anyway.. .P If one forgets to call this function the memory allocated will be freed automatically by to call to \f(CWdwarf_finish()\fP, as is true of all other data allocated by libdwarf. .H 3 "dwarf_next_str_offsets_table()" .DS \f(CWint dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table table, Dwarf_Unsigned *unit_length_out, Dwarf_Unsigned *unit_length_offset_out, Dwarf_Unsigned *table_start_offset_out, Dwarf_Half *entry_size_out, Dwarf_Half *version_out, Dwarf_Half *padding_out, Dwarf_Unsigned *table_value_count_out, Dwarf_Error * error);\fP .DE Each call to \f(CWdwarf_next_str_offsets_table()\fP returns the next String Offsets table in the .debug_str_offsets section. Typically there would be one such table for each CU in .debug_info[.dwo] contributing to .debug_str_offsets. The \f(CWtable\fP contains (internally, hidden) the section offset of the next table. .P On success it returns DW_DLV_OK and sets various fields representing data about the current table (fields described below). .P If there are no more tables it returns DW_DLV_NO_ENTRY. .P On error it returns DW_DLV_ERROR and passes back error details through the \f(CWerror\fP pointer. .P The returned values are intended to let the caller understand the table header and the table in detail. These pointers are only used if the call returned DW_DLV_OK. .P \f(CWunit_length_out\fP is set to the unit_length of a String Offsets Table Header. Which means it gives the length, in bytes, of the data following the length value that belongs to this table. .P \f(CWunit_length_offset_out\fP is set to the section offset of the table header. .P \f(CWtable_start_offset_out\fP is set to the section offset of the array of offsets in this table. .P \f(CWentry_size_out\fP is set to the size of a table entry. Which is 4 for 32-bit offsets in this table and 8 for 64-bit offsets in this table. .P \f(CWversion_out\fP is set to the version number in the table header. The only current valid value is 5. .P \f(CWpadding_out\fP is set to the 16-bit padding value in the table header. In a correct table header the value is zero. .P \f(CWtable_value_count_out\fP is set to the number of entries in the array of offsets in this table. Each entry is \f(CWentry_size_out\fP bytes long. Use this value in calling \f(CWdwarf_str_offsets_value_by_index()\fP. .H 3 "dwarf_str_offsets_value_by_index()" .DS \f(CWint dwarf_str_offsets_value_by_index( Dwarf_Str_Offsets_Table sot, Dwarf_Unsigned index, Dwarf_Unsigned *stroffset, Dwarf_Error *error);\fP .DE On success, \f(CWdwarf_str_offsets_value_by_index()\fP returns DW_DLV_OK and sets the offset from the array of string offsets in the current table at the input \f(CWindex\fP. .P Valid index values are zero through \f(CWtable_value_count_out - 1\fP .P A function is used instead of simply letting callers use pointers as libdwarf correctly handles endianness differences (between the system running libdwarf and the object file being inspected) so offsets can be reported properly. .P DW_DLV_ERROR is returned on error. .P DW_DLV_NO_ENTRY is never returned. .H 3 "dwarf_str_offsets_statistics()" .DS \f(CWint dwarf_str_offsets_statistics( Dwarf_Str_Offsets_Table table_data, Dwarf_Unsigned * wasted_byte_count, Dwarf_Unsigned * table_count, Dwarf_Error * error);\fP .DE Normally called after all tables have been inspected to return (through a pointer) the count of apparently-wasted bytes in the section. It can be called at any point that the \f(CWDwarf_Str_Offsets_Table\fP pointer is valid. .P On error it returns DW_DLV_ERROR and sets an error value through the pointer. .P DW_DLV_NO_ENTRY is never returned. .P On success it returns DW_DLV_OK and sets values through the two pointers. Calling just after each table is accessed by \f(CWdwarf_next_str_offsets_table()\fP will reveal the sum of all wasted bytes at that point in iterating through the section. .P \f(CWtable_count\fP is the count of table headers encountered so far. .P By wasted bytes we mean bytes in between tables. libdwarf has no idea whether any apparently-valid table data is in fact useless. .H 2 "Address Range Operations" These functions provide information about address ranges. The content is in the \f(CW.debug_aranges\fP section. Address ranges map ranges of pc values to the corresponding compilation-unit die that covers the address range. In the DWARF Standard this is described under "Accelerated Access" "Lookup by Address". .H 3 "dwarf_get_aranges_section_name()" .DS \f(CWint dwarf_get_aranges_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CW*dwarf_get_aranges_section_name()\fP retrieves the object file section name of the applicable aranges section. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_aranges()" .DS \f(CWint dwarf_get_aranges( Dwarf_Debug dbg, Dwarf_Arange **aranges, Dwarf_Signed * returned_arange_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_aranges()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange_count\fP to the count of the number of address ranges in the .debug_aranges section (for all compilation units). It sets \f(CW*aranges\fP to point to a block of \f(CWDwarf_Arange\fP descriptors, one for each address range. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges section. .P This not only reads all the ranges, it also reads the per-compilation-unit headers in .debug_aranges and verifies they make sense. .in +2 .FG "Exampleu dwarf_get_aranges()" .DS \f(CW void exampleu(Dwarf_Debug dbg) { Dwarf_Signed count = 0; Dwarf_Arange *arang = 0; int res = 0; Dwarf_Error error = 0; res = dwarf_get_aranges(dbg, &arang,&count, &error); if (res == DW_DLV_OK) { Dwarf_Signed i = 0; for (i = 0; i < count; ++i) { /* use arang[i] */ dwarf_dealloc(dbg, arang[i], DW_DLA_ARANGE); } dwarf_dealloc(dbg, arang, DW_DLA_LIST); } } \fP .DE .in -2 .H 3 "dwarf_get_arange()" .DS \f(CWint dwarf_get_arange( Dwarf_Arange *aranges, Dwarf_Unsigned arange_count, Dwarf_Addr address, Dwarf_Arange *returned_arange, Dwarf_Error *error);\fP .DE The function \f(CWdwarf_get_arange()\fP takes as input a pointer to a block of \f(CWDwarf_Arange\fP pointers, and a count of the number of descriptors in the block. It then searches for the descriptor that covers the given \f(CWaddress\fP. If it finds one, it returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange\fP to the descriptor. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges entry covering that address. .P .H 3 "dwarf_get_cu_die_offset()" .DS \f(CWint dwarf_get_cu_die_offset( Dwarf_Arange arange, Dwarf_Off *returned_cu_die_offset, Dwarf_Error *error);\fP .DE The function \f(CWdwarf_get_cu_die_offset()\fP takes a \f(CWDwarf_Arange\fP descriptor as input, and if successful returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_die_offset\fP to the offset in the .debug_info section of the compilation-unit DIE for the compilation-unit represented by the given address range. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_arange_cu_header_offset()" .DS \f(CWint dwarf_get_arange_cu_header_offset( Dwarf_Arange arange, Dwarf_Off *returned_cu_header_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_arange_cu_header_offset()\fP takes a \f(CWDwarf_Arange\fP descriptor as input, and if successful returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_header_offset\fP to the offset in the .debug_info section of the compilation-unit header for the compilation-unit represented by the given address range. It returns \f(CWDW_DLV_ERROR\fP on error. This function added Rev 1.45, June, 2001. This function is declared as 'optional' in libdwarf.h on IRIX systems so the _MIPS_SYMBOL_PRESENT predicate may be used at run time to determine if the version of libdwarf linked into an application has this function. .H 3 "dwarf_get_arange_info_b()" .DS \f(CWint dwarf_get_arange_info_b( Dwarf_Arange arange, Dwarf_Unsigned *segment, Dwarf_Unsigned *segment_entry_size; Dwarf_Addr *start, Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_arange_info_b()\fP returns \f(CWDW_DLV_OK\fP and stores segment number of the FIXME FIXME The the starting value of the address range in the location pointed to by \f(CWstart\fP, the length of the address range in the location pointed to by \f(CWlength\fP, and the offset in the .debug_info section of the compilation-unit DIE for the compilation-unit represented by the address range. It returns \f(CWDW_DLV_ERROR\fP on error. .H 3 "dwarf_get_arange_info()" .DS \f(CWint dwarf_get_arange_info( Dwarf_Arange arange, Dwarf_Addr *start, Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error)\fP .DE This is the same as \f(CWdwarf_get_arange_info_b()\fP except that this earlier function does not have a way to return the segment information. .H 2 "General Low Level Operations" This function is low-level and intended for use only by programs such as dwarf-dumpers. .H 3 "dwarf_get_offset_size()" .DS \f(CWint dwarf_get_offset_size(Dwarf_Debug dbg, Dwarf_Half *offset_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_offset_size()\fP returns \f(CWDW_DLV_OK\fP on success and sets the \f(CW*offset_size\fP to the size in bytes of an offset. In case of error, it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*offset_size\fP. The offset size returned is the overall address size, which can be misleading if different compilation units have different address sizes. Many ABIs have only a single address size per executable, but differing address sizes are becoming more common. .H 3 "dwarf_get_address_size()" .DS \f(CWint dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_address_size()\fP returns \f(CWDW_DLV_OK\fP on success and sets the \f(CW*addr_size\fP to the size in bytes of an address. In case of error, it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*addr_size\fP. The address size returned is the overall address size, which can be misleading if different compilation units have different address sizes. Many ABIs have only a single address size per executable, but differing address sizes are becoming more common. Use \f(CWdwarf_get_die_address_size()\fP instead whenever possible. .H 3 "dwarf_get_die_address_size()" .DS \f(CWint dwarf_get_die_address_size(Dwarf_Die die, Dwarf_Half *addr_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_die_address_size()\fP returns \f(CWDW_DLV_OK\fP on success and sets the \f(CW*addr_size\fP to the size in bytes of an address. In case of error, it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*addr_size\fP. The address size returned is the address size of the compilation unit owning the \f(CWdie\fP This is the preferred way to get address size when the \f(CWDwarf_Die\fP is known. .H 2 "Ranges Operations (.debug_ranges)" These functions provide information about the address ranges indicated by a \f(CWDW_AT_ranges\fP attribute (the ranges are recorded in the \f(CW.debug_ranges\fP section) of a DIE. Each call of \f(CWdwarf_get_ranges_a()\fP or \f(CWdwarf_get_ranges()\fP returns a an array of Dwarf_Ranges structs, each of which represents a single ranges entry. The struct is defined in \f(CWlibdwarf.h\fP. .P New in DWARF3, for DWARF3, and DWARF4 the section contained just ranges. The ranges are referenced by \f(CWDW_AT_ranges\fP attributes in various DIEs. .P For DWARF5 the section requires that each group of ranges has a header and the compilation unit may have a \f(CWDW_AT_ranges_base\fP attribute that must be added to the \f(CWDW_AT_ranges\fP attribute value to get the true ranges offset. .P (A compiler generating \f(CWDW_AT_ranges_base\fP will add a relocation for that attribute value but will not have to make the \f(CWDW_AT_ranges\fP attributes relocatable and will thus save space in the object (ie, .o) file and link time.) .H 3 "dwarf_get_ranges_section_name()" .DS \f(CWint dwarf_get_ranges_section_name(Dwarf_Debug dbg, const char ** sec_name, Dwarf_Error *error)\fP .DE \f(CW*dwarf_get_ranges_section_name()\fP retrieves the object file section name of the applicable ranges section. This is useful for applications wanting to print the name, but of course the object section name is not really a part of the DWARF information. Most applications will probably not call this function. It can be called at any time after the Dwarf_Debug initialization is done. .P If the function succeeds, \f(CW*sec_name\fP is set to a pointer to a string with the object section name and the function returns \f(CWDW_DLV_OK\fP. Do not free the string whose pointer is returned. For non-Elf objects it is possible the string pointer returned will be NULL or will point to an empty string. It is up to the calling application to recognize this possibility and deal with it appropriately. .P If the section does not exist the function returns DW_DLV_NO_ENTRY. .P If there is an internal error detected the function returns \f(CWDW_DLV_ERROR\fP and sets the \f(CW*error\fP pointer. .H 3 "dwarf_get_ranges()" This is the original call and it will work fine when all compilation units have the same address_size. There is no \f(CWdie\fP argument to this original version of the function. Other arguments (and deallocation) match the use of \f(CWdwarf_get_ranges_a()\fP ( described next). .H 3 "dwarf_get_ranges_a()" .DS \f(CWint dwarf_get_ranges_a( Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die die, Dwarf_Ranges **ranges, Dwarf_Signed * returned_ranges_count, Dwarf_Unsigned * returned_byte_count, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_ranges_a()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_ranges_count\fP to the count of the number of address ranges in the group of ranges in the .debug_ranges section at offset \f(CWoffset\fP (which ends with a pair of zeros of pointer-size). This function is new as of 27 April 2009. .P This function is normally used when one has a DIE with the \f(CWDW_AT_ranges\fP attribute (whose value is the offset needed). The ranges thus apply to the DIE involved. This function never sees the per-compilation-unit headers in the .debug_ranges section so of course any errors in those headers are ignored. .P See also \f(CWdwarf_get_aranges()\fP, .P The \f(CWoffset\fP argument should be the value of a \f(CWDW_AT_ranges\fP attribute of a Debugging Information Entry. The \f(CWdie\fP argument should be the value of a \f(CWDwarf_Die\fP pointer of a \f(CWDwarf_Die\fP with the attribute containing this range set offset. Because each compilation unit has its own address_size field this argument is necessary to to correctly read ranges. (Most executables have the same address_size in every compilation unit, but some ABIs allow multiple address sized in an executable). If a NULL pointer is passed in libdwarf assumes a single address_size is appropriate for all ranges records. The call sets \f(CW*ranges\fP to point to a block of \f(CWDwarf_Ranges\fP structs, one for each address range. It returns \f(CWDW_DLV_ERROR\fP on error. It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no \f(CW.debug_ranges\fP section or if \f(CWoffset\fP is past the end of the \f(CW.debug_ranges\fP section. If the \f(CW*returned_byte_count\fP pointer is passed as non-NULL the number of bytes that the returned ranges were taken from is returned through the pointer (for example if the returned_ranges_count is 2 and the pointer-size is 4, then returned_byte_count will be 8). If the \f(CW*returned_byte_count\fP pointer is passed as NULL the parameter is ignored. The \f(CW*returned_byte_count\fP is only of use to certain dumper applications, most applications will not use it. .in +2 .FG "Examplev dwarf_get_ranges_a()" .DS \f(CW void examplev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Die die) { Dwarf_Signed count = 0; Dwarf_Ranges *ranges = 0; Dwarf_Unsigned bytes = 0; Dwarf_Error error = 0; int res = 0; res = dwarf_get_ranges_a(dbg,offset,die, &ranges,&count,&bytes,&error); if (res == DW_DLV_OK) { Dwarf_Signed i; for( i = 0; i < count; ++i ) { Dwarf_Ranges *cur = ranges+i; /* Use cur. */ } dwarf_ranges_dealloc(dbg,ranges,count); } } \fP .DE .in -2 .H 3 "dwarf_ranges_dealloc()" .DS \f(CWint dwarf_ranges_dealloc( Dwarf_Debug dbg, Dwarf_Ranges *ranges, Dwarf_Signed range_count, );\fP .DE The function \f(CWdwarf_ranges_dealloc()\fP takes as input a pointer to a block of \f(CWDwarf_Ranges\fP array and the number of structures in the block. It frees all the data in the array of structures. .H 2 "Gdb Index operations" These functions get access to the fast lookup tables defined by gdb and gcc and stored in the \f(CW.gdb_index\fP section. The section is of sufficient complexity that a number of function interfaces are needed. For additional information see "https://sourceware.org/gdb/onlinedocs/gdb/" "Index-Section-Format.html#Index-Section-Format". (We split the url to two pieces so it can fit on the printed page join the pieces to make a usable url). .H 3 "dwarf_gdbindex_header()" .DS int dwarf_gdbindex_header(Dwarf_Debug dbg, Dwarf_Gdbindex * gdbindexptr, Dwarf_Unsigned * version, Dwarf_Unsigned * cu_list_offset, Dwarf_Unsigned * types_cu_list_offset, Dwarf_Unsigned * address_area_offset, Dwarf_Unsigned * symbol_table_offset, Dwarf_Unsigned * constant_pool_offset, Dwarf_Unsigned * section_size, Dwarf_Unsigned * unused_reserved, const char ** section_name, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_header()\fP takes as input a pointer to a Dwarf_Debug structure and returns fields through various pointers. .P If the function returns DW_DLV_NO_ENTRY there is no .gdb_index section and none of the return-pointer argument values are set. .P If the function returns DW_DLV_ERROR \f(CWerror\fP is set to indicate the specific error, but no other return-pointer arguments are touched. .P If successful, the function returns DW_DLV_OK and other values are set. The other values are set as follows: .P The field \f(CW*gdbindexptr\fP is set to an opaque pointer to a libdwarf_internal structure used as an argument to other .gdbindex functions below. .P The remaining fields are set to values that are mostly of interest to a pretty-printer application. See the detailed layout specification for specifics. The values returned are recorded in the Dwarf_Gdbindex opaque structure for the other gdbindex functions documented below. .P The field \f(CW*version\fP is set to the version of the gdb index header (2).. .P The field \f(CW*cu_list_offset\fP is set to the offset (in the .gdb_index section) of the cu-list. .P The field \f(CW*types_cu_list_offset\fP is set to the offset (in the .gdb_index section) of the types-list. .P The field \f(CW*address_area_offset\fP is set to the offset (in the .gdb_index section) of the address area. .P The field \f(CW*symbol_table_offset\fP is set to the offset (in the .gdb_index section) of the symbol table. .P The field \f(CW*constant_pool_offset\fP is set to the offset (in the .gdb_index section) of the constant pool. .P The field \f(CW*section_size\fP is set to the length of the .gdb_index section. .P The field \f(CW*unused_reserved\fP is set to zero. .P The field \f(CW*section_name\fP is set to the Elf object file section name (.gdb_index). If a non-Elf object file has such a section the value set might be NULL or might point to an empty string (NUL terminated), so code to account for NULL or empty. .P The field \f(CW*error\fP is not set. .P Here we show a use of the set of cu_list functions (using all the functions in one example makes it rather too long). .in +2 .FG "Examplew dwarf_get_gdbindex_header()" .DS \f(CW void examplew(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Die die) { Dwarf_Gdbindex gindexptr = 0; Dwarf_Unsigned version = 0; Dwarf_Unsigned cu_list_offset = 0; Dwarf_Unsigned types_cu_list_offset = 0; Dwarf_Unsigned address_area_offset = 0; Dwarf_Unsigned symbol_table_offset = 0; Dwarf_Unsigned constant_pool_offset = 0; Dwarf_Unsigned section_size = 0; Dwarf_Unsigned reserved = 0; Dwarf_Error error = 0; const char * section_name = 0; int res = 0; res = dwarf_gdbindex_header(dbg,&gindexptr, &version,&cu_list_offset, &types_cu_list_offset, &address_area_offset,&symbol_table_offset, &constant_pool_offset, §ion_size, &reserved,§ion_name,&error); if (res == DW_DLV_NO_ENTRY) { return; } else if (res == DW_DLV_ERROR) { return; } { /* do something with the data */ Dwarf_Unsigned length = 0; Dwarf_Unsigned typeslength = 0; Dwarf_Unsigned i = 0; res = dwarf_gdbindex_culist_array(gindexptr, &length,&error); /* Example actions. */ if (res == DW_DLV_OK) { for(i = 0; i < length; ++i) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned culength = 0; res = dwarf_gdbindex_culist_entry(gindexptr, i,&cuoffset,&culength,&error); if (res == DW_DLV_OK) { /* Do something with cuoffset, culength */ } } } res = dwarf_gdbindex_types_culist_array(gindexptr, &typeslength,&error); if (res == DW_DLV_OK) { for(i = 0; i < typeslength; ++i) { Dwarf_Unsigned cuoffset = 0; Dwarf_Unsigned tuoffset = 0; Dwarf_Unsigned culength = 0; Dwarf_Unsigned type_signature = 0; res = dwarf_gdbindex_types_culist_entry(gindexptr, i,&cuoffset,&tuoffset,&type_signature,&error); if (res == DW_DLV_OK) { /* Do something with cuoffset etc. */ } } } dwarf_gdbindex_free(gindexptr); } } \fP .DE .in -2 .H 3 "dwarf_gdbindex_culist_array()" .DS int dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * list_length, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_culist_array()\fP takes as input valid Dwarf_Gdbindex pointer. .P While currently only DW_DLV_OK is returned one should test for DW_DLV_NO_ENTRY and DW_DLV_ERROR and do something sensible if either is returned. .P If successful, the function returns DW_DLV_OK and returns the number of entries in the culist through the\f(CWlist_length\fP pointer. .H 3 "dwarf_gdbindex_culist_entry()" .DS int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * cu_offset, Dwarf_Unsigned * cu_length, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_culist_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an index into the culist array. Valid indexes are 0 through \f(CWlist_length -1\fP . .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind and the error is indicated by the vale returned through the \f(CWerror\fP pointer. .P On success it returns DW_DLV_OK and returns the \f(CWcu_offset\fP (the section global offset of the CU in .debug_info)) and \f(CWcu_length\fP (the length of the CU in .debug_info) values through the pointers. .H 3 "dwarf_gdbindex_types_culist_array()" .DS int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*types_list_length*/, Dwarf_Error * /*error*/); .DE The function \f(CWdwarf_gdbindex_types_culist_array()\fP takes as input valid Dwarf_Gdbindex pointer. .P While currently only DW_DLV_OK is returned one should test for DW_DLV_NO_ENTRY and DW_DLV_ERROR and do something sensible if either is returned. .P If successful, the function returns DW_DLV_OK and returns the number of entries in the types culist through the\f(CWlist_length\fP .P .H 3 "dwarf_gdbindex_types_culist_entry()" .DS int dwarf_gdbindex_types_culist_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * cu_offset, Dwarf_Unsigned * tu_offset, Dwarf_Unsigned * type_signature, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_types_culist_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an index into the types culist array. Valid indexes are 0 through \f(CWtypes_list_length -1\fP . .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P On success it returns DW_DLV_OK and returns the \f(CWtu_offset\fP (the section global offset of the CU in .debug_types)) and \f(CWtu_length\fP (the length of the CU in .debug_types) values through the pointers. It also returns the type signature (a 64bit value) through the \f(CWtype_signature\fP pointer. .H 3 "dwarf_gdbindex_addressarea()" .DS int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/, Dwarf_Unsigned * /*addressarea_list_length*/, Dwarf_Error * /*error*/); .DE The function \f(CWdwarf_addressarea()\fP takes as input valid Dwarf_Gdbindex pointer and returns the length of the address area through \f(CWaddressarea_list_length\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the number of entries in the address area through the \f(CWaddressarea_list_length\fP pointer. .H 3 "dwarf_gdbindex_addressarea_entry()" .DS int dwarf_gdbindex_addressarea_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * low_address, Dwarf_Unsigned * high_address, Dwarf_Unsigned * cu_index, Dwarf_Error * error); .DE The function \f(CWdwarf_addressarea_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an index into the address area (valid indexes are zero through \f(CWaddressarea_list_length - 1\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWlow_address\fP \f(CWhigh_address\fP and \f(CWcu_index\fP through the pointers. .P Given an open Dwarf_Gdbindex one uses the function as follows: .P .DS .FG "Examplewgdbindex dwarf_gdbindex_addressarea()" \f(CW void examplewgdbindex(Dwarf_Gdbindex gdbindex) { Dwarf_Unsigned list_len = 0; Dwarf_Unsigned i = 0; int res = 0; Dwarf_Error err = 0; res = dwarf_gdbindex_addressarea(gdbindex, &list_len,&err); if (res != DW_DLV_OK) { /* Something wrong, ignore the addressarea */ } /* Iterate through the address area. */ for( i = 0; i < list_len; i++) { Dwarf_Unsigned lowpc = 0; Dwarf_Unsigned highpc = 0; Dwarf_Unsigned cu_index = 0; res = dwarf_gdbindex_addressarea_entry(gdbindex,i, &lowpc,&highpc, &cu_index, &err); if (res != DW_DLV_OK) { /* Something wrong, ignore the addressarea */ return; } /* We have a valid address area entry, do something with it. */ } } \fP .DE .H 3 "dwarf_gdbindex_symboltable_array()" .DS int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned * symtab_list_length, Dwarf_Error * error); .DE One can look at the symboltable as a two-level table (with The outer level indexes through symbol names and the inner level indexes through all the compilation units that define that symbol (each symbol having a different number of compilation units, this is not a simple rectangular table). .P The function \f(CWdwarf_gdbindex_symboltable_array()\fP takes as input valid Dwarf_Gdbindex pointer. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWsymtab_list_length\fP through the pointer. .P Given a valid Dwarf_Gdbindex pointer, one can access the entire symbol table as follows (using 'return' here to indicate we are giving up due to a problem while keeping the example code fairly short): .DS .FG "Examplex dwarf_gdbindex_symboltable_array()" \f(CW void examplex(Dwarf_Gdbindex gdbindex) { Dwarf_Unsigned symtab_list_length = 0; Dwarf_Unsigned i = 0; Dwarf_Error err = 0; int res = 0; res = dwarf_gdbindex_symboltable_array(gdbindex, &symtab_list_length,&err); if (res != DW_DLV_OK) { return; } for( i = 0; i < symtab_list_length; i++) { Dwarf_Unsigned symnameoffset = 0; Dwarf_Unsigned cuvecoffset = 0; Dwarf_Unsigned cuvec_len = 0; Dwarf_Unsigned ii = 0; const char *name = 0; res = dwarf_gdbindex_symboltable_entry(gdbindex,i, &symnameoffset,&cuvecoffset, &err); if (res != DW_DLV_OK) { return; } res = dwarf_gdbindex_string_by_offset(gdbindex, symnameoffset,&name,&err); if(res != DW_DLV_OK) { return; } res = dwarf_gdbindex_cuvector_length(gdbindex, cuvecoffset,&cuvec_len,&err); if( res != DW_DLV_OK) { return; } for(ii = 0; ii < cuvec_len; ++ii ) { Dwarf_Unsigned attributes = 0; Dwarf_Unsigned cu_index = 0; Dwarf_Unsigned reserved1 = 0; Dwarf_Unsigned symbol_kind = 0; Dwarf_Unsigned is_static = 0; res = dwarf_gdbindex_cuvector_inner_attributes( gdbindex,cuvecoffset,ii, &attributes,&err); if( res != DW_DLV_OK) { return; } /* 'attributes' is a value with various internal fields so we expand the fields. */ res = dwarf_gdbindex_cuvector_instance_expand_value(gdbindex, attributes, &cu_index,&reserved1,&symbol_kind, &is_static, &err); if( res != DW_DLV_OK) { return; } /* Do something with the attributes. */ } } } \fP .DE .H 3 "dwarf_gdbindex_symboltable_entry()" .DS int dwarf_gdbindex_symboltable_entry( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned entryindex, Dwarf_Unsigned * string_offset, Dwarf_Unsigned * cu_vector_offset, Dwarf_Error * error); .DE .P The function \f(CWdwarf_gdbindex_symboltable_entry()\fP takes as input valid Dwarf_Gdbindex pointer and an entry index(valid index values being zero through \f(CWsymtab_list_length -1\fP). .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWstring_offset\fP and \f(CWcu_vector_offset\fP through the pointers. See the example above which uses this function. .H 3 "dwarf_gdbindex_cuvector_length()" .DS int dwarf_gdbindex_cuvector_length( Dwarf_Gdbindex gdbindex, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned * innercount, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_cuvector_length()\fP takes as input valid Dwarf_Gdbindex pointer and an a cu vector offset. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the \f(CWinner_count\fP through the pointer. The \f(CWinner_count\fP is the number of compilation unit vectors for this array of vectors. See the example above which uses this function. .H 3 "dwarf_gdbindex_cuvector_inner_attributes()" .DS int dwarf_gdbindex_cuvector_inner_attributes( Dwarf_Gdbindex gdbindex, Dwarf_Unsigned cuvector_offset, Dwarf_Unsigned innerindex, /* The attr_value is a field of bits. For expanded version use dwarf_gdbindex_cuvector_expand_value() */ Dwarf_Unsigned * attr_value, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_cuvector_inner_attributes()\fP takes as input valid Dwarf_Gdbindex pointer and an a cu vector offset and a \f(CWinner_index\fP (valid \f(CWinner_index\fP values are zero through \f(CWinner_count - 1\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns The \f(CWattr_value\fP through the pointer. The \f(CWattr_value\fP is actually composed of several fields, see the next function which expands the value. See the example above which uses this function. .H 3 "dwarf_gdbindex_cuvector_instance_expand_value()" .DS int dwarf_gdbindex_cuvector_instance_expand_value( Dwarf_Gdbindex gdbindex, Dwarf_Unsigned attr_value, Dwarf_Unsigned * cu_index, Dwarf_Unsigned * reserved1, Dwarf_Unsigned * symbol_kind, Dwarf_Unsigned * is_static, Dwarf_Error * error); .DE The function \f(CWdwarf_gdbindex_cuvector_instance_expand_value()\fP takes as input valid Dwarf_Gdbindex pointer and an \f(CWattr_value\fP. .P If it returns DW_DLV_NO_ENTRY there is a coding error. If it returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the following values through the pointers: The \f(CWcu_index\fP field is the index in the applicable CU list of a compilation unit. For the purpose of indexing the CU list and the types CU list form a single array so the \f(CWcu_index\fP can be indicating either list. The \f(CWsymbol_kind\fP field is a small integer with the symbol kind( zero is reserved, one is a type, 2 is a variable or enum value, etc). The \f(CWreserved1\fP field should have the value zero and is the value of a bit field defined as reserved for future use. The \f(CWis_static\fP field is zero if the CU indexed is global and one if the CU indexed is static. See the example above which uses this function. .H 3 "dwarf_gdbindex_string_by_offset()" .DS \f(CWint dwarf_gdbindex_string_by_offset( Dwarf_Gdbindex gdbindexptr, Dwarf_Unsigned stringoffset, const char ** string_ptr, Dwarf_Error * error);\fP .DE The function \f(CWdwarf_gdbindex_string_by_offset()\fP takes as input valid Dwarf_Gdbindex pointer and a \f(CWstringoffset\fP If it returns \f(CWDW_DLV_NO_ENTRY\fP there is a coding error. If it returns \f(CWDW_DLV_ERROR\fP there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If it succeeds, the call returns a pointer to a string from the 'constant pool' through the \f(CWstring_ptr\fP. The string pointed to must never be free()d. .P See the example above which uses this function. .H 2 "GNU linking (.gnu_debuglink, .note.gnu.build-id) operations" This section deals with the way GNU tools allow creation of DWARF separated from the executable file involved. See https://sourceware.org/gdb/onlinedocs /gdb/Separate-Debug-Files.html for more information (the line break is just to make this url print nicely, there is no space). The function here is new in September 2019, revised in October 2019. An example of use follows the description of arguments. .H 3 "dwarf_gnu_debuglink()" .DS \f(CWint dwarf_gnu_debuglink(Dwarf_Debug dbg, char **debuglink_path_returned, unsigned char **crc_returned, char **debuglink_fullpath_returned, unsigned *buildid_type returned, char **builid_returned, unsigned *builid_length_returned, char ***paths_returned, unsigned *paths_count_returned, Dwarf_Error* error);\fP .DE This returns \f(CWDW_DLV_NO_ENTRY\fP if there is neither a \f(CW.gnu_debuglink\fP object-file section nor a \f(CW.note.gnu.build-id\fP section in the object file. .P If there is an error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CW*error\fP to point to the error value. .P On success it returns \f(CWDW_DLV_OK\fP and sets the fields through the pointers as described below. Two fields must be free()d to avoid a memory leak. None of the other fields should be freed. .P If there is a \f(CW.gnu_debuglink\fP section the first four fields will be set. .P \f(CW*debuglink_path_returned\fP points to the null-terminated string in the section. It must not be free()d. .P \f(CW*crc_returned\fP points to a 4-byte CRC value. The bytes pointed to are not a string. .P \f(CW*debuglink_fullpath_returned\fP points to a full pathname derived from the \f(CW*debuglink_fullpath_returned\fP string. And then \f(CW*debuglink_fullpath_strlen\fP is set to the length of \f(CW*debuglink_fullpath_returned\fP just as \f(CWstrlen()\fP would count the length. Callers must free() \f(CW*debuglink_fullpath_returned\fP. .P If there is a \f(CW.note.gnu.build-id\fP section the buildid fields will be set through the pointers. .P \f(CW*buildid_type_returned\fP will be set to the value 3. .P \f(CW*buildid_owner_name_returned\fP will be set to point to the null-terminated string which will be "GNU". Do not free() this. .P \f(CW*buildid_returned\fP will be set to point to the group of bytes of length \f(CW*buildid_length_returned\fP. This is not a string and is not null-terminated. It is normally a 20-byte field to be used in its ascii-hex form. Do not free() this. .P If \f(CW*paths_returned\fP is passed as NULL then no paths calculation will be made and \f(CW*paths_count_returned\fP is not referenced by libdwarf. .P If \f(CW*paths_returned\fP is passed in non-NULL then \f(CW*paths_returned\fP and \f(CW*paths_count_returned\fP provide an array of pointers-to-strings (with the actual strings following the array) and the count of the pointers in the array. When the strings are no longer needed free() \f(CW*paths_returned\fP. The number of paths returned will depend on which (of the two) sections exist and on how many global paths have been set by \f(CWdwarf_add_debuglink_global_path()\fP. and defined by the rules described in the web page mentioned above. The default global path is "/usr/lib/debug" and that is set by libdwarf as \f(CWpaths_returned[0]\fP. .P An example of calling this function follows .DS .FG "Exampley dwarf_get_xu_index_header()" \f(CWvoid exampledebuglink(Dwarf_Debug dbg) { int res = 0; char *debuglink_path = 0; unsigned char *crc = 0; char *debuglink_fullpath = 0; unsigned debuglink_fullpath_strlen = 0; unsigned buildid_type = 0; char * buildidowner_name = 0; unsigned char *buildid_itself = 0; unsigned buildid_length = 0; char ** paths = 0; unsigned paths_count = 0; Dwarf_Error error = 0; unsigned i = 0; /* This is just an example if one knows of another place full-DWARF objects may be. "/usr/lib/debug" is automatically set. */ res = dwarf_add_debuglink_global_path(dbg, "/some/path/debug",&error); if (res != DW_DLV_OK) { /* Something is wrong, but we'll ignore that. */ } res = dwarf_gnu_debuglink(dbg, &debuglink_path, &crc, &debuglink_fullpath, &debuglink_fullpath_strlen, &buildid_type, &buildidowner_name, &buildid_itself, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { /* Do something with the error */ return; } if (res == DW_DLV_NO_ENTRY) { /* No such sections as .note.gnu.build-id or .gnu_debuglink */ return; } if (debuglink_fullpath_strlen) { printf("debuglink path: %s\\n",debuglink_path); printf("crc length : %u crc: ",4); for (i = 0; i < 4;++i ) { printf("%02x",crc[i]); } printf("\\n"); printf("debuglink fullpath: %s\\n",debuglink_fullpath); } if(buildid_length) { printf("buildid type : %u\\n",buildid_type); printf("Buildid owner : %s\\n",buildidowner_name); printf("buildid byte count: %u\\n",buildid_length); printf(" "); /* buildid_length should be 20. */ for (i = 0; i < buildid_length;++i) { printf("%02x",buildid_itself[i]); } printf("\\n"); } printf("Possible paths count %u\\n",paths_count); for ( ; i < paths_count; ++i ){ printf("%2u: %s\\n",i,paths[i]); } free(debuglink_fullpath); free(paths); return; } \fP .DE .H 3 "dwarf_add_debuglink_global_path()" .DS \f(CWint dwarf_add_debuglink_global_path(Dwarf_Debug dbg, const char * path, Dwarf_Error* error);\fP .DE This is unlikely to return \f(CWDW_DLV_ERROR\fP unless one passes in a NULL instead of an open \f(CWDwarf_Debug\fP. It cannot return \f(CWDW_DLV_NO_ENTRY\fP. .P On success it returns \f(CWDW_DLV_OK\fP after adding the path to the global list recorded in the \f(CWDwarf_Debug\fP. .H 2 "Debug Fission (.debug_tu_index, .debug_cu_index) operations" We name things "xu" as these sections have the same format so we let "x" stand for either section. The DWARF5 standard refers to Split Dwarf while libdwarf tends to refer to this as "Fission". .P These functions get access to the index functions needed to access and print the contents of an object file which is an aggregate of .dwo objects. These sections are implemented in gcc/gdb and are DWARF5. The idea is that much debug information can be separated off into individual .dwo Elf objects and then aggregated simply into a single .dwp object so the executable need not have the complete debug information in it at runtime yet allow good debugging. .P For additional information, see "https://gcc.gnu.org/wiki/DebugFissionDWP", "https://gcc.gnu.org/wiki/DebugFission", and "http://www.bayarea.net/~cary/dwarf/Accelerated%20Access%20Diagram.png" and as of 17 February 2017, the DWARF5 standard. .P There are FORM access functions related to Debug Fission (Split Dwarf). See \f(CWdwarf_formaddr()\fP and \f(CWdwarf_get_debug_addr_index()\fP and \f(CWdwarf_get_debug_str_index()\fP. .P The FORM with the hash value (for a reference to a type unit ) is \f(CWDW_FORM_ref_sig8\fP. .P In a compilation unit of Debug Fission object (or a .dwp Package FIle) \f(CWDW_AT_dwo_id\fP the hash is expected to be \f(CWDW_FORM_data8\fP. .P The \f(CWDWARF5\fP standard defines the hash as an 8 byte value which we could use \f(CWDwarf_Unsigned\fP. Instead (and mostly for type safety) we define the value as a structure whose type name is \f(CWDwarf_Sig8\fP. .P To look up a name in the hash (to find which CU(s) it exists in). use \f(CWdwarf_get_debugfission_for_key()fP, defined below. .P The second group of interfaces here beginning with \f(CWdwarf_get_xu_index_header()\fP are useful if one wants to print a .debug_tu_index or .debug_cu_index section. .P To access DIE, macro, etc information the support is built into DIE, Macro, etc operations so applications usually won't need to use these operations at all. .H 3 "Dwarf_Debug_Fission_Per_CU" .DS #define DW_FISSION_SECT_COUNT 12 struct Dwarf_Debug_Fission_Per_CU_s { /* Do not free the string. It contains "cu" or "tu". */ /* If this is not set (ie, not a CU/TU in DWP Package File) then pcu_type will be NULL. */ const char * pcu_type; /* pcu_index is the index (range 1 to N ) into the tu/cu table of offsets and the table of sizes. 1 to N as the zero index is reserved for special purposes. Not a value one actually needs. */ Dwarf_Unsigned pcu_index; Dwarf_Sig8 pcu_hash; /* 8 byte */ /* [0] has offset and size 0. [1]-[8] are DW_SECT_* indexes and the values are the offset and size of the respective section contribution of a single .dwo object. When pcu_size[n] is zero the corresponding section is not present. */ Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT]; Dwarf_Unsigned unused1; Dwarf_Unsigned unused2; }; .DE .P The structure is used to return data to callers with the data from either .debug_tu_index or .debug_cu_index that is applicable to a single compilation unit or type unit. .P Callers to the applicable functions (see below) should allocate the structure and zero all the bytes in it. The structure has a few fields that are presently unused. These are reserved for future use since it is impossible to alter the structure without breaking binary compatibility. .H 3 "dwarf_die_from_hash_signature()" .DS int dwarf_die_from_hash_signature(Dwarf_Debug dbg, Dwarf_Sig8 * hash_sig, const char * sig_type, Dwarf_Die* returned_die, Dwarf_Error* error); .DE The function \f(CWdwarf_die_from_hash_signature()\fP is the most direct way to go from the hash data from a \f(CWDW_FORM_ref_sig8\fP or a \f(CWDW_AT_dwo_id\fP (form \f(CWDW_FORM_data8\fP) to a DIE from a .dwp package file or a .dwo object file ( .dwo access not supported yet). .P The caller passes in \f(CWdbg\fP which should be \f(CWDwarf_Debug\fP open/initialized on a .dwp package file (or a .dwo object file). .P The caller also passes in \f(CWhash_sig\fP, a pointer to the hash signature for which the caller wishes to find a DIE. .P The caller also passes in \f(CWsig_type\fP which must contain either "tu" (identifying the hash referring to a type unit) or "cu" (identifying the hash as referring to a compilation unit). .P On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CW*returned_die\fP to be a pointer to a valid DIE for the compilation unit or type unit. If the type is "tu" the DIE returned is the specific type DIE that the hash refers to. If the type is "cu" the DIE returned is the compilation unit DIE of the compilation unit referred to. .P When appropriate the caller should free the space of the returned DIE by a call something like .DS dwarf_dealloc(dbg,die,DW_DLA_DIE); .DE .P If there is no DWP Package File section or the hash cannot be found the function returns \f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CWreturned_die\fP untouched. Only .dwo objects and .dwp package files have the package file index sections. .P If there is an error of some sort the function returns \f(CWDW_DLV_ERROR\fP, leaves \f(CWreturned_die\fP untouched, and sets \f(CW*error\fP to indicate the precise error encountered. .P .H 3 "dwarf_get_debugfission_for_die()" .DS int dwarf_get_debugfission_for_die(Dwarf_Die die, Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error * error); .DE The function \f(CWdwarf_get_debugfission_for_die()\fP returns the debug fission for the compilation unit the DIE is a part of. Any DIE in the compilation (or type) unit will get the same result. .P On a call to this function ensure the pointed-to space is fully initialized. .P On success the function returns \f(CWDW_DLV_OK\fP and fills in the fields of \f(CW*percu_out\fP for which it has data. .P If there is no DWP Package File section the function returns \f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CW*percu_out\fP untouched. Only .dwp package files have the package file index sections. .P If there is an error of some sort the function returns \f(CWDW_DLV_ERROR\fP, leaves \f(CW*percu_out\fP untouched, and sets \f(CW*error\fP to indicate the precise error encountered. .H 3 "dwarf_get_debugfission_for_key()" .DS int dwarf_get_debugfission_for_key(Dwarf_Debug dbg, Dwarf_Sig8 * key, const char * key_type , Dwarf_Debug_Fission_Per_CU * percu_out, Dwarf_Error * error); .DE The function \f(CWdwarf_get_debugfission_for_key()\fP returns the debug fission data for the compilation unit in a .dwp package file. .P If there is no DWP Package File section the function returns \f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CW*percu_out\fP untouched. Only .dwp package files have the package file index sections. .P If there is an error of some sort the function returns \f(CWDW_DLV_ERROR\fP, leaves \f(CW*percu_out\fP untouched, and sets \f(CW*error\fP to indicate the precise error encountered. .H 3 "dwarf_get_xu_index_header()" .DS int dwarf_get_xu_index_header(Dwarf_Debug dbg, const char * section_type, /* "tu" or "cu" */ Dwarf_Xu_Index_Header * xuhdr, Dwarf_Unsigned * version_number, Dwarf_Unsigned * offsets_count /* L*/, Dwarf_Unsigned * units_count /* N*/, Dwarf_Unsigned * hash_slots_count /* M*/, const char ** sect_name, Dwarf_Error * err); .DE The function \f(CWdwarf_get_xu_index_header()\fP takes as input a valid Dwarf_Debug pointer and an \f(CWsection_type\fP value, which must one of the strings \f(CWtu\fP or \f(CWcu\fP. .P It returns DW_DLV_NO_ENTRY if the section requested is not in the object file. .P It returns DW_DLV_ERROR there is an error of some kind. and the error is indicated by the value returned through the \f(CWerror\fP pointer. .P If successful, the function returns DW_DLV_OK and returns the following values through the pointers: .P The \f(CWxuhdr\fP field is a pointer usable in other operations (see below). .P The \f(CWversion_number\fP field is a the index version number. For gcc before DWARF5 the version number is 2. For DWARF5 the version number is 5. .P The \f(CWoffsets_count\fP field is a the number of columns in the table of section offsets. Sometimes known as \f(CWL\fP. .P The \f(CWunits_count\fP field is a the number of compilation units or type units in the index. Sometimes known as \f(CWN\fP. .P The \f(CWhash_slots_count\fP field is a the number of slots in the hash table. Sometimes known as \f(CWM\fP. .P The \f(CWsect_name\fP field is the name of the section in the object file. Because non-Elf objects may not use section names callers must recognize that the sect_name may be set to NULL (zero) or to point to the empty string and this is not considered an error. .P An example of initializing and disposing of a \f(CWDwarf_Xu_Index_Header\fP follows. .DS .FG "Exampley dwarf_get_xu_index_header()" \f(CW void exampley(Dwarf_Debug dbg, const char *type) { /* type is "tu" or "cu" */ int res = 0; Dwarf_Xu_Index_Header xuhdr = 0; Dwarf_Unsigned version_number = 0; Dwarf_Unsigned offsets_count = 0; /*L */ Dwarf_Unsigned units_count = 0; /* M */ Dwarf_Unsigned hash_slots_count = 0; /* N */ Dwarf_Error err = 0; const char * ret_type = 0; const char * section_name = 0; res = dwarf_get_xu_index_header(dbg, type, &xuhdr, &version_number, &offsets_count, &units_count, &hash_slots_count, §ion_name, &err); if (res == DW_DLV_NO_ENTRY) { /* No such section. */ return; } if (res == DW_DLV_ERROR) { /* Something wrong. */ return; } /* Do something with the xuhdr here . */ dwarf_xu_header_free(xuhdr); } \fP .DE .H 3 "dwarf_get_xu_index_section_type()" .DS int dwarf_get_xu_index_section_type( Dwarf_Xu_Index_Header xuhdr, const char ** typename, const char ** sectionname, Dwarf_Error * error); .DE The function \f(CWdwarf_get_xu_section_type()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP. It is only useful when one already as an open \f(CWxuhdr\fP but one does not know if this is a type unit or compilation unit index section. .P If it returns DW_DLV_NO_ENTRY something is wrong (should never happen). If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWtypename\fP is set to the string \f(CWtu\fP or \f(CWcu\fP to indcate the index is of a type unit or a compilation unit, respectively. .P \f(CWsectionname\fP is set to name of the object file section. Because non-Elf objects may not use section names callers must recognize that the sect_name may be set to NULL (zero) or to point to the empty string and this is not considered an error. .P Neither string should be free()d. .H 3 "dwarf_get_xu_header_free()" .DS void dwarf_xu_header_free(Dwarf_Xu_Index_Header xuhdr); .DE The function \f(CWdwarf_get_xu_header_free()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and frees all the special data allocated for this access type. Once called, any pointers returned by use of the \f(CWxuhdr\fP should be considered stale and unusable. .H 3 "dwarf_get_xu_hash_entry()" .DS int dwarf_get_xu_hash_entry( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned index, Dwarf_Sig8 * hash_value, Dwarf_Unsigned * index_to_sections, Dwarf_Error * error); .DE The function \f(CWdwarf_get_xu_hash_entry()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and an \f(CWindex\fP of a hash slot entry (valid hash slot index values are zero (0) through \f(CWhash_slots_count -1\fP (M-1)). .P If it returns DW_DLV_NO_ENTRY something is wrong .P If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWhash_value\fP is set to the 64bit hash of of the symbol name. .P \f(CWindex_to_sections\fP is set to the index into offset-size tables of this hash entry. .P If both \f(CWhash_value\fP and \f(CWindex_to_sections\fP are zero (0) then the hash slot is unused. \f(CWindex_to_sections\fP is used in calls to the function \f(CWdwarf_get_xu_section_offset()\fP as the \f(CWrow_index\fP. .P An example of use follows. .DS .FG "Examplez dwarf_get_xu_hash_entry()" \f(CW void examplez( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned hash_slots_count) { /* hash_slots_count returned by dwarf_get_xu_index_header(), see above. */ static Dwarf_Sig8 zerohashval; Dwarf_Error err = 0; Dwarf_Unsigned h = 0; for( h = 0; h < hash_slots_count; h++) { Dwarf_Sig8 hashval; Dwarf_Unsigned index = 0; Dwarf_Unsigned col = 0; int res = 0; res = dwarf_get_xu_hash_entry(xuhdr,h, &hashval,&index,&err); if (res == DW_DLV_ERROR) { /* Oops. hash_slots_count wrong. */ return; } else if (res == DW_DLV_NO_ENTRY) { /* Impossible */ return; } else if (!memcmp(&hashval,&zerohashval, sizeof(Dwarf_Sig8)) && index == 0 ) { /* An unused hash slot */ continue; } /* Here, hashval and index (a row index into offsets and lengths) are valid. */ } } \fP .DE .H 3 "dwarf_get_xu_section_names()" .DS int dwarf_get_xu_section_names( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned column_index, Dwarf_Unsigned* number, const char ** name, Dwarf_Error * err); .DE The function \f(CWdwarf_get_xu_section_names()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and a \f(CWcolumn_index\fP of a hash slot entry (valid column_index values are zero (0) through \f(CWoffsets_count -1\fP (L-1)). .P If it returns DW_DLV_NO_ENTRY something is wrong .P If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWnumber\fP is set to a number identifying which section this column applies to. For example, if the value is \f(CWDW_SECT_INFO\fP (1) the column came from a .debug_info.dwo section. See the table of \f(CWDW_SECT_\fP identifiers and asigned numbers in DWARF5. .P \f(CWname\fP is set to the applicable spelling of the section identifier, for example \f(CWDW_SECT_INFO\fP. .H 3 "dwarf_get_xu_section_offset()" .DS int dwarf_get_xu_section_offset( Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned row_index, Dwarf_Unsigned column_index, Dwarf_Unsigned* sec_offset, Dwarf_Unsigned* sec_size, Dwarf_Error * error); .DE The function \f(CWdwarf_get_xu_section_offset()\fP takes as input a valid \f(CWDwarf_Xu_Index_Header\fP and a \f(CWrow_index\fP (see \f(CWdwarf_get_xu_hash_entry()\fP above) and a \f(CWcolumn_index\fP. Valid row_index values are one (1) through \f(CWunits_count\fP (N) but one uses \f(CWdwarf_get_xu_hash_entry()\fP (above) to get row index. Valid column_index values are zero (0) through \f(CWoffsets_count -1\fP (L-1). .P If it returns DW_DLV_NO_ENTRY something is wrong. .P If it returns DW_DLV_ERROR something is wrong and the \f(CWerror\fP field is set to indicate a specific error. .P If successful, the function returns DW_DLV_OK and sets the following arguments through the pointers: .P \f(CWsec_offset\fP, (\f(CWbase offset\fP) is set to the base offset of the initial compilation-unit-header section taken from a .dwo object. The base offset is the data from a single section of a .dwo object. .P \f(CWsec_size\fP is set to the length of the original section taken from a .dwo object. This is the length in the applicable section in the .dwp over which the base offset applies. .P An example of use of \f(CWdwarf_get_xu_section_names()\fP and \f(CWdwarf_get_xu_section_offset()\fP follows. .DS .FG "Exampleza dwarf_get_xu_section_names()" \f(CW void exampleza(Dwarf_Xu_Index_Header xuhdr, Dwarf_Unsigned offsets_count, Dwarf_Unsigned index ) { Dwarf_Error err = 0; Dwarf_Unsigned col = 0; /* We use 'offsets_count' returned by a dwarf_get_xu_index_header() call. We use 'index' returned by a dwarf_get_xu_hash_entry() call. */ for (col = 0; col < offsets_count; col++) { Dwarf_Unsigned off = 0; Dwarf_Unsigned len = 0; const char * name = 0; Dwarf_Unsigned num = 0; int res = 0; res = dwarf_get_xu_section_names(xuhdr, col,&num,&name,&err); if (res != DW_DLV_OK) { break; } res = dwarf_get_xu_section_offset(xuhdr, index,col,&off,&len,&err); if (res != DW_DLV_OK) { break; } /* Here we have the DW_SECT_ name and number and the base offset and length of the section data applicable to the hash that got us here. Use the values.*/ } } .DE .H 2 "TAG ATTR etc names as strings" These functions turn a value into a string. So applications wanting the string "DW_TAG_compile_unit" given the value 0x11 (the value defined for this TAG) can do so easily. The general form is .in +2 .DS \f(CWint dwarf_get__name( unsigned value, char **s_out, );\fP .DE .in -2 If the \f(CWvalue\fP passed in is known, the function returns \f(CWDW_DLV_OK\fP and places a pointer to the appropriate string into \f(CW*s_out\fP. The string is in static storage and applications must never free the string. If the \f(CWvalue\fP is not known, \f(CWDW_DLV_NO_ENTRY\fP is returned and \f(CW*s_out\fP is not set. \f(CWDW_DLV_ERROR\fP is never returned. \f(CWLibdwarf\fP generates these functions at libdwarf build time by reading dwarf.h. All these follow this pattern rigidly, so the details of each are not repeated for each function. The choice of 'unsigned' for the value type argument (the code value) argument is somewhat arbitrary, 'int' could have been used. The library simply assumes the value passed in is applicable. So, for example, passing a TAG value code to \f(CWdwarf_get_ACCESS_name()\fP is a coding error which libdwarf will process as if it was an accessibility code value. Examples of bad and good usage are: .in +2 .DS .FG "Examplezb dwarf_get_TAG_name()" \f(CW void examplezb(void) { const char * out = 0; int res = 0; /* The following is wrong, do not do it! */ res = dwarf_get_ACCESS_name(DW_TAG_entry_point,&out); /* Nothing one does here with 'res' or 'out' is meaningful. */ /* The following is meaningful.*/ res = dwarf_get_TAG_name(DW_TAG_entry_point,&out); if( res == DW_DLV_OK) { /* Here 'out' is a pointer one can use which points to the string "DW_TAG_entry_point". */ } else { /* Here 'out' has not been touched, it is uninitialized. Do not use it. */ } } \fP .DE .in -2 .H 3 "dwarf_get_ACCESS_name()" Returns an accessibility code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_AT_name()" Returns an attribute code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_ATE_name()" Returns a base type encoding name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_ADDR_name()" Returns an address type encoding name through the \f(CWs_out\fP pointer. As of this writing only \f(CWDW_ADDR_none\fP is defined in \f(CWdwarf.h\fP. .H 3 "dwarf_get_ATCF_name()" Returns a SUN code flag encoding name through the \f(CWs_out\fP pointer. This code flag is entirely a DWARF extension. .H 3 "dwarf_get_CHILDREN_name()" Returns a child determination name (which is seen in the abbreviations section data) through the \f(CWs_out\fP pointer. The only value this recognizes for a 'yes' value is 1. As a flag value this is not quite correct (any non-zero value means yes) but dealing with this is left up to client code (normally compilers really do emit a value of 1 for a flag). .H 3 "dwarf_get_children_name()" Returns a child determination name through the \f(CWs_out\fP pointer, though this version is really a libdwarf artifact. The standard function is \f(CWdwarf_get_CHILDREN_name()\fP which appears just above. As a flag value this is not quite correct (any non-zero value means yes) but dealing with this is left up to client code (normally compilers really do emit a value of 1 for a flag). .H 3 "dwarf_get_CC_name()" Returns a calling convention case code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_CFA_name()" Returns a call frame information instruction name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_DS_name()" Returns a decimal sign code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_DSC_name()" Returns a discriminant descriptor code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_EH_name()" Returns a GNU exception header code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_END_name()" Returns an endian code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_FORM_name()" Returns an form code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_FRAME_name()" Returns a frame code name through the \f(CWs_out\fP pointer. These are dependent on the particular ABI, so unless the \f(CWdwarf.h\fP used to generate libdwarf matches your ABI these names are unlikely to be very useful and certainly won't be entirely appropriate. .H 3 "dwarf_get_ID_name()" Returns an identifier case code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_INL_name()" Returns an inline code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LANG_name()" Returns a language code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LLE_name()" Returns a split-dwarf loclist code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LNE_name()" Returns a line table extended opcode code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_LNS_name()" Returns a line table standard opcode code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_MACINFO_name()" Returns a macro information macinfo code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_MACRO_name()" Returns a DWARF5 macro information macro code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_OP_name()" Returns a DWARF expression operation code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_ORD_name()" Returns an array ordering code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_TAG_name()" Returns a TAG name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_VIRTUALITY_name()" Returns a virtuality code name through the \f(CWs_out\fP pointer. .H 3 "dwarf_get_VIS_name()" Returns a visibility code name through the \f(CWs_out\fP pointer. .H 2 "Section Operations" In checking DWARF in linkonce sections for correctness it has been found useful to have certain section-oriented operations when processing object files. Normally these operations are not needed or useful in a fully-linked executable or shared library. While the code is written with Elf sections in mind, it is quite possible to process non-Elf objects with code that implements certain function pointers (see \f(CWstruct Dwarf_Obj_Access_interface_s\fP). So far no one with such non-elf code has come forward to open-source it. .H 3 "dwarf_get_section_count()" .DS \f(CWint dwarf_get_section_count( Dwarf_Debug dbg) \fP .DE .P Returns a count of the number of object sections found. .P If there is an incomplete or damaged dbg passed in this can return -1; .H 3 "dwarf_get_section_info_by_name()" .DS \f(CWint dwarf_get_section_info_by_name( const char *section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_section_info_by_name()\fP returns \f(CWDW_DLV_OK\fP if the section given by \f(CWsection_name\fP was seen by libdwarf. On success it sets \f(CW*section_addr\fP to the virtual address assigned to the section by the linker or compiler and \f(CW*section_size\fP to the size of the object section. It returns DW_DLV_ERROR on error. .H 3 "dwarf_get_section_info_by_index()" .DS \f(CWint dwarf_get_section_info_by_index( int section_index, const char **section_name, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_get_section_info_by_index()\fP returns \f(CWDW_DLV_OK\fP if the section given by \f(CWsection_index\fP was seen by libdwarf. \f(CW*section_addr\fP to the virtual address assigned to the section by the linker or compiler and \f(CW*section_size\fP to the size of the object section. No free or deallocate of information returned should be done by callers. .H 2 "Utility Operations" These functions aid in the management of errors encountered when using functions in the \fIlibdwarf\fP library and releasing memory allocated as a result of a \fIlibdwarf\fP operation. .P For clients that wish to encode LEB numbers two interfaces are provided to the producer code's internal LEB function. .H 3 "dwarf_errno()" .DS \f(CWDwarf_Unsigned dwarf_errno( Dwarf_Error error)\fP .DE The function \f(CWdwarf_errno()\fP returns the error number corresponding to the error specified by \f(CWerror\fP. .H 3 "dwarf_errmsg()" .DS \f(CWconst char* dwarf_errmsg( Dwarf_Error error)\fP .DE The function \f(CWdwarf_errmsg()\fP returns a pointer to a null-terminated error message string corresponding to the error specified by \f(CWerror\fP. The string should not be deallocated using \f(CWdwarf_dealloc()\fP. The string should be considered to be a temporary string. That is, the returned pointer may become stale if you do libdwarf calls on the \f(CWDwarf_Debug\fP instance other than \f(CWdwarf_errmsg()\fP or \f(CWdwarf_errno()\fP. So copy the errmsg string ( or print it) but do not depend on the pointer remaining valid past other libdwarf calls to the \f(CWDwarf_Debug\fP instance that detected an error. .H 3 "dwarf_errmsg_by_number()" .DS \f(CWconst char* dwarf_errmsg_by_number( Dwarf_Unside errcode)\fP .DE The function \f(CWdwarf_errmsg_by_number()\fP returns a pointer to a null-terminated error message string corresponding to the error number specified by \f(CWerrcode\fP. The string should not be deallocated or freed. If the \f(CWerrcode\fP is too large for the table of static error strings a string reflecting that fact is returned. .P For some places in the code a \f(CWDwarf_Error()\fP is inconvenient and this function lets dwarfdump report better information in those cases. Function new December 19, 2018. .H 3 "dwarf_get_endian_copy_function()" .DS \f(CWvoid (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/)) (void *, const void * /*src*/, unsigned long /*srclen*/)\fP .DE When reader client code wants to extract endian-dependent integers from dwarf and the existing interfaces won't do that (for example in printing frame instructions as done by dwarfdump) \f(CWdwarf_get_endian_copy_function\fP helps by returning the proper copy function needed, the one libdwarf itself uses. The client code needs a bit of glue to finish the job, as demonstrated by the ASNAR macro in dwarfdump/print_frames.c .P On success this returns a pointer to the correct copy function. .P On failure it returns the null pointer. It's up to the client code to decide how to deal with the situation. In no reasonable case will the null pointer be returned. .P New December 2018. .H 3 "dwarf_get_harmless_error_list()" .DS \f(CWint dwarf_get_harmless_error_list(Dwarf_Debug dbg, unsigned count, const char ** errmsg_ptrs_array, unsigned * newerr_count);\fP .DE The harmless errors are not denoted by error returns from the other libdwarf functions. Instead, this function returns strings of any harmless errors that have been seen in the current object. Clients never need call this, but if a client wishes to report any such errors it may call. Only a fixed number of harmless errors are recorded. It is a circular list, so if more than the current maximum is encountered older harmless error messages are lost. The caller passes in a pointer to an array of pointer-to-char as the argument \f(CWerrmsg_ptrs_array\fP. The caller must provide this array, libdwarf does not provide it. The caller need not initialize the array elements. The caller passes in the number of elements of the array of pointer-to-char thru \f(CWcount\fP. Since the If there are no unreported harmless errors the function returns \f(CWDW_DLV_NO_ENTRY\fP and the function arguments are ignored. Otherwise the function returns \f(CWDW_DLV_OK\fP and uses the arguments. \f(CWlibdwarf\fP assigns error strings to the errmsg_ptrs_array. The MININUM(count-1, number of messages recorded) pointers are assigned to the array. The array is terminated with a NULL pointer. (That is, one array entry is reserved for a NULL pointer). So if \f(CWcount\fP is 5 up to 4 strings may be returned through the array, and one array entry is set to NULL. Because the list is circular and messages may have been dropped the function also returns the actual error count of harmless errors encountered through \f(CWnewerr_count\fP (unless the argument is NULL, in which case it is ignored). Each call to this function resets the circular error buffer and the error count. So think of this call as reporting harmless errors since the last call to it. The pointers returned through \f(CWerrmsg_ptrs_array\fP are only valid till the next call to libdwarf. Do not save the pointers, they become invalid. Copy the strings if you wish to save them. Calling this function neither allocates any space in memory nor frees any space in memory. .H 3 "dwarf_insert_harmless_error()" .DS void dwarf_insert_harmless_error(Dwarf_Debug dbg, char * newerror); .DE This function is used to test \f(CWdwarf_get_harmless_error_list\fP. It simply adds a harmless error string. There is little reason client code should use this function. It exists so that the harmless error functions can be easily tested for correctness and leaks. .H 3 "dwarf_set_harmless_error_list_size()" .DS \f(CWunsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg, unsigned maxcount)\fP .DE \f(CWdwarf_set_harmless_error_list_size\fP returns the number of harmless error strings the library is currently set to hold. If \f(CWmaxcount\fP is non-zero the library changes the maximum it will record to be \f(CWmaxcount\fP. It is extremely unwise to make \f(CWmaxcount\fP large because \f(CWlibdwarf\fP allocates space for \f(CWmaxcount\fP strings immediately. .P The set of errors enumerated in Figure \n(aX below were defined in Dwarf 1. These errors are not used by the \f(CWlibdwarf\fP implementation for Dwarf 2 or later. .DS .TS center box, tab(:); lfB lfB l l. SYMBOLIC NAME:DESCRIPTION _ DW_DLE_NE:No error (0) DW_DLE_VMM:Version of DWARF information newer :than libdwarf DW_DLE_MAP:Memory map failure DW_DLE_LEE:Propagation of libelf error DW_DLE_NDS:No debug section DW_DLE_NLS:No line section DW_DLE_ID:Requested information not associated :with descriptor DW_DLE_IOF:I/O failure DW_DLE_MAF:Memory allocation failure DW_DLE_IA:Invalid argument DW_DLE_MDE:Mangled debugging entry DW_DLE_MLE:Mangled line number entry DW_DLE_FNO:File descriptor does not refer :to an open file DW_DLE_FNR:File is not a regular file DW_DLE_FWA:File is opened with wrong access DW_DLE_NOB:File is not an object file DW_DLE_MOF:Mangled object file header DW_DLE_EOLL:End of location list entries DW_DLE_NOLL:No location list section DW_DLE_BADOFF:Invalid offset DW_DLE_EOS:End of section DW_DLE_ATRUNC:Abbreviations section appears :truncated DW_DLE_BADBITC:Address size passed to :dwarf bad .TE .FG "Dwarf Error Codes" .DE The set of errors returned by \f(CWLibdwarf\fP functions is listed below. The list does lengthen: the ones listed here are far from a complete list. Some of the errors are SGI specific. See libdwarf/dwarf_errmsg_list.h for the complete list. .DS .TS center box, tab(:); lfB lfB l. SYMBOLIC NAME (description not shown here) _ DW_DLE_DBG_ALLOC DW_DLE_FSTAT_ERROR DW_DLE_FSTAT_MODE_ERROR DW_DLE_INIT_ACCESS_WRONG DW_DLE_ELF_BEGIN_ERROR DW_DLE_ELF_GETEHDR_ERROR DW_DLE_ELF_GETSHDR_ERROR DW_DLE_ELF_STRPTR_ERROR DW_DLE_DEBUG_INFO_DUPLICATE DW_DLE_DEBUG_INFO_NULL DW_DLE_DEBUG_ABBREV_DUPLICATE DW_DLE_DEBUG_ABBREV_NULL DW_DLE_DEBUG_ARANGES_DUPLICATE DW_DLE_DEBUG_ARANGES_NULL DW_DLE_DEBUG_LINE_DUPLICATE DW_DLE_DEBUG_LINE_NULL DW_DLE_DEBUG_LOC_DUPLICATE DW_DLE_DEBUG_LOC_NULL DW_DLE_DEBUG_MACINFO_DUPLICATE DW_DLE_DEBUG_MACINFO_NULL DW_DLE_DEBUG_PUBNAMES_DUPLICATE DW_DLE_DEBUG_PUBNAMES_NULL DW_DLE_DEBUG_STR_DUPLICATE DW_DLE_DEBUG_STR_NULL DW_DLE_CU_LENGTH_ERROR DW_DLE_VERSION_STAMP_ERROR DW_DLE_ABBREV_OFFSET_ERROR DW_DLE_ADDRESS_SIZE_ERROR DW_DLE_DEBUG_INFO_PTR_NULL DW_DLE_DIE_NULL DW_DLE_STRING_OFFSET_BAD DW_DLE_DEBUG_LINE_LENGTH_BAD DW_DLE_LINE_PROLOG_LENGTH_BAD DW_DLE_LINE_NUM_OPERANDS_BAD DW_DLE_LINE_SET_ADDR_ERROR .TE .FG "Dwarf 2 and later Error Codes" .DE This list of errors is not complete; additional errors have been added. Some of the above errors may be unused. Errors may not have the same meaning in different releases. Since most error codes are returned from only one place (or a very small number of places) in the source it is normally very useful to simply search the \f(CWlibdwarf\fP source to find out where a particular error code is generated. See \f(CWlibdwarf/dwarf_errmsg_list.h\fP for the complete message set with short descriptions. .H 3 "dwarf_dealloc()" .DS \f(CWvoid dwarf_dealloc( Dwarf_Debug dbg, void* space, Dwarf_Unsigned type)\fP .DE The function \f(CWdwarf_dealloc\fP frees the dynamic storage pointed to by \f(CWspace\fP, and allocated to the given \f(CWDwarf_Debug\fP. The argument \f(CWtype\fP is an integer code that specifies the allocation type of the region pointed to by the \f(CWspace\fP. Refer to section 4 for details on \fIlibdwarf\fP memory management. .H 3 "dwarf_encode_leb128()" .DS int dwarf_encode_leb128(Dwarf_Unsigned val, int * nbytes, char * space, int splen); .DE The function \f(CWdwarf_encode_leb128\fP encodes the value \f(CWval\fP in the caller-provided buffer that \f(CWspace\fP points to. The caller-provided buffer must be at least \f(CWsplen\fP bytes long. The function returns \f(CWDW_DLV_OK\fP if the encoding succeeds. If \f(CWsplen\fP is too small to encode the value, \f(CWDW_DLV_ERROR\fP will be returned. If the call succeeds, the number of bytes of \f(CWspace\fP that are used in the encoding are returned through the pointer \f(CWnbytes\fP .H 3 "dwarf_encode_signed_leb128()" .DS int dwarf_encode_signed_leb128(Dwarf_Signed val, int * nbytes, char * space, int splen); .DE The function \f(CWdwarf_encode_signed_leb128\fP is the same as \f(CWdwarf_encode_leb128\fP except that the argument \f(CWval\fP is signed. .SK .S .TC 1 1 4 .CS dwarfutils-20200114/libdwarf/libdwarf2.1.pdf000066400000000000000000020003341361531463500204420ustar00rootroot00000000000000%PDF-1.4 %쏢 5 0 obj <> stream xX]s8|ׯ@e+ !'od&^[Tʹ$R$~wF$f6̦?~&`ffYWgf{lཐ~_mff`2m,p]ϬXWF$v-<3Y3H¥`aD1$wl;/_Hg&HY4U-V՛8Q-%YN ePrW{p ɄC,gs?rBJz޺]"7p,Z}c!G"i>qf ΖV7'֟/ޮ?a fs' )нe K-KUZ5,.X X 2.|.|>1"]I2 cq>(B:QȆ^Wr6"i3R\-t-X$itr y\.[Lpk&$njG?x^W{ ׵mVlͦ1juڜ#޾.Bp_ހYXqدAI' z<w3̉ӴR-`+Ru"ޣ'Us`㽜%pM:`DЧ)㛷 + K8 qb}2Ȝhz'CsŠ,^ž-GH;ueXDl_ |X鱹I{kb = Kp*e-wm_CU mE^~`:RIzjZ.f]_.?|I;:4U~_pgPDZm;;h%x}ƍ8T0A1E >_>z83HaRa,͚5ʈYπv(5PBK$ 2+kڦ+nO Y5f=j"-F膹a11յ([#{Y\L9)t%B&.>Hgl?6:(^">gvև~ s]X;kułÙASS/$-uku"HS3p|'(kօThȫؑ3ts8,p`m!uhyhy:3\D <{*]Ow84e Ț}=5 (3=ݓULN*J!1W)AϖY3壻8ϕOSl~t$ n+weA.f{ڎ<)F#lsϙ h{/V;wO'ŧW3w@SU ?'zECN CF[Ad68t3&ıdOU3]4]w7oGP>H)jJ\}zw{k ='8qT7] `6Z-]]ܰ뻛Ϸӯ5è@]jtHh$ͭ||Å:zӖ#A+F/>8ͧO̷(Alua/􅄆 |ďL@'#e\9ɸhe2msuLLGf;EtC0٫q ü~nOCc\HiK{2YAJn5 Qx(endstream endobj 6 0 obj 2305 endobj 17 0 obj <> stream xY˒F+:沠x[ Ja& h<f#1ѐ@wuVVVVwc/~_p%#f!٦S)mv "g"|Dls\xk^n~2xx-#|Y./m ݱz:U]ٳ->~TS,/N*YNy~f^)vk˱P{[m{]y6oibݣ -3?˒ Ben~^d<2z_Mԏ"a?ݧO߭O$ekzUPM^:AB Df­.+K-yxbFY vcSXe?hVyFCmy!hss_=]$u۝NübC>\2]-8P'yY5{vqܕ*Ior(D؁t""9-b8 S~BKPVDТ= p0*@'[ՆVxא6E0N]{"m&\?A/4a"\B^E!OY랺TEUb1/;v(Y)N|DhL>ڶIAQ]MJad8IvM%12f@TydxT ]c ?Ef9R-|?{XHtyK}A?/CPT#ڽq;&<5)hLQ=4 :Sxjxyc~]^GC0ouԝ?\jTv)Bϼ3 NnBKa*m$|)utzP 50{ V=wyqŬߢ8;ahOHQ﨏R$ں*WkpgömmL8I JRݔwز 4 B؃n+J`ܐg1 }LGb{ؑXvڈu7/LW-(bjBAgӕ :y2ymNsp 9%ܴSڋfC&6^VpjݝXVX !Ϡǁua!Mϔ8S>] XϹkcܨ.XEnȽ~ؚ7xߙX1<:`"5ƫ`@huZ ƶ:˭=O%M?8GK7iNоAd6S, )+̔i5h5~N~M,[^pIEr+ I^6/.naCdf>pa\75 I,TRj!Y7.Ʈ\nmǣ`V}(!?P2BLۼ' tڹI?] ;똉55Hq90D0U-qzG-mIf6 ! f|bI&*`2Dc?LtF Aq> stream xY˖+:+9"4ɖ'y/fr@sPxϭ@ʲ}f13nj~~y!O&O :6V.B)02K(YE//dA]lV解.ͨxVUs(UeۊUSw(Z0WjaiZ2.7x݄Nek#ЏRM^@kl#x@Ya I4@߅%W✩7э  Ԩ.c?؟ke r3#lϘ s=V4@ :Ʊ ޯ:OtbTowI@R-vA֙F*QU#&ݴNtT.Gs}o__t%Z@J[fhU(g1"H՟Mk5_)Li %8F|odN u`"*z@9[uRݤm@#ACr<, lS!oM00teKjIS3,JSVwǑɼp $ڗ~%cb+b)ޱG|h[`v$[d]My`.blWGU=sx̆|rXʑ827lYӪbICw][*^jQ2?<,/rc6jfc#4Gͳ_XJމuziIƯ#g>Kti׮VE`ǹkzK*l)è:!v: :`)'4P8|gϤx!~Tr9b8#m󃇚Y$~(_"Q?!(V"ʙOWi^mbǮE=G{w;0C1oyzn:,^Op qm8\k|#&еɅi̊(<o AR6/>@C]sȍ6r2AiuSU<`oz Ͻ>?Y{J1%yozRs-D\I`XB-!԰ ^nSi&js[V=EDKZG+ѣK0rR26xۦSm`>J X:qdlk I}*mTCV#݋MiBH}Т3TNNzp΍Q>|EͮZキfTQfξ#S!Rm[v]a;Vef'euD(}oLjodd|@O5зL.#XSШ Ay7O;7s 0'Cꕦţz(턤#`tK}!"+CFܠ*Xmmՙz&{b04l Q(ԉy:1mA_Ftg^1AH$qh:pN^.<8H<3%Kq%#V–)L:@$7Ґ썮WRipxlYsVzSΈj]gHx˝F+C רu'ahp%# Kbt^DYd%7=T;_~By7չh#6$;̂YDUO+/Mf)53׬y5b?b\VB浘vg(9iF<|wZ$ccc5?UY?"{0ʡmeV4:$q# o b.0eva gf2\J~sK\dB}U12B$Kv1蹴Foj*FR @ 9W1;[AEd,uu@ Mvi.}f %Ĝo3=MX$Ȩ~{QB&0#칶b?qW?3E Bܣ%Q‰̗ʼn2Ӫ*R }@W K2'J̟oANcBn^ݰdXvVhVbri}ڰ20*d/Y]Br;X?1XWW?4K+ `EqԨVMWpBpJ_DZ*4QAL}дFF˽Wt>]`;Em:"E (2p ]$˟wY]4fhp'ѪJf2*驏sé>wQqZG{k?[hd F%/Un$֩ܟ:"ex#;un1tEC`麄UG뻝jjVJkvF*X=(}cẁى&`s\;tWL l;wU_mKbf!rwƄmN6n=R3Q~IHE+F3jk|Zϧf_Dv 8h ׺ ҩ r*{T}( _r}K)tݑ|uByz;ʃrdH2rS"S`jGFZFLaNV~KY%1sfN2Xv@.2RQendstream endobj 25 0 obj 3182 endobj 29 0 obj <> stream xYے}W̛5oJ$J.UJb4@&s,䂅_fl7,B[KfTdVLD~0˘e2eE7,^Fa0f_n"Xiᆕܨfۭ`GmٸW/}MˆWjtiKp~EQvj|3hҭ_vH.Ew505 iCyPlv]_ʁ5zs"qFf:'m:E Ԑ^ AiK~g}PeSgǾnhq" sWQ(}oCm6 nݕwl?w @4o^e[W.y";,2?e궦P՟˱Zk] i`{j+Z@6MEpdra3ѳM7ԏ֏lz| ًf3Y&a<쟘]P~.Aiy'Q[QAY)CҊð[VVCpQ`ǀS4LnUjS(-}yb$)E bʧLD!n3þo"2q+MlGms F0ɐҩ͹DoHMF8ugV3(Dú$tf? q&F ޗrv}yNHO5@d6syͺ},X+h1xY@q_^ Dȡ4bvC[1D2XHt̳.JD`K$XJ cuu(RB8I]9;\)2]8Yfh`vh:aè2< ­"T9,;P&] {ޠ.0 'Z,O"i2G4}xog̏&pM-M 0A::!<9LoЇ(oF@Nnm2t%Yf?ZWz@Nh3f!2uz't["'F9ED FB<7Ȓy!~]ReꑭUE2r_dRVtibUB1dt/uiۓVm]́lEn.P(YRrp@\qϡԺH$rWx=j]#X_ҬKyyNIp{r;ILe PyNt1hdj<;l j{cI 62˦ZHjpءh ^#C'EjFNO O h#^N.9WYM5Z}内2Q+ p8D@̠n-3]#"YBېUҶ;gMoB{6LB ke4goѩ6$<>`Zգ<| !$a?^Y1PHK-ICyK:@S}Ɉ Vu#gX(:  +?~y&h~L ɋs3mhmd @J-+mu] $ $Y+L@P^hgF]Ce2rnwKsą Iwm]}@SPGw'qQ_ך&#B4MAv.Qye/u Hh_#p곉L/gH9j0 +9I]n`RĮ0hlz0Pr_5,@3PYu{Oh$Q2qډ$l™Wzahd[뱴KBIU[Yd? V\U4F^$Iȣ0sOЕsd|h LqXO 虁GΰJP/ՙt&퀯=BC2}]wLU7KВDU@"֫>_T454r/n٨ iscl,M3?f՚ GӀ6Hg9!LW#)WF5$CҴ4]vP1w/2/som uhMu DOK@;OeM ~eǖS68crbE ]Q5jDgбS jDǖymSB+46.Czcp4-P 1.%h?W!rJeYќXԴt\DJ^~{#9{lXǠC%t0Xj9r$!5j!/hZOI~frX!0TxfpD~3mФ< r3 KK>ãYa:xw}" d)SfkUl(}EfrA-K;cN'jr?y_0Gendstream endobj 30 0 obj 3265 endobj 34 0 obj <> stream xYے6}W͜ d&J*Nv]JafKEQĄ"^,~n$5'[~ oO/E@G%*՟+/SŷU$6%NeBbsXUGPQ*6畷Nwq  /Go݅1Ir\4gWU~?ur}%yA DCkQ uH?3&qc^9tIcVa2s\2TyÎ5 V~$WՇ&s[u.\.cS(`bVcOUW0 ,J#(xo_~u7;M}c }%gp>yg!{2~@%؉5+?DZdPvDF|Z `ce {ge'q,ЗYx42` + K"+CL.>6E/ "i$ĀAa߫SR]q4%ul?y!J8GыLyuhVdy;NIK ,)π̆!JWͻy=z08p/~[vxhQT4ZuE3ݳSgR"CgT7L%Ų۲ е--Yܸlթ{Qp)|I.78Qz ;-OL-#4K Fa4@R{z_рnL>z( Mjw!Lz^)mZ 2$j_xU r g(r~" /e1۳qrR\H1ݑO ۳66~M>h04E-6֏K 9B)SRcP(ob{tA b4?.0赁:C7yS l_ȥ_:Mՙ_tV,UV-٫.ҩՎD{0ފSx!5W"V5J_ٴpXtJt${^e*p%؂qcSsiV5=5f\| o8{*/sel p7B=R.bwH -OsDŞjk13|V06ASݸ82=[b Y잙Yhи1S(CMd^&>sIBFb1~Nt2, 2a,n0>#k =#WÉvD/EIʋ2|oj R)"wQXLp~@+ 4'Or[B,X$3LwwP*3ɜq>~@e~~481W~F>oɼ Ўf?̨)b ;(([7t\'`w5Zf4H}a7+w/]Jp?N~QUl H D6=ovPuEsPYL3I3Z&7~^'Q5)-+&7\=[Bp;F5 Z_T: vz槄=&PExiT%Oc^8i$ϬRϑmG\KQYe"V#g#Oܶ)rXދTL+ fL)n7Áendstream endobj 35 0 obj 3006 endobj 39 0 obj <> stream xYnFW {fȪk [,&-&lÇ4sEv[Jd6,YM޺s-Ƣ0f_;Mvb!_3n']rsv̋1Y 2.8/0.csylQT}6y0EnaZ.auZmˣ\CӉ9tlebC!yX;?q& ֨W[v,efp Өrn'LIe [Yg9mOfHKy{H[Igmi0Ve cyC/K[0<4uh͒M(,@</*Hek'2Efg ~jc^3@eM? G*m[XWE7r M1AI)rFj0_1E2CLt8O|S+t:]gQ +u=:qDfftZ)`9_|Q@|haڜ1>0h(c7˝*˄k.ǖrD=jERjTc]5^˦YQESo8ѕ~TD sk 嚄C,׾Q!MUyPER}x^QBqKN Q~vz,˄@r%ϧn8z8PaJ+,l[b1ԭ@Oj h{2eX:U?~ ~ՙRkVvpȯ!Iq!N G<]L4tgjQjU?$RG'vZU0=«".&/VZ8݁tA==h GKWM}p)㵕3R4@S٨=|Xk6ST9j!@uD7ڑ^o?ɽWhs#-ULskZRp0"9F5#ZV^.PVoQX#:J[Dg0K$%؞1^!q~eo~i8tm %X74mobɍrҩK8#=yvTZM|ܠ%,R"76}a?P[f9 >VұX+!{9-Y8LQvwL$9l*r¦ЩE%$b~^O[Xj+102 F@JϓלP`ObEWgoifh}S|x:Ei-^:Q.dQ {'2{-ѿќP^^poG︎^`[)h{L\۽I`vzi =f3ytG^wȬiF3|_-h/ ` FH4>CxqʳX\wn+eH':1YonPsqdĮ-ޚ[OsquisDz0~sSkGKazrAmv+).'d.ΘIn$,L c ftcЄ6%!2.IզɌy,d}O;<;]4qdՎ==8oˏ{}@[f!( /M4b=3Ii_cWK*6Ï| o=Dz_06 ̙n/p\'endstream endobj 40 0 obj 2781 endobj 44 0 obj <> stream xX]o}ׯP 0}JmM"(IP8~3Cv:{qi&e~au%C?vmS ɶ(L0Y)=MYoHBcI\E۔PM FU&I2ـ 3=˛jZvj;|_ vZ.bsadm"Mf0aۻU Bn yD,n~zb)tЍOI.FoҔؾXgjzFqL)JC*Ƿ5"wq+rd?LkɃ6Hך D_P tFL\f>/>ܲ?]-W*ݔYW)L.+tӘY^׬ݣHq_$DϦ F*4)X۲4# f< 3/DH$ճig5"!n\ X q` Ks`<|.F i”zIO\?6aK Mu_Pzȸ^n7n+|?Y "8jz #ލaYıH-xǒ cˡW1o`!f^cQgE[]߯!$p5=wU ,zJ>*20nϦs**Q@t }zVǡN.f.~E(b=IőHh}~[( jqa4,nS/= 1OBZ_eWf:8JPQ, e aVޭ3N ;,GD>lx9dȶd[Rȇb3JzU&3f&P=9ctmd &mh"Oӧv\ t';Khi6#D%TJ4ΈCFf$;;;Pg}*@ USr`Ф^QCڵuU&?O-7i ,|36f3%r UDv P|AViw? p,NҦ+U(^2%~${18#)BQSS<{^L,m35EY))K`9&:x 4wKZsb hعVn:/lMgO>*š*ӿԃ[9;=)#HbO"cѐ_F_5a|j.0n"_{<:AA<fisv֩ys+:VKm[4 49!l(OAX[(x(GDJ SV h+•~O/_d?u`:IKB7 $ChC:@Zd.}Nc8UL8Eá3?n19t?zZ\3=ic<{h *h;Y,ݷmE029Bq[/ں}b~AI)"\P Q1.T0w)]m?y ~3X'۩v4t1qnOՀ"WxLjz* n^/;;VX*}e꒙ F(;x{48tΊ)3ٝp7qwAJ>3bK)o):ãi^"9!q)t:ؓTd/4Tԑ(/scBgRnu_Lhpb Vb_*$\m/տψendstream endobj 45 0 obj 1947 endobj 49 0 obj <> stream xX[oF~ׯ k27͓:i\X/ Jl)Q!){ sBrV@Μw0 wM;ad3:% ?-y5H2_)C _Dd)dRvl:ĸ +<=LSixH$TeQ ޚ12WeSj޶f@53: ( |Iw몪B< )K:x`I+x{ bR(˅W%hS&.Uyl?zd< grǽդuYK~B{7vmAU zrg^_^hH֣7/, v39U)錛Nڈժ95.WәQ kǜxbls; hnſfs;}ys@}JƥyQؑ۶lȡr. #4Ŗ@MT24 2:@L.vC 2P+28YFf塠VL`vסrv?)TmƓ:En[PvwΡ 1)H.A%2LA/9_r3q}>Ooz :=5!< OyO4d8r7<yF4ˑEe=*Kr8,{Ƴv;ώewVo7h0 ,qތX=,8n#kƯ  nLXq@4r~P"?p}$#knUU/_Ͻq?uh֋0nbQ=Ej?za6#'wiX>Q>ơ3JŲsvfגmo\!ÉSHo0d?}`cY|Ƚ-ЪU v⇂gS)85_~C9IwA`S(rk/|cjGCdXTZ[W,Xma9t+wB]шq9.&D&;d\?[b>1$4 p?-<~ߋ#C}A4@&LAB(wL7M~4oendstream endobj 50 0 obj 2065 endobj 54 0 obj <> stream xXn}ۨmF(v;ڵw+ىOծ;ɶчKͦ]ewm O UC><5˦axOiGʸ헶ojO;:Gj^\/vC_ si51-χ)xzȺ|.gqΏHW[|%<.d@BC)8D^N]igң7ę<ʛIuNUÅU0UY,#~,D+)R.ڂʸع"{^wbНHaMWgZ0 Pi$,/ ovCo2SGiwꀏ$\AKjʉp:q+ݥ.jg$H<\:-\e#Z'z4E&J n`TtnO&x@{YxƋ}&b<ܒOkxԥ_Za3Ӄ $v`H1ɔ?/l qLFX PQhѹ YZ)Ŭ+PX]=\ߗͥ[owx47!DcQpH#}u;$.Ґ/N7&Z '30FE")`_3<^ O5XDiiqoQӵ|IkIdr ur6;W6"Bq[ʄ!`* <6_ֵKG'mt-3x!ujDDrzpWGP> LBMf wԿ,ڧ|ZHl tL[, <R0Iaar,kN@BZ|>ǹ)ZͬXΑ("Km+55FROOXX( q` oO2_E/0U^&&$LP.x|gԼ@w@K![tbJw,zC8'+kZ%"sӺ%>+|a;ema1䙰4Èr'6+':|(U㿿ԌR~e^Ũ #iT`XvåaU}8A`Y锺?=|r3rͲB/A`!:^NDDпcl/4X @Dv#endstream endobj 55 0 obj 2173 endobj 59 0 obj <> stream xXnF}W[S@i]}p "W[TxxdMa$ٙ3g LQ_{Vh߮گ>~췬Do6+6Xň2٭A`Hmս5 GNGS># ?L&_qByZy3ҮU8 Tne5=֖44&X')mv)s_1e6$Lr'yjd+Ei&ѱh;Ti$0lp,J0yg>#4P6| $c5ZQ!'UjE'KS$&:,kiaPPyb)Tg!p.۴ Rim @:V3`NmDvI!~W]QJOJ۶ &5ט <ۼ3]g{jb<hoAXePhrת-*t+EW~Wpӄn┇f>1PĮrs!ԔƮ^UiO xPx0o]1E`0W'TޓG 2pM$q=f `˶EMZ% z:_n4+AHA4L]r+p=d6`LEћ;h%Br6^ ٬WFVv[:!nx%u!hDQy\ cp+H,S"ECSCwwէ$ɞ׾c(U,lh>=[1L KYyAUE@`/tvcۺPje51&){EP(U0#0 40E4jPͯQY[^+~fT'qr8iW)@I8$=.C`?)ЇȃVi*'%r@d!ul=aЪբy$c k|&&Xp" jqr ~:`zc/!hg 7yJq35Hmh`8W$ey_P? a[\@XiE~iC@\q:.c[\O|qtvWh(P?Y*LeNg|S %'FVl4-i;RQTZIȽ6CS*Gt*:3o߽aR\)!7Ðy`_!b  ͒y0^`+K3l3'|?j5b"UeZJ)9b& >ppRƽ;y2d[B M,M18e]œ#|.evR]-W|aQ,Q03kM_Uݴ/ o Q7Y5)W*Yzٞ;'vbNf > stream xXێ}W4%bİcg/ 8`3RLRU{NU_HIk'꺜:_DJ?ݯ)*ϫ/+ɋlwXmRzeJrƉLWFUrLJdiOmTQMUǿM YQ^lpwEZ8mSYޮ@2$aT.f.òjV;XMZE$I+8ŜPD")ĎÚA㱙g`}ȏζP:c9-p>IdB8i7Ta7x}kTYPf;y>v[ W>%};/vZΊ2/-wz%RuPҧAHlTRɈ8" = zR(Q TaZ,{4-GmJ_g/Z#ƞo5;^W"KɒmxB.V4>H9,|?'¼0e g՜QeeAWqǑ|\v?+D,R_4fM1!mMUZ-ZTblg8 GQO,˰$u%Fw1dZ"\nZm*٫0{pbb.`IY/Hcd³70k^3 qTLOE2'Fy눒k:yؿO'e\'ətm|m2U<_lJ{= i$2K6M〵:QDp^H*0\^@rmbS{ b;] oQ51e~$S5c?\пMdǻMaתiנN-"&XQOn>Zb/6 3ş hչe6!kŦ%A3`D*+ X  G_mz4uuIULA|˹ ] %'5g.qp)R~Ubٻ=+!_w2Gل?"+"/ "#hm|p\LTGûKTˢwt@CdQʇ51Qqm&37Ljq8+EJ@H*4:WE&;:,b~=ā, [*>h Mb':W4~*3|;t -Q =ۛxl I:Y]4=7> stream xYko_1~(&_ݢ7Yě"E@I#%9$e )9NE> gǹ瞙|b1,?r{*c,fOg~dr˾)6[bU΄d($We*eu4đN~sv E2V<5& =E0vє[3 F4XWfӕSdg¬b[ùVeHBaO@}#Ƶ(|H gԿ~(<4qW8B\)ζϡ=[w]YlMz˔k|Ѵ1mo`j|lm)e]XeQ}u0ruʝX6OJ5"TޕmD"塝w?Od&:zu?BWdEV̲>~"R]u!s6SGyA ʊSspve"=T-e~e֓TCѿu;G9 ˓Q"t}Sv 4ۯ] 4NC>//_]^޿{;֏l:5;B|_քF\eƳbpge(\.@,|<6OI@Z%&ě\G8dqޚnn=/ݤ2Dj,*r[hؼx=Q'T:9f5 P @>T/n,ȺwDZ^Rvw5*(y dj>B˱rj32p! 0ݺZ C^ -8$'S¥zs/e_!Wo~&":ݛ|öCDmc xK?Uij(7=駿_RZA;KR]N仳ۗ?Z"cee1O W!?*fແ Cma1/'o/'?0C# 2oPr͍|H|^S46vڿ6fj}U3ؠBCmL}j^Yvd'x~w"/:Tv}ʦ)+s4urHH6~+b0H&4,l ,gA3Lc$Q'U^&pZryB%/p"c-Pi !LS-|lqvW >'c'#[eSua8҃ǕDZ&Qtp|i=`N]Z^nKȵj,J#c}+ H9+4!+0>;RTS(_ dH}.6\ٚr5W5+2]3},Ek_c9RTOj]')0z<1?CNjBq]z踓!d>N~++qK8 l1 R@sN4b1wЀBhzБt NCSE/B~>V/R Ѕ͝'ª' LYe5\)؅'g$ڤu(NH%:=lm˯LV ڇ{LN⸈sNcCкs8\ࠟ8kC/=+cȑ"؇fzؚ~鱵GbUiΣ7Wzd v6-돷Ծm2w+<ÄW0~!W7Rs;}X4WQ8^I)3N}}D` Pި~&$ ]85+3? /@s|{Cߏ"G:j,>s^LLyJ${9WTc;#Д ;7lk`Dendstream endobj 70 0 obj 2547 endobj 74 0 obj <> stream xXko_.UX}FsW@I–=K ٙ3g7&dW?'lNNM?||U)7Q2(Cw`&*M sf IMfJh.DfQ*bI#!.=ѳN`c.#(-go;Z\e);u6OhXǘu5FrH`+M ͡yays:8ΛKJJiqoʊ)!b>E!Ol]A~:׸hB9A=4x,Mtf+hց{7/_/88(ʼӒN_.||kaK{[]Fgi=!͏+:*щGr ƾ:j>6VZ=9gf9[啹!ᒆˢ-ņJq*US;iW.X/WSEh3tXFgxMYL= Y!59QeXf:y pyCA]~$-5}27J\5{& Nj/b֕",ife̛֨w~PuOBD&3wEo;򠬶"3/ 43OvW'F}JE(, bͺ=J)lI۲=QJ;fMv{UYvyR13L %,8BR YuHm);8fa?^a5%[m8@nVsBm`Y1KR.)DE4vaձ{Y\]sԋ(qB͆J)!^ݓ܂=i<K^mhQSlÎqmpY,Ɤi}F?uTn}Ђ8?FچM> '\Np ~t&S! |*AfABZj/f,p ŠP qD\<™vR8C-oȌX6+% 7kP>r#C޴az^)},Hk"orC%"o; "jAYTkfk*!"_}C8&)X:4`bC߮rY]P'-jqh虱E{ǙiF%ٸq8(z%za&q'1с.Ԍxes}ϖEYo! 9z{R`q8{$Y$hk?0rjTw*'CiHc<ա1CeI׮>eӈ utݔ#S.Q4j=?_^vM)wO/ߦRSrYӦE/6m߳pu}~BAZZf|Z-X*p}[gO^@[8gLn^LёK9Fb3p'Y_~ab2MlH6Pt$^Xv]3L Pdbqw׌ȒT xiC8 +tՌwBSλ4Zm_If9vfv&}bݧ 7liѬG=@B {TxS#hKl $]FB4Y5MꠣZ>ԃ M]ׄA .XdM9ҡs)]~0ABW&0ڂF]`ncC59dMXu-z&*h5v*fR8+J ܄vƹΔ?jWtk p3QzuƿnfX[Dn|@0 Q\3a'גb4η+FCMc z)à$k'IL Πesh<qƣ^WydX9kWF`A_%t2ط1)з4An'}F(@DnNXf C?@[vO32'NxU mDdEi7LYbKhH3y}|dlbTHtK-/CUbyx]$tk:k{2zTCI;0B=jXު 6NKIEy*.A0N*ѓ;.t %?\Y/o?~ :9==>Ѡ3~i|bs^ȔPb%_'şQ9endstream endobj 75 0 obj 2515 endobj 79 0 obj <> stream xYr6}Wm- o\eU֖( t(3ޯO7n(y,^(1yFDEIN9bs-G4$(>[\NHg'cp*K rGWPBmف)nh ,΁,I[`dž_>tZ)ت}PO}PAaUa*T`<}¾RYC!^ oW?|xG3l4)U4ErJPqR O:!gj0q vykV/wAGɥw jHV|}Br Jgn(V0s6N "pc e :yL@Skw #Di }$_2m&ֆ8ew+|1#DeTx1r+n-L!U_ByPreqsl|dXpL0{9{4R_[NGhBࠄ|n}md_~J|ODسWiI5 Ii;\me0]@?zg)L%o(Ff܎FڎS*0,V8qq&JQ+߲90_3TÀ` @QʠJ+ㄎdH@j{o8ͱ*,Ҧ}d1|eT;wcȗUZS(O/ t@*t VEC=dn0em`^$M;F־FW7.s U-u@Vk &>s2Q~oNQ/L`/qgA|Y?Q(Qȡ K iEsE3DԶ,8&E3gj Y x+V#8x5 tCʓrJjKˮv{r[v}ᙁB}\@h7KKtvGHg}#rO }J)3+uN"KzӴn A -` Ȧ{GdydtÖ> =^AE2#/Q_yq UK/xk7R~yҼa_n;wTRpݎ]' 5hSQ Ȅ`2A{ןkendstream endobj 80 0 obj 2315 endobj 84 0 obj <> stream xXnH+j7T Ydiwi;D@(%a̿Ϲ )Z e^}{)}cY@?wq^)enۊ*Uv2VED*0biy/ޮu |zP" 6r}Y;tEda0|E9.b8#e0Q64"r{W#kVjjiԓTޡ.4Ur2i=_`|^OW~qC{=_aeK"˲40: ]Jb~…:N#{^[ꒇσ4sVH2칎k]ۢf4 \NO yg8q{&P ez]S^q{J0L|c<6lzV`cr G6D&a ]/^`dc:$*ué, ӜbupaEG5{ |cΐb+ژΰӢ# Af0 P^ LBlhR=6éd{l{\̋9LB͡!j*Y PEm0uh`NdȄcc7L`Kd~BS:nmk .fw\Q&I*UWńM,dڤɏ2FgછUQ**κW:î-Hv<?9#h8&NBI^GDvf$fnJsb(GiH83إԚ t,f$osЅws7 }.(*'͚'{-򐘦+fX$+5#)ؑkʟ5OtNKV0G@^]gdkهje\@\<tj=UerMCDPuWDIfQGTGAͯK4>to^OD@,bc 03Nr(SDӎ,']&^Uwsa +ث 1֦V.9 1dӏ8XNnl#&k!(S)rSh EOfwþS!YM/S iA%$}e91]SX> stream xXYo6~[by>M6EBS .YlX#C2,Yh!)"}ǻO_=fgw3/+ޡGa Q> 鬽"1Ʋ9r'H7ٌpL@AɌ@@ZݣzU(U\f(Q)mVERd*-?P :`B)JQ&2nxi-mP3z68mΊ ȐMJt}yU(5FL8Q4˳jsb}BEIS8EPe"STe\g>mx\W3 h,Ga=#a2Xk6m.3Um7aΜ :kY߮ʧ쳮L ;e/zxBlxW vi훕>\Χ()lZFȨ<@dp\и|r!x#8菏vq̇tvoe;` PI#yg}FtvaFrm(p:^`|}ro|^N=KNW>ܣyc܍[F^o fKML ~_ t\l9zO`av+m:X[ըR}jTzT|T#XP^}^Ԫ#`pZ|wxgp 0Sy19xPfeuUxjqOgTz;JU UC76?T@.MT#F,xg?Wendstream endobj 90 0 obj 1302 endobj 94 0 obj <> stream xX[o6~"ċD }JlhQ`Xu`hT;$Elye}9w`O]|_#!Y0J"BQ[QA1H%rMV4 b' `Ӛ Ge EqTԍ*R]rJ$GS&b8v,?>j*;8_2/S5oCM0:pҦ+- ԗ?4&]*r I-:ΫYisBc5NlD8.qSjWmDS:wLBnllLcwej`3Ua1LC- h?ysg\* Da$!=>rsu} Ǧ;],P x4Um= EDc{rk.eQrHBc8T.e`Yxf\&Y8 ?u ,bmOxFa zJ)_`K=zpFvs8ۗj߂TB}ecf&R`y>&G2Z{$PaZk-~%9 x',{f^&ɌkR,{|=90gXVaDI޲lJGSH7\@H$ jSJZ3^Ixʾ#d\j= 2+&q%/&G)B_AOfMjsʘFy5d ̠'ֆR{֧ Gb qn+kUïz#;69BI1]z!yFΰ)0)\B3\9=3!<ڠps2%QC_GNo{ਈ:\̙S(xS@Mko-dvQ8yhwTIw;j6`XyvשZ8t6'AOvEGs𢯁eo|@Cu<c'=j?{+NgrR^Ap0pUH'.q!7J푫E7`#v@F>φk,Tnxlf"g; >+w}Sܺп틃)Y1aFjVɎ4w\, )"[yAÕoaD ;ed jLN^SO;i([ șx~E,_=E'~0_jk@#`k5.HA?-<р3…E*ZU=!`oAkendstream endobj 95 0 obj 1676 endobj 99 0 obj <> stream xmoSPj$Wn .zp|@QT&.oߙ}HY]Qٙf? 0 Rr F?ܽ$WyO^H.aUF oDJERi~qRhd׿9aJ0ISdan~~|?.LN 5pz:V iZrjCՑvՎgn -,wCٓۧo~mfW=o쇋'?pDž|Z$4//rMܜ[,p sg$EWꇮvdߵ%fÉdIߒX]ޘg 9ǪUݗ—QqrʤD_Д}6hvΩCpt湐sκٷ}; UA4ͅFA,<[| չ!r!DvKMF5Wd j+|r XCCwZwɺ]X)c|s61~>Ie. ]4h _o k LI(>&6ЕWy(Ugr }n|v"iL{]u SJxoqdlc*@:Uzی811`ޖ+ͤ`, {ýA2nX7o-~7|6?, ٮ<ٺ}7s[QuT~- P͈|f':4GfpGp,`?#ULYbfS\e~h ]TaGN`#M1Ke6)l/"5=^]p83dJh+{'m)YxsNۇp_ ՇTҌ)9!AX1 1c;ajX aNYoG3RH璿ëEUtk%pmoivQ95S(O@N0,ӱ{\P8 Uqr/j[lyJ{| Hu |\Ⱦ'y{7e^Sdw/Kq0ĔA<`-4پlVkÌ X_rB Tf>;R:q ױa^ (( 7 `2Qr_Ú huNJ qLr0vR|A6p,h] 3JZ/Yq%%dzȕ˷b.rSW5Ņv4p3tys\b`tQz}%?IM_ :P6yMlxϙ bȯE3N7C_\/ ?endstream endobj 100 0 obj 1980 endobj 104 0 obj <> stream xYr}W̛9 ysVrE[އNP. pP9=\h9MyfzzO>=\{W!{\#sG*br&$Wv`2u*_ː"I[ TW瞝ںlhYs0},ۓ-618R Cݤ];2mi&C9PԪUȋ.tNgs(R^0"1ŵ81_Bw_9Oiz LZƼ(D\z6LzJ,<&uFA?I T&n+, gyߛ'B0jޮ5E-񏵠%N@hFQsJ\X8:v?׷'zP bRmn$Ŋ g.Lck lk ]#B.M?tqCz̙&>ue$s˛_nL󈹑DD0(G.3Pie!R_U6S 52v $\ ;VGC)WĢ鵠y/O拹Vg؆(ODN973&5,p\)C1KR@i F0mL9~t%fF+5Ig%yZ 7 cԝFIC~I. 9#Ƙ!f/Fkiga̘^S_ W4 bsc'S+$??0bYw<`Ϫپ Do`JMÝ<Ysaۇ{k@`ְM_.!m{䖏>@y@',IKjzx Wl#5*@}u i AUfژVڶ@A7j\G;FXccCS4<>GU'=v4E3x&ےǹ> ~p+P5RF,jz0:}Ru"E;vj$PyQ4\+'9r0pۗo+bTXRu F $,KMy@`/,FD:iC?3QF~ IA*{n=\ᘑ~W.9\P\5%51 PNIEfM!M5͙PPTUvEAbP{AÑcA $^3@:\UBK79`/f~-+ 3X͌2"&1zg $yAʫ3 _eG:aƓh6"ry豨yl DF:-!Z4eMb3$L9ų g՜ed(C#hpݮ?ōendstream endobj 105 0 obj 2884 endobj 109 0 obj <> stream xY]s}ׯ[ % $릛&뎇 YJԒz_߃OL;~%8s$^fdb}1_~9dƪ0Nۙ}.9 "#csQgK   YXE:߱+~Q`ObTNmq= |iVct v+ qNG 'TN`SYH"SiZNn"q^u2gOKR*Ի=};RFb H_ڐHߐr=lLJw;m6؎H9cF,qRݺN]( H2wݘLbYJ0D]d%y2I,&o~8Z9:V}U@",HތB {_ccSh"ݾi{rP]Wmo3+DP^'a290u$_YL3< LhO!ZX(Y| l{cM b4c"ʑp0ei, QEz]!Fr<= *~fk )3x4g0*RWgUK+ 86Ir9 If'x]5 l%lC4YBQ9xL0~ mS͜*ȣ'[]u}gˮW'|Y~X4B'll]$1 䇽Z֤&y'p5&2u5$3%̲|P[Rm Si*3p\x@Y*43!hʲ8+ \_7k]кɨ+B]Gϔrj$p%-΍Y(уa3btBu~CX4Փ4JfV9. }Y3jS*~|Wh[=OۊN/잗!^ <;uhUn /(>+سS9x$CiG+u ])19%  LGKvcB Ms^6>,q1eu],af1m5krȆ8yUf70شB>9ѫ+Jc TZBa{Ktn j3 G7<Lb{Io^%#B[gCU28Bo-bJ@&Ek۵fݸ]w~|w_'dUxIa G&5yxׯ""TphM;pfyKٷNT54j " 3/r~u#ĐH",Y"0yNAg*6ք:zYT+o$ܢXXh:Uْm\k Tw_dV>XFmWD6mnأ,>2:蕅/rkC|7Ekg"'惌~Nz׈TC.W-To؜j웉X}eF0?Ozⰰu] VVdzPI"2 ⇼G;&}扯\zb¯UiD|7!0h5nZ|6PuуrH_8HSG<&.+3=֮97jkGa'<\[CyG753$ĩlj}-0FscM먛nDY,ө~C8igA޸Ay޾Y6enC"e4NZz{E 3j]s[Qpr'}+cfxdĹi&zg; l6-]aFېMٗY?~y7'8(|ŦiF o ܄bekw mv5, fN 7DP>R0<G/Y_Ha3Eeӈ14{a2;1mϵ[w<Vv쮰K?X;<éVMijX/ ˈ9͇ "Ox4 mm=lS۩gX YiiЂ:H'U[1w}bs]w3 YFof}lh,^lgfn8R8I:xc@&[\oЂFPVH[{R2r8}1H[~qG*u v{-Hd*íEgLP+SVͱ~YaN@^44cwU % 2-WcЗY?Bj- Z9̵“g'4"Sl'tC%s\݌;?P#fG}a868܀ -"޶{eG_{wUtp :Y#&1з^hB]9Щ $yh=jiB)UM˅2i-~|wnnqǟY>~nwq( 61ԿL1 [0ƹu}y^'ƁEϳl y<,dGv9'~ y^endstream endobj 110 0 obj 2759 endobj 114 0 obj <> stream xXr}WLUs0WZ+dKJ   %ߧg$]i\{j'1{>-q1QlU ($We*e.˩LḨZh$4X8l«D-^'C.=I,Y*]+Vej56Q^;l}-e+x/u,Jcpnsi6AЈO\D4ܦ*Wyvk¥),k-`\h[Vh_öh` s(nS Ft5<3|:) bSk-ѻ<}z8\\<^@\t+[vhbaCz{gF\ )+\WSa,ᬚ}ǹw0Rg8'(nŏ%nZ)c. S{)UWR$I?sUF+x[DxhǪ=~: 4< 粷?y?Gxʔ`q>?LJMU,y 5Qx%.3(J6r#X-&N47= ˄%s;*' 刓, rRtÏWchB,>`Ri­H{3΍LOl4 sG\l1=?Y*8Z D+ltpv}MH WD$`_켻fJA?WPLZ/S kTF >F|gy{ָXҐ1H`tit!b]h DuLQ ʫ. x,_nZDl"h䎬@GĐ'HNt/]uwC< @=M':PA?3T Y%ԄL `7ꐹ.A320d}4σ8_Z4#rZΕrKP7칦" *jR]7V΅.O‰@&$&P({{uAhFwHet7M}xPּ1Z &&(JĚ6zD, 3`w—BęC3bHLi C-B% O*BtI~9Z;NhƳLo&yЧh T;(h7+H߬ `zyf\3XHrcPDl=w=\.JMܔ$gjn ]UbT>(>s\Y9$ח;["/W-6_)讃 Y^#9Z{ % 7P2!X+b0ޫ_FY"9XM=:'߆#;<:*eJYY9Uf6zS\#Qja?:q k8CV̅@T>j˟%%?8 ]v]xҧN*H%݈#5P/]s`*]iCIaPߡph+@XzragPSCAHGfZވsΣk&\e]H;\._b2)[\bb51FO#$.Y>9z}DhT" _0Xv%J8[? [i:\@(f o=-v{Vz.:7I8OhΪ %Jw۾b^J/+k!0S'X9z?FKZ<_V6ڔi,y|lCCJJF|g!&_C~v̟VD}?|AiPu6dA!2>NI3i:⋞]>x8:`z[>mlY[sf`St{م[wK)0ه^g̀w$_ ep~/qa? 6H_|r\Gv1- 7{y¼Gt5w˥'alET( (kW`#vDnLu= Π=:EHI:6LBT4|NU5֡FfQs8 #0S(-RV]^eiSxj%VY}8^/7ؗ7!@`(vؖےnu }4u>zywLa`&ww˸|7s &_'7endstream endobj 115 0 obj 2375 endobj 119 0 obj <> stream xXn}W4e4yM6؅H`Ւ+ IY3u;u0c&}N~پ__|Y!sߪzغS%[\r\el}ZD+jp= >Bq!B񔭯(7sj DnޜL3g+  1op;6 ]jۦtX`E3]<֛UwIʓ4-ݙ an5jŰ髮>m׿.R20mۅ䥈~.d= yd1sɕ}ͰMH $x1 ۾7TWx|g_[l2QvV%$2~\=c.ϊ`JS@*xNH=Lfr)}mbU⋨0y^"űKTܵ8iVo!eC13gpմ_TZDfXMߢI oDKݧD -$Zz }DkdPPԝm#OʀqoW஻.Gݱ˩tS]2)}2 y{4z:A;(d',Emr$6?%/T  u9@/X}O Y7{IjOMA&4OFoWms|_(Jv|-/Kh~1/‘Lb)'ηrض#t nPT̝` Lgv~ l1ia`B:>v ! "qzKKaO9@ GXK5Ue:Q Ҁ]}`}gh|BB̑s:S׮ qjyG&oM!Qe^Σ[5}YoR*7NacT8¤rg)xd1=6)x7GX58AP3p >߈T³TPH1fEjeTEBt"z؍D=f-'Dƺ86uTz0[Lrde%w9hV}UDI[Ņ\aBvjҰ x;5IP$_oQ[=hv=ՁM;8iTBB=zs4a QȰ?v)Ӽ=̮D1Hdِ"9lO͇_=n5π!z m&<5s"dٲk _hͤ^@`V5M d` dVs8>Spe7@wdߍɍq!`qᄼ-U\J27T Ni޺!haa0CwA"//%%.ayt&-2vAnvyrIE[RsFӡw<";FmC< ("%:Ž,B:"u<^5Luhj}oaC KгnA D'=]2w73ԵJUʽuM}>*P9}c ۵"{`U7ԮRHAС Ka ?1endstream endobj 120 0 obj 2247 endobj 124 0 obj <> stream xWێ6}WS"'6ÛnHn\>,^H:F${V$̜P€ڏ7w_cX5# яs : +a!!6`<>!;@i,I)LC_jWg~= AwV#IqAbщHIx̼v91ݏZ]mM{fGxt)ѐ$qǢϠXHh hSA9#8ڗ8yVB I]ίbI1AHC%|.IMDI'"ǂw&AWendstream endobj 125 0 obj 1351 endobj 129 0 obj <> stream xX[s8~B|`2,഻dֱ e~$pCu&ad}9;LgYhkt䇰A!)b6úlB7`}f1<_Agx-[5,Ld9.a[$VWhYK l#(PbDŽ g7{s:zKt}6%lakF#;MF"0MW-=OHJlmB @Afiń) u %J-lZ{? Wr:E>^F*Aڀ҂k&vf4>*l?ȶ4D`gs. I ;A57MWcHDnp^G}%rM.2ZǫG)/v1+﮺w07wSw-W-iɰ&c3 qioRT֋" ϏUaaӶίc̢ :y( .+e\]/Eפӑwq"y|l/WJECNllϗ'cYFi:0{iZ)B E70`[b{U6v,8]qgr)VMuKMIʸE% h˲4w㲘*HC|['D΢14t^'Me!.Mwv )u p9^Oa$N9ǀ\_3&{?$ ZaN9YZ7ɂ~8thƛ'*M m_:diuYh;mCi\!~?@eK2/GU)2g.sh\]uvu\(R1LєE/+H\$ecrc_6!&|BâOSWz<2qy_޼.1}+R_j&h6, h5v'-u9p+U֙C,w9t0 Qm5GgCt@fh`x`SH8FM)"2M<!$4(6 ưè%Qr.+Zh[ (bx?# #QcD(bc7g%aI(dASZ͒*^S˅ WH3t &(@/`յX+$OEc$6hʐQ1 T; ZDiQ4d. Q+3()Ӳ$G%E(AzU6Xcz~TLFJ *΂D74YCMk8W7~BxQ2[,3U/t> $Y=G=:d*LHV6C98 a\DF8^YcE‚fz8]Rx̃\S3 X'%!H0}8U(GOěT:jI }5 9A F_fez䷺Jendstream endobj 130 0 obj 1586 endobj 134 0 obj <> stream xXێ}W)cawyAw*1v0$J!2 IIc`1,]UN,䂅_?r]; nL~d[[a2!r; *bq%Xȹa,;U *[-73ťf,Y6巙ʸV2w>U=n5:'A~WV\20~ uvlzPqdzcOFf0sAqPên.#-wUa;L y|.ږ,]횺?Vv{e]=6aE,trɯy7;znU{6+$D}hpKa!3lokW¾r5^ _]kBc_^X+i$Ib|UM!X/ض]YW) 8Z ~Yir5&' B,G[k ujW\锅42|{BG+LnFVgyc;ҚG,7!{:ą/A/[ffiP7YrxS#4u!:BQhB^}+%92(랏E2*߇Y~ M뢸.}Z~AbPH@}/IU88)Jy"u]aLT;VZtSWPD8EÝ<4B#i9B`&* a硎01h)θ]x<-'Pt@ 6B5 ~vO5sb/dFLэ#F eRz xh8I`Ki"Ҩ#I4"˼[*ĉ9@jZ4" 8TNSM">B|Bz,J}kT$_Ǝ p:l%˹}i^uH#^;뚊OVdE?5dG&$YuhOځ)Dy`Ea ȭ,kMxfȬ;Qgo~uԴEᗯc7p͟1- XRU pATӘ:=SjSqٖS.u]t`_wҚ>'JYvGP-́iܕU~0_v>IT0Di{m$4q!N#_f̙igL-5!e^B6%3[i O VmqÖ4y<|8G꯳]kqž66='aAtkUw{̻ x4/Ѧ.v}5~xzy% VH i#ߛR+H8r䄟&-nX~ɫ>o e8z0ɒx)rO'vendstream endobj 135 0 obj 2248 endobj 139 0 obj <> stream xXrF+f,ׂrl[r{<氧њ`@@M4zgւMuBI@UV./__QNi:&v~ׂOBMv#'"T$ٜ_X łhg0VIXHV  F]SH]iRHwdԗsV䜵mYߺɵ<IŷYgWJ!* aOs-[=g|!\N]Z;]~ 5ݚ.Vhbk춭ηf-S\n'4S) zjS7&UJU-Jc 9Ս+p,YaЅ XVue]Q4Z9h*c\;'B] JIO>zwճpSn񲺜u"8=B.Np>'4L >GZkIQ)M| #Nw([[IXP .69.8MC4e%i&r';,OSIW2r˪ ]fo ",HڽD/ EƑOQAvN0*룃fbR}3%hfa&zR義6Y#T;AyfႪhXȞ-5:}`P M2yx-0*0؀ p+.lj/n6%`7 @q{Y>3:dO(by'un4Q# z3 qqRx*Uw`F~w[xg[tG +a(Z!!vlI{SUgeJZȚ[l%{3o> V&h@H~k]Ƽr;_Dnq )%\ߎDz[9gq>"5o2I7L0p \Nۣ jw-5+)]#_O@g*ȡAPbK@܁w0f?;Yx!>LhP'(3|YWk% ,q>2%gRHif4?ZE (pcr;5_`04~+fX5 endstream endobj 140 0 obj 2018 endobj 144 0 obj <> stream xX]6|[fDe$H&ra ˴-)yk78lZK?ྯ:Ģ{)N'n[VWvhKG͗?2aޯZ/E&ec?U:c5VOfS[GqI'L܌i)+waơ笾sd0N얐xܼ,}հshZl--{ɢsUi.e7eO9;G€G/zrI%Y+Z*N7l54~E 2QzCUB8e` wBxyQX<<*T'ɖIV~tpY 4 Z }8gFp%mt(Ln/U{AeGunTHKHUƦQ¯'< "Ys4|И:kJ6 4 2aI1&-X:8tE x' |`)k`HyJ'TySj WyQ^^x)D<]B90ӿ+a䓻vUͮ(չi| 9+x$Rb*c/GβAZny)|e{[!6CG)0Y~.rlnՖy/ˁ]pUF劊,'Af`|ɏ =m|t@?C) `jY[sR'܀>߁^hcyV"/tTQJrĻm-Bɣ8sWڨڎA xi׶gr:}NA.eW 3vW-i_E{ӋYN/ס:LmZբLd nD dX]|jݥRSKҠ7D*Ew p[f&1эk?KE.I(e/U/PM.$RB:]-%}& .d:)_'$(~3`\-CɨXQ^ L0ZrмBeOrBܗKgoN}5r}a˶'/=hXȣTmPOrP#J"Á;3d)%Z`0C4˼*) uTͧԴ`I;ӚXgtãU_DBAl&3Dj-PmH@%!"OJ(M!EϤ9( E)RTkHmj0Ӛ+#mHFQ2j*,sO)( l LTi'ZdF1!Xpkp*Fc|Hi7%wGDdN$Yze"J&jn2@,4 6t? m_I*p~mwi(1";-vҳ~_+}L 7,pŴg&*Ѝ㖮?6Ū ̂nern|o>Pl_7 ^?Lܙ_1L~|_?m|4^/(/? $gXA|[O[wک̢"p-Q.~˨{N/!s3h*@%|c(/-b20<3:J&rbAgu>h$N28 #[0`di#FMV;'b7r]Yka@C0_cݹU Fc eoCwV'" f@_5ږ/ds6pgM5-fк| M*ݨ^p#R9G4K{GEPbH|B%ɤh6utԄꬻ7 }5` ^UJh<z xq"V,bg>H_>I7\Y jendstream endobj 145 0 obj 2225 endobj 149 0 obj <> stream xXێ}W ," /.3@"ECi[,yuF!)J f1HUN_ 0g_V)&viE2/Oە$W '"T$^VFbAY!Ҝ&)c!٨l+I"۷UQNC-k/ΪC_+.$M c_]QWfed7ƨCc9؞oV 7'*]&dz ǝOYYn!gPt;w>p5Km8/ =o"b.xXSף(or]u'ẖZo4aL(oY&]i;9죸B'7JgU=Er*&`_gh8ra0,80ύ,SQeZ'XJzMxB*10ij_3$%AhFild|'%"AN s? /|Wm֗`ḩ#iK1ؠQRt[T5m<މW͓[SZ> stream xXr6}W୔BǶvڴJ3'DHb*IN^-7Mƙ#{9{ 0>7woobgfg<$csG_|TB ^DĂ,fBE<_ s q_ZS%Yf3,f^D9H6_~H`~z=vU^;ݜf꾚2θ6i2"c.Ekp^^4$XԎEBqaKΈ>ju_▪9}̻0&u+;lT]ϿiAUDUn̷i|y\fᷗUUVLws|W`a&)A ˽"ci$,vzS`*, `ԁVޮ[ -hB=c2Sn}CR j 2ja3qAŔs_h1)-\ ҽOu͋QiF-Iv% zS TS ?GT>5&5!P]S5\e$C)rbgHő=dɇJc"񐑵"Cl) p>%X+YM=#V.m3)}'z 4ϊї"t7°KMvJ<:/1 e8IGy]ON=HzO<V&pT4x]cِ$|,H]>i)2_EPU%MW4 VY(k*'!3ٙ8m 0<A0=PD%sZmDc-Q{V䐯54:X@ R. dcUDUw> zs]i?EH0lEȌ5V$}\Z>䇃c§Ч1TO[Kcd4!X' /m ׿" Y~7\==ʢlME:剤6?Gi00́f6( LZ`.m5{ S=ld;8az7 zE[ ߘtI Yg)⣠U kHq9ӣ9KY|vKNuJd8LUc'4b OMqmUa$ Fىg”\@zz.0cGS_c]\L@Orj0"=jvKI 89gx 5V+#mqFt>?\(MSk;;6Em&k,FP\QΆPG-ڪJiIOM>>k%Q|k6FBU1xMdbf5mNQbzmS8l22Õx]2G3LS@ ~seŒ:Y4Qu (g%b³Mx(-U/f\ $:'9-i`dʸoendstream endobj 155 0 obj 1690 endobj 159 0 obj <> stream xV]F}WܾvTl$Ji2x:{cШ4UUB3{JPh:!G3lb$`]0ݨ dCN8'\PzogXl >aj'A@ 8!f*>A $E ͓*ɕa!#Q(*i;`B\nl].SURu`ko0Ũ|Wv¦Y^`aQKM gN]UnE$QݰMWյjݺ((VuR}{+lԮl-L`Z }:ZfAx{}HH )Ɓ97Un/ EI_CYЋ a:fwYvKΓ)&7>f]ق+.ps##6~ ]45%݋€%f$16%7]1$ͥn6]i7һo׸"Lnj/藘յwZX!d3 4:]N)訚 Ǥ% X R"lPew;S×87s[/6"y&Q7C Bލ'9endstream endobj 160 0 obj 1112 endobj 164 0 obj <> stream xWYoF~ׯطPًc@R#AAaE$ WaDV  Y9f L]|]]%h-/-9Dޭ Jeh[؋a.PcBd hk (@\{"R-(1aQ?CcRLEꞷ~ntR ڦӇoW4srpԉ|isqʞ!vJ 4OBr <A3J-/bLUq2 t;١RcLU[\pƸXd5jeZNUK "˄GTb{!RvE[{B",5gOk4vBX JE2c)Qո7jؗ:d,Ӻ*!ZP$|NOT_n$)F]>(󪪝ƼLY$x Y! }`C[5{&h|mXe0"D3H|5&Ν۹q}8;n(POM@'| ASGGNh2e.<1\ wEAUߡ] g̃G'xQ D䫖jjTZu&VTA?8&E8<cxDA u^B 5B9;c7Cy>`jpbdeqrԻ`zՑHN'8*CBd [5Mh+xu56q-Qq H("܀Oݏ0з0x %][8OĴ dfxmAG<[b1~DZma|/dwl%4 &TRCo ͩvlIfY_3vB}%oDquDFwՇjqh33MA4rƝv?JZYavRU=HOr?)zlьyԀT 1̔g0V}R E Wat:e@<")":"yT=Ԥ;GT, u ]RV GUwcV[bR Ֆf;u{Duw9.sq՝.i Rx ȟiƗ.x߮$I__a%!,rk6Yr7ΏYLЯ$`XhF/"ѩZ!Mx 7FӲACy ؠ6=H$Rb(%sSu}F[˖4k5rk0`w &n7Zy|jpȟ#щQV"哎};s@|P6MaL'? Qz> stream xWnF}W[V n u.^,Iwfl%Fð%Μ9sfp&ǟo_Mȶ_p]|[L=ePd]©I "TH~qG2X(\1CDpZ|0- `?n-4'T5Җ~IunMz[Mp0Yb)9"8a;]1o|B0 1*jH1\-zF,2 C@0tFt-eQ49IXE[ҥ|:"CS idۚ"oI[ D~ ))'+Xi>#t~RWեՋza> daY?[?Kd ipٗXac2  R ^1(RA}˜q5uG7v)RbܔVl!sOln0gnT+| /;wgx07J G_oq 4Y˜P//)_δ,͡A6:$fsR;Hm)\DŽG9aI ߍ{T+6EuDBЃ/: 0ҵQ*xtu O]w/SM,YoLIShGV==A1r@Mm!k Y$}nJ׉.nLP\(29>r"Mf8sYLYAm"8XLo-Ce@zפuD[klr[܀$(+VAH |\JD9y;_& %h)< 6?Gb>Óԅ?Oy|Cf,u}<$ ` jPuA!q5~!B^LlQ܁?:as]C7h[祾"`Bi]⤴v\Ӊ?4[|]l֌ngt1nHU8˕g 5L_3yt)t" YNEq!mn`2q: 4Iz/"*qfdq$}Ox GPG^pADd |>豩8i.L'tu?Mhp ,PMCn$SSk.Cp5ꥠ'*C=lgrBOPOKJ"XLEKфY%S^I&a3AɫApA 73(WJ[clAS(QByj, @nng̘I*fBpV]?ah,( ۗ)q+*8r{LKy 낚@f,*;5·'8n_ 4gEШʚ03,{A%Se5q%cʗ^#&wgF[j.3h aG|k$)?$fxsρۜ;@}N{e 3ɢ93_Ul p"fm\> stream xXM6WD6֌H}٠)Rݸ![DJ$_~H^6`$goWRFBsUxuZ`f#?nT+'~a23NdQJ6S< hk CkF4 cN`Si3GAd>%ǡcyB8fۚBdD'zMr %Ǵȳ<؋zWjj"Y8ryv?Y?Cpqfr^`<.ВnlK-H%]6=doy8400FY{^'ŭn}ЁMq0$qXCZp 5PpL,T$f TiIЋ97 f/DwҐ k~IvK FM0WPn]}6VX8w.1:f+=$ J}2GX" TL`~ @Rz.<&f4&0d_.0Z8ZP7SA Ƴ<߂7fχ JmZ {M?C^Z11 GzSMr8bF+R̚v3r ;ř0Ը(MٔA7 }$q7~e3[v㐻.hń۝>iEY.y^V+qW@H\4 o%3l"] 3J9-2>eaB9,Y`j:yc!&Yo?_WI&DCT85:ʾoM=ϰ,IAf34dyvzk'Y vZŶ*09W=c!rA ˈkZBׅNT_X2Ly{_ $_uэ9d"eGپq] "]9|  6}91Vd^߶?@ ( $oh eAG" ; [ F'F}$i5Y|{_.$P,~eSKy !aD|9EyPa;EA lC5T٬GL+O e4>{39W3/͉e ZBGo*(ŀFaC}oF 5 `Av dڄ)˖i$T$!u{2Sr!6?) tae$M1 >ˡɲ1mBͦ ^Z쌢wV2 BἜz4H?8@S h== Fz00E4K؋,j ifLW t%=v,1pAK;K^o?}ۏoOAŠ$]j}jNtצ> stream xWnF}W,2{ K;'nmEkš\JL$ŊQ8i\Μ93ηfff2523cNМ Kա/mQV辩5%fi7/f fN M Q湃8pl/'U("KޗX0l깎m;sjjT-˶WUS=v M.β4  rW ]HI ;T4 kO./O/+@@e8! ),uXPCfLUW}%7W.*h1J!08Z (_Vj;+$} 5X<-`SΞ %J!`O`='_g)8ӑe߮ήNtFoICq8TW&sD&yGõ 5r36 ͟e,ZB:ۀxAm)!pg#1Pd~HG;$QA0r/Yt'Q ^Et7oO?$8oYMQ-vԉbgO,0E)N g&<%M: ˯W^#*v1_%*,EeLhF_% jϽ-?NZmAr/'FhJy:1̒${sTWu7 nei7]#2Ek{,澃M )Ѣj0 Zʫ&>Z4ww;mRC(x Gy? FsSsłK#ЄP=M<6x~bpЩ@vG 2lAo1Zo̡F<|Ԋ URj5H:q4bY!> stream xXrF}W[@8\0*ONlؒWfrY[,)@FɻFO_NwIH g?䡙a˙ 8YngCFx̩$,g_( ?A CIo@([9evU]mt zu}WeӒ|aF;OhBLEț˯3|n˦x(8^ol烞<Ȧv)11N8gk/ t uW}? ^\Xgxb$1uӐvXmQ.ts^R*SE_?PJY* 'Zы eL{Zn9T( (Y]Tdžl6C[`2%$AqJY'* R(z8>m}M^k#dIH7wS& ST0ߩ'8ȳdy]A7$p%[TÔT tRi0bVޠzkާ ElMoWr(槁UBkMIY!nvT&;ikA˪PzߘO7UIeqDC?xt cWn~$"&>1ȏ\ " 꺪jXSPAڴe3"NItCpns)rڂ}%2d h X(/4BI%O-Q$4LJ2yxjT' (3/+Ei#ؽ5$Td d3n <_jjU m ,+GcE#ɵQQ+s;h XZTdWMԛnR`t~6qQ1Sm6fDe9很:rKsC3i18cEyTc6CotBs` N4&yu(*?,C1$ʳ *u;#|'L,̍34K272ۻN*)po,I"6nF̠>8 `19<>)0 7ٞlBt{ `ɂ NewMs_ #c<#oOzKu~x1 vyϤRE (_yxhr"W` !D޶$t]-;Ҵ5L.٬/+}s6R~$  ya6ߊ|!mK*49S#Fq#?U &D2;#iF*L|^14hbQ`yeyLXO -+t|E:빡.[t&Cջ_'-Gu2NޛkxVSDz`jbp3@ड़߮Z*zLwT1` rdڨ|%T%. $( 4p oΧlylL5i禣'Zڳj;^Qgȅ"aXgu+'!2ZnVPj NCnIMjv,kUS06@ۛ1}0Exw\gU9=߾j Wڄg~pz9U%UʊAWΔ\Z%}i̇8hTO8]EH ,4xm*0Ht[';2[=$pCq*텸%0'Q=4e`mq͵;eU"P&E -=sӎ HRc|Fźhۃ"+qs*xF88-gn<ׅ1 tcYۖk7+ +G0]p_7`gT::ڝrk˕q6vv'. xY ꍍZl}Ѵ9]:|6.@uA=+lO> stream xXMo8Wsq".vЋLчx(h`Ino?$IObիWA2H?s_7EEF,[$c'[-Ym`WI'2B% /T,y%EphL,$5Y AyNVERPN9B\ÆTuG vz|Q SL3iR nK LSm<&`\8_2mTv75Rŝٙg1]Y/ { DL fJAKѓŐRE%}KVp&(T78e2䴤9"ژ1Ui-Aפ}Iu8d ʷPa%&F[tnbsOIA>ƶ_1"[Ubr0]{4lJZr 3!:"+jGvksLN/%n`"UKɩ^0> |:D.}" 2a";uFD %)HN۹ ɓLv͐'WZEAGWxtCj:~_oPQt&pz 9YI(dEN`kԅ*T2/1jRiIU9jɇ2 3UOz նT|ףYȘWH_{H,ij|u]*T973p9i<ȄEr~|uq9du5d&V/J7'I"6Qޘa(8@rb,bYueh)TƂ['|wwޠOA"9[ˈ n~jv;UMѠ6 Q1]\&ajj&/Rߚ ?P-YbYh*e1IOGA㱳Cg,2GiGREqA =]~#((D&Rʬg'l]xn_k-jbDю%_͛'6nECD/쒗 Kg`ckz Tv*.YQC㕓Zly ebɵqp]ql@:a 5@ a!^O*uK&ۋ(K*=xr YGQR 1D7tN8!I|P/39b#EN5+NM 3?y놯atsEPVS[G 9n]*/kU=8+(߾l;H䤐j5Gt6; wɮ11&r^!/UDЁy2oTQuO(`,eGY4лԦvQ:?l&,L1Z]Ũ؛QP {!Oo@pU]1I3 {?%l3 0p?n^fN(!-uC Φ0MՂ!qIS(O0<3% foE.*HCUʧ`3Q/֗ʱ@Ms&e\ٺ` %!%84O _?UC3~-N7WxT8OB10Yvlfg^=1}?AI ?QX=;C%v(|*7 )/U{3&V_n7endstream endobj 190 0 obj 1822 endobj 194 0 obj <> stream xXYoF~ׯPƨij@x`a/JjL(CRv_꓇`abu_}U_Ht-_|YP?#~h)(C½H I.MV|2@}3HVIYh\mNSwwrۂQ,Њ++w{0ѧuWz.h˦SoSa+bumz{SXgypDZi OZʪ}I &$W Kf494d^̣kdo2 sƄjU}QVt`@:b|7Xfm'4=G' "P+ j,$& q*FQv"* aTV=>.lC bY}407sBe>\pǭt@)08^t6:1Jl|wӲ\c2b&Bxnjl NoltQ0Q֒P&r .Fu2x=MQ~ﻒsdڷv }hNZne10|> aa&t]-?/HOp A<,ʄeᣣl( ངL8rk79*x3+_̯~p:z/bf``krQ@)ڶ8uV +ԝ]B ¦.:]J uDġ@1f[(HdfF4-_Qendstream endobj 195 0 obj 1925 endobj 199 0 obj <> stream xWێ6}W-rڷ4Fb̵ؒ#Jq_CRmAص93B儙8L~'d'l'_&n8IN xDPDdq<39 wå`2YCHH4 ;Eh˺.>C>ziD3J9Jbm:e;MqHSHfj9/dHjCVDo),ufך."sG56rƉ$3#׶%P3 ,Tz@ 9t%ZyFz N +U˪#+} _44(+ҚPQƅNer Ѥ<ycgéjvؼڐcǦ>6%\!ǺZ83krR47% ^7;VgYg6cYD64Rb)}"5H5A 6<5?8h.2s㛳F_}{!( ןuݙ1'4@ jJu\,ay/ ZȩhMOؑٚ82yd@Me .kys΋C5Y&ȋBiS_ik, Q>}rе "Q1D)Yr0 lƇ~ >QwID\dfi#=m5xק5} >d,IPFY. 6غ7:C2gi{u_NM*!m@4ɲ$KPdڼkP^uDw@^7  (#G{lqL% y-(yPh5ņ`2RI4 ]ˍYStMzcT7Xd)!t BڎDKYs5S |{ yL02Xn̍Puk,?C6Rv N^YOdڻbYUAHZ{wvv>G+3O2\V> AbHQo~8) 9kdۨ3ɓD䄰HU9tِdG1͒'Z Q? [_J| ~y])Ջ)5LdfAyPuAgZiHp#-N#S,g@l\$n1g( /I6K\~x(XsgJ)rCG'MZ ,_ *4hTFM-l 7w.ˁ/$zXT 6*7fCO5aq2bA~)iЎI3nQW5 @_Du~ l'ULY$ÌujI{TL"iLq^6MLW)MQx;?ίM@`ᡁ*aL|x\3~ Q<Ektd6QRMYwx45jwUQ"vyiS30ToBL@п3PeRdn`r$}X5y Udh/:)lendstream endobj 200 0 obj 1697 endobj 204 0 obj <> stream xU]o@|Wl^l ;ت֩4UԔ0>c"9Q{0#*,;3;=20 )A9f PyTG{W1 x0wC +njFH~N&Qcgd dn>hW4AS'[?]L't a> =Msl{/ZW!Cc8QCJ3z'Sm[EaB%ӀmcȰ@!x8c$QqhTR'O*d)+MSؠ&&тܲ$&y\WhU % :e`;8M6qQD!*n^ X,z=MCTUĬȦּiR⻶ CjQ jyeGZym,v#҇J#4a O ;tr}z_YLee0gئ, {$&M)47\%> stream xV]6}Wܷ"lvәf24qv3ip$v{%w?J^{ua?K|_I&s V 6H 2v>߀'M2u2ޅv[jkNڷ8\m}7!D701Iraі˻6yÏ4(7x>7;n|8O\,>' 煒$03yB}d=7iendstream endobj 210 0 obj 870 endobj 214 0 obj <> stream xXKs6 W9⊤DIS_Ї{J:Zluex__G4d&6~>|OPFV_r.~IŸ@Y-YU`Uɪ^S\H:,8],X}C b$)3. d{R}amu54YԗuWV9͸#rǂ 1Kч7fgK@ǣfd7|9X?>"d_I"@f'f W(QdȱvSgԷ,w(v,N2"x80E`:̖}LS ˉ'{atNSٔŎaFdմ..,iY䢌ԙt=c3Û ˔Jg"?T^zfY{H hVLd: {m. Xq #V&ۦG ,9heT@Z(^Rh '8})'2gk]5zUo(iXdx׎P+D[.y8΍7NVb6z.^Axף4S$P܈Sr3{'+@*tEOv/n 2zi\lW^fʈz$8ǿ60 "He58/Iڡ޻#\B+ @%[SJa~sa =#HQל_1ȧ  Lo`稩2>SKR኱P]@joAǧȹJPVDg$Mz">\d++&A`, ^-^rPi]c$MIN31iY{X ~WA?qӀYegdD6܈׻ƂIP':nvdg\sbI=.dK3wC&4t̓iK{ $IrrGl̛ V;1TvTjش@2tԜN dT(j ]z7x_<ſ(&xs]-< vz+\q`l! Yt~L$S­$@Xf~G/1B@t~YktKVDF<8E xo_ rۼg<ϼ5QC>͜cV^T;Q,RZouq(Cn;71pلK^=< Cvy1$3[ Z%XE/U#{C?I~PfT^> stream xWnF+fj0+p`@AV P\lf$RE&ȿFj8q0$VW'('L}l7{!"O݌٧˙$ V1,˙9ȉ>dH٣"`X[w8LR|` aOUM8FgKCё-ȀgoHUW}n 6q$N|% -vfI)Yy#Yd*s|la^p_=`T&-q ĸ> c(H'4aUxT0<> stream xWnF}WSC9斻7C@i}&($U) %;C`ٙ3sf!Y6ߥflgg\Q6r1 aQU\D*XA&hfwEx?x!tC: dAB&bXg^b?E|qE,K"fy]^ceQAjWOBת,FյB[z3@xǢ4*4|Ǐt$oC9 VlV0lxFE2y4~:WUKۗrgX~U~@VL͟<ת[5_=_z 6K'$2Ћa84Tq'=(U#qk÷ܫ'ͪ#mًV(&S^gԶpE@tMˮF(wEW&_Rv?eyE@ 湞#JUԘ]1NxBQa9B JHIZr\m\YܫhCI?)]ȭZ\yY}qαg!@[B'(TDZF'ˮQ-L2:I.5܁ ۾Ir~(I*OLD &FnjbMa r :T)*-\&6*CS:4+sˉ(@r{@;=ݙM۷뢃ANRm,^hrڶqe N  bM/"8v~][)tBTQu^ =y‚$.d{v uawb@ 3->ĉ8DQC~vM,ZZjo1rr0Qh5E&fqIO㔵@)b&4 h]'n; k@FF1 3s_㽗$C`ӣt\S^'jۆ̰4^iM>ER#q)N/^jRѾX"2λ[)s[)XLHaSՃE~hE>8{]`Ur>KdSm]^`cN{䝮D-Na/yqU05$h^mD ~_?Eendstream endobj 225 0 obj 1661 endobj 229 0 obj <> stream xWnF}W#i۽>8ucTUqAPb@ IU$8Odywg\Ι;('j3aa݄!qՆDJERf&T(b(k#W`2H$nW]8{d;Tq{Nt݆\3A|? Vd\kڵXw-vUrxfs(Š-7yʨ9' ؑluo c_wd_kD-jD<&Wd[4Nvy osLJ~^*n~10|VD]SsG; 6ЌT@EfK[?_ 1K=Eh^Hzg@ǹG(b[.@ꑀm7 9!A͚,4y5l(YbP Ըymol{gQ LIpw[s8ʦ1+ G~0b<^PśP7581=ec Bk}r}s%v =ф#oeBEu͋Da|49ͳ, Lzq*^/3tq+T*+'=T-'JѶ&_N,N 1zw!2Arr6r;g4NZ 8Lrۃtf84!@lFt5ijfIFrW0R) ގ l&jD4<~UXֺpeD*mx $o#ijE:>ªcƧ{(9TgxmZkמFT] T˞\\(Ɨ[gX [GCe&KbB8quIlcj06.0 G2aU8JlL׺%]ɺCdzu=eJ^T"Ź(^` GmG ֲHYlfeg'1ԜـDvVzP Ig'pZ)4DV|ӣg4@Ϟ3 9\)?b~9#wՋPL;HN=eS?X(EVxQ9AY[6Cw&D*z3s f0N2R<1}%>cJ=*=x߸Fe%tʎ֨8=ʯD{yEwߟ$?ޟls}b}2Rjx}BB ٫} |\Z~,]RcWŽ9 E:0[1߱!,yFlweOB m ~_5J1endstream endobj 230 0 obj 1366 endobj 234 0 obj <> stream xXYoH~ׯ跥oاI3k$2^DIܕIͯ꓇d'0` bw_U}o`sۇ?octhfffEGzyfSOjoEanWMnY{$/ǿVdmW/؞sZ81~28řcu]` @Y2SH1\\sm <@bDL'%t8Ɣ[c^gmޠD- _d# I݅`P,y*Rw KMnEQ-$N4RT0fTV򯼮g c*GA#JQX֩UZuX)5 6=sXL sƽ○p{v>I3ޣEyӔ4ʊS@YNb>g,"n7vdz=nY2:SR2) (5BB20se$凊G I,Q0`^-J&14d4? T$^JJmi1ˮ hAp%HQyQ`t;&CWD UpOqkB+۬(s_<6"Ԍj0ыH݇ T:tA1):e݇yX'M'4ƒHH+to&G]}cl8edZ$VxR8|ӝN}m0 ₶YJG!3GPVeBC+O0йX' JTP?F4[]-\ki)!(\E "̂TW?O>nK}BZյbRtA!%t8e =sJ%m.ioΘj:ֿ/WW{%XP_O\v^y֚ٚv1yPng;T@B Ҍ=bntoKb!Ov(穃dXW+i(ܘnp f,O(vs<<*3?2CHj(=r=UH.K #I֔UO^t%#=r~FĈa!Y̥ ǀ"O>{J?/Gb$aL 󺔰Ѹ% 2 ԗJt pc!&#>A?:ё'a|rsh[8uJHJ f0 !LU x=!]DfCźD/߶b .E`P=mNpꝰŵZM*iQwT]g+`Y~q~7z m)ϘX ˌr8úimfOv/[sokR8;1Ue:!e~$N=90RmKHL< `oUBةp^#Ɔr;Z5`1jE؁ޞؘL> x ߖ hqsW"LNа..cJhՀՌ0&6ļ y |aCʋ=džO HTvA;ā 4 e4`8ţyͳjm%+$)q VLШHC2lYÍ;O}4~]f =t5|rm7(HlO6)kVvY}]^4{j endstream endobj 235 0 obj 2093 endobj 239 0 obj <> stream xXnH}WPþ}3 f]GA%$.dRCRv2_BRu@]}rNUOsbYv?g>dc~Y[*gBv6 &3ɕfJav-\&q.Ysشq",Jl4afӚc]aUU{3_wœlVG@>ƅBh}u1|HdƕE$b"$EL ˚  lӺC_2emp%ae6ΐLʰJ+ڮ+S͓"-r U3sز\uU]{VunڇMҰn~z͙C:+'饿 JET*:-&psWy,dסP*YCbc۬:X},*9Xە-Oӝ(diLc[jm#DJPOQx:H3 FTRn@!O8qT86Uݛ5uErZ̅P}.'ql_K., ?ur 2܀yRK4{D|XFd\֩3Ӂ3%#vRSOܩHonoE!@R^7ǃA>IހLgZ\[/8o[e}B韟o^/T+ۍÚ<o["F.e?Fȇ]4D'Ge֭){)G vx( _?%$(mtb+UuQÝtBb^HxBtw'Muσ٢* Bhh &3ɋD'40L|[UScqu#J@hOL^ !5 j]ou{׷XRC`Ѫ؞zvcO+4&o̊Ёy6jH D-[׃QD. "/D}6eAIMMe v4[59 [PW51/wSڭ`t.jW( ʧߪѱToi}Dȑ!R'CuBH`rG*jѵmptO4vnMnm~WUSq y"߯O.dϦT ̕L(Y: tHA+F2GtM7j1 2*1w4N}MBK軎q/{@:+z3Hطp{bhI+?xWpc;T_zR:]z5FV^m~hɯ 6f BĂ{(Ȇ.giF A+aj5|[v[$j:l$s7tJ/!̥Q3Bk[]3\ ygŘڱߪOa]1:ϵĉ SXYa4!BIc;3ld*9ύ 0)W. g k\H7EpV~Z8'lŽ{ЉB!۬vWe=iu JR~n`Zd"`{Tkc_>iU> stream xW[oF~WBs\>JU+TM/TKHD7WD0E~̈́넺C>{bb ((CRx_6b&eӦEdVyYVMcګ,M,/cA'nJ#_qZ$ǃb9~kc?f`؇ooj´n#0V5á[abF882hs,-}$p4.ĀdÆ~zJ+4̘]GOe^n*{% >mSb,& u5IwJa+ǃ8^w}S[N:Vem eSmX',\nUBJ4;oi{0Ɣd5PQcA29VF\)wŻ7tvCG{o[P NsY<$P^Fbܥ%L}覘ӘD뻦jt;vZB ㄠ* 4dW;s]תηy9ڏ&N(a&;i)n%*@[/ T X Vzja5P^>R\ /b.ĈB(k&C.3@`! ^DCY/zGÄ_P0~uo^82h/I *XM*[bP+`M+ V &0Ok9G}NcZ<_ɧ>.&Fendstream endobj 245 0 obj 1219 endobj 249 0 obj <> stream xX[o6~Skˋ$R".h]14ش\IN ;um<;aO^(&l&&.ܓw$%҄ 2_OANTDɘ Mu0mC:+rD4C?"`O A;V#RQzeqyPV¨dJ 7W2uE4I& d{oHJ<@S"'ĭ.'Z(=ZcM6kl fakJ>$yA㑬&ãm>~Z\}:ճ9ݗ@Q q- ,C:.Ƭ0yzCDb g !h%NÉ+:'Pth@WZ١$,ϋXh] NcW X@H ~qpO|Фktcώ{qZV>/HL>1-`u,%|j>~f{endstream endobj 250 0 obj 1672 endobj 254 0 obj <> stream xVnF}WSLzoC @.QAmPX@+L&$e(]rydK9ï@ ?ar`_N('_'B}- qX&!p"$‡q{ԉg mr*\/e2{|8>ItDDj݇!iq񧮕QJV 1CABn@!)b;cC@W᭜ȏjIIT-/^3F '-ʪt0ڟ_ii@":_b/"!~MUOoK3(8*55|Oiu0y׽GwIKCH]cbdmirSԥ-d4?-[NPJp/d4砊J՜$K2.QyS90Q\ d[v4^t "֘u]O\6L7@zIUF?Xɠٛޚ7^ҖBKwB)~+j-%p}c"}'*>ѥk7}^mi\u ڬj#<#Ne9a9: N''\9Wz"}De zj~hw¿~Be-,yyo[Yކ |xgxN9q[*_ɯ/endstream endobj 255 0 obj 1215 endobj 259 0 obj <> stream xXYoF~ׯ E1j 0(r%H]EJ~0̝fcP€;/\'v?z!`T z x‰!1*Ztu%4ĄZq*!" b!`b*aL)G1kv[vs,ʋB@jEd1}a.fAٝk}?n;՟/wMSAݖ9|Q*xݪ~h[m^+ Dqep&c~}`;y_68!4{3&I"ЦນAId.>^|-II$c䲺 K#$J4^[ v t} YB%G4JM0F#~!CԡA>CC6Fޝ;UCC7REw>>q&F}K,WJgb![5lI(cw7z&ݾIz&QaJh cqJL'&'Buy[HfkjDI)X0ve]!>,Udi !螭cR" 8I )S(7uY; _SJbDk`"|B2Lz 8N&z[-E$ј/dSyʎy-3cΊUVg[}6oG Syвͬ{S4ya䳪B1EcG*mn lZe;2%2#iC5gO8}\M#1s"arfl:=MGܰeMG,O3q:8'pAWI2lzGfJdt3KC4!ɸ+xHKaT^m(`ep@0::* gXV d=yfG7K.ދV<̴NerP vm1]GǝP ˅o`BdnÚ Gn n!l_KfEحrip]BB$߇ _97'ϕ鍢MwŮ]7g@blZ]3m>o,~m~/DvzuZWy9Ⱥk7%5ԋoNsjr6^'H2]?h`FXԗje m~I]%v)I$XU sc8Nc3,p 'x,ՑLQӋ_6𮿽= ( q|26/s\UЉ}` UeY4@̬2hOV\ 1Gj,Vht|*V“4>>d SN'$6..׋_ endstream endobj 260 0 obj 1771 endobj 264 0 obj <> stream xXnF}W˾I[;dc2X8 Ed&!)k[7Q'N:Uo$V?rf);͘?Ձ TA'2sN$Pdu='lγ4aW?;k@%OMSIYIVLPy((cIES p'n{҇ OI}efpI~|o67~ =n3.w|cȧތ]'}?i rbVcӵ7Y)E`Cb!RIs66C7Y`nI~x5+)Sܝ85%,*p=!5! cߓt.nVQ>NYrn̉@J@ `s,j궾2K^ 2,*D4.,NzW<[?-$ձGN!4%}l:_fEA˔,o*m͎=LU40՜]@l;7PA \;jv']ZucɹtK+(V ='A%V'@=vϭo[%]p>cF~=xF: ^Ѕk9b@{}cmp4UIS,HMo0PЦg D`6B3Ǐ UG8`-"kG?` CBXglw H"Nj7f4:v X,Mp-C.Ԙډ;O{ ||{ GԂ(nO>Oyz"aW_{=f0endstream endobj 265 0 obj 2070 endobj 269 0 obj <> stream xWMo6W-"bERc lX45ڃSDڒW CR-%mENLr͛73?Oa׭"ح=#?͊&[(Mr)CW k&7> $b^*V 6/!;֛?*UX!Z{A>벾o2N! K<AV/81r"UmΉ0P"HwTORSN&TԬ Vuտn2!xaE"))~cәCս2T唴XP 5rm3Vخ`uƘ%(nQݵSN$89:|=,Cuرf(ƅ㈏ a]gN 1m%lL6atRGKʔA=[~#P;|l3C WҙgJV8N V.#0N]?+xaWʷ) Ǘ-paMa'Ss؂ӳEUޖX;WSC[ Ņ ^@ n~{㧟(ȋ`o( z>RE*V*P|EJI$K_rF+wUIkʲP1WJ,G? "\" fCK5Xt~Jyf3,{endstream endobj 270 0 obj 1463 endobj 274 0 obj <> stream xX[OF~ϯubvnKBQUd'qج=s,ZgscM6팠ŌE$ -3"E,aG(- ,&.9x)dcB"ph58&-n[TP{Xh}򮬫?Xb{F:fz*zn!xA&pJMNLK&=sy!bN:Ӯg S!O imˉDXrSYj-UP&)ODY2WFH[-+m-tjQ^W]VVeAQҽ6x$"r!L&uϴꚲhCL*q2!Xj-ʜaS"V*XI Yp!8bƫ,#Q⌮u25,,RFR`cYÏ8(tSPԍoiЇ\'8 8Ʊ Ld<(p|4PgS.kU`M#[W4-ݫq2eKs*ڼ)z|$8SIw@Sa G &1Gb6K;G)Qu>Mr>*󫛛뛱mkm iǐdJA6_ cj@ NەEP̙4VZ"ժV˲'f&Ga 8Wd,g]$\si^Q_, tq88pTDIl80۪-7C_R ˹#p (߳z{;t@)yDe(Aseg[xWָ"TՕ~UD 93?v p0'ӄ4:@HQ ]2RO2So7 ^L˫ưru(ӝQd| G6ӮQ%ܵ++fCD:q4\XzWWW|s'5( <@#Tqzw(^Y-+pRZP,fx#M 1s:lx)z2"tv.$"v=qj_g67R ڳv":7ºBj`3`GMp6g&._K^'Hlv ڠ=>0 BxTB4+ZPs#וv}!Ch 2?e\ڢР5fƖs\Wi@OC2nW:= mԇ֔ qÏx[4^U##V>ð;c& gMvUVeB+>{uRCfJ\Nyp& g52nHfO,r ̽1iUd/%\ vqB#əΣ">M.t 8)&#(x8"}*wN+zLF_970 fM5NFiv9ݝ3i'޷mq8'uW5oF϶!\&]i1,=S:ت--Pnc=5o ?2IGd #we:yNеU@WW'P:zMq'!Ԏ X3"ix͡g?&r[]x>bWWV  NO s4n{$ =d5EC*&VǾ tj-RN9OQGx&-6{§z n ?M@'Ϭo<s$З:d+bPيDW_?endstream endobj 275 0 obj 1844 endobj 279 0 obj <> stream xXnF}W[@ccEA} V6 THʎ3\$E!sfoQNKB#o IBM lv *I&&ZKHm>uOSk$eLu ([}ݶwnضPC\}nua [2.>vþxjd%?;PUMY]C`koW0˩b".S-ELK9DW\V5, u+p"BoGTfb @!%)M c5A0e_01 άz @؎ !}|N&oAc&0w GBP.dwup`e: cP:5=\\YdO.p.u1<\҅ 1_}t]> Zr4\Q%EW%eމ䉜 λ )V=K84@^.zė)'Q hK,\3hG*X060־g{K&Ӱ&jxD^"@jkxdW6 PP`s&}:Bq!!0!kS ;V00%!胧 {99N0a,e N{G@? V> I AR^M>e)_> stream xUM6WL/Yɰ"%EI6"hua-%G](l€mpf޼y|$8xc~7{sEgyPX_-NA0?=O- f[k( ""?to=ڮtl:xb\%p%}jԟPhi/vZ|], zj>,o nUf8 }쿜K,W/`U{gZ|nasDPf fZkۦE&"bj:j@T*ʓ"K36!q r$է\1ɲogû=U`أgzQVǶUe^Ϛ X't#/]&d Ҫ]F% @L{_ =) "0w]iͤKqŁQY4"{Ru"3fN2Ytyߞ:ۿbRwLv'(fྎ8 /8C <"4od ӻ?]endstream endobj 285 0 obj 931 endobj 289 0 obj <> stream xX]o6}ׯ 298HC-]`bHCX-HKeIڭȼ<C#""?;y%o<5~;C(*Ft)b# ;?f,"fl0bB8 "_y~QhŪPeSYbrcsa/ \/kOb||l'8l#fSڮ.l ̚$f_{YlWL z? 1%l|Q%*ZtyԪ9GFuWmQ=2SN[XR) ``6׿/n>'hLe 5"aBp$w'8̩4m2PA1UCm<2kEy5rXj kYjPF~6q| ZZQwBMQ<2’) MX&4v@%*lKN'z$$EbaװB8!d-4mUg&o 3juE}1 u?׭~)97n6U]%7(F.qkt4ó3q~~PSshH>ůlj+0nyMUVh["`jZp0e0@Ze<u!ֆ2^\tE!vqy8nbכӺh@:OɾWj +-diرIqҽ79IFˈ∺Y!#h-Zm yPc!~hoG3e%2UyյZa  x)h)Ĕ"_.0Xɰwי|X/P#OvmZvsYJyb OtL7Po>X !/k3.tix̽d(a"}W+uJK^lգE@:5ԟQ\zvg掓/G5,oB\E݌ ahO蜘[p+oreD{=FOj(lrk=~+CiSxE,aL&%M-Z-$hS%׆pbMճ `k=Лt199sFru<`apv}&A ZDt s$л3bf v/tD\/lpendstream endobj 290 0 obj 1457 endobj 294 0 obj <> stream xXnF}W[(ênSft1zA{ PRIf@IqڸKKSw9[P߻ۇEH,kw"X/Y+%aa2N$% Y- pЧV<4 %YEY_AL-i(x xa/&.YHC`"}GhKw&Pc.gI67K,d̏͡9b%YIs84vUG#83`ӭq  yy 7Oyk⻲G;ܿ~Rpv]QWQݹZZy;`Q{8Ťtqy[EHԇ>xVIQǧ7W1npi $495 w{41Ic|Vݿ7?C*dO <Ԟw;նTonGT yjjrYrIeA^B[L: r"%5\C|ڍ+40p>I(ύ"EׇzH4i?L9eԸn'E[k+0O$ }v g1̞%5sOblJt磫ù="m[k C" j$|0W 5/Ha`8c!>HVK ƪoQ 'h#xV/'Uuͫ!bbw[$M>1ר-tM> stream xW[o6~[ byICR`]`bhCiG-~/Dkyp|w>ESDO,Ϋ튠늺E>39[qK#PvX10HqK'kH?wŌpL@q+(F7u3M!"Gysޘ[H1#z˪3 *[ 1ԘiB'S aS;ӘC{@KLR0D麲:¥@t(one4UGUݡAO`4K%QLIaM^ACBQgٛmo7(AcY['_MqUHړZɐȮ'>Y~M@=?>J; áKD|btU=QX H@&d8՟MAJaҁ Fk*x4xm5k_6ܼ@#Rn+3_7pQgߜʶ!- [h8j2Tz4h_k'*aA7plvՏʮu_u5KWNlb97V$󃩬gQ PT2gPݯvWCLnnRUf]%)st%wB3%c\СKYQe 5m rYC)ǔ 4C?IAڀ̪<s yTߪ{MqE݀~jo}kEʠfrʩ |!eѩPꮱG⛓[튿mpŕ9&|F΄E l$3[t"pm~_0Uj5̼Jr(mށ^J O} ltI,1w.(ӈ[^Y6C/ \n2e*qJ om-X|Vɰ zR 髼KkS>Rm ӢCS㐒w:b k3icþtj}}xT`@Ծ(OI<9ҷЦKh>frK8Ύ &;aپɲ`)67ѡ6]zvs"eKfsU^}go ?}aLȱ?aV^?@.S0Scl͗Q . :zu>[B^I`BO  9qhןBZ2{hʆy!z[{8bhЩͥx-KtW~~< *T40* #ycF(d'6AF˫>o#L H.wf֢endstream endobj 300 0 obj 1481 endobj 304 0 obj <> stream xV]o6}ׯO ?$JBׇ AŠ!. E Jr"eYb 2yyxy0c~G|q(ӓ`~Gx;B`-dN?:w̟pl5pz̪ "B33} ?o<\IZ^5d)"z̳"_L& qܿ'fjź3Hڴږ-V-2m[6 xm꺪!v@yώ+I@X $ɡzN!iTn'2mTég+;$j>fjt'U:ou?ӱΌBp|mN2uz_myL}a-Ӷ y#;G] mF""xpqJ"}L'4y;F?=C#`ټ {zs˪G[isځaCZb5f# DL QHۨ'LFv.rUfFg春32?8/H#=t50hrך6 7W>RDk"2|>ڠ6QDž$t5%1IdI~ C?O4 א(G_;8r ?`W%bBm_ZFI(V85c4#wC^Uʉ^_!Ȩ2YQMZZU56p҇\ C߾vT둍D!?"|苖%4jOW+ҵ';t] ~Andvy)6fTI]TNlG L.mZHM 4g$ F1"(l *22K )C5V1Ԡ=Ts7\]Jm]癶FK> stream xXYoF~ׯ7KAًG_Av+ hʤC;{`H2gg}CSD˿/Gg m#6o#j"GgG%HiDG EL1R\x*',"c25!PD95ecBF1F &GBb™ u|HbWLb4v|;Au cSa7+AsĨ0bRYVY3G ժD&'"22w7ؓS_A:/˲(51:ØS,oSe;8-#7Pw *YhGQ/seq/}ERU+O&A"<%UFP5o)b;?wx0-^pؔ=Zu^%z9':E~_,JWU[k^jxt` +t, 2SX*MߦLt%6*\Qp/jJ,R&M5 n&7(Ey PU~o}ƈºӹ(e IK̬&1`J1XrE/cpc W׋˫Ͼ-I(ؔtulXEUQ^Thn*@+0P'A$"$ `8Xhĉ _UɠV/gYGwc"4L`)Uܱ*˺,WaV@=v6ۇe73u{tH֎V [Cӵ} Ξ9٭ᬭæ޽%{|Xߟ^x/p|W+ hKWJcИQZc`F4gݠrN1os@Cy&3WS2>)ZĶ)Ab+Jv)/#z~)}hpo-iYZGӴ.|Pf;8ЮC8@ܛ]`ewuP^Z izuPB6I1NZz#8l q$0}lNp.`Cٰ89KC$/;EOcgdDB2_Dg`f822`S UmLͰC#8e|Cϧ77Ӌ͠(l SQ: |&IhA\0njJU%0ގ)2a-bx R#Yiv=F7G$M@"r~"dA{!j>pm6EKn^ְءc5!ZŽ%@RIcёtN*)B;/p hӳL Ngq@e(` 'a_?4P@ xڢw~ydFM kS l@ՠ`P,5r>^Q&endstream endobj 310 0 obj 1803 endobj 314 0 obj <> stream xWnF}W[(\WɁmڠ " TxЃ ٹ93 0}ǏjAa`>n61 qؤ֐9ƒβ%wOF6Pda^C)̫daxsյ/˛W?.e)D9Ȳ,J()K̈́G(>n _ ]<-,3H}| tOQnp_}j,!*3ǜ6$}|IH2yEZ~:P{f֦v{a NJgwϝ:5*'ϴ !mΊ܈ n$/ff`g5Ck|ǧ{aG1dk]½j ^,eq,ے;$  QUq2>iOn@(ىU]^}"̎5+Kͬ 2~ RV2+45/Áxi~W$:~{(#E@7^lt·.]S2]Ro|%UWCfVO?O]߮F!$m{QFjE V [[w=Z-PM%HiqAOA=e *Bߐ~yUG('#5oA9VsLgVSZ#4CYYp,*=H=\BGY_.FnsȐF|YkA|S"t?xY!+ȋQ@:a BKMB=F %Z/YHYtEBx-3~8Mm\?m(&8 Wx:?3%ÄNmXT26#l`u*W~28mUǪӓaoTF婴 DaL먣+a)U*5v!PO5H`Xw *Zg h%ɶcCEWmnNy; !Ran#8e1ZY=f<̡D2v6%#T^9BX)]Y$Mrpsʼ^: P>$-Y Yw wYo'Kg(0i[ʜaX齚-qפnߧqיW^g[*8GGT*5퟉Nrp_ *pd3g%./g+\/n'tNtp.q2\ 7>کY$OQQGyߎ66b(endstream endobj 315 0 obj 1362 endobj 319 0 obj <> stream xWIoFW)i2 a1 ;(r(ɄK\AҼ{")"~f7ڵ v ~dm(ɀK PR, E,b(!J:\xluZVjDŽh2c;8eX%ї:_ M>@^UWk{^62P/y#Y>NbGưk>̒}U*O)訝bΝ <'>U9=e5lQY#4p~p_çcD \V(K[5MݠC:2 r?mί~\4X0"HY{ "ny U3xd/܇Ňw`*Z-03 ($Na)Yc?A6-jugZD9 aQ~L> m[nCY}h[/`>=>,c {P=@Te2zɾlQ!SM"#sPLf~NlQd5RnG͡l;󺂎CpC,2 ] 'k yn?/i=M38Xqc"|~J͉'-,C؃U4*zy0+jƊreɶKb>kǾɸ x tcg:/ ^M(C2̔(}C=|l}lk i9á4웶2)vdqwCe;Ǿ b3nOm5 Ln0։nF-b#Y]u)sʪ*IwFmHB5a9i5KK1T'E|VD(þ0Zj 4iW֕Paid @Ę gLхQ:]_kyF\t L8 +b~<('=cm$+m8r\UT*8LӠ3u IIt3 u6gp HcIHh )q^\q̈́M5l6Te}ܜs͹Vx#;rB;t}EB!zV} #pwAM1w"Yrendstream endobj 320 0 obj 1400 endobj 324 0 obj <> stream xX[o6~["ċHqCh[1$HR]Zd~7IVVt;||F1&(6?8,~h.b[|^Gq@? Jh]QI1H2ևuK[-Xwv8"Zј8hdh]. Z]DK\\pcFSp׼nnuMt41q[غUfM1nsPՙY6 ZT6jc-E zDfR;"v;U!ݡ/ lgL"042p̼ 9)dwisǟ1 #h `D.W,%8CE%9ΰ`Z uըSAQ]>e#.I,!V} ( ʻѷ} jA8(Bp9lFj)NG_ 43`ƒʂ"c *FbQن1q>|\|X_>?Lv%3JH5 5DKhZ;TUjhEhf, |MRmM(X&I6 #f,8T _R uXxf*MqU/>^=B,GSFp lUb{d4`px[  Wr:sn`KLg7ÒeӛLl&5()^jIӤWy9ԭ]&t"n૧(s`sD@HgxMOGLH T1Zi[AΜ\G.%0LF{ gTPm7z(R!$ 1iݝk*筍M]S2d}֎4@` PGRw,T]9(ӳ;.N >s`0aƝrt;I3('3wCԕł1c4$qy1cCMm0r|(&kA<`qwwS5@}P (/U@kzLE Jg'4JY242L 4#͎3ᗅuLenW^%F7U\CTmn1?Թ\l%Ax=;vK=)w#~Ӛcbi N"B|W@bxe<{S[;Qۙj[7&́yALbM XPԨ ,G.љL8C˫>јƣ IC\X/~:Ɠendstream endobj 325 0 obj 1539 endobj 329 0 obj <> stream xX[o6~["x"h[1CHt-\IN"uqtNIwH_3| Vݮ]DGGo7+6Jeh]a.PWWQLH?6=DTDŽK_QmǦ-u%Zo\(n;[+Je~`0%z#hۦE1]ʈ4R%睮QգXZu`)VI4 S;_M!q169|}? % *EԺ%tT`jr?$u%Y2s#/6[T`)nn|w7FU]VEW-wYfkA>uy4 tlRI >+7"IG PtX Of{(|};FFp"~6$6>^_|\(5>.3kbD-7ltGESyUOJ3 '*n4Y*Dt) ,֛͵/)4yjmβ<Yy^ !)6!5 8.`8J MJ!!ޯ#V]UTk*=!τd"8Jí;憘'NeXK0A=(ZH) e`,hc}fzE3c~uR26]w\ٌB@'3 =?3;O/{ Dyá4h㶟νݺc j0 $V'=ym ;^&Kљ&ӀdĴ3r$rʓѬ{:fͲVL~XIHFf!ټxD%&'/NS#t0$F'n8p') .;ҳewбj7"etc@'|ΠϼIp&^[ HO^2wm>yr>19*<ݕ:z!s$$d(+ѥ9&]/SuzǼ}D02ZH`HB]lVT?zendstream endobj 330 0 obj 1885 endobj 334 0 obj <> stream xXnF}W웨>p&Ma0RCR6 IQ08;;sf̡F9anvS[0euClvB2Y w *IeBֻ(NVBHǫ=č? &)c췋!o˛}V}Z3-h-M[Y 5&K7$DZfނ6.1IrF?M7Uj*E^~|͛} )К2.#j4SЎD8!e $i"B.W>2Y}VmIQZ%T@I\%<0 aS&ds甫yHn3RTi ߗY0Λ?E(YVEQ`T0jGcPM1Wh)bno ,WLEUKRM"0_ Û|\4G!@$T'릷2gkU}WZ,SC%&+(o =uML0Ɲ{6fTjjhvb:_cuo ϰ<?EVIؐԭ'џe]`vn}sqVE׼.+L7a78Iw9)J6PhvȇIwlb]b70iU P$(Fa&=\vXX 1+slIWs jwԌԤr)ch"AOPH@0أr=o /p|֦-ڢ+ؒϏv-ĵR4a􌜭cO>B`7.X#gH&I'ibeF!+" >!Bb%̱H֌m>h(bf`hC F ;JBw4eYَ2&DvT#m0'Mv$ {M$UcUMWy7%5haUEs A] AM]z~;ϟ)V֋n|4{X0E3NeaO+πشzY[O!`尫j q2H g0 [U®ȭvE^[=ȡj@設sbo?Fo{t7Sj=eDm\x=)}窒uŸאּ:%-:x ZQXp~:7H uyN wΉ#X->J V5`]6.YO۾f8t2!vYƣ>14tϴ}0>ͭy^_2hendstream endobj 335 0 obj 1596 endobj 339 0 obj <> stream xX[o6~[!x/[/.Э[[Pl: K$7~Inm\cBSD(t._!vGbh+(C¿HS ). ͏^Z11!)Z 0/(REPѡo?Sp=ͱ1vcH;޸1ݩڙTLoSoM]yG.W\SLF+:Ig7ܘsըhV)/;OIx0; {;Qh҇2c4 <45Ugao]S#XBHUtgʺo/,,\}7//XNek+37\`lӱ *./]œ()&X풀5v Uul,$Τ[xmP(X B)l2ZMMsLkƚ`F/ޗCS 4IKb;*?L%!CipS&k}T-֔xo;zOaϵȾ \bf NyI\  /xH¾]$/-/)R龨K=HUo RLi#,;LdX?Ѯb("^+`L } ܹL!8C* SCu?gY(&1OԹ!T.G4?aki+tdA pf7Ӷp IBDfpE]oo67~_~l_<5=zIXGv/Nծ+e鷤Eio84`q,ލ|g:$$_- Hz3k6G3h0c\˫z[]h:UWSddvmu }6\ obJ@ ~JRҁʶ.@S2P| l# Z;~N f)e_LivI 2һ$_JAtVB/=GX("Ov97P{k4/ͨƽk !b" {.]e^_IBd夻d =a-,0x/:B b4zB#jk 믂#QiҐס2Qkb)E u?UTfP)@J}X+ӏ¥eFԏtaV ԜTi. CXZSH:#2 AC QN^K8a4h<42(&/Qj]~ ݰ@X@ص̪@Ch/7|򇇲0? puw"Ќ\[EG3&,P<684+ŕ,@k=J-Fu Qy8nA|xǀpp%M2g]YG٠aX$ج@n{O> stream xXMs6W`z)P| xL"%MSYiNGCT"J]DNA\}xvτQN0e];ad7aTG!Y}i手r%VϚ;6պna]Q*fWv5 ue]͚bv%0D5BIBv=[_ Ru&M[ldSay`o"'#;>GL_ | ) Qe&:2zFI1vBEe,u&۠|ۺ9v]SnϏSR7Q>\y"?__/Xuf+'YR@Ge(b4Yj)ɂC$y@=}q.r8弇%=@AaV>;|54|WjH+J&(ʫH]Y!$z@Xr'vvF8Z/N3MS7(n; pS1P;B1Ϋ"+6m7?2 q!} FY] "h.x{Ui'u^ʑ:`dCNm _ɞ|f}"K DS8H^D$ZTA&4 v,Mkcq:vY&TX; ]D-ȃYp# !gW&[A3 @{|q6sn $<3@궰FYVy|\K;ޅj _SpT׿P7Zz&,k@ph^BkyfMyhs}2R>(E -MN҈ л<(V\^!s^aRCI\R^:lR(<VS x|d,|&+ s3TiҰR8. nr/\]AHڔ-v%4[+x31V9:,=f9"|H%uZ''iO+<Jby$g۫7b狗߬Q ū+Pj{y S 2:NR.wzTdP.;ec'$<zUx: C g2|dp֬/^P!} ɞ4Q|A}Q^'1ڵRm T,m Wi٘7@]}$ݷ5APvc?n/xL~{ٱKBqNJIExlǞ$ѓ5uW:i,Q6\myY SƲՂ qi` OtpXO: M ͌xG|7 ~?A[҃5,@D` eSeI sFszs HtSow C$ҳJmċ(BqMq0flne*4E?F;F0y44ˍ(ZE]\W0b:ؗMI@??\@NhxR7wƖqb/: soiu;`" ػwj' tendstream endobj 345 0 obj 1919 endobj 349 0 obj <> stream xXnF+fW0"9)6*( 0hXHCRqtSxa3ssψ`qmA5ZћՂnIDZ "2JyVm%!I {0"F8&D(K"芾 W59鳳m}_y^.U{6o }[=Ta% }kMb*mD)Õ;G<)BwadU[GIp9]}<T c&(b-q"<]~ryF"aj򩽹Cn)ãPӒ,hQb0xW^]Wv|m)ɛEI,ebIXn~xoȬ=WgWP{_~Z ]nپF0 }!EPup-`Ic5iA"­1:` hT^3{yStnz@%)] [4IXaʉ[.z|0B@Xc uջtttލ`@!%)]۟*F3X69M6g3hV,ď'>F Kgz먓t[[pX{j͈'7dVcr+)ݾeuʿ|Ev$ 5uUr'of7K\'g8eOR1g@R9>B HavL/͈t٤>'{Mw;u '}q"+%gCх[Bp818 @/YѷK`,L@bwڬhPIN7ԼYA-L&Cbt*q[-uUZRA B6o0Md?PawE֎"i:_fW]QHQq2 F(D gPnkMhes֤ݳI_lskOA`&ǝ2_}>,n' -o<6|鱩V!G>ngZT`38~L)Ai>)TDrp%%Qyg'pr*6!i0~(AZL!t\\Ͽ gendstream endobj 350 0 obj 1716 endobj 354 0 obj <> stream xXr6}WTDq#>&3K6q:Z2吔^`N3i2I`D`;  PR5~ܩ>h}`DSE~(hzw?c7)B)ϱ(fzf!Uixq3ώ8ZuZuQ-!A]k1uW=Q(@/y]#V Gltk㤡{{!S0DI E*V>L |BwPBjiߠ:m6F #I='U_"r]َPE!Qt"I>/+{J#xDG-=qR`˚UТBq$S/2dKEC!?xfHʡb!#8 k0, @8Ehz(Zn60C};89LʘietW{rz`V蠆ɂݯeb1 eKoPx^;{6̏y AMIɆu$zWC02XPPSHORFsendstream endobj 355 0 obj 1459 endobj 359 0 obj <> stream xWrH}Wr 5b@jkxHR,'%%M2T*%˹L1f/ mgξΨ}#ߡWGViDZmfn#E,a pVe's&ID߫`6ŌpL@EljL,ʷYb i5X5dXS(P4u6C]C7Ŷnͷ:<mW7muYul2+fiG1f"Mm75E77fË%M&y߲fsmBWܭ d 4,o~tЦ) -MZmYW~싉Ә1!͗7/__`jRq\Ybڛw8 ;vgibVlM_a'J%4}8 8'D.>L1dE3*gG@MWD[R"<4~6o 8k(.++c8a#3{tlfW;qpla20':MI-,͛r 8\`/9s3fb'!1b};bn3AL!ϫO!L=S'dJK `,q=݀q8e)puV\A.*/")B0ž>*@eD4t:T1b!UYW3 ){ve8ߍXZUDc)˷hWp -`me`{`}6ڦ0km56XrP僑v衆k& 1J"Q s9/W\q8$ 'K>U[ze>]u 5a7ZE`&ZRٗJuy,UjBX.%W{zɁ JfF'%L 4q9 S`j$e 8`?Ll5}nzT30? s,jQஐ.%i,Lф }ͷˏM-csgx( $G)v7kk" $xX.>^Ct̂>auf<Gm#P.< Jh@:z;T6ЃiTE?@ڀo,C/̧d2(sy xE|ba‘83j4KB,B_dʀ %7]F'|9L'~<]!pz3-WePbP_3l}߄Єβmg5r.H"є2a#gU2h,MXXc6/endstream endobj 360 0 obj 1547 endobj 364 0 obj <> stream xXr}Wm- @T;'m0NhH-/8_n\HfS[~-ݍsN7+a?w~Z^}`du"zu Ⴌw w%qB֧ŷhBZ!S+bʘ$+:}ɚfW79c\P&dť|껂d a-U%?XEu|Bx [54 >7goxeW'+n qi;g22I ʻ$5FN=1T@r*o;3kMPifՖEג^tB+8[?㢭5O(lEٱ/lH+4$j['ݡ魃s P(Vh@0׮hI@sB2twM+҄9RT]JJwS lP1ݩtƝے4Mc!J͹ 7c]H`#s/8!+n&%GS.+SQU$ ?^ĥ"}Yq!(!PV{Fi, EOXiNunf*1K3.> 70gxw}Rx]R1QИ}12m3|WuV 8Is1.}Krʢ ,|ھ,AKMqe9CG^P;  @*tό+5_`~Xi =#A*FT  ""KvAx[Z1ɣr 88[,g)pym/4v,RAayG[q٢ea8xFPv.g5FňCvLlq`L˪*# y)}NHh}` P-j>}'쌡5)91^@8{v:YޤxrT٩+ !v( *N%p{4Y8_dȩ CrQݜkh0ycº|FcTvLiKhDULN.8o:E6R1!ȆGc.-J(@iD+7:)X O%ږȳh0Yp$~|( $o~/w_.=݌Yy)]< ַ U5;2iTws=káьEKgxBcJLWOf7XJH=p88}KOp7侼{$ >1r>DU7@fn7&A,A82';d [\)G_SAy2 6XALKI\!r#!ixn(z5w<~:'ۓV*h"5 ~1qsȦme._1"(A #[+s\r?]|FwMxFg!gV"acaElf[y9mwn|'zq)\LoZ_ IȏYg+Lтn? }endstream endobj 365 0 obj 2144 endobj 369 0 obj <> stream x}VM6+<5(@IT%Z/l%!`&i{|0F[Oݯ (a@?֣y- !m!0l=\pA},a:1*4$F_-olVEisJ~?OHAB~LoNU-~$B}j n 1=ږZ*]zx7 _qt=n;1 1TeBΘ?Ә+uq͙^aO} :r.%"N\]Cق\QF1$4߅EXxv2$Iyzx!:2uBLu~LֱRS}^aƽ)$e΄KFwG*CPbDkFg=in\:ȇle.dbprs&`Tp r" 9wg}#AD9x x\.t:V58{&wY/)ap< 8HWv0|k} Aa`)t oVe.z TME+RŽ#pThh6`8 qd^T׭#?r8У/S' I|1Su8,qѫ.> stream xVnF}WL_ \ F*35 (q)D;i.orm9g.FA\\ؕ;B%4?\ <")AL&j:1'ek'njnFX!Ë$Fkj>ca"ҲZ٣Ju5]I8c߾EěX׃U{"/`ĊbJQ=QG\ 3~BQa:Cs]x i` ,+1Ũ0 ,ړ9fW-V; IyG"Zы~R Ce($[%,WbǴ՚{-L#_ o{Ex,5qt M5qpDx$knv|S=SXO=M`-e#Y9faYpqw:P;Fu-.%ӟd`U]9a+?*i!Zn7v⭉DuNZ}@ --ϲOj|0!O$ˡۿ`T”gk1X$ j4>;L H`f9xU7׬܆Y*f T,*66(m ..n {ѕUu{ FkUp8iqTEuGǘ9ۏ 'p^v 󝧤/"XoE ?WoGڧǝX$b5U -1C8V.=O۲|S+ jZ%fA7\\b]4<i4c wl}C]ʯ/>endstream endobj 375 0 obj 1090 endobj 379 0 obj <> stream xV]o6}ׯO) I}CSho,іYJ)ɂ1$q0Ks@ԫ[bæ2lՋ?-\ e0_A gv=o{4ML?;yhB]ĕ ^7xck &/ʠh]jhq„WᬨaW4?G֤((_CRxKAmw٦ $ywh恏CIX]^_sc>vl/􌨋mYiI_KQu[c ,u6(Cox :(~W/7O:$bE-fRۣp(XgBJ(m pzkq!f 3 DŽqTԽ2wQ^;J lPɒhK,ayTIB~]^fvCx-Ӭ@+Jy~1A Ny/PX_ҷݻS`@ͷ+ N\ܾqqh|fz(aPVU9>;Vsrٶ#ZkDEm)ĥR,/4PfֆDU SZ oxTNk:]ݔ5T]EȟDVq;jzO6Gݣd*Ey#3Rݙl)M|HC!ZG3[>=e3X m<3n8.ŞGb^.rU0;T6s(^C-Y )t)QK^D2W!%^ ;0H <2rwd'-8lJyپNjcY> stream xXo6~_:E$JksC:Dl)_;R%n1aHxwߝ7a?gPdqX$Y`.r=9JP%c灺GG\@0I IdY$Y>1M(OIqsƔI{?fzUmެt5O+iM9ŌӲHq< sKnM^ |—k4D7䷪-7&YdO*gU[{zЃy/>ۖm yR6(C`&똆 7ꊔiyu^O,> ;f4NܑFwj'^CA67V7oޯ~;R!,LYUVwSL:eQ74'cRG: m 9 zULހDR鍸jm51ؗgC:0%k`C:CFN~ 9A|?J-KmWaK*:Ἱѩ0|]2Hc)Fthԓ X1t鶫AfS"L t钶n=&7H76îl3 gIv=ܱ-]+^OE@]i3HB}+g^v'#CBBW+[l82e`(UIOg N55u>PS$ ,\ƑS!}. BBY{IqPMVmE$hKsgH,s+>60F*uZ@h̢1mIoH/$|4%|<\S^fTFܪ PUe0(OiA8nA+4,4J-?Lh!^DJ[R1J9@8<ڎ`(it9u&JI4-nN!@8ٞ Mps;?e- VC*)X]\8F_Y/+ [c9o୪;z%َ4QoSK65:Ptr#1ԬO le@~W3- m1}B2ZEֹ֯vI̼x`pPwMnUoVo:,2ؖz&3QANm+ͳ.b.w1) 5ЅU6xkYv^ OV ,Ɠ~nΓZH5V;B-ww] ^n|K3*uwX kmu6y:*YrL{GiT j[D nj*cn#xaiۅbц#bA2u䎎湦% !F=bNyΪ:Mk7 `4 98fZh(Yuc&5:dL0XILpp ?x^sendstream endobj 385 0 obj 1518 endobj 389 0 obj <> stream xuVMo6WV)X~Sڤh j-0dNڒW IQ9gy3gD0E}B>"%Qw}8Z#rDb D}*aep. Y)#"P*ᨊ8kؖPM3 5cXjsATp&d YpqYASm/fXrrH!%s%q :%kgySB &aMBmJF`Pn?0:4JL\3A{^OYM* 3Fi`~i1qr̩c3ړ3&B)>_l}躶bu؃U B)wr|{=6)pЂƦCk1Eu-:ahѾB UFL3йfXHǃΠz^evk΃v4K1iH@eTtKx9M3գ6G8k\S=*ZI~h!|1`3-iByC7&pi-f& Y3 |k;g1gzb`>hsL rm}KM$̦ES Bts>:h:561f:Ս5ѥQ؁|U@b:+ӗ]}p{[|vSTi+ztc_1d^r3 4 J@s6Ͻ~d&6`7Գ`Ye)"ԓ羞lc=g$Ӑ%XeM~nmL6B(Mg{ mmv@o6@..t\qBܳBBn'M6>0g'01L -/FcGquYm?^*D襔3Lmޭկz2%aX<-.8=  58{nή HvHcWg ^:'; j&uםr&߃v{HY/Y~zZ?|Z.~Ҕ|ś!<;6!ZO; ڀڪLT{ r-Dri}_Y7[$ч9b9DՊ.=,?ū[endstream endobj 390 0 obj 1179 endobj 394 0 obj <> stream xUo0~篸Aҩ*MLxӴ?1hI >ߝ#3އMa81 Wm\z f7uL4ܢ;eimǙha>1 ;0sR,Ni!⥹G|.Ȫ@XRNW PDZG _ܞH:D$Ƭ\s.Ow,oH1-.+ZsƁwCYIQ EQ P5h+5P,қN ]RC~hocyz Wd8A{ v^'9~2 T:M{ҜWD C A=( *NX UT}P+yL:eMS )ep{EW-}%or\b $%lQŬqE,eJ"eyY JC [R+B%%;dHLl!wRcӝfklYnM[ R@ shS)JvkیZ- ~Ɏ@Eژ9*a-kV-WnJ4abzU‰wBY~E٣Z5m"!HWu־⯐2bb+I(g Si/p!y~΀*&H:ͭGRㅍ}0p=^QQx.WcɓruS-3 fpe9s0'Yx Kp:endstream endobj 395 0 obj 805 endobj 399 0 obj <> stream xUO0~_qOBe!A=)2Jb;*P`(ᄏ|}!03 waH+;)z!$ϝ&02"~thqܹިG;zog.L & ?skΠZ1(KiY32 /Ħ/+ESѴLC)ViQR .*@/ضwT2їfdJYǕrX5ybAH`kd< N#c !%L7TΓ\9g, CQ5䩚cg䓃ۊ%:=yև ?A]q-I*j/t9)=F2|k^R.Z7 @ܩ.OĪsܶTfãؗ_wqĤrֻx5bqdz+fN`*, æ )T 0 23&+}C&D?1LY )xbvvxz͠|E[įR@E| (AB gG"y6ꕱ#ī U,͒4 TҬg'wfE%ëflP"-FډbTY(m pR^~.Q{މ[=E+52DFϑOowOpf"EavVTCۍ@/6ƊĮ00Y<9 , <Q^Sl' HG_K?endstream endobj 400 0 obj 763 endobj 404 0 obj <> stream xYr+ `|:՝&%hT YII|}vw&]$xsߙ߯?)v׮|v}%K_vrJlw\J d*~۪|/ݮVm#*p:V f6U7ƪ?}ͨ]Z%x aOYWD1^v}}$Q<%W(^(7u%O(brp6}o{^_nj"f2KSFu5ktg,U+svg05.GKCƚ:_!}MKrbrG dJź“^jVGM֗&wEu߈ &뵠m[վ>!i(Y:(ߓLCcBΛ4u_nq Mrvgo$T lH.2bveKwp5}#cb2/b.e?$THdbD6:}ff82DP=cķ=^wYyn{A7YW&FMgND8JfNHS.< $,܎.ZA)ߝ 'b$)Ox1~_? oV4RLxoǀ88_ލR+r(Y<= D 5Sܴ7(=Kzs҄*oDZ$ GzΨbڶXM\'f&6بaZtS[Ͽ]/U0x iWv{^ˎ W rm՝"k A!mD7^ḋB ]rL~|s=8n; Y#+?Jt]UE#r!_-^Ħ̝ R2.W#Rta&SYkDdZ&mد̀>~O MV7mބòXZH9Cg[}ny=h3x\V $Ga&.Fw րІ> Cᢈm{bނ`N(J Ue}ą`!b@b*UD$w ⡟Xw̬GRAӠz+Q[  M9XZ '4@XɝoqMt_zfhtYS0EFS-7M Ieݚ-y4A_Cɭ}x(3lh} iQAY8P=z ;/k2hŇl^w(`> stream xXr8}W-@Sٚ)W2lj+RQ$kG"=$ۍ/Q.$88}2]?-RrX`%3z!ȺU0N/8"'cRKIZOMSIV,-)x^$GCvB0s$,H{|=ޣL>|~jMz7ofqCkK[wW9MU]bLƄCrR3[\\(2asjaW`4/ bhcҴOq7yV ;Zp(b,\&w洇؞x=KgكN ^8rWY6BTq-ȅ]/v4'v9\R u _ ECmS=LpFRM]ODqcB3ؒ_jRNL6"FvysSP/:vabvw3 IqbIž;.88Gw<&cspzzw7o߭3}͟5m翖ɥ'{IǞ4C4byaa|B[rGڜj* H opi +)O@:7!U0;Ǻ'@2\4֙߸< w>G*ց ЛŸ1w^%=β\K4=cT߲ӉX*r7gL`gHLR),nHdZ 0sgMwn?vlawvWSt̹q łnϘmx_R|aQ+]戗 ⨟ŕ Y;Iqa=iNPPU;1;dykY\Qqg#~6yBP,p4ԪPPl<'%洯Ҩ(d@z޾T]өq +u ̦n'(!A Aw F_X1U3N|5Yr %+hh@eT%)ՌzPM.LD1*}tƐ7NH7${(q^R4 '?]Sf#M=Ąػ.%6quXPARW,Kl>HfhY[W)Jrhgb("Ƨfz}sF\˅ãOA,VBoXz+{V]aISpUB[c7 9A˔BTiZqΩR;WQQmeGl/?]o2ľ2ݞ⡡5:p*& zNL O &l 6zӓ]~) WXPGӚ0hEs ><]H7f4%BYLl93ͳP_|ϘޕhJ^_Q%iSɔ wopE斏eK!)h̿\5>s^5uo': M ^Į tn9v_}?kuf}8t007Z\vRqp壁lқ,-Xm!FD)"}kED"O7"T Wv4ɠNC ߍG^`vh P.!qЌp?`nݘyg2jD.,cAF+0h|QhdUӈpa4߫"P;13m%*2j}9ܵvgɔ[rܒ C{ˍc;i*yӜR07,s|䋡Gͻ)a|uu҄?-lAswFM l3CS+hMv6yײ<`>?E9endstream endobj 410 0 obj 2002 endobj 414 0 obj <> stream x}Wr6}W୔B />3Lph ⒔{%`{ſ$o,ٻlYH6g.O˙ R8Yg #|gȶ3N]Y~8K|3XHp ϐ1؄F\ !hΙS!fnZ;OkMC[)$SݗDﳕ^g_a0P&"NMŌDwG|ٓ()z*-ik sZ+8$z}!RîkzP 87RRƢ/՟/&ҽvŊ8 k۬ '@ԋcf g>k%wsL]ؼ *4 Vyi%bpK{BrMpuݓ*tGwsj6˭>ƁK G 1**I$f̓F$N\,)f@r`D31CUC C;#46xoRsIedy=%&^pRvr{t|=h6]RЖ,a LI#&qasݗFC\NQK#\XI9(HQ,ތ5Bu+[46zpL # -Jyj5~& 3MH!R9) 6T㒢*e!qLU85m X~b;-7 9/zNCY⧘EhDiȓqѵxQ[{,EMlsbgwZ\\#$/ ;%Kj^ qbvxpa/v:fPlc'wнZ4ag9lhP}+ 5E%]k1~LTUXTT65 Ji "N($Aە \" }p4bT|&n>c褷y3M3kJ|lKɥI:j} x; Bh} Q8^ گb^@&t"3[AJ*@atձ/BxxƴbBp?LSq ql9+E&?Xgփc2܃wz]bp#S*oe*LA06tP7 DZD(毓>͘6z R>t}~, 9vP,T6UrfrM/ڿ߽1J>vZm%gNI`! "捞 EANSr I4wھ\~N#;endstream endobj 415 0 obj 1681 endobj 419 0 obj <> stream xVn8}W̓KBR E_PA못(BP$RR*N{.NҦ^ Μ̜uP|o].Cشb+AWC  uC>%ܱ?%o,\(éR*ѱȱϸsÀr B" . dReK.e< _|EvQ,8ɚu6L,af Wk? TIou#Q7Y{CB7dD PM% Bq,< `Vr:+אEq[F!9Y;qMm*&j+f'q<}-"a/xDB9T]mr'F,~dgw=s= z'Hje!P(a uﳲhs,rE$+P+.Ҷ>41ݳnWMS|ǣDP4MOnPJ81S1Fj݇@'S2UR!G]$=l-d6tcfne+Y8ZܭW=y`as5т.Iſ oߥWo.ʆfL5;4KִZP>k#$wL-ryV; ü@o$dC3~FBQZna&Ұ%|>TJ\l^/{1p-]s\Ey7oK cELqD$,.:1 DPY/m b%m -80Sϴϣa5lX֭{"Nt~#Eut ),`'^!fzG>GxU N9!&Ai\%_\S`vendstream endobj 420 0 obj 887 endobj 424 0 obj <> stream xVmoFί~ɁlvʩkSuuLeCpS qz,a㝝ygfP€ʏ.v2΢po}ZU -*!][z#qy!;o;t\%RJ>m۴+IU.GZnEOH![\9RBo].^"frOl|rطvm"ۈ̊_W|Nuea~gMvKH ٫HN?c7utB_".. ZbF*O}:˥$<Fr̓oa?2Ų6jy[uVԒ&٩_1;D]7-fsgPwGYJ1Ӓ-0W QowHGLg/]u_JjKjKkcQN6͸Ra҇ "^y_5uwkدDV .AJ> stream xYrF}W̛-qvn=:S7Y)ł†VgR6%%3}?ݧ0%>-~}lc!퇬}b?80zp%SڰXGl VR"0o!VJh.aE̅E~,Tm@L{qctF?gns6}pt9Zqx[tLJVn*!\]͎uYu ?d˚&{an&sRh%[Ic}f~yng ;|CHZeۺiXWyYImmu(F LMFI#8ԲIG} YHa/ysv%fRJ#oCpPTS"#֐*dxuzz(r8OEYRRݩW26\g_7?{31 R|.dY5R 2I`e˲㱩MuQVd⤬qH+* Ly: β2놫6$+td[v8ԀBϔlEskDEHU@)>8IT#fZ yZZm=E9PtbRdcNj30XXk̼bguǺ݀b1.iR2j`6Eǥ & ~<2(6W=$]H;NPm!MY(d"$ELE:  IZa!oa kbִVL8Rk%l(1e86a;HJbkS.!ߐ¦ɩ œz7z=׻ehEEՖs-SJ@C5Y¾ Raٷ(rb[ڒ 75Bl1x2BpsqJ1׺ rʤ\q7 Fvoa_U]q/FFNxDHNH'O7b)Tq[,GX 7mKOD-%eޓ .b@CR(0@ZS0ȼ #΋9,'&z] f^!FT0"B}#8+ `$rtkHuHE{3Fh`PD)PHu|('=:WH =9ߧ/SU}`K2 o|>V4D86\s:@s`h %<_eHNf0`fNJ0<D_^Mle( 1 }-z^ߠR|_^4҉F4 ,YjC7y۹_ԴL.W,ϛ+-HE]pN* L B* dcvypIY}kStX ߖ|.Ğx=Xʳ=dm Jzt×_)m ^b!a1UA|bX[m2SEH})ܙǜ!D1C*"K)}KX7REA2D`CcϭO* EDMh= , +0"TVM3DlV$]\E)gK[`ΰٺҥ諩U~H`i14Vz-۵c=U7*vz4{O'+1%g{ö.:nڦ#>xAb)TK0{GZhZn*kKFC6n4,Sowx@vUܗE[Uػw#l!gjztHCx"5~&ۻ7`=5';|F&-S 9s&IF̈н.=߬jj^Aaw궘<zUWl}߈6]*iL.'v|3XHwxvv{&tu\\g%>l||iLBJ_XBS54}N˶itUFMΑ!}4>geK_]ES5u7|^ lГ ~6C'2LMw͞}nC_mQ+#4M:*2\HPJLR}~p(4g̐`6}Kg]m#iӔiw ~goe7iD~rlK/=C|{'S[v%HPuV@$a9N)xd'&iէendstream endobj 430 0 obj 2385 endobj 434 0 obj <> stream xWnF}WSB9z/6M$FmyW2[IʱQ;ENBmqwf̜9C% uzDa=1}>LGK0]!r"<Eq1ONrYJ=p}2KA>&m.s-V3ح!]'ŮPx>J]^.ṉH'JG2@&XhV0k/?Wgc~fY f޼ɞƷszRyC`?6JCAhIBs'(W}ؖXJ9\e:lkG~R>,wQ6Pn6v˦&pr'LrQ%OTjQZC󛏦]\\L_ qR<L@bBny2p 9={X-t蓮BMgiZzPv.S&ÖIa( Dֲ+^p[4Pj(ӕ̓vŲʢF֍LRVMC݌qzmNKcy1GC"ľL/69elL`j E2[k fE/SLG2kgB}~@ FzP}8CH-])%$BusY8bKTUcB|qZg(9ˤn6 c7BE:wz;maZ*u}J[pG#A⎡{qIK[ T1]9j*U4%:(3BahcQ`c<B8 %*^F;fObֶLZEQΛ!<" _q||QDiGCs5b)tB$cm :M@- ϻ j9^c߹X {CUqBiEbGiDA0nʼ0TO. caʶo73&,P?:n*䚃J .)BW?*؈QjEK'2 x"G6%|F=]eG&ޞ__GJVܶX,1ҤI6KޢвțxIp2QP稕nF/f ]-{xmت3I,ؒn> stream xWnF}WSBf/DNI u!.J\IL(%[;{H. ŝ뙙`ؿmv͌CdlrrR1 -3s"1qϏ,$.߁:31!Cf#L8{YBEUd-VֲiѝH9_~4q6EEfAzdZλ?A[ckQĭ'kP ܘ b҆oؠEijM[wA-Cmݟ)ܟ%! d͇׫W^ P?"K ^ vV@;Ze!QCfK@+P*X85y?` q돯h'8v)J&cGpC-&uyd1B>IO 0g1O 6]LLQv'8IPx QW7LAX> %'~TyUtg!y%el:_w-:~W5yϟXbW4c+ŦDugzteN뺮j$;F'ڶ}dFRssigƋ3n4X-L<%ҕnzq1}h]>ퟭ%V .^ާF",V'}qnd_,Zi3𞂭"GG`1fZP 4X$eXm9aUy_? IȩU^2FXLwh5 V6\ l UGLI݅س`£yR9pJYZem|c/'mI/pbIHR0!xBR ǽ>1yP</=Rk lF@SОXqĎ P|lLۮ8c#u] GpdiN7:3XMBqb׾.$ixPfy: COFmܪe֠"\M=\~s blSݒ¤)cb/,=dyme"< 9e6_i!=PCB+OB, F54dL]5_PMU1T`A4MlK3-T Zҋ)r;'E^-J~SM kGʪ>x@:XQ;] X{>oo?܎'_<rPO=cȧ\U ne |n y? X ޥeFN#@Q7w @cendstream endobj 440 0 obj 1623 endobj 444 0 obj <> stream xWnF}WSLfwyGnM&u!*\Jl%R!);ni-K23g~JP2n&u;|0#O wE8,>Ȁn3ܧN8x9.ԃ %~|&] H:K;RhY&ڶ8l!%/bcSJbxߧM ۲풢wor>G.1^EBG"s]vFTPհh?(N4`BuCCwuO8Iaoz9%ب[=N"zѹ^c0 8u m0 L}-ˡe~8>=¸kI{CҸ睢C0Ԙh?VfiYc4Ș*(8$aoQshLcJ(20`62vKֲ{?5f(g'|{'7РO,=ȢɊ)[15IPg?A8;@̡$a`]!uΡ-qJW_)h7ОˆM6\G##zs5b!h:ɔI4=߱]eݜpNeܽ4z.~[|mE6=F*hvga1J^=WMS7 Ի] -v0mӳ-V@gBY>~P&S|T9WGr ֗6ft{>8_[n[s"u6ء 3zF( ,?y9Iw}j |?rU9Ǿk.jNI rQ,BcrdѾ(2<$]:ҸX^=tMjvŞzQ2_mi7I[# uQ{rN4-6N{k˕ kP72. =YqnǾ1A"P_g3*pi@¾ > L6Өdz+Q~4sދgOȍNɑ 0,R5&Qp'דy)3/pc PD'Fw8GN )PLӶ6V>BɐL eJ7⑪y0;kGq FES/.-+;ֈ7Rnt@q;v`}8d7oOx2lz[3ҏd=rnU0DOeљg1 6Pa֋Q90A:>{W=-EմcRcŃӽE2J9!)|?*#1 \nc%?$?v8ˬgQEڢf 3jėC)rnddK<%(R LRVEԑY4"ojh#rUDw6T}hHc,EXh ctLlvo-9QUBZUa:(tgNbFF4䴅4 N]ջ};UOpj.#sOx~zs + -q˚!抬-I֣<Ť[p/nx Q$Đ#hVT$^FhM*72JuۆH iuHbhY[&/psX,endstream endobj 445 0 obj 1731 endobj 449 0 obj <> stream xXے۸}Wbjjx{v[>SSIP,O>43ٚх@w Bה"d>dKyd]/$[XHn6FLKRq [- &$ZP0Tll]H.b, P 1n˺2Ӯ[F,$2hOǩ{*ߖCx+odzmo̐8 [E6<@ eAQL>?O3_뎝 co,#V"ʉ!Ejc(+J0]tv!Oda?tnw+FT_<ɸהmUS5{#m0žM3S Xξ-Yq:Xm1t 15UC:$q"ۃX(YnLa4њ[V]lG(D(<%ɞ0l[hy,őamtGTnϹzl4P\!/'| ];DL}7 Max'lX>d(y&GYf}/UCHa4 Iw6 +eRx2z!lRw旪?, D qAzr*s=;G^D$!CFyfHV9,Slɑi]m0p_4[ve8py~).}+UZsU<h W18`]۰i҈YT Rt[Sg b2AET UwCrJ̿TWTBоq6%nWBQ7`(q=!t!lZdeN7lΘוơb7axG#frŴ#C=Mc)FS;+tIl{W2;rnd0βn`V~kRAOws]t/Zʔ{zuy#K .dYt]]Lb,g h`p bS[zO,!Cendstream endobj 450 0 obj 2085 endobj 454 0 obj <> stream xXnH}W[(ewܷ;l`=g!TD"=}#)Z@u9uHH ]gKc; ی*Le+I'd"!>X9 [!8bBZP0"r=dy e:_T7_.f QI\3eT&B>P7}Y| ʪeHگfY@TWWd;~8pj,mْ^9VEWUKN{u%pWƧ'l(\/7:QdJʓe|iHQ8'G(Ho-PMX(9w4Βpu֤۪L<7ȜCh9M̖!o՚9P7.jʽ|G)cbbO D E^2%ę+}0@"nGP7Z" 3|mE"^L @oڞQ7UuSU[P|RxJ>y*.m'4b8i,ɶdڢ)Єj5圡r@}$A8(N5mHQLO@]Hr3w|dQ˿Na}8$ۉI#nXl}Q6 FeNՇ ^j7mQvi6XQC:.¿'zf%4DS|'9d2&754 8]Đ9{m~td}P{G$1nM lv>UmX2WOlV.wlW- S+Som4G@sG ;t6MS7J_ě†kS^'#~0Oi_mNIؐAs 2Tzf`t4z(w^ =0d~k'g,h={w,m'cF4iڙ5:ݘ(5dwQZ;jnElMa4MpyX;FߛXb&c:h=3SjG r!}^ݼ? 7cHcnCzS=Ap]w 2ݶ[kac%c# l>F|%Xƞ }>n?,~XKb.As9 XLƻͫrC4y2HREי=xA є0T . >=͙O8:wwh֏/DS3 +zwc CZf-B`-2SƽY.]&ҕpe4ǥc3f,K1Gdݠ="%wTz{c0S| ͺy:Z:AekS]ijׯq_H'{72)_^_]Vϛ0Ląa[ڥlnDLU_0!)xOr#xAWW55)7rkUP|ɛ )!\GTvӔ)i 6Y4Z܀&xAԮUF :8m۾(x?y<}~3tX3d)1='F(I cI# &=>ߎlO.4˴ Ҩ A!^x2m -ZV,iD~4^]9C,)]ے ˿O| q\,\MZA E~oTv 5d" N(_i!Z 1$Qv*rZmR2+ۑmI`!= )9 YW?|~,i8&]Sի&?3ȀZk?t7s_ӠgX~ƛxr!2  n$׼:j!) Rٿ?-endstream endobj 455 0 obj 1963 endobj 459 0 obj <> stream xWnF}W[(썗[[;@S7F]5AEdGr)J6籐̙3gF9a~˻l#ٿ3nW#?-f,rJ dDPH"c,x P()F`q#EvegҐ iMuE狏3 j,OߚM_Mx7x%sMN8Ȫɾ)#Zwr%M9$9G<;D} ^}'Hc<쳦 ^ RXS$)x#iSEC+>TUI9zybp|6ұ;v4 غȚ0UZ@McܔTk.єDc"Esɘ_~S31U)K!f,[~]f;HHm[LpyHnno!K%]QCD8)@+bv080108FL,>jL^o⋱cjo,.., rd Bh):Sm ܜxX`xk49eh''@,4j08*x|s~ )QUw/:v-O(mB9ms*4 t۪-můj6$ӧ5{xp]7s|H@XL6'pIb:9;zHHw|g0endstream endobj 460 0 obj 1585 endobj 464 0 obj <> stream xWoF~طӱ`M*j]m°Nh18wRݙoffD|b}OSE1<$W'?=AJ dCFx©$ރf#O`<4$ cTz2>zokSr<,]#ܝPI5Nݏ,dJ%g_՟-6*㥼)K'ۼUC=<=÷6&B;Aw=5<ldDGz4@z V%؇6z}LȢ2r!n0)fyvn/ѥ%pucɱIіzXm揳1N={p %)r(YD5⇅'R ɻ.?vGnHmVS 90hͰ \|d9췺3NR5xh3\`ft I_w`Piʪy#`+04__tWu35hsK kKsP*JL3FtksmrH("PTyMeh[ c1 -|c"+p(G`WM^ /X59dxjέ%/ԏgT>]OH"fAP ŕ4>Gm*ZNXźvyw2{&* Բ\gf%y,4M 5!) *>2`uȞ٢ qTEb%.ެ0V|J`eBv>U =f* Txj9KH-1Še0'9(xYĐ-GP} f(p%puI K1Y*(`tJE#&ȃ4w4d! iSj`u[lcp%F(gk[]A'stas :`:7<0WW-8|*2wR!䭟!ek4fփ&#|$zmw-˙A5rN (!6 HC*eve2P4ʜ$Q-/}H?V]߈Q!wF!zu36֬jrjn3t;Q<a̹9f#/[PzezMHԪ! 5s>ߍq*WM 9l抻t\|v/!ňřì=#`$ta 4@TOHfS$HYby}MsоAX}<@X Fc>`o|䍦QS4`8Kt>G)6endstream endobj 465 0 obj 1385 endobj 469 0 obj <> stream xVQs6~ؾG!@o@5MZ EpǶrޕ,p\{~~{ A\|#B ]Ő0CAQŗރߟt!~-Ny$ d!g, - Uzs`u|&xx8C,dx9[~70_ 1T!Mf`rW ]+lwC!6+bN0to"VLԕ+ ?O)5->F`5ilإ#^Thk2` ;_}I4]&AE TWj3*1Br *(nu.چJ׊CGr]˪k.9h&|hJu^=B)$o0 Tn+x&'IX}lf( Z.~q?>k1ߘnk;CZ7`Rz}Gz ÷VYabWG-|υKg/׌X13Ö[%G^$Xs% mXǵ9#WS?Yo E\D,Η@O >&k~BAdG`OcTF 6K#cT>rP>rj5y +++5Tg 2).&iYr3)9b8FAy+QrKz4TofA,y!6Grv({[NRivz40sA%/8U<ٖk\(gp>p)PsX!b22.MWD3$ng7NV7O )5!Fv~< i1p^NOzSӴ;Uvݪ˽F&puǖ^E>V4cKvhPőE50H}M?G;¡[ Ɨ=) !";d伏Xf^Ռendstream endobj 470 0 obj 1002 endobj 474 0 obj <> stream xUKs0W,4imׯ3gX&ߝ~'hE(QPb|xEJ0jTZz%zMar gJNb4腉2nA94VdT֑D#TDSgm\J΍Jzj5\pMiظg3#Z1\sv(ϪS*w-`ZF _i9R}f$V |Qee`NWRwtkK|WB(DݯBH En N=]Vvb/7YG*}nL ^]уuF}-9zɘ,9r-pPL="|W-E:&8,~5q 5CiCN|cK60Ng-1*7f̺].tpen*wm2XmJzaCeź,=ηr=] 2L͵ $"C'ZQ0GvE%l Ҝv<29}mZS/jr9;B"5U&x^Rfk֓wĹ7ۜ6*"Hh&xݿVN+mJqٓ voy5VVr벜%V,7v`nBG5 ~W˲̹$~u. kcQpr7endstream endobj 475 0 obj 815 endobj 479 0 obj <> stream xVMO@W̉8%6ᤔ-@UYnm/:Z;^D3͛ٱM0ħ RaʣbJ#?A ]n^c0-p#4-??7UnUmҵ:кw sRFiecCx8Ieh#F!-=@́=I/YNsYc} 9᪟ca|I,$LO|8ũ08Vq|^W [8 2Od+8R,WM8 b*ד"*^dH?94u:G5 y"(J:G`dmR ~@X |EY <ǣϖ>>-2@e+U\endstream endobj 480 0 obj 858 endobj 484 0 obj <> stream xW[oD}ϯ^ՃG+jEEc7^9vח>b'NX"g滜s3' PljCaiA"_]-82ܕe* 3\jgQE=3rň ۅWuΚk *`um6Ca߳fܱN~H%$@'d{n Y$aIB)\cRU2xY5xi{&%2P$JhcX}[HF@ 0THŘ ;!Җx'A 4={YlXH#ē,vy 9}B0e1rZv\1#7p69o~h| gG$$N*XښT]i;I'k?M{.AC T"ƙPm ݐey] /ePg}ٌ4[X#%'}g=3(2Jg8UlfRv<̜u@Xl4uFH[6KM3@Td2t(vhM\cY1RIt`ĄcH.΀5$|ѻ/v9SPpcu֐kjd4@3ȴɩTnG,^$Wy37뫛3PVMLtD1wc1>Z/cџg[O>^;=X_b]Oc/w-꿰-D+1kIB6H1k'#@c/vf[v'ǬPt5Ջ&'nU|^(E;U~tWXd?G2Zod|+}6qKv.:$$O!m񭘅1:.BWOZendstream endobj 485 0 obj 1265 endobj 489 0 obj <> stream xXnF}W ҐS[;@AFaE$Tl;{H$Μ9sfO a¶Bz<~yE0/pW|㙃XH!;*~2 GsԔ C=:X?f6žd,r]6 R/\/uܡLHSʵ5\h;(vy +JٓEW7O~YWMS~s95Y$c1nGӨ[VD Ma6Z#S2a82?wxR%x"yQk4zul`=3X+660!bjK0|X;#M@7Acq4${%jF v[U(JHBBO9~!D8&N/}MQ2T&O$vA 1QDEL$E_Ldh/Kig41"#~E u}q cT$vzmcs.97' )'"Ws7endstream endobj 490 0 obj 1550 endobj 494 0 obj <> stream xXnF}W[(/lاxH0GIxBlYPCR(_f2`C~e6rԩjBH?/>ӰH(_ Nq.܋S!I&YQ\,yDY+0/<4I$S8T-dAVEeKJ=m_~^dxdt+røwzǎ`ƴO߯ q )aĦ{eu0Ω<\Չ2czKm7a$ u]h9HDn-0$H51Z9Ssi$^K8ؚZij;cDhBr6+{ӎNm5[  46M5\3UZdyٲ;#!Pv9ԄG$?Ǧdh]uʲ$XlԂP;Ic L/,i σQ]{SW*:Q,|4~Bf@ ڈfdI9=1 rl q+`ٜ>C,oŭ䵕CIY1ɴO~>#]y~Iń g86N~rIDrHM,J%R[٪5(wNetQ}|+> stream xX[o6~[ fyDbOݒ+sC:E'd8;IgP {( xxxw/`7z)8 ǜ;EU5jʸ]h3pP<%X:8*U(s]T DlR@t N}_]-/-kuW%ޣDc@*hYL]{1CId{E$@fl)MDE+vYTre^4K[ޟOCofAL,ܫ=J\قeV`tt}qkRy+e/D=݉]NOL3iA)4[_ \]UݮVmlT͍nLz싩늢h;#=d8ʠhdTE8;C4_CaISKqLc,:B3Ѐv.KF T48j8S2H3ǁtA7@n UqLdT`5L7emDXD nrѫbc@l>#c9^3 ,VI2=zS8g4UgC#"(/Vj|cN~PƟRc&0Nٷ 81'#,N0 `~u͜NgTUFYe#38Έ0#9;we7RiJ3 :GďǬgY:$Bu#`uBb#1[.o9 w?'$:~0x6f&G~/1$,=BJU =(S"&';AV}>no>CiQ}o\[;V)4[1{S@R% \qjLU7u0ޡ6ȶm !&Ϻ),Ƴz] g>ӽ8 aG@Ca+1 IEs r?qFg29C zU۬yD0ҿ)\Ӿ_ ^,&o"Oendstream endobj 500 0 obj 1607 endobj 504 0 obj <> stream xXnF}W[)Cr$ѧv:j`E$6EIbpwgfϜ93o(Eg?h"}?1aWE$3b&r?{tNE0g!F GGHѲ1LZgĄ/*fbhaCpͪk$i* ZunXcٮǹ NSjH(N=nR̍ӲQOnGXYԽzux!KD!Xϭr4_5kWr[u^F8[<`QZts3)jaYw *T^6e~xmYǧ <`ڶ?z)xJ;[0}=`+;M]=SBDz!5'RCytPmWuU?c*]&h@R|@͢& *sRr$ٺR",ѐ3<_U(OLH4u>}}SYJ]P֍QAxqS*;!ܿ +==$Ih˝BQ! iGH|mX}F]3BM02tھ̇ 7CYoqC4I}&fBmi#Yo '3kNuS'd+>,JF޴M]PPe@Gp84modP@%rݘn9-3:/O*>‰8a J$ga׌Ɣ$ ۭ2KVoO|RײY'i5T:U-h.h>6ysjVfɚS4'`}RI9ec!N4}EsnR8*J/P䚰$PD gy/21E?joC{dkۤLCS波ENءhs4Dд_;I'c5V-jZ(L kЙdCӹNRG'N]RN~!9,dP&zدԴ./+@LsEtZ o Ŧ-8$'3EVGaKbJCP`c^u d t8|w/ڙendstream endobj 505 0 obj 1792 endobj 509 0 obj <> stream xWnF}WSB9zw\Hi4hDhȕĖ"^E" [wvg ?% qiq>CpX|^0s#=ϛ"`6Ȁ˘B_l ,$d RX,v*,aH}|t./ KMSE^fK}ɀHXuE;]2˦UIFR cKg&Be[RrsMuRYMv|mVC~(pZue />W[t.tnoǯ꺪AIZ5ܣi}O>0jKa7Woyv ݣC[Ϻ^d#~ϞFc"|?%Hk5vҭkXYGkϵDP!V\ڊCipТ=O:BbP6A4 L34Mr5٪1z1⢿z#;k,Nk;F)tiT,$b6gوs8#'a*Eiଭ{Rfp۵']=$H^ 3F9LP!b#ei~^%QPuqUc \ Ђ+Dpȇǀ&a˔c=^tc#dZ:l۔v)VGhpaľ8 f +*_t$w;2 |5̷; H߼R>k_5Y`6<)Uu'jLit~&>]7QQ[8,XCVy~ωÖeIц]&ZOܴ#+Ό{ 7uˮ(唗YB-Jo LfnJY a XvJ8 vᗘ|v0ޫ_u _q[7I%=BFW/6??WOendstream endobj 510 0 obj 1734 endobj 514 0 obj <> stream xWo6~_qOZHJ-iKC\M;l)ݰ}GRdmW!6g@5k jfyD&4;x;q.T t=)0Og)#I"j|3^LHqt-d*3![+KV|34}y/a_=zRxXμX?s1{1S`uVPWJϒXOCsśݡD 6 q"l`w*moT UHDD›eTw~Db][y# olCCYU71 F'b?eH6.o\!dBXs3;CIY8az_0qa0qgW׃$̥MG ʲ0 \aYwDG H"X=o9f.J}_^. SB{6Zg4ՖE/,ǒDܩV;p_2ˈ"XfuQLgc9焆!̆kb˱CH8$Dٍ[Kb fHiVr=fzs/۪0x >IXC@Yj杚8UVͤ)Zeb3~É;Z7&G| +}[ޥ%h7wvN6X>ӤkwP/ bWl 7f^31:kM8虵]}I{ x'>am N^P!ZoNkD7MYkʘ= F ᝪH "EҔl`ԣMPղ뢬ZL0\ՊRШI޾:!=46_n?. _YYє4h:r Gb>PʞAj`U˥2XA0%spZ!C]&ma6Y*r|5=8fU1P+A}~S6(pb3:_PN>]+1p0áHCAIy`N> UIT~2Ds\ _'3j]4󚓠nU9ք "XJWa%ŸpVqZwbRݣ# ~ʯH-EfKCY,8P73laVs-K)tɵc20=BeqB`<|a&av 8Dwp!vG?[^Զ+7zx$IǶo@Q(s ,? QNkp cqH#3/*~o>u_f֥ffO.gN ùDSM(JVro^xeóK!WʵjT]w:^H,& }S= XY$ҙ7[endstream endobj 515 0 obj 1591 endobj 519 0 obj <> stream xXmo6_oHqZ$-x+f0R+M_$;N|pw=wO` nRM7#h34r^.f-Jeh11HqYa[f a(G/A+VE3ʹ=ehq;K$3BbY4zySԫ|ڛ4W<o@ u?V¥즨QD5ӯ)H4&CEbε "nUEeљ#kE#1Lh>3uߡEݵiCQNX#"`!C ܅}bV@Ϫ77sjk|9j4"J!=Y6 d8D#0 `rLd48= MLh@d&1!1KՖ3x-{q3 pNt|u~:(Fbx&`QԜO-ʋ:v[[X5`ud]UCot 7\9r߶{|YqVCWIp}C)K[cQ<|b /3Ʃ>wQ,ӐS"sH_PєzO\* KxWq+X V4 DGG1/./^ 2%5ؓT` L* *yLEL>ct#  #}v<v|@ڲXD=f:o./,.:'qG3BOruGzfn/p/;SLNjS5=C>*(=QP9 1>R-Ovz|V'Q@aZx.hdPN/Π6MH Dqi<7PNvaxtD =6̋kzuD3E w ))jE"Z#j-%QXO)ґxFoGfu\bU180&*R+^t֓DTlP`Ewv`Ө7_UB;ȈC2 <ԝ!hUwJ7Z j|uRNF[|PIIp@H=J-pZ \4ޤaF>TA{wv1@rށO> stream xXYo6} Rys;]|Ѣ"ю [J%9AM[3<2WSivq`SH);) O%LtLΆYevf,o{X>Atʻ)p RWc I{gMB34hWvz=P>la,ِE 4)=Pq>BZ`IM`} .%?_3 E7?۹g0>#f)L\|_@~Ÿ`at2BF6C(u./V+eKee HU REp:֨>M=?T} Mm%#P|:kɜFxvx;cC{1m.gUN d4mݙ" 5?c0LQϥZy=7mr4y 9zlTCu *=Iޡ}S-0 4*b'Hw0Fl ͸`ϯһ]c/3Rt[ĝmk=͒p2(fzdʽž*KBWgZj/&CjHt-+Ph#27ChJͧ6/~aBޙ]B40ul:^r{{LU;d?iNS#_MU<6@]UEfg-m(Le \p(zk;bVD `<;(@ hp°0Wz;$# fhlwަ-tE)„a>Gw"p$uנRYlu8lfӹk TSt% .AmH7-TׅG%=V8 N4[_'nHji쁴L|t3&MW0ƅ'a?}>EL UPП 4!o}NJӡD cuNtn|UBAa6~{}&|m@ҤP̠n 5ـY)| *R[7Wn]*k9ZB%e6ꯤSMv)N&ӧ I]^`{zW%endstream endobj 525 0 obj 1821 endobj 529 0 obj <> stream xX[o6~[bER tEކ! Zmx4;H0ܿ/aX_:;bW B?hZYZ#Z۽76)+z/;m1zX\ڷedU97 0!&,عBRqFbI O5`@^~;6F4dZr.~ke(%7@:wN*NvA)F~ {ģξ 4GY㙃Q}^,˅djKVQ0V`% Mq3z:T {8m*Q-#+$}8g2sd1$4qh[;6=Z@%I;iqeFuV&(2"N1DЧ~γ"k #*A9/-?@4qV5Sg2 B@8!И}orI"lऺ{gS2.Gj-)]+G 鬩@ouA'Pcz>ykrs=RǛ6oTQcJmD(+S3SLjh GETSe/e.|+RUNR@7RQ5@u9wN]2.w\0>&1#b#UiFÀ~+xjj(N!#ǪD"E4qf;|4 ~:YʷpGC^Ihr>6Pr~AB=vQY5 %kp*Nr-:~5Uc$^ pPnux L;pH&fWI"L*FxX*BBF#Mn <ϹջL5 9ӃE\0(஡67׫&ۀK}U{n$Ht {iw6U#;ضzjȓf}eC# 9}֞$ XybC WP b1D- PV*ưL7K=E\~ZB3z^9@*n{sRR%bO J_}t.jIS9rLT¹cXVd¨||v0,j;^З\Ҍ1{Ug4 g8ebb9uÚ2GVon'7PrWF!3*Bh_/PPzYz3Wendstream endobj 530 0 obj 1663 endobj 534 0 obj <> stream xX]o}ׯطR.?[EzUk@S+D*$e.IQ"$qggggΜ3W&d~U¶LLE{a9lY*eRf7J%:f,|'V*e1-׳@ҏW2]JjحU֏yYʮvͪm@Lc_8O0dd Z4,}{T;X.n;KsE3x^]|}3Wk; ujxɛ[p{ojVUmjvr5G{;Ǐ } Xٲ}EU$>Ώ]ew,'PpBM#UN>(q`%%ٶ-ɩ@sN̥BdiZ^_fZe\q$}ⷣ7yh !Lc4(IIFjnW;~VYƍB{,Hl{۴c 7l_7[9؟;48ơmWo:GD3:r0j:+;!횲vO7O8) a.P'Vse\bPK.Jӧ&pvh2, ]=]:J8湓C t 9%y E 3uXp^{(;-WvUmwE_˶h}Y]ݐ-ݜ,6KӠk3A~-+Mc+EC!zP4HQ~i0ˋk'pZ:DVVq]{JAM›g@]hk;ktW!2^Ŝv αoWW41F=SfJո염:bI,\Wendstream endobj 535 0 obj 1903 endobj 539 0 obj <> stream xX]ۺ }[+>ݛM:ͽna#K,9 HJӏlV@wrBǔE a>dWydlmJ81!fIURqrgyM„\e\ad.x4 y Yevb2K< Sw2f[ ySuˆxjtƎ]zԬGl#vnG9ϳp(<Qb_q `)=GQ$qD"_A!ܔA.' zDoWA Ux)9!ϝ:M]M*n'mcq 㹀CG@NNR܈aF&y%#ISć+^D˩A>vj4*ȍ,p:\On)T}Ia^6_idyYjx]Aچx늄=ʻv__ePzaHбpucTx,Q%n 37 W>F0JUy$9y_<2Ν,=Wo|Z4b oiĀK}\+N. a<gvJh Η$Th;$s+;D㓫&B?}׿cݒsMIKNǼHp0ةngo+hd{fEf)Wv^II-}1M5xH_Fs Y* _;M8Q_>SMɉ|sBqZ+f=Ϸnΰ*LDYi !`7}x|\F4G+!, (`K@+O#;ݾ/%:dM&^\zK4gڶv/NF^Ab?kgnx9ҽ U]gNK!ݮ>S"86ΜpxM vT4Oa}xtWf>ؖ1Y"_1ԏV ybІqM" s􄘾H?z۟ /Nq4}ςynI}Zz4Î i'ւTnH!?N>$O+2\t+:6e!X"|^1 [6W3n) T1sODSZBb+r% _-r"\Lc~}xNYk^_BZWl> stream xWnF}W,J6{NԈ[EmP؅@QK-E*q79s ")"~u͌~'f&U mH b}mN3oE盿! qm3hh%Q&{Y}&X=|1773//[Ll{PThf߽wErf"*Ǚ]yehafVeY]<^6{@,qJP= &ʗyU[sZ@}Hz+p%XݖT6 [T˶]{Re{u a loAIij= M+n2P؀^RtUm|t1BuǪ;us\|G<~J6/q㌆ icA̘{:KOK &Fވ{YUD]PkcV4˺2mWsNh=6z kԡhbD}jY/k -:Hs;ȫ(VS8aaX LC л!& qc[kk+lTGw;VC:bF{D]Q8/ݜ8b;( ԴGRԦZؠ@$vD-ҨǡnKf#S\qc|˞yinÕu]Zbaw#mZuؑѠūFD#9:ML.sZlp)#P5IPA R\2PDGqTx@,1I^,Zna)Yյ[H7*C=EkyArüԋi\#6Kp2C &pXX9h>؛kˢ_<Ft1, ,CXTR;A,5Ď=j=iIo<?U K#-*b79=&s{awn(,KnQ Dafȟ }\WTjIiJ&y&Ņ9vd8 =U[Z@t"}qe=ȁL@N$^0fq|ZU+Uwtf,qA&8) 7UOwF' 77 ;{#Ad{3~T4No\\:N癢{ޏ м`0&eO@5F`)k_ofAD]endstream endobj 545 0 obj 1685 endobj 549 0 obj <> stream xVnF}WSB9⚻C\ A]!BmX@+-E*X{gwy9E ;;3g3)>wծ=XW kF%_B͂0F+(pr!jAGm)#A 0tC\]?ҠuaP?qK&>*W{l֐,xKm|UO: Ep x}Ȋe+u]{w,JowY.Wݚ}Ō= 4+y'|Y:Jd5kp5ױ1y_|$m1IW0WNnjuU,޽KL L9Wײ/6y"Qq[_Ry_phH&eY7V1&i0 JG5v7XC:c`鈳@U9`؞>azbc-ֶ%(Ny-#ױۢ<#Yac wMOSe,`)nWQgzU^&smxiK埕rRUe8X/Veqɐ%ZA.>X',CT]01U#:P7e);b8*Ȩef{ܮ~ݳmrnuPZ26*.]]TX"5$̲٣& O2Ű;͘+= &8DMPn)\)Tb!\*}ZoH80iC}؝C3+Ňtc8]!}CIx!cϋrO9ݖQ=/ȐÓֆ)lhP5]QR ;臚pv-,Amd@ߣAB۶BHeiUTV<[=y!ҁ0)=:`4  㲃X.zQ7jrk.uIaQ/^VH/?݆jv4Nwp?~y@] s`X;T!mpq> stream x՘o6W-r`%=nHP+6 `(2mk)Wߑ%Y}(<8)ݹ_~fɇyՄC~d;k2(@*Bd5i.Rd@!(M@Ek13B$~MZ%!^CFlOi-Ĕ2^ ` &/(: =rC8s]h#H7V#\XV?4n̚%T=V(d*DXgL0tzuaNC"z_0]2}EڋTU@)҇ևvNkVeרޤ52TB *վTFk=y4F^1Iz-U.ʩ0kjc=,lXǬwFF:j~#]4>Zt+ Q7\l⮑-mg4 ) ?8[!CN\ 봳IgJ}:daBAkjjSORAb*n̶TTC\9ϞJ,yzAK`h^oVejB~\QaY?b ¾Qm /V9t)wk1=N@WfzD1a7{"΍ӵ0uuO`EJa70 B>'#hinΜvբXV=#v|En0"F:cV&ej]382xfDҰ :ĞԈb$$a̴yԣ8< pC%# r 7bEnllPV:͵m5C9Vz\a*; }jk!PP4L-hK?T85hak&ߜ+L8o@d)q?CM- z\hrIbmPAWd-H, %DPT3D~h?g> stream xXrF+&P%gvrhfqI)H H `K,XNrJA/_nD0ED~jm=#h;gFMd?6{z9hS! -әy"G p-3ǥ`RW[jA#ke#hPrtjӮL4m$ um'DV,zK6sM\uEz{[7Cw.MQvjj~1 0|]9UVK&F.QNV쉛*+t)&pqIŦbXCϗasmmuUi>hh^~c;~U$"AwjQPsyܱm>}4%j23NCG=ꫛr͝| "L͑ulm5m3υCEX^d{0O)âh 2=0b^R` 'ProT" $s3vYwvi`!8OqX-CuvP|>zMlTAVb { yPUC 9g!=ryRҁuam:Msoئ@XC$tUVUV@x >ۺALeb*J8A<.И1$T``$|LB]67#/F(8?^DJ5$X%Q@MxKMH/д>~6oP~C[Gc$-L7 9Sn"Ÿʯ+@|]@﹩׃~FqdV:*?>&^͊]$D̀ҍlf%˽l=e:0l!]hdEq[cza_˫ &ۂ GPG58}jv+<,,JFڒmAm0D^uթ hI6P |5=RbQ6!l4X \!6 Sc?yq ?YαTendstream endobj 560 0 obj 1631 endobj 564 0 obj <> stream xXYo~ׯ%!NfַN}]45YPBR6_sf"7}( K3s;gw(' gqXp}`d}"ŁedSpA69ȉ3*CȘleWͲm%$xfEKD^/l_vzzlvN$sdpE()x],%OmeW&e#v#ҩ8]d_ڶ ?V8(0 F1iT}Գ$ h'*8@9hfCF39W=^ۿO%J/'&ӌ̧bݩ Ԉ40}Crrl %K}:h۲ޓ9ɾDje%dLC+rF YqN_%H44;P2޵aL>ޭꊶ|ܩQhx,(bQ$͜FoڙB{/WfS<7>};D%nݚ B&hvl\b3&MM44pol~-d61WEU:&_:JIC@"BTDLy{4<4>z,Apֺ{sfs#.d%sϣUu %e=TeA|Ur%JȑF:-m^,rE9Pn bBvzbKW=ySqH]#"7%vie,KjJ \CI#CӪc:UG^d5D#LҘf"2L9W4cYԮNFBӇzT O8[3(uiz uyP\Em)SQ۝*[d6V' ?,Ih:Ӓ1<PaWW5"q~؂06@\cCssš T:\K(ўmU^7{ ֯CBIQ(g] Z.%ҿz KijF|qĝ;> zjZ]TU %<㲹_^t{nAn ,ۑ%G/ `.tDjM"G! 06Ca;#b*R yVG 9L)#06͌Q` TsaxJ</GhݢE0\̫9!HpPm ] did'ȒV?; JPcfg)jX֏ Ȗ@ľ5G&ii5&M*4eTDC4!N=RLp<ƊtZ0 3?`9eaekoB'ȲR-@p /5_NO3p|7 [ZwW4.Ǚ"ػI]fWkٳ@'gC]K 뱿@Bw+NG iDcP‘$i$> Bx"m9+]4P#צ ӮeH*۩;.eY+'hȻPU;ۙYJִ60L$e>.I7:D`q6Ґ'ǭ 0*c|9 ?~ =k۠w& G * 56hZ^,4I>4 NUgYڤ[Z&5t%BWd ] B6Dn N1q>fkpK׃y;XW9&DCĿ^XiOO]Arqa=|-X9?Zoءd<.$LKGAX?x^˗.{fxʝP S_$;,)_מ43I3ZXf ӽ-ƏKb(ט>ܧdO_˷AD:!En@ޞ)(< ..\IK3 j] jdin?am 㩁Ôq~"g7!NR4zd4$5ڑPvIe'\Xw5ede%su䨬)K,*P?E`M-mKC+rNP⌒Kcje*ژaMOj$8bBDQm#8#ȭ Gd~Ƣď(vDNfxk`M5Җ, S9hkEy[?nbmmEe$NOAb*V~r/Y8V'qۡwUќ+[\uWUuл|?u"#c͵ݷ/Tn82,!.8>ov6`X_ˏo~+J)NyP^ڼ% R#6 3?i$v9s]0uӹً}\6dhs,|_;ty}U/mq{&n/wDžQ,LbcaaTUQecԚlUH4l-v$#!:9[mQo-<}2銘X0%\Y՟Ncs. tvt+R44^+uR|Iܜ~8;:^X*~6 VTQ F8 H= Q$ĄC+8"UUPQKVTm2S#2jzds|xr<9flBA(W0:x)([&peB \M%c UL5U:dF[J'v] CȼeWƤ"T:7Z X㡏DIIjt3V4Vx{*(OCelM&ݾ_ JUS=豺ɄyH15RQ.dEF2_NZ|d3k42haKȘkQXe&4y7\$9?GKOS1%&&Ǝgxk2|4ӀE؂. .:6J(ݾ5(  oP ^M@<ǐ0c JQA's^@5_ 9M2#b O`"#vL<kU Ѿ qJɥeXJ^ŊA*=tn/M+\0a2&`*p8[I3"PmQ6.XnC%ΐCc t--!p1Tdq-2 ae^G[l_WECNMQ׻ULJLaXjo~p|΢P򛎲p0zUzix hܶa/%a[Z:r6:m{Bn-c븯eH.;4wf7ca}8S Ї<bV ݾ+zsziendstream endobj 575 0 obj 1713 endobj 579 0 obj <> stream xWnF}W[.B>S8 bT!jNaRb+ IwFRs$3gfΜ}ASDśB~AfeAK=-_$(/T(Cyp)b2 G*(/. g4"Uhb!çnPӢ]lt ͠;؜}p 3E$1ew+^ gIs.2'.%4F)_1|[P ~FAud$KT4kit(xXtktisnR$a>oX.Z[ `ifX<{4 ȷר:6_ڃMV# U szyh0s*:1dX2of5n_S&lrS>)T](m35gpWrp$w:K}c6RO_bi4&g# m,R&!QSE h\@Gq̣SU=XX8q8Iw-' '.q 7[^/4z=6U׵z}5HN6l:N f<4׳B6Ɓ$pīw5NxqjGFґ? gXйLNG:` (CA8DYWoֈ!1kjHo33:Pcm$Urڂ?̦ jYUpL”| -S\I C-_<Qkv"ZI7Wg)LLuk]}j7S#܏duħJF!vj/Aؼ00%`A֮HȱL b1N& *oX&2̦1Mp\Mۀ0s 4gCG(x B9zC[A;OEpu[f$V(!S?]:ATul$.Vnj13H)ab8e [@ic8"-Sc1TZ(:QWK.v|Aa%*l` n;%b(F|lG #3W_D h uͲ4kܒ`|@_{[9KhPq!*.m6Z8ͱi65 ZHyb-O9O@ !f|Kg5 39xADSy$z_4Ǣ22]Vf*_ غiendstream endobj 580 0 obj 1500 endobj 584 0 obj <> stream xVYoF~篘rvjo%hWV.ޙ?#];se-|}AFGGx/bn$jG!aoe|/5^K(Z宑ˬvd-+` @5X)fR#DWEb ժA>$Dmn:aB8 mI"^Čyv7XK5uL NH@vO'nݠcS|MT,AXBt>^b[[A)fHtx2Yv6&Kٶ^MQDm "2}el]W7-/sXЪP3{A)7sĢp,oQ#ȾrW52 m+uE]Aw]2xHhd@OO?>g[d8:5xA5jƥ{P&$ENINIL) #Vf |aф&jPl+]ݨWpYowȢ({Ϭ{tXmWŚ[ '] C+EtYY+Oy\-qW>н = GZtGef}e] / X,^`u! ӚuEqǥȅ6u\;n(Ȭjx^u)w'Cv#<228Z]VYs 18b'?+~XT&endstream endobj 585 0 obj 1068 endobj 589 0 obj <> stream xWmo6_OZHJ:5+0dR*Ɋa}GR%9N6xw{=7`?7Bm9rvmD"?6s8b(܀Ea22Q`"8 #& .GVK !l^ɿ^K)*Ս\(^ocK\ލW#cYQr*z>f2FUfY,? J픶Sp.dkF}eRʦJQ&`]ncVV+҂>ukY Zwr` >~ُ;#}6s:2 JjX9؂CY:փ_---z& CRSj_똖Υ߯>4s}xG@W`9t.Y(ca ;mx=ri wߘnXrk*ELD&BV"[xSsjgvvѤIy$AM;c<=FaxB~ 8p&`8. j#HUQCVÐ.uI~NԪrN?Pv)ŜE1(ڑab)sm9PvmuHSVEm DJjE@fv]- zskbŲCcWU k:~\Q7# eJ hl )J›ϟ l/%n?1+3# ?m;Xk!\m`7HcMoyݩb/ xuɟ٧p)`N ܤRj5fQB=Lk*Z,G/PR-mO59kʖRjl(BSI!\{>fvyL> iyHU}Cz~ v$| DUπϳ-t} WUU$0@ ^shb$o&B0.M~ rB p=,/xY i\6A>8":i'cm , kBjd>UQe$#:܈uܮ,ɧjk7}ڈ9>h5|}I%``5wQ"DC/iFLW$m]F_Tɫ^sdvz\Z@`*3tH MpOvZTig|v7E}cT|Gԡ) 8MWѯwendstream endobj 590 0 obj 1397 endobj 594 0 obj <> stream xXnF}W[(Cp/]>8 bTNa%3Hb;{Ŋ~%mgΙw`>ׇۥDv}Ռ"3{ *28LadZ@PeB˭6HWo"8M{%|>"I9fh4Vclonۢ};,bn%FoYuhsR>J,PL1saľҲ -_}bJ\o)cS9egJ\6MݠBoIj\$ NU/X&+e.$ ΔOugI^|cERa),$rc \ 0!Q)sʡ~,gQY$˪v]Mq7'>FTWfT;DŽ&I4j,8| kh) W$X[. c X 288%0Ḷ2G5\)R*~ڮijWЧ3J%`1% p_m7dtNYGf;0҃N̴ J|tSi H|@ HRh9VIϳȽ '!}|4Կط5r5k_ m6'I>'QuN=n=Zi <^m't/ F5s 2e| 9zh:[)Oq*+3t#JSL 2-NiRz ]b{1aG!4UbT9S^P!;DdFD2ș6'Bfu8j|T{%fŬ.d+uzʮ1^ky$ d,x4s Phqm0 łbGzwz !q {T&l9q[X,?̈ml[)\6M|̪9}5Ǿש7j4Fχ`)Gp~y~2`J#Jn PU3y/F`_W;;R-n013IB &CFs. I$ps*>7nlî_!V%`jk{Uw!o:ryAn g/ hܢRoNJjFTBЩ`j &vT[3[l8tLoa[u1ӖYBN#^⚃) lΉPL^a}W6}$Ղw[L"l+LIzrʉ9Tõ)N8DDNiª ,'ƴ T _Jْ ҆Fc]mtB F,;\ i")F'Fc)nGupT v'{ҩ츥zP)"mhr8L0YEC^' M !O0w/`!endstream endobj 595 0 obj 1799 endobj 599 0 obj <> stream xXnF}WSB9zo$H&`7QG!Z\l%R!);F7+M ?̞9s6~Wu6E~V;bbVQHyI0şl)IiE6 Dstz ^).r4Cp  4!ĕikcF@!ˍjCo󘸠~.b\E^3qTo[u{ؠv3z_zɉ?>?Be|_CϪЉ?^tf$])]5yYB, $#_X ljUQ\';-߾uyO$2gZdVء`8sثХdX.ԫs"/BI"sT%1NPFu6-*ҝQUM;je VeѤy^0͞bPF8SpYc&|cacJn6`tnrK$0%ZVqڌJ%)xRbs& g7Kmӈy<sUD).ָ;8Вh"jo\ NU!H,m[0 _F1L a]%F21%NGqmjV6H#ZX< iq/(^ q" g< =^O:*%s0gCZ].ufV-_w&i;)+E 5$ ͩA2 @d}XT][Wl( 0HBx0U?-rŘ}bsk XϾ]yfW)O$ $k]f*nFiKx.i?wK浃- l[c#L) IPg}a`` /4,8l gI7@K.T'lϺ}3<͇y%OS#B ks2Ly;2ϐrnbV6f+GkE v t3kχrD8Zq8֎I#[ܧ'} zfu zf% z4dÍs f9&A\?؄^/rcngz-auN1NN 62IoNaSO1hPXQ1UըZLLFT+֓u-o:| `9P3.yVjGeSz̨R ~PkU }:Cƒ!؇iE_Ago C4 |+&i~.9k3 ;:s@[IӾs𰸽c^Mɷ'2]!:<Ĵob3 mendstream endobj 600 0 obj 1717 endobj 604 0 obj <> stream xVmoF_1.g6 zkmU'š!Kܨ.`C^TYJlvggf+X%?nt`S,،:zÑ | d)0FIៈ .G G&6.WcQʋB@66<4D!ʊHё3019O7u!mCeMPlb3ec7]6>1fG ZIJ<ψd*u4co|+*1~܂Ǥ aq01si%֙7ncIb#dIubxVyB};#(V=N7aYQ=:Cn0_iAH{ oԏ*z˱toIX6oX'iN`z~9 g?@)DREX"n*zt? $Xd~Թoԥz~iQt.ʭjV^s3{_^\/?Hk*=1u3F<b4v<, \,Z57`)Dx*]Tc}0e"[Ij'N3u0Ζ;4Ip2$ܵ6I8-`'>Bie1B:7A0Q9#t#;+ C]\Lr [,˪H TwQH_>tU q=+2q(M j"?E?3cfA?vdʮgLup~SAuVB@kC巶,FUEqIyhb50[,'o̡N=ʶOGwqU"7-E.n&JWA>w>ʗZ8P\;H|5 D=ouk* {ns͢pVyvW1Գ̥^EY&ts w8mt[5 `Ry-yVqPu.]؞ߟGE] 4NH[ݴS<Rz ŻWY7ffD#N7 DbK[db' LzߵS' CTMud ],8|:*Y:8{^k,`=endstream endobj 605 0 obj 1195 endobj 609 0 obj <> stream xXMoFW,r HvҴA*B) Zd2T~hvwvv{3L?qvж3f_GrrDZn& E,N1H-'ќNKNX['#hr40Iƞ&!GCjԻ.h.J4MSVoֻuUM_S}Rkpg,q9[%޹=estQܖ?>~wͫljߓkD`9fۛڣD`'6j+B͔ L#}MЪ*۬(r>^73T#4ht妚)}t<&iVPV5Y[B %؟5rp⵫VFA@:&6kGPoj2f eRq! ,! EXz X-Q'I1o R&K%ʴtlPX2yVaSA/i aV㣁4O"GW>燎˳&ubtb8wz{cJ8{7"ķSQ5TM~ڮU46㱟Ћʃ?4о? Vu9fhQBٚz; {TĮ.>4P;DŽ A}:vwܚC=(SRfR?R}weQ(%;wٞ!/QYٷCySэfî*v0ʚ7mu 9t]w]^kDԋ;(rsָ6>4;w@ōCELXoKE0 +̗&bc%N#`UͥXV-gu Yzep>뗲=mx?U|5%oϕU8{ -,XZA\IY*Sd4jw?c¨ 2PŘ6mѷ)<F8FcZWfto7u{Hps׼Y0t5qA0ڟFl9n6K.]!HP'kdʡ*̅A*Pe"KEeCBm"DqطպЅÜ7<}M/P{9/YyF: h]z9 ~ endstream endobj 610 0 obj 1952 endobj 614 0 obj <> stream xWnF}WSB9zoH1- ;0hr%H$F썔h%) X^f̜33?Y삳k}@6PGC?Jeh EXa. Z0`R,e2"1Q'zh9  Rݯh4 |zԫbm3UӣNۭv6+F0!ZE}>*4[}X ́J MEX5DT?a ET1$KH $^ }vM388//;Lʇ|@zT»E4QqܪtWɼ)}pŇu"Fybsm2@rٙLf1<Q:D`c@Hw EvvGLȀ]}3tss\ݏ[ToOM`p6[1E;6E׵:QKxdgHZ1_Ijy.+?Žy/D^Nv@&ޠiv]g>Z0kUe!cىnrvX>3i̿&DGuc9߼dQdio>A[{{}ڣ2NSy3F/K {?/endstream endobj 615 0 obj 1503 endobj 619 0 obj <> stream xW[sF~ׯا9Қ݅!NRjem&xXI@V=e>!w].G.ڌ>z̟G + (^A(0P8w#gJ_l Qĥ]JT>RK #' .&$Ai+cVlЪLj}%VI#RԨ\wAi)jT ZWB$Q%rpʇq{,21>$]4:Q9d4%z've( <0”ps ǝ{o."8l!ddO0¾˜ 8 2/rZtM?d$T#Om"*IM2 ͳ*킒$iYѼ8Bn$yupXD]͡*N\ghbǤZmDslqgUH+侔'̣lSVh}@*s(k:f>xGuίg;xH\ְ3T'mj' %gJ >ԗ㗽Rek>^!?ÍOJ(h\!u^/2e.O!C-&!0 A$C_v#gcA*Plnvh >h"r;m$tAٚO^%XQ.5M=(Jkż3Zm ]\e{v{5/La7S}2s C,6@aOTJGX0dD"caigRХGi$Y:u>a(%g^'P}ǀ>h ;B)ˢD *y>OPn*^mҨTEؖ!C+iX؀?Yo`(n pG#P#hPny[%cO`O]OvtA3rєFGZT}> stream x՘n6X\%^HPdؠѢbˉ GJy:ĉEQŽDÙo~+""b~afBڗ G5eh11( -'ӄΖKZqd8J̫ J10 4Nq2UJ0G3ZXx}z(V]ۦhL̼]]K¬Dyޕ-`+Pa:0s34֚qݢhug܈jtVp^$>B3gyyW\m,XP}4^LG<4: !t6#B`_WW? rcC f:rcD`*g`_aӶB-ĠΘ zj]i7 ZWe]y//9#)nfTitz]m5SfIVyC]4EfCS)~ɦڧ ߕƦ mf]n͓`,8snvi\C[3A0"Ά@,C뭪a g~u|iu]A`8Ga2:̣j1S@ڄ}P2& I/0)aXfx |Kb5 65{>_.>/s;v = E '^3&[x7O(ġ= 7ƓCk]oOF^[y/X 6:ڊ5QK(jN eB)T{)m W/_33fK>M٫h$RD:aa $'1I]^,<>ifdsEBAb/I͹Yquf}GƘJ!Arvπc5Sľu2Bs<;6*B z' @#Q@zwevyR5(+LJi'E<߸n *!E˜͙@&'w$*'Ѐi>:mIK:ZN ֏曈/Dio*S7Q1`GSL0vƟƜ8L&cy[H/󞏀* } Fbthm04 p =Ң = JtQ.6O92W|~K {\2^D!wHÖNs!(AB{•*yV'w,֡$RL 2VEAO$ 4oSNe`/ RUe U$XYQ6.)#`dMp,QhԱJ'h`QIUĎ*&"!T;El{OqOaćh}U5_m1RsHhGpJ)l~hh.`C4^ Go| S y'ni@-^k~ OW,|uvǻDeUyn5}Mk%{BC^ej~B0)ds?#r33ѐ9endstream endobj 625 0 obj 1641 endobj 629 0 obj <> stream xWn8}WraMHHhb. E-lɕ$I ?ؐᙙs?P JŻD~ǂؗ[`(/aBZ4Ì#RQL?,5"ջ5D%̄)|"3O(D`ޗ"\,̒GK$$*%Mƣ8~wq8AbjECݣ^C6~~G]Ւ&Q]ٚM;c P?âۢ+>&s-'lʠ]ETeX(PAgh>+BSC҆>q : )s>>BxJ> e{8{LCohtă܉! smo\B?ɨ6;=D)2 ΘOؽc3+}ڡne Fkѡo@ԻFoy)S3]w] [o㎦D~AT2nWn .TgS9, Jusy,RIoaTP,\&硤4PCdXXeVq`DaJD2'Pnxy'5$cu :`B]q:3D1d:PW;k4'14 Ibtc+*2X~EUpI2}X,ժ83ׂtuB&Υ`U nu_vrT*E.(w_=p±]OefV|5&y,9;3=8iѹL&@ƺSX/snD{ip=g{^߮ $#*Fݭ#Yig37e^+/.#` ;7ϷK@l2^ITf2`9#U$mȋ܍auuj,zp4yb /YU[CJtBDq F Xwۀq޳U]{Ԟ%5qs> D+ tlRB&uC0dhHk&u?C; z9Pg(Wə6[]@.C!VT@8}w'v*èi:ϒ8qgq8532i 3C&Zp@m84mZ},SJd,,v߲|'|7Hendstream endobj 630 0 obj 1524 endobj 634 0 obj <> stream xVnF}WSB9zwyovFڬ[ J\Il%‹UwBҒm@ ;3sf P€]lVCa|qwA@tE 1oWWӑe>׎cD*YWX"lܽ >9*E\j%1?+̔?~ݍ舦#cd S.~]\n~YJKLbķ&]1#3hkCΕHo Xrm6ra17&_8:b}ڜ˺wt-`)эCv ̾(W8PԐ]%Yg5%\` @ !,eJ,2#D7|ЕPw]Y6Z眄ت]f[A]EF6BF^D|XGHwd]%z4 s`+?j^M>W*kGXDt> l2̏]A) ft),x1Ze7.»iSV{y vЭ#ɰYuiLNRe2~({YC -,9'v8x;SznM> stream xXMo6WV9E[$(]lPآ- Ec;dɎnCs4|3|`nnzBE?i1hBBzI@1h!.,KZj0BnY)5)BF9 Ȭ3$F8 Llhs|^j|R QqTS*VRE˾_? 9$/rɒ=jvb (oB33fdq9H74dʚ}Ud4wUUB`f> f̢Xf-6Z·-E8Z~Cvtta=JcKCn_~|eN LfQ(iw4f7!f ǶAS=pBY~ ]^$M6U^HcZS"o&KVpr٪1xHL~pAo셒0'o9y=% 'o(;41U~Afyڣ:P/pSx `* $x;>ij)  kGoJ,?\ZB[Z@(FWʫy[(:XW=+9CO}R}C0g0/+n1~endstream endobj 640 0 obj 1458 endobj 644 0 obj <> stream xX]o}ʁIIЧ\8v຾-0UؒWqpHJܢqLrș9~#e$?w~}^Ikg;.+?gsؕz;3qJEH8|6_ V`/4Mco]<.>XjM G1UGsl7/Ym"Ic7/qYC`B/녯3Є3/MTOagwa%7Eӕp45Ur6,xzȶ򮬫+F6>!)70Q96˯n~4$*:C"hq ÂԦ)jS U ?pcYe{vgٕڨL48>o i,LZMqa:>yo&nRbEr%irfm٣wP~'oϺ2'/sYeM=)T73qYFTFγϗ!ԹhLR(#ڋ[FkQw1H2¡)̾&K|l>ya:ϯWg!ǁycot]L)L򼪸Ay1 ␺/i$d[LsCZ`;̵/8# ]l4ԨVUA<'Z\j6Syp}UvEee1lF4؞(y㚸@ZgW %( C8"xuC2vݭVKn!C,"Xu>E\\R5?ᥕa ^S&A1 ~]!zE|U|*C$.Aδ}nm5^ǵJȅv1Y7N_EyRɯqnIc<ـx(o'PT9yL2T#7&Rt'76_֫/~㭥Q^UAiTWP ,:oPMM1d& @w#Xj!.IROrRL9 @BqO8ssm;> stream xT]o0}WܷA| e#8ŐwmH/R s{nT?;_[%TʢPY7305-Q0qi x"K/xm.s_ȂXjj\\X6[.gA/?A!TՙsXD(֢q~Ɵ0-[My.Ӕ[Y nȆMB]٧+SEV]9:/ØϖygMY[!tx/B,DGßvWG]K'@쐰p( to t[aO`E>$={yBhjc &][~_!Q8>qajxb+>wTendstream endobj 650 0 obj 756 endobj 654 0 obj <> stream xUKo@W̭6($"^GxM3ﵐ8޾_\Pvf]Mah<"Qo b t+'rǎL )`Df"1.2* $ʸG Nu]YN;H #=]/̅ȍܓ's [2T,)Yjx> stream xUn@}+V})TfU\QPJqYmf6%VB9sfhbeEk]BPukaQmbQL@RY:Đz HZv|, @Ҳ) ]pl(\|FPeJKOulHƵ-S pЗ yQYV[Hk74uJt%vS3p^u@|荈a3QipeYՒ*I ׆hyl&֎s\͆H,%}ii^J U{ A)(k{7bػޗ>Lڒ^0tZf _:z8\əgGOGW 5aP4W< ι}jPzftPiM+O_=>8/imflư쉖5YE_Y}jV/Ӫjaù\rZj*y{8&ЗŞ+&TKcC>F*릌oAB pG{X[I=endstream endobj 660 0 obj 583 endobj 664 0 obj <> stream xUj@}W[bmZ҆AB\lj$i;/$ nA3s̜P€cڹa9V΃LkYû.utB!F&R=y[f\lV*eE+)[6g6CP faǬ;U+% T!fjS/d;<ۮæ 0ouW;0ƒGS1/6+ΤJvϐ(xmZ RW7|_?Ϭ|Zu"6 &<4? ^JI(tyz,і-=JY"w-hD o&hjO){$!xR~~Oendstream endobj 665 0 obj 552 endobj 669 0 obj <> stream xWn6}W"ԍBdw.MldʢW\!)vxQ~HbgfΜ|#eÏoc,->$G#?>Y`%dU.EFxP? nl -4I"[ ţ,.\T7Ex2-z4NvliTg ;pF#@߻w/2+H\@`MUFj 6n-ۋ2V޿dʲ}Z5 4~g,lb͞!w8:cjw&6t bڈW}Y?}Z'V 9[.\}:R'; ]եQYBnw"> iYS.y|bW!_տuι\0.B1_|sN.G$ 8oL|Y4 V۪#5VH '?83b5^d U 唔U;o%Ф!d>lR}G싀zr .Pp|3hȢ(I@:dߪb1l^KBq _#F$U`p!h̥,J EIE՜@Obʓ3 q.ݐ8rnZfe{bx}D _wIQkθy nsc$n_ԉ.Ofec&OJ5l3>赐'!BTU&}H?CL#YduĆ($Jj4L,:=r 9Xf umgcY`~}d@a0u2eםhb{"6dD;=+ \= (M"\(*T`_)הk&Y?Y! e@Č L:5i;T5Q=s$Ю(*Q`Йcs 7jUIRTRO~3M._^  :f$-UCo}xTP7ٽO^CSt 8q@MYZfo_qpVxՏ'zZ>T=L'0O( 4$GEO)ݾ͸Ŀ[j@cϚ8P"`rDG=OcۖQS䙀Q٨/={/4l|TV΋'QQd(8dkXTQzryIWA4݅h@x"1e:1SB%}Vc7zQxܜhwmk&j2>J.HD>e͐O{ܛ> stream xXnF}W[셗]ݢA. '(BB"^8_ߙݥHJ,ù9sfτQN߫,%zvyCD 7"'"TF$ 'Aȧ rANnRç8/#E_&G|,4,UlՌkW43x4UŲlgץ"FU^4)IqnlFfTI ?gh1Oy~ fC<%qߛ~&122"!lfU0R6\do>I\ *g ǘqDJDq^lj5S9$5"TE?bpɦ.ӈ*u0iF*S!YMf"ژf0&e : FhH(F#$㈃)U,߽_޾>)MNgde*fq}G2lpyoŝn8vH@S',&uv(M鳉q8ܬ*˱ߑl\>̐<֝v뜬M;`52*9B|e^ N&Û>JIvKpcp|ᒰ#:' k|#J1KVm[et ZIPFAr_WEZɆ0bn>4d={ݍ5 YO1͙j"mkE&^Byht~]f؇Cyom._\ r!,좛l炯 [3R/cV\A+; ȭ{~f'K6M_dGŖ1 ݙ;s|g*rSqw$n|(Pd!:\Sh_a,pW:;~:' ӱX \^pY,./ܟ[Y `jeڊ@P! _~B&nE]_gzhؑxu֧=+2(kdr&%0+y4 'LMܩm uE`+^48x$ yywa(xrFjη+ȼ?^.n'~qr1t7Kp\Z&Lc> Pg/QO([F vx=m$$uV\w={ڹ'Ѯ#endstream endobj 675 0 obj 1580 endobj 679 0 obj <> stream xSKo0W̭ /PomCT݊f$k l|0x{xS Zv۠ml!f!Y(B3sK%4~yK6FNyY"L 5 E($!J(CMa]nvp]9O!f#_'e?Tck]^[ n6 _:iѠekW={h\Ȋp8ÔQ S3HEjĽ죵﫱ya.ZKŠӳznZ(7 ;\^` "NF yWUD* ;Y٩"8_v1X4'c/c&0gz-Us9.36~.}_R{fNnGn0󳞤zܸC1Wӵb-߃ ?0V3ݯ-endstream endobj 680 0 obj 456 endobj 684 0 obj <> stream xUMo@+`1k4JuzAB]쭁uNTwv8 3ǛG=֥ڸ3\/*0F$A5ϟ٣ |rô~ Wh r aXc_'69<`J/iMvkURP*2R*naE{f%ÚR:` |* 7 ZOӒJ@+VKLZU &K.rP>U^ 'ysm 3숂JS9#b2!itMWj=($UD+?p Zgp:rM-JVc٣\(h?ku/_x!Q;K.)Io*_Qʷ@BdEI p;p, 9TM!OTBFCPїu z@^~֯w@hXNk#˛ }=endstream endobj 685 0 obj 785 endobj 689 0 obj <> stream xUN@}WLyNp̮r6HD nQEM셵SP͕Z<8ڙ9gv.goZ sк6)|:!zzVHkvzZ&eh(K=i*??lהiO;FAS{&ə,ihP 6ɒ˜#Wnj1# e'1 9CuϾ~TZ ܯ…H9gCHr"PW%/&2; {x!"}-y0WT!ԨGmz1~ ɌdK6r-ݽd̾ey2C")C;Oc2GP Qs2c(;+n !_eHsI6Y< ,Y" (.`<EY e+>zZ13+MBI-Am(mmR&Pm(Ox,w)cDtB՛{?K, 3fYdfiQ|#vW]Cgiw W[r)BAocy%[{Gȁ]u+{GKRf7zPqJ PΖȈTjpFd_>)›Y謂Fa09 w.J-jK a_"'c~P#j5+>_g-BMf\N Ż[ͨ{:>W귙]Roo3t A6 x#u;Yo}_1?endstream endobj 690 0 obj 803 endobj 694 0 obj <> stream xU]o0}W*lZ:a[u0&Xt%YeՄ9~ycM:ˇue! -oMb5!)-CD a4"'&U$a/BK fભiAE>BpBȳ'xA ZV-%]>V4t6o%JCsoBJN񒬨 Msd5+sZAoD/uޯUm,)~%7fʲ¬KƛN0U2y꼒Kw*!58Q^|$w#{.j-:v\햽wNjJCgZT'fd4 *RTUջ(t⫝̸ Ldnϒr7vjz<&Ѷм'?\L/<|TEGZLԖk$Uf\c?5x^6?_YQ3"Nʘg 0*>P2j> 8b<@Yg`wن rX endstream endobj 695 0 obj 542 endobj 699 0 obj <> stream xVKFWt8Җ5;3zxS*Yyd豛⿧gF~{)$OG_Tg2f,;b0%el8g6d8.0mfeD/0l)htaSW ߤ7E+Ϭ TǨūmRM'ݰU+:xCR*f4_ԽXOgml)5C>&c^]B@׬DWKBE]<ڳoӮ4 pp? I\u鸋 !܃0}{LJ.aܽTdC (l>YQ.{x#\0Mt)0q!"'6p:si;ecO*BBmY;%9?ki9NAqG/S%QWc{nԻtMߤUj9'X{veS+c[ Fsge-r1qs*T=^<"SGij>ĢJGl4K(c.Ni+w.f-ڴλOx6beҸkԉގz ny esT ռ1lI%%<% GYn'to"3T?\FB>F:uA1YD;<H2E3KQ4jFmB:3ŻF_iW  ^9 Y&(Py"J_>FHjG72$pP yEZsFAߨLuerY_dH> stream xX[s6~ׯ[)OF}&鴝6u -B6[tIqJ;;~$/D0EuAf."oC\8ZaDfR2@9r7Kt^ʰRٷ,g WhasQif?,#̝XYvUStQw轗%9"f(,ԋIHӜ d$ViwE1b$b6,Uzlu*j劰׵E&M`  f-%xdvKIBަ5U㔲_5M{-%OaR!lA}cl̤DĜ؟qTP~Bu=76vIv=kaM(  /(ߙ)*clM>?(XzӭXߙ.. }]ov_VYq'9tQv<6:S>TOHI>v%"<.;}7&ucdgAwb3& "4m RTҽu[lоӛv p̤ ()88NC(!,P*rV.)au-3`(|#1v kר~&^sW.. LL`)1}21}H˥4Yʱa*}__UM$Brs!KH6CV#s u^WRl0M#5j!(^QRL0=Ktz);qBlr!~h7{(}k*MnTY}&yeϫV>.stCZZn{< mLEKxtkp}zZMtT꾨埸hpyp1tMUGgd{($&YpNP,Mbgr7H(P lB'צEs0(X{]{׀ϽC8TƎЦcPwwb(9°3|*BWo]~/JB t y/;+Nv&]vpcFWW(-ڶ\`1ww;PE͗ҥ$Lvps/M4M퓀[\auP܏D"kG:d0V0HT ~Mŷϩ(=IȒ/Apg< <8O'Dd|)7Xly$<>Uƭ)zPU/`qw0ķ(K&85Ek;.> stream xXr6}W-T&DOmnSWmw4HIleb^l$Ev;1 \{O`n_\h.->-}zhU QVۅHsR.nt ZʰҬ[HW1ʼnbSW V_D}|'Qb`HH e^o+>w"L:STޖO)&QobcTrtmBe^T]]Rb:*u٣Q_Zq<SIqx0/4IGg"x9F&xX1^*/>?u̵D1/JᎻ3lbq}dpܗOD}_4YFeF-)%Pwe (@x4aLBiYSf3RL!Atw{SYޒt~ h5E1E7Г]TǙT`z~̚"o T8YV6 1s8ZSh|g KCٴ SÄk:0%Ӡu]YW9r8ONN4*a2@u̶ʚܮhQ /vHU&8 R@Co%8utWT-z%^DEBL0!|l)WB=?|PCNEzf*`K}yUCPweccI9%2*K$CKq-k;_L铬iGX]XtLCw]ўcSJAg^[3V~J ċ}V̳N@LCFp4u3gxm01NdrjOkEǞ@I3ϸrw5,$Ly9M\]WV;K LG?TyABVC}Xt6& Ӵme\$1hjN}:`Y%,*Q-'O`w F!}+dʼZIa5ҀkG}]iּ?[ڬmu[lLzv`ՂQ6}5<4%8l[b+82m:R7vș.;˘*B~;-8XL~g0w6sg%إ|NeMѶiyԗC̀})W'%y^mi=, bgnRȳ}[P٩)F] F.> stream xXk۶_AK`!QmQM4E.E0h[%G;|J]\Xh89sP]go3ffg,"z~X8Z*Gvf_ y2.b?b:_^2,v,J(R(Gq*}ҹe N2Kۦwus{kwSLV 4C٧-c[Tvc9 q+Z$: ^ݫ:\4)8 4%8Ov&a.zpQ}ܯ5[:EwE. FX7bVAIE"_9ߗI;$!1ثu۠PoڗД9,w;wJM\UUtx4(f˷?qwiz9f)7QѶM;7vѻM~=QR,9)UYuH`߷qwi%Xf>ѡ)뾘F8}`|.Ũe2snsY L31CFaFA藺s0y&f]t77W2 N6g^ޚ_7 Gfm>A8ZwN9,mO7.+Tu_~Šl]5GUm+xN/h,[S'zWn^:PE FMm/JayeCsR Na/ϪMqO?gm`&%-%D4 0쥘ԞuV˭UY ++e~oơ!_qbQE/HL4w}03#& } '3,8}$nT5H6:ʍ 0}x}tE3",w_$V  m*b f'3G9,ER33 U# g'Px^nןq\~/`Gv~+ӢNA`-g=4+6:0hx({K]slׅ<͏)'c )@D!L0 :Av`B(@gȎJa ~G-: eT¸@?4#x38g~oYݸs©cbvؙp6 C!I[b3A&jcFrHkcFWCQD}mhZ*mW\ !Ӧ'0(Udpr,/|x K=`laۑqchO aj@鹠gv.֤6>QV95?LfG 4Q84=s~)r7y)9F>ܰh=+>gbhO=PC۫ȽAwmH }1rɌjUeG n-,(obeWuÀe+a6uvE!E CjVpv9t}O@}Yl,(S%$|4ge?e=;Ä?|RON,ٞQ_{@9NI?v`T_eT] '_ny]_Tgt`3U|l))YnFpײ%ęx#xv]}3ih>J0R2MXy- WWg;V $\on5pǓ0!s!7HT}T 1HD36g[ ?7endstream endobj 715 0 obj 1962 endobj 719 0 obj <> stream xXYoF~ׯX%anhQ A (-E:<|wHZE ?6gc ""~vjzB˄Znя G%Hň24_OAX(1(!o'OA R |5C3ʑ ~](RfTZBbel5}^8.fF")8KYi"]Xfh6I(ҝHfĴT,#2+t|; ۓU2Ah BL#1G+uBDP\zI^ܤb,)8 rQ7Iդj˜w56w}umbCNL?)Tb;̨Bk7G)F!].v{V}o <+N"٦X\h&VK<$gRGPGO5L)7=nu7?ixNCWP]GJ0H\?w`AV\=t@71v+Q?q{ 0uW҃^+ zTDнz5Yj>|X~-#l={iRV TˆP 4]2q qCK56yxy|˅l{[V?{p:' ,_}MmHq51*V0/GbW= NԐhw̴ަΡ"zC{0_OQ%ETFv"(ȩ8x> ? wYendstream endobj 720 0 obj 1740 endobj 724 0 obj <> stream xXkoF_1RE5<8t:)R81V,@ŮD$ey-1g}{NbHq2%w,&wg,c{$\YmaWF'd+M$PduE 6_V`/TkV,,p%Ă3(~iO˛Mu<5m'=\(͜1K eվimlMݗxL)fT3bWPRkvBBY=>G ʂT5ݜ4SUeG}I\W=gp71bfH[8ウ,I2eeD/i TiM l4M}>ޖ 1"֯ϩ a_m.Ty]!/{J~3S(?Th(Mz̨LSa*t%~ܔ(:-Jp߷n*0T6Js,4E MǂuenkH l~C0C6we@u%pt6e+7fgG]Yh s{SݖiBT8+}gLWgE6ZO0vEKܖ--ԡ+}w!.Lh=5c \A3H&y4&m.M[$OKs5*BtUj31\\cc1] .eyUA]`6ZDO' sDBsC&K 3N$& 8{:G }$opĂHJ>HvښMͿp@ c;natuτ1lVҏMOQc,ΦQ &wYٶUr].oSg5E^J2d (:X []VD&`طO\j<$i+ual |ΔpK~hjb5hs }e@fM$2`?@C&Zߒ+wRrY_8)Iy0!5&ҡУG=WL/v4ܬ2)N \^8bD]{U.p6ǡkWvZvg::C ajJR4UsG)pHgpd,>![arP .,m?5@aE깁=ŁCɔ ` .'xBdn䃟 l9K59I#9s逎 9 ߋ/Ld^.U0 G!ۜ>2~,u=佑FJqQ4hfh6 0I 04zphk5ߓ ]*AOifþnʋE}01prvã> stream xWnF}W[$Z\.n4QEmQą@+D*Dw«l'- A;=s3""b>{s,$ڕvj G XE2N܃Pa.!Z&9-/`KV*4vd2͂*b(G iVNWC)U8ݗ[{p\%͵qFTctx9/v[ۣI eetO>6y;hF:sc ЧCz~yܺ۠+/f[^}fwEfB(fZ}-Q`BOU]d<œ:Gf]YرG`%FCM-~1mAT=jՇ.PV`ЋmS߻l9@D-^q:.+DQfm AXgi,V+Pm;' QUPgJd2AP [ HpȦ}Gr(y}JCÈaiT*f CMk[`%=94IҬ4p^ƅi.3eX>E1 æ|N%r09QYI ZY$g~\3 {&ܨW LL!84ȋK\rOt0== ?\ _N)ˋb%em RDM@ZyZ >!N.w["rVQ:@[I2&$fSL{ 5{3* tT^ 9vnXSWfpI\Up9jکAW䐬^YF̆! @ h۴-DB*rn;7NS\Tf;N*YlL=LN:GU 2ŪKt"`w;c@BBhXz@9n6|'Y mD+o)|NO@eNZ<ZMahj*@/iwb#jUXei/D6s@(J*ԭϦ:VWߧ~uar- t tJio^g26b 3(|f/l"ٌM}Y(.$㲴h61 bXpsDc= "õۆݤyh̳tW[ZӬP5"(gϾOӻp#/hΩm:K/QxB.8#x"t݇ vi8endstream endobj 730 0 obj 1590 endobj 734 0 obj <> stream xVnF}W̓M⚤(NMU ! /Rܠ]Җl) Iع̙s8 6q3) ư!7>2B22&%B:ăć4LE`u\R`I `M}e BmnlVsrHmA+eHs<utn OkQS/+B"ն Mjw \4)xԩOW6 hh{(x[!vC7³7LywB0@+BV(6QnyA[.*&hiim[*&Zk^eXZ+oPj\:Bo&UP`NCbSMRe8Se</d۟|}5Ǧ{=k'Ot:\rM'S[=I+V n2]gjSFB$=n$כջhӯo$4'sh!|}xnjKKRhjA$Pmц7h!hMa˭?%T2p| `Su l{X߷ oS4,Q`⒡t<$hXTAN5~mǪ=S}CFڶ2{7d-/6Y3}>*K,6AxtߤGTt ?#\><|\wO m2Ur (1^2~u GV;Y~\Ӄhƚ nVltî5`*%SY޸C1PUJ/ lk1r<kxʔR˚A M%Q#,/D-%sf#{2sz:l|xK+=k+\!ӾUd&~Qendstream endobj 735 0 obj 984 endobj 739 0 obj <> stream xYr}W̛AGc.y㮬*my7ĩR,Ȃ O@j%\lr/&1e$_gIvd;6 cqhrИRxS a4'7ݓkh+R!(, ʘۨþ%s)rmaOAȸӤ,ڮˢ!kRTUE?_S-/qWV +>tm53nʃ-_b G4AzGsB|74'8!D 1l[xxJS;pu{;,guC/0h~ X,޽e 9OhvUmw&mœztjw*Qa:zt^FG@rȒz2,q=ZS0,yvxԴcoҳz(k#@AuRZHǸ+Fj?"o۹<0@S4gXpUJԴC:M92dr5d5pN0ilÈGK|ǣ[/XhAIo[=7^#!kzLh{Ժr-b]2r3g'2 ibʒ02&F4 S0_6UB8cim4v77ּ1y0f P`ԶȯϪ$Wq#Ytvqa㺋[q͔?)v,Va"&,RLRFj8l"宫0 z%p= W=v[NR~iV$ C%gCmCbSI$`tez=dJ}7&e~p+E_qL>*wR] ^ho ؗ츙&`{3!Lj]9d KHC'"2b;:_H4{QY-:G0ꒄa%aLO=> stream xX[oF~ׯ7S5\8ysRnn@S#[tIɂ38ED9$'[g?|dr1c#T{Le a,7p,hr?l/HSk[gd(h4%7Epst9iθ\GsٗO7?[w?s&$ǻ9ٻ?˟fJ)`p+N4 [kfl[T9ؐ Ս[{c`"0, ,9JkZޑ'uCrs^8Ǎ\A(j5yrL1Aٗ6 - =`Ƈ!7:++.~yp||Yvxpjw}C42Jb޼GMPY6~Y В*Y2/z^0@Nuq%(w'Dx eqK\TV#eP4u3FJUo\ʑCn-jkQ&M{6'_F ,UC}}Q\DAfڂS.37ap9uȡd( 5a< njt Tnqu4S9sIJ9c}s y4e}Oz7{yT!{s3,ˁ2zgN$3?}P\uҌ6+7(,HYMZg/ N %nB!qF [5Euo Bqj:gAH@B*9(IH~fXn#nAػ{mq|X cMjVXj#ꉝe@94co!cAň03iC+6kciY#ciפow Tr5 +| tяy. !Eg,t3d3p^oP9/GDZ@P2?Xn0jQKDX6"6m<K&GYUXj`Yz`jfgsƔΞhm]d<(ӸLP%حSKF-3Ǯ-*S2Ŗ~/!ha_d*K?GXS)8C>UHz.Q^&ImlGVfU.h{2Ÿ/|F+(>(Dr茥]~T ~ەdݺP#Ӎ݌s ;.΀pNw80 aHNjc|G$p~GJr $ZcJ F n {ւoI^üV#) VL@6Og(>\ \0s{;$P>,@3ziپ|^e8P.m0ymUSqO 9Gi2{,W&L̜v^z#W!ĭ;_ 6Fq)fӤL~ A2 ǨX_ S*<`,'}=BT$e_VYG",8:عד?&%(H&}mx/ܰJOAaƠ!l2 @[ ^K #Fܻ]l=ʡI@u|i{4X>DGq}H$$5(S@ci^P@endstream endobj 745 0 obj 2436 endobj 749 0 obj <> stream xYRH}Wb7h E*! 8E {lkזɆb~{n&&[Ea4>sLPbdHѼ4E>DeB#إh< 2ÌI4^E+PeO+42NLjc6_GJ% $Uf_WW4,G9w`}.c8STYtG'*:3F 5Hb. |ç/O`mC+OB7yە׀\RK<ÒQӋw'ׯNcbBx`I7_7{܎<'r*ѦS4jR\2$#:~=Y^P!j($Rs]Iy\Z@5r\ :a)$43T]7`Yw |}XDW=)<[,,2Jd НRJ%< Fi3x7Dp 7f\j 1.7"*v xG.f/-s0| 0G[w0% 2 Yku\2m%ķ;pIhެ psʗy T\BeT:/JsptkĀbw\wX2D02 i;O6%}~kR!"Y-$XPCI ̖Sf]mTPn9fcơ,2⩩E/`2^E1YMpU PVfbyɤZ}]:t= ĀeJTaR6]|0dXeS\F7dQ &:0-:ʞ4B0oiHio?w ׸qGJ׶U%VGǠZprFKv}~T9@ n27`FBf=́)F[HK*3C~]ENDo]WQ\_oUjzjeG4 8m24ȵ+N vWS[Ǥ#JB<"v(K/H>jxё6鮕}#n{Ӷh)aZ4ևC%ŕ2jUuk% f TsYhl4V] 4ӻ %a S(,:wķ\FrJ̻)=*7Lנ࠯@l2GBTwbt PUZ{UkC8m[HgTIg}QF;c@N=S4BOkFbkw =rzB@mubIh.lY[5a #/:ݢb .쬮Vg3i*Dߡ\ggFjn1.E,|d8]f8@_0|([o\Fg0nc?za>LvK;|$zG4I':S |@Wendstream endobj 750 0 obj 1885 endobj 754 0 obj <> stream xXnH}W)a_Hv?f"YǞQ g!P%s@[RL ,r1BvWS]T12/s~d̼$zOYa"6ቦBT$d),~(qu LlHB?A1I>'e^Zp]S!bMTxwox)T-<&5( |?#ϸ)q]Vr/f==ݓbĽz tM]b77gˏw׳w'^4|BHon>Ϫ,kR MFaQ NzX%k_梮j:#cN يA0Mn ϣF. $l7y sbHI9JU:h={0E@VEe]ZcTT@3 7jshԁ,h;i_0^R+/j:̡tgBuo{mOb;&O(##b@!]- Ҳ]QW %2 pvd7OHpid@u:f°*u]Y?f $lRnβfMygqKjvMQAwH}T2ZiI^mk*^ nχp|Р*w4d ́TGp-}h$[==:-9b5#ZͪN#O fA9\P6VH>`J [iP )kLPzEeDeo=X:`:VT#ӿMcQz" P]·",~q5f(IY=f HPE082%h3mWt~+o J%l Cm}&P 4F=Q.:$9}*TVlqLp4D*i4S@FCԬ\FW?Nx}A6F EGXaS )|dOc~" yUy!<!edž5/Q endstream endobj 755 0 obj 1958 endobj 759 0 obj <> stream xXnF}W[)r$ѧn:j)\,(R!:wf/$I`\Μ9O$w lgf.ؑ3AJ dpQ!I"4Yfт͗82,R1Y҂3AJ?,gQ?tU%)mH ,Ni,3gg>Z>T=Co6lڎ}]94Ùኁ ƚ$9=0v3{v.tW=ޮ?OE_v dwhq3*%EČjե|T)wCـl.҄2|+ .'U&ǧ 2Ю5)oM1eBe|opC3%7_=~iB\O*HVLR+W=dwՕY(My%Ύ3f};l!UPuQCbO}0Gݷ;yX/iD#5jAW+ܝ]qRvM''^L]Wa}8pSt`z9A  Ma1^Qio vRd}˜wP@rqߧ΂\dx^oXhzxx>tyVƈ.'M7]ӟBx\]z `it&ij:B-qp+3bB-pO 4e4b 4)nw阪8 ޴CW"`>fi#pX{~*i+*dL%U[qPG]1i Fu09K3zXM$n`rD'ěw/oF5sMyA%40RѥDNt[U Śur2;1'|8V cLW~*Kp,ϕ!EeVe>ȩ~C6K6; +P$px+q .?¹ΟMg%̨Tjsk;32GΨW@cRύG鋮m@MTjWȲ#LWi2?ִ|d؝\I 9,E8TTaHO>~t&/o(-A`$d5A] 2h9ծN3)@;]Vs DžG6\RYy861Hwp42֗ t*y4P?`qq SAאTm=vp֊ <~i0>Krs hKFtP&: *6&Rκ5/N1iƾ>GTzL 7foW(P%~urNhًj^e(36s*è$.P2=%Ka9PheIP| ){=ĝHԩ(jz?J)o.QAD.B!B9Ww3j [c˽@:O;qٛtƽy|yZK4 PjX1mq#;sgeԥ'Ʉ|RR#!r)vIa=F&s]w|>wIFuBVg@ 0n?0/q=BmR}I4y7{"> stream xT]o0}Wܧ h˖4CC3E eKHm Ǧ )Ds}}`DǾs~A:*! C0HsPHK'žJ}1$̧JiQDq{T46$MƄs7RiB!ȳN`ւ,z: @1uj6eF!F&(` >; L!ΐJWZ6GfX(ᖂ,}k+wm{1vۮVjʽHtqaŬtĶu㽍8G\ծ# Bk45@Q > stream xV]oF}Wܧ'x` nv6mB?0m*Y{g`Iʒ 3;؄-?o3&. ƓA&4? F+(`eԎ sDm)#J 11ܺ~bD=FcW__,w?:s hOМ~b*5$u8 ;~1x0^I\ƩX$Q[}Dr;YU}Wɱ*w\gE wc.*DH7KrZj!SmӲ Ml]hN`uKp[-PB ta-L\L,n ]ڞXh,"z_ i~>=f"6kUy8C=Ԓ>`BB^0`>L_6}Px5i}Oʞ%*+1F{1_ %'$qͱj͞uBlBѱ9VaeG vTj:Rn]LBjKlNdAm,^r{ ]fuu^  #6%d<% Mh U)#qx)2u~*蓍c88m0&:XC8sEQRB/:qdσbUF}8nMՃ7WW tc>K.2&ʒm!p"s鄎w4k y&\ kɔU.c9(E|)e>0} M}Z/Lcw<("}l-YWvuٵ*sC[5|tj兩DS}+wK$ocN5svZ6I\myNR( 罈 ୀXPx8aRa_MOe^]>ݥۨ~S c3Sz0td1R*ԋ݊E* Nݩ.P(#{O!'k l߀>DPCY`(2endstream endobj 770 0 obj 1035 endobj 774 0 obj <> stream xU]:|Wjqm~6+u[uڽB,npZ+H̙9.޻Mޣ~xlZU}ꅐX%qH+oȀ EP@KKϏCR~!}C[Aw0CS-~aj9O*B%_n_J=9N"!*^JJ]}ڮ\ ImU̇Vs""rOԙ>}1Yw2"(E6c8VDu t-3څ9\l"鉳$R&m; ug$>ݮU1[&ER?NGI$jfU5֐+Q {,"׺rr̪?OKcY<;:=PCAsoefas 9R'[ɥC9'Aĕ⢕a3: >?d+=81ՊY̯1TzozoS ˚%,GWMf =Y=(?gk< syuZ9B}56 ܰ6'1̟7XG2Nِas~le==5PQu3{apFunr۔wr~j+T,$+Ls r> stream xXs6~_P@ڹqKZWMP$(**8vSK~_QN i!&v~׊dxN* V)+%4$"9<7+ $+/ >d0 ?H)m^w۬ۺ~ņrMk4">f}Cjt7B\r6Mݐ+/߬|kHX?qm"*eb )O+F$](*VO^URɤ2&t0 *ÚvK% viF3k (c_(\HYtW䐶$KGgs<[Ŕ@Dz힁\*ܼŃN}Y}FĒ E0~R4G̡֜yxv:jhw7͏PqB;"bspZ./qn[R@uIYZHDyOeéɣjMJ5.ʺ"5~@*](2K)*+&$jzɸN1{RWE3n;-R23~*Gt"(~eJy5D&U mA~cX2q:asfqD$4˪ V y7$% إ&X i h8Y i(s(\WpBI 6 t(+"׸eХG}mMѶy|4*a)Ou+ SgD) yJT cNƖph];^F x^F19@o%2D*‚iS4$Cr9Ix56>cN% 1@ppXˎ)FsN)T;@=MBWB5e Ǵ AӵM\SvޥbCL羳ktފ5SKcߌtmZ|,{!wswoo ~><0#3 XvXkm` F`ޟ2\W7 Cz>rfj,ipQI\OOzf>34L`(bnAkF4߶~4E:z u&z1Y۶Ӿ:Ƕ3@gTAzk܏y~{i2uy01q6f7p #H#7tuȑH^͂4;,HFBB0 xЙt5oXq';W]=tSѤ0GpHMWf1mlB+DzwCby}e߲b AWoP$-_wo}=,ۛ{eF]*Anq#/8!AB9㗎ȳ&XԊ rԣQ~wb:l@6Wgj lxk$?BKV~ٞy{Hg|^3.D!rz(@ g}Gni;w5bFi:.3gyA fEscjk>pVƚ7U–߹pt%a"Ev.ᇗ7V oXDwk8K\ӂN05Ag;j l:|bW"$I;;\! up);0,0_@41DuLl5w䤐~Tأ,Y1~T8VK D]_^@9*[[.xrԲ)z!yp%pbzz6.ATzO9 D3}yͪ;I@VGr/;<\j@$Tr9& 1z tLTH47bA> stream xWn6}W-rsŋH}j,ml]},ӎ GJr}7RApΙwcb\m3v}B"_=i1ahUEm$ G D32] ^P0v$JOs% `eև,]nzYgVFfS"1l'Z^Zk,z]]uX>ӳϲ)^;̗;]nۻ-2Ǯ[ݜW_nly^e4=Z5EO]]Wu]A8|N#:ZoJ\7ňDaPIfonK҄㰡.O&0,6//Z6t#8جXIsj.4UyU*<0Vh<:P /Q\t ֺ7d,54q+TFP48v{,XL +cq>;ᨣJJdU+qǐ|2 Emv'\zjb=pG| דi gCXBύH4>m@ Ƞ:Z'/C,ecȁ%(;jJ8'o:NJ܇Pr{F0Of`&fhX!x0yj[hDкUS(6m/$7YJK[f,XF(':!='ctQSN$< Qs(h)/B[0֍L`|yOhڷnIl?"N㚜 <:҄׽2&M(ǃ_1JhHvTܨ-28q¯[N)|~3 p=n 41Im ve].Z0bÐۉd&$,(w@ |)FGڗϷ+! $Зg31{kEpb;|S Nendstream endobj 790 0 obj 1390 endobj 794 0 obj <> stream xWn6}߯[&RBNm,QkZŗeW$393g_3|ͻ;토C4|n.Qv9Rd@K;lEա%ix8-t\Ty3>TC18l+k/1hNb_ ]5 P zʅCf&<$p`"1`:IL?9*2X_0Ț## Dv%j4}yε S°Pbyw|yUju$ߧ"9TWQ?<9,2N"4k(UyCd̛3_OU3-ķ_r!'-$g 7)ZK#{/mO0b[A0.>GLHo ZSͳnY΅Cyŀ ʷ4D^ˬEIQV4P7 zP>RtGgH̉ڏVy  MAtcR& ~]3Vs6|c0g!=iG'V9PpBF&n%8\e& 8}|A檭\:+fޟkOU``2 "  $cW>YiՈKBK.ŁDD b&WXwU4dM1AGSѿ1g<1;JOAel楬ʘRLŸ)(ˀ |OgM@{^dK>֪1D¤ѱͭ,as! 0H r訠kzD2e'xL<-DJS@EeKT+݀ b<:yW-a6Fۄ׋a33X18d@ǒ#3Ϥ2qbA91эE?ר4:19}ۘY~)'T^NgJ񝴕99O2ԕ~\ 0KFpB]q 1~:j~6P{`b:M`mVۗønؔEוڜfg,%Hu`^K/>AOf 6dp\&K$ч 1AQ1ۺm'E,endstream endobj 795 0 obj 1433 endobj 799 0 obj <> stream xYko_1J3CIS8mQ(B%bW";,- =\ |⇻==.->dc{dX/$[oq+a\u0r&TːRqr/H].4Uto[xQVtO"˪cKǼ|SVml([P~ wo~r>wZH{;[ՖUӧ6Mr_+RcG'M|{wjgB;~| ROjڼK qO%Ƒc.u5J_!l +QNC:C?,qD|j$.oXWLbutLe_n,krsmsv`Es:oZV ݾl)rI(>u,;q'cmqVTNB;ca){or:xi"YB?H%Y9I%fԬ %&uJ£۩v%D :Y$u{ƴg+)ZI 54lCq^_!fys΍pAYDA|/3uOIrjpxh]}՗WR!{ʇǸCgQd(\EyӲCi.}]*<9BAqt\AXki|<;5TPm.4*&DvzoA\c~gvnE`6DK9__A"9|<=lϪG4p/Grhrч $uW<•B㓇N}ΙGRX_KAG^l%4z}G;vNb͚pMdD7$^ƿZJ3~uF^ 놻\DG@Z5(3}#d%S&g c9e$2Й2f_D#oM#%pl(LoaPHLp;یȭ16Kvk#- `5?5{1p3& ͒qiުzŞVĠ,t\!rR&#OIǼ,ś`J2u"ĈIx!d2B">8E# 3Kjp?0ްȎΨ`L `@}Ͷq<[RV`;f%7ɽgqJ.+dzm {Pֶ 6Ѳ۳rn.AٔQj-=˒Ȩ]ETO&ysTDmY͐g:4e.lT'*R'- 22 m^WǬ$Fp,qDHu;`u&ѫa3[ &q]$0訛fEh[) qXmJ@k0钀؍ҕl.3 e#yv&*̍-@8AI/XaFЛ2tkF^ W^*KBcnǖ98 !i=Nj$}>ATVd2f4yA)mvp1$Xš)^8Ik$4cM}>!-&N@L+9 fS.g Ů*CMS̵S]u@=0@]H#9۰h4ݺ _뙑7!WW7QIQn4_CUhv,^d`DMsخ#OJ[ yIBq a:ܬF\!潬Cw_$}󕭢H{, nuu1YD a}A_kendstream endobj 800 0 obj 2421 endobj 804 0 obj <> stream xWnF+fJڽlĞN4BrM$2!)O)AիW!)"UvیC?z:[1 3"*x`I ܥ +{lHbE7d yTN7m7y-7۲Tz5:w/[ߌƘL9i5jPV:CM~9:tRkts̒w 0P缨dp@IFͩ51}KI6BL.ywܜILH$@^mCh,лb{y{k|)F!4UkBpvi_|4ܴ?fY)v@Qv>?kVz$`{cڗ| (^hu,FJcT1P+ +XD *#߹ksyױ`#x?פP%)\vL,Fr(4#fQU[,\2K0ĜVAG9(L)IT2Ăhih>]^9a' iiA6ݙ`6L"58j)9vN]btZfyUiBPBs-%t0Dž\>Z RLEWErC¡dAhXA21[*IQL;0G"mwI}Jr">Gem:I&TS*{sяr&Y^Ls-[cxo g$8( :rzu19#BӲf_@43লCm:@qzxF/W>Ǚ.FםpT-93dd -ڈٜ5O2v96HzƤETu#rq젡9&{6(F`z @A?& 0yy'*>d iCIY,c nldLgUD m?&|(&}9Aɏ"~69X@DۅuZ&/ ء'B[0ꇭmV0,e #ޜa\gϰv5`vRSv54}.N2wsi+Dc&tOE?pxN3h̰/\_-mq͞0Xo j w=xEfqkL| cŸ8V۬.i.nq1z_3"/ s^/-0 .07 +]KѵW^ K j́-P}JS]O/ t8ޤktВ$#p|ƋT$C+Cc6„DC]D 0fVjtLdӶAlu9zx75[pݠ66MoРat^a~3JX+7jC'PY[a5-W2ݼ=]:p}NSR}G04XEw;_gl9_endstream endobj 805 0 obj 1521 endobj 809 0 obj <> stream xX[o~ׯ7SF $''RZ$<AK+ E"]-m@ٹ|Lf71۷3?g29f X%L*AɔIY [fB/`+OSv,0- x],|/k"~;.S.CEHHĻx̛])lMWUVvEHGcyQult~8%Cұ%Y~.ηhfd`TTxڝa5g[oucL.1-mpja6/3_ԕ_Q֒k_ԯkƶBE<|}߯PsAcZ=XƷG&@weQYzGIJyZ/B(P~*[P-D~mk8uJ`񃫎cf&l;߳lusy*I!j,+ZW*<".d$N/6\Dfm`%n0g]~68 W!O4t[}ZLz1 L[]lͺ>u˦p L,k<&-h,[?ئfJ /cGw8_-CA9(Eɨl}[T{Wbb(<|F x*Ǝ6CظL3FR@Tܵ3kj_>Ap]|@ J ~p(bw1Px5Dq2x(qi!DN41HS/ 0ib>vW$ޭZKfs7aBFCݗ[voYޱmyC&5I: TT&tO]h(1I%l\5uhkM߱ WV.^oHl 4xTiԉ)V#uj,Р2_n=vfflgOo~@csx "FBM*xlC} eaP$+!|9yRQvܼ_rE9GXG/Wç3I452Lc0UPDx@m԰S`ڏ+r2=r31?7w$1LF{E5ٵnY0?jl+,= ld}+Y \@ :p ۃ#TU p+ ^p`G#IѷN%#X<8ze=JqVaDrSū,l̜w-XA}_49v lQ\my. j h p9QJQ6{ϲSX[?z- 8'>׻`ƙ]%v軮/ ܷތ_noֿwk>c=q2퓳9 a;~ /FwAr0/XeVGG)iL'E``a^rx2s鶻PZ10O ;bOy˛'"` W|/?Mendstream endobj 815 0 obj 1802 endobj 819 0 obj <> stream xXn}WR˾/ۢ KS90Eqc CC6tR x3AC`'X\, FlkϤ'Vʙ .ГLsMHâكܗ^(8}%76w_ݧ/7]7r@e/ҟ'N2Yе}IS;{4lC>tU13 2+ clX9ȡȹhl/40\LI ݩJ |r?Ŭ`><%s#}f%RCXOnx3H/k?Zynܫ7v37vL9wl!/BEf py"EHppdƒfg G@sÇ,cՎ=4~OcWiSS*RLd&l'Ծ[1HL5jM4D +o==k=¼GdMwKAOʾR!x(!1]G+5R `6%9FoQ+#X ' RA }[i`aw(ph9쬊5-$uژ8Y96DZǙLljaZM4]TuKVF]IN'-4]zQ_9=Ǿ<52IF/M.͸FܣB8?:=+3*,uz}[}'m_ d`&d%OG*BbQpd@T*=Faܙw3 ?2Z5)ٲ0bNEi>&JTm/u# #ryW43NbeIH* |',ӂ& bqq[`X8\\uX~Zu6( _ٻ)S dW= KxwTnfST_ʣrfjZ5W@`7Nc5XA@xR:`fPob_8Nh$pldN?9~#QӘ @~nmy(ڍuYwp%iulj ܗd{_Ƞ$bڰ!qr~X. H.( Lȫ~.0%`e> stream xXRH}W[nJO x7o8,vl-Of$Ko+Uy?yF9a>MJ #nQl?IHi'ENDQH*2N ,4&Q" 5'o<|ʇ8eBM$ˎ=eY'T4szvŲ-t_8cI9yݿ"lO諦&vնSRo#6miqJEWƀr n]GS20UY1Q>MG2oˇ_W岪rݴK^Z4M'E/&ݮKҬ͒U^ҕ~_1]Ly Z:W)=`443#|* GI? 7h6m}gUKygcb4??PGeW Tu"GmʧGZ_vYoalm tI\]T+ (\c: {^B )&Fh;o˳,9<&x3QDEݾ(ʮә1U:.{lnHQDQ}js$s.JMZɛbbY0@ ჺ<7닋947[LOș] 1RLgW") 5t91ˌ|j NkM 3:O<qƇI@rmjKs`z$鐐1`  W}F ~T1e\%m|9< P1Եw ؞_LW>jmJ8c-ԚQ0rW36mP~jcèʇODc'@(L' _[ϕR@~? 8~uv~qyu~ܸ¾lE{ CU:;8%:—iH};_fMƠA[4^_8CHxCꦞlRQ „xThMcRSmc IOSoL17 ¦F>ے̵4&|ȺLk_v$VJC?nFxN%րVC;d߀ϩ-~sowS9 217A<`fDe8&sqYi "Jj@(ZitL\\ԧ=z)Y"ݴ`QtӅaPPq(O_%4O|./}g0Mg,+v} np8xHӔg,U:_Y5~ ;A&:O{[ӏkeƘ( *US>-|Bv[`(|bLܠ{*10'[IuU24;`sj=6f|KxT5}#W3{`=>hh1e/fR+r2k֯P+Ǩ}kIC0nM8Q8Da@`? S,4k'L=$, _Z|Dlx޿Yo-1+4.rjM5A7 49se0ò1dH.pf7}Rّ:x"õ BU/31~DoIaw0lb}i]WhG3IcLjqջиx2A0F%!1 TbX f_@5܃H29̽Tv bqxEPY΋4tH=~c`:]cmm`zˬ9V߹m (@~цpd,B:ɭrA93t۪.ぴAUm]w&QW p&ΠDߜ|4϶~b<Fy\UJglfj?.]೭8 <۝#eup)gp4Ϻy<Ʊ1LfXqϏU2ԙ|UK ⲲͫPnR1Mۜ}]@%7%Y:=l6xy~!3nn)6",Eۡky,y3iW :iT>QP$ b ?>O~Ţ,endstream endobj 825 0 obj 2366 endobj 829 0 obj <> stream xX[sۺ~ׯ[LA}K3ќt&hhJ‹Uw #R۷߷,[n31/~,}?iPl][ ֻ}Q0\%,S)[J,S]!yz҄Jtd[ߣ:uU_5Cφرxbkӱc  b]DZ=;,l[ |`X>,e! 2(󇅢˅Jyr{t.J\) /o!6"s#a<l7;jɓ4PX-9Km3U0x|y"?‡C!FMV$gYErU?ƪ-=.yiQ֩C Y*j2kbb4lYV guc E) }JnLloЖP ;u~'v +!A kϛS9(I}n@kss66H I'"B\#\tG(W=HYAiwK =!},egeѷzm)E?o|f 7wG"p+*im8  wѯ`TQ euY@N1ktQlۖC^t%*iwP=0O~Mg k„,Z\]A@POAxXBɣaZft& W | B~< uPKZ1SrURͳp6lq] V. !<!ā4!xu8QXۓx*Hn! h!+^_IlNvl')𯛯_?}A\U"g\`v{ mUs5 Q5ij P(1 O Ʊ)$컎J ڤ?%Z HNu7Nmi'΃O7igaVH$^S~a8i Frlxboymz~VhP!TMX7v:}V$d>ًdg?dM4@^͡rP ΐpgoC{Eu;;0p22͞5kG 0FFn֞D*".0Oj^ꖳ^.qbh@BJPT0~^r3y~0QL: d~xB$`wSn_~qA^y#+H0pE~m JK`&.IW4vK1ZQ@I.i;M(X0$]H5[P@ǞկIXa\|12sDR0BXSs6{Цݶͮ`_|k<+ $A|gKTꏂBeWLEu դlZ?V@<k=s@4q-2Avi-VtKΑ)Md-l%K %{FpX aUm^BzؽcΚ]5*_8O OwL( 0\82eHjͶnJ^\1H_#3 jso=#';E)=M$JXIد)-p չd%l$ɫ' Npv'pO,h*l1hQ] MȤ;V&0= : EO\}uaͫd1aOL&V0NC]qjt}%2XJcOIR:&)0&Kߣ0nRمK?\ #:)<_s^ %LJ8*#ʑ&\f+\Yf:Y;I`3}&4xT$rǪͬ-ffv}{;!:D0.uOYE&T]rH' /oKRxۤWSJ5<嘳?Z`V1|;P&0 {U+ E^:~C?ʩ^BoY~)R2MI<3W7=7endstream endobj 830 0 obj 2358 endobj 834 0 obj <> stream xWnF}W[Ip/\hmmy "2Tx썺u pٙ3g挾ofn#gZϾΈ>D#ߠCbD(Z3s *8@[x[Bqe,fB%uE(y e]吖LlӲNYz0-w.U!؟cup~ ٪i9pgEѡmd" q&k4QV*РZ7@,{|ʚgTH6cR]m%uoC`;tʀp tNݥm i|O) e8L_\>V=R pZYC A(ૻ k|LCJ>=&K8lmc$0ٓ;Y+S|K׭'HA;Shh=D۬a@Yn>]_TV!T ^#޴ɜp)RF5d~=L~iOԼeLL*`Bء'mB|.,5p?OߒU;{0ǧX%&o.j; Mv,-zcTrVk;( ^ x0Qkd&meK#鰸X$Dc%Z'&VB4&QB(-!F9TGtr;%O0 0MDj-ef@t V`s;q5Wc-139i]K xN\[N贒 r">* |CD%@2QCNS8傀r4EqLA$ H ky ף؏МB Ո./)#0`ʝ~f66 @&y_ ђzSί?]!(O> stream xX]o6}[ bcm)ݩ}"SZ[Hr%)J&]dqK~{Υ2<ɾ_%db_Y )*#Mr *B-ٜVQ֛?`e湲v*RX9 @vע{3lMnۖU^l;Cn(I̤EIu~:r.au}ܭcɓ$z*p_VRӾH[U=8ۙy*~ܮn\N<@Ƕs{4bq:~-]2-9C +}􍻘;!2^\u(_[q屷Eh8B'T⧮k*L 1ʥks{b࠺,dh5*ޭo!'-d4WcP(=Yip01ZsUx $QѭYFrz1TT&г)r1W4Ef8I.^$<h"̸pߗ,rH:LyJĻmTh ?-B+*شEO d+)={gHmzHGd6u@,U'C!O_p yZs;ᑥ!]Jk ` [\p;\ f˯ma$˴ 51XD}$T[&`D{֗9wTqbl [f s,+S1mT @_I ӁNև8"lMJ#ȥ7v4UEX p8Fe ߊfp2 Mԁ@8ʥ" @ZsI,Ϣ ڢq ,@%8|(rLXIP\p^A;Â5s^]QpKz26Y9(\by!36H`{X`^Cr 60@CI\I5b(pj@sa;Er>еaL=`:^(-7AF #(k"&GJpCSt:{7ӜDgl` G3h}RZ%^obmŔ:TjR/ږ~{+2[TS̕+C\2 17o%&Bo3XK,X;3\:I!sBއmYsp>M+rJ&l&`l Ź L[ӡlq! MHQ\ t6=1%`NwEaaG~T{IrAE mZfQw5pB7[c\Qr%r kϖu# p"@xx3ves;zdkhdT5aKEe6`hYJnqYoӵ_k,A%SL>z BF/onRM㸶`y! . ;Μܢ?@J2EM$ 44(Rw]gGSfm,dimnO2}4y!q=4vusv߶)WWM[<{^?d-0C$"h]t{/Es)gLaC3~Oտc63endstream endobj 840 0 obj 1904 endobj 844 0 obj <> stream xX[o6~[A&|v2@E5[Ht#y$9Û$d"I,\s؟x\|C aeAC~͂M mv "ELjʸDE k-MHdVkR鞗y>~+Ͷwv״pض㟓K~ 3Om\3It8_sC 0y^$y]s+8;p3b,qZ=B}*B$&y4EǙPʔe%XP,_NMy8A }p:L(˿7?OPeкY(OVX7$w\VuoUt:JS4eU? d4L*HnCB\ 3bxqJeʒəq- ΫXp2x A Q$^A'3x956Ag|2uvCô.^ 7M)"p'pܡx#2lHǏc Su{65aIP%-쁩uT8fa2E2ord[ճKf=F:sPEq|j9D扌}4DNDP_m[>a.u0+SjWMɋE H̩; kPA|oXh,XˑhzZ2jKԶ2n8ذ{pCHb. w>BF/cS,1>XSh13d͚=TIWM \H.vRXZOVėKObŝ s`XP_ r0& XJ_77狐 z#>+}ЗCߺsT0fޯq؞|\PS J+K<(z6X8_xU. CRle%ӶMLm[hx|~L~rv:IhK>//;[nq*?XzhRڮI ǽˈsgTc&[8u>66tJPOrs4r}@=4=W}~6 YwՃe |O,MK80pkۇ޹.B"A.vmѦLo?xM{F;"}Mp2}5wkflʜUK43Cg h-Ү $?I#a͂b*Vn71sĞ)2,gءcckiB%-|}--HX`s?VG KurwXFpywp[^'4|qK`%xLBj{A Bw=j끓1K5OK#@&~ u˽*g^{?R 4m7şzuݚ§zܙ%z4;oـ1ęe4uVn~Y1[$0 w>)hh?dFF +9Q`L{ /c+iR9|>*(w#W@9W *%$dÐ@Ȟ5H1wqoVtdlt`5f<ߝ "m :uS 4qr0z ZrWAgZ#3R7"jM{`bkwR BcVQ!H$ !{S!X=L5/Emk2fEk`̽ه"b%>`b;aO`zl7H/FƗaqAQfp=endstream endobj 845 0 obj 1933 endobj 849 0 obj <> stream xXms6_o2J$N?=M/>tꎆ WTHʎwo|t 8#*YBqb3AL IePenPe AݸUFe8lycmf" a>4p}zqug쵈6k:EOO&DD@oli|9 a,QJ,`UR\|u !R9/HRs9Qژ*)];m&,yȷW(X[H2 a^G+#qT} e!S+/9,f;Eҫv ƪ!`ׅ{ 3>pNENZ2)"" Y9!a@ϞSjY:L"W0řO'ymC Ee0/7kZH vCYO/"ֳo?|4XyaFv GI0usȇ SE}'k&=&ť.jR -)hhfr4ƚ6ac 땑(J[ xTC%W1 (^]+їivA!~`_X"V)]W},5y˔Tfxxh5"};Y0^F*a,$g;l4ohL&8R7Xa> stream xW[o6~ ʉ͈QҺ>͚swA\D*lɥٰCR4i %w 1Ai4DjˀЛـY "D(֐ *b8 @3x8,x"FclJŘD0mgH~MvۻDoYlDi.GpƄkZjդu^ǢׅV6߭UZ6E^!>O\*r_s/܁RBvordwFơ}+u\Xt qKf>BMoWhnBo\cq~>D?%VPܳ47~dwvJ"M }=-*L2{fzq1}d.cyt3CGј2ael@q_7j-*гTuKa!8+0흟17|I"{%xz#ٙ8n *W N0c4=AM:'f XGcKGSa]N/B^J[ES,gSj qt Lݨ2mdF !{.Md F +","fxzfy W􌲶ՆuٗLC9t2\84%raH]:jt Hx! nܚP w+upv%Ü6k%ba6t߹ėXM2W%{:Lϻ:r>|Y<Î>Br zȇ.Prd:º ʋC6Te16/eZW:QA-oTkK[NGA$.nQu6HAoh@BW-f% MDHU#qYRĬtS*':ş>OA7P&*1fh'"/n5,<@Ih҂bؤE-A˕j[ZߔS]TCfWm +f KJؤ> stream xXnF}W[.4HZCmPą@K E*Xv3{!%nRA;sf̙aF9ag?mLv݂Cb?u:Y sI$#>,_?x *eϭ3£`hb%sJ<"*ջ&KԏkSweד7u%)ck͊ HЈEf_MHhZ޾&iGj<鉪aE<WK]9&.c\Y1@is@kƟxHu )=c!IeR4S1@ԩ)sJ󎤤HkDׇt}e#i?"s:+E&}> stream xUM6WL/mH\E[xIIP[qa-R(;$[(P@3|q|7߰Oc UP9f0,|9df%8d;?ȀG) B'xl(8MeCb -?[gΏk endstream endobj 865 0 obj 891 endobj 869 0 obj <> stream xݘKoF{+}qDO bIE\ʤCR6;Dv"B0,y7C}ESD^/rgf_gD]8ZnBvsr.ft YpQHsnY͒J(ͤH3H%kf3mc^k*2,hQx9}mW;=wW=-9.@;5DfFqN w?>|*HqLP Tc>]y&1+9aD0:挔pDKR~շCۡ- &̙p5WHk6#dڝGaн)3J\ *is2C.IaVL#V.B5nPd1z8~b1Q ^d7y`9t>t3t辆hW ~8\ a#6I;U )ڴ7]>4(8!q,9`\\,>-&8Kn+1w]ۙùqKLނ%4vC!VrwU3hu܌%&;=))3\=+`v`86%9S9&*rЧK93D!N|3~26<+AĽYyvqyh8%׺AM tb+jO]aHjPfHZ3QuΩ[Auƅnf ֐Cgq<#CfGIƀ~'":[=,Uu95nV۽n dqFn FeqZHes(eFF :yLٯ٭endstream endobj 870 0 obj 1611 endobj 874 0 obj <> stream xX]۸}[ 护(}"Y4An) Ymu=D磿Hٲgg``"/s=R?HLY~Ȯd71c!>;r&ȲĨ0NۙO DJwh 2NJ͸fe,̣nB,8Ï2ϫ'Ǣݮv_uV:lZ]bw2)YNh'| 22eTZoȻVl?͆Aڶi;m>nx8xV8&*{MǺ쫦ȤlXq!i5lni0/Z}y,\>NQoEf<~360vJi>I@fٸp9_ Q%=PUvln0*Y}p=FY]#'*S9ia1~CUdTe=A2 l{4y0qB}ё!9i.cg `Ϻ O_x*<)8/D^D"9Gp@| R}ŰPnnޜÒ+:`b=[s]0Q≪e!2SnOVLXI1Y쎶v4+iN1u>֣'f B8r2P /)"TLdu$ OQ nV^*vS QޑE߷xgΰm!`qrET[2UPlꮷ^q&ӓ`_[D2pn!xW"L{w%x]R/JW4"BIXE ^5*QRJʲXQݱ BiI#o*5aC֚;xr(JxIUKTs{rL@{ˢIWl0ܨ+cG]h`JyÉ} 4rI窞Xґ9*pjRNs3!O-fp:'ljIi닺7[lm=9DA"tN ̌zy8sI藘&'U?9d;R4H8yE}hQ[Ӷ,ZMl˞8#u ^*Bxܓ&q!(b*g~N*RN,3y! ɣvLhiJ,:p&NL%>> -IAص80Df dbVc}AnК1yqn\xVQ3 *̫Tc\'"k~yk5Ar)2C; [`$Pk2 BmgbL;y`\yP\y=># 0싒徲FN~7a#<E$v9n=2 {] ^bzMTgciۣhiq @+[Y66[F)VR^bO- $Ȁ2i%BڗmU"Ϻ$8]UESoٮ 3k0i;\lVO;-]yKc @}A=x5#+TmpE^I"ܕ")KǤ prR©҇I`ܛ\%-EC(U!GO\İ8Fc\KȽ.ϸYVy7{s8?P4A9Up2/N ts C²tK_K=u5k ic h8a1T&С)7J$Mo;M$%\d!suLA.qǽAM'M!E 87V Y SS.@g=m= okԓip㲰 j.}3.<#m^}/i9;$endstream endobj 875 0 obj 2140 endobj 879 0 obj <> stream xX[o6~[ f)ȽmH5V `2T';f` sw>"8DD8{Lо}%r#e5ch@!E %f%,F,XW!Rn G jACQlzUiBmQ^kP;$zpȳYgeQ7j,Ї(N$GYWPfiz(m'ᘹ;ݮV;+*XhO ܰyn*w@H8ؚ8s1O7sJ~8w$L%Z\'hTjN#LSnglNR}?#X${•%L|qa.uD^l6clLiLS#+܃rS(p…ipʶ2.+E2-c(纘&rE*hVXpU8"Jr\"I1'TUJ9&!%2ILzԻi[UN|0T"2!UL@=__Z@p-Dޠvhɻ0OllOfNӽ l!S@CWQ=j2x_ʼsvpƒ*fHT6nj2 qX 4b; fiQ#S' .!?O' JPqӽ*v7Ёn ӴÏḮhEFeHpP0}`&\y7l7!bCvM=| HRľ 0:wnL=\Oq!D1'g1e$cGI~ & jAv,SR1Hs krv 4:M0;>mfLskXH, T.k,Gas s/.PeڥL6]n 9xtOS'4M LqקSG_h@V0 l({=uϲm4{P䫊?v=^(ʑ/cA_M屣7}CeqxFvA}텄i{ m,ԈOhD5-"_ZYѭ͵^i Lؤ(u: U9c@BٴMa^no۵s.ңUhՋ0{$r)+98P zLbeJ4S CAa {䇑QC'54|si"XZ9NtIsr]Zi(7 k]rendstream endobj 880 0 obj 1637 endobj 884 0 obj <> stream xX[o~[4fERs؞=4ӢH ChG"\7 .Xk87rBݽ.{L١[c!Gٽw 1!z$*bJurhY!y'(.A~ZI*Nǐ+ytzWaMrˌT뗪cf{Ӳx];/] ݄JsRZ4}Xoر/^p˶KP(8ΜNUW"B\LQg`lj.ט7VcZxݝY((Q(]H~+%jW.%4Y q ﹪k[0݁`!ؾ?5;>Nc@?m%+^H)E\.[?" T{R8()g4͝@ g'Ww=0U򖛣n^w "EZD%HM#9re,Vq`~TYpB4@ni]vo x<7Һ3w% TiNBxEN *@"t?d.;W5J8%]{!)2-rn|S 3ύ\.~OTB4D܋r[ˈYˀ @[ЛJhܷڦp'4+xyKB%(U<c{C&c\4ͬx}u_]{j[ 0K;"#3CЌ>M a8X|7L7 { qk,4gB;sh/S8r+AS*˺veW-|e}+#4^ MTWB̒Q!b~$Z#γz{ܜ`<Ӗۿ\0 ]j"T8Jxa# sQ5dO bӶ>4V\ Ko1?5WqiylpC fWcE4ҟGK;7հ(ONC5~*$ū&/`2giTw86X1 [8$Ťý3L3vdۂc@oPjEf ^pOrE}{s 0Ƌof[ f Pg2>ô2786`_13i GFQ01RYo > ,Jwz|L̦X_SmtzRҮ wtH!eHv!(݋9%6"O7-#Yq(8|IgߞM2'(`Ns&\PSAsxn|MMvJGCgY.b~KHH6_nSR `?4Yb'`4|.}mw.a>-yrw/OGcI2y<wkL*tA刿cq GsUkf TYrCќPVeVd鯾+߯?Ÿendstream endobj 885 0 obj 2346 endobj 889 0 obj <> stream xn0~=T6^lsr+% $ҟ!^*V~38̳l&PC.%̣l2 `+vAKaAD.%iFYDjyכED:Eb51χڍ0'b;(⸈|'`HW)!v; EILPnaGNdٵG3EYPovqfldލ$rtk%W>m^|kT/ɲ~eu~endstream endobj 890 0 obj 287 endobj 894 0 obj <> stream xUko0_q?QHHP&M MSU:9(GxC"%}>--ִ)3lH7QP}|6@qO m vzmQ7"Xq8?6r5u`v=,;ZqH9G+D`28Lg t77۷`3}'qD> s t|',K aq9$\2)-(`vܾX;+TI XM3 5hf SE%35s05hAR  c-ȧODs$rLR>AA*RJGjc `:`o,=Ueߗ?\Uڧ)R nLvű*;{/З(/5}^~Ъ(jw~Z,|':4ͽP;M$vj*J58Q4K739Zb192Q(ϵjl!<9 Qoq$&fǺUmb6KIptz3+R3Ƴ/tb=9vpDB)!YD lsĵDIS]*#~,|-MC_ihVLĤ8G#UL9uג K8X⍜tvmu:mnoF]j{M+"%Ե]{gsAockwKendstream endobj 895 0 obj 808 endobj 899 0 obj <> stream xVMs6Wl/0oK+qt⎆"!D$hGwir۷K܁883vt6`ՎXF\]˷S: *BiGn0χ !ݎ,m˒$$YQ 6]xbB;Ųn*/s(Gb#٦*y_7c¸1ÀWhY[5΋ݼ jk9)'G':d>4us3>'c\"JL?ΧW׿[!eEVlvՊdpzFwEȮǯe~$!w*FA Ŏ:C) Eq3Qlk%6e%7 *=B,@AAuզ2e+˼ ;yZ) l4B`/uhZѥjڣY*/fS\W-G46thͷ64OU0oV\=1:r@RJv[+"HIw! 9 5WPa٢$l I?!Ry͏fzԞqiDt;d˯ S?dfQ)/t3~ Q|O1U^S,(+{rmJf‹Lf4q+kKNN]pԌ/ pO@5p#š0?Ԫ)Y¸:˩NlLݸ"UZUY5< Y&;]>3ziĢ>,ZCXj+Zi ъQĸdMVz.*9yFw%c_ eK\ˆ 4OVb4YA'|;\Ǯ}<>K ԎWHҷ#Ǫ7*DvQUSoָUZNaJlo"Z^wD P?&zF_,\$OwwL9 =s=fU5;pyrj2W~ wendstream endobj 900 0 obj 1203 endobj 904 0 obj <> stream xXr6}W୔BSxI=Q MB[TҎŅdA |%!e$?NFB}1󒸟EdY0N뙽I"I` efsr$Y7`Ehbwg><&Y ) IÈcޭWEj}jkzZPZs$sq.f#L,(_euӌlr@[s#\rזxe*TL_t]ۑ3RdRv ߣ I,v~,@mm.9ɓ&XwJi7F)qNCc̻{eJ2Ap0&ZEcoIU"Z<[r?IsFP?'cTޔS5Ń2t=vz{9gaHCƃVW{_ ‡D&w=4vF]u:@ONBf"pbt18X>]^jMJN,_i9*AC3hӥ9; blE sNJ졂:x|8 Ƞf3q&ks*d2ȫbnܹV ޣjŒ&zRVqlvKrHZ#ha~ slL yg4F \C" ņg754"k-՛G cq]{.## }{%n';r tj*~#˝sOo4(dyt"'wc6dB6LJ\QtG?Z5EChf_^fӺ#]m`TVͦ߮ڡ?"|QtwQACkrۯt:h_?NC>n%̋Nl׃Z4h+a1DӸ=z[[DD4<ɗD3H/Q KC" DrAaO៉mjpZ*n ʰqƏꘛq,oIL٩7Oi:J8;G%G<'#O"svڦF# d,f>+AehӑF$Y7H3$ ,@n΀]n91$c<'#yN[T vpchyh'Pm`4Kp| 3o'e dTe۹ձsmV}83!;M_'5nn;# [f$<||c%Aw'NQ".o`)tumJ/./uK=z۵f'S=a2cdYM /hxHd}m0GMi?jQ?sxj2sުƫ05 Q `ω$fAKx) }X?ڲendstream endobj 905 0 obj 1801 endobj 909 0 obj <> stream xXێ6}WRbER(.ЦE: la6m+%G|}gx6l3C&1e$Ə{2mg1>ϘY$:_3A+إdكpSLH2?̂O 2N\zDq&HJ|1(+]QiqwXU&u%VI!NUߓFw!QO|X81Ki-rg3S{]mݢ>ucJIktl_Ж#]mLI )-y܄ZIQ2eEs @2PB6pO\\CX1:J/A8 Pթi eYž\;0"b1WN-A,X(Oz4e}V4qR.)Bq-SQ@RC 1êX @Lj0PC,W% v,Heʙےd9⌛T -t$wܟ0ŇEWh `8O +u-g=Bw=p\QHw<PЉ#wLG],KI̦,xj[gK@ r\e{X_ft82n]ؗZ/s85' C"(ed h=[a\O2 xYQ2*E2yWtĽ932jΐlb$]Ֆ[;PnuVsёPPzXZ鶽A) ?<(y 9R4Ts4""m`REc#1[sz lMq=a&ՙeuZP 2>OIS80rF3)97ZIaM\a r%4IۡovwK{:M$"6vD,0$ A{p4*;<w{Dv@&%rSDTT./!3T*GV#_|TCRk =DEW벨*7Y* 8 9ȓ`-W0@SU]zuOؘ6ƌ#xUS.5 P^?P=4U㾆ֱn`96Q7Dt#0N2coXmNr*1s0J2x|:Ȗa0Es+=Qp?LeP)!1qV6㔂p,q [3AudO Xo} ]&3XqL亗-+ۮ\74/tkvG#-S<$d泿Vxendstream endobj 910 0 obj 1722 endobj 914 0 obj <> stream xXێ6}W1bDa&`؎ ^Dۚ%Gq>UER:47QdթsN`~qSvfⷅ"f VLH.싂ɴbYqb Z!yQnU/\}$ E(E$M;R۵u=34ymB+GX薯Ar(;5ͮ5c ^o^Wݹ.evq<Rr?lP$KJZ$$p],+;Yn3ݞmؾčBVNf1E6Ifyl3i&٫nYӚ u6tùos0۳:ٰt(R8Zzj_u[VNep /KHy@33prӵ|J4MݲX.aA"NW@4q,%I`pJ9ogB~=4faa/K塩9EŮǖX38 _T!H? M0x,%xr!.e Eq8j1+x;f| 0cqv h\kaDi3;[0B3vY ~`x@vyTxDW*Ys*m[;2ː0$2}?5!l ` xH'CyǍnCRC5j c8'PiwV;`عc,uV]ZXu=~EVuSs ps Z7*f◠ AxUfH#q! ]״V(-tHΓK{gV9qs/{gXM7u7PH2;27C|]Ҽm19|a mxϋ+-7F<=T7&/oe{$!7;wBT} C:(׹ͱnpBsԻ6U7>BLQ̸s| p3e6j@ Hm>CM;ڼ2urK/Y~M Rw@W<HK3oBK@k'\'Yn =gsqUj7xG5YRuTÄD>Tik3ӭQ17& ~v'QDΆH'jvF$boqΘ>ŘX?:C(tՕwt<ۛ‹V3/(t(HV΍jGUk?4IusԚC#i`V=X5d}=p]4bWg^ik^z)pm7f["[woݷ]: pWc3 5wsv&oXioY~(s_d4 VOk?'Tyvendstream endobj 915 0 obj 2204 endobj 919 0 obj <> stream xVnF}WSL9z/"̓ FEa-d6鐔SwFQ@vf̜WU܎.f1i#د~F%z%8dȀG)"l;|6Beib%|e9:dDo#zݣl$-U'*߀lBvrBjW-ݮZz1c'D4Ocqub:͌?$!~yU@+V=@ |hs!Z u=:qJ#Q{Q&xqс j"oj-۹7nC5$ngt}n zƙ.U8?3}*VܖC9eT$?d7p: CAP6C'Hz IW ) ij!P8N75 KdrI0'A"tZ^_Z TlԿ(ٶ`Xc8΅@ Ė#%c1nrLͽV,lۧr]Uv|L~(PA]w&V}'F)L9F Y76$:=zuw$u}3Q UuK$)i'PW>L̗ViLRwc*XA}/4C&RT`2ɵ2Ckӗpu2=v N vbz<&cnI]ՠeR }d;$\ &2/Z7%r;i𨭭UYqsBhL V_lTwd 3~oC5 hDu2lʕpf_(!#/v_Dm:W˾|p;8Wy\jCAxNޘUoRznPٓa131Z2۷)sصttg8llCGqrvyP9.Hps)G;6z|{n%"WyN9_bw/l~o08endstream endobj 920 0 obj 1157 endobj 924 0 obj <> stream xWnF}W[p\4QAmQ؅@S&J")YrBIyggfg9bLPl>=.ڶmgf."ȞЯC D(Z3 *5f)&i6b/x[Bح6yPd.+aED mS[.qh=|Ibͻuڤ6-Cs†-XVl6[E[8˜-UAbջX;lŸm~51jAor[ bG.SjO%`V*ʺB tLҏXp:(mQY=:7c}Du1 8ZqDcoiN裴(V^!۬)1 E6A! wͭٺ\b(yj{2Lx@2di|m^N1`;m4Ma("kK`*5dXz1LE^KM*@e)PaG_o~@)BQ`ԫi`*Lh vHtbe3-G ԼBu;;\7ߓnA>_K&GeM~o% wƏHNkNIR*9G:zRk`LG?9zS(9&>N0.*;s7E1+#fW#ۯy4=bn4XT8iR3`,NzI=a Wqdf2YkfoF NpeUԐf~VXHG~z.Sc*W> stream xWrD}W[T4;]݊XT5%|==3,,EJH}9}L3P€s,4b%- B`ep?"…@,aW(]Yv肣^9 p<_?jmWzf>dX-"k~d]We&_ka'9WVh*hR\o,N<Tvr{>Ma1aUJإXJiJh󝄶BHwy)!_ga憆jUU`(1g^b H9nvJ92,: =]OK|+TphG̞lduZnd׮'l2t3pcu6"h:JQzT[V`/Q7%pNڻCȯfoF6_v.diWw5$eR׍ըdl2T)S˂x+ǃz2Gx *idzY%`Qxwߞ ac̠iZP0=N?9%o+>n)k8 ySQC <`<$ L{ఫ1jR ]T+lD<_ 9 ǃA4*-d&TE{4rw|״_%~Yʐ6 h|| g;i/pUk x!ѦWc5C$W &F+_U}^:[fa'AP3y9dxN'#m(_]~"DŨ8$5ry˥EJ|{],o0xO5,IGPǫwBg3(d4aJ[Dri]gSvxĈwڶvVʪ{E0 #oX(_`QEkYC ;V}{uP$HJ#dX`Z0UZ,= MfGuDm٘YjmSTzJE6zdA"`MMYG]AqML:t~Inz+9LYJ#Lki%b#;D5i%6:U(Mf^:񖱂z6MJ{CAvs%FHa^~exU~x5%*銦C|Uy$|h%9fJ&CX0)8bFDow۝#~1^H*KmIM?c3xF?xXI9v#/i4ٹkg8dws7 OEo^RB;|#rn$ᡀg7>ۡG?'Nv1I1;A5CÂ|N9qn^Pv1)m %:,snԅC A=Jd=6>,ձ\uẙtꂩ/fxV> u#*K+h$ˊmV=>> stream xXmo8_o+W|%}!Y{vq٦mJrr_3CR/NR$gy}c ,9-~~ؾ[$l͉mPlU9v Q0i 4˔a"rZ!yQ\.ܰVFņ+"2\P{,i g#Dζ-;9[^ʄ'Bli?_'P,ɔrgnueKq6m)OFOֲ5Nd庹?XVn:EjSv/" an]\4q//6:*x} ~Rĸ ]z WG/e MnF} M !Xnep0-#5Y %kvAA ^1^ASo[9/7\3@~ɦ<IK(U꯰}.>hh똠K 1$7pWSX WP>'YV|ڶ|{e\+˦nC Pug!eBh;iIE3UEk)r5|k2%aUǶvG啀UMwy(5N ch/#yr̘DRP"P 5T* ${Xނpv!W[JyZ߈[xܫ5|MS%˥}6)4 0 ],A@FL%vbkc҃G@ $7D6J$j.{S2=0\w=4j1Xirt~TP"eٻٷ%t(xږ؇ 5&s Ԝѱzv=@p2nu\9B fd<^ D;KZBp[xZS8wzA, l`')6aq5XbDPJ@T,-]g{#wc.k`62~4B4$C'=Wf RK7rTy#ǁkpiӘ~ @D7 .i R7=blVTyBBn5bIziZBց˯~$ TL^13Z) Fgr M.d9hqݼA‬3Cmn af>Ek_S@\UkB+뫓DI\iae%G] b{KmDkI.Ov cݱ/g=CǶ-څ5zPP6:m4n,~c?-bg3\)Fuj+;'DfO^#hdf*i5yWA =]DړQ)Z=0ojJZØj ~/]1ސ;@'"![+2yARόI!닋O}x2 o ZnC&! 2hKi=̂@j-htuعl{촸~%ۺj:b9}R$?3`hN +J3ix7u|дvnBb\rxܸCUЩAWCD=o/,'>U|/)uu+Y@7+T Alf*V,{{|YZE@.ܶuewLboMPJ9?0}:w' C+7'U*TmK< pGpܶ?T2$f^^hڬjހ?7 2dh.(Radd&?^KQ Ã捖Xz޸J޿Yj:QB5#`JcDϤyhu`pKc]NsHzl!HL0VS[~`Ao+S ofJpP_N֕>u!Olay35pF C'ĽMQK'ȱ$DG[fدe})&pVn ?˼'endstream endobj 940 0 obj 2391 endobj 944 0 obj <> stream xXrH+rWad ,^*ƭ {DJbZ5rU/qux!K>=\`QYDs}m?vnj~,f5V F΄,8aY,0 |/NZ.¢nY͂D,[-?zjWe(dja0Eno|]-DPY78mNEwjuڲj, >ʬ Λ^ 0mjED:vscm6b7Séÿδu{j'ok;v08*tXqh lN͚t" %/"g5Ի}˗Mʣ0˃1V'j/ qEX9VoeUu9 =XwY``۵#mlbaVs@DRxJ]ׇHP.: 3,N]E%2AzZ;VcYwb9j.O:$0Oյ=plQAJ/0r-Of]S1XݳFN3LH8{BE}?6Bdu<4H"OǮ3EEh4K$J#$&ǭ NtYםjX(+{Dx8܏KiQ7)(844(&Jl! x([-i.GPOL' !@@U*"օbR袶v'u<]rn 42 k{&zLGinqViE{GW +I-Ujm]{Wlt2,S }ba<8f?.Gh-4f ~ ,wGq|lf }3tRẂx!0dDb=Wal:+ދ^y:"sT7Ķi)!KNKX']\Zp dDu ePvs>yia/y,CZ}:#Vq{c%,! t \ :<#V@PdLP+K;ckQ$eS5u4ށ!,#sCF2R{Oai(W{pܮr1 +=Z~ l9,Dd/M<MCI2~[fK|[M>|u~51U~bpqednEoL|N| vdqdI=y>2'<} >}r`q,ޘWr4lhD}ճL ] ]U@lU#z݋ 0R?CiVCK.7_ HK”ۉǬ 89x?tjGnRhɘV#))_^H+ҔsV[F i ?jfV9'\$n K c.>_Hfim#K6vξ2w9jˆmCKLd Ln~URtPd7f{&v\FT1z> O>\.Yk$Fl3ѿer,>LG[:+M=^)C h/Ba=-~l5/ρ9;F2  nw7ˑF:ӕѫ=f3Ғ䖞7ޫ` ̴fz*^3?b .:zU1BgҾx7>G20!F-t7Qhpk8 a_@[2Ht8GڼoKPxک5&M;cB G9(S8k/a.od͉D5iendstream endobj 945 0 obj 2261 endobj 949 0 obj <> stream xVnF}W \lsE.MR8.((CT+r0H_;;KF€%qfY~?g̃'#|.g,sJ,g:g,! bXgϗ}}β,V~b)ʴET ^(7rxˆpL! xjq3QǼ"cx B΂سxw2N6^L,MrVvkrVsSNf*":9 :s}/Zn-m- hʲyz]I(*CX9_TO_=@|VP*n)[Yk3kO<_mӂR7{AǽQzkϫsJ:Vs*= JX^WT%:PQs@N.TtƗqq: hbpt!'ӔBݮukLdGzwM6\0P3'f G֐B>@sP{Fca>w;@ Te#vMy8@/6;,h |8 l uMt|muD9"Ed] Iy@5u;I3jT^ƟAQ\_(xUje܂}pJ2 ݋~> stream xXr6}W୔&D$Li&j:IHb+ /뻋 )3^^:~-`g.Dgqxy!ɮ[Dd`f|^d].E'2ӌƂ8%Ew{YuTFB\zy^Y.BazLyBַ \BT%)bۼnvUUnyriBo c׏AU]fJTpjE2 &n,/Yj6WKg"vڽX~ <7a0&9߸'%MeS[F_~ xc.)#jW뒬ȍ luUM)b4%UtoퟶlumV={}w}6}~uľh~slst؛S?gP.7n0\lMH?tJ_SLRIG̔mmiB8ԸpWLP%$!7&^P#]fdF4u')e 'Bx;Rǡ'996P%}Cr)YU d_,2PCI^kݑ풡҇#mj'jΟQ3bvn97| + 8Uټz bH"y~ªr ˩7 ~'Z]kȣH xodODHnTMoFDT;3|1O^o8 @5ȫE0 BP570=1IU> L*2ygēaH.@*^.*K% ֣-,Ә&)w1a(8C a9\%*ophPuH[h7v8x]H H㑤60|qu*60`b pE *1&aRqKUo׮9S'QƑ$ O)Uq{-agUR3BtĦo#*rL)E &B2'3~Q*,&AA%eSCzq+|կ8~tr`Z;7[yV7vD~V vfQFkd.~АY0{?QD.~N7 !|6pe*\B'TWǮ4yq %H7 "7\p=).T/HJG<2:gLz/z#c9endstream endobj 955 0 obj 1783 endobj 959 0 obj <> stream xTM6W̑ "hJآ u`h%ZV*}7R> o{oC )bF_"/aZF)5Fh}ATA9D$qQ0 ZŕMD JO!9(w@ʋs 3龉?0 /< ݤ빳4uߴCnQ`3fiK#h<:h+2L*HSNsZL9zn^VLFjs)6G;.TwvSqxLX_ኮ\zQG GCYr̳p3i&w _/N-s{tѠ>`KPR O^}nͰ6Pg4X![i}ls'yb WSo]xv9v4yq0~w;c'M xW? z*MG߯ϧV'(?PuPtU#9^$n܂\e~풏;di ,\:{P2K5~A"wߕ_mendstream endobj 960 0 obj 784 endobj 964 0 obj <> stream xUmo0ίO@$)Ѥj56MBB8S8ij}RRMH|=wg?e`LCHKłTyRliz3(b@0S68ga8p!Ͱ{±cz+pAh 0}۫) {qJ -9ψ΢1RH^K8b6+1gCBp5ֻP9CLp %[<娮ꆐW2R $jޤ:ɬfTߤGnf[wHkOn{V(8gS"iKu89>]-ქW4F##SjLVvv7M=g\\p,-ڦ7lV'?aendstream endobj 965 0 obj 693 endobj 969 0 obj <> stream xVn6}WS"g-7Qy).66(PlVkK^I$(/M- 5<93P|w9 a^({{>gdQ0Isp!! UY?Q0q%sͣ[QNYYi.={Agn>U6yg0ݔYVƢ`(9;?}ImbͦnJ\W2VmR>rJx1L?NlL$.iuS xg]탳f *dfqer㯓NR~yrE^!GfJ߾="ޫF(7RaǍK<.<Ub}inˋڏQQy{}J{<|3J(c.6M9>wb ڝ=3\%Qx 0 ӏU @ötYjDdSF*2fl$qH"eFb$ ٦6yY<( fs"iWaRv6Ikȋ/FXi>]v|ɶDmM C q}%Β{53ncG'AYЕue#t*8a8[>5T]ô,4ԋrDuhնLJOQ%< vͿc{yW9/6`1fr)j$ԂEB;Ec%Qn1jxxȝa؂ߌ (FbdgugtF9#MOWHR;H)Glb\AH t:,MrxtЦTZ (e=&Ybx yr((r9}`LUn.v_\X"86a}rn=)`ExlͶ^-ȭ)Sr-#+橎]fgaM0 MnSh=Y(Tt#?ڙ<ƤY`{ޢDVr1$~ka\ 8ͱS„6 ?'AL >&SNw!zTA|]:*endstream endobj 970 0 obj 1127 endobj 974 0 obj <> stream xXnF}W[(#Zs/o"i A(L:$eߙd90+\ΜgRFRgKE %/3%g dP!9- 85&G|AFj|r|x= YJSd,&oj^ Uzʴn{AfE>J2~$uYuEC~U{?hMUrMPR_T]MUAfuvd4G̓è42xGo(u9F e$gĮQ&ûv7P&(n Эz\%3>5#LFFLظuQ-qY%3k{2ZVɫ);ݦZrPp|bJe~brv|i yZxᾏ]s[cْ)Zi1^#1X})?`ۢ#L5${ȩZx3,aɔygraCso@3Ο_:3M yP^%0c#mA>sB@N r69y8w5#!P[{uiz.<`^#̓ ߢF+aEКxq}Qv3m&*T"~rM8ytBfIXEk?09_'жue]庾maP/)i.>xfuF輸$4f9)E}=+6^}*wVl_۲[ @G?\{)>~AK}:AH(cx!!\QI(/s |~~tˤ{+ډ#%ę ((6^%`? ,u!C,9TdPl_NO,:^]srҕWȓ=^yYz6Lx-X'N e,\~zqBFUi4ޤ%֔T+h (k EfN [) nhf mv0ܖBzNp;yiSΛ,q8F2Ks ?M;/v7Gw 'PIGnE> stream xXnF}W[I#\$-PV!%)G|wf/. ['\Μ93g(' \e;bd9<% fH N/F"'T*eAף$/gxn<%V _eK{^#K [0*j"Eh/I:.Sr=T$l7!89n;]UͲB_CZЂ& {}VҢ Wδ F>!Nr2ˤ\mn啳ڴ4 SuGU&n6E6I[/^VdPu`ubP1r( LP ʝ^~r++nCGB-tͶ-d='3Žs-FA -mȏH(*2"+v895cg`%6?Q 4SFBb]Kfυq}6PUm  B49F#M$P{[j4c9(,9xr~<)Mh7=qH\ I=Au+r™$LI@hUInTu,u([d9fdvӄIE`|hWjg۩DAA%~#@wxVaлF/NJ&;#95}`la) EYϝ]9 {H@!=U :=*ÿޝ n}<'IX;DX;vč3:m[%9wY?5dR@ǕPHFA#Q A} bX[i(\%`0m&!$&!Wn0VΟ[%Ъb|4JjKCIj;|q~8XAy~|9v"ɫ:4 ¿uC!+AXҬ CP!sX?-&zhȶrXW8_n#]c8$,/qi#O R7e-7D0˰YoZg endstream endobj 980 0 obj 1660 endobj 984 0 obj <> stream xWnF}WL_2./HR-1 "%H,E\E˚33/YgM ̀be_500V|` QB qx=F?QP7,M#7^`dD7j!FLHt~,(/0DkdHn,jO^V/$KxEv[Y1~k=$)SYPϧ30N":|u''otaP0{ r q?.vjN`黁T)鰬oXybLWy o6v +y1 *^uUC^{c8q\3Ä{>L$kΛeQ.`WWbAU,sy#)wjZ7ƨe53'1f4 *fG{W\MQk(^TL4t;ڢeX:'vjɿՙi^6C?q(<Μ#y\1_CS[Ҏ`?樢8_{{]7C*ظxpcW4K(憋(1Y Ϋ،{Ȅh"&b0P1d1Mkmj*D'Gd7r#y-sS_C|Sq+$8U"P/ؑn5/ Tސ@F"pb3l[0MK BЧ[rh7 K|΃o&, S[nff"1jABXuLg nqȠ0vW#KI #8䞄 (,.U?RF5V$f\OЎ1j ԵYidܳ>چL$V6=4;^ERLtQe> stream xTn0+ .c hZ !$0dhqwHQ  ߁T2mP:3`y _SG@#*!8$"v\yXƉƥ|}Ss&#sx$X'%b}^/ "H~Z°SumVV6r$nlDNhd"̳A>iLR!Bީ'>)MgFWvjF ];nw&LRJdb`XY}[60Dt)gB>708Lo7cuk:،M>mSa=,t2ع-EKƅ-DMwТ!Zy f-TzUTv{d J ^mҷ&ٶ݇Һ%=Ķ)OA{ÂY&; .> stream xUMo@+j |ɥJZ)T5TÚlkfgCzhyf= wnHsɀTLa/Y@-ɚ? 5y6Iи얡9Et6{n)wˌ w[ȭq^6fjpsFOAcfy,uL4|2L0k#yb* !E_:Nmg `d! >/"Ceπr#ɏʘ`A_Na,ɋp 0ؕqmtCS|'Y DO@mS)TG,og@|s˛᧏'Ŗf' to QrtZ C C\h'w{Fzd2ha ʒEkY.s\*ow8O}5dy]D-^Tg*HNjV:UQZ-)$K!, tQP"iqvņVm5{ʣi-MZFd¾LŶ'ïY-pb9]b(7$gm$hC Ӱ-!mTDڙ>6^ Msmm vueXڡvիMwmlmD d{{q_g\.WNendstream endobj 995 0 obj 707 endobj 999 0 obj <> stream xWmo6_}I fDRD2$-y-xd:R';R-7 sH@ }gۈI@֓&n+'&2 dpI$O)g 2NVh7[N<)n]2ALuDaU*kPgh31nn|%jQ88.y4UhSй I^mkclgmM1Un-r]֤.ɣ!!-):25yNiJE^,S;5eEݤEfp^oxx#.Y& jgp({NCg;3U5A:Q櫹G0owɛ>$/? ݛfkY>p>~K@~\P.*#CEZ 5b y/ܛ?? 2P}&iD$%ǝw賀L4VFQ>P2;o==4\J҂LúC( `uaĆkaјi>˟)*5vi9wAjxb+4Um+ŗw>ã\ @!vzMUJ>7l4L \fXm5yYS$hz&HA&}d05*2EEzhmpb|i!_-E%()[.5䠴HP± 4}HOs Ҏ BxF6İ;1x(5YMUTew 1=xxdM5u&%cԑܮuDGŊ qWk4cJr7٭#{8}is0 n62\b,mmŀ)lcvw\""TCΡC;m2*,!Έ?`4J$Ӑ[St2j-)WlbԟJp- v "v'.4cu*DHԕ X̲'4&>X=d_RڣNQ f@Ԫ,3ujn$gL8qʠ۹,`U࢈ɀ{bvz#PkʹQ_@F@%à+q:2t)U S[N̘Դ5bT>[7eG_P[Kw0 (:Aن54(ɕ`==O$;O`~9 (w|h 9=~0@`RA7*qXՐQf0燃) %/ See[rͭ-GЎUeq(2-Z0xGC-忬 endstream endobj 1000 0 obj 1422 endobj 1004 0 obj <> stream xXn6}Wr3EI.vE"ӎ\IYJd[@AGrI2𳼙dNR|0<$GyC~OpK|5/2•B\(2$36 V.͗2sG3e=i‡I2dˮ93QR:XYj^^U>,ݝ-mz]_&Sv˔JII-)ZRշܹcRy8-6ÖL|Ë~RL&.|-NA.v|\8{??GZ |]=p%36T {5Mm`ћ۪4\k0$t*BX- +eB3:8x,OriJ\+}♦ õ/·s9>;(i7|,ׂ剫 \NkYEg]#Mizl`Z $CݭӸI\LþzM3G*i(&3%d:ݕmns >ӌAU B!.gԠя?#飅 q`k,yDinQ `Ebʉ=[rʔ4 N9{-$h*dHȞr{s[m pWWnᔥ7|KV[~ (dxtp`)H*x˛WYd0z\TgPn,)5,LScw܏Zrh#ahֆqlZCTSr#8y:lL]Cs[]TWS.]g[\.{m!h,dyvuC,Ug)q3w#VD~Z Yf>8lBX$ 5O`Ϲn*.fJ}JܰTs7c AMd1M=3-!/#dtq7n+G:+_^n8cAa[8MX l:1 a (GkkNe,,!щUj%` |eܫߍaZ:©jX#aiy*`4ʦtڰGo*zYoe%l[.F^!JJ#)Kb@nxDrT$[ߧ%6K8 h]@>(w` hr xCĬ)O: 5V]O9U4@:,6(LAM`aa`u oOn &a8(p<`}20xAsG;L>50TgC8qǢ#mkq+6KJ&r*eTwv8eu^Sl`G6|{ 6trb &VJ>}MQl퀸L?"PM{--ͰGb bK1vE]څƝEEͼN4+H2(wEHxӽQGl>endstream endobj 1005 0 obj 1632 endobj 1009 0 obj <> stream xXnF}WRa_ξzv u8(Hly>U}#){Ɓ1vu]ϩ$gdR1c6GL4a,w3w Bq,|?Sc-$M ~TuOs:IVe4M,69L$oUUw}QoUiTӜ :ˇd{p,t,)ˤ5oo :TN_1D˭0]V\c9iUA3k򧺫u%E߷0J\(z~kSŘ<:WDu7ds^90kW۲+'s.rݯ^[AjQo,m۴Ӡ2 %)aw #yNT*mU,K;כjj\P}aBaXOs-@HF};bYɓsin]HU=ڜCի-3i$Kyo 0l ^G2>jQcB2Ssv7;rZSȓ_Vw!G&?~A2=:*$0A$3$u z,D iU'D"pW;Gp_<8 okָPT`6gδ% 6xK4l+f 'JI6JjsKsʏe 'Q#l7֯d$e.]D)hݤ ,R{l[LQ-`F05:e1 0:$ Yi5M+ bg2o nÒTٴq/v<*uGAfYsWZd> ݗSzΚq3s1dZPqM*%a2>j.HAЬͼW ˔E=p|T| v"9 J8SX1KqOcаp1vK "LE!AqE~wǕƚ=~o{׷D\/<4䌚8#ODendstream endobj 1010 0 obj 1896 endobj 1014 0 obj <> stream xXYs~ׯ) d=ڣ8HH EjyXny:լÐ~xT_Rw7\cv):YTi ,]-IIig}&K m וg.]Yyf""ݎ:hVrܷ F A}kAB<=uСJyJlPFgySSaLH}TJBq/"6w%1LZ_("[i8[d'ҷ%POʺ /Tr3pKĺBiK 񺔐(hYT_0=V.W5K#Z՝S B8+|SkR_TE-[͍Sg#QEOZ!J˖\NW Ơ?^pn P&ˆX%4.l,zhFiH} :&86o1 Cӏ`%mtUFpAD`$4 @wJ䠃G^+ bRRL,_ , c[\ hҡTN (}ީ.ۺo#e0ik:e\9h>}]A Zhi 8.tP}9$rGSKOݹ$!gg ɨ!_gDD#/[ K,I0 DMI.80EWG4 [wh?蜡PAI{I3ʥC"[p9*k>^B+}ĮŚKAث>8&|4pPNg@<"^껨c\CڝWUx0?r-@^E~̼k:Wm׊i6Myn = d0s0j}GsJ8B^NӍ{ &0ͧ~@Qg, k҆Ow;| 4 -8&o!ЗBRwe$_dRUDžV(`*j)fl#5yg8Lwa$aʂs@G'~=݇ۧ)D{W7Igw3{&W ~HhzF̀$d8,]Yyn\V[G2vL/3‰656ٹmHm 0G!ʯRyJ?==>͍LqNe\+Kr~"N@G 3CP.@?Nc H!c3\!m䳰<2AxW ^ʼq!=mR#C@Z^C 2 7{Õ4s.mr_\kl`8bDj?Uaǃ;|vJJ`t T4~zJ)]꺛 ~hD XtkaY/h2Fw0Och P`moR~-`o&蛡$оS S<Mt=w*G(sQil3 (~$)Ry:W+.z=&l^` 87ڜ`6E &a;].SH(߷՚7z^]%Fv\7%(*=#jŎ kW-\/ 1j5sL]ı?xG>gmɻJ?BKcp'U-M!7M{9K]02 TXu!A80C*._6 gмu ! PÑ/4ۚ8k΃ Rlv7$)7c ;"iէ(!/oW)JU3endstream endobj 1015 0 obj 2082 endobj 1019 0 obj <> stream xWɎ6+D"Ht̆`2 ȒGK"EVwg2TU+ (#_\}]1LoY aUL'ndDBa|N$QnS Ke~5k0uZ?zk\u%E )>cnc:췝ƮхjEIHeͯ*!{#^wT=I+Fe,hH Z\ʄ*"zU%$[&q 5h0U.zrdz];{ܷyY") Yh9U3t4&%|~ m &!p)/GM5\c&`/Fw&=7I 'rB14]0 C҇I]~誦OM},bTxbT5w||Go->Wa|x{tfQJ{|V%HH΃Crؿ$2Gb᢬#Nc'ͥM$olCX4P:1AҦp-k_Jj޻L!\wp3R1&TjAUCjϫʟPҙus" By4"D'0Fտ \+Ʊ yL{L2>@HX_~iN hFc3 )N1Τfv;:jv*L.VDZ-23:/T{D !s 8vFaLҘMS쉘Se#iץgqgz>1@| x"F=mֵZTqJלwƱI c/.|^lTr6k8(ka<`Τ #l6h̦BkmS4Z@ m#8V.L/x"HɩM' \AH)Aw? R\-^b5}ћNk47%"'.r`+R{ސ+|bx8y%l.Áq./`Mu L>0k#9'D>se2$J!"K׎Mb{Kct"Jp &2#r!7ЅƁͫ{\7А ]ƌq?fT8'%xnhA A9gAԢQ=(V }yR^}w?=X=fP!j?S/z4)'8!JZrB#+ */ ntgj0 SiyXk,H膵52o76v% 'dhObp>tGq)Dy6cڝa.ၩk f'n8endstream endobj 1020 0 obj 1442 endobj 1024 0 obj <> stream xU]oJ}`"pmԺU,c/fSc(AU{g^cBVHfgΙ3߀ffڟh~^ s0s bCQfd>J??6L%+Dm ,f TI]H'F\J^z5:ܱYs[M)cf\n-WKSZPAjejhU]dTj/;&\O(ާ=uFD -Q=D|Z6EtV6{ #02z d>ѿ}?Mendstream endobj 1025 0 obj 934 endobj 1029 0 obj <> stream xVmo6_qTNmdڊ/Eamla A([B,(:ںBD^G}iu]AXgBh># ,Xj!1tP\ e/,SzAO^X6`D[o\,BŒ*(x&l_I ཱུ ki%o˱R[Rٝ0)ʜ XCk-xrN#6iݎ{ 5qi5d TWhja<_D$b-+8{TR32۷hTB01l.|>vn^_Lr(kEx;{_gy%!mv=j Ov):IDz Ϝ%PF}͆DbB@U $<~+QHΌ"޴Y(?+M))o/J㪿DyȨ ~yQ̌r[bÛ`ǘ!%ꃑGu{cXŠ\11"U<6T#J+Vˌ:Yj֦A!τ2a_YZu:)ttzcA]e}Q\uտNa9К΁Q"1U⛿_7|endstream endobj 1030 0 obj 1002 endobj 1034 0 obj <> stream xX[۸~ (VԵoȢ<lѶ6e<"N-a,<| ҟ9>lB1#s6GL2&$[ngv`2ɹX<΂/yB,cO UD$b!b|WڈX+B;%Hj@%Wag<U lGeDDF8mm5J,yL<ɓ)d3H !t,xʡ8đQp!*0Ip2 [( I#VJQ6`!AOm'OH]dX:SL_JxRkJcu߲k 1q~LY:Y %FUOPpu_߈^$FBenlIX=)'e zv$Em 7V)M68hɄ';.eYՀ΅fw?u}x@]=ƴ g\FJ[k ;>U|xwoMyJmyH>s%/^I*n}a}'Y{Z 9HL.@uMѾ=D*C1ЅށT_d8~_ԙmƖm}'$z(Ls>k&OPng+l0X>.D@Xi+ ;ƻ$KI+7N»Oe$Lh#ʔ)wiL[k O5'ù42EPxcëX"m:if;`Fœ Ҩ Ю0Vp<؋mw XwXӥܳci{Iiөi{bPL1 +wvO"~DL tiP7yp8Y?v2BDa]QzRhY#!~Dtӯ>*7vǭ#I}> stream xXnH}W4! nMyڵIdA2lIH /= I)l`꺜:uZ2/6l'NzIGv O|2`UL'Dod|A應3wkI"p<8 S|5'PÅ\n\Qc)JIfx|[}vLX@'ӴudvrKb'7\uqH itՇi\}aՐ*"_/u*|ڀ UK6I喒dU٦Eِ7YT5yvo(Qw|y'!'5%K[Jnn(Qb!""&ӳoi"·?J#(-Mn%P55 i\%9fݪ}9Jr*{GNCs LLa i - #ā98gw \Q&p C9s~s ;4ffy:-!U'&[ŔUv7YGt?F=qgmHZzP:) ujςVWݧ߅@'ɺ:2i}HU=JU`_FO.CpdnEtЛ̊tO]}t]A^sAJg]߿RʼQ}v cz釲)̇34s6 NXDt!UAqb)|1GX b~i%cʆ P\x*>*7xWSqIZT * T;c yJNg?K&~diQs@=T qly&f PMDBNس)U<)eYLU**u?X:|} 0)XnCi~y4Ĥp%,3b[Gfpƈ2SߵˆJm?6~,p,} 󟌪 ŏOXʮ9مw]36Bs#zY y$yڦ5uCݩ: d ulsYЎ )tjxH 8,auWvܲ~E3CN}@Ϊñا X]YF/TF'7ޚt 6:aӕ ZU(B;wP .ivU %j xˎp$֍AA@ |ʢȺP\PG͘B83$EBsHy$*PJF*^Wy\k=913p0t867rLb2iq!z7Drյd]$uQvcHX}q (| ABwErC[z0,韰gB6L8AM6r .AȥIe/Skp4JPx}ʥqi~j_uU@W|ַS+X5}qlV)z{1+!#c0ךr :ɖu]WD}gk-mJob. ӫeP1A"h$'/j`D- j7O#KxcSEh1rz6K7ՇO_~]rn2=Q:iV6S*sI@ND{4.bHOίΐ>K`4* }A?{(T+Gr4w7s}Fb`"?4dt!]piezVJ#ue([uU=va3; D؛F 1d"V\@n"vE3j-/JGi tc~MCC rJ< }_FjGN4VFOcqM%-;{= "y?^7endstream endobj 1040 0 obj 2025 endobj 1044 0 obj <> stream xX]o6} e fER(ݤ@fxwH Ci[#d^"j/2Ӝd"%I4Oo GęgȧI۵ͮN/1f]UPGCxó%'nZ>/˫G_-~e?0fe"u K}H>NQio(7ڷEW릳\5{lL4,װjo-Յ#川LF0[I7.J qqٗ>+ Hh>IFe3.ʼn Mgm=Cjӓ;2.[Qy6AM|Dv"[e|QH2Hjxb]գ-qѢi1o9pLdr_C.%m lW۝qa1i>`sU;;\ 5|;F,D84gIQ1.78rzXm4DžCfR>n*۵FxD cܽBR!4#qlXpܓRkaP=xhArBZ.Vn91- j7=KYGL̕TKtS/z򳖥Uź sG./rAv-fyKvXvh_`q?3g~gErd~0p="5t]J,ޯ1lp` {0]o$V|J)6; Y9qPA pgj=E{G /# +m,~*IEUƏ,74+x췝}>F˜N[pKwn}FUWAv{/tܘoR@\" M`<[_UҠX =GBvh2C+?f #AEW8'ARP/΁$K,Y[XcHrq iؑRѩtەKUA x ²ǯi syeqmMK!O$G £y Us(.xw_FH̸9U}_}>)|}pIR]Q O~ϯ((,endstream endobj 1045 0 obj 1836 endobj 1049 0 obj <> stream xXYs6~ׯ@K(Il]R,4I"nSyy]eBx(WV)~䩗[v:ׁ3bh%>pECVOņw70zotz:T0`cA b^zpeA٭wdRk5Fds^da/obrcĽB#ࡌ!>]^; g FSeeQ7$ۦ(0"|?I'd/EF啅?NȃvY|,Ύ|KP/zN#*nm\ؘy! CXi\H7^*jҀ>c%F-u6)Z\V]$%t0Cݧp0L/)raAFF"yM\N9fE o_)Dг"@FO$_~/ˏ_?2`eTi- NWD:HkcdD& jlZQr]t1ydO2wØa805٦EėT](zT|:T1 ɒ JApIlP@VuڐB-r#-.RI]e՜c@ؘF6`w.]=xDBz![Gs@d IJ$qҠ%BOrmJ TX>T*keVEVBV(Xq{ O׾>K$rҕKkV),. " c L7̱ 钗yШjf@h2+䮅tٖ[tY(l=X$ʋae0m='J}oU@MOPyԲ8/jl42(28[0 to @{k:<xM7_` ;'5-ڴz!~/A}\LWEendstream endobj 1050 0 obj 1997 endobj 1054 0 obj <> stream x[FGyHjhڈ:h,cx/ l33fj0sn;93Pb3 nfT~$x,d.IJ\7cĆ'&#AJ041ӂ;Wu]!s53v3.!HZ< RI0kk>m[*JDSʛfgġNwe#4`VmPbQy Y1kEYfy\gD a_Y"U[x lfJi28ujUxidދ,?R%PNj )z6 ~lX.ȼG?"vwګxRGEߠ˵g Ni)VUeX|XjX[1ƞ!Kx˓Tmz (F|'J\:K#*H<%Z4U %OĪ8}ي JV2D.3jӏ ̍^P]+["CͶ>@UYHq9[VR^(IJ*`2h04mm3f+,γ.~U[Q__ [G|R7nwqhxŜ tNjwR乾6]E1[:1[5*ǖwqbb~6\np6#O;CjYz%G]|cAw<Ѿ3r}V |x">Zu3Eu-[hV.Vתu\•בeDnXFyWRO^U}{t}}oiyau*Pf({Q;оa%KT|;O\MdmOb%rR36RDu(=^t}{[ 9F'}?[v%2I^+x}SK'%zZ^A<謤lG N~43 d!eSS|z{h<},xk9yv(V2 :buG߬^ɩuՇMw,Z esĢ3V;Ս? { .&.(1=u/_ endstream endobj 1055 0 obj 1152 endobj 1059 0 obj <> stream xW[oH~BO`jM7JUcZ ):s1I̜w (#~w[Cۂ~;~dé0NV)!$[rYiJ<*Zw7 4R|/(j$)Aa]օzZw*˦^Guƾp/Cm @^Y)D73곈uGH,Yn{4`Qm3/I*+TKm%{gظ\xySw=ɷYK޾%v3eCqoWo?ow:yplZ ImŒFp.uyS}_C%0G:ud> #YU!TV2ە/P1ʭ]z1Axa*SK_8FWOK@7& IՁ oUMZj!fh, z 8 (~Rr~Sz \B}35!"L`BThuӓu3ڀ$hۗ>oOr9ٖ,HÓ uZ*CHgzv0Ә2Q *Cة2f|!`Ųp zWՍ%2V->wOBPN۲~lm?n UAje} @Ʈ@ˣ3FY|ۣ/8y4=L|J.6ڊovb? o|R*ߘS01\ߐyY]~ffғl~a$vSuir: P]p٩ ̳Fɠ s:&n{Ty&+sy~չ".aD,r@lј}ٴa ̀MuP>W0sU1s\)KF;l]vA|ZZ7@ 1'k}b802I\ByJXǡRtii>^:ۮa_ĘD ||5hgDY=dG EQ|%endstream endobj 1060 0 obj 1641 endobj 1064 0 obj <> stream xVn6}WTqyхlZ$@wݠmbӶZ[ʊRݯVX̜3g!j?afQ}1uVb&b$b-63!(""-3`D{naPh Ɖe@IKכlf2]6%^p(dvs %őg-:`QRq|~Zu L8q ̆nRi*}q^b[5*lXQEctp0Je_ hGLu+]eGv8+po3T)Ez}*YL)v8hUSTW/uUۻk2緄,vm҅h̙!%I$YZe BR5ƈQИ>qA< ѳ;b|_'uDuL4V&EP@NkOq ID*zuXO@ Tn Af_5ȱ$<Ј9g\Cp )TDQ # q֜0 85 e]]㔨WA[VU S cb%~e T^M u֥A7*bGvs}va1wLcEfBA7ܢ c][?EC sZ ,"gaZWDie#"3zivzJlf%.=()=*&S8V-}2}`ѫI D23q*/凧L=(>/&-6C:8~\6) 0F*ob+|Fendstream endobj 1065 0 obj 1249 endobj 1069 0 obj <> stream xUMo@+'0ZUE/ Xc*:`;߻,Ƒz8 7oo0 =ε܃iڃf [_  .4rhl7v5}hN]'Ϋ"4sbhz<2cVT$^َʱk5ipTy9u>Ez zDapWˈ-C\1Ѓ~-M M M[ِ, .{^ ޅ8J0]L@0_/' [)Y(y{^1<(yxj^X̣v(MB>ٶK9c c#8ceTfsN S"hmYf8ͱ,MX/gۻӠϲHoIMru7>%P:,7zU;b9R)b?qyٱ9\| /nn.㎬: i5E,\q?s\uV +n٭?-VW0ݯ8uұeA˞0Y-c^]AIP~_@UTLWb <̊ McuR/1{GShPUOhDf %U+\qdRu@U #ɹvWҾp2#EXD9fr,aSW#xͱ)M5Bw.\GEG xALߨ!˙'~n"endstream endobj 1070 0 obj 777 endobj 1074 0 obj <> stream xX[o6~["fy)j{kWXPmfK.q_CRdYaX_>sw>""b?ɓm Aɇ QcG&͖pJ!l=q)b2MAhu8 rzq,*"_^W },)ͧL_|CD%,[ӕ.]]!J/'ģ 1#rQ2f5K^e\в5|? |lƮ984LՉ(oui2Df[1Ub \"jܦ%z82&H`J=>)eYp=r~kNM5plѺmMOh6\1,h۹:߫yz@DZ:fayk[BiQnAqvtFqM# J?q4T(LD r%.ME!r;a"ɕ~2p@b4u\Pxp"G[ 7#m1zdH gFzw!E?\Bq}m( 2qڪ`@bOk <^|<6A;VGaD8NF5[2T7z30-H~{X?$s"; alq@<S&zֳ̆_lʼnh;Ȍ͓Mʒeq8')eh*} atT?#V֎4YG0:uG̦=qNRw?<<'Ot:6j+¹`L n#s%dDAz6O#35+<M7HP(#~y lAm]6>/S1w1֡7(66B[Gq,q>ՙ3MPtA\Ϫ 7wYilQ2geO y+: Ǡ'z@'NłA:Pn*@H&-?"F-7^/g_(bQendstream endobj 1075 0 obj 1836 endobj 1079 0 obj <> stream xVێ6}WL_JԽif4 Ptt iK,9%ECR%>l9sfO`lӽqu®1l GnBᇥ2E ˭AL\B70-:_~(hPǁ[n [u\@.Y]u ڌá˖ͷƉ(3̆I6 n4 86xVf >,: cxgiaEa+bārReZ&M^ Q!= @J5IEk ܬV~UVBxM+;-!NDAO+`ͱ/wmW[;4"vTAB~^4XIFB Q-CP}Pi%#G?"t*Ob?GC_zx> stream xW]o6} YDqdmP+ZV `2ms%W^R_v y0b^sΥ2_foY@v3fI/L40N]dNJH0O/`8U*Ft3XDxf ^Y. I3/GE@D?BH&F޾'C(ię͉ +ɦuAH%|vx1ųc,M'{8RYIiī&PIK6ޮv]T 5WG 2NecvX6dn^juNB}?ڸF#+F,u(5=L.dbq?c4)VOY< ˹EhRkc5ǔ\@zeϿ]ƌ`U< iCE#)ɱFL&p1a*@:&k{X]5Kij8S Н!MHqd-܏SslIA5SJ80(#([ԴT"RWT7XoG3ZO䄢Z^1ajPcЇj-Z*qF\;<ȧϫO0V0sz>@(P'ѕ^%Si-EI_.Ga+}9z*J قCnROPY[%\@;QkqNZRu\NJF~g`Қ&gFA5$05; ]؀]N(UQXD0I1]BɢhW1kA&@l@n`B/va`{Uk3sT&|F)Rma%{BG r[ O {}yqh% M+k pkMzD[p{AÂq46.<߱6!frwe0^gkn@Ɨf J sP CnC=n:ޱO뒜 d 5{ ńIcs AqQ9D>b[;u[-ew_ݼ}f--@zn"3qI1#v:Oo7C^Ȃq#O5n߾\}(I|t]C85v5,m'/%zV v3t6[bZT"_,ܬMa]qSpnܹ)؝*#0kmUdrp"eRƶDT'X9sYyBeɨs~z+endstream endobj 1085 0 obj 1570 endobj 1089 0 obj <> stream xWs6~C3L8tC` r ޕ@nuviwڰ`a|2l#Yϑ@U6hn4m,$ Z ڔ!vQj6\:жbS6oźF* v;w{.qh5 wxu_fn!{̌t4}0q`o`hҼOɠj ڮ2|(?Q]0N$~GR$+8r-5X? f^xݼS2r,7yMU3HK(J!NqSqn4 W-itv Qm%= dT Ѝ {S ˀaRe1*xa N0 gu1 7_/LV4Hq;{-$2l} h9c/\Wev10H,O2+D 1֢_JsHXwz6oԺĠ_oŵRь['OPPovE//<%0*ػ)Ewv袎:,; } nhxr!S~qd1KˈBׁ^3w%WRVx !s3\8Ix]|-$eA =2EVE&ϲuܕPºSOu ux0YbYnhِ:$H@Хf,Tl@-q̵BV}OLxT:Jb"+0Qb{ρȀ/CN@,GX!a4uNBX=>$&S,Ƞh&djI q,\A/cԋ^;FxLj[IY5[*~H\TY,{cwsâްM1 |GdWL^O!/c(U#cϞ=䠈bESsŗAniJ|/}H2lpLBݡ^^jZ~OXwClǎi14w^QFG\W:!ժxGDIz|`!.3? ^yY~:>zh|u @cI/S+ʋX``bGD"B8lsE੘!M5E*i1QL}ȾѵЇ ow ;bW[O gk~\Eowhiendstream endobj 1090 0 obj 1238 endobj 1094 0 obj <> stream xXR8}W gkŖGanŰl (a+g9 ے\ &@,u9}wD0Eľt>x{i= h:>!9z7p4NaU(Co yb.x>Fl8V`-eXJa׍A@c4Fr4`IᏇA̪P3v+*;? Kz+m6~EΊ(sʮx:sn1 F)ѽ} L(cuVCy*S5RQ'E(IH :XF4.X,IyS6{7e4&PYJYѬFvE:(觮 4 ݐ2fA۠L"7S7>JK(F' j)QZ4r!^SVsUi9_䅮,Dz7%bUN@ge;  `r95 Q6<$%=UMnMgyUChT57Ͱk[1gBޤrrƀ"P<7K9[,@Y%Cufi.!Ϻ eCjehA9 x`t%(>]n*aH"@#RUO~J8e=~sF8/e2UehҚBd va.y3[fW痫m7bP|y B+ݷݕ-A+L{d{|g.>%@ jLc&Ft{Yt 43]nЬG8 j?oIWWMhFPN'kUgg$fbI =He%-͆wB"TdSUk m Hْ:7 ZX:(?> %28=sN'TL|[0uSAGb(Fl'V9l߻Tohi4Au>5+QAƜ͒cf"SQP,'SCiCcY4 ƠqvZC@:&'vG9e"+VE3@mʣq#p+ m\R8R3u?m^5VGv~W_DMqڜ(1Qa{ IAqLpS7;&8X: '44EP]@#Nl9{1Lcw vNBU7.Qk ]f`gp Qmk9m˙^n6cٺqm*jP=uNtíAg(Ur{ qiN}֍N;ass3 #L׆*UqGZWѮ{*CAn;i1Hc3x?B s+cܧ;M8:Pfڪap7Y$X+\gɲ߯};7!o@_i'#6˸w{_Uendstream endobj 1095 0 obj 1572 endobj 1099 0 obj <> stream xr8}P5h$8\z7VYV" dlpo /hu[(a@QՀ~A.~.) q' G p}v|Vp.$|=/ C_GhڄH '.zA' N2Qgg"k66{ PmɺQE TY^;ҎH WXhfe:˫2 C=Ues;ūin E.U㲩FfZyQKe A("Pr}&#O9l2Ɲ$HykYd2rѲK@\#߆␈6 UuRdz #<ŅpopZkh,G5%0͓TR͓:/ ;瞔CA V3ExgP9">gf]+&V?9xړg@TD -DxtW.e:PX %J+R{3F6iC6сRdݥ}VogdOiOD?Dܦp~{xu|ȫ&J]L^CWM૸\TEm<]/Ջxi}&NNeK.SKf>S v<3/Q,RQ>) Q^ ^I*U+Nru`9ŕLu˛; m||&+uC͞P;AVo%|[6Nʨ=>x92{r: [8I>g…Cy\CaXUHs%).ܨD=پ:9HUPT)%nԟ#9˼ldt8k kpg;-H >w Mv(h]1[T[oi+39 IS.A\\[|YVMZ먭#7waF'I*/ӕrҐ֚׃5b(QiS:J|Ui#t Dm:S+-f҈B~A©FaNgۿ6[W>|KrR;)7 n_qendstream endobj 1100 0 obj 1306 endobj 1104 0 obj <> stream xo6W["bCDiC.X0%QgS$')QAaGwǻ@ j|?{H`(lg_g-BL2GU r3 p Y zA-D)iub0]z@LX!0Vv]qH"FUXm$ <={-va,s\|X !fWNyׇ-gvbE6 dAN9׺O  lPV)zED/JWn5T5>YA=jsnwŸ2O ˱u󼰥yL(UQPO++V|<Ǻe5&VziVsi2|Ĝ)+4=\5sJIJ#rs0ۤӤ$\F_yD\D&uwdS_OɔH*T/*]/Y KG%`[:R sB\2hÔcOY<^ߙbE$\ #cpa MsDMJJd'<6~].6H^[wX(iyJ;Ba}+I)I0>.Grx(pֻfaNqW抨4q`ASFӵL1S"u23gK͸wst DY>cͻUWsn2]=gʢzGAvySȃsЉׁ4"] uE͘qcN@xP/0$9䋵8C`$#/)UG Ƒ@~<"Rp҄2"Lz  DYŷz<@I]c"Xئ{+ ):g&alE;'"Ǫ+{5{%T l2B$zda,p@`Sbݮʳ֙VKdLhZ6npY\iǰa>lP-Fv4̼lTm/}fnݭ1m=> stream xWM6WV9)$9e@h[%:c}gH^Ez$̛AY6w_2WW?Vl*!niV!'B4II(iVQ,֛@ {j FbEOkg>Χ$̨׶- FMu_u#E6@sdQ<|oVvC6|23w9SƼ!"NdFH \ip>|R'Sֻ5LgQ >PR "Bgg/P3.Ԧ_CҶ@Cѽ"f"{3q SD.,X%[1ԭv}7 t*"U#C d\W)Shs敔wq߄LOZG=+ځl BtQe]&ZQ% e== jƨm^ع5 c$|Q4'ߦXA{uE G\]QgLT͛oQS<68Rȳ=ZkK$%ۢɄ框|0~ еk- C^M8I2 P=;YAy[2^fXy>aDP{%%/_qyJhCHťwvʎ@ o{xZ > *Nj q CzKhOq몠2'S344Eݢw%)%d1q*yBhw,_$u 6i6㋐2n`J7#HdbɡF 4<~^xC`T;pϭPIYF3&MMy' j$41NTe3ȡ9ګ4K8fP? -`2'0Sm)j<{i` ƚ\B1 ttA|ws-tur*aX<ʉkdgvG1U9 0#6n_ w~Jh.#:8t:šm-+mc q֝Q:֟vr%ZS6ufXiہ?}ᵸRmq8 8d0hͷc,u:7'#;&ҀU`B73I]k n/Nt0G 4x,gx'Vb²=n l:-QSўq8L T6~ܬ^/endstream endobj 1110 0 obj 1573 endobj 1114 0 obj <> stream xXn}Wۥ M6wi;A`E$^pp|}NBJN$Y쮮9c.^?/\vXCfu&Ǫym c"J؏ئ^8k|Oӈm#ƲAv=wm͊sYl87?-@Hh^8}T^`Jq*w~('$ ,=&)|SҶh5yqbi]-by (lyS%;u\wYMC7,Y6>t^@/NqBXP5Zy(3¢B<"BH=%}\G5G{YRB8y*1nlc?w$-񍯮^NE3FB+u*wn+lC/={s d%Z2v=;TdU4.9( a񘻩@>~q?*O*l@!!gVgy #+l@zk,#MG:O @FTb: Ԃtdv)n]@p[髂\Q)EC=YN#8<ٛЌUeRDz;aG~*y0|ш2"^؎ǥHi0[Oy( B%>۫cJo.NY sY`P^o.яA|uuhne-aim:VxCZK#eŧ6'SM\!GT/ofP˴蓴T81Pimu yM܁=XU^"HtщlL^E4-x$LP^K" y(> +Mvd"z#$|v M)13iٍy [oO|ktv]bH Hk>v ,G݄pT( |{ MWk.#%A*SMZ+&hpgtZ9C:yjN^rdɤ2Gua\>5L"*JU )f>2D ל= vb}K)[bTnuJLY콬ǚ F5J[yZAjwT!`J0MtW| mEC,'xhU4: +v2V'몣|fnwbrL4)eSeV&T4YIvcdM$Lߡ@k5Dg ؍7+^Nv6|oeKKc]P't6iIrR4X'?O7vCײnd4yęGc C0(OR~m~q;k~w-n2C> .=QJ _IDTmĞj(+f8SIkRˆ4/U#mt3raZ~]Zi.9)A ^%a\L΁lJ]r~g9Q |dgxX~ʚ1>0 w[KЏů/%8endstream endobj 1115 0 obj 2084 endobj 1119 0 obj <> stream xXَ|Wԛ)U;k`^OFJ=<Sjf\*fe%|%˒p-`0Xu-+ꡛ|,%"{85}jb F:~Zw."F3ɗ7 'yhhjwK'E"OjT'V(ATǶCԭԞ'3-k jĈqpH.P/e2 稧ś$OBvAK+IBa(a}pr1s׏w[@˅ѵ(8h|[;|#dvSBi" Ǘ/ n$O<5:d_l_5niTT(.5)}[aH5$(^VW-J&MGQ#xeAۍlp,qfae@)ǽn{<޸*kzeݒȲkЙpybTT 3& kevdK!_s Zk7K5CyZo?Gu>30a 4q&48 ƾ ׊'lGeMKbF// SAaLۑMncn,MB^Ă \ɣwΦ#?ܯ`wk&#ORō"Sb'WE<-I {+t6ǐ;0~xlLwc/4=!)ZuSgxEG\:82ׂB_FP9hL:j?DΠՒ1CX0̆ޖcK8mes#B. \З.|5F?0NyBw ?@{R~t\1m,pZ RK!4ׄ>qpqAt F\(Ҕph-2G_&-4͖q4W8ƀt1=&fqD//!}AJ8A# 05Px#"Le틔Ib,o!Gae1YJF$i,$55l.ا:~^n^8o[$DOһP#i/"N]Z]Mqn}ucz#43ϒ'_v"*f* OlWߟj5endstream endobj 1120 0 obj 1917 endobj 1124 0 obj <> stream xX]8}ϯi#})PQj5]&$4k; $S €s|^WD0ED+^[n":wZ;_jDbfG ehr1b!mZ/ fKeWݙp;ѫb`#DnO6 ZgEYe !Ckabb%S@`Sg}u(+f]D* }v^Pap 7& }4P:$cqt:B~>ǂe?ݟУ;8Y6mb{TY;-CSFK9J&/dŽЍ]|:%1WNA@5hirGwЪE &nojbC_OEt 67> D6+dRHb u.ռ$jy4|<縃&NT AZHT(jB0ݣ(E}mc|hE/Rq%8c9ݸKO8,pWQQ<, jהAJDM@jx{ԯnS ·S(Ťr&^(kA0w}تdB>u vN d)U/W:N! @ܒB+l$\ep]76L7^Q\m{8=Z*7e(R7S66rz87='\azNH6QdO*| "̶A ʰXr߫z{ªUx鐨%2rRNXMUJ,-6KF(TY@/2gu \-H7 l^yv$735GKՇ潬D_}rx `ƄgOx}0}Ǩ+oNt1jj旚۠tM L8D&.)Mgz9!>nhXA3, Fjj5( [[_mBiޫ+ 0#F* PnBϷƐt[7{r vl(/> stream xXmo8_oH7v'}%XQ`IR0$$8/iMUD2~gfO#d{>4m)nkG@P+V.$r-`j .Xi:enyEcEG zf1Lm]aƨCϯ4>sV l*Zuo: xD^{N_lFy(NrmC86׏1 Z@uygNpuDŽ;&Vr&8osVr.co1 xW6'Ne!0_+?(l 0!7#*nЬesVV_xaR.t^Pp&.h ӁW`&6MU%d,/U ' BW7M*/nޟ) e5T?ς3P^Ё3B~3]Mw @΄xm{܌-bv{ Yd||ޝ =䄴Lr2h]hrf=_L[nL[nzB[-Z䏍@9x/bMi}&̯M'JIpkSQ+ s"/M)4X&f(C(QFR\Q2?d.@j4&۰&p9sJb&v+%?EEMl6aVarK+|FǶ8&d/|+Qx%T"9:kuq)iHdнDLx{m8ܣp1vMrH]L0QTu ! (ޠ(FhVCf-e*r'LfE)ԏet6 .e'"d!T S ! dx zJmR]N=.P>lv(> Qivg@|t5扚[ۭr%,T=)j?2iR>P,:2L[U 6Qu.U鳋WG]É*Sj;Rt**fmPSC^a13m/%q YQ4]ɭbXЈ"eΟ%?nslP-cP D`$*/ h.stzeSYd/k\yz>LA.q9!$> stream xWK6W;>$JDo4@Pmb!K–=ሔ%uw CoF0szIѮ)VV{dg~%>pAp4!"j_\P竵H`@+VE DڞK ZQ)hBr+*ʤHǴ9>&=iΡK!3Tw˜HHC|w$?[+`> ߒffyEڲLNOL :i,ctdՐc_e]YW UBd>Q3gIZ'TXQu1-@T2#mW7iaȥ.κYª`! rV1BvZj酶魸r B٥TP%%:a cQ0@h[57 ~28T7dLg4XSf"Z6Al.T~8oQ0܎%iEl-6ޱt+xzФ!:jilT]M7Eh`ͩ(4v9ᒃ=KԘoۯ#'(8c4Nnz%5s LQS]t`5;b9 ,{u}S8Z'>Tp鯇Ͽ -2D@UA>ˌ[KN1ː#*z5b1dKw2vLukHcOl-lnIK1Ѐ6;G|8 4f|T0RŸeBO  8m%! 0h [k

> stream x] 0D{`dS7U͒(U B* Ivf3&:_aMp|f0*ÄR cR4ȶ`QDIY\m;Cendstream endobj 1140 0 obj 172 endobj 1144 0 obj <> stream x[sF%\]CNm2\ԝdZ2 y_]v9I'1.<Ƃ}<r1 1"ue!X[On WwBB=]Q`xc.w⿭f Ad!`Rޯ[!Mn"0jע{"i3eF3-Y$W%*y*m[~<) YjfA ȫ@zj˃|˟vme9*3ugh1Peف 5L| `RZ4S&q茓Nz Džwe.oyag;9 9ԏV=CG׬2N4&g'gqAt{h1 i18ɆѾQgB_uڿ 9cդF NOؼ\}V'[^?>ز鴉^S@oC}(}@ 0MI޷i>v#u"R/v[ϿSbendstream endobj 1145 0 obj 1223 endobj 1149 0 obj <> stream x˒8`u5V%5|lב;f:@ 9kFʾ-*f?Z׾rHDJ$4dbȕ]vՌ>T>yDwWԯ6v(zA;XuA*:׫Vi#MpvW.,=n".3WҠP:+uzy}>%x^>z W$G#'H$Z3㍠J:9j>v)!`=l Y炔76S=Cm'Drz 6f&TDyI (2oF!JL,A&6:d21<sh @PN5GYB;4Y<ə̬㟓vlȳ X?) C7~%ɳ~cAH#g޲Y9&Iˢц?=8vyoӹ/8 yC1SE1/t9̸Y/.u'(uU)0k\2΄~5W4 [6CR_yv+SJ}'& 䦰#S{iLNd3SqtΫGZü֝6ܽp| /FWuѧmS} & '[4ݛ+j洶Cq=L> stream xKF|>Ksڍ6mL3OnnƐ4`(~Tz7CۣdA}P}_#i@Dz5  aq GB"8!gOC bw.WkCjkԓ!`(*e&I8ͥc(h"lŇ~TU{&TE(nHvrT"?e[P Sg{!eTՍ1b]ρ5v- ئ\Wi#ifq{\÷FĤp@IJ .?$b"ZkBch70*g lشRNhFP'Jކ6q\+]6B&U!֧Z=ionc]c>| 91+"9erQA7Jڂ-Y4)9:e_UZJL՞c-˻aK6B5e>x{N{>I}K6FiNJ|<$p$.F`xm #_n}4Ro,1DO^GU[+␗l'lյDwj OJö(trQݠ0U6tu 2۠ cP}[ylMO\aj6[%3!WQ73J'\2Z?Gحv-Ճ;ƪ .J?j +h#s˿24e .=]e]b{HzK Df5mBPHUP6X$E.?bo]%<`Rz%We+̚NWjFvZbdO*hf"&F1W(] B<)Qmq^ 58jqNv7{Ҏw\?X;iK{= p9Y &&"Lsȃsbq7wXOMHj/ VpYYendstream endobj 1155 0 obj 1108 endobj 1159 0 obj <> stream xM6 `IM6IUj+l\NXvb3 xvߧ8 ۭͣ\L^=9X}dh_Z.[_,R[r@߯; Bdc\̘ev\좽8D`E`QYQzJX~rֿXZZ6Yc Ί)PLAwyqec!~ر0ǥ펹,iWq QuH`qCgy UZQ(:f6Y|~M"=\P0 ^.;*2b>0 ʫ8cF:]0J,{.NB4<`i Í0۴L(Ka$+XXߢSO"ډX05FPԬCqPB \USx!O*͏ ϲ-5{_3:] NV4}bp^2!졨#b+ #H(^;NrHn9oDI=PmvE~t +\K-KPQ}^ Y3Ws|\8׸z*[!3g"%@L̇soIrv9gNfx"-Ny9QP^[OңDYj ;wHqNIvB\!e&+(ZKo2YjyM#\9O,eY|Y.,@21>&MZ}|BR?XJ6n8vX!і7vNe>tTveXAʁ H/R=ʭeMP>\! {>_\.c>tѕqߥH4:B #T转4S}[!kܶ]Z +})@e- ,@m&<EIIZo`JY--ָZu8[%l1P֘,<WAkӱ=shP= S(xpI;nN{sApe[Dd嚬%OjE; :4AScaK5> stream x՘]6$mکZUUi/v*DM7l Ϳ1v@&sщ9~|Fzt|Ѻp|v~8t>a+G#GiBN||uC`vGP=M8M&8.|1+ܧo!G/qώ]D4;w)K',|92) sRQ]Cx ej[QzPY{ `ГSX橃!1$_m_}A`/"2??Ce+a p ӄCtRN ~_[ֶ&Q}̏TV?,)7}_sEWk5fFD<elvI3tȏ%J&[~S|5m,5-5n\m݂ݔ- 帻dEr'co VeEFd,䏣RٜfMF18ĸWá8Yn&hqim`6('7mഹ6Kûd0 Q|5#]Yɥh?%hRL RLQ0+K'm~/AFzM+Z6\! WT0 7hДmQƐPcYZ')c 3] @4[yD@^{u i"XpU+E%A݀y/{̠> j MeN@RPkFCV:,,}Hp;kt&Ke"7H`۬U_?[}u #`at8)n0E9X^)Ѭ7TuЃ1 6^nd\U* p "z ǚF]rJ 遰Q.PW$zPSV0N:+1&(s}):N6j ZJnvXS ?~T iLB}=s| q@VϋL8gRX47@c8v&NA(s7+g\ȀC.p:q4٫G54,]ubC +v07$=ڡL1W&۝[z1 bz+zQ`Ba гVp) Ҩ#v5ƈGjꉸ*-s/xBOEendstream endobj 1165 0 obj 1184 endobj 1169 0 obj <> stream xK6 UN$! 75<*[{IQcYL&>-#gHhn|L_=;߾hsr|q8<[GE!" EkZC 3&E{+08`Δz}_nr\/Y9Γ}@OYqzp qFd44QGpqaQm%$kQS l$^md RR%WS.ҌnI>]` iDTϥ<!}Ĥ>'Va>fo90= x;(^1QaBv t d\# rѨQsFj$&4*iFCzJhHLXT\, t˞EDl ^8 *0!†LpTQ%yŪ&Uî@Ygڨ4 DSH5Z ri|5V ZLw> H5PkUEE08B?cT`Ev {PSq+{E)"4}}I)'=^eKO }ĵ0~`vٜ[ r Ą 1s %DWcs޾I 6h*sRhYA(Y^_k(cgmfwH]\{X@n Zv 6ƩqNbZ+26[wZLYmƔV.E.fV67ZՄdFْ7grqFdS 1R IzEQVUC)o)˝(jbDj{U젯 ZqkfqztC-ЏT"$p`LIPX[|n\@E]T@jS\$]g8T/B?(E[cendstream endobj 1170 0 obj 1197 endobj 1174 0 obj <> stream x]6+iCm|tvUui/v*R2 d1@`H`2hp ;ȼvtv 9Տ;?oIVM v0>8+|,}%EUWUOyza>1ʜ/Ѷ88?"C^:wQyn~[)|aMReS/3m^ e&l la| pr TFEt Exxzpzp,U3&x8>1~c':b&te0M3P|(w5x % >{kL`@C>UuM8Dtン"ar$mǯ ԂFZ)B._ 5eo=͒2@ʎW{U~sz;>{*(;fMtv$rO8DmhBΝ~lqE@aF[tSx[|.V/k>CPMtq빗ϭYFP|M ~ve NhKt3ɽ:M(XPT}fևXWQ$'JrT3w3Bmh/ϨY@ ެWGR3 i2zk(lj]1` BWˏJorі90K.;aAfo.Fb5:8MM70T0u%;>/{W\2Z=p"ΉU"w}6΁BٚUegd=`l1T[Cxa:Ie rHmbMJK*!7l746f>D#|v;X FT|<鰊L7͞@fO̅IJhXՄ msz uQl޷ ˆ1`04"oycr= 7 :L'N 5[șX -*@ƭШ錾[w0^%+tV^jх'n!ZOg*' Xvt:-VTOwށZ!m>t/Lendstream endobj 1175 0 obj 1283 endobj 1179 0 obj <> stream xOo8| ]iR3ͬ'Ê4~m`!4ձ}_?~GyO>3vB뭣  2 W8V@Qfo>DIsKRfJEuSM/o7gP>f9\}Z9? B'v0QT(( [0؀]aq"`A5-ņ"q&u~1:534r B, b7Ƀ uC24MZS)Oiu39 G,'q֍_#8•ndM2֧E"gas_Y\7;^FMǒ`sRpu c[iEG%q0Cg")̸5rx{dmfU(]$Nt!Iht!ό<3xGȟ1VE3a #0|F ( q>t !}{l>ѭ\ȴpVgq懘DxqjhUPʥHIImjX8pFNkHBނgчa3Eci$Q##idYpFeRrG#l S[vZS3a.6{-ɕ|(Zt.- ]$hsS)&3I f6{>U I&ا^$:ۀe- iE>k =R3vi=d}.ho{4FRJn> stream x[sF{ 3+I;Oc+WuAb%߲+qr"]xx#a wdzѺ0Z[_-R "|BaBCDq P)?YہKK g偰.&q"%Z6iQFqǯ3â܇;KwvO "3ך&W[m*_eѣSijQx3x$eQĹj^8#KOf6QxQnxk61"/ {qv&Řy\X>V-접,ye."\ޕiC?^|B@z!`QL[ ,8KoUgǛ<2{@4DvbRehmW{Ur})ZŪ~Upm ]g(pۻٶj]8K7$M}y\۬ЂW5hx^5X AQ9&3{ Ȧb>1hz]ě9n)?pLrޱEmށ7I,l {>D.ϳ_n \ u0 :2tB4M;3oGA~ֲQTo$*>Eq:]^ʼP#@ t<8fu6 %\k#ƾ{Pb^i cQE f+L'vQMԡ> stream xMo@ pv?XnDuHإ2&]>bb685,w0;à Ra~Uw/R>,ju"`J) !1UaՉ h#̴5 2muuK7^Fv?/ ) U?zTVFyy*Y/04r/ "Rg!3 |$ȡܔ$&GM& ix ŒLdzX1czvX)P2kЁiжZ0zKQ.:mڧ|.T8bGU -t/B[9H)b'"b"Xwβx{vhl7*q)Q( H(9% <$\+znsKI{(yzUX MCgM/ԭ)e9u0@LTJBߏ]cW,:6TA|ZǁPU~*LMey݄YKGܾOcv҄q"Pc3gR:aéqo%)쑟ܶburIFeك۬EʲjK+?p7 _^hnTK{#0gWDx> stream xKs0;bp0t#әNrj:l!&I}%įƓqbcv R/>[8."sA0o|8` q1H""xǗ18׫K/uF1?!BqrϋcELj=|ﳕ;vPOx4NY^=몆2-fISTK' koѮ9YܗnR瓤iX5ׂ NBѬcXه/Yl% YJ8)@VfʚIZd$י(2J 4j5TUUfM)bRh bZyБS 6U$+aeFd y:U(°/r073m2]Cen:4aWj%R!,\yZG)9$lONL|.UJa|x+W6%|!u +L9 + *r*2[YrxN ޣTBHLPI =QB'2;m̓cz.c1Mv\Ob|Qendstream endobj 1195 0 obj 879 endobj 1199 0 obj <> stream x՗M6| U @Ǵtҙδ'MA`zWBKXy `D6m>`'ʶ煾 *kb ,#|_4B9#Anw@<HDP6t댆PB 2=aba~-B`6Sbf3g%dYoufMQv*+d >!k+rZ N &:}C2`th'_ޮrE{;pFk%طd5VX9R%|9`@L/mp-h|6̵AuS_ENVy2VO}f~L0Ed~@"kCrOk]PA) ۠V]rNĤ9Лf6m:S%8%Z׫5=0j+zswسwJԭ"N.K,Smˬxkёu8%hE&j$J9t>&̃Ѕ:ٱ\t;,NG&.xɲRWwJœ|7O4pqEQ:_UnS>8<%s՜0A<=1y#' vuAP5> stream xL;0)L " Hbaα`38"C[{gzhsNьbb[ 2בH"m ;UґRč0Xj(U9F~GRڈTi[rىP*NV"VR"Ht:O۶[:y~9endstream endobj 1205 0 obj 174 endobj 1209 0 obj <> stream xVmo6_o(,E`@,ѶVKJ%9YwGvdsϽQNEݬS#Fvя{%?"IӄdA6 Ɯp+J96ZՇEHL2+mc:Pm{%m^82oB(* *A¨\s%K!i?*ɪ)]Ԛ},>[ C j[֫@F s2GN*^2W=)mR認Iސʧ2&d<枓XvKǦ*{(:$ FxTgV/2.Є3nW5;rvuQH|G! n5(zd8 [bdo==0*--TAlo&eKPNuumAK-5LДRjځw_ۄ2!|WcV!0\ȋ?rE[C<,]۷h[Ԝ2\( BNӼwc 3qΙS%wuH"&$GPB ɮA ؟ھ6GڧBBtKI<*đna>ȼsyt vA.V8I>e(s?|}Tّfo=s;G.YJ}>, \rkjbvrErE'0U=;#T%T ,1k.=|P 䂳x O{Uj;ɧ9zk}U'CAj~Q̛㕤 W5TRG_sL%SI &!&T3㙊#Ԍg*BLEɌg*b31z3&31g*31f3&31Oq/mja4i0FrXp xWpuy׷>&d;g V2 _ wKߺa[%>sNgߗhᆦ-tzpaL{j'k}~ |qendstream endobj 1210 0 obj 1107 endobj 4 0 obj <> /Contents 5 0 R >> endobj 16 0 obj <> /Contents 17 0 R >> endobj 23 0 obj <> /Contents 24 0 R >> endobj 28 0 obj <> /Contents 29 0 R >> endobj 33 0 obj <> /Contents 34 0 R >> endobj 38 0 obj <> /Contents 39 0 R >> endobj 43 0 obj <> /Contents 44 0 R >> endobj 48 0 obj <> /Contents 49 0 R >> endobj 53 0 obj <> /Contents 54 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 63 0 obj <> /Contents 64 0 R >> endobj 68 0 obj <> /Contents 69 0 R >> endobj 73 0 obj <> /Contents 74 0 R >> endobj 78 0 obj <> /Contents 79 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 88 0 obj <> /Contents 89 0 R >> endobj 93 0 obj <> /Contents 94 0 R >> endobj 98 0 obj <> /Contents 99 0 R >> endobj 103 0 obj <> /Contents 104 0 R >> endobj 108 0 obj <> /Contents 109 0 R >> endobj 113 0 obj <> /Contents 114 0 R >> endobj 118 0 obj <> /Contents 119 0 R >> endobj 123 0 obj <> /Contents 124 0 R >> endobj 128 0 obj <> /Contents 129 0 R >> endobj 133 0 obj <> /Contents 134 0 R >> endobj 138 0 obj <> /Contents 139 0 R >> endobj 143 0 obj <> /Contents 144 0 R >> endobj 148 0 obj <> /Contents 149 0 R >> endobj 153 0 obj <> /Contents 154 0 R >> endobj 158 0 obj <> /Contents 159 0 R >> endobj 163 0 obj <> /Contents 164 0 R >> endobj 168 0 obj <> /Contents 169 0 R >> endobj 173 0 obj <> /Contents 174 0 R >> endobj 178 0 obj <> /Contents 179 0 R >> endobj 183 0 obj <> /Contents 184 0 R >> endobj 188 0 obj <> /Contents 189 0 R >> endobj 193 0 obj <> /Contents 194 0 R >> endobj 198 0 obj <> /Contents 199 0 R >> endobj 203 0 obj <> /Contents 204 0 R >> endobj 208 0 obj <> /Contents 209 0 R >> endobj 213 0 obj <> /Contents 214 0 R >> endobj 218 0 obj <> /Contents 219 0 R >> endobj 223 0 obj <> /Contents 224 0 R >> endobj 228 0 obj <> /Contents 229 0 R >> endobj 233 0 obj <> /Contents 234 0 R >> endobj 238 0 obj <> /Contents 239 0 R >> endobj 243 0 obj <> /Contents 244 0 R >> endobj 248 0 obj <> /Contents 249 0 R >> endobj 253 0 obj <> /Contents 254 0 R >> endobj 258 0 obj <> /Contents 259 0 R >> endobj 263 0 obj <> /Contents 264 0 R >> endobj 268 0 obj <> /Contents 269 0 R >> endobj 273 0 obj <> /Contents 274 0 R >> endobj 278 0 obj <> /Contents 279 0 R >> endobj 283 0 obj <> /Contents 284 0 R >> endobj 288 0 obj <> /Contents 289 0 R >> endobj 293 0 obj <> /Contents 294 0 R >> endobj 298 0 obj <> /Contents 299 0 R >> endobj 303 0 obj <> /Contents 304 0 R >> endobj 308 0 obj <> /Contents 309 0 R >> endobj 313 0 obj <> /Contents 314 0 R >> endobj 318 0 obj <> /Contents 319 0 R >> endobj 323 0 obj <> /Contents 324 0 R >> endobj 328 0 obj <> /Contents 329 0 R >> endobj 333 0 obj <> /Contents 334 0 R >> endobj 338 0 obj <> /Contents 339 0 R >> endobj 343 0 obj <> /Contents 344 0 R >> endobj 348 0 obj <> /Contents 349 0 R >> endobj 353 0 obj <> /Contents 354 0 R >> endobj 358 0 obj <> /Contents 359 0 R >> endobj 363 0 obj <> /Contents 364 0 R >> endobj 368 0 obj <> /Contents 369 0 R >> endobj 373 0 obj <> /Contents 374 0 R >> endobj 378 0 obj <> /Contents 379 0 R >> endobj 383 0 obj <> /Contents 384 0 R >> endobj 388 0 obj <> /Contents 389 0 R >> endobj 393 0 obj <> /Contents 394 0 R >> endobj 398 0 obj <> /Contents 399 0 R >> endobj 403 0 obj <> /Contents 404 0 R >> endobj 408 0 obj <> /Contents 409 0 R >> endobj 413 0 obj <> /Contents 414 0 R >> endobj 418 0 obj <> /Contents 419 0 R >> endobj 423 0 obj <> /Contents 424 0 R >> endobj 428 0 obj <> /Contents 429 0 R >> endobj 433 0 obj <> /Contents 434 0 R >> endobj 438 0 obj <> /Contents 439 0 R >> endobj 443 0 obj <> /Contents 444 0 R >> endobj 448 0 obj <> /Contents 449 0 R >> endobj 453 0 obj <> /Contents 454 0 R >> endobj 458 0 obj <> /Contents 459 0 R >> endobj 463 0 obj <> /Contents 464 0 R >> endobj 468 0 obj <> /Contents 469 0 R >> endobj 473 0 obj <> /Contents 474 0 R >> endobj 478 0 obj <> /Contents 479 0 R >> endobj 483 0 obj <> /Contents 484 0 R >> endobj 488 0 obj <> /Contents 489 0 R >> endobj 493 0 obj <> /Contents 494 0 R >> endobj 498 0 obj <> /Contents 499 0 R >> endobj 503 0 obj <> /Contents 504 0 R >> endobj 508 0 obj <> /Contents 509 0 R >> endobj 513 0 obj <> /Contents 514 0 R >> endobj 518 0 obj <> /Contents 519 0 R >> endobj 523 0 obj <> /Contents 524 0 R >> endobj 528 0 obj <> /Contents 529 0 R >> endobj 533 0 obj <> /Contents 534 0 R >> endobj 538 0 obj <> /Contents 539 0 R >> endobj 543 0 obj <> /Contents 544 0 R >> endobj 548 0 obj <> /Contents 549 0 R >> endobj 553 0 obj <> /Contents 554 0 R >> endobj 558 0 obj <> /Contents 559 0 R >> endobj 563 0 obj <> /Contents 564 0 R >> endobj 568 0 obj <> /Contents 569 0 R >> endobj 573 0 obj <> /Contents 574 0 R >> endobj 578 0 obj <> /Contents 579 0 R >> endobj 583 0 obj <> /Contents 584 0 R >> endobj 588 0 obj <> /Contents 589 0 R >> endobj 593 0 obj <> /Contents 594 0 R >> endobj 598 0 obj <> /Contents 599 0 R >> endobj 603 0 obj <> /Contents 604 0 R >> endobj 608 0 obj <> /Contents 609 0 R >> endobj 613 0 obj <> /Contents 614 0 R >> endobj 618 0 obj <> /Contents 619 0 R >> endobj 623 0 obj <> /Contents 624 0 R >> endobj 628 0 obj <> /Contents 629 0 R >> endobj 633 0 obj <> /Contents 634 0 R >> endobj 638 0 obj <> /Contents 639 0 R >> endobj 643 0 obj <> /Contents 644 0 R >> endobj 648 0 obj <> /Contents 649 0 R >> endobj 653 0 obj <> /Contents 654 0 R >> endobj 658 0 obj <> /Contents 659 0 R >> endobj 663 0 obj <> /Contents 664 0 R >> endobj 668 0 obj <> /Contents 669 0 R >> endobj 673 0 obj <> /Contents 674 0 R >> endobj 678 0 obj <> /Contents 679 0 R >> endobj 683 0 obj <> /Contents 684 0 R >> endobj 688 0 obj <> /Contents 689 0 R >> endobj 693 0 obj <> /Contents 694 0 R >> endobj 698 0 obj <> /Contents 699 0 R >> endobj 703 0 obj <> /Contents 704 0 R >> endobj 708 0 obj <> /Contents 709 0 R >> endobj 713 0 obj <> /Contents 714 0 R >> endobj 718 0 obj <> /Contents 719 0 R >> endobj 723 0 obj <> /Contents 724 0 R >> endobj 728 0 obj <> /Contents 729 0 R >> endobj 733 0 obj <> /Contents 734 0 R >> endobj 738 0 obj <> /Contents 739 0 R >> endobj 743 0 obj <> /Contents 744 0 R >> endobj 748 0 obj <> /Contents 749 0 R >> endobj 753 0 obj <> /Contents 754 0 R >> endobj 758 0 obj <> /Contents 759 0 R >> endobj 763 0 obj <> /Contents 764 0 R >> endobj 768 0 obj <> /Contents 769 0 R >> endobj 773 0 obj <> /Contents 774 0 R >> endobj 778 0 obj <> /Contents 779 0 R >> endobj 783 0 obj <> /Contents 784 0 R >> endobj 788 0 obj <> /Contents 789 0 R >> endobj 793 0 obj <> /Contents 794 0 R >> endobj 798 0 obj <> /Contents 799 0 R >> endobj 803 0 obj <> /Contents 804 0 R >> endobj 808 0 obj <> /Contents 809 0 R >> endobj 813 0 obj <> /Contents 814 0 R >> endobj 818 0 obj <> /Contents 819 0 R >> endobj 823 0 obj <> /Contents 824 0 R >> endobj 828 0 obj <> /Contents 829 0 R >> endobj 833 0 obj <> /Contents 834 0 R >> endobj 838 0 obj <> /Contents 839 0 R >> endobj 843 0 obj <> /Contents 844 0 R >> endobj 848 0 obj <> /Contents 849 0 R >> endobj 853 0 obj <> /Contents 854 0 R >> endobj 858 0 obj <> /Contents 859 0 R >> endobj 863 0 obj <> /Contents 864 0 R >> endobj 868 0 obj <> /Contents 869 0 R >> endobj 873 0 obj <> /Contents 874 0 R >> endobj 878 0 obj <> /Contents 879 0 R >> endobj 883 0 obj <> /Contents 884 0 R >> endobj 888 0 obj <> /Contents 889 0 R >> endobj 893 0 obj <> /Contents 894 0 R >> endobj 898 0 obj <> /Contents 899 0 R >> endobj 903 0 obj <> /Contents 904 0 R >> endobj 908 0 obj <> /Contents 909 0 R >> endobj 913 0 obj <> /Contents 914 0 R >> endobj 918 0 obj <> /Contents 919 0 R >> endobj 923 0 obj <> /Contents 924 0 R >> endobj 928 0 obj <> /Contents 929 0 R >> endobj 933 0 obj <> /Contents 934 0 R >> endobj 938 0 obj <> /Contents 939 0 R >> endobj 943 0 obj <> /Contents 944 0 R >> endobj 948 0 obj <> /Contents 949 0 R >> endobj 953 0 obj <> /Contents 954 0 R >> endobj 958 0 obj <> /Contents 959 0 R >> endobj 963 0 obj <> /Contents 964 0 R >> endobj 968 0 obj <> /Contents 969 0 R >> endobj 973 0 obj <> /Contents 974 0 R >> endobj 978 0 obj <> /Contents 979 0 R >> endobj 983 0 obj <> /Contents 984 0 R >> endobj 988 0 obj <> /Contents 989 0 R >> endobj 993 0 obj <> /Contents 994 0 R >> endobj 998 0 obj <> /Contents 999 0 R >> endobj 1003 0 obj <> /Contents 1004 0 R >> endobj 1008 0 obj <> /Contents 1009 0 R >> endobj 1013 0 obj <> /Contents 1014 0 R >> endobj 1018 0 obj <> /Contents 1019 0 R >> endobj 1023 0 obj <> /Contents 1024 0 R >> endobj 1028 0 obj <> /Contents 1029 0 R >> endobj 1033 0 obj <> /Contents 1034 0 R >> endobj 1038 0 obj <> /Contents 1039 0 R >> endobj 1043 0 obj <> /Contents 1044 0 R >> endobj 1048 0 obj <> /Contents 1049 0 R >> endobj 1053 0 obj <> /Contents 1054 0 R >> endobj 1058 0 obj <> /Contents 1059 0 R >> endobj 1063 0 obj <> /Contents 1064 0 R >> endobj 1068 0 obj <> /Contents 1069 0 R >> endobj 1073 0 obj <> /Contents 1074 0 R >> endobj 1078 0 obj <> /Contents 1079 0 R >> endobj 1083 0 obj <> /Contents 1084 0 R >> endobj 1088 0 obj <> /Contents 1089 0 R >> endobj 1093 0 obj <> /Contents 1094 0 R >> endobj 1098 0 obj <> /Contents 1099 0 R >> endobj 1103 0 obj <> /Contents 1104 0 R >> endobj 1108 0 obj <> /Contents 1109 0 R >> endobj 1113 0 obj <> /Contents 1114 0 R >> endobj 1118 0 obj <> /Contents 1119 0 R >> endobj 1123 0 obj <> /Contents 1124 0 R >> endobj 1128 0 obj <> /Contents 1129 0 R >> endobj 1133 0 obj <> /Contents 1134 0 R >> endobj 1138 0 obj <> /Contents 1139 0 R >> endobj 1143 0 obj <> /Contents 1144 0 R >> endobj 1148 0 obj <> /Contents 1149 0 R >> endobj 1153 0 obj <> /Contents 1154 0 R >> endobj 1158 0 obj <> /Contents 1159 0 R >> endobj 1163 0 obj <> /Contents 1164 0 R >> endobj 1168 0 obj <> /Contents 1169 0 R >> endobj 1173 0 obj <> /Contents 1174 0 R >> endobj 1178 0 obj <> /Contents 1179 0 R >> endobj 1183 0 obj <> /Contents 1184 0 R >> endobj 1188 0 obj <> /Contents 1189 0 R >> endobj 1193 0 obj <> /Contents 1194 0 R >> endobj 1198 0 obj <> /Contents 1199 0 R >> endobj 1203 0 obj <> /Contents 1204 0 R >> endobj 1208 0 obj <> /Contents 1209 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 16 0 R 23 0 R 28 0 R 33 0 R 38 0 R 43 0 R 48 0 R 53 0 R 58 0 R 63 0 R 68 0 R 73 0 R 78 0 R 83 0 R 88 0 R 93 0 R 98 0 R 103 0 R 108 0 R 113 0 R 118 0 R 123 0 R 128 0 R 133 0 R 138 0 R 143 0 R 148 0 R 153 0 R 158 0 R 163 0 R 168 0 R 173 0 R 178 0 R 183 0 R 188 0 R 193 0 R 198 0 R 203 0 R 208 0 R 213 0 R 218 0 R 223 0 R 228 0 R 233 0 R 238 0 R 243 0 R 248 0 R 253 0 R 258 0 R 263 0 R 268 0 R 273 0 R 278 0 R 283 0 R 288 0 R 293 0 R 298 0 R 303 0 R 308 0 R 313 0 R 318 0 R 323 0 R 328 0 R 333 0 R 338 0 R 343 0 R 348 0 R 353 0 R 358 0 R 363 0 R 368 0 R 373 0 R 378 0 R 383 0 R 388 0 R 393 0 R 398 0 R 403 0 R 408 0 R 413 0 R 418 0 R 423 0 R 428 0 R 433 0 R 438 0 R 443 0 R 448 0 R 453 0 R 458 0 R 463 0 R 468 0 R 473 0 R 478 0 R 483 0 R 488 0 R 493 0 R 498 0 R 503 0 R 508 0 R 513 0 R 518 0 R 523 0 R 528 0 R 533 0 R 538 0 R 543 0 R 548 0 R 553 0 R 558 0 R 563 0 R 568 0 R 573 0 R 578 0 R 583 0 R 588 0 R 593 0 R 598 0 R 603 0 R 608 0 R 613 0 R 618 0 R 623 0 R 628 0 R 633 0 R 638 0 R 643 0 R 648 0 R 653 0 R 658 0 R 663 0 R 668 0 R 673 0 R 678 0 R 683 0 R 688 0 R 693 0 R 698 0 R 703 0 R 708 0 R 713 0 R 718 0 R 723 0 R 728 0 R 733 0 R 738 0 R 743 0 R 748 0 R 753 0 R 758 0 R 763 0 R 768 0 R 773 0 R 778 0 R 783 0 R 788 0 R 793 0 R 798 0 R 803 0 R 808 0 R 813 0 R 818 0 R 823 0 R 828 0 R 833 0 R 838 0 R 843 0 R 848 0 R 853 0 R 858 0 R 863 0 R 868 0 R 873 0 R 878 0 R 883 0 R 888 0 R 893 0 R 898 0 R 903 0 R 908 0 R 913 0 R 918 0 R 923 0 R 928 0 R 933 0 R 938 0 R 943 0 R 948 0 R 953 0 R 958 0 R 963 0 R 968 0 R 973 0 R 978 0 R 983 0 R 988 0 R 993 0 R 998 0 R 1003 0 R 1008 0 R 1013 0 R 1018 0 R 1023 0 R 1028 0 R 1033 0 R 1038 0 R 1043 0 R 1048 0 R 1053 0 R 1058 0 R 1063 0 R 1068 0 R 1073 0 R 1078 0 R 1083 0 R 1088 0 R 1093 0 R 1098 0 R 1103 0 R 1108 0 R 1113 0 R 1118 0 R 1123 0 R 1128 0 R 1133 0 R 1138 0 R 1143 0 R 1148 0 R 1153 0 R 1158 0 R 1163 0 R 1168 0 R 1173 0 R 1178 0 R 1183 0 R 1188 0 R 1193 0 R 1198 0 R 1203 0 R 1208 0 R ] /Count 240 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 14 0 obj <> endobj 15 0 obj <> endobj 21 0 obj <> endobj 22 0 obj <> endobj 26 0 obj <> endobj 27 0 obj <> endobj 31 0 obj <> endobj 32 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <> endobj 41 0 obj <> endobj 42 0 obj <> endobj 46 0 obj <> endobj 47 0 obj <> endobj 51 0 obj <> endobj 52 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 61 0 obj <> endobj 62 0 obj <> endobj 66 0 obj <> endobj 67 0 obj <> endobj 71 0 obj <> endobj 72 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <> endobj 81 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 87 0 obj <> endobj 91 0 obj <> endobj 92 0 obj <> endobj 96 0 obj <> endobj 97 0 obj <> endobj 101 0 obj <> endobj 102 0 obj <> endobj 106 0 obj <> endobj 107 0 obj <> endobj 111 0 obj <> endobj 112 0 obj <> endobj 116 0 obj <> endobj 117 0 obj <> endobj 121 0 obj <> endobj 122 0 obj <> endobj 126 0 obj <> endobj 127 0 obj <> endobj 131 0 obj <> endobj 132 0 obj <> endobj 136 0 obj <> endobj 137 0 obj <> endobj 141 0 obj <> endobj 142 0 obj <> endobj 146 0 obj <> endobj 147 0 obj <> endobj 151 0 obj <> endobj 152 0 obj <> endobj 156 0 obj <> endobj 157 0 obj <> endobj 161 0 obj <> endobj 162 0 obj <> endobj 166 0 obj <> endobj 167 0 obj <> endobj 171 0 obj <> endobj 172 0 obj <> endobj 176 0 obj <> endobj 177 0 obj <> endobj 181 0 obj <> endobj 182 0 obj <> endobj 186 0 obj <> endobj 187 0 obj <> endobj 191 0 obj <> endobj 192 0 obj <> endobj 196 0 obj <> endobj 197 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 211 0 obj <> endobj 212 0 obj <> endobj 216 0 obj <> endobj 217 0 obj <> endobj 221 0 obj <> endobj 222 0 obj <> endobj 226 0 obj <> endobj 227 0 obj <> endobj 231 0 obj <> endobj 232 0 obj <> endobj 236 0 obj <> endobj 237 0 obj <> endobj 241 0 obj <> endobj 242 0 obj <> endobj 246 0 obj <> endobj 247 0 obj <> endobj 251 0 obj <> endobj 252 0 obj <> endobj 256 0 obj <> endobj 257 0 obj <> endobj 261 0 obj <> endobj 262 0 obj <> endobj 266 0 obj <> endobj 267 0 obj <> endobj 271 0 obj <> endobj 272 0 obj <> endobj 276 0 obj <> endobj 277 0 obj <> endobj 281 0 obj <> endobj 282 0 obj <> endobj 286 0 obj <> endobj 287 0 obj <> endobj 291 0 obj <> endobj 292 0 obj <> endobj 296 0 obj <> endobj 297 0 obj <> endobj 301 0 obj <> endobj 302 0 obj <> endobj 306 0 obj <> endobj 307 0 obj <> endobj 311 0 obj <> endobj 312 0 obj <> endobj 316 0 obj <> endobj 317 0 obj <> endobj 321 0 obj <> endobj 322 0 obj <> endobj 326 0 obj <> endobj 327 0 obj <> endobj 331 0 obj <> endobj 332 0 obj <> endobj 336 0 obj <> endobj 337 0 obj <> endobj 341 0 obj <> endobj 342 0 obj <> endobj 346 0 obj <> endobj 347 0 obj <> endobj 351 0 obj <> endobj 352 0 obj <> endobj 356 0 obj <> endobj 357 0 obj <> endobj 361 0 obj <> endobj 362 0 obj <> endobj 366 0 obj <> endobj 367 0 obj <> endobj 371 0 obj <> endobj 372 0 obj <> endobj 376 0 obj <> endobj 377 0 obj <> endobj 381 0 obj <> endobj 382 0 obj <> endobj 386 0 obj <> endobj 387 0 obj <> endobj 391 0 obj <> endobj 392 0 obj <> endobj 396 0 obj <> endobj 397 0 obj <> endobj 401 0 obj <> endobj 402 0 obj <> endobj 406 0 obj <> endobj 407 0 obj <> endobj 411 0 obj <> endobj 412 0 obj <> endobj 416 0 obj <> endobj 417 0 obj <> endobj 421 0 obj <> endobj 422 0 obj <> endobj 426 0 obj <> endobj 427 0 obj <> endobj 431 0 obj <> endobj 432 0 obj <> endobj 436 0 obj <> endobj 437 0 obj <> endobj 441 0 obj <> endobj 442 0 obj <> endobj 446 0 obj <> endobj 447 0 obj <> endobj 451 0 obj <> endobj 452 0 obj <> endobj 456 0 obj <> endobj 457 0 obj <> endobj 461 0 obj <> endobj 462 0 obj <> endobj 466 0 obj <> endobj 467 0 obj <> endobj 471 0 obj <> endobj 472 0 obj <> endobj 476 0 obj <> endobj 477 0 obj <> endobj 481 0 obj <> endobj 482 0 obj <> endobj 486 0 obj <> endobj 487 0 obj <> endobj 491 0 obj <> endobj 492 0 obj <> endobj 496 0 obj <> endobj 497 0 obj <> endobj 501 0 obj <> endobj 502 0 obj <> endobj 506 0 obj <> endobj 507 0 obj <> endobj 511 0 obj <> endobj 512 0 obj <> endobj 516 0 obj <> endobj 517 0 obj <> endobj 521 0 obj <> endobj 522 0 obj <> endobj 526 0 obj <> endobj 527 0 obj <> endobj 531 0 obj <> endobj 532 0 obj <> endobj 536 0 obj <> endobj 537 0 obj <> endobj 541 0 obj <> endobj 542 0 obj <> endobj 546 0 obj <> endobj 547 0 obj <> endobj 551 0 obj <> endobj 552 0 obj <> endobj 556 0 obj <> endobj 557 0 obj <> endobj 561 0 obj <> endobj 562 0 obj <> endobj 566 0 obj <> endobj 567 0 obj <> endobj 571 0 obj <> endobj 572 0 obj <> endobj 576 0 obj <> endobj 577 0 obj <> endobj 581 0 obj <> endobj 582 0 obj <> endobj 586 0 obj <> endobj 587 0 obj <> endobj 591 0 obj <> endobj 592 0 obj <> endobj 596 0 obj <> endobj 597 0 obj <> endobj 601 0 obj <> endobj 602 0 obj <> endobj 606 0 obj <> endobj 607 0 obj <> endobj 611 0 obj <> endobj 612 0 obj <> endobj 616 0 obj <> endobj 617 0 obj <> endobj 621 0 obj <> endobj 622 0 obj <> endobj 626 0 obj <> endobj 627 0 obj <> endobj 631 0 obj <> endobj 632 0 obj <> endobj 636 0 obj <> endobj 637 0 obj <> endobj 641 0 obj <> endobj 642 0 obj <> endobj 646 0 obj <> endobj 647 0 obj <> endobj 651 0 obj <> endobj 652 0 obj <> endobj 656 0 obj <> endobj 657 0 obj <> endobj 661 0 obj <> endobj 662 0 obj <> endobj 666 0 obj <> endobj 667 0 obj <> endobj 671 0 obj <> endobj 672 0 obj <> endobj 676 0 obj <> endobj 677 0 obj <> endobj 681 0 obj <> endobj 682 0 obj <> endobj 686 0 obj <> endobj 687 0 obj <> endobj 691 0 obj <> endobj 692 0 obj <> endobj 696 0 obj <> endobj 697 0 obj <> endobj 701 0 obj <> endobj 702 0 obj <> endobj 706 0 obj <> endobj 707 0 obj <> endobj 711 0 obj <> endobj 712 0 obj <> endobj 716 0 obj <> endobj 717 0 obj <> endobj 721 0 obj <> endobj 722 0 obj <> endobj 726 0 obj <> endobj 727 0 obj <> endobj 731 0 obj <> endobj 732 0 obj <> endobj 736 0 obj <> endobj 737 0 obj <> endobj 741 0 obj <> endobj 742 0 obj <> endobj 746 0 obj <> endobj 747 0 obj <> endobj 751 0 obj <> endobj 752 0 obj <> endobj 756 0 obj <> endobj 757 0 obj <> endobj 761 0 obj <> endobj 762 0 obj <> endobj 766 0 obj <> endobj 767 0 obj <> endobj 771 0 obj <> endobj 772 0 obj <> endobj 776 0 obj <> endobj 777 0 obj <> endobj 781 0 obj <> endobj 782 0 obj <> endobj 786 0 obj <> endobj 787 0 obj <> endobj 791 0 obj <> endobj 792 0 obj <> endobj 796 0 obj <> endobj 797 0 obj <> endobj 801 0 obj <> endobj 802 0 obj <> endobj 806 0 obj <> endobj 807 0 obj <> endobj 811 0 obj <> endobj 812 0 obj <> endobj 816 0 obj <> endobj 817 0 obj <> endobj 821 0 obj <> endobj 822 0 obj <> endobj 826 0 obj <> endobj 827 0 obj <> endobj 831 0 obj <> endobj 832 0 obj <> endobj 836 0 obj <> endobj 837 0 obj <> endobj 841 0 obj <> endobj 842 0 obj <> endobj 846 0 obj <> endobj 847 0 obj <> endobj 851 0 obj <> endobj 852 0 obj <> endobj 856 0 obj <> endobj 857 0 obj <> endobj 861 0 obj <> endobj 862 0 obj <> endobj 866 0 obj <> endobj 867 0 obj <> endobj 871 0 obj <> endobj 872 0 obj <> endobj 876 0 obj <> endobj 877 0 obj <> endobj 881 0 obj <> endobj 882 0 obj <> endobj 886 0 obj <> endobj 887 0 obj <> endobj 891 0 obj <> endobj 892 0 obj <> endobj 896 0 obj <> endobj 897 0 obj <> endobj 901 0 obj <> endobj 902 0 obj <> endobj 906 0 obj <> endobj 907 0 obj <> endobj 911 0 obj <> endobj 912 0 obj <> endobj 916 0 obj <> endobj 917 0 obj <> endobj 921 0 obj <> endobj 922 0 obj <> endobj 926 0 obj <> endobj 927 0 obj <> endobj 931 0 obj <> endobj 932 0 obj <> endobj 936 0 obj <> endobj 937 0 obj <> endobj 941 0 obj <> endobj 942 0 obj <> endobj 946 0 obj <> endobj 947 0 obj <> endobj 951 0 obj <> endobj 952 0 obj <> endobj 956 0 obj <> endobj 957 0 obj <> endobj 961 0 obj <> endobj 962 0 obj <> endobj 966 0 obj <> endobj 967 0 obj <> endobj 971 0 obj <> endobj 972 0 obj <> endobj 976 0 obj <> endobj 977 0 obj <> endobj 981 0 obj <> endobj 982 0 obj <> endobj 986 0 obj <> endobj 987 0 obj <> endobj 991 0 obj <> endobj 992 0 obj <> endobj 996 0 obj <> endobj 997 0 obj <> endobj 1001 0 obj <> endobj 1002 0 obj <> endobj 1006 0 obj <> endobj 1007 0 obj <> endobj 1011 0 obj <> endobj 1012 0 obj <> endobj 1016 0 obj <> endobj 1017 0 obj <> endobj 1021 0 obj <> endobj 1022 0 obj <> endobj 1026 0 obj <> endobj 1027 0 obj <> endobj 1031 0 obj <> endobj 1032 0 obj <> endobj 1036 0 obj <> endobj 1037 0 obj <> endobj 1041 0 obj <> endobj 1042 0 obj <> endobj 1046 0 obj <> endobj 1047 0 obj <> endobj 1051 0 obj <> endobj 1052 0 obj <> endobj 1056 0 obj <> endobj 1057 0 obj <> endobj 1061 0 obj <> endobj 1062 0 obj <> endobj 1066 0 obj <> endobj 1067 0 obj <> endobj 1071 0 obj <> endobj 1072 0 obj <> endobj 1076 0 obj <> endobj 1077 0 obj <> endobj 1081 0 obj <> endobj 1082 0 obj <> endobj 1086 0 obj <> endobj 1087 0 obj <> endobj 1091 0 obj <> endobj 1092 0 obj <> endobj 1096 0 obj <> endobj 1097 0 obj <> endobj 1101 0 obj <> endobj 1102 0 obj <> endobj 1106 0 obj <> endobj 1107 0 obj <> endobj 1111 0 obj <> endobj 1112 0 obj <> endobj 1116 0 obj <> endobj 1117 0 obj <> endobj 1121 0 obj <> endobj 1122 0 obj <> endobj 1126 0 obj <> endobj 1127 0 obj <> endobj 1131 0 obj <> endobj 1132 0 obj <> endobj 1136 0 obj <> endobj 1137 0 obj <> endobj 1141 0 obj <> endobj 1142 0 obj <> endobj 1146 0 obj <> endobj 1147 0 obj <> endobj 1151 0 obj <> endobj 1152 0 obj <> endobj 1156 0 obj <> endobj 1157 0 obj <> endobj 1161 0 obj <> endobj 1162 0 obj <> endobj 1166 0 obj <> endobj 1167 0 obj <> endobj 1171 0 obj <> endobj 1172 0 obj <> endobj 1176 0 obj <> endobj 1177 0 obj <> endobj 1181 0 obj <> endobj 1182 0 obj <> endobj 1186 0 obj <> endobj 1187 0 obj <> endobj 1191 0 obj <> endobj 1192 0 obj <> endobj 1196 0 obj <> endobj 1197 0 obj <> endobj 1201 0 obj <> endobj 1202 0 obj <> endobj 1206 0 obj <> endobj 1207 0 obj <> endobj 1211 0 obj <> endobj 1212 0 obj <> endobj 8 0 obj <> endobj 1217 0 obj <> endobj 19 0 obj <> endobj 1218 0 obj <> endobj 12 0 obj <> endobj 10 0 obj <> endobj 9 0 obj <> endobj 1213 0 obj <>stream xyiXSW!{o nM&j:[Z#ΨLʤ *2S!@0 ZVkֶkEuV^w쬽^~~gC8"8X1QAYg;u6w2bHcc 0 :TL5ё͚ޖ9{<ߛ;wƘiK-^:`괿F'DO{H Nu0)a{y$E=A1%nS-[%oO !>zhGBC=<ý"DN[,]!`-bw>Z5kϖs퟿ p"A&VnGLXE"G bL,"bXJ ćNb9XA#H DL&8E.1p IMP !"FocXMb 1xXG'&8`'fӨQwCE,i0?MOO6h7tCvz9gh 0 C#{BÊ]EV ~6?`1h=s-8 xI^-԰2Fql6(gOCܲI0Jӊ@; [*-->YM)vE_6-_Ң;IT GJvl>oq[*P&c )RMhhގ J%jԨCB~ GA[[z S׳ˤD"AKh1ڳdzfO޹FHAZk:84է4H 5MJ)7OZx`y:>|nr-G0nh!`_;BK#HMvth2<Ӭү(:be6 [\~ }X3E5SNZH臾b~v)ĺ;=ɇ%Fh?YAv;@ +N?Cϒ)`O\gs_s=ɋ"!l hH<FduTw'bΤw_+@[/C`Ĉ3 TY hWhJYl͆PzچZ m'4NF^|}( 3hf#|#_9|!fa/$)R@:~J"rצ EPB%ajQ+x:54ᬋgw #1vPR5.9>x^Lv*EQ ,#k4\L9۫TGoo}@#Jcؓ*Ҩ}=jR R`R妡lxɵh[qG{p A'ށ.LԴXDdѨd]x**Ւ?7@H8rxo<){.<{:;8^$pK&ז+v|~_G?<iGoU'(AXICTkia',荃?X C L@;.9/`s.f?fj !.&X}"LM۔EKcQ4=6g HȒғR "4|ϯ4o^Ïz@ &HA`DΗ44|S[SWUS -ES*uያR"f4C#wΠTqf~a->"vn@gCޓWn 31$f]Ef^II'H30Fޫ[wMtcpmm4 ͖98ؤ:Îmg2B,3ˣ¢%JI^kg9rygZrsR\Zz]׵Dl/^xɵMM6r]¢KÃ1JW~lQku H6GB~= X HGfgXιn~s$ |qH+𥑂1226)RGE zWFǚQ.Ͻ:ao/o=Un>],S/\ikWnxPdyf;%>U(g'+gWs8 .Il JRA,X).Pf6i+RZ&Qmjc!+GkyTd}~íOBm!( s~[k*}3/ bC)L@nAI7ˎs+q˯v yuR@'DЛg2Iln5іR]]Q^ՙD]>0u͕'wQhI)0sص/r_OřBe)=έ։BQdE,6#С1Jۥ8 ARbڄaPhن:03 Æ\VΈ6&Waݧn֜ @*D28字.ɠ=ۭ%r6dO?r`$JF>4kA`EKTPd@H(R)*H#nRm-kPD޴{4H2J-YV*Z[d+*=o}h @m:+\;옫OÔ/pL,6_.Qyz#twAzh|_Q8~ww:to?S_W#+4XPY;R؟6'8,z+ƐaԵleWT8gD?g/g3ؒ,&[-z5 i.z 26T/$-z]޷]Hi|XU4TSjN["l5 ;ﲼN#.;.b7$xz말zu"Up(/)?LR  /I 9( Vшyru4 l?> WvI7l@igYfv\IdB Φ`q^1 ۼan̑kGpRt/#)C̤Η)f {<+Fo;+ Id~7$eiJ=L`: inװؗf\PAZD7ǚZ{h{xh g᡹V+TJIJ*| C;o粲<&;p)䧙Et}M 3֊^PѽoQJ VVWEOLvlTfHsyp@4D_LT7k2q]վ}aƺ4]<Q!z 1ǭePStDhb{\ yo^xC4/Sq^"OtC?Om841M9;=^e!M>?/t9w | zq =k`4Ŵt: fZHѶ[ _<g_0n8a|p\fn^:>~NUe% @*ˈzX,G%)]ڒM;}11ѕI Ѹ=+kO*gQOXPdy'NdijRR!qVI$vj)>r$?9J£C#S7X >s&@ m7,y&(WI:bfx&igOF3|3kW4bP8O?qQqH)8 lx(lۑL΄`]sVվ [XLѨd2\RU&IEjWTIRDW:Q{s-vghG9Є Y#`y`QT"]MjeR*ȩ(>7Mꖥ۵_kA9\$() #6nJihwN1Ә-W5 NO(b)H[i47 С2Kgr.h]Ae+=(;ziJ_4Lfg(GԾe9^?C{J*&eZS 3iTE-`ITuUOmVw47^}joԓZt%\9nu G4, &0ϹJ c,O be[5(lg=R[, /3HL*SUD\> Q P^\lf}&Nfw $gZ'mp^<Oѧu4l!d-mt_e(V(JRz M5Re},vPZ7]oRq\t A qw8=ԋau{@A?Ԇ0^nmAQZO .aclNg)A,HĪb-|m BcJ[]UxC+Lo]ղ? XuYȁceq|VLδv̇{[H-`WëxV* 1-84RԤ{HՔsq6[ZV mxp8\MfJ)5~[ qY~6Qip_>4 ߘ 1NTm]ÔVu(FԺJdku^nDm}l}o3#J>ep5t껮৏t0"L!qw6?|˗fSSq +8= 7nn=wGnkE8 ̤ʹHZa >O]/ۯuk#J K 7Se57lRktiʆDp3z 6g\rwg V_M=wI1Ubo`ʒC{n?|RsBtfgc+Ŗ6\n873 |%!¨vfk }vHCDQxhK؏=x#,l$Lcf$9[*GpKm 5  dos6S7w~O7IS5I@IA*V7wG:rfMݽnuJ2JQT">?᳻uO~S}U荊Y~Nw0k.1x"ָ!)`i`;?2?ES:8:@.A|qr#NQwm`prf.$ffܴ] `]'a 6鿲1i&A ݡ suBhł3}qk-ny~DMĄ(\[*㫣D#Wx0^b~:n\E.nu+Yy{B}tGa'ЛSg2C'= `Z+zO|,c=WonwhKf-a722Ca%@Wĩe ќI(ToI t(:ou8G3 W.$4fɻ$-9+<#44/p)Y`Y?c.\טűeh5})vܹGjf6Y~=>xd !4rix "~'Q$ol<8/ ;bo YOS˅S@&*>>"&)6J?)O{u눟TtMv;|{ \Ov$& +&^'t 59?OsdQ'q{דݗT7j/?5¸N-Aih4q{:JDgϵ<[]ۅ)$#~K(pc~$\ӎ3&@äa+8L SqHgDMGcӦ{ΜmZKfYږzA gvK1J M w 5"'=3tyb%!+eV~ /B< .B W0ayxa5;dCE&2U yo_I&A'( endstream endobj 20 0 obj <> endobj 1214 0 obj <>stream xYTT־̽׈%ԹD@Ԙh"),(i^r(C5*:D GPDh%yY;%o_ X̝ϕPfD"a#[o5?E!F bߦH%c)AҢ~䘷סk,$w=+{/0idͱ[7~i7vkcsY-xcXOЈa#=*yDG-[~24pO{Pay+7lqm~rATtG1kyĭ\xÒ, ڴ<;'7Ӧ37=so~0v8s&Ljr88Rhj15C-fQR}Mj5Q˩75&R j5ZI9SS(?ʅz\)ʍrSoSjN}DC-fPԻ'djjQpJBPf2lHFQ XPvk@ʒM j.5z%,(%,34悅Na>a.^f|ymk}^n|1(xP`2fHah+yfdӰnͽn]n,{/ed{#rG0ۣƏPᨨV\mx7~#?`]dAz0qz,ΧTqZJUDBJ:.9J#zg0IBzGп^iݻ7z m.7VU n6..%.6tθd;+Ρf=.vGti$F/kJƇC&}Bvmb'9pHiU"%͉)}8@1#lI' #xl&[J ċp4E0V[xtE&#|_ lm)-@=got=^&5y|3ס 4wyP*TV&GFux4sKx8F4^+B`mRo۠(VQT=yõSג-J˻+l$9t|bJJBYiW2co76-L] ;*([qLG8I((KIFɱ^54ma8Agv;r3ܠω~I 5CV]d4zW."S` ,o {u|U< #YN"` 7$XGϹv]u`ye`UDMFvzb-~9b{b jؙE; !ƤY݊}|[MRL@l?EoU̗ܬ- ,HFD[Cˎ-^pfbL?yv2gNTġbvv۞@lkn f ҃&L,MJh4oB?) XHY#KVYU >H3q8"=J5XACV~Li+R[{u0v|I145Jfu2m^N~#EMj [{0+&x*/KuS発ϓbbH7ĺ6vt o3B s_08!P;3i✛O~qJO FDVṭIA)5 y4Q0d=rEL!=ƶ)xɛ?_zFVZ\ƠbU=B+g=6aᱤ"s}< kAY.a ¶،6w3GD1K#dսL2kѦ 2|J]IE81)t+B\~LQ]&UӤ*4g=$"怑`8%A* a sG ݼSzw{<`dL> >Y;%L尘5oܑh5K$J6p?^%љt2׮}Ͽ 6ZYnp-@z zުچK>EP. 4E8%Ȥq|eV}k}{aNQM79Y=~)L;uX˲ '"{F7isoE -H=麸kl)zR+(Zi oXaXfɚՁpXRv 9Dvgˎ B-t ҋĒ5Ꚛ|`rWUUM]a(us_8y"F]X$ҤR$rFv,K#`wWm,h=hvgɖm*vBDZ;;zi9RSK/;hR]ܥ6.8e^cL9G?ʺz5+xV^@KXD9 =uX+J0g#({-S\Ǟ&8OI[u !<^0;f鯇4 3 'ZSHFL 1*W0yc^S/ 璚@'~u[; ޙ~nuq=df,Lg~o?Tdr6&BtWig/^11IO*zf1 Fr}[NNE톻>r*(?[{B>;b 7~Pp}n)ϵaqAm"Vv?LJgEcXw`& g>O.1Q7&f?}zw+0_ݟ;R9Դ1>Uإ UE6LY]KI bY:c|EFUĄJ^Tibo h{o|{7ܧ?SIX\v *FZtlÑk7]Gը"DS.@ly~C[6@x?'/X}pWߢ*l:f^>1w\_7@~k W dggg 9| P(X `t 5x"rrj"mHWeqJ%W:6ႷFܶ/ظ> b-c-.q5GnǥM6)d?^d;w^XwfABm(cyZ_-qqGsgnv;pa~.k4~(i3ċ O .' 8GŚBU~ Kl,h QggghZ5 &+=kzm}19|T~U^$V:?ycF;e֚ ղ++9ޱ-{28<:>_jAxX܆ʐjYԴnWYrB᚜t 84ңCǖYH&K lW\C@gٶC%IO[J#^"NMJV%&Ue`4FuJ K~98IYds~jma!*%&gfek*H Ø^4 &J_`/~6Q(zdg* M^xag&5+!K&(8c7B079VM&Jdy9 R$//Օi4Ž`oLdbp]8`[0?`4DK" & 5E,\j||!7 N[beer&!Myjb(B2IBERg fb6TO)`LS?p|cMMUQ j iX]y |uTȦu(mj ?{cW Tu25ŖG,Qe= endstream endobj 13 0 obj <> endobj 1215 0 obj <>stream xXyTS׺?1u 7ho֩Z}JQqB8! yΜ@Ȩ*NP:ZmkzWvYڷ^Vgo F" ƫ17JO ]KOeЯD3Q⯂a`1Ѿ׸k!L ;Q=v3{ysJS -^i %~fښԜi3ܼaهr/b ~5knn,*>$Q#}g̮=K͚=w[b+NI v3b1M!jb>G!k:b=H,!2b M,'D0W18b<1L&R(c8*v]f:VeZSWWrc̛cc6jprOO3m#<"6HKlN4'4~AO3^%{0;B' JE/[Xx0GfY|,UmҒhba΁'QExڠMӬp5h$IW@4NVSAÄ0N=`ҙWis4Z2]1Xv+%| T@kҚt$'m.1l kO޾U߹N@V%rm::Ʊd)ɕSG_LNĞ#8'v\OY{ ɹj͚+@ 뺮Rr@>_S& GJk;$3h7 _->bHDDnD +g*N=uԖ; tQzRg>pA"A8}jo_֍]C"`ʎYܗqޣ4%:h4: Rd?Itde@?I+-ٞWGMp2{[+з x3Ʉ&qk+ @DzI _}t{p$ #OheMp]MkШC~+~]Bm2JX״U}1t};Ԛо} .EΏ/槈+WrgaY}yyo *OzSwk, \'xai-yRLSue@…2SIL|3૓Õӏ.7'Jإ[, K 0`y_2/ٵ6 ezj:6Bb[|n~: 릶\0ݪPz۽hnK,ukM8p*S)1ʵY>!,2п|e4@gRR&0#R/ Dpxpagpђ0/<~L,M]7ٕ7@%J oN[Tj@ Tҕ/FߐErvHQYk Wqe4[~FVk0f-P0 Ǭ(hT5_J( i<@,H_uV0ۨgXg p4j J h9c]{j^ a!;&/{KMivYB4Juˎr\aqA-\K+={#8Y!,7JeXl5z@} <څf)!9y[b3eUV`5[ m/ew(ٍv@Ej@ R]~E و($gsVwp?ctXf ^o)s V^3^\:jJŒwGc\fcL\փfh2ǬuyOAr1P*+8AܮJ/ Z׵e,* ogFtO/c$ߞ-v,gk%# S&S 8{p3 sN ZW•l5V^`PUwⱜ|=pV8sF5'9ry sی Ƭ$9 9SSӗ;?y8my:zY G Ep *BSh5&׆azv~8wmX'Z#[]S0RgŪrtHܓ 7~0m*%9]VJ R':v}t23Dlh{/v<(䧉K**߹Q?񲓻UtnenP#j<2@2h$RQnJa\V$Te2ZUZ)%7{Ά{! 'dsBIPReS 1/Ő~./e4M)JIf MASFsτ?ٖ̍$yyjjd]Z3*J#3jTIރmhf.|=xU++ xx?[9m" >LUފ ;"9*k乓]ʢbLrʪhT)|;Cp_T<ء =.܂CD'B&7fR-R*cheqGҐb%d>UWSM9f2Z9ko>mJk,!J\~'@]nJR1Ѽ7Ъi ]?_uWl CPׅ,?^ _W@a]d205CI> -z~YM;pdžM8*~G|,GK"XMpqˀt=St@&=$TAvb>J㕵K+O"8Igѳ,YԎꌲdW d% sk[>|q}߉ ^PEV5TX,d>O[Kcq~EKXLTf~Iڞ޻ݨw58?YTngMTy(&d , ~&ɧqHC|dqy|穦k+1)jMct$vsZJ@7dKuE!Nv UuS!GH(QFTI_\'&}=h-οGʎ֦ud"@f Gk7i\:%@n p6x[\Zhe0wS'Gap _q g ?NY9{S,T6PR륿32a>dq3jR,.UV;]eVW-ap`yS$2$pM.TVIjs@1-nh~/(pY5EM uu†POJPFNzYNi.<E*ȀZ"9EoD*&ʮ|"JRU䪘l-nA%`;> endobj 1216 0 obj <>stream xxwTTG*eXfX0j4jW^ P: ef(-(%&'hMrRLr{r[޵?+yQCP"h~`jކ ow"~~x/ߺÆRVlNc PhE=g܍a1J_) xg̔?L٤PLIR+B"=#US{L})ں>dC葍aG7oVnQm=*C+kww^} >E_2eiW8>6g˼wP4ʉzrVPө=JjIfQ)5:HCS#FjuDK6S-j+ZHmQ;N}jM-e%R5O({JJ Dj5ZER#5(-j5FF |"eȄ!Ya⦡fMV?2<{6|=~ÿ1gqlG5gQ G=+ǣ=Gwqg7NgA8v<1.ioS7^elt4@+D&l 3L $npn(*>ʁsy ǒJp0NTJ 5!nYU"Q6/+]X%^r?m|vr?\#{d;{{J[ 43㛫5VL )0G55ډ*q:Sh2fu>j?i ,`xGq0!t~'7mlW*dVij&F)=|ʝ%/__8yd[lE=]V.IiL(>3_(,xf!$`} S`ט냸U2n=/m!uIDlu.pnLA!(Zx=Mf.;+O_QJؚEocϔLKV;{7xbq< f S "+% JxIû8츪~2-s/~;F K*QV<؁,F瑒r\@M# ZrXRj-Al ǣÜԶiVNYEdFAN}"]OoYmlLi{A~fe[K_ZDߓal ܽHi^g}2jM%g]rJVlZE/tw9sB/3D-0ac3mJm q9;bJ;΀ux`޾ҳaJ`y,,2;VXnJ1}%05s9,a: R :Ķ5u7?z\. Mx$%W1x #3i4M,uIe♟Z}Hxc07 \;)Qvf-4_,d߉%|H&MEi(9;./w/򓻼?^Yp.美P_PaVqƉ '|uVD ĨYu!܍eR7[E`ؚNI=<){;9mGUgrS,$c:3F?S/It:v[&~; &| w$Uރ^;a}ӫN2!ZrLKќk=p$9M`6d6Ɩ.P]qk/LBNx ^+\^>,Uw$N5fSALb! 2Yc{3t99sN(u0]T̒O3щ!Ԙ>7Yt$ pc]8U)ㅫLg9v+9|h!I[]8lk%Ifu8F!$o5RRg덧e,a {TYnWM>רϣNhl ]‚T ozߪ$"6sqyjdh̓*ӛC1HQkQM 5ш S0GC|CC i1YV| P92uuUEǗGk (%himg\&a`))ܹd';K nӚ H җy)P2psUfh܎~Cb+S#|ĬdV~#!TH \R`1 _]l'o}#@&Q>G\DO8x儡ZV]kj? fS+7D^R~M @x{"va릛}|y^2C" ggnl]'͚c0W~f=7|,"#^.M| W+S(s&hHkaVM,@ zl򙬽ڄ:=aTG stJprL\*}BC?˦naR4:mv^K!sOL@Ćys͉/EgYT13S;` !˧=bB|]jɻAm׍BI3> ҒbQ=cvQ( k)K/].玶k ctX~&CXw@MFWJn*(W3*ieBsMh=pjō"~&<Ǹ#oRu*)9<:3MHN:x90nq9rCu,[ؖ! `  Z,x!͜>urp> Z~ӝF6n-(..\_>o\0;afb6/ @*KIC݉zc;:GPpDŽ*''\ Cΐu xmϡbcߴO۩8Hcaug 4 ͜h!׮?m|jkI !r=̟ks@WWKsWPJ2&.R41^W3)ai1&DzT=OZK{wyA閣nkZ+daͱ! D 5c[S*{pGϺ=҂z7ζ=wVsZg 1\1vk䭃Eҝ&RA ]URZ6;Pk r e%=nQ*}z>XAVT؆κswwi <=Agt&v9AWnIK2oLOh !D'+22s3sP:JJILcX{~#vR1M DA:mfxAF5'T*P%ħ 'f&$_?ZWy7&?a<[Qzu0 ݮ$|=hG %ӟffC_3hvяznG'5>C/Y诗oP;BLvf]ZLI83(ii;寤?0 ̄Xw,1Iݝa@RT[nhCr=﹒ZbEW7(++ />} o͜B-wrlwò~]h'r S8oΦevVT3㟛P DJ4V *')pBf!yƪ rm*^ZEQk4&$_%})< !m&#c 'd@K+'B%n+,SAuj=?¶<^UDIQ`zٴ䊣7} |8\qeN"w1hAXaM8SS]_l)(Ey\>1Q1"E$˩Miu,#_<PȒKeԼ(.kwׅL֋`.q)ϯ%HXX?l<=<Dgye 2w#_.1F ׬;QޞKC-{to3mUZ߈d,u?ȍ*FsCO^tz|v=P抯%OFX?3)M5(͢;u 整>X),go !+IJ\"b2Ȍy?ޠXDdb`̿;^~o〽scq:xX&v9ؕ2kDCarǺCK~7hw6&}EWwbE"v]Ǯ${ kuAڅW !#QП1U-~Ҷ4mJDfIP 9dwnGCX?)lp;q>rNY#0[1 ̭ri7%=Jny +IQ,3^ endstream endobj 1219 0 obj <>stream 2020-01-06T15:11:13-08:00 2020-01-06T15:11:13-08:00 groff version 1.22.3 Untitled endstream endobj 2 0 obj <>endobj xref 0 1220 0000000000 65535 f 0000447814 00000 n 0000499795 00000 n 0000445816 00000 n 0000405878 00000 n 0000000015 00000 n 0000002390 00000 n 0000447881 00000 n 0000467606 00000 n 0000469756 00000 n 0000469275 00000 n 0000491307 00000 n 0000468849 00000 n 0000485945 00000 n 0000447922 00000 n 0000447952 00000 n 0000406038 00000 n 0000002410 00000 n 0000005212 00000 n 0000468249 00000 n 0000478861 00000 n 0000448004 00000 n 0000448034 00000 n 0000406200 00000 n 0000005233 00000 n 0000008487 00000 n 0000448097 00000 n 0000448127 00000 n 0000406362 00000 n 0000008508 00000 n 0000011845 00000 n 0000448168 00000 n 0000448198 00000 n 0000406524 00000 n 0000011866 00000 n 0000014944 00000 n 0000448228 00000 n 0000448258 00000 n 0000406686 00000 n 0000014965 00000 n 0000017818 00000 n 0000448288 00000 n 0000448318 00000 n 0000406848 00000 n 0000017839 00000 n 0000019858 00000 n 0000448359 00000 n 0000448389 00000 n 0000407010 00000 n 0000019879 00000 n 0000022016 00000 n 0000448452 00000 n 0000448482 00000 n 0000407172 00000 n 0000022037 00000 n 0000024282 00000 n 0000448545 00000 n 0000448575 00000 n 0000407334 00000 n 0000024303 00000 n 0000025994 00000 n 0000448638 00000 n 0000448668 00000 n 0000407496 00000 n 0000026015 00000 n 0000028529 00000 n 0000448731 00000 n 0000448761 00000 n 0000407658 00000 n 0000028550 00000 n 0000031169 00000 n 0000448813 00000 n 0000448843 00000 n 0000407820 00000 n 0000031190 00000 n 0000033777 00000 n 0000448895 00000 n 0000448925 00000 n 0000407982 00000 n 0000033798 00000 n 0000036185 00000 n 0000448977 00000 n 0000449007 00000 n 0000408144 00000 n 0000036206 00000 n 0000038577 00000 n 0000449059 00000 n 0000449089 00000 n 0000408306 00000 n 0000038598 00000 n 0000039972 00000 n 0000449152 00000 n 0000449182 00000 n 0000408468 00000 n 0000039993 00000 n 0000041741 00000 n 0000449223 00000 n 0000449253 00000 n 0000408630 00000 n 0000041762 00000 n 0000043815 00000 n 0000449294 00000 n 0000449325 00000 n 0000408794 00000 n 0000043837 00000 n 0000046795 00000 n 0000449367 00000 n 0000449398 00000 n 0000408960 00000 n 0000046817 00000 n 0000049650 00000 n 0000449462 00000 n 0000449493 00000 n 0000409126 00000 n 0000049672 00000 n 0000052121 00000 n 0000449546 00000 n 0000449577 00000 n 0000409292 00000 n 0000052143 00000 n 0000054464 00000 n 0000449630 00000 n 0000449661 00000 n 0000409458 00000 n 0000054486 00000 n 0000055911 00000 n 0000449725 00000 n 0000449756 00000 n 0000409624 00000 n 0000055933 00000 n 0000057593 00000 n 0000449820 00000 n 0000449851 00000 n 0000409790 00000 n 0000057615 00000 n 0000059937 00000 n 0000449904 00000 n 0000449935 00000 n 0000409956 00000 n 0000059959 00000 n 0000062051 00000 n 0000449988 00000 n 0000450019 00000 n 0000410122 00000 n 0000062073 00000 n 0000064372 00000 n 0000450083 00000 n 0000450114 00000 n 0000410288 00000 n 0000064394 00000 n 0000066509 00000 n 0000450178 00000 n 0000450209 00000 n 0000410454 00000 n 0000066531 00000 n 0000068295 00000 n 0000450262 00000 n 0000450293 00000 n 0000410620 00000 n 0000068317 00000 n 0000069503 00000 n 0000450346 00000 n 0000450377 00000 n 0000410786 00000 n 0000069525 00000 n 0000071187 00000 n 0000450430 00000 n 0000450461 00000 n 0000410952 00000 n 0000071209 00000 n 0000073011 00000 n 0000450525 00000 n 0000450556 00000 n 0000411118 00000 n 0000073033 00000 n 0000074965 00000 n 0000450609 00000 n 0000450640 00000 n 0000411284 00000 n 0000074987 00000 n 0000076833 00000 n 0000450693 00000 n 0000450724 00000 n 0000411450 00000 n 0000076855 00000 n 0000079320 00000 n 0000450777 00000 n 0000450808 00000 n 0000411616 00000 n 0000079342 00000 n 0000081238 00000 n 0000450850 00000 n 0000450881 00000 n 0000411782 00000 n 0000081260 00000 n 0000083259 00000 n 0000450934 00000 n 0000450965 00000 n 0000411948 00000 n 0000083281 00000 n 0000085052 00000 n 0000451018 00000 n 0000451049 00000 n 0000412114 00000 n 0000085074 00000 n 0000085901 00000 n 0000451091 00000 n 0000451122 00000 n 0000412280 00000 n 0000085922 00000 n 0000086866 00000 n 0000451164 00000 n 0000451195 00000 n 0000412446 00000 n 0000086887 00000 n 0000088776 00000 n 0000451248 00000 n 0000451279 00000 n 0000412612 00000 n 0000088798 00000 n 0000090516 00000 n 0000451332 00000 n 0000451363 00000 n 0000412778 00000 n 0000090538 00000 n 0000092273 00000 n 0000451416 00000 n 0000451447 00000 n 0000412944 00000 n 0000092295 00000 n 0000093735 00000 n 0000451500 00000 n 0000451531 00000 n 0000413110 00000 n 0000093757 00000 n 0000095924 00000 n 0000451584 00000 n 0000451615 00000 n 0000413276 00000 n 0000095946 00000 n 0000098265 00000 n 0000451657 00000 n 0000451688 00000 n 0000413442 00000 n 0000098287 00000 n 0000099580 00000 n 0000451741 00000 n 0000451772 00000 n 0000413608 00000 n 0000099602 00000 n 0000101348 00000 n 0000451825 00000 n 0000451856 00000 n 0000413774 00000 n 0000101370 00000 n 0000102659 00000 n 0000451920 00000 n 0000451951 00000 n 0000413940 00000 n 0000102681 00000 n 0000104526 00000 n 0000452004 00000 n 0000452035 00000 n 0000414106 00000 n 0000104548 00000 n 0000106692 00000 n 0000452088 00000 n 0000452119 00000 n 0000414272 00000 n 0000106714 00000 n 0000108251 00000 n 0000452172 00000 n 0000452203 00000 n 0000414438 00000 n 0000108273 00000 n 0000110191 00000 n 0000452256 00000 n 0000452287 00000 n 0000414604 00000 n 0000110213 00000 n 0000111982 00000 n 0000452340 00000 n 0000452371 00000 n 0000414770 00000 n 0000112004 00000 n 0000113009 00000 n 0000452424 00000 n 0000452455 00000 n 0000414936 00000 n 0000113030 00000 n 0000114561 00000 n 0000452508 00000 n 0000452539 00000 n 0000415102 00000 n 0000114583 00000 n 0000116543 00000 n 0000452592 00000 n 0000452623 00000 n 0000415268 00000 n 0000116565 00000 n 0000118120 00000 n 0000452676 00000 n 0000452707 00000 n 0000415434 00000 n 0000118142 00000 n 0000119368 00000 n 0000452760 00000 n 0000452791 00000 n 0000415600 00000 n 0000119390 00000 n 0000121267 00000 n 0000452855 00000 n 0000452886 00000 n 0000415766 00000 n 0000121289 00000 n 0000122725 00000 n 0000452939 00000 n 0000452970 00000 n 0000415932 00000 n 0000122747 00000 n 0000124221 00000 n 0000453023 00000 n 0000453054 00000 n 0000416098 00000 n 0000124243 00000 n 0000125856 00000 n 0000453107 00000 n 0000453138 00000 n 0000416264 00000 n 0000125878 00000 n 0000127837 00000 n 0000453191 00000 n 0000453222 00000 n 0000416430 00000 n 0000127859 00000 n 0000129529 00000 n 0000453286 00000 n 0000453317 00000 n 0000416596 00000 n 0000129551 00000 n 0000131540 00000 n 0000453370 00000 n 0000453401 00000 n 0000416762 00000 n 0000131562 00000 n 0000133555 00000 n 0000453454 00000 n 0000453485 00000 n 0000416928 00000 n 0000133577 00000 n 0000135367 00000 n 0000453538 00000 n 0000453569 00000 n 0000417094 00000 n 0000135389 00000 n 0000136922 00000 n 0000453622 00000 n 0000453653 00000 n 0000417260 00000 n 0000136944 00000 n 0000138565 00000 n 0000453706 00000 n 0000453737 00000 n 0000417426 00000 n 0000138587 00000 n 0000140805 00000 n 0000453790 00000 n 0000453821 00000 n 0000417592 00000 n 0000140827 00000 n 0000141938 00000 n 0000453874 00000 n 0000453905 00000 n 0000417758 00000 n 0000141960 00000 n 0000143124 00000 n 0000453947 00000 n 0000453978 00000 n 0000417924 00000 n 0000143146 00000 n 0000144202 00000 n 0000454009 00000 n 0000454040 00000 n 0000418090 00000 n 0000144223 00000 n 0000145815 00000 n 0000454071 00000 n 0000454102 00000 n 0000418256 00000 n 0000145837 00000 n 0000147090 00000 n 0000454155 00000 n 0000454186 00000 n 0000418422 00000 n 0000147112 00000 n 0000147991 00000 n 0000454239 00000 n 0000454270 00000 n 0000418588 00000 n 0000148012 00000 n 0000148849 00000 n 0000454312 00000 n 0000454343 00000 n 0000418754 00000 n 0000148870 00000 n 0000151405 00000 n 0000454396 00000 n 0000454427 00000 n 0000418920 00000 n 0000151427 00000 n 0000153503 00000 n 0000454469 00000 n 0000454500 00000 n 0000419086 00000 n 0000153525 00000 n 0000155280 00000 n 0000454553 00000 n 0000454584 00000 n 0000419252 00000 n 0000155302 00000 n 0000156263 00000 n 0000454626 00000 n 0000454657 00000 n 0000419418 00000 n 0000156284 00000 n 0000157476 00000 n 0000454688 00000 n 0000454719 00000 n 0000419584 00000 n 0000157498 00000 n 0000159957 00000 n 0000454772 00000 n 0000454803 00000 n 0000419750 00000 n 0000159979 00000 n 0000161523 00000 n 0000454845 00000 n 0000454876 00000 n 0000419916 00000 n 0000161545 00000 n 0000163242 00000 n 0000454929 00000 n 0000454960 00000 n 0000420082 00000 n 0000163264 00000 n 0000165069 00000 n 0000455013 00000 n 0000455044 00000 n 0000420248 00000 n 0000165091 00000 n 0000167250 00000 n 0000455097 00000 n 0000455128 00000 n 0000420414 00000 n 0000167272 00000 n 0000169309 00000 n 0000455181 00000 n 0000455212 00000 n 0000420580 00000 n 0000169331 00000 n 0000170990 00000 n 0000455265 00000 n 0000455296 00000 n 0000420746 00000 n 0000171012 00000 n 0000172471 00000 n 0000455349 00000 n 0000455380 00000 n 0000420912 00000 n 0000172493 00000 n 0000173569 00000 n 0000455433 00000 n 0000455464 00000 n 0000421078 00000 n 0000173591 00000 n 0000174480 00000 n 0000455506 00000 n 0000455537 00000 n 0000421244 00000 n 0000174501 00000 n 0000175433 00000 n 0000455579 00000 n 0000455610 00000 n 0000421410 00000 n 0000175454 00000 n 0000176793 00000 n 0000455652 00000 n 0000455683 00000 n 0000421576 00000 n 0000176815 00000 n 0000178439 00000 n 0000455736 00000 n 0000455767 00000 n 0000421742 00000 n 0000178461 00000 n 0000180335 00000 n 0000455820 00000 n 0000455851 00000 n 0000421908 00000 n 0000180357 00000 n 0000182038 00000 n 0000455904 00000 n 0000455935 00000 n 0000422074 00000 n 0000182060 00000 n 0000183926 00000 n 0000455988 00000 n 0000456019 00000 n 0000422240 00000 n 0000183948 00000 n 0000185756 00000 n 0000456072 00000 n 0000456103 00000 n 0000422406 00000 n 0000185778 00000 n 0000187443 00000 n 0000456156 00000 n 0000456187 00000 n 0000422572 00000 n 0000187465 00000 n 0000189340 00000 n 0000456251 00000 n 0000456282 00000 n 0000422738 00000 n 0000189362 00000 n 0000191257 00000 n 0000456346 00000 n 0000456377 00000 n 0000422904 00000 n 0000191279 00000 n 0000193016 00000 n 0000456430 00000 n 0000456461 00000 n 0000423070 00000 n 0000193038 00000 n 0000195015 00000 n 0000456514 00000 n 0000456545 00000 n 0000423236 00000 n 0000195037 00000 n 0000197518 00000 n 0000456598 00000 n 0000456629 00000 n 0000423402 00000 n 0000197540 00000 n 0000199299 00000 n 0000456682 00000 n 0000456713 00000 n 0000423568 00000 n 0000199321 00000 n 0000200566 00000 n 0000456766 00000 n 0000456797 00000 n 0000423734 00000 n 0000200588 00000 n 0000202006 00000 n 0000456850 00000 n 0000456881 00000 n 0000423900 00000 n 0000202028 00000 n 0000203733 00000 n 0000456934 00000 n 0000456965 00000 n 0000424066 00000 n 0000203755 00000 n 0000206129 00000 n 0000457018 00000 n 0000457049 00000 n 0000424232 00000 n 0000206151 00000 n 0000207695 00000 n 0000457102 00000 n 0000457133 00000 n 0000424398 00000 n 0000207717 00000 n 0000209504 00000 n 0000457186 00000 n 0000457217 00000 n 0000424564 00000 n 0000209526 00000 n 0000211100 00000 n 0000457270 00000 n 0000457301 00000 n 0000424730 00000 n 0000211122 00000 n 0000212264 00000 n 0000457354 00000 n 0000457385 00000 n 0000424896 00000 n 0000212286 00000 n 0000213757 00000 n 0000457438 00000 n 0000457469 00000 n 0000425062 00000 n 0000213779 00000 n 0000215652 00000 n 0000457522 00000 n 0000457553 00000 n 0000425228 00000 n 0000215674 00000 n 0000217465 00000 n 0000457606 00000 n 0000457637 00000 n 0000425394 00000 n 0000217487 00000 n 0000218756 00000 n 0000457690 00000 n 0000457721 00000 n 0000425560 00000 n 0000218778 00000 n 0000220804 00000 n 0000457774 00000 n 0000457805 00000 n 0000425726 00000 n 0000220826 00000 n 0000222403 00000 n 0000457858 00000 n 0000457889 00000 n 0000425892 00000 n 0000222425 00000 n 0000224182 00000 n 0000457942 00000 n 0000457973 00000 n 0000426058 00000 n 0000224204 00000 n 0000225919 00000 n 0000458026 00000 n 0000458057 00000 n 0000426224 00000 n 0000225941 00000 n 0000227539 00000 n 0000458110 00000 n 0000458141 00000 n 0000426390 00000 n 0000227561 00000 n 0000228784 00000 n 0000458194 00000 n 0000458225 00000 n 0000426556 00000 n 0000228806 00000 n 0000230338 00000 n 0000458278 00000 n 0000458309 00000 n 0000426722 00000 n 0000230360 00000 n 0000232499 00000 n 0000458362 00000 n 0000458393 00000 n 0000426888 00000 n 0000232521 00000 n 0000233351 00000 n 0000458446 00000 n 0000458477 00000 n 0000427054 00000 n 0000233372 00000 n 0000234094 00000 n 0000458530 00000 n 0000458561 00000 n 0000427220 00000 n 0000234115 00000 n 0000234772 00000 n 0000458614 00000 n 0000458645 00000 n 0000427386 00000 n 0000234793 00000 n 0000235419 00000 n 0000458698 00000 n 0000458729 00000 n 0000427552 00000 n 0000235440 00000 n 0000237042 00000 n 0000458782 00000 n 0000458813 00000 n 0000427718 00000 n 0000237064 00000 n 0000238718 00000 n 0000458866 00000 n 0000458897 00000 n 0000427884 00000 n 0000238740 00000 n 0000239270 00000 n 0000458950 00000 n 0000458981 00000 n 0000428050 00000 n 0000239291 00000 n 0000240150 00000 n 0000459034 00000 n 0000459065 00000 n 0000428216 00000 n 0000240171 00000 n 0000241048 00000 n 0000459107 00000 n 0000459138 00000 n 0000428382 00000 n 0000241069 00000 n 0000241685 00000 n 0000459180 00000 n 0000459211 00000 n 0000428548 00000 n 0000241706 00000 n 0000242773 00000 n 0000459253 00000 n 0000459284 00000 n 0000428714 00000 n 0000242794 00000 n 0000244882 00000 n 0000459337 00000 n 0000459368 00000 n 0000428880 00000 n 0000244904 00000 n 0000246900 00000 n 0000459421 00000 n 0000459452 00000 n 0000429046 00000 n 0000246922 00000 n 0000248958 00000 n 0000459505 00000 n 0000459536 00000 n 0000429212 00000 n 0000248980 00000 n 0000250794 00000 n 0000459589 00000 n 0000459620 00000 n 0000429378 00000 n 0000250816 00000 n 0000252856 00000 n 0000459673 00000 n 0000459704 00000 n 0000429544 00000 n 0000252878 00000 n 0000254542 00000 n 0000459757 00000 n 0000459788 00000 n 0000429710 00000 n 0000254564 00000 n 0000255622 00000 n 0000459841 00000 n 0000459872 00000 n 0000429876 00000 n 0000255643 00000 n 0000258300 00000 n 0000459925 00000 n 0000459956 00000 n 0000430042 00000 n 0000258322 00000 n 0000260832 00000 n 0000459987 00000 n 0000460018 00000 n 0000430208 00000 n 0000260854 00000 n 0000262813 00000 n 0000460060 00000 n 0000460091 00000 n 0000430374 00000 n 0000262835 00000 n 0000264867 00000 n 0000460144 00000 n 0000460175 00000 n 0000430540 00000 n 0000264889 00000 n 0000266917 00000 n 0000460228 00000 n 0000460259 00000 n 0000430706 00000 n 0000266939 00000 n 0000267686 00000 n 0000460312 00000 n 0000460343 00000 n 0000430872 00000 n 0000267707 00000 n 0000268816 00000 n 0000460396 00000 n 0000460427 00000 n 0000431038 00000 n 0000268838 00000 n 0000269750 00000 n 0000460480 00000 n 0000460511 00000 n 0000431204 00000 n 0000269771 00000 n 0000270720 00000 n 0000460564 00000 n 0000460595 00000 n 0000431370 00000 n 0000270741 00000 n 0000272790 00000 n 0000460648 00000 n 0000460679 00000 n 0000431536 00000 n 0000272812 00000 n 0000274276 00000 n 0000460732 00000 n 0000460763 00000 n 0000431702 00000 n 0000274298 00000 n 0000275805 00000 n 0000460816 00000 n 0000460847 00000 n 0000431868 00000 n 0000275827 00000 n 0000278322 00000 n 0000460900 00000 n 0000460931 00000 n 0000432034 00000 n 0000278344 00000 n 0000279939 00000 n 0000460984 00000 n 0000461015 00000 n 0000432200 00000 n 0000279961 00000 n 0000281942 00000 n 0000461068 00000 n 0000461099 00000 n 0000432366 00000 n 0000281964 00000 n 0000283840 00000 n 0000461152 00000 n 0000461183 00000 n 0000432532 00000 n 0000283862 00000 n 0000285872 00000 n 0000461236 00000 n 0000461267 00000 n 0000432698 00000 n 0000285894 00000 n 0000288334 00000 n 0000461320 00000 n 0000461351 00000 n 0000432864 00000 n 0000288356 00000 n 0000290788 00000 n 0000461393 00000 n 0000461424 00000 n 0000433030 00000 n 0000290810 00000 n 0000292503 00000 n 0000461477 00000 n 0000461508 00000 n 0000433196 00000 n 0000292525 00000 n 0000294503 00000 n 0000461561 00000 n 0000461592 00000 n 0000433362 00000 n 0000294525 00000 n 0000296532 00000 n 0000461645 00000 n 0000461676 00000 n 0000433528 00000 n 0000296554 00000 n 0000298772 00000 n 0000461729 00000 n 0000461760 00000 n 0000433694 00000 n 0000298794 00000 n 0000300496 00000 n 0000461813 00000 n 0000461844 00000 n 0000433860 00000 n 0000300518 00000 n 0000302447 00000 n 0000461897 00000 n 0000461928 00000 n 0000434026 00000 n 0000302469 00000 n 0000303434 00000 n 0000461981 00000 n 0000462012 00000 n 0000434192 00000 n 0000303455 00000 n 0000305140 00000 n 0000462065 00000 n 0000462096 00000 n 0000434358 00000 n 0000305162 00000 n 0000307376 00000 n 0000462160 00000 n 0000462191 00000 n 0000434524 00000 n 0000307398 00000 n 0000309109 00000 n 0000462244 00000 n 0000462275 00000 n 0000434690 00000 n 0000309131 00000 n 0000311551 00000 n 0000462328 00000 n 0000462359 00000 n 0000434856 00000 n 0000311573 00000 n 0000311934 00000 n 0000462412 00000 n 0000462443 00000 n 0000435022 00000 n 0000311955 00000 n 0000312837 00000 n 0000462485 00000 n 0000462516 00000 n 0000435188 00000 n 0000312858 00000 n 0000314135 00000 n 0000462558 00000 n 0000462589 00000 n 0000435354 00000 n 0000314157 00000 n 0000316032 00000 n 0000462642 00000 n 0000462673 00000 n 0000435520 00000 n 0000316054 00000 n 0000317850 00000 n 0000462726 00000 n 0000462757 00000 n 0000435686 00000 n 0000317872 00000 n 0000320150 00000 n 0000462810 00000 n 0000462841 00000 n 0000435852 00000 n 0000320172 00000 n 0000321403 00000 n 0000462894 00000 n 0000462925 00000 n 0000436018 00000 n 0000321425 00000 n 0000322818 00000 n 0000462978 00000 n 0000463009 00000 n 0000436184 00000 n 0000322840 00000 n 0000324248 00000 n 0000463062 00000 n 0000463093 00000 n 0000436350 00000 n 0000324270 00000 n 0000325701 00000 n 0000463146 00000 n 0000463177 00000 n 0000436516 00000 n 0000325723 00000 n 0000328188 00000 n 0000463230 00000 n 0000463261 00000 n 0000436682 00000 n 0000328210 00000 n 0000330545 00000 n 0000463314 00000 n 0000463345 00000 n 0000436848 00000 n 0000330567 00000 n 0000331965 00000 n 0000463398 00000 n 0000463429 00000 n 0000437014 00000 n 0000331987 00000 n 0000333844 00000 n 0000463482 00000 n 0000463513 00000 n 0000437180 00000 n 0000333866 00000 n 0000334724 00000 n 0000463566 00000 n 0000463597 00000 n 0000437346 00000 n 0000334745 00000 n 0000335512 00000 n 0000463650 00000 n 0000463681 00000 n 0000437512 00000 n 0000335533 00000 n 0000336734 00000 n 0000463723 00000 n 0000463754 00000 n 0000437678 00000 n 0000336756 00000 n 0000338488 00000 n 0000463807 00000 n 0000463838 00000 n 0000437844 00000 n 0000338510 00000 n 0000340244 00000 n 0000463891 00000 n 0000463922 00000 n 0000438010 00000 n 0000340266 00000 n 0000341729 00000 n 0000463975 00000 n 0000464006 00000 n 0000438176 00000 n 0000341751 00000 n 0000342549 00000 n 0000464059 00000 n 0000464090 00000 n 0000438342 00000 n 0000342570 00000 n 0000343351 00000 n 0000464132 00000 n 0000464163 00000 n 0000438508 00000 n 0000343372 00000 n 0000344869 00000 n 0000464216 00000 n 0000464248 00000 n 0000438676 00000 n 0000344892 00000 n 0000346600 00000 n 0000464302 00000 n 0000464334 00000 n 0000438846 00000 n 0000346623 00000 n 0000348595 00000 n 0000464388 00000 n 0000464420 00000 n 0000439016 00000 n 0000348618 00000 n 0000350776 00000 n 0000464474 00000 n 0000464506 00000 n 0000439186 00000 n 0000350799 00000 n 0000352317 00000 n 0000464560 00000 n 0000464592 00000 n 0000439356 00000 n 0000352340 00000 n 0000353350 00000 n 0000464635 00000 n 0000464667 00000 n 0000439526 00000 n 0000353372 00000 n 0000354450 00000 n 0000464721 00000 n 0000464753 00000 n 0000439696 00000 n 0000354473 00000 n 0000356762 00000 n 0000464807 00000 n 0000464839 00000 n 0000439866 00000 n 0000356785 00000 n 0000358886 00000 n 0000464893 00000 n 0000464925 00000 n 0000440036 00000 n 0000358909 00000 n 0000360821 00000 n 0000464979 00000 n 0000465011 00000 n 0000440206 00000 n 0000360844 00000 n 0000362917 00000 n 0000465065 00000 n 0000465097 00000 n 0000440376 00000 n 0000362940 00000 n 0000364168 00000 n 0000465151 00000 n 0000465183 00000 n 0000440546 00000 n 0000364191 00000 n 0000365908 00000 n 0000465237 00000 n 0000465269 00000 n 0000440716 00000 n 0000365931 00000 n 0000367256 00000 n 0000465323 00000 n 0000465355 00000 n 0000440886 00000 n 0000367279 00000 n 0000368132 00000 n 0000465398 00000 n 0000465430 00000 n 0000441056 00000 n 0000368154 00000 n 0000370066 00000 n 0000465484 00000 n 0000465516 00000 n 0000441226 00000 n 0000370089 00000 n 0000371426 00000 n 0000465570 00000 n 0000465602 00000 n 0000441396 00000 n 0000371449 00000 n 0000373095 00000 n 0000465656 00000 n 0000465688 00000 n 0000441566 00000 n 0000373118 00000 n 0000374432 00000 n 0000465742 00000 n 0000465774 00000 n 0000441736 00000 n 0000374455 00000 n 0000376103 00000 n 0000465828 00000 n 0000465860 00000 n 0000441906 00000 n 0000376126 00000 n 0000377508 00000 n 0000465914 00000 n 0000465946 00000 n 0000442076 00000 n 0000377531 00000 n 0000378771 00000 n 0000466000 00000 n 0000466032 00000 n 0000442246 00000 n 0000378794 00000 n 0000380443 00000 n 0000466086 00000 n 0000466118 00000 n 0000442416 00000 n 0000380466 00000 n 0000382626 00000 n 0000466183 00000 n 0000466215 00000 n 0000442586 00000 n 0000382649 00000 n 0000384642 00000 n 0000466269 00000 n 0000466301 00000 n 0000442756 00000 n 0000384665 00000 n 0000386283 00000 n 0000466355 00000 n 0000466387 00000 n 0000442926 00000 n 0000386306 00000 n 0000387782 00000 n 0000466441 00000 n 0000466473 00000 n 0000443096 00000 n 0000387805 00000 n 0000389260 00000 n 0000466527 00000 n 0000466559 00000 n 0000443266 00000 n 0000389283 00000 n 0000389531 00000 n 0000466624 00000 n 0000466656 00000 n 0000443436 00000 n 0000389553 00000 n 0000390852 00000 n 0000466688 00000 n 0000466720 00000 n 0000443606 00000 n 0000390875 00000 n 0000392137 00000 n 0000466752 00000 n 0000466784 00000 n 0000443776 00000 n 0000392160 00000 n 0000393344 00000 n 0000466816 00000 n 0000466848 00000 n 0000443946 00000 n 0000393367 00000 n 0000394638 00000 n 0000466880 00000 n 0000466912 00000 n 0000444116 00000 n 0000394661 00000 n 0000395921 00000 n 0000466944 00000 n 0000466976 00000 n 0000444286 00000 n 0000395944 00000 n 0000397217 00000 n 0000467008 00000 n 0000467040 00000 n 0000444456 00000 n 0000397240 00000 n 0000398599 00000 n 0000467072 00000 n 0000467104 00000 n 0000444626 00000 n 0000398622 00000 n 0000399992 00000 n 0000467136 00000 n 0000467168 00000 n 0000444796 00000 n 0000400015 00000 n 0000401324 00000 n 0000467200 00000 n 0000467232 00000 n 0000444966 00000 n 0000401347 00000 n 0000402236 00000 n 0000467264 00000 n 0000467296 00000 n 0000445136 00000 n 0000402258 00000 n 0000403213 00000 n 0000467328 00000 n 0000467360 00000 n 0000445306 00000 n 0000403235 00000 n 0000404377 00000 n 0000467392 00000 n 0000467424 00000 n 0000445476 00000 n 0000404400 00000 n 0000404650 00000 n 0000467456 00000 n 0000467488 00000 n 0000445646 00000 n 0000404672 00000 n 0000405855 00000 n 0000467520 00000 n 0000467552 00000 n 0000470373 00000 n 0000479490 00000 n 0000486304 00000 n 0000491790 00000 n 0000468134 00000 n 0000468755 00000 n 0000498370 00000 n trailer << /Size 1220 /Root 1 0 R /Info 2 0 R /ID [] >> startxref 499949 %%EOF dwarfutils-20200114/libdwarf/libdwarf2p.1.mm000066400000000000000000004511571361531463500204750ustar00rootroot00000000000000\." $Revision: 1.12 $ \." $Date: 2002/01/14 23:40:11 $ \." \." \." the following line may be removed if the ff ligature works on your machine .lg 0 \." set up heading formats .ds HF 3 3 3 3 3 2 2 .ds HP +2 +2 +1 +0 +0 .nr Hs 5 .nr Hb 5 \." Increment body point size .S +2 \." ============================================== \." Put current date in the following at each rev .ds vE Rev 1.50, 20 September 2019 \." ============================================== \." ============================================== .ds | | .ds ~ ~ .ds ' ' .if t .ds Cw \&\f(CW .if n .ds Cw \fB .de Cf \" Place every other arg in Cw font, beginning with first .if \\n(.$=1 \&\*(Cw\\$1\fP .if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 .if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP .if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 .if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP .if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 .if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP .if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 .if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ *(Cw .. .nr Cl 3 .SA 1 .TL A Producer Library Interface to DWARF .AF "" .AU "David Anderson" .PF "'\*(vE '- \\\\nP -''" .AS 1 This document describes an interface to a library of functions to create DWARF debugging information entries and DWARF line number information. It does not make recommendations as to how the functions described in this document should be implemented nor does it suggest possible optimizations. .P The document is oriented to creating DWARF version 2. Support for creating DWARF3 and DWARF4 and DWARF5 is only partial: various features since DWARF2 cannot be created. .P \*(vE .AE .MT 4 .H 1 "INTRODUCTION" This document describes an interface to \f(CWlibdwarf\fP, a library of functions to provide creation of DWARF debugging information records, DWARF line number information, DWARF address range and pubnames information, weak names information, and DWARF frame description information. .H 2 "Copyright" Copyright 1993-2006 Silicon Graphics, Inc. Copyright 2007-2019 David Anderson. Permission is hereby granted to copy or republish or use any or all of this document without restriction except that when publishing more than a small amount of the document please acknowledge Silicon Graphics, Inc and David Anderson. This document is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .H 2 "Purpose and Scope" The purpose of this document is to propose a library of functions to create DWARF debugging information. Reading (consuming) of such records is discussed in a separate document. The functions in this document have mostly been implemented at Silicon Graphics and used by the SGI code generator to provide debugging information. Some functions (and support for some extensions) were provided by Sun Microsystems. Example code showing one use of the functionality may be found in the dwarfgen \f(CWdwarfgen\fP and \f(CWsimpleexample\fP application (provided in the source distribution along with libdwarf). .P The focus of this document is the functional interface, and as such, implementation and optimization issues are intentionally ignored. .P Error handling, error codes, and certain \f(CWLibdwarf\fP codes are discussed in the "\fIA Consumer Library Interface to DWARF\fP", which should be read before reading this document. .P Before December 2018 very few functions in the Producer Library follow the error-returns as defined in "\fIA Consumer Library Interface to DWARF\fP". .P As of December 2018 every Producer Library call has a version that supports that Consumer Library Interface and returns DW_DLV_OK or DW_DLV_ERROR (the Producer Library has no use of DW_DLV_NO_ENTRY). The table of contents of this document lists the latest version of each function. However, all the earlier documentation is present here immediately following the documentation of the latest, and preferred, interface. All the earlier interfaces are supported in the library. .P Early interfaces (before December 2018) The general style of functions here in the producer library is rather C-traditional with various types as return values (quite different from the consumer library interfaces). The style generally follows the style of the original DWARF1 reader proposed as an interface to DWARF. When the style of the reader interfaces was changed (1994) in the dwarf reader ( See the "Document History" section of "A Consumer Library Interface to DWARF") the interfaces here were not changed as it seemed like too much of a change for the two applications then using the interface! So this interface remains in the traditional C style of returning various data types with various (somewhat inconsistent) means of indicating failure. .P December 2018 and later function interfaces all return either DW_DLV_OK or DW_DLV_ERROR in a simple int. .P The error handling code in the library may either return a value or abort. The library user can provide a function that the producer code will call on errors (which would allow callers avoid testing for error returns if the user function exits or aborts). See the \f(CWdwarf_producer_init()\fP description below for more details. .H 2 "Document History" This document originally prominently referenced "UNIX International Programming Languages Special Interest Group " (PLSIG). Both UNIX International and the affiliated Programming Languages Special Interest Group are defunct (UNIX is a registered trademark of UNIX System Laboratories, Inc. in the United States and other countries). Nothing except the general interface style is actually related to anything shown to the PLSIG (this document was open sourced with libdwarf in the mid 1990's). .P See "http://www.dwarfstd.org" for information on current DWARF standards and committee activities. .H 2 "Definitions" DWARF debugging information entries (DIEs) are the segments of information placed in the \f(CW.debug_info\fP and related sections by compilers, assemblers, and linkage editors that, in conjunction with line number entries, are necessary for symbolic source-level debugging. Refer to the document "\fIDWARF Debugging Information Format\fP" from UI PLSIG for a more complete description of these entries. .P This document adopts all the terms and definitions in "\fIDWARF Debugging Information Format\fP" version 2. and the "\fIA Consumer Library Interface to DWARF\fP". .P In addition, this document refers to Elf, the ATT/USL System V Release 4 object format. This is because the library was first developed for that object format. Hopefully the functions defined here can easily be applied to other object formats. .H 2 "Overview" The remaining sections of this document describe a proposed producer (compiler or assembler) interface to \fILibdwarf\fP, first by describing the purpose of additional types defined by the interface, followed by descriptions of the available operations. This document assumes you are thoroughly familiar with the information contained in the \fIDWARF Debugging Information Format\fP document, and "\fIA Consumer Library Interface to DWARF\fP". .P The interface necessarily knows a little bit about the object format (which is assumed to be Elf). We make an attempt to make this knowledge as limited as possible. For example, \fILibdwarf\fP does not do the writing of object data to the disk. The producer program does that. .H 2 "Revision History" .VL 15 .LI "March 1993" Work on dwarf2 sgi producer draft begins .LI "March 1999" Adding a function to allow any number of trips through the dwarf_get_section_bytes() call. .LI "April 10 1999" Added support for assembler text output of dwarf (as when the output must pass through an assembler). Revamped internals for better performance and simpler provision for differences in ABI. .LI "Sep 1, 1999" Added support for little- and cross- endian debug info creation. .LI "May 7 2007" This library interface now cleans up, deallocating all memory it uses (the application simply calls dwarf_producer_finish(dbg)). .LI "September 20 2010" Now documents the marker feature of DIE creation. .LI "May 01 2014" The dwarf_producer_init() code has a new interface and DWARF is configured at run time by its arguments. The producer code used to be configured at configure time, but the configure time producer configure options are no longer used. The configuration was unnecessarily complicated: the run-time configuration is simpler to understand. .LI "September 10, 2016" Beginning the process of creating new interfaces so that checking for error is consistent across all calls (as is done in the consumer library). The old interfaces are kept and supported so we have binary and source compatibility with old code. .LI "December 01, 2018" All function interfaces now have a version that returns only DW_DLV_OK or DW_DLV_ERROR and pointer and other values are returned through pointer arguments. For example, dwarf_add_frame_info_c() is the December 2018 version, while dwarf_add_frame_info(), dwarf_add_frame_info_b() are earlier versions (which are still supported). .LE .H 1 "Type Definitions" .H 2 "General Description" The \fIlibdwarf.h\fP header file contains typedefs and preprocessor definitions of types and symbolic names used to reference objects of \fI Libdwarf \fP . The types defined by typedefs contained in \fI libdwarf.h\fP all use the convention of adding \fI Dwarf_ \fP as a prefix to indicate that they refer to objects used by Libdwarf. The prefix \fI Dwarf_P_\fP is used for objects referenced by the \fI Libdwarf\fP Producer when there are similar but distinct objects used by the Consumer. .H 2 "Namespace issues" Application programs should avoid creating names beginning with \f(CWDwarf_\fP \f(CWdwarf_\fP or \f(CWDW_\fP as these are reserved to dwarf and libdwarf. .H 1 "libdwarf and Elf and relocations" Much of the description below presumes that Elf is the object format in use. The library is probably usable with other object formats that allow arbitrary sections to be created. The library does not write anything to disk. Instead it provides access so that callers can do that. .H 2 "binary or assembler output" With \f(CWDW_DLC_STREAM_RELOCATIONS\fP (see below) it is assumed that the calling app will simply write the streams and relocations directly into an Elf file, without going through an assembler. With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the calling app must either A) generate binary relocation streams and write the generated debug information streams and the relocation streams direct to an elf file or B) generate assembler output text for an assembler to read and produce an object file. With case B) the libdwarf-calling application must use the relocation information to change points of each binary stream into references to symbolic names. It is necessary for the assembler to be willing to accept and generate relocations for references from arbitrary byte boundaries. For example: .sp .nf .in +4 .data 0a0bcc #producing 3 bytes of data. .word mylabel #producing a reference .word endlabel - startlabel #producing absolute length .in -4 .fi .sp .H 2 "libdwarf relationship to Elf" When the documentation below refers to 'an elf section number' it is really only dependent on getting (via the callback function passed by the caller of \f(CWdwarf_producer_init()\fP. a sequence of integers back (with 1 as the lowest). When the documentation below refers to 'an Elf symbol index' it is really dependent on Elf symbol numbers only if \f(CWDW_DLC_STREAM_RELOCATIONS\fP are being generated (see below). With \f(CWDW_DLC_STREAM_RELOCATIONS\fP the library is generating Elf relocations and the section numbers in binary form so the section numbers and symbol indices must really be Elf (or elf-like) numbers. With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the values passed as symbol indexes can be any integer set or even pointer set. All that libdwarf assumes is that where values are unique they get unique values. Libdwarf does not generate any kind of symbol table from the numbers and does not check their uniqueness or lack thereof. .H 2 "libdwarf and relocations" With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP libdwarf creates binary streams of debug information and arrays of relocation information describing the necessary relocation. The Elf section numbers and symbol numbers appear nowhere in the binary streams. Such appear only in the relocation information and the passed-back information from calls requesting the relocation information. As a consequence, the 'symbol indices' can be any pointer or integer value as the caller must arrange that the output deal with relocations. With \f(CWDW_DLC_STREAM_RELOCATIONS\fP all the relocations are directly created by libdwarf as binary streams (libdwarf only creates the streams in memory, it does not write them to disk). .H 2 "symbols, addresses, and offsets" The following applies to calls that pass in symbol indices, addresses, and offsets, such as \f(CWdwarf_add_AT_targ_address_c() \fP \f(CWdwarf_add_arange_b()\fP and \f(CWdwarf_add_frame_fde_c()\fP. With \f(CWDW_DLC_STREAM_RELOCATIONS\fP a passed in address is one of: a) a section offset and the (non-global) symbol index of a section symbol. b) A symbol index (global symbol) and a zero offset. With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the same approach can be used, or, instead, a passed in address may be c) a symbol handle and an offset. In this case, since it is up to the calling app to generate binary relocations (if appropriate) or to turn the binary stream into a text stream (for input to an assembler, if appropriate) the application has complete control of the interpretation of the symbol handles. .H 1 "Memory Management" Several of the functions that comprise the \fILibdwarf\fP producer interface dynamically allocate values and some return pointers to those spaces. The dynamically allocated spaces can not be reclaimed (and must not be freed) except that all such libdwarf-allocated memory is freed by \f(CWdwarf_producer_finish_a(dbg)\fP or \f(CWdwarf_producer_finish(dbg)\fP. All data for a particular \f(CWDwarf_P_Debug\fP descriptor is separate from the data for any other \f(CWDwarf_P_Debug\fP descriptor in use in the library-calling application. .H 2 "Read Only Properties" The read-only properties specified in the consumer interface document do not generally apply to the functions described here. .H 2 "Storage Deallocation" Calling \f(CWdwarf_producer_finish_a(dbg)\fP frees all the space, and invalidates all pointers returned from \f(CWLibdwarf\fP functions on or descended from \f(CWdbg\fP). .H 2 "Error Handling" In general any error detected by the producer should be considered fatal. That is, it is impossible to produce correct output so producing anything seems questionable. .P The original producer interfaces tended to return a pointer or a large integer as a result and required the caller to cast that value to determine if it was actually a -1 meaning there was an error. .P Beginning in September 2016 additional interfaces are being added to eliminate the necessity for callers to do this ugly casting of results. In December 2018 that process has reached completion. The revised functions return \f(CWDW_DLV_OK\fP, or \f(CWDW_DLV_ERROR\fP. (which are small signed integers) and will have an additional pointer argument that will provide the value that used to be the return value. This will make the interfaces type-safe. .P The function \f(CWdwarf_get_section_bytes_a()\fP can also return \f(CWDW_DLV_NO_ENTRY\fP. .P The original interfaces will remain. Binary and source compatibility for old code using the older interfaces is retained. .H 1 "Functional Interface" This section describes the functions available in the \fILibdwarf\fP library. Each function description includes its definition, followed by a paragraph describing the function's operation. .P The following sections describe these functions. .P The functions may be categorized into groups: \fIinitialization and termination operations\fP, \fIdebugging information entry creation\fP, \fIElf section callback function\fP, \fIattribute creation\fP, \fIexpression creation\fP, \fIline number creation\fP, \fIfast-access (aranges) creation\fP, \fIfast-access (pubnames) creation\fP, \fIfast-access (weak names) creation\fP, \fImacro information creation\fP, \fIlow level (.debug_frame) creation\fP, and \fIlocation list (.debug_loc) creation\fP. .P .H 2 "Initialization and Termination Operations" These functions setup \f(CWLibdwarf\fP to accumulate debugging information for an object, usually a compilation-unit, provided by the producer. The actual addition of information is done by functions in the other sections of this document. Once all the information has been added, functions from this section are used to transform the information to appropriate byte streams, and help to write out the byte streams to disk. Typically then, a producer application would create a \f(CWDwarf_P_Debug\fP descriptor to gather debugging information for a particular compilation-unit using \f(CWdwarf_producer_init()\fP. The producer application would use this \f(CWDwarf_P_Debug\fP descriptor to accumulate debugging information for this object using functions from other sections of this document. Once all the information had been added, it would call \f(CWdwarf_transform_to_disk_form()\fP to convert the accumulated information into byte streams in accordance with the \f(CWDWARF\fP standard. The application would then repeatedly call \f(CWdwarf_get_section_bytes_a()\fP for each of the \f(CW.debug_*\fP created. This gives the producer information about the data bytes to be written to disk. At this point, the producer would release all resource used by \f(CWLibdwarf\fP for this object by calling \f(CWdwarf_producer_finish_a()\fP. It is also possible to create assembler-input character streams from the byte streams created by this library. This feature requires slightly different interfaces than direct binary output. The details are mentioned in the text. .H 3 "dwarf_producer_init()" .DS \f(CWint dwarf_producer_init( Dwarf_Unsigned flags, Dwarf_Callback_Func func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void * user_data const char *isa_name, const char *dwarf_version, const char *extra, Dwarf_P_Debug *dbg_returned, Dwarf_Error *error) \fP .DE .P The function \f(CWdwarf_producer_init() \fP returns a new \f(CWDwarf_P_Debug\fP descriptor that can be used to add \f(CWDwarf\fP information to the object. On success it returns \f(CWDW_DLV_OK\fP. On error it returns \f(CWDW_DLV_ERROR\fP. \f(CWflags\fP determine whether the target object is 64-bit or 32-bit. \f(CWfunc\fP is a pointer to a function called-back from \f(CWLibdwarf\fP whenever \f(CWLibdwarf\fP needs to create a new object section (as it will for each .debug_* section and related relocation section). .P The \f(CWflags\fP values (to be OR'd together in the flags field in the calling code) are as follows: .in +4 \f(CWDW_DLC_WRITE\fP is required. The values \f(CWDW_DLC_READ\fP \f(CWDW_DLC_RDWR\fP are not supported by the producer and must not be passed. The flag bit \f(CWDW_DLC_POINTER64\fP (or \f(CWDW_DLC_SIZE_64\fP) Indicates the target has a 64 bit (8 byte) address size. The flag bit \f(CWDW_DLC_POINTER32\fP (or \f(CWDW_DLC_SIZE_32\fP) Indicates the target has a 32 bit (4 byte) address size. If none of these pointer sizes is passed in \f(CWDW_DLC_POINTER32\fP is assumed. The flag bit \f(CWDW_DLC_OFFSET32\fP indicates that 32bit offsets should be used in the generated DWARF. The flag bit \f(CWDW_DLC_OFFSET64\fP \f(CWDW_DLC_OFFSET_SIZE_64\fP indicates that 64bit offsets should be used in the generated DWARF. The flag bit \f(CWDW_DLC_IRIX_OFFSET64\fP indicates that the generated DWARF should use the early (pre DWARF3) IRIX method of generating 64 bit offsets. In this case \f(CWDW_DLC_POINTER64\fP should also be passed in, and the \f(CWisa_name\fP passed in (see below) should be "irix". If \f(CWDW_DLC_TARGET_BIGENDIAN\fP or \f(CWDW_DLC_TARGET_LITTLEENDIAN\fP is not ORed into \f(CWflags\fP then endianness the same as the host is assumed. If both \f(CWDW_DLC_TARGET_LITTLEENDIAN\fP and \f(CWDW_DLC_TARGET_BIGENDIAN\fP are OR-d in it is an error. Either one of two output forms is specifiable: \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP . The default is \f(CWDW_DLC_STREAM_RELOCATIONS\fP . The \f(CWDW_DLC_STREAM_RELOCATIONS\fP are relocations in a binary stream (as used in a MIPS/IRIX Elf object). The \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP are the same relocations but expressed in an array of structures defined by libdwarf, which the caller of the relevant function (see below) must deal with appropriately. This method of expressing relocations allows the producer-application to easily produce assembler text output of debugging information. When \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP is ORed into \f(CWflags\fP then relocations are returned not as streams but through an array of structures. .in -4 .P The function \f(CWfunc\fP must be provided by the user of this library. Its prototype is: .DS \f(CWtypedef int (*Dwarf_Callback_Func)( char* name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned* sect_name_index, void * user_data, int* error) \fP .DE For each section in the object file that \f(CWlibdwarf\fP needs to create, it calls this function once (calling it from \f(CWdwarf_transform_to_disk_form()\fP), passing in the section \f(CWname\fP, the section \f(CWtype\fP, the section \f(CWflags\fP, the \f(CWlink\fP field, and the \f(CWinfo\fP field. For an Elf object file these values should be appropriate Elf section header values. For example, for relocation callbacks, the \f(CWlink\fP field is supposed to be set (by the app) to the index of the symtab section (the link field passed through the callback must be ignored by the app). And, for relocation callbacks, the \f(CWinfo\fP field is passed as the elf section number of the section the relocations apply to. .P The \f(CWsect_name_index\fP field is a field you use to pass a symbol index back to libdwarf. In Elf, each section gets an elf symbol table entry so that relocations have an address to refer to (relocations rely on addresses in the Elf symbol table). You will create the Elf symbol table, so you have to tell libdwarf the index to put into relocation records for the section newly defined here. .P On success the user function should return the Elf section number of the newly created Elf section. .P On success, the function should also set the integer pointed to by \f(CWsect_name_index\fP to the Elf symbol number assigned in the Elf symbol table of the new Elf section. This symbol number is needed with relocations dependent on the relocation of this new section. .P Use the \f(CWdwarf_producer_init_c()\fP interface instead of this interface. .P For example, the \f(CW.debug_line\fP section's third data element (in a compilation unit) is the offset from the beginning of the \f(CW.debug_info\fP section of the compilation unit entry for this \f(CW.debug_line\fP set. The relocation entry in \f(CW.rel.debug_line\fP for this offset must have the relocation symbol index of the symbol \f(CW.debug_info\fP returned by the callback of that section-creation through the pointer \f(CWsect_name_index\fP. .P On failure, the function should return -1 and set the \f(CWerror\fP integer to an error code. .P Nothing in libdwarf actually depends on the section index returned being a real Elf section. The Elf section is simply useful for generating relocation records. Similarly, the Elf symbol table index returned through the \f(CWsect_name_index\fP must be an index that can be used in relocations against this section. The application will probably want to note the values passed to this function in some form, even if no Elf file is being produced. .P \f(CWerrhand\fP is a pointer to a function that will be used as a default fall-back function for handling errors detected by \f(CWLibdwarf\fP. .P \f(CWerrarg\fP is the default error argument used by the function pointed to by \f(CWerrhand\fP. .P For historical reasons the error handling is complicated and the following three paragraphs describe the three possible scenarios when a producer function detects an error. In all cases a short error message is printed on stdout if the error number is negative (as all such should be, see libdwarf.h). Then further action is taken as follows. .P First, if the Dwarf_Error argument to any specific producer function (see the functions documented below) is non-null the \f(CWerrhand\fP argument here is ignored in that call and the specific producer function sets the Dwarf_Error and returns some specific value (for dwarf_producer_init it is DW_DLV_OK as mentioned just above) indicating there is an error. .P Second, if the Dwarf_Error argument to any specific producer function (see the functions documented below) is NULL and the \f(CWerrarg\fP to \f(CWdwarf_producer_init()\fP is non-NULL then on an error in the producer code the Dwarf_Handler function is called and if that called function returns the producer code returns a specific value (for dwarf_producer_init it is DW_DLV_OK as mentioned just above) indicating there is an error. .P Third, if the Dwarf_Error argument to any specific producer function (see the functions documented below) is NULL and the \f(CWerrarg\fP to \f(CWdwarf_producer_init()\fP is NULL then on an error \f(CWabort()\fP is called. .P The \f(CWuser_data\fP argument is not examined by libdwarf. It is passed to user code in all calls by libdwarf to the \f(CWDwarf_Callback_Func()\fP function and may be used by consumer code for the consumer's own purposes. Typical uses might be to pass in a pointer to some user data structure or to pass an integer that somehow is useful to the libdwarf-using code. .P The \f(CWisa_name\fP argument must be non-null and contain one of the strings defined in the isa_relocs array in pro_init.c: "irix","mips","x86", "x86_64","arm","arm64","ppc","ppc64", "sparc". The names are not strictly ISA names (nor ABI names) but a hopefully-meaningful mixing of the concepts of ISA and ABI. The intent is mainly to define relocation codes applicable to DW_DLC_STREAM_RELOCATIONS. New \f(CWisa_name\fP values will be provided as users request. In the "irix" case a special relocation is defined so a special CIE reference field can be created (if and only if the augmentation string is "z"). .P The \f(CWdwarf_version\fP argument should be one of "V2", "V3", "V4", "V5" to indicate which DWARF version is the overall format to be emitted. Individual section version numbers will obey the standard for that overall DWARF version. .P The \f(CWextra\fP argument is supports a comma-separated list of options. Passing in a null pointer or an empty string is acceptable if no such options are needed or used. All-lowercase option names are reserved to the libdwarf implementation itself (specific implementations may want to use a leading upper-case letter for additional options). .P The available options are .DS "default_is_stmt", "address_size", "minimum_instruction_length", "maximum_operations_per_instruction", "opcode_base", "line_base", "line_range", "linetable_version", "segment_selector_size", and "segment_size". .DE .P For example, to set the line-table generation default value of is_stmt to 0 pass in .DS "default_is_stmt=0". .DE To also set the minimum_instruction_length used in calculating line table address-advance values to one one would pass in .DS "default_is_stmt=0,minimum_instruction_length=1". .DE It's appropriate to add .DS "opcode_base=13" .DE for DWARF3 through DWARF5. All these default to something, but the something depends on environment what macro names are set by the envirnment or a just constants which makes it difficult to alter these values. See pro_line.h for the use of line-table related constants (which will vary depending on the target ISA and ABI and compilers). .P The \f(CWerror\fP argument is set through the pointer to return specific error if \f(CWerror\fP is non-null and and there is an error. The error details will be passed back through this pointer argument. .H 3 "dwarf_pro_set_default_string_form()" .DS \f(CWint dwarf_pro_set_default_string_form( Dwarf_P_Debug *dbg, int desired_form, Dwarf_Error *error) \fP .DE .P The function \f(CWdwarf_pro_set_default_string_form()\fP sets the \f(CWDwarf_P_Debug\fP descriptor to favor one of the two allowed values: \f(CWDW_FORM_string\fP (the default) or \f(CWDW_FORM_strp\fP. .P When \f(CWDW_FORM_strp\fP is selected very short names will still use form \f(CWDW_FORM_string\fP . .P The function should be called immediately after a successful call to \f(CWdwarf_producer_init()\fP. .P Strings for \f(CWDW_FORM_strp\fP are not duplicated in the \f(CW.debug_str\fP section: each unique string appears exactly once. .P On success it returns \f(CWDW_DLV_OK\fP. On error it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_transform_to_disk_form_a()" .DS \f(CWint dwarf_transform_to_disk_form_a( Dwarf_P_Debug dbg, Dwarf_Signed *chunk_count_out, Dwarf_Error* error)\fP .DE New September 2016. The function \f(CWdwarf_transform_to_disk_form_a()\fP is new in September 2016. It produces the same result as \f(CWdwarf_transform_to_disk_form()\fP but returns the count through the new pointer argument \f(CWchunk_count_out\fP . .P On success it returns \f(CWDW_DLV_OK\fP and sets \f(CWchunk_count_out\fP to the number of chunks of section data to be accessed by \f(CWdwarf_get_section_bytes_a()\fP . .P It turns the DIE and other information specified for this \f(CWDwarf_P_Debug\fP into a stream of bytes for each section being produced. These byte streams can be retrieved from the \f(CWDwarf_P_Debug\fP by calls to \f(CWdwarf_get_section_bytes_a()\fP (see below). .P In case of error \f(CWdwarf_transform_to_disk_form_a()\fP returns \f(CWDW_DLV_ERROR\fP. .P The number of chunks is used to access data by \f(CWdwarf_get_section_bytes_a()\fP (see below) and the section data provided your code will insert into an object file or the like. Each section of the resulting object is typically many small chunks. Each chunk has a section index and a length as well as a pointer to a block of data (see \f(CWdwarf_get_section_bytes_a()\fP ). .P For each unique section being produced \f(CWdwarf_transform_to_disk_form_a()\fP calls the \f(CWDwarf_Callback_Func\fP exactly once. The callback provides the connection between Elf sections (which we presume is the object format to be emitted) and the \f(CWlibdwarf()\fP internal section numbering. .P For \f(CWDW_DLC_STREAM_RELOCATIONS\fP a call to \f(CWDwarf_Callback_Func\fP is made by libdwarf for each relocation section. Calls to \f(CWdwarf_get_section_bytes_a()\fP (see below). allow the \f(CWdwarf_transform_to_disk_form_a()\fP caller to get byte streams and write them to an object file as desired, just as with the other sections of the object being created. .P For \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP the user code should use \f(CWdwarf_get_relocation_info_count()\fP and \f(CWdwarf_get_relocation_info()\fP to retrieve the relocation info generated by \f(CWdwarf_transform_to_disk_form()\fP and do something with it. .P On failure it returns \f(CWDW_DLV_ERROR\fP and returns an error pointer through \f(CW*error\fP . .H 4 "dwarf_transform_to_disk_form()" .DS \f(CWDwarf_Signed dwarf_transform_to_disk_form( Dwarf_P_Debug dbg, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_transform_to_disk_form()\fP is the original call to generate output and a better interface is used by \f(CWdwarf_transform_to_disk_form_a()\fP though both do the same work and have the same meaning. .H 3 "dwarf_get_section_bytes_a()" .DS \f(CWint dwarf_get_section_bytes_a( Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Ptr *section_bytes, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_get_section_bytes_a() \fP must be called repetitively, with the index \f(CWdwarf_section\fP starting at 0 and continuing for the number of sections returned by \f(CWdwarf_transform_to_disk_form_a() \fP. .P It returns \f(CWDW_DLV_NO_ENTRY\fP to indicate that there are no more sections of \f(CWDwarf\fP information. Normally one would index through using the sectioncount from dwarf_transform_to_disk_form_a() so \f(CWDW_DLV_NO_ENTRY\fP would never be seen. For each successful return (return value \f(CWDW_DLV_OK\fP), \f(CW*section_bytes\fP points to \f(CW*length\fP bytes of data that are normally added to the output object in \f(CWElf\fP section \f(CW*elf_section\fP by the producer application. It is illegal to call these in any order other than 0 through N-1 where N is the number of dwarf sections returned by \f(CWdwarf_transform_to_disk_form() \fP. The elf section number is returned through the pointer \f(CWelf_section_index\fP. The \f(CWdwarf_section\fP number is ignored: the data is returned as if the caller passed in the correct dwarf_section numbers in the required sequence. .P In case of an error, \f(CWDW_DLV_ERROR\fP is returned and the \f(CWerror\fP argument is set to indicate the error. .P There is no requirement that the section bytes actually be written to an elf file. For example, consider the .debug_info section and its relocation section (the call back function would resulted in assigning 'section' numbers and the link field to tie these together (.rel.debug_info would have a link to .debug_info). One could examine the relocations, split the .debug_info data at relocation boundaries, emit byte streams (in hex) as assembler output, and at each relocation point, emit an assembler directive with a symbol name for the assembler. Examining the relocations is awkward though. It is much better to use \f(CWdwarf_get_section_relocation_info() \fP .P The memory space of the section byte stream is freed by the \f(CWdwarf_producer_finish_a() \fP call (or would be if the \f(CWdwarf_producer_finish_a() \fP was actually correct), along with all the other space in use with that Dwarf_P_Debug. Function created 01 December 2018. .H 4 "dwarf_get_section_bytes()" .DS \f(CWDwarf_Ptr dwarf_get_section_bytes( Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Error* error)\fP .DE Beginning in September 2016 one should call \f(CWdwarf_get_section_bytes_a()\fP in preference to \f(CWdwarf_get_section_bytes()\fP as the former makes checking for errors easier. .P The function \f(CWdwarf_get_section_bytes()\fP must be called repetitively, with the index \f(CWdwarf_section\fP starting at 0 and continuing for the number of sections returned by \f(CWdwarf_transform_to_disk_form() \fP. .P It returns \f(CWNULL\fP to indicate that there are no more sections of \f(CWDwarf\fP information. Normally one would index through using the sectioncount from dwarf_transform_to_disk_form_a() so \f(CWNULL\fP would never be seen. .P For each non-NULL return, the return value points to \f(CW*length\fP bytes of data that are normally added to the output object in \f(CWElf\fP section \f(CW*elf_section\fP by the producer application. The elf section number is returned through the pointer \f(CWelf_section_index\fP. .P In case of an error, \f(CWDW_DLV_BADADDR\fP is returned and the \f(CWerror\fP argument is set to indicate the error. .P It is illegal to call these in any order other than 0 through N-1 where N is the number of dwarf sections returned by \f(CWdwarf_transform_to_disk_form() \fP. The \f(CWdwarf_section\fP number is actually ignored: the data is returned as if the caller passed in the correct dwarf_section numbers in the required sequence. The \f(CWerror\fP argument is not used. .P There is no requirement that the section bytes actually be written to an elf file. For example, consider the .debug_info section and its relocation section (the call back function would resulted in assigning 'section' numbers and the link field to tie these together (.rel.debug_info would have a link to .debug_info). One could examine the relocations, split the .debug_info data at relocation boundaries, emit byte streams (in hex) as assembler output, and at each relocation point, emit an assembler directive with a symbol name for the assembler. Examining the relocations is awkward though. It is much better to use \f(CWdwarf_get_section_relocation_info() \fP .P The memory space of the section byte stream is freed by the \f(CWdwarf_producer_finish_a() \fP call (or would be if the \f(CWdwarf_producer_finish_a() \fP was actually correct), along with all the other space in use with that Dwarf_P_Debug. .H 3 "dwarf_get_relocation_info_count()" .DS \f(CWint dwarf_get_relocation_info_count( Dwarf_P_Debug dbg, Dwarf_Unsigned *count_of_relocation_sections , int *drd_buffer_version, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_get_relocation_info() \fP returns, through the pointer \f(CWcount_of_relocation_sections\fP, the number of times that \f(CWdwarf_get_relocation_info() \fP should be called. The function \f(CWdwarf_get_relocation_info() \fP returns DW_DLV_OK if the call was successful (the \f(CWcount_of_relocation_sections\fP is therefore meaningful, though \f(CWcount_of_relocation_sections\fP could be zero). \f(CW*drd_buffer_version\fP is the value 2. If the structure pointed to by the \f(CW*reldata_buffer\fP changes this number will change. The application should verify that the number is the version it understands (that it matches the value of DWARF_DRD_BUFFER_VERSION (from libdwarf.h)). The value 1 version was never used in production MIPS libdwarf (version 1 did exist in source). It returns DW_DLV_NO_ENTRY if \f(CWcount_of_relocation_sections\fP is not meaningful because \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP was not passed to the \f(CWdwarf_producer_init_c()\fP \f(CWdwarf_producer_init_b()\fP or \f(CWdwarf_producer_init()\fP call (whichever one was used). It returns DW_DLV_ERROR if there was an error, in which case \f(CWcount_of_relocation_sections\fP is not meaningful. .H 3 "dwarf_get_relocation_info()" .DS \f(CWint dwarf_get_relocation_info( Dwarf_P_Debug dbg, Dwarf_Signed *elf_section_index, Dwarf_Signed *elf_section_index_link, Dwarf_Unsigned *relocation_buffer_count, Dwarf_Relocation_Data *reldata_buffer, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_get_relocation_info() \fP should normally be called repetitively, for the number of relocation sections that \f(CWdwarf_get_relocation_info_count() \fP indicated exist. It returns \f(CWDW_DLV_OK\fP to indicate that valid values are returned through the pointer arguments. The \f(CWerror\fP argument is not set. It returns DW_DLV_NO_ENTRY if there are no entries (the count of relocation arrays is zero.). The \f(CWerror\fP argument is not set. It returns \f(CWDW_DLV_ERROR\fP if there is an error. Calling \f(CWdwarf_get_relocation_info() \fP more than the number of times indicated by \f(CWdwarf_get_relocation_info_count() \fP (without an intervening call to \f(CWdwarf_reset_section_bytes() \fP ) results in a return of \f(CWDW_DLV_ERROR\fP once past the valid count. The \f(CWerror\fP argument is set to indicate the error. Now consider the returned-through-pointer values for \f(CWDW_DLV_OK\fP . \f(CW*elf_section_index\fP is the 'elf section index' of the section implied by this group of relocations. \f(CW*elf_section_index_link\fP is the section index of the section that these relocations apply to. \f(CW*relocation_buffer_count\fP is the number of array entries of relocation information in the array pointed to by \f(CW*reldata_buffer\fP . \f(CW*reldata_buffer\fP points to an array of 'struct Dwarf_Relocation_Data_s' structures. The version 2 array information is as follows: .nf enum Dwarf_Rel_Type {dwarf_drt_none, dwarf_drt_data_reloc, dwarf_drt_segment_rel, dwarf_drt_first_of_length_pair, dwarf_drt_second_of_length_pair }; typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data; struct Dwarf_Relocation_Data_s { unsigned char drd_type; /* contains Dwarf_Rel_Type */ unsigned char drd_length; /* typically 4 or 8 */ Dwarf_Unsigned drd_offset; /* where the data to reloc is */ Dwarf_Unsigned drd_symbol_index; }; .fi The \f(CWDwarf_Rel_Type\fP enum is encoded (via casts if necessary) into the single unsigned char \f(CWdrd_type\fP field to control the space used for this information (keep the space to 1 byte). The unsigned char \f(CWdrd_length\fP field holds the size in bytes of the field to be relocated. So for elf32 object formats with 32 bit apps, \f(CWdrd_length\fP will be 4. For objects with MIPS -64 contents, \f(CWdrd_length\fP will be 8. For some dwarf 64 bit environments, such as ia64, \f(CWdrd_length\fP is 4 for some relocations (file offsets, for example) and 8 for others (run time addresses, for example). If \f(CWdrd_type\fP is \f(CWdwarf_drt_none\fP, this is an unused slot and it should be ignored. If \f(CWdrd_type\fP is \f(CWdwarf_drt_data_reloc\fP this is an ordinary relocation. The relocation type means either (R_MIPS_64) or (R_MIPS_32) (or the like for the particular ABI. \f(CWdrd_length\fP gives the length of the field to be relocated. \f(CWdrd_offset\fP is an offset (of the value to be relocated) in the section this relocation stuff is linked to. \f(CWdrd_symbol_index\fP is the symbol index (if elf symbol indices were provided) or the handle to arbitrary information (if that is what the caller passed in to the relocation-creating dwarf calls) of the symbol that the relocation is relative to. When \f(CWdrd_type\fP is \f(CWdwarf_drt_first_of_length_pair\fP the next data record will be \f(CWdrt_second_of_length_pair\fP and the \f(CWdrd_offset\fP of the two data records will match. The relevant 'offset' in the section this reloc applies to should contain a symbolic pair like .nf .in +4 .word second_symbol - first_symbol .in -4 .fi to generate a length. \f(CWdrd_length\fP gives the length of the field to be relocated. \f(CWdrt_segment_rel\fP means (R_MIPS_SCN_DISP) is the real relocation (R_MIPS_SCN_DISP applies to exception tables and this part may need further work). \f(CWdrd_length\fP gives the length of the field to be relocated. .P The memory space of the section byte stream is freed by the \f(CWdwarf_producer_finish_a() \fP call (or would be if the \f(CWdwarf_producer_finish_a() \fP was actually correct), along with all the other space in use with that Dwarf_P_Debug. .H 3 "dwarf_reset_section_bytes()" .DS \f(CWvoid dwarf_reset_section_bytes( Dwarf_P_Debug dbg )\fP .DE The function \f(CWdwarf_reset_section_bytes() \fP is used to reset the internal information so that \f(CWdwarf_get_section_bytes() \fP will begin (on the next call) at the initial dwarf section again. It also resets so that calls to \f(CWdwarf_get_relocation_info() \fP will begin again at the initial array of relocation information. Some dwarf producers need to be able to run through the \f(CWdwarf_get_section_bytes()\fP and/or the \f(CWdwarf_get_relocation_info()\fP calls more than once and this call makes additional passes possible. The set of Dwarf_Ptr values returned is identical to the set returned by the first pass. It is acceptable to call this before finishing a pass of \f(CWdwarf_get_section_bytes()\fP or \f(CWdwarf_get_relocation_info()\fP calls. No errors are possible as this just resets some internal pointers. It is unwise to call this before \f(CWdwarf_transform_to_disk_form() \fP has been called. .P .H 3 "dwarf_pro_get_string_stats()" .DS \f(CWint dwarf_pro_get_string_stats( Dwarf_P_Debug dbg, Dwarf_Unsigned * str_count, Dwarf_Unsigned * str_total_length, Dwarf_Unsigned * strp_count_debug_str, Dwarf_Unsigned * strp_len_debug_str, Dwarf_Unsigned * strp_reused_count, Dwarf_Unsigned * strp_reused_len, Dwarf_Error* error) \fP .DE If it returns \f(CWDW_DLV_OK\fP the function \f(CWdwarf_pro_get_string_stats()\fP returns information about how \f(CWDW_AT_name\fP etc strings were stored in the output object. The values suggest how much string duplication was detected in the DWARF being created. .P Call it after calling \f(CWdwarf_transform_to_disk_form()\fP and before calling \f(CWdwarf_producer_finish_a()\fP . It has no effect on the object being output. .P On error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP through the pointer. .H 3 "dwarf_producer_finish_a()" .DS \f(CWint dwarf_producer_finish_a( Dwarf_P_Debug dbg, Dwarf_Error* error) \fP .DE This is new in September 2016 and has the newer interface style, but is otherwise identical to \f(CWdwarf_producer_finish() \fP. .P The function \f(CWdwarf_producer_finish_a() \fP should be called after all the bytes of data have been copied somewhere (normally the bytes are written to disk). It frees all dynamic space allocated for \f(CWdbg\fP, include space for the structure pointed to by \f(CWdbg\fP. This should not be called till the data have been copied or written to disk or are no longer of interest. It returns \f(CWDW_DLV_OK\fP if successful. .P On error it returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP through the pointer. .H 4 "dwarf_producer_finish()" .DS \f(CWDwarf_Unsigned dwarf_producer_finish( Dwarf_P_Debug dbg, Dwarf_Error* error) \fP .DE This is the original interface. It works but calling \f(CWdwarf_producer_finish_a() \fP is preferred as it matches the latest libdwarf interface standard. .P The function \f(CWdwarf_producer_finish() \fP should be called after all the bytes of data have been copied somewhere (normally the bytes are written to disk). It frees all dynamic space allocated for \f(CWdbg\fP, include space for the structure pointed to by \f(CWdbg\fP. This should not be called till the data have been copied or written to disk or are no longer of interest. It returns zero if successful. .P On error it returns \f(CWDW_DLV_NOCOUNT\fP and sets \f(CWerror\fP through the pointer. .H 2 "Debugging Information Entry Creation" The functions in this section add new \f(CWDIE\fPs to the object, and also the relationships among the \f(CWDIE\fP to be specified by linking them up as parents, children, left or right siblings of each other. In addition, there is a function that marks the root of the graph thus created. .H 3 "dwarf_add_die_to_debug_a()" .DS \f(CWint dwarf_add_die_to_debug_a( Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_die_to_debug_a() \fP indicates to \f(CWLibdwarf\fP the root \f(CWDIE\fP of the \f(CWDIE\fP graph that has been built so far. It is intended to mark the compilation-unit \f(CWDIE\fP for the object represented by \f(CWdbg\fP. The root \f(CWDIE\fP is specified by \f(CWfirst_die\fP. .P It returns \f(CWDW_DLV_OK\fP on success, and \f(CWDW_DLV_error\fP on error. Function created 2016. .H 4 "dwarf_add_die_to_debug()" .DS \f(CWDwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error *error) \fP .DE This is the original form of the call. Use \f(CWdwarf_add_die_to_debug_a() instead. .P It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_new_die_a()" .DS \f(CWint dwarf_new_die_a( Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf_P_Die *die_out, Dwarf_Error *error) \fP .DE New September 2016. On success \f(CWdwarf_new_die_a() \fP returns DW_DLV_OK and creates a new \f(CWDIE\fP with its parent, child, left sibling, and right sibling \f(CWDIE\fPs specified by \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP, respectively. The new die is passed to the caller via the argument \f(CWdie_out() \fP . There is no requirement that all of these \f(CWDIE\fPs be specified, i.e. any of these descriptors may be \f(CWNULL\fP. If none is specified, this will be an isolated \f(CWDIE\fP. A \f(CWDIE\fP is transformed to disk form by \f(CWdwarf_transform_to_disk_form() \fP only if there is a path from the \f(CWDIE\fP specified by \f(CWdwarf_add_die_to_debug\fP to it. .P The value of \f(CWnew_tag\fP is the tag which is given to the new \f(CWDIE\fP. \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP are pointers to establish links to existing \f(CWDIE\fPs. Only one of \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP may be non-NULL. If \f(CWparent\fP (\f(CWchild\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. If \f(CWleft_sibling\fP (\f(CWright_sibling\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. .P To add attributes to the new \f(CWDIE\fP, use the \f(CWAttribute Creation\fP functions defined in the next section. .P On failure \f(CWdwarf_new_die_a() \fP returns DW_DLV_ERROR and sets \f(CW*error\fP. Function created 01 December 2018. .H 4 "dwarf_new_die()" .DS \f(CWDwarf_P_Die dwarf_new_die( Dwarf_P_Debug dbg, Dwarf_Tag new_tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) \fP .DE This is the original form of the function and users should switch to calling \f(CWdwarf_new_die_a()\fP instead to use the newer interface. See \f(CWdwarf_new_die_a()\fP for details (both functions do the same thing). .H 3 "dwarf_die_link_a()" .DS \f(CWint dwarf_die_link_a( Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left-sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) \fP .DE New September 2016. On success the function \f(CWdwarf_die_link_a() \fP returns \f(CWDW_DLV_OK\fP and links an existing \f(CWDIE\fP described by the given \f(CWdie\fP to other existing \f(CWDIE\fPs. The given \f(CWdie\fP can be linked to a parent \f(CWDIE\fP, a child \f(CWDIE\fP, a left sibling \f(CWDIE\fP, or a right sibling \f(CWDIE\fP by specifying non-NULL \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP \f(CWDwarf_P_Die\fP descriptors. Only one of \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and \f(CWright_sibling\fP may be non-NULL. If \f(CWparent\fP (\f(CWchild\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. If \f(CWleft_sibling\fP (\f(CWright_sibling\fP) is given, the \f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP pointed to. Non-NULL links overwrite the corresponding links the given \f(CWdie\fP may have had before the call to \f(CWdwarf_die_link_a() \fP. If there is an error \f(CWdwarf_die_link_a() \fP returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP with the specific applicable error code. .H 4 "dwarf_die_link()" .DS \f(CWDwarf_P_Die dwarf_die_link( Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left-sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) \fP .DE This is the original function to link \f(CWDIEs\fP together. The function does the same thing as \f(CWdwarf_die_link_a()\fP but. the newer function is simpler to work with. .H 2 "DIE Markers" DIE markers provide a way for a producer to extract DIE offsets from DIE generation. The markers do not influence the generation of DWARF, they simply allow a producer to extract .debug_info offsets for whatever purpose the producer finds useful (for example, a producer might want some unique other section unknown to libdwarf to know a particular DIE offset). One marks one or more DIEs as desired any time before calling \f(CWdwarf_transform_to_disk_form()\fP. After calling \f(CWdwarf_transform_to_disk_form()\fP call \f(CWdwarf_get_die_markers()\fP which has the offsets where the marked DIEs were written in the generated .debug_info data. .H 3 "dwarf_add_die_marker_a()" .DS \f(CWint dwarf_add_die_marker_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error *error) \fP .DE This is preferred over \f(CWdwarf_add_die_marker()\fP. The function \f(CWdwarf_add_die_marker_a()\fP writes the value \f(CWmarker\fP to the \f(CWDIE\fP descriptor given by \f(CWdie\fP. Passing in a marker of 0 means 'there is no marker' (zero is the default in DIEs). It returns \f(CWDW_DLV_OK\fP, on success. On error it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_die_marker()" .DS \f(CWDwarf_Unsigned dwarf_add_die_marker( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error *error) \fP .DE This is preferred over \f(CWdwarf_add_die_marker()\fP. The function \f(CWdwarf_add_die_marker_a()\fP writes the value \f(CWmarker\fP to the \f(CWDIE\fP descriptor given by \f(CWdie\fP. Passing in a marker of 0 means 'there is no marker' (zero is the default in DIEs). It returns \f(CW0\fP, on success. On error it returns \f(CWDW_DLV_NOCOUNT\fP. .H 4 "dwarf_get_die_marker_a()" .DS \f(CWint dwarf_get_die_marker_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned *marker, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_marker() \fP returns the current marker value for this DIE through the pointer \f(CWmarker\fP. A marker value of 0 means 'no marker was set'. It returns \f(CWDW_DLV_OK\fP, on success. On error it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_get_die_marker()" .DS \f(CWDwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned *marker, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_marker() \fP returns the current marker value for this DIE through the pointer \f(CWmarker\fP. A marker value of 0 means 'no marker was set'. It returns \f(CW0\fP, on success. On error it returns \f(CWDW_DLV_NOCOUNT\fP. .H 3 "dwarf_get_die_markers_a()" .DS \f(CWint dwarf_get_die_markers_a( Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, Dwarf_Unsigned *marker_count, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_markers_a()\fP returns a pointer to an array of \f(CWDwarf_P_Marker\fP pointers to \f(CWstruct Dwarf_P_Marker_s\fP structures through the pointer \f(CWmarker_list\fP. The array length is returned through the pointer \f(CWmarker_count\fP. The call is only meaningful after a call to \f(CWdwarf_transform_to_disk_form()\fP as the transform call creates the \f(CWstruct Dwarf_P_Marker_s\fP structures, one for each DIE generated for .debug_info (but only for DIEs that had a non-zero marker value). The field \f(CWma_offset\fP in the structure is set during generation of the .debug_info byte stream. The field \f(CWma_marker\fP in the structure is a copy of the DIE marker of the DIE given that offset. It returns \f(CWDW_DLV_OK\fP, on success. On error it returns \f(CWDW_DLV_ERROR\fP (if there are no markers it returns \f(CWDW_DLV_ERROR\fP). .H 4 "dwarf_get_die_markers()" .DS \f(CWDwarf_Signed dwarf_get_die_markers( Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, Dwarf_Unsigned *marker_count, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_get_die_marker()\fP returns a pointer to an array of \f(CWDwarf_P_Marker\fP pointers to \f(CWstruct Dwarf_P_Marker_s\fP structures through the pointer \f(CWmarker_list\fP. The array length is returned through the pointer \f(CWmarker_count\fP. The call is only meaningful after a call to \f(CWdwarf_transform_to_disk_form()\fP as the transform call creates the \f(CWstruct Dwarf_P_Marker_s\fP structures, one for each DIE generated for .debug_info (but only for DIEs that had a non-zero marker value). The field \f(CWma_offset\fP in the structure is set during generation of the .debug_info byte stream. The field \f(CWma_marker\fP in the structure is a copy of the DIE marker of the DIE given that offset. It returns \f(CW0\fP, on success. On error it returns \f(CWDW_DLV_BADADDR\fP (if there are no markers it returns \f(CWDW_DLV_BADADDR\fP). .H 2 "Attribute Creation" The functions in this section add attributes to a \f(CWDIE\fP. These functions return a \f(CWDwarf_P_Attribute\fP descriptor that represents the attribute added to the given \f(CWDIE\fP. In most cases the return value is only useful to determine if an error occurred. Some of the attributes have values that are relocatable. They need a symbol with respect to which the linker will perform relocation. This symbol is specified by means of an index into the Elf symbol table for the object (of course, the symbol index can be more general than an index). .H 3 "dwarf_add_AT_location_expr_a()" .DS \f(CWint dwarf_add_AT_location_expr_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_P_Attr *attr_out, Dwarf_Error *error) \fP .DE On success the function \f(CWdwarf_add_AT_location_expr()\fP returns \f(CWDW_DLV_OK\fP and adds the attribute specified by \f(CWattr\fP to the \f(CWDIE\fP descriptor given by \f(CWownerdie\fP. The new attribute is passed back to the caller through the pointer \f(CWattr_out\fP. The attribute should be one that has a location expression as its value. The location expression that is the value is represented by the \f(CWDwarf_P_Expr\fP descriptor \f(CWloc_expr\fP. On error it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_AT_location_expr()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_location_expr( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_location_expr()\fP adds the attribute specified by \f(CWattr\fP to the \f(CWDIE\fP descriptor given by \f(CWownerdie\fP. The attribute should be one that has a location expression as its value. The location expression that is the value is represented by the \f(CWDwarf_P_Expr\fP descriptor \f(CWloc_expr\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute given, on success. On error it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_name_a()" .DS \f(CWint dwarf_add_AT_name_a( Dwarf_P_Die ownerdie, char *name, Dwarf_P_Attribute * attr_out, Dwarf_Error *error) \fP .DE New November 2018, a better alternative to \f(CWdwarf_add_AT_name()\fP. The function \f(CWdwarf_add_AT_name_a() \fP adds the string specified by \f(CWname\fP as the value of the \f(CWDW_AT_name\fP attribute for the given \f(CWDIE\fP, \f(CWownerdie\fP. It returns DW_DLV_OK on success and assignes the new attribute descriptor to \f(CW*attr_out\fP. On error it returns \f(CWDW_DLV_ERROR\fP and does not set \f(CW*attr_out\fP. .H 4 "dwarf_add_AT_name()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_name( Dwarf_P_Die ownerdie, char *name, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_name()\fP adds the string specified by \f(CWname\fP as the value of the \f(CWDW_AT_name\fP attribute for the given \f(CWDIE\fP, \f(CWownerdie\fP. It returns the \f(CWDwarf_P_attribute\fP descriptor for the \f(CWDW_AT_name\fP attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_comp_dir_a()" .DS \f(CWint dwarf_add_AT_comp_dir_a( Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_comp_dir_a\fP adds the string given by \f(CWcurrent_working_directory\fP as the value of the \f(CWDW_AT_comp_dir\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_out\fP to the new attribute. .P On error, it returns \f(CWDW_DLV_ERROR\fP and does not touch \f(CWattr_out\fP . .H 4 "dwarf_add_AT_comp_dir()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_comp_dir( Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_Error *error) \fP .DE The function \f(CWint dwarf_add_AT_comp_dir\fP adds the string given by \f(CWcurrent_working_directory\fP as the value of the \f(CWDW_AT_comp_dir\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. It returns the \f(CWDwarf_P_Attribute\fP for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_producer_a()" .DS \f(CWint dwarf_add_AT_producer_a( Dwarf_P_Die ownerdie, char *producer_string, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_producer()\fP adds the string given by \f(CWproducer_string\fP as the value of the \f(CWDW_AT_producer\fP attribute for the \f(CWDIE\fP given by \f(CWownerdie\fP. On success it returns \f(CWDW_DLV_OK\fP and returns the new attribute descriptor representing this attribute through the pointer argument \f(CWattr_out\fP. On error, it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_AT_producer()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_producer( Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_producer() \fP adds the string given by \f(CWproducer_string\fP as the value of the \f(CWDW_AT_producer\fP attribute for the \f(CWDIE\fP given by \f(CWownerdie\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor representing this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_any_value_sleb_a()" .DS \f(CWint dwarf_add_AT_any_value_sleb_a( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *out_attr, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_sleb_a()\fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_sdata\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*out_attr\fP to the created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. The function was created 01 December 2018. .H 4 "dwarf_add_AT_any_value_sleb()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_any_value_sleb( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_sleb() \fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_sdata\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. The function was created 13 August 2013. .H 3 "dwarf_add_AT_const_value_signedint_a()" .DS \f(CWint dwarf_add_AT_const_value_signedint_a( Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_signedint_a\fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. On success it returns \f(CWDW_DLV_OK\fP and sets *attr_out to the created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_AT_const_value_signedint()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_const_value_signedint( Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_signedint\fP adds the given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP (signed leb number) and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_implicit_const()" .DS \f(CWint dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *outattr, Dwarf_Error * error); \fP .DE The function \f(CWdwarf_add_AT_implicit_const\fP creates a new attribute and adds the signed value to the abbreviation entry for this new attribute and attaches the new attribute to the DIE passed in. .P The new attribute has \f(CWattrnum\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The \f(CWform\fP in the generated attribute is \f(CWDW_FORM_implicit_const.\fP The \f(CWsigned_value\fP argument will be inserted in the abbreviation table as a signed leb value. .P For a successfull call the function returns \f(CWDW_DLV_OK.\fP and a pointer to the created argument is returned through the pointer \f(CWoutaddr.\fP .P In case of error the function returns \f(CWDW_DLV_ERROR\fP and no attribute is created. .H 3 "dwarf_add_AT_any_value_uleb_a()" .DS \f(CWint dwarf_add_AT_any_value_uleb_a( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_uleb_a\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWattrnum\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_udata\fP (unsigned leb number) and the attribute is \f(CWattrnum\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_out\fP to the newly created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. The function was created 01 December 2018. .H 4 "dwarf_add_AT_any_value_uleb()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_any_value_uleb( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_any_value_uleb\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWattrnum\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_udata\fP (unsigned leb number) and the attribute is \f(CWattrnum\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. The function was created 13 August 2013. .H 3 "dwarf_add_AT_const_value_unsignedint_a()" .DS \f(CWint dwarf_add_AT_const_value_unsignedint_a( Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_const_value_unsignedint_a\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. On success it returns \f(CWDW_DLV_OK\fP. and sets \f(CW*attr_out\fP to the newly created attribute. On error, it returns \f(CWDW_DLV_ERROR\fP. Created 01 December 2018. .H 4 "dwarf_add_AT_const_value_unsignedint()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_unsignedint\fP adds the given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. The FORM of the output value is \f(CWDW_FORM_data\fP and the attribute will be \f(CWDW_AT_const_value\fP. With this interface and output, there is no way for consumers to know from the FORM that the value is signed. It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_const_value_string_a()" .DS \f(CWint dwarf_add_AT_const_value_string_a( Dwarf_P_Die ownerdie, char *string_value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_string_afP adds the string value given by \f(CWstring_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. .P On success it returns \f(CWDW_DLV_OK\fP \f(CW*attr_out\fP to a newly created attribute. .P On error, it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_const_value_string()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_const_value_string( Dwarf_P_Die ownerdie, char *string_value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_const_value_stringfP adds the string value given by \f(CWstring_value\fP as the value of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP. .P It returns the \f(CWDwarf_P_Attribute\fP descriptor for this attribute on success. On error, it returns \f(CWDW_DLV_BADADDR\fP. .H 3 "dwarf_add_AT_targ_address_c()" .DS \f(CWint dwarf_add_AT_targ_address_c( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_targ_address_cfP is identical to \f(CWdwarf_add_AT_targ_address_bfP except for the return value and an added argument. Because this is type-safe use this instead of \f(CWdwarf_add_AT_targ_address_bfP. .P \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success the function returns \f(CWDW_DLV_OK\fP \f(CWDwarf_P_Attribute\fP and \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. On failure it returns \f(CWDW_DLV_ERROR\fP. Do not use this function for attr \f(CWDW_AT_high_pc\fP if the value to be recorded is an offset (not a pc) [ use \f(CWdwarf_add_AT_unsigned_const_afP or \f(CWdwarf_add_AT_any_value_uleb_afP instead]. On failure the function returns \f(CWDW_DLV_ERROR\fP Function created 01 December 2018. .H 4 "dwarf_add_AT_targ_address()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_targ_address( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_targ_address\fP adds an attribute that belongs to the "address" class to the die specified by \f(CWownerdie\fP. The attribute is specified by \f(CWattr\fP, and the object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The relocatable address that is the value of the attribute is specified by \f(CWpc_value\fP. The symbol to be used for relocation is specified by the \f(CWsym_index\fP, which is the index of the symbol in the Elf symbol table. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 4 "dwarf_add_AT_targ_address_b()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_targ_address_b( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) \fP .DE Please use \f(CWdwarf_add_AT_targ_address_c\fP instead of \f(CWdwarf_add_AT_targ_address_b\fP or \f(CWdwarf_add_AT_targ_address\fP when is is convient for you. The function \f(CWdwarf_add_AT_targ_address_b\fP is identical to \f(CWdwarf_add_AT_targ_address\fP except that \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for attr \f(CWDW_AT_high_pc\fP if the value to be recorded is an offset (not a pc) [ use \f(CWdwarf_add_AT_unsigned_const_a\fP or \f(CWdwarf_add_AT_any_value_uleb_a\fP instead]. .H 3 "dwarf_add_AT_block_a()" .DS \f(CWint dwarf_add_AT_block_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_P_Attribute* attr_out, Dwarf_Error *error) .DE On success this returns \f(CWDW_DLV_OK\fP an attribute with a \f(CWDW_FORM_block\fP instance (does not create \f(CWDW_FORM_block1\fP, \f(CWDW_FORM_block2\fP, or \f(CWDW_FORM_block4\fP at present) and returns a pointer to the new attribute through the pointer \f(CWattr_out\fP. On failure this returns \f(CWDW_DLV_ERROR\fP /* New December 2018. Preferred version. */ .H 4 "dwarf_add_AT_block()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_block( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_Error *error) .DE On success this returns an attribute pointer just as \f(CWdwarf_add_AT_block_a\fP does and returns the attribute. On failure it returns \f(CWDW_DLV_BADADDR\fP. jjk .H 3 "dwarf_add_AT_dataref_a()" .DS \f(CWint dwarf_add_AT_dataref_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_b\fP but results in a different FORM (results in DW_FORM_data4 or DW_FORM_data8). Useful for adding relocatable addresses in location lists. \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success it returns \f(CWDW_DLV_OK\fP and the \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for \f(CWDW_AT_high_pc\fP, use \f(CWdwarf_add_AT_unsigned_const\fP or \f(CWdwarf_add_AT_any_value_uleb\fP [ if the value to be recorded is an offset of \f(CWDW_AT_low_pc\fP] or \f(CWdwarf_add_AT_targ_address_b\fP [ if the value to be recorded is an address]. Function created 01 December 2018. .H 4 "dwarf_add_AT_dataref()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_b\fP but results in a different FORM (results in DW_FORM_data4 or DW_FORM_data8). Useful for adding relocatable addresses in location lists. \f(CWsym_index\fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for \f(CWDW_AT_high_pc\fP, use \f(CWdwarf_add_AT_unsigned_const\fP or \f(CWdwarf_add_AT_any_value_uleb\fP [ if the value to be recorded is an offset of \f(CWDW_AT_low_pc\fP] or \f(CWdwarf_add_AT_targ_address_b\fP [ if the value to be recorded is an address]. .H 3 "dwarf_add_AT_ref_address_a" .DS \f(CWint dwarf_add_AT_ref_address_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_c\fP but results in a different FORM (results in \f(CWDW_FORM_ref_addr\fP being generated). Useful for \f(CWDW_AT_type\fP and \f(CWDW_AT_import\fP attributes. \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index() \fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success the function returns \f(CWDW_DLV_OK\fP and \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. On failure the function returns \f(CWDW_DLV_ERROR\fP. Do not use this function for \f(CWDW_AT_high_pc\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_ref_address()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_ref_address( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) \fP .DE This is very similar to \f(CWdwarf_add_AT_targ_address_b() \fP but results in a different FORM (results in \f(CWDW_FORM_ref_addr\fP being generated). Useful for \f(CWDW_AT_type\fP and \f(CWDW_AT_import\fP attributes. \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index()\fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The \f(CWpc_value\fP is put into the section stream output and the \f(CWsym_index\fP is applied to the relocation information. Do not use this function for \f(CWDW_AT_high_pc\fP. .H 3 "dwarf_add_AT_unsigned_const_a()" .DS \f(CWint dwarf_add_AT_unsigned_const_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_P_Attribute *attr_out, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_unsigned_const_a()\fP adds an attribute with a \f(CWDwarf_Unsigned\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. The FORM of the output will be one of the \f(CWDW_FORM_data\fP forms. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*attr_out\fP to the newly created attribute. It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_AT_unsigned_const()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_unsigned_const( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_unsigned_const()\fP adds an attribute with a \f(CWDwarf_Unsigned\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. The FORM of the output will be one of the \f(CWDW_FORM_data\fP forms. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_signed_const_a()" .DS \f(CWint dwarf_add_AT_signed_const_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_P_Attribute *out_addr, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_signed_const_a()\fP adds an attribute with a \f(CWDwarf_Signed\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*out_addr\fP with a pointer to the new attribute. On error it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_signed_const()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_signed_const( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error *error) \fP .DE The function \f(CWdwarf_add_AT_signed_const()\fP adds an attribute with a \f(CWDwarf_Signed\fP value belonging to the "constant" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_reference_c()" .DS \f(CWint dwarf_add_AT_reference_c( Dwarf_P_Debug dbg, Dwarf_Half attr, Dwarf_P_Die ownerdie, Dwarf_P_Die otherdie, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_reference_c()\fP is the same as \f(CWdwarf_add_AT_reference_b()\fP except that \f(CWdwarf_add_AT_reference_c()\fP returns a simple error code. \f(CWdwarf_add_AT_reference_c()\fP accepts a NULL \f(CWotherdie\fP with the assumption that \f(CWdwarf_fixup_AT_reference_die()\fP will be called by user code to fill in the missing \f(CWotherdie\fP before the DIEs are transformed to disk form. On success it returns \f(CWDW_DLV_OK\fP and returns a pointer to the new attribute through \f(CW*attr_out\fP. On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_reference()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_reference( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_reference()\fP adds an attribute with a value that is a reference to another \f(CWDIE\fP in the same compilation-unit to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and the other \f(CWDIE\fP being referred to is specified by \f(CWotherdie\fP. The FORM of the output will be one of the \f(CWDW_FORM_data\fP forms. This cannot generate DW_FORM_ref_addr references to \f(CWDIE\fPs in other compilation units. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 4 "dwarf_add_AT_reference_b()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_reference_b( Dwarf_P_Debug dbg, Dwarf_Half attr, Dwarf_P_Die ownerdie, Dwarf_P_Die otherdie, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_reference_b()\fP is the same as \f(CWdwarf_add_AT_reference()\fP except that \f(CWdwarf_add_AT_reference_b()\fP accepts a NULL \f(CWotherdie\fP with the assumption that \f(CWdwarf_fixup_AT_reference_die()\fP will be called by user code to fill in the missing \f(CWotherdie\fP before the DIEs are transformed to disk form. .H 3 "dwarf_fixup_AT_reference_die()" .DS \f(CWint dwarf_fixup_AT_reference_die( Dwarf_Half attrnum, Dwarf_P_Die ownerdie, Dwarf_P_Die otherdie, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_fixup_AT_reference_die()\fP is provided to set the NULL \f(CWotherdie\fP that \f(CWdwarf_add_AT_reference_c()\fP allows to the reference target DIE. This must be done before transforming to disk form. \f(CWattrnum()\fP should be the attribute number of the attribute of \fCWownerdie\fP which is to be updated. For example, if a local forward reference was in a \fCWDW_AT_sibling\fP attribute in ownerdie, pass the value \fCWDW_AT_sibling\fP as attrnum. .P Since no attribute number can appear more than once on a given DIE the \f(CWattrnum()\fP suffices to uniquely identify which attribute of \fCWownerdie\fP to update .P It returns either \f(CWDW_DLV_OK\fP (on success) or \f(CWDW_DLV_ERROR\fP (on error). Calling this on an attribute where \f(CWotherdie\fP was already set is an error. New 22 October, 2013. .H 3 "dwarf_add_AT_flag_a()" .DS \f(CWint dwarf_add_AT_flag_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_flag_a()\fP adds an attribute with a \f(CWDwarf_Small\fP value belonging to the "flag" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWflag\fP. On success it returns \f(CWDW_DLV_OK\fP and passes back a pointer to the new attribute through \f(CW*attr_out\fP. On error it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_flag()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_flag( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_flag()\fP adds an attribute with a \f(CWDwarf_Small\fP value belonging to the "flag" class, to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is specified by \f(CWflag\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_string_a()" .DS \f(CWint dwarf_add_AT_string_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_P_Attribute *attr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_string()\fP adds an attribute with a value that is a character string to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is pointed to by \f(CWstring\fP. On success it returns \f(CWDW_DLV_OK\fP and set \f(CW*attr_out\fP with a pointer to the new attribute. On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_string()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_string( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_AT_string()\fP adds an attribute with a value that is a character string to the \f(CWDIE\fP specified by \f(CWownerdie\fP. The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP. The attribute is specified by \f(CWattr\fP, and its value is pointed to by \f(CWstring\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_with_ref_sig8_a()" .DS \f(CWint dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_P_Attribute *attr_out, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_add_AT_with_sig8_a\fP creates an attribute containing the 8-byte signature block pointed to by \f(CWsig8_in\fP \f(CWDW_FORM_ref_sig8\fP with form \f(CWDW_FORM_ref_sig8\fP. On success it returns \f(CWDW_DLV_OK\fP and sets *attr_out \f(CW*attr_out\fP to the newly created attribute. On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_AT_with_ref_sig8()" .DS \f(CWDwarf_P_Attribute dwarf_add_AT_with_ref_sig8( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_Error * error)\fP .DE The function \f(CWdwarf_add_AT_with_sig8\fP creates an attribute containing the 8-byte signature block pointed to by \f(CWsig8_in\fP \f(CWDW_FORM_ref_sig8\fP with form \f(CWDW_FORM_ref_sig8\fP. It returns the \f(CWDwarf_P_Attribute\fP descriptor for the new attribute on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_AT_data16()" .DS \f(CWint dwarf_add_AT_data16( Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Form_Data16 *ptr_to_val, Dwarf_P_Attribute * attr_out, Dwarf_Error * error)\fP .DE The DWARF5 standard refers to 16 byte as simply data. It is up to the eventual reader of the DWARF entry this call creates to understand what the sixteen bytes mean. .P On success it returns \f(CWDW_DLV_OK\fP and returns the new attribute through the pointer \f(CWattr_out\fP. On failure it returns \f(CWDW_DLV_ERROR\fP. .H 3 "dwarf_compress_integer_block()" .DS \f(CWvoid* dwarf_compress_integer_block( Dwarf_P_Debug dbg, Dwarf_Bool unit_is_signed, Dwarf_Small unit_length_in_bits, void* input_block, Dwarf_Unsigned input_length_in_units, Dwarf_Unsigned* output_length_in_bytes_ptr, Dwarf_Error* error) .DE This was created in 2016 in support of the attribute DW_AT_SUN_func_offsets but the particular DWARF project involving this seems to have died. We have not provided a way to create the attribute. So this is pretty useless at this time. .H 2 "Expression Creation" The following functions are used to convert location expressions into blocks so that attributes with values that are location expressions can store their values as a \f(CWDW_FORM_blockn\fP value. This is for both .debug_info and .debug_loc expression blocks. To create an expression, first call \f(CWdwarf_new_expr()\fP to get a \f(CWDwarf_P_Expr\fP descriptor that can be used to build up the block containing the location expression. Then insert the parts of the expression in prefix order (exactly the order they would be interpreted in in an expression interpreter). The bytes of the expression are then built-up as specified by the user. .H 3 "dwarf_new_expr_a()" .DS \f(CWint dwarf_new_expr_a( Dwarf_P_Debug dbg, Dwarf_P_Expr *expr_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_new_expra()\fP creates a new expression area in which a location expression stream can be created. On success it returns \f(CWDW_DLV_OK\fP and returns a Dwarf_Expr \f(CWDwarf_Expr\fP through the pointer which can be used to add operators a to build up a location expression. On failure it returns \f(CWDW_DLV_OK\fP. Function created 01 December 2018. .H 4 "dwarf_new_expr()" .DS \f(CWDwarf_P_Expr dwarf_new_expr( Dwarf_P_Debug dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_new_expr()\fP creates a new expression area in which a location expression stream can be created. It returns a \f(CWDwarf_P_Expr\fP descriptor that can be used to add operators to build up a location expression. It returns \f(CWNULL\fP on error. .H 3 "dwarf_add_expr_gen_a()" .DS \f(CWint dwarf_add_expr_gen_a( Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Unsigned *stream_length_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_gen()\fP takes an operator specified by \f(CWopcode\fP, along with up to 2 operands specified by \f(CWval1\fP, and \f(CWval2\fP, converts it into the \f(CWDwarf\fP representation and appends the bytes to the byte stream being assembled for the location expression represented by \f(CWexpr\fP. The first operand, if present, to \f(CWopcode\fP is in \f(CWval1\fP, and the second operand, if present, is in \f(CWval2\fP. Both the operands may actually be signed or unsigned depending on \f(CWopcode\fP. On success it returns \f(CWDW_DLV_OK\fP and sets \f(CW*stream_length_out\fP to the number of bytes in the byte stream for \f(CWexpr\fP currently generated, i.e. after the addition of \f(CWopcode\fP. It returns \f(CWDW_DLV_ERROR\fP on error. The function \f(CWdwarf_add_expr_gen_a()\fP works for all opcodes except those that have a target address as an operand. This is because the function cannot not set up a relocation record that is needed when target addresses are involved. Function created 01 December 2018. .H 4 "dwarf_add_expr_gen()" .DS \f(CWDwarf_Unsigned dwarf_add_expr_gen( Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_gen()\fP takes an operator specified by \f(CWopcode\fP, along with up to 2 operands specified by \f(CWval1\fP, and \f(CWval2\fP, converts it into the \f(CWDwarf\fP representation and appends the bytes to the byte stream being assembled for the location expression represented by \f(CWexpr\fP. The first operand, if present, to \f(CWopcode\fP is in \f(CWval1\fP, and the second operand, if present, is in \f(CWval2\fP. Both the operands may actually be signed or unsigned depending on \f(CWopcode\fP. It returns the number of bytes in the byte stream for \f(CWexpr\fP currently generated, i.e. after the addition of \f(CWopcode\fP. It returns \f(CWDW_DLV_NOCOUNT\fP on error. The function \f(CWdwarf_add_expr_gen()\fP works for all opcodes except those that have a target address as an operand. This is because the function cannot not set up a relocation record that is needed when target addresses are involved. .H 3 "dwarf_add_expr_addr_c()" .DS \f(CWint dwarf_add_expr_addr_c( Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Unsigned sym_index, Dwarf_Unsigned *stream_length_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_addr_c()\fP is identical to \f(CWdwarf_add_expr_addr_b()\fP except that \f(CWdwarf_add_expr_addr_c()\fP returns a simple integer code. .P \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index() \fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. On success the function returns \f(CWDW_DLV_OK\fP and sets \f(CW*stream_length_out\fP to to the total length of the expression stream in \f(CWexpr\fP. On failure the function returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_expr_addr()" .DS \f(CWDwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Signed sym_index, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_addr()\fP is used to add the \f(CWDW_OP_addr\fP opcode to the location expression represented by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP. The value of the relocatable address is given by \f(CWaddress\fP. The symbol to be used for relocation is given by \f(CWsym_index\fP, which is the index of the symbol in the Elf symbol table. It returns the number of bytes in the byte stream for \f(CWexpr\fP currently generated, i.e. after the addition of the \f(CWDW_OP_addr\fP operator. It returns \f(CWDW_DLV_NOCOUNT\fP on error. .H 4 "dwarf_add_expr_addr_b()" .DS \f(CWDwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Unsigned sym_index, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_expr_addr_b()\fP is identical to \f(CWdwarf_add_expr_addr()\fP except that \f(CWsym_index() \fP is guaranteed to be large enough that it can contain a pointer to arbitrary data (so the caller can pass in a real elf symbol index, an arbitrary number, or a pointer to arbitrary data). The ability to pass in a pointer through \f(CWsym_index() \fP is only usable with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. .H 3 "dwarf_expr_current_offset_a()" .DS \f(CWint dwarf_expr_current_offset_a( Dwarf_P_Expr expr, Dwarf_Unsigned *stream_offset_out, Dwarf_Error *error)\fP .DE On success the function \f(CWdwarf_expr_current_offset_a()\fP returns \f(CWDW_DLV_OK\fP and sets \f(CW*stream_offset_out\fP to the current length in bytes of the expression stream. On failure the function returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_expr_current_offset()" .DS \f(CWDwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr expr, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_expr_current_offset()\fP returns the number of bytes currently in the byte stream for the location expression represented by the given \fCW(Dwarf_P_Expr\fP descriptor, \f(CWexpr\fP. It returns \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_expr_into_block_a()" .DS \f(CWint dwarf_expr_into_block_a( Dwarf_P_Expr expr, Dwarf_Unsigned *length, Dwarf_Small **address, Dwarf_Error *error)\fP .DE On success the function \f(CWdwarf_expr_into_block_a()\fP returns \f(CWDW_DLV_OK\fP and sets the length of the \f(CWexpr\fP expression into \f(CW*length\fP and sets the value of a pointer into memory where the expression is currently held in the executing libdwarf into \f(CW*address\fP. .P On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_expr_into_block()" .DS \f(CWDwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr expr, Dwarf_Unsigned *length, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_expr_into_block()\fP returns the address of the start of the byte stream generated for the location expression represented by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP. The address is a pointer into the current application memory known to libdwarf (stored in a Dwarf_Addr). The length of the byte stream is returned in the location pointed to by \f(CWlength\fP. It returns f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_expr_reset()" .DS \f(CWvoid dwarf_expr_reset( Dwarf_P_Expr expr, Dwarf_Error *error)\fP .DE This resets the expression content of \f(CWexpr()\fP to be empty. .H 2 "Line Number Operations" These are operations on the .debug_line section. They provide information about instructions in the program and the source lines the instruction come from. Typically, code is generated in contiguous blocks, which may then be relocated as contiguous blocks. To make the provision of relocation information more efficient, the information is recorded in such a manner that only the address of the start of the block needs to be relocated. This is done by providing the address of the first instruction in a block using the function \f(CWdwarf_lne_set_address()\fP. Information about the instructions in the block are then added using the function \f(CWdwarf_add_line_entry()\fP, which specifies offsets from the address of the first instruction. The end of a contiguous block is indicated by calling the function \f(CWdwarf_lne_end_sequence()\fP. .P Line number operations do not support \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. .H 3 "dwarf_add_line_entry_c()" .DS \f(CWint dwarf_add_line_entry_c( Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Bool is_epilogue_begin, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)\fP .DE This is the same as \f(CWdwarf_add_line_entry_b()\fP except that it returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_line_entry_b()" .DS \f(CWDwarf_Unsigned dwarf_add_line_entry_b( Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Bool is_epilogue_begin, Dwarf_Bool is_prologue_end, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_line_entry_b()\fP adds an entry to the section containing information about source lines. It specifies in \f(CWcode_offset\fP, the address of this line. The function subtracts \f(CWcode_offset\fP from the value given as the address of a previous line call to compute an offset, and the offset is what is recorded in the line instructions so no relocation will be needed on the line instruction generated. .P The source file that gave rise to the instruction is specified by \f(CWfile_index\fP, the source line number is specified by \f(CWlineno\fP, and the source column number is specified by \f(CWcolumn_number\fP (column numbers begin at 1) (if the source column is unknown, specify 0). \f(CWfile_index\fP is the index of the source file in a list of source files which is built up using the function \f(CWdwarf_add_file_decl()\fP. \f(CWis_source_stmt_begin\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the first instruction in the sequence generated for the source line at \f(CWlineno\fP. Similarly, \f(CWis_basic_block_begin\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the first instruction of a basic block. \f(CWis_epilogue_begin\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the first instruction in the sequence generated for the function epilogue code. Similarly, \f(CWis_prolgue_end\fP is a boolean flag that is true only if the instruction at \f(CWcode_address\fP is the last instruction of the sequence generated for the function prologue. \f(CWisa\fP should be zero unless the code at \f(CWcode_address\fP is generated in a non-standard isa. The values assigned to non-standard isas are defined by the compiler implementation. \f(CWdiscriminator\fP should be zero unless the line table needs to distinguish among multiple blocks associated with the same source file, line, and column. The values assigned to \f(CWdiscriminator\fP are defined by the compiler implementation. It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. This function is defined as of December 2011. .H 4 "dwarf_add_line_entry()" .DS \f(CWDwarf_Unsigned dwarf_add_line_entry( Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_offset, Dwarf_Unsigned lineno, Dwarf_Signed column_number, Dwarf_Bool is_source_stmt_begin, Dwarf_Bool is_basic_block_begin, Dwarf_Error *error)\fP .DE This function is the same as \f(CWdwarf_add_line_entry_b()\fP except this older version is missing the new DWARF3/4 line table fields. .H 3 "dwarf_lne_set_address_a()" .DS \f(CWint dwarf_lne_set_address_a( Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_set_address_a()\fP sets the target address at which a contiguous block of instructions begin. Information about the instructions in the block is added to .debug_line using calls to \f(CWdwarfdwarf_add_line_entry_c()\fP which specifies the offset of each instruction in the block relative to the start of the block. This is done so that a single relocation record can be used to obtain the final target address of every instruction in the block. The relocatable address of the start of the block of instructions is specified by \f(CWoffs\fP. The symbol used to relocate the address is given by \f(CWsymidx\fP, which is normally the index of the symbol in the Elf symbol table. It returns \f(CWDW_DLV_OK\fP on success, and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_lne_set_address()" .DS \f(CWDwarf_Unsigned dwarf_lne_set_address( Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_set_address()\fP sets the target address at which a contiguous block of instructions begin. Information about the instructions in the block is added to .debug_line using calls to \f(CWdwarfdwarf_add_line_entry()\fP which specifies the offset of each instruction in the block relative to the start of the block. This is done so that a single relocation record can be used to obtain the final target address of every instruction in the block. The relocatable address of the start of the block of instructions is specified by \f(CWoffs\fP. The symbol used to relocate the address is given by \f(CWsymidx\fP, which is normally the index of the symbol in the Elf symbol table. It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_lne_end_sequence_a()" .DS \f(CWint dwarf_lne_end_sequence_a( Dwarf_P_Debug dbg, Dwarf_Addr address; Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_end_sequence_a()\fP indicates the end of a contiguous block of instructions. \f(CWaddress()\fP should be just higher than the end of the last address in the sequence of instructions. Before the next block of instructions (if any) a call to \f(CWdwarf_lne_set_address_a()\fP will have to be made to set the address of the start of the target address of the block, followed by calls to \f(CWdwarf_add_line_entry_a()\fP for each of the instructions in the block. It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_lne_end_sequence()" .DS \f(CWDwarf_Unsigned dwarf_lne_end_sequence( Dwarf_P_Debug dbg, Dwarf_Addr address; Dwarf_Error *error)\fP .DE The function \f(CWdwarf_lne_end_sequence()\fP indicates the end of a contiguous block of instructions. \f(CWaddress()\fP should be just higher than the end of the last address in the sequence of instructions. Before the next block of instructions (if any) a call to \f(CWdwarf_lne_set_address()\fP will have to be made to set the address of the start of the target address of the block, followed by calls to \f(CWdwarf_add_line_entry()\fP for each of the instructions in the block. It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_add_directory_decl_a()" .DS \f(CWint dwarf_add_directory_decl_a( Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned *index_in_directories, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_directory_decl()\fP adds the string specified by \f(CWname\fP to the list of include directories in the statement program prologue of the .debug_line section. The string should therefore name a directory from which source files have been used to create the present object. On success it returns \f(CWDW_DLV_OK\fP and sets the index of the string just added, in the list of include directories for the object. This index is then used to refer to this string. The index is passed back through the pointer argument \f(CWindex_in_directories\fP The first successful call of this function returns one, not zero, to be consistent with the directory indices that \f(CWdwarf_add_file_decl()\fP (below) expects.. DWARF5 is a bit different. TBD FIXME It returns \f(CWDW_DLV_ERROR\fP on error. .H 4 "dwarf_add_directory_decl()" .DS \f(CWDwarf_Unsigned dwarf_add_directory_decl( Dwarf_P_Debug dbg, char *name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_directory_decl()\fP adds the string specified by \f(CWname\fP to the list of include directories in the statement program prologue of the .debug_line section. The string should therefore name a directory from which source files have been used to create the present object. It returns the index of the string just added, in the list of include directories for the object. This index is then used to refer to this string. The first successful call of this function returns one, not zero, to be consistent with the directory indices that \f(CWdwarf_add_file_decl()\fP (below) expects.. \f(CWdwarf_add_directory_decl()\fP returns \f(CWDW_DLV_NOCOUNT\fP on error. .H 3 "dwarf_add_file_decl_a()" .DS \f(CWint dwarf_add_file_decl_a( Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Unsigned *file_entry_count_out, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_file_decl_a()\fP adds the name of a source file that contributed to the present object. The name of the file is specified by \f(CWname\fP (which must not be the empty string or a null pointer, it must point to a string with length greater than 0). In case the name is not a fully-qualified pathname, it is considered prefixed with the name of the directory specified by \f(CWdir_idx\fP (which does not mean the \f(CWname\fP is changed or physically prefixed by this producer function, we simply describe the meaning here). \f(CWdir_idx\fP is the index of the directory to be prefixed in the list builtup using \f(CWdwarf_add_directory_decl_a()\fP. As specified by the DWARF spec, a \f(CWdir_idx\fP of zero will be interpreted as meaning the directory of the compilation and another index must refer to a valid directory as FIXME .P \f(CWtime_mod\fP gives the time at which the file was last modified, and \f(CWlength\fP gives the length of the file in bytes. .P On success, it returns \f(CWDW_DLV_OK\fP and returns the index of the source file in the list built up so far through the pointer \f(CWfile_entry_count_out\fP. This index can then be used to refer to this source file in calls to \f(CWdwarf_add_line_entry_a()\fP. On error, it returns \f(CWDW_DLV_ERROR\fP. .H 4 "dwarf_add_file_decl()" .DS \f(CWDwarf_Unsigned dwarf_add_file_decl( Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_file_decl()\fP adds the name of a source file that contributed to the present object. The name of the file is specified by \f(CWname\fP (which must not be the empty string or a null pointer, it must point to a string with length greater than 0). In case the name is not a fully-qualified pathname, it is considered prefixed with the name of the directory specified by \f(CWdir_idx\fP (which does not mean the \f(CWname\fP is changed or physically prefixed by this producer function, we simply describe the meaning here). \f(CWdir_idx\fP is the index of the directory to be prefixed in the list builtup using \f(CWdwarf_add_directory_decl()\fP. As specified by the DWARF spec, a \f(CWdir_idx\fP of zero will be interpreted as meaning the directory of the compilation and another index must refer to a valid directory as FIXME .P \f(CWtime_mod\fP gives the time at which the file was last modified, and \f(CWlength\fP gives the length of the file in bytes. .P It returns the index of the source file in the list built up so far using this function, on success. This index can then be used to refer to this source file in calls to \f(CWdwarf_add_line_entry()\fP. On error, it returns \f(CWDW_DLV_NOCOUNT\fP. .H 2 "Fast Access (aranges) Operations" These functions operate on the .debug_aranges section. .H 3 "dwarf_add_arange_c()" .DS \f(CWint dwarf_add_arange_c( Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_arange_c()\fP adds another address range to be added to the section containing address range information, .debug_aranges. If \f(CWend_symbol_index is not zero\fP we are using two symbols to create a length (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) .sp .in +2 \f(CWbegin_address\fP is the offset from the symbol specified by \f(CWsymbol_index\fP . \f(CWoffset_from_end_symbol\fP is the offset from the symbol specified by \f(CWend_symbol_index\fP. \f(CWlength\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + offset_from_end - \\ ( start_symbol + begin_address) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 If \f(CWend_symbol_index\fP is zero we must be given a length (either \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 The relocatable start address of the range is specified by \f(CWbegin_address\fP, and the length of the address range is specified by \f(CWlength\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. The \f(CWoffset_from_end_symbol\fP is ignored. .in -2 The function returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_arange()" .DS \f(CWDwarf_Unsigned dwarf_add_arange( Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Signed symbol_index, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_arange()\fP adds another address range to be added to the section containing address range information, .debug_aranges. The relocatable start address of the range is specified by \f(CWbegin_address\fP, and the length of the address range is specified by \f(CWlength\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. It returns a non-zero value on success, and \f(CW0\fP on error. .H 4 "dwarf_add_arange_b()" .DS \f(CWDwarf_Unsigned dwarf_add_arange_b( Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_arange_b()\fP adds another address range to be added to the section containing address range information, .debug_aranges. If \f(CWend_symbol_index is not zero\fP we are using two symbols to create a length (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) .sp .in +2 \f(CWbegin_address\fP is the offset from the symbol specified by \f(CWsymbol_index\fP . \f(CWoffset_from_end_symbol\fP is the offset from the symbol specified by \f(CWend_symbol_index\fP. \f(CWlength\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + offset_from_end - \\ ( start_symbol + begin_address) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 If \f(CWend_symbol_index\fP is zero we must be given a length (either \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 The relocatable start address of the range is specified by \f(CWbegin_address\fP, and the length of the address range is specified by \f(CWlength\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. The \f(CWoffset_from_end_symbol\fP is ignored. .in -2 It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Fast Access (pubnames) Operations" These functions operate on the .debug_pubnames section. .sp .H 3 "dwarf_add_pubname_a()" .DS \f(CWint dwarf_add_pubname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_pubname()" .DS \f(CWDwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_pubname()\fP adds the pubname specified by \f(CWpubname_name\fP to the section containing pubnames, i.e. .debug_pubnames. The \f(CWDIE\fP that represents the function being named is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Fast Access (pubtypes) Operations" These functions operate on the .debug_pubtypes section. An SGI-defined extension. Not part of standard DWARF. .sp .H 3 "dwarf_add_pubtype_a()" .DS \f(CWint dwarf_add_pubtype_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_pubtype()" .DS \f(CWDwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_pubtype()\fP adds the pubtype specified by \f(CWpubtype_name\fP to the section containing pubtypes, i.e. .debug_pubtypes. The \f(CWDIE\fP that represents the function being named is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Fast Access (weak names) Operations" These functions operate on the .debug_weaknames section. An SGI-defined extension. Not part of standard DWARF. .H 3 "dwarf_add_weakname_a()" .DS \f(CWint dwarf_add_weakname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error *error)\fP .DE It returns \f(CWDW_DLV_OK\fP on success and \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_weakname()" .DS \f(CWDwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_weakname()\fP adds the weak name specified by \f(CWweak_name\fP to the section containing weak names, i.e. .debug_weaknames. The \f(CWDIE\fP that represents the function being named is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Static Function Names Operations" The .debug_funcnames section contains the names of static function names defined in the object, and also the offsets of the \f(CWDIE\fPs that represent the definitions of the functions in the .debug_info section. An SGI-defined extension. Not part of standard DWARF. .H 3 "dwarf_add_funcname_a()" .DS \f(CWint dwarf_add_funcname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *func_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_funcname_a()\fP adds the name of a static function specified by \f(CWfunc_name\fP to the section containing the names of static functions defined in the object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the function is specified by \f(CWdie\fP. .P It returns \f(CWDW_DLV_OK\fP on success. .P It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_funcname()" .DS \f(CWDwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *func_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_funcname()\fP adds the name of a static function specified by \f(CWfunc_name\fP to the section containing the names of static functions defined in the object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the function is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "File-scope User-defined Type Names Operations" The .debug_typenames section contains the names of file-scope user-defined types in the given object, and also the offsets of the \f(CWDIE\fPs that represent the definitions of the types in the .debug_info section. An SGI-defined extension. Not part of standard DWARF. .H 3 "dwarf_add_typename_a()" .DS \f(CWint dwarf_add_typename_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error *error)\fP .DE This the same as \f(CWdwarf_add_typename()\fP except that on success this returns \f(CWDW_DLV_OK\fP and on failure this returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_typename()" .DS \f(CWDwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_typename()\fP adds the name of a file-scope user-defined type specified by \f(CWtype_name\fP to the section that contains the names of file-scope user-defined type. The object that this section belongs to is specified by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the type is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "File-scope Static Variable Names Operations" The .debug_varnames section contains the names of file-scope static variables in the given object, and also the offsets of the \f(CWDIE\fPs that represent the definition of the variables in the .debug_info section. An SGI-defined section. .H 3 "dwarf_add_varname_a()" .DS \f(CWint dwarf_add_varname_a( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error *error)\fP .DE This the same as \f(CWdwarf_add_varname()\fP except that on success this returns \f(CWDW_DLV_OK\fP and on failure this returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_varname()" .DS \f(CWDwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_varname()\fP adds the name of a file-scope static variable specified by \f(CWvar_name\fP to the section that contains the names of file-scope static variables defined by the object represented by \f(CWdbg\fP. The \f(CWDIE\fP that represents the definition of the static variable is specified by \f(CWdie\fP. It returns a non-zero value on success, and \f(CW0\fP on error. .H 2 "Macro Information Creation" All strings passed in by the caller are copied by these functions, so the space in which the caller provides the strings may be ephemeral (on the stack, or immediately reused or whatever) without this causing any difficulty. .H 3 "dwarf_def_macro()" .DS \f(CWint dwarf_def_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name char *value, Dwarf_Error *error);\fP .DE Adds a macro definition. The \f(CWname\fP argument should include the parentheses and parameter names if this is a function-like macro. Neither string should contain extraneous whitespace. \f(CWdwarf_def_macro()\fP adds the mandated space after the name and before the value in the output DWARF section(but does not change the strings pointed to by the arguments). If this is a definition before any files are read, \f(CWlineno\fP should be 0. Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_undef_macro()" .DS \f(CWint dwarf_undef_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name, Dwarf_Error *error);\fP .DE Adds a macro un-definition note. If this is a definition before any files are read, \f(CWlineno\fP should be 0. Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_start_macro_file()" .DS \f(CWint dwarf_start_macro_file(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, Dwarf_Unsigned fileindex, Dwarf_Error *error);\fP .DE \f(CWfileindex\fP is an index in the .debug_line header: the index of the file name. See the function \f(CWdwarf_add_file_decl()\fP. The \f(CWlineno\fP should be 0 if this file is the file of the compilation unit source itself (which, of course, is not a #include in any file). Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_end_macro_file()" .DS \f(CWint dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error *error);\fP .DE Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 3 "dwarf_vendor_ext()" .DS \f(CWint dwarf_vendor_ext(Dwarf_P_Debug dbg, Dwarf_Unsigned constant, char * string, Dwarf_Error* error); \fP .DE The meaning of the \f(CWconstant\fP and the\f(CWstring\fP in the macro info section are undefined by DWARF itself, but the string must be an ordinary null terminated string. This call is not an extension to DWARF. It simply enables storing macro information as specified in the DWARF document. Returns \f(CWDW_DLV_ERROR\fP and sets \f(CWerror\fP if there is an error. Returns \f(CWDW_DLV_OK\fP if the call was successful. .H 2 "Low Level (.debug_frame) operations" These functions operate on the .debug_frame section. Refer to \f(CWlibdwarf.h\fP for the register names and register assignment mapping. Both of these are necessarily machine dependent. .H 3 "dwarf_new_fde_a()" .DS \f(CWint dwarf_new_fde_a( Dwarf_P_Debug dbg, Dwarf_P_Fde *fde_out, Dwarf_Error *error)\fP .DE On success the function \f(CWdwarf_new_fde_a()\fP returns \f(CWDW_DLV_OK\fP and returns a pointer to the fde through \f(CWfde_out\fP. The descriptor should be used to build a complete \f(CWFDE\fP. Subsequent calls to routines that build up the \f(CWFDE\fP should use the same \f(CWDwarf_P_Fde\fP descriptor. .P It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_new_fde()" .DS \f(CWDwarf_P_Fde dwarf_new_fde( Dwarf_P_Debug dbg, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_new_fde()\fP returns a new \f(CWDwarf_P_Fde\fP descriptor that should be used to build a complete \f(CWFDE\fP. Subsequent calls to routines that build up the \f(CWFDE\fP should use the same \f(CWDwarf_P_Fde\fP descriptor. It returns a valid \f(CWDwarf_P_Fde\fP descriptor on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_frame_cie_a()" .DS \f(CWint dwarf_add_frame_cie_a( Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_bytes_len, Dwarf_Unsigned *cie_index_out, Dwarf_Error *error);\fP .DE On success The function \f(CWdwarf_add_frame_cie_a()\fP returns \f(CWDW_DLV_OK\fP, creates a \f(CWCIE\fP, and returns an index to it through the pointer \f(CWcie_index_out\fP. .P \f(CWCIE\fPs are used by \f(CWFDE\fPs to setup initial values for frames. The augmentation string for the \f(CWCIE\fP is specified by \f(CWaugmenter\fP. The code alignment factor, data alignment factor, and the return address register for the \f(CWCIE\fP are specified by \f(CWcode_align\fP, \f(CWdata_align\fP, and \f(CWret_addr_reg\fP respectively. \f(CWinit_bytes\fP points to the bytes that represent the instructions for the \f(CWCIE\fP being created, and \f(CWinit_bytes_len\fP specifies the number of bytes of instructions. .P There is no convenient way to generate the \f(CWinit_bytes\fP stream. One just has to calculate it by hand or separately generate something with the correct sequence and use dwarfdump -v and readelf (or objdump) and some kind of hex dumper to see the bytes. This is a serious inconvenience! On error it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_frame_cie()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_cie( Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small ret_addr_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_bytes_len, Dwarf_Error *error);\fP .DE The function \f(CWDwarf_Unsigned dwarf_add_frame_cie()\fP creates a \f(CWCIE\fP, and returns an index to it, that should be used to refer to this \f(CWCIE\fP. \f(CWCIE\fPs are used by \f(CWFDE\fPs to setup initial values for frames. The augmentation string for the \f(CWCIE\fP is specified by \f(CWaugmenter\fP. The code alignment factor, data alignment factor, and the return address register for the \f(CWCIE\fP are specified by \f(CWcode_align\fP, \f(CWdata_align\fP, and \f(CWret_addr_reg\fP respectively. \f(CWinit_bytes\fP points to the bytes that represent the instructions for the \f(CWCIE\fP being created, and \f(CWinit_bytes_len\fP specifies the number of bytes of instructions. There is no convenient way to generate the \f(CWinit_bytes\fP stream. One just has to calculate it by hand or separately generate something with the correct sequence and use dwarfdump -v and readelf (or objdump) and some kind of hex dumper to see the bytes. This is a serious inconvenience! It returns an index to the \f(CWCIE\fP just created on success. On error it returns \f(CWDW_DLV_NOCOUNT\fP. .H 3 "dwarf_add_frame_fde_c()" .DS \f(CWint dwarf_add_frame_fde_c( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned sym_idx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Unsigned *index_to_fde, Dwarf_Error* error)\fP .DE This function is like \f(CWdwarf_add_frame_fde()\fP except that \f(CWdwarf_add_frame_fde_c()\fP has new arguments to allow use with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP and a new argument to return the fde index.. The function \f(CWdwarf_add_frame_fde_c()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. If \f(CWsym_idx_of_end\fP is zero (may be \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. \f(CWsym_idx_of_end\fP and \f(CWoffset_from_end_sym\fP are unused. .in -2 .sp If \f(CWsym_idx_of_end\fP is non-zero (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful): .sp .in +2 \f(CWvirt_addr\fP is the offset from the symbol specified by \f(CWsym_idx\fP . \f(CWoffset_from_end_sym\fP is the offset from the symbol specified by \f(CWsym_idx_of_end\fP. \f(CWcode_len\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + begin - \\ ( start_symbol + offset_from_end) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 On success it returns \f(CWDW_DLV_OK\fP and returns index to the given \f(CWfde\fP through the pointer \f(CWindex_to_fde\fP. On error, it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_frame_fde()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. It returns an index to the given \f(CWfde\fP. .H 4 "dwarf_add_frame_fde_b()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned sym_idx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Error* error)\fP .DE This function is like \f(CWdwarf_add_frame_fde()\fP except that \f(CWdwarf_add_frame_fde_b()\fP has new arguments to allow use with \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP. The function \f(CWdwarf_add_frame_fde_b()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. If \f(CWsym_idx_of_end\fP is zero (may be \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. \f(CWsym_idx_of_end\fP and \f(CWoffset_from_end_sym\fP are unused. .in -2 .sp If \f(CWsym_idx_of_end\fP is non-zero (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful): .sp .in +2 \f(CWvirt_addr\fP is the offset from the symbol specified by \f(CWsym_idx\fP . \f(CWoffset_from_end_sym\fP is the offset from the symbol specified by \f(CWsym_idx_of_end\fP. \f(CWcode_len\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + begin - \\ ( start_symbol + offset_from_end) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 It returns an index to the given \f(CWfde\fP. On error, it returns \f(CWDW_DLV_NOCOUNT\fP. .H 3 "dwarf_add_frame_info_c()" .DS \f(CWint dwarf_add_frame_info_c( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Unsigned *index_to_fde, Dwarf_Error* error)\fP .DE New December 2018, this function has a simpler return value so checking for failure is easier. Otherwise \f(CWdwarf_add_frame_fde_c()\fP is essentially similar to \f(CWdwarf_add_frame_fde_b()\fP. .P On success The function \f(CWdwarf_add_frame_fde_c()\fP returns \f(CWDW_DLV_OK\fP, adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP, and. passes the index of the fde back through the pointer \f(CWindex_to_fde\fP On failure it returns \f(CWDW_DLV_ERROR\fP. Function created 01 December 2018. .H 4 "dwarf_add_frame_info_b()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. This function refers to MIPS/IRIX specific exception tables and is not a function other targets need. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWoffset_into_exception_tables\fP specifies the MIPS/IRIX specific offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables for this function begins. \f(CWexception_table_symbol\fP is also MIPS/IRIX specific and it specifies the index of the relocatable symbol to be used to relocate this offset. If \f(CWend_symbol_index is not zero\fP we are using two symbols to create a length (must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful) .sp .in +2 \f(CWvirt_addr\fP is the offset from the symbol specified by \f(CWsym_idx\fP . \f(CWoffset_from_end_symbol\fP is the offset from the symbol specified by \f(CWend_symbol_index\fP. \f(CWcode_len\fP is ignored. This begin-end pair will be show up in the relocation array returned by \f(CWdwarf_get_relocation_info() \fP as a \f(CWdwarf_drt_first_of_length_pair\fP and \f(CWdwarf_drt_second_of_length_pair\fP pair of relocation records. The consuming application will turn that pair into something conceptually identical to .sp .nf .in +4 .word end_symbol + offset_from_end_symbol - \\ ( start_symbol + virt_addr) .in -4 .fi .sp The reason offsets are allowed on the begin and end symbols is to allow the caller to re-use existing labels when the labels are available and the corresponding offset is known (economizing on the number of labels in use). The 'offset_from_end - begin_address' will actually be in the binary stream, not the relocation record, so the app processing the relocation array must read that stream value into (for example) net_offset and actually emit something like .sp .nf .in +4 .word end_symbol - start_symbol + net_offset .in -4 .fi .sp .in -2 If \f(CWend_symbol_index\fP is zero we must be given a code_len value (either \f(CWDW_DLC_STREAM_RELOCATIONS\fP or \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP ): .sp .in +2 The relocatable start address of the range is specified by \f(CWvirt_addr\fP, and the length of the address range is specified by \f(CWcode_len\fP. The relocatable symbol to be used to relocate the start of the address range is specified by \f(CWsymbol_index\fP, which is normally the index of the symbol in the Elf symbol table. The \f(CWoffset_from_end_symbol\fP is ignored. .in -2 It returns an index to the given \f(CWfde\fP. On error, it returns \f(CWDW_DLV_NOCOUNT\fP. .H 4 "dwarf_add_frame_info()" .DS \f(CWDwarf_Unsigned dwarf_add_frame_info( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned sym_idx, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Error* error)\fP .DE The function \f(CWdwarf_add_frame_info()\fP adds the \f(CWFDE\fP specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the object represented by the given \f(CWdbg\fP. \f(CWdie\fP specifies the \f(CWDIE\fP that represents the function whose frame information is specified by the given \f(CWfde\fP. If the MIPS/IRIX specific DW_AT_MIPS_fde attribute is not needed in .debug_info pass in 0 as the \f(CWdie\fP argument. \f(CWcie\fP specifies the index of the \f(CWCIE\fP that should be used to setup the initial conditions for the given frame. \f(CWvirt_addr\fP represents the relocatable address at which the code for the given function begins, and \f(CWsym_idx\fP gives the index of the relocatable symbol to be used to relocate this address (\f(CWvirt_addr\fP that is). \f(CWcode_len\fP specifies the size in bytes of the machine instructions for the given function. \f(CWoffset_into_exception_tables\fP specifies the offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables for this function begins. \f(CWexception_table_symbol\fP gives the index of the relocatable symbol to be used to relocate this offset. These arguments are MIPS/IRIX specific, pass in 0 for other targets. On success it returns an index to the given \f(CWfde\fP. On failure it returns DW_DLV_NOCOUNT. .H 3 "dwarf_fde_cfa_offset_a()" .DS \f(CWint dwarf_fde_cfa_offset_a( Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *error)\fP .DE New December 2018, this function has a simpler return value so checking for failure is easier. .P The function \f(CWdwarf_fde_cfa_offset()\fP appends a \f(CWDW_CFA_offset\fP operation to the \f(CWFDE\fP, specified by \f(CWfde\fP, being constructed. The first operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWreg\P. The register specified should not exceed 6 bits. The second operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWoffset\fP. .P It returns \f(CWDW_DLV_OK\fP on success. .P It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_fde_cfa_offset()" .DS \f(CWDwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_fde_cfa_offset()\fP appends a \f(CWDW_CFA_offset\fP operation to the \f(CWFDE\fP, specified by \f(CWfde\fP, being constructed. The first operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWreg\P. The register specified should not exceed 6 bits. The second operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWoffset\fP. It returns the given \f(CWfde\fP on success. It returns \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_add_fde_inst_a()" .DS \f(CWint dwarf_add_fde_inst_a( Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_fde_inst()\fP adds the operation specified by \f(CWop\fP to the \f(CWFDE\fP specified by \f(CWfde\fP. Up to two operands can be specified in \f(CWval1\fP, and \f(CWval2\fP. Based on the operand specified \f(CWLibdwarf\fP decides how many operands are meaningful for the operand. It also converts the operands to the appropriate datatypes (they are passed to \f(CWdwarf_add_fde_inst\fP as \f(CWDwarf_Unsigned\fP). .P It returns \f(CWDW_DLV_OK\fP on success. It returns \f(CWDW_DLV_ERROR\fP on error. Function created 01 December 2018. .H 4 "dwarf_add_fde_inst()" .DS \f(CWDwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_add_fde_inst()\fP adds the operation specified by \f(CWop\fP to the \f(CWFDE\fP specified by \f(CWfde\fP. Up to two operands can be specified in \f(CWval1\fP, and \f(CWval2\fP. Based on the operand specified \f(CWLibdwarf\fP decides how many operands are meaningful for the operand. It also converts the operands to the appropriate datatypes (they are passed to \f(CWdwarf_add_fde_inst\fP as \f(CWDwarf_Unsigned\fP). It returns the given \f(CWfde\fP on success, and \f(CWDW_DLV_BADADDR\fP on error. .H 3 "dwarf_insert_fde_inst_bytes()" .DS \f(CWint dwarf_insert_fde_inst_bytes( Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_Unsigned len, Dwarf_Ptr ibytes, Dwarf_Error *error)\fP .DE The function \f(CWdwarf_insert_fde_inst_bytes()\fP inserts the byte array (pointed at by \f(CWibytes\fP and of length \f(CWlen\fP) of frame instructions into the fde \f(CWfde\fP. It is incompatible with \f(CWdwarf_add_fde_inst()\fP, do not use both functions on any given Dwarf_P_Debug. At present it may only be called once on a given \f(CWfde\fP. The \f(CWlen\fP bytes \f(CWibytes\fP may be constructed in any way, but the assumption is they were copied from an object file such as is returned by the libdwarf consumer function \f(CWdwarf_get_fde_instr_bytes\fP. It returns \f(CWDW_DLV_OK\fP on success, and \f(CWDW_DLV_ERROR\fP on error. .S .TC 1 1 4 .CS dwarfutils-20200114/libdwarf/libdwarf2p.1.pdf000066400000000000000000006155211361531463500206320ustar00rootroot00000000000000%PDF-1.4 %쏢 5 0 obj <> stream xWnF}W,R6}Rb'QخD#>PZb# ~}gBQ ܝ9gf23&ȉK6>#tр9 I#hh^ec1]hs_]c<9 EA>cB2C`Ty+2l/}W!0j&iP5~B4DAܴٔvՊi yupWւ}P^lCpiQbSv? >`7QvVYuU+rrp4 gaC-5P۫

k!/GǙck[cMQWuA80ة pMo=xid{!چЁ3LP낔2 zPfb>MP VBqr )CgTj<9Q~ߴDI|DLB0ʆ`_I}C|XO9n=|ϰ^:I5@1Vh<ە UzPB a! Bc!-oZ7^avBgtf(1Ȃ>и }^EIȎgDeӷ郄@=KMj6'l62/jv 44(`{b^֧< PsGI#Ut.i`CXz|vM CA:hzvӶbX) X7WD#ܤ~]VpuWR\=k؀ʢ D$ 0zC3 1!7g{JJ`zV x\JVl uh$ax ܤ?Ͽ@ endstream endobj 6 0 obj 1789 endobj 19 0 obj <> stream xY[s}ׯ%`G\c[lNzTvЌ}Ϸ7tc{o\~ųۜmm/>_󑹿={Hت*!~6v`2OyXdlrXsح^8q2źEe&t={5¢:iU#iGoZc״x\]e3)J+y0Bd<}}Mn(e]^CS?;^^WMeC3e,yY$l)ٿjҎJB4)Ƀ՟?F/9׺{,cQ/ "6eiыzm?-,3+( رdM 4څbv6O'ljiNi }ߙ$%/U>D/,lbmbrcÚj`kYk$jZ& /ɓ"1J$Iz }:P":LZ L-+QGm$W*ŏt̸?틞\;W^]vѬ\/K\F6_w\Xťmvzn B M"."aծϢ (v) ɅL|XU&_fnoͱY3cݲl#]\{ x"Ci;vIYU^|v߾Z@en nʚRwecwƺC@@KZ+I k3vըуA@]690$OO -Y)Y*|ɌQQŪ"SS:jLUk|EEvY<, <KJء~ |yhTi,m`}Ly Il-0/rO 6_(lΞv& X5SO">X:1<퇺0R{+xv~o0݂ʐmujdž& 1\sc9+NTVrht=5OtGA`JDhL|lFd٘Q+A-Q6mUmnoY{X fN}fa+m֥E`pFd/Dp)ei*?O[fPĬ(PLd kaDj݀J"`o"M-2^8&y )ῄ-tO'"'%l^P[xz*5d GK|vwF4q׵{ )/Z1^۱ y6a;ńzDW0:Tf8=a]6/fh 7-"dO,_5aTP0ExAiX1e#~6X5ۛZk+}c߀ KFO~](~GJ`M|z!/:"jscƨ~Ye Ahӄ4YMk'3tLffegF.C+]Sݽ%HKHtNB#7ľ=LAW}+Q@䪈}@Y#G}L:cuwlGGi0ByWm'Jk}G for)OyLTjْPGSf&YPZ %ѣqxMs- rΤ?j<)I?v;T͆sk+18HDE!@payt: ª8Yp{EQ(a׼PݸڲdJ9(B|_Gho_#xկM/W/nuG8$5A|wH! N *" P)I3_u#i̕á_[&vK35ry̙^4󈶅ǖîXj͙©`EYxD>Ap.m7a ]?4DWPtZaJn^E(tn5^QEC4}hՕQ ]8 g:wMܝ?)zo"$4; 'rRn}OUf<{= 7y%VQ][Aê8}4,'h̝a7fVBflOcqdq,]xgD Ol,ou3<ىkWPcKo̫?1{endstream endobj 20 0 obj 2841 endobj 24 0 obj <> stream xXr}WL%`Jcfp͛6rn6?X)H I sz.ȹT*$t9\zS"d/ ad׶f?xJHnaO &Ә*azjvJ Èb|Y.|lv`uimQviچ;6tn='bq!8LeUv{+48(tWM oR\d#66 {V5 ] y8Cg$V=<|)P/?gzCF1c%=}&ϲ= +1(Bl%"vS0:my)yh7iSCBk |0 7z(K>d7JΫEV:tK ( ]EZ`46N;_' OB{b^NE7TVJe, t(4 7Dto(j 6nΜ eت0ߘ!z0K);xl2Byp(ߥ7#O \K]}XL2hlZآ֟yHɨSPT~zr!DڄQ{Gj,W~ZxhMt0{AuUEcsK_!!_9\eǀT5-d5qh_𥫍 -ɤZ&):QI))M}']Q3s7M =N0LQk2U?E+dXt(n4< X%c vO #:Bd dtP/QNbA$5&ɍb$B/Y/HxfU'ӗ⦞0i*-Y͕5c8zCI14G˩ E̷:1EWE%$@rtjnw~&fFĻ 6Q46p6H 7ɾ">->Rf!{eӒl%̒zÇI>1qg3dĪ\@+leJ 5̧罙W6H}qe)\%fwb|_!H XQeSu->34 Oi52oinѨ—gm-X0HOwq[w[t`X܀Q&/)֖L;zO1aFmg*W 1(7%UkɂR2D{6n:LoK0+7 RzvH޹3Çw/ٴ ŒmrpXL& xc67j4Ӗ xmEs8=25RBC'y3 sBPj5R1-@6{c`tU՚^H%qmr6{|6Q n.lOxIOcr> stream xXے}W[8ۣݤ-gŊ-.a KsgRv**En.BDH/~x˸}T{zu) [oQX,NzVz\=^)0ba]mq*ZЪ* 's~cNDJŏRb09-EL;#C_qVT)'ñ*d[%MT $=&3lYd.M׈ǥ$U~`o"ʣ\R~(q2$jarٶx ʑd31? p~ZrH| %XCokdTg5jJqHC?L&NFXmNPfqdCKe˫9zQ,#s/V`+]bRIJPif:S3؋w3H x߶H kD"%jjMLTjcmq ICif:4"i,_cli3/ +d6) c0 f: ܵgw R>|kP|E֊Ty1_$,_tPҐ|ȤЭK}|dz&A.vQ"(ۣőJ3^yX_i7ǗE+ב fTaOio$R%V4[8h>GjoКw8e]bYl9D+i r>uʽynm\=OKR ץ@8]?.VJv/N Ȫ [Eenʡm𶒿\ L[l<̯vuL~x)ЪYime$Ś1̾BC@.:g4T5ݟN7ց R3jhZ7wDt@\{lSIr]iKPQB@-;S "grO= 9lG[Dq )T|I2ǀ`q,dW%s$2m*8TW=dkӁboH]iVvJjnVZ/Byc\ ~yq٥BYrQ3nlNSL"ک"8:KIu`8 FjP}h7 3ze=ݾ$(puDffP#FlX &xid"$<\<#AƖ@ 4t cp0cqsz>gQLFI6=d7$b ۯCɥ:5qa!a\ar}Մw,<낸Nb&0Je:BN;ãX7m9`d$*8N`6 kq$Eoƥ/ sfHMÔ+/D L<˿,D^k(#Jr HzA돘7D̓k]JYSGS_\Cez=V8P xmQ#?9̞Yʕƀ<]jx\%w&x<Kܨ |%_os{n], gkoq1xK+irVzMTB{G(u1ˇK1xͽ d(t3Gn@,=\aXSԸFs5GrSn3tøeg78+zK{~QiT^;_aLdMe51Qc()HB!8 4uv$D/|qE7 JZԭ²yFhixޯ˧RV9@M_`4fF el{=?p\ p9pGzn@Yxn]8:{;E@ Xz> stream xXnF}W,Eo}sRH4# ( ȕ̆"^HZqҦٙ9gf#a_g_xݰbdf垼X$Y ʞD12!*(\UK(cD1lVqEy ~>>pḘ̆ۗoxw7o^^_;Q {N~]м&e4u#@a${r}nu_8/DNx3ƊL$ZylϤMWcݵd{]R9 ^UқPK\#uGPx9޸}eUr$cgndʃѤɋEL4jwG8h/C6WpgfRHGlr\0">U&CURS/pkbg\_\:QCd*s>rym"6:k3yl6Z .w`Ytؙ98]̜c49tu;]đ‚LJmLpo:p^ 72髑i5Em2 <cɩ#=RFĆ9uw{ZBܜ;U J&.GiʅC Yc}@5V-=^%98oIF@"V4|=3D}Y̖k>T:nHmH 4gҵ1OeShʬJ l#f>T7MQ~ ck9 +}ZƶAI|p-zC mr9bN=Ai1GR)2A<"SlP:B;̉>8XX _u*इ>tm'匦/IeeŸ- -<2ܯL1rRwN 0!Cp9ɘYr/ H} "뻛_Wu~ۍ zmFԼ .<6q PyH$ƥ27_Ha8rݻX[ИH Ԗ.2ZU-W_-x' y0+5RssB Ϥ,|ބV`S>yY-9k,.GI7F#qo`SZ?N>F*bgm9]!S[)OBcx HmHΎ^a~U\0o9B F0D)N`]1Έ> stream xXێܸ}۪BQ-o873 ,=JtiSj;_Û2^c DXU|!4 Ϫ[1'qA~eE~TyHȪ®_dLXF 'yU,\i }"d4($L^5z굘GqaE^w8AIZm?<?<~x~/OVEdq"mKIlJLЏD(IFjjORRL&ۓ Y0"m^`y%kL[1m u"cH\L#Dž5D77=d7򟫿!rcZ$F9.f<>w͒E"jQ0WL\'ʨ%&'ޑi@McA"AFj"d{>(u9Jպ.V-Z.\FY7+ cZ۴F:>ܷV0{nBEoÒV;1*Is3-ÔqM|Y{g>S9Uz/ ܟSv׉ETmG^7O2^ǧ??||#v.(lfPx."#YZ HDOwdPfΐDOww-uP');wijU'gZ;qҡUm_Vt6 K(2EޞI>hZ7)o\N/J$ͤp<,q3#tNfCG zRA9?{pACQ!W}kh8p_H Ҙ&w㤭"5:ݶ5}f %I3BU_#5z`/r CwhS@@oIxE:(9YUR&yD>Y Ft9mD/t0|I:-WyP93+s^*c_ QԩP( ΀8{R VJ=ĆJ*ݲ"M@SS/FdBgQg~Fi&$_ /,Ƨ#]h:=6< ƏQe5\X OFyxomwh*h-#VQ8MPV6g>wZ+7픔5:X|a㨙7hOs)ڨ1]^͍ S7^5:;@nvMߌ/0ҡ4~Toq}7%hqj٪$ OMMulm01Ӱpyo"u^n&^'j9V9LF pr΀p69xGey@p6<lfeDCGQ`=Uc`@aRX5GJdv]x%[pP{C) C/ñ455:2,}n "d gqLsL`K 864\@B?8o+z3 ƘNpeh.-+ 5oG =|v_dGJRx0f6] P}X-/xendstream endobj 40 0 obj 2094 endobj 44 0 obj <> stream xYm_B'|~k`pUhP؅V:)}!)6Ap|3cEEzX{O.$Ǫ]VaRRfss' {UV4|:W |8j`W{<ȅral8;kT͉jCM6r iȹ zi4ւ X$¯躶[I( (!gȍ&0SԄ1nV G\D3jZJlIF 0eQu5ë6-5h qfQ"46jxfG&71orճRh݇ƭLi@#|ӰWT<{RȾ!ORN (p"Ԁy‚+cSҺd唸rS]W?^ۿ$,ڇv*8`itb <[~||zEzGL7sVd>>UInFVX_u*BT5:VX&dl',010IsQPH!|jn )a<7ye])(gZCH˃+AP]24{'c[RT2C~Mcp3;&\ga"mzC,y<&cĈh.\Ef%zAGIޅUuI^ջz_aJ<Rs& Tm=EyZ"/PT>Op&s`Di왧BOK y ۅg? jZk0 |7qhb<#/&USげ2q-j < uݚ\WzEuԩ˓ߘ&ԗRwEw6jZQ)E"'uKa?IB/+<WoO/Vd~޲S׎w'Y!@Su9+g:YE3f' ȩD>~=RF-WBZN4ܳu %^ZD{U |iu}j$^}[' 30)R_k4<}^S\Š0Qn]@(F/{nD;s 'JItB3 {[g.‹E"G2k4Lr7_&YތFY94 #dFF7Q6BS##9E$'YǺb/G %,ݢ2u^8}p4I Ļ\nq<{&c9"0V3ED܋ 0L?ZtRy)k7rHJ]#:!'A}펝ФF <Ͻ[p/rwRxn,/pOu[x߅c_xɌY:#e)0!5gonڇ% .~gf)? oCogRy$|O\Lp0^e/bŜMc-:'`<5 S)/ZIhv :ǃK$ +xZ7akvߧiSЩ'/vZ%; y*,>:Q>OkWQ;rĨ!,nhx5(`l1O?@ET?B" nՕcwA;Ҡ}_?y>{ev~<\B ̤[1s 20[=ݰ1i2+HT3$ŇDu/ewCf읝e}wc?3N 匄L,yB>h )IH9)), ɞ' %*L"ZMX/9кQiϗ?XnQh {5i ^\@' qvCчu@y#w h6H ^Ɯͩi6s$رߒp@0vE$zŰ>;1sd^Gu T2n#=^E د{B&&PTK;}!;[+hsNEb8P)p0KLJ0&9U7X - X;A'&q.i$=eU.4 i> stream xXr}W̛A0`޼+mh&N! (9sBZy.Źtӧ{Јj8aȮQ}1HG~$?frbj;s'*$J$duaW9M"J% c,3gfwǎt%uYu].Nn|-҅A}:d59 wJP1M5[EL2ǸČKnK7wL(8%! vvxL$/uz[Ve_g|K?Y\؋HS+:n:C[-7M:Զ93Eé#>kmǖlhA<Ղi" Ѻ Ciyn=1G!pCt-.;5yv*Lݾ;tV2 xDdE15 mRMNLɴJbWMeVg#Yӎ\7~gC=&7H>2ukDHkLM~F/zG7mgK3 |AW3p1WZn,SS=nqB{_]nZ2[+O%I&btIT[njɶm|ֹ+U|?wL tB#O)ot=/l <)a3{ l}ܠKw2"˷Η Q\Em#np*RrO}H^~n~b sj{1rԇC=hStɉhY]OaIzJym 6Gk'ERnB_"%8c_}8. 59v ==<0&uô lCVZXi1(Mέ"ОK¡iҡ&?cuLsʢA=k3%뵻˼GKҡo;h )JT>=p\b1}S˽Q}fTQ SadQ4c4P3&Mx$q*zOg~:=wdccs&1z LA30{`AEby֛-Yox3lMt " = >[Ml=ZE).7t)w#.\L|u!l3TLfvh W6,$Sֆd%+m%)֓t@bܻ!PA(T@϶&r i=H| M $m4 Z ˄1]-Û.C$^ &Y$!mo%(()^lUxС6QL?N7zr/QxT׫?endstream endobj 50 0 obj 1984 endobj 54 0 obj <> stream xWs8Bs_3$p&Mz7ƃAi1ەS$_MFT#lF_FL$ͯxGބ#AV1N;\NFROHF$OVOSvąȦ> HxYն8d 9T[ETTfOdaKEpQL*<< [/̧˛b1&OSHH&2|CCVi q;=jmu32_Bv-ӊQp%4(x]}\^]_.?n\:2@L ʪGU$epԄ. x{=+eiSiNVbo"p_2}Mtrl= Trxx17 of7Wa6{rҡ΋gax=}1$"b¨dP\g^| Yj z:.%'*O(UUiVPEU80?Tŝ-Ar"< X]5WEaԱ3$\Jepi# w"OObEЭVjl [Z ކK>3hNS$EaFK$mq+KwrWmS6PJU~}Qk܅|z}{yno'aܿ޿]~'2 !B'ANה"%j=f2O&z3{n Nx*G9m%@"_`qeУN[}#JP+^GRE;2p5!mCF #~6i&꓊ش, |=BXǯ 4T'Jmn@r)%)H?f+ Ί*xrFFsN{MC\!Pq+ad*9j.qRpS\Ia}N4L(˰׭M+׳-HS5葂yT^#COs̡y8 AG@eC,e*{^ GJ;8mx$ݜ1 CJ srUif)\5ԲD!uUdl5.(j rn՘hMzh*3Q+a9j>f]hhӽ:^'D/z3FtrRjh́&h vŃ*aF5^EvA2u[ᢡ0droiz4CvCEր5A7 "9m:WY9p cEW-Ͻf=5*A]A%@U^le4Y6*δFPCԵhU|5M?*`m\|;|ҋ,?tF* =}/zjE-ڒ'P;Ar;͂SϣA;۶w%endstream endobj 55 0 obj 1713 endobj 59 0 obj <> stream xYn}W1A  2<vРiԐTsnmhnnXu.{{ę8i_0nxta~է诏=X%d}SD2L%QyĝLywgJ[+y=X]uwmY:B~Ef\}kM|Ѩ;Z82,Km4~}[ƯW}"aImO37&3^JQnˍtnMLK&tG;g,`ÙjmS?"sXs`Y"SEK>귿!NrTtQGdʲhpQǗTmC`͇tEZj.=W18ј.D7h]?` .3EUؐ{/&9cpD7 G2qFsUHr"y{]aY.7f2ϗ)-3z]rrOk[JW1#%—OŊB}~Ҭq@"sD 9/2/ut$ͶoCbv=H1l9;P]x&G:8dMҦϰgOwa`>U} 8 &w6nB.fX?w(`<AE@ʱ'`%B2Kkx IIhsHx kPo |.^ͅX,&-O%xm<I3]5U -}>aݺ?F?C#LT,ĻȋYAFC2ٲE5Ƈ]"GSij[xtԼX|K4cyb"2sϢ!=/=9f)x(`dQHV)4.`BgNND&@ie"1DA7*3:w0⩕;Z-yL~[X .'4fPyAyZ|?24.YB¤\UhILAչ|0gXVJ.p|x7qF]H-qմA͒8\LhrHC? ,5L :$L/wLeQ=ɒٹS) <LWU=]?g_Ax(9ЊseXYXԞk2ډ.PIfޔkK`3nӭZJ%jědXKQqt$ N~-s:6'оX`Ω7 I̟P%jN糥Ki'7JK|;轹H5QF;i4ZWk򌕂I s7Ru/Mf[#lwIA a5HRJPmƅJ-d}O(֧ 62n?%%Io- %)NhVoET B߈;ևԝPu `K^+3_?֗Cbj86H2&FΎT.]ւt5Q',H] 4.spowPopsbA_'&AJ_x3QS:FiƩP}-Hkfk!L DS vZmoD,:J+eZ3I*E^ζ>WCu?C5}C'H:ֺQf7۹wPhaW.`?{(/n YL d~*ϊ`<ȓv= * P̷zV". t >57A" \Cs>K)V$<.7^hH+`(ȜTix 71$+L.~H8rOAPhGJBuB(,'~Dfao hg߇FZ*k0sbbO:8;euXT,/ zĶ]K]_jMo*C":N ?oAlw&()* ? >΍40.Dn_wES\d>K 7StHcZ8y>ZF_lb-?;F 4_@_l5&B/Z>Bϓ6-(g6~?q/b-:endstream endobj 60 0 obj 2967 endobj 64 0 obj <> stream xXr+P U5b|g|+N|g[Y)MQ6oG>ǝE*e]"F?N>3şcv/v%5e:*.~ۅəJťK_-+aJ",,rK?^mw].r`۳z O}}|FOCs&o_ƲE3mSlc?즥+ĜS\ӞI^qKkjYһ`z!1;̵̳ͦlnpWt950~BqsI[.nE~y:E mf[@0|6}ӳKͲn$;H)`CKI9#i.§~0][z'-/sföcSٕi+!$?Ju6<7EKqcBjj7R?Mϖ nt FcX aXÿPٚzC{` _Z<@r`G6J{ P4m2H? 9)2 PFÐҬa.ltb]vcRm 0pD> R ^YU!0Sܕ50dImaYa워8a~a1~˪ Bny-E]8?E>[~n&)Dn _c }W%KQc Q&K5qdN™$ȏb[;, 2Ie &KDHm,Kİik|_I0M# o¡I8dN\wؾ>Bo6GTlXXdE 㖜H LӬ8b |?fuImwĪMO` L}v:z#c<'Pa& IK]Ϡ 8Gg?x@%Ca̸!/!މ#>"d_,O{\f 0(=$EZ6GrxA4ՍuoDPS:z9uYvck'VLǠ Y?͆ cb( ly{7PP(JWDR^8G&SakKPAG[.LY 1)X9hZo=D[i;SH0YPƥ%ʇr*q h٤HJ_lNJ` W R$JJ!@U2NwfAqWϮ.[c,uj4|z5M7TI3V`2d% 2 ~lSl3S9r[UӐ";0wrXhQ]x.w==&裙 Dћk%$jWr>~u a+7DHyShzb4vB@ScF'Cza2DU]d IxG*d=/vCO0Mfm[_0UbjI ("]t@w xSʡnew4oЂ 󓳯u˜n4Nӯ_.|ET~p)g&i@>WX=C thj@}!O3P~,ȕQz0r7 +wk{Y.~IDjo~:=- o -@L]mӈBO)+RdxKmn1=L^ji`eDOx~G>`R}vHY9&noa4` N ?ܕQ+pΤM(.Yw/_qᤲLx*ʢ #uQ a3-cQ0-J)O1\#0Fӂ7)й+,3bPҌ WCюfj}iܻL ܃ʽT7rs#F\XPtY{+Sa TӞX?f Vֻ9ҕ]@鲐Jwݕ >cύZayHeB> stream xWnF}W Q`Nf{<8H h(r$1r~},d9nZ8]9_3Aqyx}]dk!K>]-|a%$vaO "c~DVzb)CNs3'8¨ыBmluٯ^\" _EV[K<˦z]6ЍPͺRnOWcT:w!o d*fg^gCa)&[yj ^U*n*E[Ҭ)&Oh;f]$}6:˻4Y 1d2|3%_HOǺ<1zK;2eG/;S/R۩< XǓ*yx*CT{LN/ >&,'#5a̒Y'Z) ROԱ 8;E{*2'&TXt4iȺ%ƅ`ВgևȾ_fY&%O_b#ivd,ifO'`~^ie!4hUِ:`G_Όݟ. x`27@ r'lu:-SiR) *pp%<숏py gaO{u1d9b^O.} nyqoF/R.7vdj)=)> stream xXnH}W[A˾o3x7,BX"^MhLE(!9U$-&dB}1󒸟bO~YYbafW2N$r?lΣ0?ZP0dh3auMYm[P7']:qHer߫w7Vm<;CFi,B FȦޕEީ )+={&"ʄ_E7jo$Eaft̄ݪ+Dţ^qLe;4fA_{EZsJ??i3Ik^tRW&[ ς}Q%eGMߜ Ĺe:﫛`IbI,q,}* S,'x_4M݌T)Y*O1Ev|UJo"4倆H\#cԇ 1f4BH}pțUUW< fզlVOǹI(w^AY8#'N/OJfVBd޾&{VOc_=UwoQQgqQѾna6}BE3S+A{E!dȍz~C"N%eQ,y+iX#*?LBr 9 Lͱ Ja:' ZuGzӃ^ZH+$ Ec/B DI{m'ɠvV,AZ&z&ybɠq;.@Sz{)oH_&2{UuT%N 'Ug`YL u9+5EjCZMɘ&~at%mn{Tk(i ]N~Hn )XLc[խSYz,9VH{|CT<\^_W}VE0g,(.^bQˡIpڥ(^*#}Q{?hL&6jdҜ1k Ю3Ƶʬr[ȵWS*s p1V>_ { O+H^j =Ck7̰aKAxvZ=q)#$Kjqn';60.ڮ+D2aM,; $<8#v#rnX\the\$4ʲ(/=?\̋iҚ5T% eL_ R FCہj:bXz .e~ܡƍAw+L4ƔnQ\Xbn@yl֌v sByeyiVcÂt1xiČ3bWL4 t`)yt FЁ7: }T{]E)M3#? #rPF4׻xI37 ΄L'#vJ/(4A/fFK1iZ㴺~tVЧD  fԎIS4[r#vu^I8Y3됅Q'EwY *& C_?UtTEcaϬUwP"W ,i?(x0֭ܰe 9 kS+K;ou:ZO[\M}y.>p[^au{ͯweLʕڧnl,ƃ8]Q Njm$?xS(j>G"u2l6F E8l /\,ct9w(%!ƥ.(KoFVB_Syݸ0W_s$Mq+jLS94"f l4~|94%OfOδW3XBQSvF^h~dsjغSPk[!ώWuO|ŔLA]'ED?F'7nuVeFu_+};3œL3؟ n rs@H""rMb_`uwufmCg4 ^hƟ#su,\մqJ}'zecyhԤ w<@8kE}n񅍈g(|KglWmj9  Tendstream endobj 75 0 obj 2188 endobj 79 0 obj <> stream xXێܸ}۪#Rԅy < lb78h[nvKc]<ߧH6bS".XmnjMΛA8_v0KHw])$n [D PF1"&0}N[H<(V5JgZK15_c(AJascADt +5-o%xjYN[0Unm/K_&t" Я4_U<*VjDm^T}ahuh%Šm;$ X%c5)A` fi tY%O<"ir}nr8W(qMXʷ_ `zӶcǁ(ɂY[q 1[xm_jHoi^jn(_թH{ So hBDs]`+hXCƬd 1/ Ysc -J;&!Lhdde<8kfr‡J`1g(ՙ7*jϏ]a3o|P7-> stream xXnH}W[u&p"d4;BıD:$FN" ]UNsb~n7C͗a^2c{foW7X%$L撫*ch)2t_7K(hRƊq–)n"X{x'I\d'TOmۦwcQ3ӛy,D]ٷۡnV5;V=Vumu:M}9Kae&۞%/TQ{9pp9 V`CS7f&,e9koXs9otnXU) ^lɨ8~hPkkү fh:\&, ayZ:"rEw9:YN!5*EQ~UXwqxkbeBE__p\(/xr}hk 2sݘ Xw*9cs1-O0BBP쪡b0EƦ4563n^չGXbB"qoNHO{/íj{:Wd߮KƒO*ϓ>aO!]QT!ޥz8z<@^Yѿ75Y}kk-xC; I ΋}(Tt$Q'"p\A*.=tT=peVH^᠁3Qh/F1F.[Rp%vkyTu5iw=zkلOo鏀t buuv/@dլݛxB4db~&kw{D?+՛SR f#һ!l4&,:*`59O*)CXr"re. ZAGeq@AZ M؍W^350awGHt_w?Mpda [$@,؝j"{&cTI(E$m\ wEy,0H0' P#_N2,1n]r`V};ht?Sxɚ?ޭ:0'u]4cyi]޺D1$?4>nћ0"P c }hg*R$&a*Pʡޠ|ƥC(303pC} ^GߎE*"O˼WXWKfR؈Ie=ꡞ5?AbMz =O[44M ߫n6)2_R\% W*u~]f.3 ՄUZPu $Gn$IEe}T˼W]Юwu|#WOU'*ь3[Q? ҟf&iYf6,hڈy-AC_2V=lc(JjC5Km5!lZ賙< 2k$s#q3@#gbV;۾$~z-cX9t6KѷpE P(lռl!7ffVy%['*FeO |ɓq{# B66m 8@:J IS^U½'ҟBB7 ",1\Imfs\$B<vj<N۹5X ,DP!; د̟D iS@g Y˼tD18V1YʲԢg统>SJ&gO>>ǟsQplʐ9.\`.<\κ1 1* k$ΜyfiՐK"P3!`7G=DdH4,TQ"|9[Bnh@[NMhQ7/KɰIٙUǥ`Oi}+]qd{¥OnuO Gُ[=W,/A7䫱q%42l.gP5BV~n+xn|cª"g"H,gvAcέK G/X A Mp,+N|V:~SUL &"O[K׳S94=r߭n~ßZendstream endobj 85 0 obj 2300 endobj 89 0 obj <> stream xXnH}Wa7gm čD:X~ uw2D][ON~Gc瓀K|517AȒ f|/M=L"ZNЩ%38i"L6OFU֪Cժ{o ON}lҫe? [(oW5VLmWl5)j8d<3axMKTDo\;&5&p{ڪKV6uW-U1Z5!ኾ1^5gEdUmS+#s%O3)vKL4FDIf֊&)Iw+5<5!VZ `A<$dӶ, xhzYe] *v4[ǡeǩDJ#~b5C4:x*1{>D;'O‘eQ*\cd@QҜ + l? "8Yt/EeuSl՘uCU<J JCa ,ToE;!.~-K37|:STM_{䅂DT%YV3Y-](ܖk~@k8왔i̙2"HclvMNbZQ(V,^4OaOYjmB8%> i{>k9L j,WϜ-rT9U˯ι4.]q8zUٴTSԶbhQaר$ T{4 "5 &Pn2_qDiLS7 !dm~y~ 8vY'=GY_0~|Pºm]t1!ɶYFLE@d:,W_~]43/'#nBQlIAb46={uU@Š5ؓv6c2z*{n{6VݷVGʓa֐*52N}qR@j1&±Vv ^!J9 3m|@۲{8nK^=Jk+pEw= ? }9endstream endobj 90 0 obj 2153 endobj 94 0 obj <> stream xWn6}W-"bIyhش^wbSMjmɕ\$KI H'p̙_`웅DvFn׌ڇ,E5XQw9Od8HZgLH& x%Fe9Z>΢;T-?f2G2`9u5SB0+jlo3،Uuj=P0g3aئ9)SǢٮv[518WBFCVe.e~_աs ˜skj;]ۋÏN&OmVݟ[ݬ\.yex àwH&  P˽FseS(2N=M8jJay|_cq8<{ <AcT>JtA,B*ږb{Ka!򼍮W$TƸ0t+{ݠzRQ (ik)RCo.58ugO"PEOeasl Xp>ѭI 9q$ߕ]BnPQq(7_i=kP1P:w<[HO5tn\ꔁ z9D*tjٝZSrR M4 P( "aRcT: "P K7R ʘ s¢m7(98 5bj7% }X-&D-xn:AT1Xo.~ WLk_qͥJTS`'i@CL Sv1ɆRaOT#24AbA`M/wH`|U5<p3wwcف`w?۳1VQW!8FYx6dí7392w7 PN2kɿL9\`XWkp9b,x⟊D0D8AS(Fkh,̂e9[ Et J`, h7'^/ofZ-H S'8[+seVt_j,X\E􏏧CiS.9™&X_ *=ϤG'wScK|cx-!J'Ҽ] ݫC0*>TNuP)vRP$ r"/+4ю~7id$N8 oL'W NㇾE\s&1@XLnIܔ{eCGX7`azj3< lܾE =Er BY\#FG}괽 Fh>Osf9~kLuendstream endobj 95 0 obj 1558 endobj 99 0 obj <> stream xX]o}ʋ5Sohۍ>$Ht{eWM/{ԗd7H299sп1%׿fǯ{hW=~[I%_#i6*)5m[o#*^YgWî>BME9m=IiڢbiӤOusL;zV,mپ.fZyֶo[T#|YKcK)wu$CdeIvEtkMl#s-c=.53VmZUp4UGܮ ~ v~W;NiѬ}rY({ZUI7SX>Xfڮ9gn<BB &bh{2!Pŷ^ |rn()y0x"[or`řl1sYvHr(w(M@?0Ⱥс(z8? ds_Oͅ', NYZOLa`̳ˈ+/k0L]1[C.֡*U&tۧ}]*7nTnx,lz}TӊB:t/O72i\eD#(-xDgX,KۮeŞU&3m6Owk hڢz(MU8!1k5tNʡFFY{JN1 Zg0"Qr”9ԥf[x#9;W2G:sCƜȊuOByy<Δ3wknY-Ef#&"\ɛ8eA˖{ЕB((ȴu7igrC⼩-ƦC_ !ݲKKOÂJ/bp:]]$G51VσW{Km \'j `S(JZ2FwG1E<_~a.,$`(^D2`)r.va|j驎PM]m=gh Xz8TeEȃ5ԖC-yڌͫE]j( VvIpUK=d2vT)D8Q*Z4С͹b]_kY,'I!F|F"$A҃Y0XA6eYd@PQ`nЩ!um OKQGAj$myhġmR)ɋ k&d/BOQI]6 bѤ )' .W={+45Z-rKd5rڨEeI$:z+|C-k q2rFg7a**;oO# `fp.4qЄ'E[H@+O>gWi6e UWPӎ$B#P%ܹvm禮/u1k X^Qf4p{Ph*G5!A.RaL"` ?nA$fτy%ڲRr(R}Tv "#B+kWuܲU  3DqFΧ^}Crԑo=MD||uHf!Ar=(y: c֫:+[jץ@ zCJċ}8l(Wݮ%vyH Cc+,*RwڸHlu<`*@cR` 0޿mŶ*muD+ǶeCsW=&q?vLm%0-g: m|^_g}pHգ?`N`7ԙ=\ LF"KMvO%ҫendstream endobj 100 0 obj 2186 endobj 104 0 obj <> stream xWr6}W-TDyp&iqD"..%+v[sv.?2[f/d="}1%qy1ɢS]f&#<4NHgdB6iů`nXVи@g"7r۾#Z,p\t ћv {4ىGIِըF*r@S(KEɽ6X_AZ欤e6R%}-lA:dQ1$M ! X ^=a/j6.5|JW [> |WAUW}3RUkM%%8IfFIf3vKE4brZIjJuA8Fe10'HDL!qbĹgڭI1s6Ģ<Ӝ=sפYMcR_J9/?547u1Έ,r,@i3cvZNl-9Gi͏WUvt*/-OgѮ VVF4e'&[3H>*RP۩3vbX,ΤMe8qGuQ/$h9Cx*oڌ99.AR)+9fH)B)' 'Np ބ|3WoQQؾw}6"g~+`G{r GXzsECo)b߭"Q)5SW)RŌ 'qϭ"!%(:w0c̋hCoZ\E@^ <xtB<)`[ H%vr/!FrC oNG`?ᔖޕԣEHmd[Hy.;naЛE%_TТV ei%Fۢ}ImO;Oȁ)R KBOf0~ˑd1W쐱ݡ9#K|s|݀Sjc3';fIv1_(B{>U9_, X,pmYa,$mQhG;V[if`/v}ݪN߀_ZZlS{kj+`)w;C/SO*wc[w+z .*FIVۿWUo~( _w|][ZZ3N A INOI#7OX& ^HYpqNRiQub'/3ƞ&6)hb}=8@&rlayOM^cDڿVI] 30 n o> stream xXMWf*5 $c3qr|u(HW5I3[Ԩj$nt~/$ϒUH_V̼$_q&ڮ"-`>dKN#Ady>5 ܬe aDPM U)_ow1zP=QZe,Hq7zgs7}0'j.uUjr],΂'ҪЪ$UCI{%BXc!S^S98lE2\!7,#*x54Zu_0@6&ԛ/yw.oC۝wݕUq?>n/no3oJf7B1nҵPnw?r/YV?\q,!_H}̾1X%h`$,8@aHk_6/R7u1c)fL9a4v'8c~֤R )KYYIYpJ)!hG!Y9v0UÚ7 pkDɡS8m iXh]KD o rbzd`o(:nFU.E,?hz(sN*ASQܿ, 6~+H>eȦ *SRa[i > stream xW[o6~ׯ[xuKd Ut0dIٲ+5wH8]З!lwnD0ED .C]@:Psr~nQ?_MX0(1wS$7"F8&DH¥*ͱCe[}]YpSD D)%fc5{ KR OhW~Q#`%q(>fpY .G#Qu΢hdc\}7P\}xvjRmk9x?ܶEok9Ohd0& ұ){olp'Rf6#!!X,B辶R%C7^d1.ޫXmjv=H(ÙS:n=@5O!,$3LA:p⿠u[6RhSthY Z`X6Z7u1Xb;9VUSl4Y}Beݚl2 𡆏/],)+;bB$Uuav~HP@H&{]c ;=M}2ON۳wyF/g%>-ֳFmgO_tjUs$(ӷN #&:vLdqK B^}ݲnd*"|_PZ=8*, SBǯs^kzz :xR&XakըCAGv?~B ~q]JN w # +Sw\a]ra[#/Ϳ d{`GnbR\#7Kl^:w@g {ǯzelpn4b "Ȅy6Hsv%#cdUR /M@c2?I&~]c!7M2$Yfnvc<:L٘S5rB] `\LW:K2}@"@3j?n)endstream endobj 115 0 obj 1315 endobj 119 0 obj <> stream xXێ6}W-r护,0F&x7݁!۴-Hr;9EdxKb]Ogs|7?cg>>τy?~9Sl)!-w3+)%WUĖٓs\] ECۙCe5{ZoYS&;u^|ͪ3*'1?tsX֨mWyt.»q8<ϗt*"D}AyЕf0(Y?J 01k,&LB)[(J.wK'&zZR=Uݡ5焮{'{7^ID](Jޱkβb= ڛ/Jp!E^E^7UҔUN:.$V<<Ё;t]>]z+n{^4y+@n\Js@/*YSAL z+*DFcEp@} Ӛ*+]Yll7F_ąB.^jrE+fx3N(\迦UND7&S~]V^]{?y@He╃~1_Ya/bW—iz,U=as{ɪtn"a!?n'*zCt5:_boL&te= ~ jat@};8^ʼh4&t}`P}d$AoVCɠs%&m:[C_ŴFۏJZǢӼ*k$ubCU'qtD<,@K΢,488 jq%Lٛݿ"KI\T7ٟ\) ޘ%p_Hښ_mYIo qoH8'Cj9`?QJz}h={k1.D7Pޱ#&]#>Jրf~hwJAHQL1jUϫ:TƶQZSGd^eY3EfbZzvy(:TMbhbD3kw-r}6+"dB2H.Z6,Y#05#$reMSkZzFn̥d?ૡ+xIP-Ryw'voзQĿ3JJgM^Sw۝ A[j d4-5hR2JS?~oX&n(OާA1 Od\) vXG8_v L9ZMendstream endobj 120 0 obj 1943 endobj 124 0 obj <> stream xXr}Wmoxܔ'U8;G}S*J,f$RCRsp#)ZSv$>}HD>|vٷ3/>,f,X8b;;"&H0{B>Ipp]! ofۻߖ_>_w||*igV1YgAQmȾ{20^]Y=üU$ҭib4ծr6dB"O^\#SӞ&N(s"DoT|HpjjRÇTXC!%2@.Ri촔,vƆHhzi$0tcb}y5rR&s1 )ȱhTՙ#*ec6XAHԧhW7@/9 *d-iH[S0gG=75/AS -z=ꪂS.li)ݾ!=u}IM@Y-.Ƃo&sޡ(E~Hh/GA'xO`ё}$ p7RM+$y1cC쭑sl.o_r_б/C[~`×jBJz;Mi'HgB/N?4qf9ɾxh/</StuXM!cUW.%&1Mc#1"*e`7㼜$IjPh$\ՄK330c?Y!,npbx}=ekYRgsYcLdY>}3U2t2 ‡V`?I"٢5'9(_tqb0ZR̷[297eQ>B,iT{ok.dB|TAtۺP4kfcd$8dgEvr/и&O&uHR뉞#`tX($i?2OՖaif&_?dc-ըT5RUw t~ѸUG8 Ty"ne3[4G!H\xܗbW7: cvА\$`}n3ikb` Fx -H F2l&GŔt`RE_]^<6SSMСW//XwO5ETXءJ5-bOjݕu// ,?hӮvm.s3`x76] t]r z6AbZ!O\}w@%|:":,'7T)TD$x\#wX3{6WA|%)F84p{g/ ^h$c(`|Ɓ$z;96%Fy6g2-a3@ѠT}GmimTs n)wMZDl5mS̛'UpY4BgSppk<fD#t4P neYT%KR. 9yյou͠Cުˮ]_+JgEI,\siF_% ^)Լ/o^+J|f iV$\eG\I\ ݴH3h\ϙ$mcS?BY6h t (6\˞ 6EW"Q> E#\#<$!FRNVH4$a?"̬o?-fWendstream endobj 125 0 obj 2193 endobj 129 0 obj <> stream xMoF{3upD¤dq%HlEE 3wf>!)"^7evU@.PfI XQlf'E,f s}pFl$ E4)]Q6EpL@4(IDKJ!tp%g].u̮%Ж}x? 3fu"}!k8k|2 Ev7>v(}];zY~gWݽyr`e^E^YwJFMh擥 Sw2N [n EUNVJ4B-z)T=P$V)5M5.5BBvѢ!YOG\Q,!NK%iR 榍N2mjv(u̻[<+,u^apJwºp'Nx 5`|iL{6eT>Lĵ:v٨.͸0%ñ HI-wZä)ta[طCqLM@.P}]UYCY־ם9ԇ-,}`LQ{+t5ƗT-@\e\QSl &\>{D`bo nLQiCWuV]= 7ÍITk}fc Er趞MN(;f6)et|\,']q%,mLr]y2(qVPFY'2l0lD  n?[5[NyK?'=>n~'5ej&,pmٿ7o$ә )8%.CAq~2qwl)1Og{<C'W ^Z^$Ny9~sRXu¶9A3tB5o%ֺfv;8ӧ4SS:Ԥ:<_sϠT\E&On~鿬+T &MEnVјx>OEqo.m8(t΁$}$fX`=> stream xWMs6Wf*c"@ڇIJ{;Zd6#w Euqf۷ψ`>ׇ A>V VkXE)@K:,-YB$^])l$A͂a_Q9rBPB̒klMC|\R %Y~idb@=ʆP9j%!lvϯCCݥYb<,5(ˋc^ȓGMS76bif6NWmjݕue*%D|RpNfX@Fw}Sc}C#<ԨwekYOp @kXTUtJ`%r&4 hXM1p/|́ fhQ 첣)ũHFR{ dr$<׋AЗ-KJ9\#$n[nA+G*Cdo>[@@ja [Ar FB%qea6+s3p>_ Oxۼ8[>Qd u~~kWeG뺯S3T . jy6ӺM -|}FE)@Cc&  =m#Mp"MpDI,|+ m' y-}۩1g )7`@qgX11lh1 S R{uuQ%y:;U܌}Za0#Aib7Hjdv~Fស\# ?] zl?-2Ynsao4>t|j!>Bhf袳w4^IYʾGID)]3wbd$S;ۿv Mxq)5o1onUѡbWuي"\98:-#Ӡ_Fvh58)7-MWe`J%[3RӌJRh*+@lFyL5+-:m啦ܧ#u]N$y~G@&p he U٦%47Lݤプt<;R!f #GI]9!v O2__tG(#X0 H@E42"pb|0'<;Fn~u? aI)3L曠I`64]s)k^` SvntJ{CijY \"̨N&# $ `Nf8E!̎W ߹E@n'}Dr`]T 7endstream endobj 135 0 obj 1442 endobj 139 0 obj <> stream xX[o6~[A";igC0dvԱ%WI}EeEpb<|ߡ~'rٷ3Fg>$8V3IVj7s;9JP%S:Ebտ<+IXL ΢K_}edkٛn-7_M>FoDє,aOٜd|qx_#lwa/U댾ϋ\7M ~M(P&g"MoS㓘4 ]s.:ribL+>qsύ3OM}? )ejgKP{_FwJ pEH a?Gm`}DʖZF΁F17INiܲ/B +=+9*| WULP}ƮɫvW7uW,ۯk*Ϭnsnkp}bcva]|G;g䝭xI*2'X@_B3xrh…L ޲!pMeppkЭXpfda y.]MM;W byG-T-+q}" lR@07 Fp6sJV`Bj\>t!B|*a{4}ݮ5S;O?.貲8sd{n}!Fv͢`}6/2h/e'&?^IF\Ӕ!-bR&˭xFgo~^`3]7!L.p>/"SI G._7|Egk<=L&Yg:霣<ƺAe:]qAuA$؞b:τ픑4|K$s~!k@ LDo\m)d6QR5VIJDYo+i j2 jvC`XjLG?7ӖWgr T4c5' eyjr[iΐGv-x $XzZB-c9~A-p3/VD{cRfR}`sLDZDf>8P{-o2fKHq=;jP9'ŝmM[4$Z1h TU ,q91]=u=Ip 2F>g ?D*ru$VVO X:C/Z.sӘ$ͩۗh)}725qmւ^JJuH ـ#puF[1Ȼ|s06=e/[.P}Ao_D . )}=ny)am``.s5d<?eunǕL0tLc'05+?Ϋ-*`eV|dr.€+eE#ΘL ;vw i`` >G"7'T_Sl-O%j3tdi gNO'YLr1do-K>v&v(Lmi"OybEkii_3 U~x֍:~p}虏.;-Ŝ:s܀lد{Tkg^endstream endobj 140 0 obj 2027 endobj 144 0 obj <> stream xWr6}W-TDˣ3Lf$NGCIM:"e' Kqb%]=؟su7ywж|Pڏz?p4_e7").nrl2twRF8&D4a&`=)P4rJ 6Fk,PUt(G*ovU H6nl55zhTg8=A &0Iiv%bi 7sH7Y?˔Rخn >dWg11kr_Xl q9BE[s}p|Y|^\@6^oL5\jo`ܥ\ L Eq.S-q]))+ :W{6e=:LC{ }]>|Y\\]}%]iD* W.ʣ+sq*| e!du~KMǕNT.PsX uȫÓT[ް}V,[^nϬ][bg7av&= ]\^u-G%9^- ?L@3Q^20=e,ϋbL)Pg2б(01 `f|M&l*'8F^^XG_B݀#$0DR.;Nfbk$'Fvޝ d*LF [dųJ2p&ذah:БL3΃ ag;fT:q:;BRF:}wK 5ZNa^Ÿ )aRZM.#͞W >37,ʲu 1B20hw% pt܏0)R>V0s{1hEy>;BB HIWa+B) : 8ӧt)b} JFpV Mn7Ӥe"$=[bim_u [{gp}[Mow > stream x͘Mo6U^,Ip.65C0YNRV7ȿ!)J2#'E  `"g83meݡ}nחu矒ꯙXZ9ʼ]e%æFaU]Win_>Q4 ok`a ܧYzPfmQ(%b4EnG2qhpw30v&A-8h 5yV@~$O|]G^)WXjEN8q{bs93柃3cR,[(zE:D#kjl0IXJcx_Ӏ26.egIRL iGx*:Pk"J[5S_?U&,]W+LU9~5$9ouL$zTP&K,2fpp,͛.[rO[rHV=W/[تD!.As{]vI]:ڌ1Y [nRXLFAW4-?~\.olfTCs(>P&] 9\XƨdΪz[덣D`b!|;Eql|>vduX;yxrw~N-X oai\* Uu^<"FHК0Bso[a zT@!'"004t]g&ɬ`Ȩ>nmHmMͳ`oزX@i+2A+(&$6㙕tMZ`*6,t=,}_\ 7)C ѶTV-jC^bG3zZ[ۑ}H+ dVʦ@ =:9y0ooŸaPٓ.f jzg@ ywnWoKQ=^>A{Y?'i Iϥ=|5da 1j_yXDmSqi"b)eϦ5,8I~$>Eo$d#'sPdq=74<,.C2ÅɞfjPV*KrWmk g=q ?_gcendstream endobj 150 0 obj 1351 endobj 154 0 obj <> stream xn6$EpSt-zbS,;*9+1;1Eș?o|GSḐN36GQ5_34B4O`e^="&9@g ?_^=7FBLGAWZbW|RlW$-?E 3zjGf)Xee1.ЇDYYϼJч]5xW[0 >XpPGˆ2LESIms`JaE3|M=V,E&_&3H2S0ZQ";ټĔqK&I@W}Y֝n47?~0ʏv%%F:{(,:qcV3b&>Z>58/S,e|8 8%8(1 #GʇT u{[N F@ R^b &%IZ(PV"/gF?x/_*B|Z9mrR5+QKXθ*-"{ QEReWM!V& 1+Q}dRXlwG((.&T3vˏ&TAM>\J!Zi0[t nRͿ,#-D['GsbY6Ww̉M ̇})Db*!&J.!#[+heS E(k5ѰӾُ< s ZK']@E_t?t5Kػ-jg]DyOjr^wŽ8r.+5՗0N;qy )=q.C<͈SSۗEkU>#TwarorDȬˉݴ\of*m΄'ADHKSBu!ft;N]dRB:`fXV5 j&ȄzdF50C#t 洣3#nE.8[#p͑)1imh{6k*WaXO$.W880,_MňpCPƴ{ok|^H_1Ye.m/?p-AlGOyYu_+6 nǙh 5|;AmN|ﱛI/!QؔUl]^}tĢ\UfV׎|hA#ؽK8zL97A:bfZfF)Q+ˀ26>}ݣ{ Â1%YpV8Z@ǧv*IK4@F& [} ڠg+갻+ }M_d Cu?_B!=[>?ԑendstream endobj 155 0 obj 1394 endobj 159 0 obj <> stream xW[o6}ׯ["byH`!C6WhAPd:˩.1,Y dw9;D0E~V in/u?-z 7IX0(1Je$$"F8&DH¦u^T^qexRm=DZ7ꪱGPSoY~Ζ矲b7e ۥ& +>zkЦUh$T&o0kS#F®w+(EDt ,M (N&t%tfy=@Jiu&kUxGCH%\em[]kzLOZd{痥A}euiN.~$MmPn{NKXTW}NůY['h͔/E2^Rj7\r`\$iP ynJ ʪOq,tgVdʋ\MUW WkPܳ˻;t53 Arɀ26091~hQݏIX`N*]zYܷ^ce&]jꚄ1tEaU';Tr9+JVdž9f/6,iw5+>+ qvFYq%YYɪ8<0ޮʪ']k|Zا&b:ZzMGc[%G%]^8ƌ-eƲ(ڲx˲C|Qҽܴ@iRʿr$G{b+Ѽ/7nB5zb-3"^l,&Kg ﶦ{CU;[7A &ob"w[GuȥĊpۀ{-HXpp?бAXp%ܷ7*}pYQʳ4>فendstream endobj 160 0 obj 1136 endobj 164 0 obj <> stream xWnF}W웥](@.6[GhB$f+QIYwf/D)qRȀ!rg~"r/5yhF<>;$rK^F̖p ?ɉЂJEl;0NDl̓__<&)c$)\Zwie4lI]j&Ѿ2O95܊Qd+y"M6U޶|oI#cAuŊb-mA] ׌*+zW3b4nK`[ ,^FB2UGp'f$Q)F*A'Wx_q z=WĦadzrW5ye0:|/MPj??N\jG'laO7PNun1TS̻j3Ӳ CUԫ[x6s7^O-r]KxoEE?`ղ-wՠ[FQ+SrR phcƁk 7ͩYhC&F0 #K&Nerq{a= !Y>H)ziY?ð n?e5M5py0a[?F)m@\p5U}Eon̓a/%X->_j!iF;"7MPaOw '<8פƗlF6b*op.;c RF b]R_͡l78K@Br%4F 8Ђ4}7GAT+>B%Qz8_.9_kLrjG.r5kі'u*Os/AQN}x@FԻk-e(Ӕ6DqڠV^p|\׸dJnQY؁aZZHݏx?\?j/`!Jt:_X\'Wz Tߔ9|W{핖D >mez\_hDk:4E5 $|v)V=W0h\IPRR,(%),eҚKR|Za+-TF* T) 0:#ȟ{c Xď@@c {i&c ZQ ,|=+rqfy̱Fs?f1)w͓Kv1'J՜T6_>^Ľ}ܔƒ\JH*~C~ )oȿh Qwsf63^!n=c~w_%q8,PU+Rxt3n|KǬ뙴Y> stream xWn6+i|H"t)ҺnH Ai G K%1iD$s>#)"7WKvmD.Q}8Zae~Vh8I ^Mtiu?֨]ԭ1!g>d %w>ag&xam q_wA:Z7LbXJR 2"'4][ހ>Y[δkH8]4aߕr1@6'̔&vb׺e?F3kzMuZt,yk?~ghл?fX)s[۷Đ'04q! REXF00́#no÷,0r) J3BqsM$c|4waH&lI.|  |Pw>d~0`ʲt!<   0{mh2jϔiar<̴dۡy|,yXHX=*"ٟ&W0T<1s 2 Cj@{.Ƹ;}4O4㌉T]Hi%退*u唉^ eaP9!e.?u6dFN Ѿ{n8 DZ݅v2 f(@[40-fIag%°-#8> :Q< gT^R"_D]F+O(1H(Z6A$B*x0,&Rײ u@[ka(ZH--|R >UW/D_VpTjd'I5U{/yc4/h^F_'zOއQ鞨{aN՘w8B~Z3> IRڜ:jd̺\Q(KO}z99a@?nT u:/bԀ*>t endstream endobj 170 0 obj 1203 endobj 174 0 obj <> stream xXn6}WmEMu l"6BPd:6wH"{l)"93g,޻DwGН٣fُbާGi(CNwp"&It_C&CN^&Y q 7:GhEBT#걘X)K :M4O +$Ek'I ecXVO-*PT X|e ]]C, OB R/_m~"h3hcB /%4!n9M9m$]MQiqhM^m9Ҡ}(qi9 me6}hu0,YrB[@9!t"tOi"Pa(=d1ui4HaF8f=?Bj5ub0p9#,C8{}(q%&Cεhm ^DCriİBq+oo՝0v!ZLHLϑ#تHB{A(q$(_NR&8(dT¹fِ1pf\l6WShD&۵͉PVߪF ǠԴ n"p1`ͤp2C^P,O]B- `3GWgX_eb/1h?=*#ױ/lQ>lRJԿJ{0!34q;_n>x?xϰbLK >TkF;Q3PAzFIL=K"~I0Qendstream endobj 175 0 obj 1171 endobj 179 0 obj <> stream xUKO@W ;1ȩDMeMpE"}gqʑݙyT>]OVEae=XL 5fYZ-χ ![[W9<:/V.7@ʲ/mi)  eWV}{` X+آ߶M'M1Das$qY^nF1oV]*/kG6ݣ¥mP dT<Ƥ\S+<lvhZL[vy[01 mf=JnIͶs0Q DNƵuu\@(&$n,MכYBD'0X$ݬzwÙJ0F"aU?n`:E6KyP}&L8GP%BZgsDW⵨ rb;A^V\ۖ:{hhߋC{E/*D19FV<_,.J7VMk@,&I+N17K"##5r Ɉ % 19^Ăp`/TalBљvXwlru`lfe7a61r ?f?U3xaưr<`z 1lIIY]Lhv4 Y }?P89D`40x]3>&Lendstream endobj 180 0 obj 776 endobj 184 0 obj <> stream xUm6ίoCE`2I{>Na[,!w%ٜ/\Ǟaw} DBd~g~]fZ#s/B/s,&d {$Os⹨1*DkRCg)X]WyZwV~B &z?PKbgFKj/_Nmiξ}XK^î*vöΌ"r. h ~T*g셮82-t:|C3JNΘQ2'0m5 z5ZTsdsBJ*`?KT\Je˒ H~3Y [O&IBĿz0aÞ5N_Oq `}M&9ɱbRsHwPrh1ݰ`NAhDd vJ+T)b5 V~YZ=v-%(u B(QX]ٵe-dYٟ L3 VV4uInYi,/d{`ea/xM_\>GBB?T%$hz`1dx3r:ͥn7YIC52>c6!hEG)ݮNNmW1 "${kߟ{24LF"ߵp\.ԁ(Ę`BP Dcӻ$u:*^uʌ[4=ר6 Xx2) ,#p\_ʸIH W&bhyi]u::[KɡJDWhΈ]3$1YbLBF v* =Eܷ{!hnA>q6SpO!MS{,Bś*9&R^g4u$.x95&der/lHhendstream endobj 185 0 obj 964 endobj 189 0 obj <> stream xXn6}߯ R)Xˣ5Pnpw.vVA صHg̜3c|3|CkW>ڭ^DG~mV mrE(veNDCG! ~ux̥wS|8QaX9Ǵ&kʬ$*(MҥN}od9J8@^ˬߡ"۝-jjXJT?V)Jy`~J[µgWmdy>'eUȯV;OpW,x6+ghWyW֕yQPP81qm[u`SJWf.qGePWu5-u<* Y}+Go7ÅoP~H[{=ʼܺԇB8%=ikpH8C<6\2++ي7j b&lgCceh%4X@,*iUh ;sLBx0X%0$1p|B_ dah%۩ ZJ^61 Tt\G5KvivM (5$ Fb.z)[  Q}~:M})m>cI)WEw.'Wޟo.?z_8h,j;({TZ0!i"'P0I ҝFZ=USdtQF5N8 7X_f flr /@(rOKP2Qb4=>vod^7Y;,j2l[itNG b;G߹% (48h$}&QP5//oZ=K̞]H'SfB]p+@Qdmgjx H8qY?bendstream endobj 190 0 obj 1710 endobj 194 0 obj <> stream xVMsF+fP|GoɩT7ZvsS*$F2 ^קg$$Tq7z= P€_mQz_pF6U<E0<%0)enso\m Ԁ{$9RjՖ$ˆ'n֭YlRv0s . F֪oCNjR-@w׶M 3e>XqSCWn I} ~V]Uz֝)Ǩ Q_^ܣ Im*3OPLe$ ّ^+ EI"pFM_6ѰnU)_,/ ;_OH䋲gvq=m1(,& v8d;M9.EoDV-S 8}^[թZ?P0 PkS-gDAmkgMaْx}(N'&A>ue̎~jO N"~MpVA`$I̠|0J(_T}'}JS|ń:=5PM<̏F*u2Qk2sRZA!3| XΚľj n|3ƌ8 'gh+XKkx6ew`ڈ_wf5aPJQ"xg7N.XFyL̈́XP*=dq6ϻ|>xYxjw3>Yt0of<:M}9c7w E_N>dwH>5>W}tv "1%yT.~/eZ endstream endobj 195 0 obj 951 endobj 199 0 obj <> stream xWKoFW̭d`nѱ4SҠ "2 Tȥ._m4C$qfggo@ _g[|]Qخz%`uO2'…@ޭn-GܣV_^N9 B **Sqe:4Y<ύ\n-dVa!~di9$J5ϾTmd4~LN&kwqQes|M$FS򋦩x'ǝs8!1~(Z\d m+ʤU<d&Ǝu!"ٶFcPex{o`i=1f>P5ZH!L %ۮT dEF\6R)'ҹ#Dn?w61 K+B#:EM)aG/EZ'lښpH?"4لD`]$HUFf0k+AVu}((Ii](N9$ͦPM<8ukk4)\YymuCR 0M]Hgh-('ǧviX zd GuRIę$&zLaqݙ CZuh:D/]XCN6EYgC&'gNq4dXٺ*k 4*s_7}zu,:;]fq\2 8:ǚ`csUAۥa*̫ꚪ](qqet ܑVRe> K.#a85ɥNוV;]XB}(] g/,~ կ])* ;}ZDH lK뼆VrFhU}8ha#'б?ۇxJ hhH‘'dEUh`8.XT|bQcKi EƋ!0O6TO~ܕ m1 NBFF @H2Їso:aIidU 8.[ŘzL()e4{(П Z-[b[ ޡr5wQN?L",p}?љև)SL)jTI@&pp:є[k> stream xWmo6_o_mR[:waH iG,4~GJ,%Y!E&(0w~\ѡY v_,䰋P~ѝ$3bqqlIKͯ`N4`88Cش[8$Z vB%^nY f,Lz7{7wmQDӠBR!}pgL=g0:c^x̊j'\0$1w ؖ=zng# +~}ÛzO3W$l~Ƨ}aΜQ9r<e+0`Z 0`kdBVRQj,Y%)fQ}$HG9SYH\(YLp;\Iɲ΅UQku8FU!/ .m?M.q/y]v;`31xrњ],6[anӁ ˶jC%wY^W~„ޢ ̈oy/O̊#A֖rkΙxo!$BqGMHlva)5zctE¨gܚۚAM+T4M}#tXH's9!bRPcb:g%&=liL;뱝GtuA 2D/&AC̕)+Gpe 2!'phn6L$6Zēy"H<31:zcƭgC n]m{@撛 J]!/P_DGBkus_1ֆft1{ m%zef֯z%.~먏y0Yݘ&%QǢ4Fϕv~)BG1~kT"%@Vc=t!iK]aDžqcz& H NAFGvqi,0C茠[].FB d`Џl-nUHġ6'3[6/|0q(˗, Ԕ1B#ʖBMoĨfwTObA8 ~c/ @C(l|8 Sc~^sE ]? 8费)rʼs^r yt)si s,IVXKݜcF8qp\yI`,?u??H6?_endstream endobj 205 0 obj 1537 endobj 209 0 obj <> stream xW]o6} R9maeK C2D;*dɕeIN eǡx׹\!r7!7 F/ nIț%{[t79GB7 Y{K3lZ02摵M4χSrxlB*a̭ ]",y}.bgK8=GCQ]s>8-30'mNJn05?Y( /Զݓl_#xx5:JUgZ-_ڃ_d#l}2rLhSg!L}^uUW ? B;]Gc>o.!qB"G䇼5<Z+3ɒަ)ٚC֌ oȶ@s0`}]!qoyP;մJ"=7p(R}gjUjrSQ{rW72q'[{WPnUv34ck ,5샣w}AǪ3(m0iȿ1肆pcb1 <ǂ- u[YR+`V`[ʡpjDKMrMRY**cՁkkV8В%0:ZB 0 Q6yHdA#Ĵ a<|[xW}.<ЀE6j)b4]_ɧ@\aBsmm^k#<K1zX,NcޤӜB\ X`Dʋǿ?z6~z΂$f` !d`sm:è'֕JRW%i4@V1BA0OpDH*"704H*Ɨq0`Pl*RVxז8b^NGb:b}rLM`|#n7 DDc#{(QcgExۋZ-D>=DHS>zu^J;MEubht[BX|?~Je#Ȳ̺NC%0LYU\<\^ϖFطUS6Ȗ1@ZA"ܣm„Up6"ĴDw9=sH\sT), -93d "Pwf0+ӰMINڜba1C3N9 *^`'F Ibh~l<[ 4 ?[[zXM7[lo9G3$g@x>`5iUu`a16,S16S5OiL, YV;C^l%*Ura*??-6Q!M #=aA4UJhPe3_ ׹؅CQ38޸0)ŹuP*Gq<$}mD/"Ǻ5v-BWۙQMb OSlE`TGp/<>݇Z?/7?/ ~-endstream endobj 210 0 obj 1565 endobj 214 0 obj <> stream xWn6}Wy@΢Mqۇla‘!E]8 m_  "g937}Z(=gڏIЛ2S!]n&EL1R\wbB`;F8&D CkP}UԳ'TBb16濬7?ۅ;eb,S~Y ]Ue5 CL(P.1l"mr8V:itEsꇵ#4mQjRp@|1Bw] B M`?Þd7<:(uApu!ޓdIE~追]|ʍU~o LncB/Sg4X ʒ&fRQzB8#6+:B'*iE{yYy Ù*l`MBA DV%`I>MȞo'X4⛫|>5F Vr2;m縍^ jg#n?eJ:ewp++z;96i?ipN{_NMea|'8/ GRD`{ s_=5'LKqL%H}/oݪP Ja8~ܾdT0W=8us%Տ/KX$rZX샅*{+A#k 7n:7p1.^vsO@=<8 /ʍKu.[H.>ӏM,Ix߆#cendstream endobj 215 0 obj 1193 endobj 219 0 obj <> stream xWr6}W`*c;M[Gm"!D)XwDq۱=s/`nc6˄ڗ{d;~>h)gIK%a8qDX`C:ty"!"8zv"0g*/bS|˺|p PX7ƙY_,o*VmQ>x;5D Q^Eo=ӫv1/O^폥BL?5J!gm8nӣwU;mPSC5IMpkѺ-ؗ& $L ej!3pB%(-m DT\+ ǢyB(,N9<2Űrx.LQdc$Z5{0oliټA6(?%Jufx@7:+|.hoEeD6AY''(9AZl[ӫn1JCw0-cqJLgi=&tw+@Hko6> stream xWnF}W웩KErN/<8@+D)$ߙ%%SK ݙ9gfΌ?F9a v!vzaK-y5H2/櫉ɉ0JEL|;b5E21[)/łIʘ"d^N504UOgY-\\M3 EgV]Y ٺwSU!ܸ+g93gU5YR4-bXЄ`WgvyXr#eeMYE|"9<-LJfא,~$>$!dޒա.jWcT'<$ M9_mjZBģ`V>㸋ч'9eQ9XKT,YFMbzvՙpPH$ΡD^_bU5ͷHS|}˱,'~E#"jVْ,YefQz(V Qӹt{t\AԄr {[ts`\f/Pu_+K9af x'IRSm*hh2*@^`@AWnU** YO-x!9ҊS7̏!r*E߭KWlOUm||3pWVh G gp M{{u:*|eѠU+w?ݾ!s:{!Kxmx3(evFeߎvͶ  @$IP=PP5(Y[r? L0Qp5d1IJ<񾞩JjG8$ cK!ݧ"18HPx<\y B;;4u븽8p>/RKM`.G%B&4gڸXv5ip^gbUzofW8"Xq3 ݌br4J,S"bw_o<ѳxR =88"9R;nS2zͳN # Fa~@В )=X(E&ש/Լ@W E/3Nb,+gmXcޞB1#fWէ1.pTA#)0|q3Z'{pBEx/^~8HUˆ J>C DG`VYG(9ЍM^8V,OT-@adP7 4^ĉƤAa`)0*\(x乜f(4L믊1f(z̅.Z⧚]h_v ʎF f|| |l> stream xXnF}W,*{!ǴvдF:jE$&bIv ̙3g L06FfFvmFK~dr2U!NX0QZfw"b78 ݮ#EYP-OiYmqvFժ*/`2b,N[._m[Bo?VBթT5r1=y/꺪|Q {?#~Y)ʬ-RG0S$p #6_1wwAѠc]i$,/rBj>u}m>9IpYxrX"].m'aM$4'c&\AWH1#0Τ?imU&Ep" Cs+1pHr5K]ӢByU*jNu(ʭ%/H? %C0n]}/M\DXҁb_\suwA*wUDf{B'NiWd;T@1O[H l]x3%xpZ^D$^]b8z͂' 80Yzƨҽ.iN h AZ#NGAڠD#Y=bnasU9ӽKeӦ1t!L-!e`0K<0:Bq/αÞBʶ zGddXhjL>蘝Y *Tz[/ж[qtq+K ؤiiR^` ֫!WFn _XhS9Э6̒9Դo>XWwALteS]ٞe`KR>Ӣ&lˡBZ舶Bτ ^ $LH~=RDҘNcIawqƲd9*ݛ@KĚ'`0ɔ8[Æ^ Mi`"' 8~"y I ũLfYW0_ <ҎڢX1o?/Dt^q=ѕowumw`Rg, r恇Cfy`,~r$N&wNQs>Reʸ]FZѿ`8DLa$%쩉/&x:7/QM4j}>D>cۇ/Cbqq?Ͽendstream endobj 230 0 obj 1784 endobj 234 0 obj <> stream xWn6}WR9X^E1 f![$;Z8rV7wHM '0@33gΑ )" ۀ}%!g> 8JsEt10Hc$NTDŽI_5kv67]TSW®dEI7CρT8FZbMV%:eSTC\7Y\6YmcJi#`)$J_0}*T]u IJĦj&3IPaAҝx asB+F0TdU2[ɍ*,T$OsM l kfQ Ts.}K(DlñWuGAAޙޡu('L{n`'D&̫44vAlTe/3>٤Y1l{VU< H\$ug{XbĨ/bkUO&8I- LbrgsqBZO3x 4$dQ9y#8G)/K&d4MdiQ\8P,}]1%I-60_vN1p]uCeFx΁N6'"/rl4,СNMݞ1Ml6'`g.IRmT/kDqۢcSfXf &AH?7?6o7 w_Vor%$@#m|w$ʡgN)%6=B%X gCsGi\%^0ݴWdV')Uͽd F?oN?eɦ]͛?.p"\F/b8d|n'>cg@AQNXpv 6ydXAz)Ywe @`T|ozKb-cŤWF0wAǠ\hPM(%PA{zP.[| A(z3k=.}=-L.A~`ٿ!DxuQr6k? qľ4xXҚB~Yڲ[ $曁AviZmyJN%7c &)ĝhZtUSSN |IPX}%}x_̏uj[˾O8)3qu[H E;&mT ss#, gڧ4(?-[d+//t8l%c $c,Wϯ4>I:endstream endobj 235 0 obj 1291 endobj 239 0 obj <> stream xWnF}W[(Grд.*D/+D:$]")n 33gά!)"}gUvCPGq(Co{"1}gz _/`[##/.OI|ܵm]Vܬ$y7 /"*=Pn0,NB.?'-JY˞XGCu]__>ݳPP>$BcEUj4#1dnWC'ΐaBvx/#G]S>}7)<4hpP3ڕClw9%KNIFj+f1Q".~c);nbO0}*Tҗaαt#8=c}08b 3aAyZˈD ULվ*w $fSPHvLY(׵ ZWk̑ I{;m5f&!3z5dH6Y00gHuHK7mH)&Bw69cb8'pmRbK_ , }=)~Fh)1]MuyE߆:#${Qka $q3j3-+8ЄK.\̸ֵ3zШQtfF\7:?uڵ#g YX8q>Qk;055hY|-߬u"`6iPLI,ed2bP>%\`:*@ȥ!#T`kTgFp4V+àT@ #{.VXTHɣ׿' < 49xIF qqBV:⚄VuWf'z|t#M>>v<u8?Ucw)w=endstream endobj 240 0 obj 1260 endobj 244 0 obj <> stream xWْ6}+6Xe[=L ͤ<16c \]y%UTi9w;򅸔|t?yɶd;2aIڟtO-'Ypqfbo2CN=^@ʙS.\'MY xpk]Ofe,"imcȺɡK2+~.?~g0 8"̟Zmbݍ$uGҁswdS+c3/4C3XΏk5{32YcT@_4D\6Dԕ 3IﴮQk<`L5itUx 8)omPUFy؝?'f"*xй4 |fMF$1MUܒ^%nn>_\G܈ Wu]S!0""Cx{Jd.y LR :Pl®LdeTTFQ,, >9-w}~9L H1(B 񶅛琩s,WQ@v[~dMnubtbrquԣ&{Yތ=r"%..lz͡twA. h ARg@퍪ӾLCBLt&8 !*@"k0W2ǤIjRm/¾xUx\P :R/!8&EARx,,NλDcM*1URZ9bI%S?з{m>A:YU#Pc MšM'Pz_ UvVW"|IwEG+c*h3e.$/̃1JUʐFB^~xxPD &`5ƤPOBx46٪:ͩʳVn+X ^G[(>>D1~WU08qޘTo 7C*z.\7d([+>gYn-Mgv5mW wArӡCUkd|b;BF!ʃРtxX19\1>inz]Ѓ~Wc(k>$cW& L+ $PWU z\"@@vȩKpFZlڣ2ɊIiX'e; A:rQd\&3Ov݅0uIr*(ɉ /wi{WyX9eM&BƝS Y8zB`4XDMe0r^4U: 0FGIh=P?tQ%$JA0U$X^ [a̼*\'p?P> stream xWێ6}W-rbyHmTmv Ch[Wr%*NÛdk lP؀"9h?گ]QO/V حIX0( *WQ,L(?=831!6իԺo䌁%x/`g2j5s YTGxFeбJt-Rk FH"/^ PUh ly3%|-@Hx&W?]nL8!l^S ˨[H0ֵǨ84(Y=Q}.ݦUOo2 `m+(iG/w`qa-B(3$P UBjں";jN2{rl5O&;VM۴{ 9):)Ϫd%SV9$f6nMM8/kգTc!́)+}j-d%n8< 7}7B`ʹ,.)Zz!΍E\$%lxKa$ FYRMiԺsPT@'ӭ$pRU# [ ~-IdrSojFĹq$tH)/h0X8 23CVR̒ qf-譵э0w}ߙ\<%$wd29ٍm>]8H&˛8hoWV@Qkۅj%A&qjVYhHeQ;Sn5:9S}lTxo\J&ۃAG)?E6nqhNUPط"~!K2Lyh?)8xoAA Y)'IF+I!9 g>ݸ?݈y$ Z:KjuKd݊_N[^ F]+>`h#ECk8lMxr,ܫJ=ooFhA j %CP[qK0+"fq/28Ŧ>l3ߐ_p7,d̄z`V`0K^ޯiDtL胞,O0БoO9pقhhT*m2U |9|vq:EN?F)ȵ4Sѕa pKls}ݟ bz^[jn\>dK %"/tNz|6ȅkoٻb+|ǽSendstream endobj 250 0 obj 1431 endobj 254 0 obj <> stream xXr6++P4LL:Jp:D*$e'{(Mڙvq9$p{OQN~ufmB͈ӈ7t$4S\3MND"T$L7h"f-ݚ&)cLb8_Uْ1糬(f-l9>D韣8L6}2CO^|&|kRmWeZ ٚ_x.=Ѵ6-rVڃSu]ŏcx~P\0\X$d8KK2oWUT&4Lw#:-ɇ|+} b,+m׃Jq{. J(n6_ǂA7Vײ2s:AIbv(RcL,M]ٺ*q.nKڊMY4! ꠽Aj.IES%s,PT!U*'~Y s޼ \^rs(RgoqUV Y(RviJ!9Dz^ZL Zmm["Ql pn.ޫ< v=̚nД9 Ϭ< g IZX(03熪'ȥ>龢 "} 6`椋 R?p-aI*$TĒﳔ!EL| hemDN:JA߰+l*s#ڛXҗ%ewhpMMdyCPuiТO.L"m' hʡD;ऄyǛ4<"jc1Ng6y il;4MB;]..%$:'“eۚT xUx;|tX$="䨥$\+7Z4ڝB;"5/z}WJSW׷7)̔0 Jq X?TP-q@ACne8$kȒIXv1دc&^4Ď1JFsmUc߬Y (Jp141K~Hye_a@\IO ¶8z Rt<@PQR ̈<۹p&yVUK/P CSq$Gذ#yU.y^Z[dy\Z  c̤aj9`TИ@:hh0!#[t(P(~"cu\0TJ8w(oanx(RfU}!H@_F# ^wҫ_^OG_͉endstream endobj 255 0 obj 1492 endobj 259 0 obj <> stream xXr6}W-TBpIܙiJ:(HfG&U.@4y79g0j揓771F&.GH.&,rfNr"bA"qr©YfӿL$Lə`2,I58q5S8'}ƜI kd]jMV)RP.EM{Pki>/aW`_RŶ򵕺:[ˢ\KqyXVfژʐ@~], @X)TvQWf+֦WF)mL{2?V_jS<}U3o*}*h +~A>hL^/==<> stream xWn6}WmE&z&)6[GE,ӎ YR&c aq3gΙ|ESD{O A u/Q7S:(eդ sbt3yg!h DZ (C.' |x!1 -߉8&p GLr9W/[m{IGtU q~)֕ZygUٚ1SG։j ɫfRzyuGećטm%",iNjW妨QڔJdaF~XC pZ *2Ec`93W(9&Jaj{тRLlgǩ&3% FCr](B2Ӯ;V.bgKp%.0Uջ Y2YQ m.љޣef255)0(K8aY[;rU(QnJ?>ul>8I^.WBi3ЎM@"}Bl{$JBZg8V>(rdEY=9w 8<|BO81wR0:=5٢T0c4#&e~u{9Oۛvzsz3?}H}}; r] ?t103WI%i!pժQfd-G55dcGgv1Mޙ[D8jvy :򨃽 $}2;]5#<ݻ56rp z((] Y]\Oc;mL$bɻo|/iRUkd^׮+1C6pɀ˨]ha80HS+ SRzYQ:* 4׳t6J"9L s~) Pʕʕc` 3/pn8,Kђp*0h'W;+ gc{ûu2$'9$Iѡ+m!c]j"иEЄhUk[Y癫{7?Xg{wE;MuB {}Sgwo Ci<Ug,QKfTM/ZD]r>VzFW߸fADFqɇMl3c XwH7K;? !+u s$ı:SHa[F#pE *N1T;Dzu:>Odendstream endobj 265 0 obj 1260 endobj 269 0 obj <> stream xWnF}W[HK1\Q<ȅ@+D*eߙ].%J ¹9sf0 W^l'?'d0|poŖM$`j<9RDj2NA"f?g@<.)LRʉ"&ISx25H!8yZvQ]Xn"Bպ6%ژz=^o&C L>l͆\]eٚ-㛶mZre xs j#l*-]M`{4duj\HͪN 2ޯ5ݡ2I =s6OݯH:B [g:eFlY{ӹYqUXX MG2%YqN'ATFt ްoXR=$cd()f̂|s0XNNv 1ˆ 6[mhZcǔqcIqh[Swh6%mx%L+櫹&.yqzM6ղ|3Pxa1U&Ǔ}ٝڶ@U֙y9@UG<Gs"ݏRHsSO5y8l-xJ]@.n%QMN 䳄V&p(%^gz$-yY?j G}[4z=$?:Y\=z .o;eYnGB6qIת}ޒMk;4En)`SBz'5B,_luu&Fԁ{=]l3jH*W6<(;h]״B$ (:ɧSԛ\,0D|T=ʽ}JCdAA5x[É OYVMk dzCH-(8'e9A`jK8)Ԕsqh p|l!F/I~ W-{<0ci :@Uq.8x; %%|ޏs N jQΛF2yu.vlCP[2xuV"^K*OeuE! ΁7wKeKh 5j+HIed/HҞII%q@r7je0mlkr[V i;=wCIw}ÖnoҸY^lp?B yX8%xJUOdZh5S.*Qoݸ90X:Hҏ1q| 5\놛Bv \%CM~ߐ푏endstream endobj 270 0 obj 1378 endobj 274 0 obj <> stream xVr6}W-TGD oqΤuV8EB2Px (ZQڱ=b9bLPl~Ϻ оb>nn&`hS)Bnv$f32MB#еlƈԭB-YMLi4Rz΃ hX`׷ʇ~}{vh >f"3BE,sN\ eNF}:(V |7x@Xj\XAtmZ^Gv6GU/ QB]ŗ5ti- 1Vabk64+yp>*]qWZ]e?C{.VKKoGyQ|Xwf3Y.Ⱦd+U5hF0:ݡҽY%rEpD4h0;]*xT9?i*o=Q`i9#qpO0Sq> stream xXKs6WV*cxc3ɡF= EB2 t./M83rD`߷""b Aͧ uQ\}(Coa.Pl>Dxb/`í#".&z7gJTeyQep6qSӽ_oԱ?xGwWFORmJnCxSY6KuOVuGE냩gO/`Q5ǯB=uvpTgmn9.Ǫ.>xF=>M(S),?]šVxnF_ɻڅAf6MݠW~o  iN):] $4K%r7Pk#`}|Q^7[.FUrm9[c;&NcC1ƇHS\rw'?}UMi˸ζ6m.-0*n@{=iᨐQʚo@geTwPA41ꁷ?cށ5p@as4PA]jD? UFdMQ[ mda Nw,hbOF~Lyn.kFH%KElF3]R|]U6L o]u$ovSUSZ9Qoր&>ٌ P6!"]jURbiSs-\i[j$[t |4 萱's\Les?#rūդ4I9?b1p'C!Qx[&Ci;|o\ufevV'Rw. ?bix.VျW]uD} EBzX.Su+UQj1Ie5eH|' _W4mtEEʢ@ Mj5&.ӡy aMt"t`CGa +PLZg9S R+n0=: {si y݃'d~6nvnsEȏxP2ؑn)$U0l`D@Yy\Y\ N֞05bV MY^s0>nt[qLlbc$.7?tendstream endobj 280 0 obj 1825 endobj 284 0 obj <> stream xWێ6}W-rbDR1nA6u!)]hZYJtw8$ek3Ù3gg2<^nVٯ<ە 'ݭ'# U+Hz5N};ꠡ 4kWۣ%TjHVga [߳?~z}RPi 蠪~E4`̣XEBӄKcr>Wj nUEt;rJu(TO8D3^n$aL,w+NlV^Dcʠjb2̕,Йju}VzΟڡ봪t(1!"fkUL{R+m= m s{zRvʺnPhvf[ΆnK a 6E>eV4]3a6P|do`Ay(>xȐ LHzl%uχS4WgBTaM 5^C0 k/ 85M EPCViSv t4!4vg_42V1/Evk2VM5,fB LCDУ3Ki$<p44@6w'Ņ8x, rBĿDPW <|T3ϕ/ .4;cxֆcYl^Ć$HHMt& ׮M*YOX |cy: cLvU.#i™E7XI5Ae AƎJZx'L8/e4Sw0&*xلJP^hg!kA4MNqIC_+F.bʡS dNU)C8Y 8Cp(Z B J4ZFbԜE1+ؠ+@ ̩XAcs;t%>]L͠]1~S-ܥ  //TNyFTDQ'?Ux?1ˈh[,*15\=GVV iX Og#R̋>Luܠ% b&2}m*}A< x]l krByei57ܛNG<}U8`=6O/-J ż^=,òxVgLHՊ4OV2R; 4;q,nyBjX_x+g'swv~nʔK縚{oܒV Ql˕QP&+ӏ=[WO>¾5KM%!`=f ~Cendstream endobj 285 0 obj 1408 endobj 289 0 obj <> stream xWnF}W[r/%ѧvAܺJ`E$}goHr$;sf ??>H-,yG~@oW V9"jQI1H2VcKG~*AhF GGaUXiX` է'XF%GSnU֝YQK"q&2P]<-M$HB EdB?ժ@Ņ[MǏ%(w`XߪqF?1jf"Nr('wm۴? 7SPC9d+=y_6>)U2a ^) X: 4Q0P NseG;\b"#Kd};6m&pAeѤ*lݕ5Fm2_kc.d؛dgf#v8ƱƘP* …蓒cFk;}sݺ*k]YPUԜ@hʧDX6 1_o_A#cd6߅CvU^n#`9Dn+e.)i"` jTMԪ ඼+s, ?Cs$Mc2hCs < he2#"%V{'pFqvhOПUJ䦁k޴VCfg*A,(묲ŅY#!Pz3RpmjN*ۄ4Ewm1ċ=8HH<t嬗eF4ȼL7}WFiL'4 q+SؕƉoN Hᳲi,͘htxbzmR+tnNSD MkҭUՋӧb fAQ 3-ht aӻ m1K8vD!Jy4ܠ.·l>op ̷ʣvj9"$n~Ò jc:. ̮ Xc8=U0Uu6Qa5ՠ>pVWL N FۛЅEbx B%w&C|U&xuUԌ,A/,"dnB cף}۫VπzZeݠVny%Kꊵp7zukSf[ Z-4ڿ"OA 8`ia[&ֻ]5+7Ķ婄@l i\DaoĂKY2a\4> stream xWko6_oIQS@h]$!KΖR=d~(يH'{gSF|f763lgg<$Gv o3AN1N̬%#.zP6ŶT9͟RTSeLF4$ ~[]u%z{臿8;:kj霆gWu]ws<< bpSdӕY[TytPRx/]aՀdRެ("K[Ր`J IIVm!}},xh& n/lں3Y6tgP>`̙˜2sͮ9Y+kZ+;U#ɴs.Q9hcLP'iqKsICH|p9@((SY[O\eUjslI~o4v)L%΅WE*!Nߠ\_;Ox  Iq7\][ܫY% ,SЙI740h7h20 z}]#EZaKVЂ侮uzПj)O4WkK,Gnkb$ݠLNKpƎDCɦaWś16Mѭ-J/BA,;573} J)Uj#Tmfx{ZBGJ׃baSݸ0!>Z^reII}iYc52ަ )fǘ"ᑿfU~xeH,4-1fƃ z Z4:1a!9PԺcan%$07w*+ @dL9) &:m8[ވ ~/cbwiwumwIty\Km;ݠ98`} (Zc03V>W(wMKQ$1T eՒU]]h<2b}mEknf5M1vكϻBA,iXB=`94ĦŤa1< .4tY%tn[zdZT>rV ua{GDoɸuS_f%@T@ =}coq>P^UG;tz@c{4WE`NofE[L3~~Evw8'ٗs+WKWT%⸦62@^Cϒ> cv}uOendstream endobj 295 0 obj 1663 endobj 299 0 obj <> stream xXm۸_oIQ/6m|wv Ch[-9z!)JIpH]I3<3/ħ_3;/Caė_7 A6N1N_؛SHds^9R`\*TNv3gO8,ӳx?Vu9 CxCrcCs*T{R٩qqzVUْK]CE}jM$Mw({kLbcQmJ>c 2GuSmj_ՊI:xJuu&"; ]r+NXAFA%*b0d>.JJ&2ͽAڊdPK X a1̭-UեEQjϳE,)wx^%9aۑ\>!`W.K35g&ήi0("}ulK $!76~KCVUi6 \ %Kh'^Q#24DtDաM¡ <(F||U)OJ;S$p=`3 0PGwK'oNs({~ZPСhJM\kZSڄTpg}}e3 V%Qu]Ks:&LafE[$U*QQ:4-h5 4+!S<Qr@5MEH nZoZr.r8" 3> }]םI7~2ɳm O!ugg:_W'HhJvXU,A8gUɛמ:C\5ojRgψ 9Aj;g1WMn?zKhqƜ_c N/]zrX a)Z}Ho&M<"<ŋMevYrƓbK $FYL,lX/Wڔ5GRJM?7(N saj,'1hFKF^-)t|ً1B0w >b̻ \qj"AOP :jM4=Judo APldz~-d ]t5>wW)a'@ӑkg +Nmw$n+Gd.}$d vb c.P K =!"İ#*m\Ki|=0?B[tNBgvC5 i*@8fuUKqJ5yIZc\)xfP2yGÀvKbrO???ܰ#hG2aq ,l0ḝ'>\r ڏ ٮe+?@ޓ\Wvmqja RRHR~X2Y//h}jyaD\яOeh,Sf<拘DLLl7/cڟ] ~yA'm~bQœ4z2.dzɄnϗLc\nƸk6H߰>'ɸ>~D?]FO4RW B7CyFeެ믍Lfz:C?,=!ЅFbdw)vR^qm!zvu"EtF "8w3/_z,5;h?.=ޭpN 69fg~{sX?<> stream xXoFb*-s!״`E$T_ov$-;6 Ccf޼y3O,䂅3|ŏ5w.8 zp'te̴L Vj0V?}TʄC(< cRE5> W\ZĂVBrX1ɦ šgJ{Q!\9BBP)\KLX~* ɋ1 ?#lٱBmݵ .ձ٥R+3F]z릛GJjXz-B$WTܐxd7ֲNg%x,#ϟ?^Oק&q񭭸_1)del8vޡkJ%cH u9)(ӹ:Db؏ZYGZŐ,ϬO+wĥD5$$N,3pͳ^?> stream xXnF}W[([@ڤFEaMd;7Jt-d;;s/(' _}}]?cd7kC{r&ɲU\[ngv''"T$)Ygw"El1}؃] $e,&mf 4lM9Tm3_cg?M(S1;ͩbY]\E\3-̼C`WOtGC+dhɽ 4b MORPTM&֪fv]s n)SE1sNcr@n6i C>讝@%u{tu8Ri,,na3S+S͙=ft19Rf7<,IYVI9㘦i(_ׯ޼\w7o^\^yO5U.[c:E)Kd\X}wUvXU9rH4UWisSgy@]7lHe5䙢h'NOe 6:)˕O3`>QE'zD4iʬ̈́*x;#9}|s!޳)n>ODhOtgہ3ɒQkNoУ | X\DxGEՑSU5!Ic c¼ȑƙtU 1 DT1ItݖF]_ ǮHx<ت;X|Dc4eQ7S}yMة~X۵M21/ϼcEyf-xnt$|ּ$ $ԧݞgkݦ7I t-sB7}8ԕe*2ECՀ^60~"F7lMFx.BpGF蓯('dAV+ 9Ur ]4Qo!qt&v 4HsQ:[T=S?Mˀh[sCِ"3b{SBF .@5;UA>=~Zl31`S4&Lp$dmIl2ũH\H^@g *uqӃ1&L'Fx},KDJPZH~i.\UoMyF?Ϩ"L>渿׆.H7.PRY 8+bNMOH4 hrm ߺ{཰*JǗ{,pH?Wfz(P/a֮iɡkK8L6X3aKm{0y4V-WLm["e2/ViLhMKԍ 39?t1u Eg+W7%Յaf@ F2ݨe۹w{rlh!+^ Lj߱7\BdvɴL[+Ugjnn UFˀt^ʉJ=ܓu~l޷Fb1s@ks]v_ې>̥m7pa8v崉Co)ϼڄi޴+n> stream xWnF}W[r.&U\HJ,$!8wfKQAQȀ q\Μ~"r?*iglff<$zO.f,p bf-9JP%#ϖE<\x*&/Cf*~y!U7|,T1)m$Ͳ$mj?xs<+3c 1jMg$;APш7Yu:lH\|xɲMY!T]tѓ{{_ջM yjfz(L`"6-9)պ+jHQw2p+lZVuK j1p!INS0͍d]W]ZVeUQ7]+v(V`€6}$-% {jE'|W.]rvi'e((MJ.0"ZK|]sWB̫gCQy,}Nam/9-ULp xbB3f`w>z x> ':xD7ξ}OCkYMP>G ;H}T_O/EEsq#+N!xWc!ա[AM(01b}ZZ+D E5>,+sͮsbTwACSA'w9qq=EnRXFnh( 5YkCXϙ~)85xFwee*2eCY̴>x cw0[VUƸQ)Ν,=4=0> stream xWr6}WT* з$vf:uh EB2THʲŅIboY3(#~ע8ȦDd3MY`2!FB.-ah ?LǸeYB˜o SΨL2`ptR?;Qf8HGZ)Kq1`LpBSY8#Qqb31SPE!KFz^{߼~ݿ}eMR8KQ3|ton~ϥʨO* KLu UTkh~ @F$IP ^ ̧f(+}2VoM i\Vl5Hq # 2ak1rY".7Q%eӄMR{쬎*wtq#@Y[I SV %Ti `,`ɱߙ?Lh$SmD]RdN>(þk`C'(j=l~_ΘB5FPH]ѱwGwG(:O`P1g)x2 jJ$@⍄:.}mRWM^aJw3;'NBgo cOZsT-2D,}ksa8 jcpa-Whwk˻5.(OmRy> stream xVێD}Wh՗AA+}Acw2F^zݎvJ+v휪:~03\mzk՛FWPٿEU-USls-TJLVs<|=yXkj} h]6Oj]\NM\ƈ pa}hʾ5&,%RXB9Y@*F8p M:1` ^:PTX#^OEF#ZӲ"g9.,e;Ӷ0(wM_Ml| D& +sפs*@0cڪf޸T&(nmjls{,;J*Huw$a7lٮ1d"6o@ŊImo+=tamօD "|cqi[`Wh{ح둉`f J2yޚgv(51R\Y6@ fHB# +CN~kLAdYLح&?ݡ ?'qVD]^|ϒxc[* <Ͱޯt+.RL!&xL $áa '||:G_|rYpKyT=s,i l2Mӂ Ycrv.hgcN(=wS 咘b_Z4OUץug%((◠0c_~m۫gG5P(Eopǽq;en&Kendstream endobj 325 0 obj 1054 endobj 329 0 obj <> stream xVnF+f*0;ͣفx"+ْ9'T/H6k{U}JP 1~`GїC~XF%~8%8)(1l%d'4% Bi I'U$sKfOȉ"wLapQ>~6͓銡nޚ$n0uH*Sl`z]S:;h mÃRŔ"0Y k}+Kz㜐YqFE?^'8BT`Q;L;s@ Xv@?MUtSjeeϏЁ4wjr#qaD(o .ӌPsmVEUMX~Mu3@k.x>n z{ZkUmggQ\>|g}Swu-DώztfurLxq5e(!-ěJ].7:'Dt II(c W0ű]rCvܔqm:c  !uv(U-[} ">$(B1I5 V˄ʤ2u Nx&]ɔup wv2^So7bh] ]PPMlPe)K|1MMpRR\j#6F3ח'rIT:Iux(|P5fn#VP#t6T})=SR"SHQɽn@M$3쪸sC&(¹r( = BYd2pby>J'Ǥ|{{piP.(,j9¤:#|3pپ`~nRv };T{NCXlz3 Jc oYA~^c벲1;ǂ갆lcAܑ\.a*0ͦ=XI$눍hYpn$Hƒ 7u$S/vE|o##ӎba8u-Lس+ۧ-k'[4L4;Mr`endstream endobj 330 0 obj 1166 endobj 334 0 obj <> stream xWnF}W[|Lapĭ4N!Jf` I%M7bH_ 0ݝ˙3gF O7 mAŇu(+ϫGnQoY10H I-$L~{RF8&DTj̀OEYU웲)ͺx,WR ^=w~_Uw3{U9[HC?Zkk}]t] G{')#֩9i mINJ`2܃d4—e ov`v PG.S&~gzcƂkK]̵Yc Gpfest5.޸XP6CQ7umԳ{TZ`nL13n=Cu7T2ku(a3g般x K\Ǻݛmy8>A$fz&6IԾF0\@zC2 7Y(!oLdhѨE*s=컦A!,rQ8ei;wz99ZoRsXRajg2 N4wCP(bai)1> Ëȝ/Z~' ciiz mOtbm!0OS*(3\D##q veֺn6m,3^E^rƞ"3"!〭_P L>x^.9{T MUt: 7yblR wsTV?2555 7;t`r؆~}xt4L ьendstream endobj 335 0 obj 1337 endobj 339 0 obj <> stream xWnF}W[c ;[nm5}p "W2tHI %v[y+d@s;s#a]/nX0[|\p|ZHVۅDJEr~qz)2tGV`2Hz!iedin %\}*( USoe]/%P1xe9ʄ}!r$]K}Uz;vQ*4Y^ק֗?1iқlk]rXyR6w> EBS^C˫Y4 DF%XW-G[ɩD0nhPB/On^YEզMRu$9uCk!ڋ~/SHٝ|yqn TeOAktsg}+_c@n>171Ս$|z %m.O1 )L Nc)tu(Ej$vF63YD]8?u@dTt( J}`7`b@4vhr$9W*;Xy~GE{Ҁ IǨk?mߑǥPh) u}TGUdcTā?NЅsH{-T^@T&MDP P(jrßXME-a*)YcKzI Cfdv!x֏PHQ9M1M+"V0z} 'peWqrendstream endobj 340 0 obj 1278 endobj 344 0 obj <> stream xX[o6~!xD { ֭[2%WdٯH)vZ ŐN%\}Hٟ<,Qd-->.8$Gy ߭J8D(AeBxR,RՏ`J[`28EtuWj!lt[냹Tь`eݥY;Y.eeȦ2˯Qy[5;vն 1v gΧ`'*dVl쫦nge9<'x!z!.&9oَ`ޞ&͖hXJ3H&hH*Ƀ=KZp,^}ˢ6塈є9MxH*uh$?YP%޸/INDN V ~=)U=eTKR(E\ڊ$2k)i$]aq+ Y$ 5l vH$MR;QCǵͤZ&uS%(T&P.7gAf膝N#/bBrrb fig4VOcRx.[ky4SZ$؁zґQ46vi{ >IQ" qϫV#GuИH.~oZ[9VWPnɣ.x_F2%h6@,F3.jcL.~"kCL6±G.mu8M{6{7~PG f!M O@f>"!#.Upj۴niϣY=a@/ۑ=m`o_Meˡeln~[mG2KE̍4^;3'\qs*]ǦuQ!FC} 3wKJq2EeNPkg@E)X\Dm4'> stream xXn6}WȃÝb"Smi3n!) Ycj$E3Ӣ@_ H,w9O;=.]jtS/Y%~Gz:U!Ya'EL3\qqԒIūZ11!$,"e{B( M0gaX]ڦڽǢs,'[sis~na.)2T1 yVUYͬ*Vȵ<ߡfo+%v"]Q}Ѡ}/aZI~4b'..,&_Rmں޵ 2F{gJRg>?eΡPp9jj6$4/1Jk{]/;W:Su fVq9eۛ3X%u~S _\<[ EfΖo][_7b|Paϼ1YL{vxH6xq!_r.V<*]š&3]2WUɣfrE{d޻tTrGg|8M}jc3,]-Q-^dFugt,Ǯ-&/yqjhP$|7M/5~'^1QoyE7f;'|GA=wKh\k|o> stream xVَH}W[LԮ^cZtig5@"d<V~nН$$..T=#)"Bm=Q}q`Eo:Of B[1I(}x01!2ϯ,׋0 /a׍PL"C`N%&T,|[LѠCr<t+̹C6_6;TnP3AIePaRSIBtQp"DF1.Āl TUa^V̬oYw] @t]ʦSjFpsgjne5/Amm_PUe>>O60aTMml#Ѧ-&/IA3U}WE `g+ӴUQObG0`뭺qP˕ ,wUKh6lTSvUA]UUa!JZź $k*Fb(eN(]36Mf4ŔBK%67.i,2pZL2#R݁7Q]湵K0W .Ehp%b{]uѝc`?]qAʅ"WĀݟDwd韚?"R~'"#o @_%d;4s4l/ 7V萖xiv$ ,huXþ2BÓ(QGnϰ>A4vCnRo}!J犒]F?nfA(YH-ٹ%:|n '|TիUNLw<鶺&P@wZb@3Wԟp .= qQ_M{ /dћg j} @xti7_?`<|D^%8K&2,`.5)È}M1n߱+ٮ{g_BUpwϧCJ:z+Il`P4}럞=4qzQY=ms$w96$F ƪy_Jb/qךendstream endobj 355 0 obj 1083 endobj 359 0 obj <> stream xXMs6WR %$L8u`w44 L%HS^;`޾}/ħf7 _L/#;6 A6X1Nw[SHH9.nuߛ_>_xEْ)w4Ϸ:=mVmz-7aD%YvvۓnB\&nTe{1=HVP˓ZTy>(su[uⲮ+x台0}m>"S."yZxW%i,SMC62kD|F3)foeEZ4v e3,$ {^V.)'{UF'R@ׁP DH'T~Ͽ\s'grFVLk|e$- Fȹ%e"L\ ѶEI!ߓ"PH[hz/1 F"+Z& p@vX4#,05-| @z<9/{//}ԍhhcjx@e¹t<.a5E䥇N5dP# w6$ D M[^o0LQB(t?#>ܞpxEC%K|+HP!嶓)xhbs4q>bɛ=H(vcx3ʥ0xb#(hZ2@޾h4 L&#φ0]xĜ kx@Ө8{R uer\d-V ~+@8 YBs(ZS.@[tEE.ʏjE6KK 9I @غJ.lJៈVȆKJ[\g𚇂F >)E |R)kd.q)TLצ|ENp*+/i]6yLfQ+Rv;`~-ҋ(p7wPU;2~.X>, {W:A $E? >zLi "g^f)L!*A菔\fA2kZr" Z+fZ4 ug`~`KRyxISU{*ZS˳!}KL!V  0}FxX;r ϸvKx6ar`܀eN\} 4RCbQR&/ٴ~o ;ef:JGK[ȒES$S Jl`c}s1;+tW@o;50IMM_$P҉}-1&D 5P}r) aouHhd=0O3=uzC ][73ۀ0׼ ֓AK Bo뺙?tVslbp3HBPCw qv-C"("QdhЯCخL5mM݃2jg$dn $Ԫjf#oGx ypnCM"Ҏx\X3KLIЋIe+%sɤVr *zK^M0( #k # S0PiRClfٹ$ᙹ$3?4ym.a\2yD02a $dZ{j 8Pb2L@t ):b.X}nI"r$p%GϏciJ u=|_5  @VP'к2 N .;<^nϿ qKendstream endobj 360 0 obj 1831 endobj 364 0 obj <> stream xX[s۶~ׯy*ՉPcj3>mP$$3HbRtb.gSF|"k>->/~H?^AqœdG I"aqﭢ%| )ٟZq_Pߗd|եYQ4iv 1X1ʻVxED}$I({o G[#O#D*tکvLSS]V]Kt)HcUu@EBC> H(kZ]d[7$ཏW7& CűVQe#yNoHVSg{UML0_Rb`)-JZ :zEaRk!tt-GOF]pQUHْ&y]-s/5D{Uy^&4x+Vn*@t'`0o#FT`yUڳ02:}:yC&[+fCh >?ϲ V=eu{?ݣI^7 >*Wrlghvϐ\&i e1^5@Ϛmq<<}+~K<|gKmJtnK QCm#ʸ-K1,DgPҴJ EM~XD09EhT`~Hc K`I$$+$6ơncU`b<_$ E-#QK(+b){g-oy8(;iyZH*cHmUD5 TtOb1!Ool &g1afX@g-,H]x &;t[4쩕&ż~@CDZZm;RlvoP}S}m0ߪUp/ec3|Q=;( ,^Lz@ ߠD{Qo-ܫۦ>X .vuz;3PƵ_ TCkq_K aP>:E7g iy nvz\=uVIHNsO327A8q3|!HCz gzT-hvFned}}Yx>: 0 (ԨU&8K@AvUJ?z{q$U+YHw >IEp){9nF *fU$Rx/԰ 49y1@9 kǡF?]6*yJ!!RBn^'Z(j΂MrQeۙTŮ􆬍ˏ?mv}ah9H8vOv̞n)eLt<`f'1`ܟl//#V8]" vNى;&|b>:8@/| a % K7g+S9`=&/p;D+srӷt0j[d]ה&`ޱ뷏* f!P%7;R,yZ`-kg 9ޣf(m/p:Ndzv)Asf^Dt 1I./')$;bK>rUWNLendstream endobj 365 0 obj 2072 endobj 369 0 obj <> stream xXksFίo#*Vz-TL\롒J-JHbB8pu߾s=_, 8 e/elNB5!{l`'f'g"A,Jl?l*?v"0`j}ZOg%c3QI~Qz]ڟui4ʖ}WM޾x-2b kANaqn}ǟ,>~}_LJ\hvȨ aWC|/Yγ vdžy/^lEZ5##Y4&ܘA$:7:4UUײnXv芇bdD-+:vږ˭^WFؔtKeŹ7V]d+')ec]{o}]YW uq26eް' @ȓ(q99( X^vx'4J$V$ih{THY޺;7H!7*zwvl/bdR)( 5]޸pl_M`u[l`d+΂8=b4 V{PR7hǴG&zDw2lXu|y恈L:,zǾXnˊ6]s`j EcXͯa>V{WI m PZr0R7W׭ޓMFy`=u>Qquړ8"Vu;=bYAҧaC  :iO&f/43 Pb.4Q3pEK8ckr+43gl Is1ɐW0Ie.4QdRJw8^U{ ` O_!sFMU7@>j{3H;j4j|EٰSZi[B8Ԁ09p"[wEO;6I_dԱT4=XպC"!4tCH"4"]yc]6mGeB7vAi7$^/V-kE"R'RH֚U!ÓTOl 6b xea+-]y*3OVVmWXKun46Ӡ{ib]HCqDDc> L^;`:$EWP=ݭEdOg 켧 wE]G Xy,Yysi'B3QCm귶 7ߙ*AHؔU<1h3Uo 1FAWyJ)e^DJγ[^6oSAHriG2:c?씡V=ȽW)"JmU`ѧ@n)r@z7.zޝK@\,aFV=.)]iǓ# o] R.$76ˉ2n*.cՃPDWdOƍo1i'J @6qe1N|&1WT\wA#vrje{E{FnOT%@7zp$ކ n({y/8L$ 6endstream endobj 370 0 obj 1933 endobj 374 0 obj <> stream xX[o6~by%=q xH. eTѲ&}s}9_j;m Aɗ 5y[ńvQoLjK0-#w,~h\F8&D ׃ę=-$3+Mb8bWQOtyX"FZ6(^m^-z_|+毦XBqj?"}MJ > <届v*[؆>Joȋ_oBխɈ'Rsu晾0͆Ff?Rty U[5p,5{ͮ>%a^>u-,ײy\;ZK8EUφviY<rϱ .3sr̤?HXFq{1I)yfx^ZWP*UV똕M]PAq# Uh u<xDd<,0ġ{^1},Q[=8rro6;N٫1firm~ JTѠfi.w 8(iJh@ \#b)1V2-1Ā6(: NKLCܼ+gi/eUj *34+)xz@B8VVΝ&yei"T A˱B hbJa됾>PSK5;!!.*\\o[#sMK%e =SY |V)TX:=j#2ZYC-+R^ΞXZeIXXN)$X{-ag`?Pjϻ_@t2fX5,ĢuQ@=KoVҽDHh5 [dɩ.҃m0ZgB<]N7Wa0Lt mt^4RnxӡfhfSZmOIb1\E{{3on,淿AeOO 8R wV1]>9F PElr= #?ǓUUͲԮ :Bg!^,H9 DÑ<<wȖpǑ䶅i8 ?v pgYV:hz-y`R* {{_`=?q? Yendstream endobj 375 0 obj 1459 endobj 379 0 obj <> stream xXrF}W[Z;7-Q-Ǫܤ-D6$i\RQr*˚>}2 w_Sg?,2z~Z.[KHžL2R*a& @Y)Ns7`]N 8*%u-2Hy-O*;?7Ɛ+EGqrgkZ1mwl{Z4 eI~] U]q>gCsm]Ɏ]a}ú?U_;n ~jm" 6Kv_-bF4.w_G\"Uox!m/Y ;__M; <#>^ݖʺi].nW2:[vCBNlX7r 8N$F3$ϟ3cC2(Mpהw)3-.YQo '3?q6_g j=3,D&_fwd DdNo8Rwٸ!<4ׄeOLXaB o\1d$2vKԱƉer Rq!}=MT!ăڕ2F[/@]jBV 2g½{챵ٚbPtzWD9g>Oy3`b<!3~;r qj~Ij&בiǾmG:id+QkϿ~p_V}qY} vf4Ra+0/?]xu2ٽܰH}ΠP Cb&7^BBt=A sF j,~a .LWpʸrt,_+wt%a*~e>+)3Zk 3eƫEiF*3J[?yKX 8_$<_#0w2bPIb@\X) _౧L.U6r)U2J5km=[ܤ#gв|=5@ A>[߷.I*'ۺCOǮgV$~J2 x5IlwR+c9Eeʢ)*D@`T WۯR`2q?f Q{g:P*y%*R_RMf,K[{> ' z !CD}ݴ@>iK"I?i2I&KPT-;U.8&$elk {q:̀0ӡ)"ɝ]Ѷ#~%l, ̓cs*MzB̟ng= &AclL}[vї|zWҳy wU\> I[Xk7 =h&Z8sz?a xU}ϊaW9[T fFeK VluynȪ Ӥ0"'pi s]H7\* )2vtS /(ޞId1L2{ι켡 wE} Cg l,x._'Ae04 blB/3FIiZZrS)O@[.~şendstream endobj 380 0 obj 2081 endobj 384 0 obj <> stream xVɎ6+6bh=&p!3'9,Q6gl#ɽ}V@U% :K?~9v9J1ߕd#Nawv]/Z񀺁g+3Z10BU, :Ej:yO.dzx׾SUܺU>a r@]0U94,gd.Z1u*_ryT]]?37G8E}`n>Ƈ9i=[dnh. )$L8s74 My/k莪Z:8f-dЪMO=qt֐e]U(UB8ӵZClO`sPsӕYdcxw1"g\0a;Y&Y>SMf"зM 8t VVNWuW )[ 8gO-`NpF,Lpb&S> stream xX[o6~fIF=M dH׮ 娰Td~fYrlH'yx.C#r~wRflff\$c#,װ jfvr"RAÈaBٗ`Êd1{+3"k!XH",:m^eWmSy|u̗_gqJSG>nJR6/p). I٢w"U^l)k,b6o1@UY{kTVgw.KԾB Jxف:C]~ځkշƪ]_&Wk>Vu0Zc޶mL~/ S>| =_y+ILY*g12wbxT jd8Ja׼z;!"*9A "5e427]ZiH,vw~i+`=648t"2G;(K^31rxC@ @#{BK F=<]  uBM'q"{" YbѥW%b \OC`}Bޗ5Ԩi5y PgVZ?ĄDz<ѳF$MԄH VL2@71BF"Uy6f76t5OVPZU9+T+ de"&qhӰ$1Ǘ瞱'ͶеtV݉Hs]A@X B GPK*#ky 44W]OAUN"OrYʒBNBqzƒr8YqCNmp`x;Ifhe`ҕ^\Fn%It]|y vb͔G.Ixޏ:D NR?ߥD‘vմ8W.bp1Ӱ00h+|nɱndM5`} G8J̝aHgѶ<2%sM9?̥Z&!D k%HJ=x%Тۮϛ*7t10cԧ9X ֡@޼k=YvEha[֖Xb^YK3xx֖./9FtN\r؈}PlO.a(K?C| q-GFp9~@~,ݝM(J !^Bԟ{i3Xd¬Ы? &DCW|cFn!h[i ~<~r; endstream endobj 390 0 obj 1848 endobj 394 0 obj <> stream xXms_oGB ̸swNmi'p(HBR_ )Fw}ߍma>$}/o%u.=$[q ߮Y 8o2% 2J)X%@Z) CAV1(%3H_4iu55ip$ ;}䂦*VY{V=KCS`W$Kv4TԷyl`BP({shf1U CIVLFyBji N(xwdo48r~݆iYfR ~G r?hkW4mcSƚK'ܦG%w<1I%T*JpsnV':^D!@!%5x(MPY ʰ&)(U90nf۶9dn+L3WPdnB]ճ,!;r{ p1>ZTu޾nHV"+t9^8{c%:?ɱm h3SmF775{gfAiO9smZE)qGΛ]!wU%7RXo`~YT&cFV\!y"%Hi ۈ &ޮ`Eɘ۪wmTUu_@3i-+5&tmYcʦ12:/2RÚRg{hW,$ b6I\)䀔ixSxy*r4mK= 4 `c_/JU0Jl$hKvBjxHo'/쐦|ܵO?}sx;̓4< r~"[Տ{[:I8:3z2p}VTk\OzxOb`E-( N;K!w1I_dd pyO<ʌqtV&ԫCfX:ޗk֋׿3endstream endobj 395 0 obj 1890 endobj 399 0 obj <> stream xXnF}W[앗6i:JR.\Il%R%);wFR@a3s9sf")"}Aٟ3jw匣eR!^fV"1x}L ^[pZ F8&Db䥚/fS.0۽˕a14&XgAZm*$IdV>RY"p`  ] 77Wg]6YM}QC ըUa|,2ۢ ZmsA#phw- OK#ŊNB" 3J1;LLMSx*^l4+fo`2\ݨ}ZUuye[j[ yޔueəYУU8uơ0sHF ˪@YUS ,KXl x$-N՗\VjNI < e|61gmd1A黧R6iīgg7h@.e]A|ިFgLia\f0*>zdwpF=:oЪ}dAbEV0Ilje %t7/)BBNB9D`{?,'CZlEK=P0Zn`,hiu~h k45)agGUy}sw+re*3;5 * i`GuP[Bo n~|G0(nH3> 4oi6&l6bJ1G5NU:ZrjfDP OP ~:VcՖ Dcd[YUxS}uDNf#|V*3H |*%߆ה# _Lia[COGS/j(i[~ o-Y,~T֖2A`k| @Ю6/!tڨ=n߫''"Mp9}s9ĞtCij2;,gFQүz\ zG l-/Q^C;Ǡ/|T5f*<N7>̵<p'ڿh$슢 <_PB-)a7 ߴ2 L;r9$l}"#(P!t_gguSP7-٭%> stream xXMs6W-RB1왴i(!hhٱHw$փGX}x }PHkx/[ f˂0Gx[pؕhEd gO)պY"d$% ~՘CR5mcuEVkJ3d+u\!=Zgzp55g Dw# |,FU6`<]4'by`&x!I{e?,UwLjn'eR37mMۃԘLWuo,s$Ǡn5ʱ@mQgo@VLY:up] `W:XcmffZCumg^oPnisR_J(6>Th#2p&sQUnkl} i-<龇'{*I63ozǀX"qgOkqKE['GUܟk sTK/'G[/>S;OxL5!< @&܆x3ssk,0\LrAIU7Z̈ ,0g-CYg'*YV]i7'̦P.RJTTB[ѹhb'䐎0ɋ|BNQ AY3PΧDSx-Kkm[ZuH؝@W}b0/T+)&u^CUEpB.-FxdI` E!`3 Gnoķmu80`ϲ%=I/WŅv2,M;~wBjQlԆStS(a5^)I(](G^ e"R4场\۾28Ao r>> stream xVnF}W[Bс\ m4>؅e$3H,{g#%I؀l͝sso`q!xѮ j(:h]e~ޤ sb!xɜI2#ogo w+dcB %ؗ<,]'AU6\JL(aӑQn{1X_I>312Q@g>7S_j]ҫj::wCan^=*Qd iO;T滅6ч3m~-swK W>}*G]2 |05pe{jݏ@f=To *|{޲7Pֶ=ώ zK8/Ӂ*Qci!}6[13BO=v{=[eV 'SSqΆ En0ߎ/Ndh"uG;p*0e7ꮒ u s/'NXۢX cl_ӣSTjF)dsZhZȰ+D)1l'9fR)flPPmjO; ycx6pتNT=:T4rlhBԦzD/9:elZК$/\nnߌܻegߛr}f.\F WyRpk)@f.1$+g[ˡ|0Itg]w:5+QeT $t@N +e6MQ:#[UEGvcb4J/n !U^)HsܔtPPo֕oߊvV'iBϿOxx~~Ky\>OwTVmvȦU  JaJnjy`I?ձWzMoPb J}Tv55k:? endstream endobj 410 0 obj 1148 endobj 414 0 obj <> stream xMsFstMNS+v_5q9 ]&Zzo[i$e=fí$*f]lu Tmthd R^J$,ꪭZ@gg!WRIyq8xu;LH!htA='vQ-v|bX9s7 S#bLXIV[Hq!߳~5J˙6Aj[wvCDϯn5rA%Kd`=0pNj:vR,W(}6<8xG)iUbJ)z4v =?B}*Xm@hM-ыkHOjc|3ƌ N;N!תn=mV'P炫 Q.EÅ䭅E (,`!ʆxe󕯕Ճe].z\\y9wj 5'܇A.sH̃J;eK@G :,&1W-c!|QY꥛'Xٱ}S/37uŒPun.o7onJѳE56%]DL3SFryYϓMZ?4 *a&6F4팋#g+%Ȝ#,DdmIJrj'*Q'F_iN{P$T+Z'm3W`Lj6.hdX*Y$71Z.}*{8]4Z4Y۳Tao>gڌЕQzHuH](?I[T&{l ɶlR'?:{"3m|L#(d0;no|j8rr$RFWuqݪaJ#BΜ3z;E?P޳rrAOruڵkeI:J箺wڿ5s|,uS!]tXS d4|iZ{$ΉR1lTq^tendstream endobj 415 0 obj 1213 endobj 419 0 obj <> stream x˒6<0ёegjHJʻtA 89HFe\~~%BW;Y?mmQ^-PI+ݑx07^\}w߶p *#q7KvRm$,.:E^ٲgqYjAn pufE_7v9U D&d[٘46;I\ ;1K` FOMS/C41HIK w0u0,XFwn u.7Pc*M,k,E1*)UeQovRe\hr 4^k$o˷#|TCQ0(<v|&᠙V87`"yL36h<.-|XF xv,&Tw0yhSu-0S<:f"bޤ#^zI<9Y2%<6% (+ ߏH\"ƇۦH" s.lDv3]xٿRE4 [|Qjwް/Ke8ST5Z'z7mX[gT(-zju0-PAw|C/R\ GswQ1Xr`1VRo(y5IfRO&ݞ @mei4*w u{4ړw,"ȇ1`"(VzhFM-`2)Mv 4L1gh2ʁ-p\]{)ES~KI~?^dE8JJݩ.r&aؿ@Kx6oF4O{ЌB'Cףrf=y> stream x[s6zVuAǶ̴ݝ쾬; qH=L}tttQ=?]Pt| X7l~ #&P\b!Rx|ƒhVpp~%QӺHoӣ%Ys䑣NKD+b"C7U敠^ҩ"ębV(=G0fs*]U(u/JQ?]ݔnd>6' >Pr9CmRbX(3N ߦ)ٓ*5-{@~Y_ENnȸO)c@YstCJdWD=\4 W^ x{{$GeѨ4ת׻Nv?o̟l_ȯ6dQGS`ꌪ:X+`J6PbiӺbaiڏ4f\OSr M,SN\Rk[IKR9.w>hA"E`Uj3t`uOo0M$([> stream xUM0W̍T"qbs벬H{@E;[ЊU2~3O?j7}D=D,a~U \ ƒ :Dӌ䩀LK ((~ߣ{ Gpj<]Q9>QJ9Pwe >ee`pp1J "Qw5O ́ݍ! &,|5ltMYܻv8#E@r(K-v +_LIj PjlL;@m{Cق C#Rx&_i0`]Hՙr0 tF(C ]՞IR%LN&R2•h#yp]S>It6_6M}\*Ջ} @;6{"5ܭBf4dZm Kz1f9EkB!S-I2(z(I@raIsxJ#)Yyo. Z ߻TOj<_8ѐgo6ߺn"=0gv2΃m9ѷSIg![m yO7E1ˉ^/+I7]'Mi)x>n4y-=M/Ƶ 'gwOk42 "vw#p"l&pwFa/8`[4κ;mep}4}6](soL&x34LYJ[?ˉ^w*5p ZLendstream endobj 430 0 obj 791 endobj 4 0 obj <> /Contents 5 0 R >> endobj 18 0 obj <> /Contents 19 0 R >> endobj 23 0 obj <> /Contents 24 0 R >> endobj 28 0 obj <> /Contents 29 0 R >> endobj 33 0 obj <> /Contents 34 0 R >> endobj 38 0 obj <> /Contents 39 0 R >> endobj 43 0 obj <> /Contents 44 0 R >> endobj 48 0 obj <> /Contents 49 0 R >> endobj 53 0 obj <> /Contents 54 0 R >> endobj 58 0 obj <> /Contents 59 0 R >> endobj 63 0 obj <> /Contents 64 0 R >> endobj 68 0 obj <> /Contents 69 0 R >> endobj 73 0 obj <> /Contents 74 0 R >> endobj 78 0 obj <> /Contents 79 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 88 0 obj <> /Contents 89 0 R >> endobj 93 0 obj <> /Contents 94 0 R >> endobj 98 0 obj <> /Contents 99 0 R >> endobj 103 0 obj <> /Contents 104 0 R >> endobj 108 0 obj <> /Contents 109 0 R >> endobj 113 0 obj <> /Contents 114 0 R >> endobj 118 0 obj <> /Contents 119 0 R >> endobj 123 0 obj <> /Contents 124 0 R >> endobj 128 0 obj <> /Contents 129 0 R >> endobj 133 0 obj <> /Contents 134 0 R >> endobj 138 0 obj <> /Contents 139 0 R >> endobj 143 0 obj <> /Contents 144 0 R >> endobj 148 0 obj <> /Contents 149 0 R >> endobj 153 0 obj <> /Contents 154 0 R >> endobj 158 0 obj <> /Contents 159 0 R >> endobj 163 0 obj <> /Contents 164 0 R >> endobj 168 0 obj <> /Contents 169 0 R >> endobj 173 0 obj <> /Contents 174 0 R >> endobj 178 0 obj <> /Contents 179 0 R >> endobj 183 0 obj <> /Contents 184 0 R >> endobj 188 0 obj <> /Contents 189 0 R >> endobj 193 0 obj <> /Contents 194 0 R >> endobj 198 0 obj <> /Contents 199 0 R >> endobj 203 0 obj <> /Contents 204 0 R >> endobj 208 0 obj <> /Contents 209 0 R >> endobj 213 0 obj <> /Contents 214 0 R >> endobj 218 0 obj <> /Contents 219 0 R >> endobj 223 0 obj <> /Contents 224 0 R >> endobj 228 0 obj <> /Contents 229 0 R >> endobj 233 0 obj <> /Contents 234 0 R >> endobj 238 0 obj <> /Contents 239 0 R >> endobj 243 0 obj <> /Contents 244 0 R >> endobj 248 0 obj <> /Contents 249 0 R >> endobj 253 0 obj <> /Contents 254 0 R >> endobj 258 0 obj <> /Contents 259 0 R >> endobj 263 0 obj <> /Contents 264 0 R >> endobj 268 0 obj <> /Contents 269 0 R >> endobj 273 0 obj <> /Contents 274 0 R >> endobj 278 0 obj <> /Contents 279 0 R >> endobj 283 0 obj <> /Contents 284 0 R >> endobj 288 0 obj <> /Contents 289 0 R >> endobj 293 0 obj <> /Contents 294 0 R >> endobj 298 0 obj <> /Contents 299 0 R >> endobj 303 0 obj <> /Contents 304 0 R >> endobj 308 0 obj <> /Contents 309 0 R >> endobj 313 0 obj <> /Contents 314 0 R >> endobj 318 0 obj <> /Contents 319 0 R >> endobj 323 0 obj <> /Contents 324 0 R >> endobj 328 0 obj <> /Contents 329 0 R >> endobj 333 0 obj <> /Contents 334 0 R >> endobj 338 0 obj <> /Contents 339 0 R >> endobj 343 0 obj <> /Contents 344 0 R >> endobj 348 0 obj <> /Contents 349 0 R >> endobj 353 0 obj <> /Contents 354 0 R >> endobj 358 0 obj <> /Contents 359 0 R >> endobj 363 0 obj <> /Contents 364 0 R >> endobj 368 0 obj <> /Contents 369 0 R >> endobj 373 0 obj <> /Contents 374 0 R >> endobj 378 0 obj <> /Contents 379 0 R >> endobj 383 0 obj <> /Contents 384 0 R >> endobj 388 0 obj <> /Contents 389 0 R >> endobj 393 0 obj <> /Contents 394 0 R >> endobj 398 0 obj <> /Contents 399 0 R >> endobj 403 0 obj <> /Contents 404 0 R >> endobj 408 0 obj <> /Contents 409 0 R >> endobj 413 0 obj <> /Contents 414 0 R >> endobj 418 0 obj <> /Contents 419 0 R >> endobj 423 0 obj <> /Contents 424 0 R >> endobj 428 0 obj <> /Contents 429 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 18 0 R 23 0 R 28 0 R 33 0 R 38 0 R 43 0 R 48 0 R 53 0 R 58 0 R 63 0 R 68 0 R 73 0 R 78 0 R 83 0 R 88 0 R 93 0 R 98 0 R 103 0 R 108 0 R 113 0 R 118 0 R 123 0 R 128 0 R 133 0 R 138 0 R 143 0 R 148 0 R 153 0 R 158 0 R 163 0 R 168 0 R 173 0 R 178 0 R 183 0 R 188 0 R 193 0 R 198 0 R 203 0 R 208 0 R 213 0 R 218 0 R 223 0 R 228 0 R 233 0 R 238 0 R 243 0 R 248 0 R 253 0 R 258 0 R 263 0 R 268 0 R 273 0 R 278 0 R 283 0 R 288 0 R 293 0 R 298 0 R 303 0 R 308 0 R 313 0 R 318 0 R 323 0 R 328 0 R 333 0 R 338 0 R 343 0 R 348 0 R 353 0 R 358 0 R 363 0 R 368 0 R 373 0 R 378 0 R 383 0 R 388 0 R 393 0 R 398 0 R 403 0 R 408 0 R 413 0 R 418 0 R 423 0 R 428 0 R ] /Count 84 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 16 0 obj <> endobj 17 0 obj <> endobj 21 0 obj <> endobj 22 0 obj <> endobj 26 0 obj <> endobj 27 0 obj <> endobj 31 0 obj <> endobj 32 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <> endobj 41 0 obj <> endobj 42 0 obj <> endobj 46 0 obj <> endobj 47 0 obj <> endobj 51 0 obj <> endobj 52 0 obj <> endobj 56 0 obj <> endobj 57 0 obj <> endobj 61 0 obj <> endobj 62 0 obj <> endobj 66 0 obj <> endobj 67 0 obj <> endobj 71 0 obj <> endobj 72 0 obj <> endobj 76 0 obj <> endobj 77 0 obj <> endobj 81 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 87 0 obj <> endobj 91 0 obj <> endobj 92 0 obj <> endobj 96 0 obj <> endobj 97 0 obj <> endobj 101 0 obj <> endobj 102 0 obj <> endobj 106 0 obj <> endobj 107 0 obj <> endobj 111 0 obj <> endobj 112 0 obj <> endobj 116 0 obj <> endobj 117 0 obj <> endobj 121 0 obj <> endobj 122 0 obj <> endobj 126 0 obj <> endobj 127 0 obj <> endobj 131 0 obj <> endobj 132 0 obj <> endobj 136 0 obj <> endobj 137 0 obj <> endobj 141 0 obj <> endobj 142 0 obj <> endobj 146 0 obj <> endobj 147 0 obj <> endobj 151 0 obj <> endobj 152 0 obj <> endobj 156 0 obj <> endobj 157 0 obj <> endobj 161 0 obj <> endobj 162 0 obj <> endobj 166 0 obj <> endobj 167 0 obj <> endobj 171 0 obj <> endobj 172 0 obj <> endobj 176 0 obj <> endobj 177 0 obj <> endobj 181 0 obj <> endobj 182 0 obj <> endobj 186 0 obj <> endobj 187 0 obj <> endobj 191 0 obj <> endobj 192 0 obj <> endobj 196 0 obj <> endobj 197 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 211 0 obj <> endobj 212 0 obj <> endobj 216 0 obj <> endobj 217 0 obj <> endobj 221 0 obj <> endobj 222 0 obj <> endobj 226 0 obj <> endobj 227 0 obj <> endobj 231 0 obj <> endobj 232 0 obj <> endobj 236 0 obj <> endobj 237 0 obj <> endobj 241 0 obj <> endobj 242 0 obj <> endobj 246 0 obj <> endobj 247 0 obj <> endobj 251 0 obj <> endobj 252 0 obj <> endobj 256 0 obj <> endobj 257 0 obj <> endobj 261 0 obj <> endobj 262 0 obj <> endobj 266 0 obj <> endobj 267 0 obj <> endobj 271 0 obj <> endobj 272 0 obj <> endobj 276 0 obj <> endobj 277 0 obj <> endobj 281 0 obj <> endobj 282 0 obj <> endobj 286 0 obj <> endobj 287 0 obj <> endobj 291 0 obj <> endobj 292 0 obj <> endobj 296 0 obj <> endobj 297 0 obj <> endobj 301 0 obj <> endobj 302 0 obj <> endobj 306 0 obj <> endobj 307 0 obj <> endobj 311 0 obj <> endobj 312 0 obj <> endobj 316 0 obj <> endobj 317 0 obj <> endobj 321 0 obj <> endobj 322 0 obj <> endobj 326 0 obj <> endobj 327 0 obj <> endobj 331 0 obj <> endobj 332 0 obj <> endobj 336 0 obj <> endobj 337 0 obj <> endobj 341 0 obj <> endobj 342 0 obj <> endobj 346 0 obj <> endobj 347 0 obj <> endobj 351 0 obj <> endobj 352 0 obj <> endobj 356 0 obj <> endobj 357 0 obj <> endobj 361 0 obj <> endobj 362 0 obj <> endobj 366 0 obj <> endobj 367 0 obj <> endobj 371 0 obj <> endobj 372 0 obj <> endobj 376 0 obj <> endobj 377 0 obj <> endobj 381 0 obj <> endobj 382 0 obj <> endobj 386 0 obj <> endobj 387 0 obj <> endobj 391 0 obj <> endobj 392 0 obj <> endobj 396 0 obj <> endobj 397 0 obj <> endobj 401 0 obj <> endobj 402 0 obj <> endobj 406 0 obj <> endobj 407 0 obj <> endobj 411 0 obj <> endobj 412 0 obj <> endobj 416 0 obj <> endobj 417 0 obj <> endobj 421 0 obj <> endobj 422 0 obj <> endobj 426 0 obj <> endobj 427 0 obj <> endobj 431 0 obj <> endobj 432 0 obj <> endobj 8 0 obj <> endobj 14 0 obj <> endobj 12 0 obj <> endobj 437 0 obj <> endobj 10 0 obj <> endobj 9 0 obj <> endobj 433 0 obj <>stream xXiTS1V)UV␠uV:#<1CDŽ! afC  ZN:=8sy7Xg/ۻֽku?Ǘwxy-F2 a_ iB} aK)d/D릉suF ˷(v9lRɃbYRg_O7sqȨpYDkpoy_dOw9EQGDnYE5f[x.Wٞ} ;~w,}w+]-XbIܨY^j6CR( 5:DIPFj!uDE6S-bj+6N-vPKw]2j7rVPHq$j2%(15C^שuj i 5 pf45:nz.z}>ϼa#ُLS?ױcIƩ=_dg_kq:X ^rq#r#Z*joL 'mdt{ҳdq0̰,,lPJA|S$]Iǵb9xY=yFT -+ڝ nYUbQF2Y½q IC͎A NXM<Wt  3Hkfqit-L`ƄZY03(XRŠZJ릞/^I ">+_$\x !y34Ya1'5qת{? _J,Ca;TqL]#".%}~d&*YCf jYZAEqHbKY#yx!~0`RR+>WIz-ɢ0»=9ك,`zݭ.Ă 8{n1{ä v8t3|/ MeںZYx|ސ6-]tE%AX> iYo~j)&2wv8/l \zŐ-% 7ehaP`1;)%t}JsGH|3yiXYHgXQ$Ɠ$E|Iiw|p`aک$E/LhrsJ&PRtVŴ]$->20#`PuH!:_YEjLbi++*}ځw#^i֙A{1Z8ܔ2 {ƎD:B[ƶfRWx9aL6'5;@yhԟ0  [wrWXHb~n ('Q[ᙜVa:(h.=H:)wM8_,h$ |X&]AHjɋAo?t0ABYh]O$x6|T]y"b >DZQ hmkOU^PyȩY  2fVgg2G"bx]{2etd)þdfA@YnIA3+dq[.A"\}ZNՇ2;:oDn%&!qdJe.dH<OCm.J(_dy%c\֊_ș;YfI87̭*u[_G5[u2 UeXHtdIlJ#O^0uĆ9[jy$;X BVigH9vS0tZ%wtdQaɻUȊ7 $Vn}^|HRjMwsH?˙Oj#* #k淚W٥iHtʍx*ҙyP*J 9Pd`-8WedhsQ\ N4,坫;rń^=tvTݚiԡ$b5)ժ[ʛSJrs6ӠnN/3*Q*K 1Ko.c,4L] EE m=_o9ۿw 6wOW_:\zoEZũ%Xޕɹ_^~7&a؝rnFe"ud56Xf}a ] ? }6uz~,"i]VH}WFАϵf4<Ӯ~Sog= 8ydWhȰ7upIe<š VfI1#x'n ?j3Mü_/5.Hw0e~BoDs&$kcRb{H~&pZsBVnB*sVt;i5Mx+HUsº5itV1\fCX|?p6Ju>v8ѻ%jlm {Zai8c*o"NN3˧ m =nOrs㿼WZ./TO]=Mt_ķӇr8XF,\<9|7aS`MǾXYxA0FJĒrF'o|JX& %'٨O:ay*cZrFVzzDLE)lXjmܲm^Q /zu?^)ɞ+#8-H{NHJ.gg/:oY`|ߗrNF:g#;w'zffl\]ei^ڕ,(C6!6㾧K&ƿdd6>]“ WdTj75ִ?C';䓑5Ç]xu뤢Oy-S-{-U/_VJآl9J| 2$Us,FC{KP0ڂtC o;T^aIIi6 4iNX+r*O-tZXԎH;\Αv,OYokGzmyfep?;p "ĔoEV;qവzКF,r" @m,?ޖkHNyt 1AA>!-͝-޶RҤ4;vøɢ hj `.cQn(~[nL*3TH|OŴbDTO_^WH?^u|jF_s-̠0u>G$A]h'aEF}(.e,Lp^r9:;22#+Tc*z"fmr u`֫~!o9o.+$'Vp9QLqM6I͂߂m!/gU0Rg&['LӔRT"F*qKΜ6kX穌BT,F'JlNGΜO/Vipap.ߗִG4|Wpmʄo'08 좙ܼkabXw0ދSl .4!/@NAGlJIg|Ńӷg  Gc馁ֆ˨(kK"N<zȚ o"~js#9뀞,zt7sm5!vAA ¥  gY`SD)e{JSbeQ7*=4Q8-&XѣgO\.: !0oLH,ao~q[ ,c;0Y 0ke4"Yti c>A";~MZ{zWihkLTI?hF˃] z +a0㗝&2ߦwQrA#,&_ C6qX0 FXH3`asLfj%0/aIx O8H(N&4C/P j1tM`B#GDeȋh+@/`ĻDtۖ[SwX~{7 -]a{Μrsq]LaK(Zn =xƓ7l ՘ujIÁ?}v("/;'킧YK~y/xoA#Sj"dڄC<5HkYٺ Uc;쵙efA7 nwHdEx,“"5;sc}rk\WxsHhahg6*GϺa=C󮳑@kt$iNx/y?[*XLy_8`o_=f}{ ="x/@@x(gH-#X 2n{YȤX-8d_yd镵fƠop[l3i7 ,Z!@۽|7]V%"b I> endobj 434 0 obj <>stream xXTT־̽Wxi&sK j,DH6`yhf#s@P bQ>+/fyy^׿ ˷# (L:EF_^8aL@0{ f T "cm|8D3NAL6#v_1c:E_z՗Q}:q؊aaa#1!akC"hʗfRcŔ5򧜩Oʅ\);ʍrfQD3j.5&SʄRPC(2d!S}T?j՟rP)Gj0JFQ w  F>F3D%s]cǧϑ缾qqwHpm A8Iy>!S&q pf_90sgR,l,T-ZZN|, DjPLs951 h~  rDGf$$TjmH㙚@ydώzƈ;S`! 5#鷰G^F@mrVj5S~Œ$+zs_ ki$-B?5/)E;[.89WM;:i`J\)|nž@WLpPfQsVS<@LCj>KݔD5Qˮ¿Z aKkގS05@nGa/߻Ihj P)oTU֦jL`<< 4J9^6/!0ֹ,$eZ p[zp~<- X4y L@\qrZTVUlLPz{wC,fl^w0@dn/Vƕ"\E6`+Sc³+&u`A0&!㓚ZL ުꭹ-DB,|x%y|O}[.vg8=?ݺ7^/ HTZb]a2ILLyj6%Bhg3zk5!A:L߂QXmL>XY6g:Bt&A+ds,w%wny_+F~-.ԶYGt*}6_+H2bjFЊ%i4=[7(aL,X]f*Hf81}ؒt~;Iކk4TB"D7gz (#阔ʴwڑOi{SU5)MfB0{ ޭG֣7en+GlJU[UWï]|ђu8e=qB҃)OӆQ'Ay?%b$$L-z:z]d 8c /Wڨ;^gV{boק/ =?_uʣdBEvAtU*UO7:v޾(> N'&m#v^V=ta{̿feڹqGrm4a箚4}ߑ^NsPC#46%PiXI/ZG9|]0o2mׅ =B+ bߑB=3ӐQe7y%[y'5_XwJ3H,"p#R+:qFEUumaSUI9YhEb a U˟+HN84@2 f,t *m@dX P=<{ڮtL,~/".B0"V[=?rЀ$oG0z&=7g|~P*/NI&.лB9.[bK $ ^2xf +"dvSh1ti1m L5:'tVCG@|=͂#MCz~?\yO2[zu0޴[PNw92;9n2);3IԪMEUʳ5#%|xլߴ tx^pEGI۝7Xs|ӒW2g-w#p`N/jZXOfW89u0b @ Е~Ƿ2"96"I D57h+8,acbXCutz7gX,c_0ŬD݉ (?D[D{vHtgg;;'ry1!Ze6?YWzzמ-%ōwU|z[@\edqZޮLkX>=0'z&tiצ/=޵ZpQ 5>E.ޅ!F=ptqz\ r(\AղTq`vb[%uyu;..68f8&x \ I-){EM_tHھqgbm8 e]&̯(OD{xRi2T58tl0Z7|Y6ʳb]ن 5;P#{ܱ{ߝ[XY[L} NJB]+ؒSk8URm]Y6%Ѭ}ӷ*&pDn3!iQsaMBp{<2HC..$iDURJ2L&Bx3%t>HS^Pf! eqҁПlGJ!!Vdf~,7oyzÓil/PiR!l3DJ\K2%ݠf vȯKVWUͿMJO ?WK^@:qgx|hWu#>pz϶}m%S"v"Gbfų?0oDg1?2 D>9ű)ꪲ"eݹ KO>L♞a.|/õ:nZة6to q1i:~w 9N3=',ۼ?@^]Ī|kd5b,+^hwi׭}ÃQI ^L++TR8BTkE{IKp6G'Sn5e楗(xϵy?ѽWf5)/?|gy,9sA+Nw_p > O8sBmz85e% JT7!=Ҽ=pRqnI~1(CeE P*.M-`9yRTnr7geg-Dif@R榜d23ssunLU1-PnavaNAyQ&9 ₒMZkp䦡0[ ̌tAw`*kXuq~an aoЯmSu跩)$-aBMCFlmLMM.۔_F9> endobj 435 0 obj <>stream xxy\S!眪*FVXZTQyPP)dNHN$!@03(cpj`~ fXjnvR'זvT}!+$avPaER)RG^ظ?Qs 1RmF;m0!2R_<htvgtE9}d*7)qwg@-T;f#ω΋Uҿ!!d< .E=9)BgNy?9! @U!( WN;biɁax ե SFfz:@Ȼ],S]e|)\ztvW'?%)e5%5/ cm0?!mvbfS.}PfBnT@lBŔ8h!= 4ΖYj͆fZ pC!-SO/-D/#2b#”;#wN=w%#ED5T W5CaB[ |, A i'Q'岟+p Mmzi>%'$0a/kόX6cL0W 8٤6[j 5K*C:qW]K@fpy˂ܪMۓV>p*kh;Hùf'8R"`ry0,"ą*˨(1\2]]: '}\8uW #3"()0;V K({OwZTcR|qi^jzA&ym:o# Y슙4z?!buD5OmR(t4csJǾ.;)xxt%@@V/$yb)0\Lkf?l8ƼǍhL†h.vsO +ْO ,X4=4r6ϸ #_Rg+A"H-q&f_h8{_m!@LPB[/#l{7 %"fS#!2EJ3IŻ2*=tZX h㢯U,gYDӕM]o6cp1= jç좙P $K4̢ڏn.TvCZ+t#:`JPᷔ#, U $R̔>XQb|%\|dJN,[*ͅ6myA9Ae(DJ-d3isӘuBK΀y--fWsx)թ)1j3P:on9aDJREuP̖^,^yay~AU.VUmD?JbPM5omYlPΫ:f.[PS_EaW?gp'ܘ7bB't|P)pV">a>ΜBC" V`kO5% vSh\YǕ3yeh+/%StlE,5/б)Bxyp/mbYk>nYI!h ZɃ)'8=:´9q)4C5G? 2@*&t@ uа 6Jd̃~ "BRo;Xm& ANE CxΦG@˥TD d@JOiRN]/i*ptqImT+C$ZpJVYkOKߠ9Zhx몝tS%.}3ERr~rGB ~pJ| 58uwv >ܠk4b\Q8]OPl?]IN{@p{<{^E[ez3 ͼ r÷dzǐOT%,krkuX% L҈d1dh49[/Se 2UX6S8LH˜8(LD~oW0,k\T`LJk< ጅwݟMrs\?Nep$}A+bށE2>y@?Sh"~TjDα79REq3hf5=9\A q٩CB:$q.eg5{l(!ZJE]Z'Wь+ BoNN;A /sFP)9id@ Nn?OHO#]c=Wt *|\]Gɝgo2:h>vMs6+s*Y w0E\['ᦕ+JPg֙ VY tZUDR #͉΃g"kiӠ[Su=?dT@e4ǬMj?)?Ʌ22Åcٔ![9N Smk=j RH1N: lFRw&zoVz"] kQONnPh'kzzuOP6Ѱ2n/=ēJcV.f|SgKXE (CL+oe/VFwyPDϯR Ѥ*м16-ϫ>.X%rSxX cC< ә'vIRF8%gOu9 C]0YK,.@bFH~*3?UӰjh:U(j5{fJ(R:@FQp ^k  Uz'ҘDq eF$\)\?៫]aJ献J RA6UoyTX|u 젾+ "ꢡDݹc oB35Ujg +zuFY:]Z̬+r3@6ynXφmYm4\G>5lt6knWv MXsl [rwUh ezDFbqpL pf~LhRނRM M#m,36_ʋUj(W=?赀CG qw;ߪuZ.D[^iϙ˸$u 4~LQ$J3r=6d&nJ ;a R;U 7;r wh*Dt;z(6\?z}9\?^u:^~ƔKV1-,;v 'GO OmYPJ[v3 =<>984R#HJ}#x5@<3F&LK2λμEafe;I[c{9;a'ZK!\!躸0 s w0saY F+"QkET=0=_[i:rv7G/.GbM$g2"SGe"s4>&\H(f\?vpksCXSfriA31wŸxr$}Ѽʼe|D87H;*KGE `ýЛ{qǼf}i ^oq)Ɇe-7)3# 7֎$ḛS_x>L0,Gp?< nӟy_zݾ}gK_!o>I8_ŝD/~#}{/>GD!dٍN z]>3.Ǐ^=uwڡmX`5:v,k2lmA ]+f˗U-3UT 0nͬoٗЭ^5=if)|D<єB*ĞJ%89j:53Z ऋk @q|%Z'|<|Ͻ ;/ [ag/"8O?$& d6 :2%rȁxz`Hrs\y5&nfJLFf}l8&'$75ַ5& roj%AdOǿTrzaep>'p/X,Fc=TdFOk6/!Ha/ƙ+pMqŴ13cDn?``2Ƃ`pouw<P++2`k '1'ĺpcXR+b@3z|9hxcل k)ݩ3n)_e5]i}w E[O6 }E#?=u26]!}UפNݕxd^W2\ڨzMS$hDbEbgMTW.wizAm,5yu9 JEF="<\_^W; ZKK@#]'Ȓ)L&H5jIENT,g JbڕS59 9 +92ivS~J-Ѵr.WG .U؊"ZXS Z0jk`} ώN6]1 +8aGWPvÈpc}M4dC㢔0ބ0&J;\YV=*fqΠ_[9I;ctg| w࿂ﯣ;,n:bҟQr1 ʐT\~k>h`4\p gn\*4G<1m(oW`?e;vcA6Nod~dC ^ %GbG#j:}¿'L08*Bixp)|qG#\< τSdLP ('{'~6> endobj 436 0 obj <>stream xXwpSWBXд)duM$tHI6 c0bdd5wuɲ-ɖ{o`b0ՄB -H,;)\r3Y>~~ b`%L+xOnVJ䃙TL4*xa-KL0vd%qDax(@d0^?cƭϜ9k|iaVFfqyߌNFeiEYy𛒴ܽ´YdQQƽ=yѿǏ}x f}wi+EK{$)Դ 6% Fx}D GBl ^%׈i&b:@l&o[mGvb)1A,#vˉJb>XM,$ooXb=`8b+ش6-AB@ʡ=̇.|VDQhv -LM7pz$8yJ-VyeLⴸj/ק]-|U3۷E7|9`5X$'s&1&k.|@|jʐ˥;QrYy1Rq! Rr+M$z)$~?n2bG] 7+]vq/g7VA(5^CoI+LS|u =+=D͸G2Ei3k bj{+џ$F h*B!8/ %0^#ڛp2spuK18 K_<T;dk[FxQ6.R3mF?WkTue3qJkUFXZA~-̀/L>? y-S@Q"!7d݂Jf+s+}RUCYbXxHeXZCϪ'Aƍ÷plpWFY~Pe c2̡Ϟ3Tڀ 45 ,KaHE)XZT t@k_z vԘ]Irj7S2A[I\0_(Gmq f H-G[Xf&?g-Ed5\!KjM;(=;r<6lN+ >+~' У;S8L[V+r& @u.<ڌf ?^FrBvl˙ԕasPtC`Z(3,.-H“rLv];qnl˭V ga&[sѣvf:x:Wu*#ٟzź?n8z4Lj1f &?ƝLV9׿܏dmx/A`l/h+%rJ.Pt@vA#eq] @oՙXU9[Ea)+A|eeu[<%z9۹gO|9B W\pW뉯<^ nϷ=eN\n . ' dVXJ`[ T )k ΁?FEg`"2_U̻xTS1FJfs&-Y0=vR>vc  GpQk3=~d~H9lvOכꝺ$L|4A Kp@UE I$\[_s;-E  ^Crefy>sdb3i= 2:ѠU UPmva8t@pg,{,>@+5@QbzFrJ}JqYb-1X0Ze[%nme\ {*Jj7CVz4- ŊRqAwvjm;Պ*V}7ϻXGO8ʠy_2gSg-.3E/,z+ᡗ-Q&v- ߅Ww Z5X&8͇`ۦ3~%a*l޲z{t\,T9_w7;>I5b r>WݙKsELYa! zw YN>JNeW@<)8i@+${Ӌ%"NwP{K5. E2Fzp'dP(Z ,^MX)V{x)"$Mpq) M, L@gM7lJ4Uh}5יǟ RE;1]ߜ>CVR2Z&-WZ\ɢ9\4ع44oɄ'7O<5 )=x>b[BI6XQJڕy@UTJΡu(nfR6 UlA␤"Oy~E"sX7)b) 4: 5:oy #/7Ný[5zR>eA PX͊-h1O/ b5-Bz.^>eJR #6qLëVK@2Y%s3{6G]*hnnɇ?1B%&2K7H>Wz۩f'|[_ظh'7ݹvO(v~c,-ʕd 4[%$V7RCmZ ~Z8XU:i;\ms7Y# ȥřO/oDAV \s4 +FDuV#k몫j7mߙ*ڝ!w gsY}==L8 !}`!UB|F~l h􃿁ˡSKNƂrO3V}pi/݉T],bsEH%¯j:gNK]2]ί.Kóf`jCT ҫVX&W\{8':0Q/kہ!YV? 9?<~rN2R,ί6zĵavj-3du6ǧ|ޮ}ݡ`[7p=S]+C$ɢDɹ,@}qcH[R=q2\8&h {R,[tH5qk٪ԠAY-&$ީ>zᜊO߽| G ҄NN%T|NEAH<7'&}!MtCsw;QR"C/YL5UeEYufU-9Ȏe0wǣQp ӏ1*<{_݆&Ju6g!1xaћLXYlNJ5Xzt:TQ*= 4_H̩fܓV\YfDy8CAq@w!A }/T457Gf";"vWp)t&ř(E@ T/ɹ+vN}%fygR.SHeW;$KcގO>؞X:YQ{XdhId]H[U|*jlRb<{![X{М* Ht, : R$_m -z@9nz7h#z{&W,2*+ǓÓ8jz毌XAi#Ɗn~8Ni q`V>`-7wYZVnѵ^fQ[&&YmY<cۃU|z]{ej/hh8|?Bv06Jx:]uT(gTigÙ~AfAG!pY3l~zQ:> r.\qra&h2Z**M& ;m.{x݅MbH#'y 4N)PMvg_6Wp%EfއͼS^U47M[($Wn## Xy|':YʕB4:LL 2ǎ]=zy NOYcSHI5ˀR8p'jܳϥgcŒ_w+g4>72}" Ӭ.A|[Yq҅X<}H+v>_ԃ;L6jNIsÕj,wDX;,xXo_9t,aF&\rP B3|e2; \ ޶z+%+*rW0[*.cARyp +.v|7.' yk{֯3`r^b]gSC& 2+,,k(lnoom+hFVMdh2wpX=NZE/ V;cc@ endstream endobj 438 0 obj <>stream 2019-09-21T14:17:08-07:00 2019-09-21T14:17:08-07:00 groff version 1.22.3 Untitled endstream endobj 2 0 obj <>endobj xref 0 439 0000000000 65535 f 0000158404 00000 n 0000194510 00000 n 0000157697 00000 n 0000143825 00000 n 0000000015 00000 n 0000001874 00000 n 0000158470 00000 n 0000165456 00000 n 0000167406 00000 n 0000166980 00000 n 0000187640 00000 n 0000166388 00000 n 0000179444 00000 n 0000165915 00000 n 0000173677 00000 n 0000158511 00000 n 0000158541 00000 n 0000143985 00000 n 0000001894 00000 n 0000004807 00000 n 0000158604 00000 n 0000158634 00000 n 0000144147 00000 n 0000004828 00000 n 0000007330 00000 n 0000158697 00000 n 0000158727 00000 n 0000144309 00000 n 0000007351 00000 n 0000009548 00000 n 0000158779 00000 n 0000158809 00000 n 0000144471 00000 n 0000009569 00000 n 0000011597 00000 n 0000158872 00000 n 0000158902 00000 n 0000144633 00000 n 0000011618 00000 n 0000013784 00000 n 0000158954 00000 n 0000158984 00000 n 0000144795 00000 n 0000013805 00000 n 0000016589 00000 n 0000159047 00000 n 0000159077 00000 n 0000144957 00000 n 0000016610 00000 n 0000018666 00000 n 0000159140 00000 n 0000159170 00000 n 0000145119 00000 n 0000018687 00000 n 0000020472 00000 n 0000159222 00000 n 0000159252 00000 n 0000145281 00000 n 0000020493 00000 n 0000023532 00000 n 0000159295 00000 n 0000159325 00000 n 0000145443 00000 n 0000023553 00000 n 0000025942 00000 n 0000159368 00000 n 0000159398 00000 n 0000145605 00000 n 0000025963 00000 n 0000027687 00000 n 0000159441 00000 n 0000159471 00000 n 0000145767 00000 n 0000027708 00000 n 0000029968 00000 n 0000159523 00000 n 0000159553 00000 n 0000145929 00000 n 0000029989 00000 n 0000031903 00000 n 0000159605 00000 n 0000159635 00000 n 0000146091 00000 n 0000031924 00000 n 0000034296 00000 n 0000159687 00000 n 0000159717 00000 n 0000146253 00000 n 0000034317 00000 n 0000036542 00000 n 0000159769 00000 n 0000159799 00000 n 0000146415 00000 n 0000036563 00000 n 0000038193 00000 n 0000159851 00000 n 0000159881 00000 n 0000146577 00000 n 0000038214 00000 n 0000040473 00000 n 0000159933 00000 n 0000159964 00000 n 0000146741 00000 n 0000040495 00000 n 0000042243 00000 n 0000160008 00000 n 0000160039 00000 n 0000146907 00000 n 0000042265 00000 n 0000044228 00000 n 0000160092 00000 n 0000160123 00000 n 0000147073 00000 n 0000044250 00000 n 0000045639 00000 n 0000160176 00000 n 0000160207 00000 n 0000147239 00000 n 0000045661 00000 n 0000047678 00000 n 0000160260 00000 n 0000160291 00000 n 0000147405 00000 n 0000047700 00000 n 0000049967 00000 n 0000160344 00000 n 0000160375 00000 n 0000147571 00000 n 0000049989 00000 n 0000051144 00000 n 0000160428 00000 n 0000160459 00000 n 0000147737 00000 n 0000051166 00000 n 0000052682 00000 n 0000160512 00000 n 0000160543 00000 n 0000147903 00000 n 0000052704 00000 n 0000054805 00000 n 0000160596 00000 n 0000160627 00000 n 0000148069 00000 n 0000054827 00000 n 0000056337 00000 n 0000160680 00000 n 0000160711 00000 n 0000148235 00000 n 0000056359 00000 n 0000057784 00000 n 0000160764 00000 n 0000160795 00000 n 0000148401 00000 n 0000057806 00000 n 0000059274 00000 n 0000160848 00000 n 0000160879 00000 n 0000148567 00000 n 0000059296 00000 n 0000060506 00000 n 0000160932 00000 n 0000160963 00000 n 0000148733 00000 n 0000060528 00000 n 0000062110 00000 n 0000161016 00000 n 0000161047 00000 n 0000148899 00000 n 0000062132 00000 n 0000063409 00000 n 0000161100 00000 n 0000161131 00000 n 0000149065 00000 n 0000063431 00000 n 0000064676 00000 n 0000161184 00000 n 0000161215 00000 n 0000149231 00000 n 0000064698 00000 n 0000065548 00000 n 0000161268 00000 n 0000161299 00000 n 0000149397 00000 n 0000065569 00000 n 0000066607 00000 n 0000161352 00000 n 0000161383 00000 n 0000149563 00000 n 0000066628 00000 n 0000068412 00000 n 0000161436 00000 n 0000161467 00000 n 0000149729 00000 n 0000068434 00000 n 0000069459 00000 n 0000161520 00000 n 0000161551 00000 n 0000149895 00000 n 0000069480 00000 n 0000070875 00000 n 0000161604 00000 n 0000161635 00000 n 0000150061 00000 n 0000070897 00000 n 0000072508 00000 n 0000161688 00000 n 0000161719 00000 n 0000150227 00000 n 0000072530 00000 n 0000074169 00000 n 0000161772 00000 n 0000161803 00000 n 0000150393 00000 n 0000074191 00000 n 0000075458 00000 n 0000161856 00000 n 0000161887 00000 n 0000150559 00000 n 0000075480 00000 n 0000076906 00000 n 0000161940 00000 n 0000161971 00000 n 0000150725 00000 n 0000076928 00000 n 0000078348 00000 n 0000162024 00000 n 0000162055 00000 n 0000150891 00000 n 0000078370 00000 n 0000080228 00000 n 0000162108 00000 n 0000162139 00000 n 0000151057 00000 n 0000080250 00000 n 0000081615 00000 n 0000162192 00000 n 0000162223 00000 n 0000151223 00000 n 0000081637 00000 n 0000082971 00000 n 0000162276 00000 n 0000162307 00000 n 0000151389 00000 n 0000082993 00000 n 0000084601 00000 n 0000162360 00000 n 0000162391 00000 n 0000151555 00000 n 0000084623 00000 n 0000086128 00000 n 0000162444 00000 n 0000162475 00000 n 0000151721 00000 n 0000086150 00000 n 0000087716 00000 n 0000162528 00000 n 0000162559 00000 n 0000151887 00000 n 0000087738 00000 n 0000089539 00000 n 0000162612 00000 n 0000162643 00000 n 0000152053 00000 n 0000089561 00000 n 0000090895 00000 n 0000162696 00000 n 0000162727 00000 n 0000152219 00000 n 0000090917 00000 n 0000092369 00000 n 0000162780 00000 n 0000162811 00000 n 0000152385 00000 n 0000092391 00000 n 0000093785 00000 n 0000162864 00000 n 0000162895 00000 n 0000152551 00000 n 0000093807 00000 n 0000095706 00000 n 0000162948 00000 n 0000162979 00000 n 0000152717 00000 n 0000095728 00000 n 0000097210 00000 n 0000163023 00000 n 0000163054 00000 n 0000152883 00000 n 0000097232 00000 n 0000098842 00000 n 0000163107 00000 n 0000163138 00000 n 0000153049 00000 n 0000098864 00000 n 0000100601 00000 n 0000163191 00000 n 0000163222 00000 n 0000153215 00000 n 0000100623 00000 n 0000102842 00000 n 0000163275 00000 n 0000163306 00000 n 0000153381 00000 n 0000102864 00000 n 0000104728 00000 n 0000163359 00000 n 0000163390 00000 n 0000153547 00000 n 0000104750 00000 n 0000106706 00000 n 0000163443 00000 n 0000163474 00000 n 0000153713 00000 n 0000106728 00000 n 0000108332 00000 n 0000163518 00000 n 0000163549 00000 n 0000153879 00000 n 0000108354 00000 n 0000109960 00000 n 0000163602 00000 n 0000163633 00000 n 0000154045 00000 n 0000109982 00000 n 0000111110 00000 n 0000163686 00000 n 0000163717 00000 n 0000154211 00000 n 0000111132 00000 n 0000112372 00000 n 0000163770 00000 n 0000163801 00000 n 0000154377 00000 n 0000112394 00000 n 0000113805 00000 n 0000163854 00000 n 0000163885 00000 n 0000154543 00000 n 0000113827 00000 n 0000115179 00000 n 0000163938 00000 n 0000163969 00000 n 0000154709 00000 n 0000115201 00000 n 0000117015 00000 n 0000164022 00000 n 0000164053 00000 n 0000154875 00000 n 0000117037 00000 n 0000118688 00000 n 0000164106 00000 n 0000164137 00000 n 0000155041 00000 n 0000118710 00000 n 0000119867 00000 n 0000164190 00000 n 0000164221 00000 n 0000155207 00000 n 0000119889 00000 n 0000121794 00000 n 0000164274 00000 n 0000164305 00000 n 0000155373 00000 n 0000121816 00000 n 0000123962 00000 n 0000164358 00000 n 0000164389 00000 n 0000155539 00000 n 0000123984 00000 n 0000125991 00000 n 0000164442 00000 n 0000164473 00000 n 0000155705 00000 n 0000126013 00000 n 0000127546 00000 n 0000164526 00000 n 0000164557 00000 n 0000155871 00000 n 0000127568 00000 n 0000129723 00000 n 0000164610 00000 n 0000164641 00000 n 0000156037 00000 n 0000129745 00000 n 0000130894 00000 n 0000164685 00000 n 0000164716 00000 n 0000156203 00000 n 0000130916 00000 n 0000132838 00000 n 0000164769 00000 n 0000164800 00000 n 0000156369 00000 n 0000132860 00000 n 0000134824 00000 n 0000164844 00000 n 0000164875 00000 n 0000156535 00000 n 0000134846 00000 n 0000136642 00000 n 0000164928 00000 n 0000164959 00000 n 0000156701 00000 n 0000136664 00000 n 0000138089 00000 n 0000165012 00000 n 0000165043 00000 n 0000156867 00000 n 0000138111 00000 n 0000139333 00000 n 0000165096 00000 n 0000165127 00000 n 0000157033 00000 n 0000139355 00000 n 0000140642 00000 n 0000165180 00000 n 0000165211 00000 n 0000157199 00000 n 0000140664 00000 n 0000141884 00000 n 0000165244 00000 n 0000165275 00000 n 0000157365 00000 n 0000141906 00000 n 0000142918 00000 n 0000165308 00000 n 0000165339 00000 n 0000157531 00000 n 0000142939 00000 n 0000143804 00000 n 0000165372 00000 n 0000165403 00000 n 0000167830 00000 n 0000174180 00000 n 0000180017 00000 n 0000188000 00000 n 0000166887 00000 n 0000193086 00000 n trailer << /Size 439 /Root 1 0 R /Info 2 0 R /ID [<363D9870E727FF154F1C98DF2558E7FD><363D9870E727FF154F1C98DF2558E7FD>] >> startxref 194664 %%EOF dwarfutils-20200114/libdwarf/libdwarf_version.h000066400000000000000000000003341361531463500214420ustar00rootroot00000000000000/* This date string is hereby put into the public domain. Copyrighting this is crazy. It's just a date string and is modified from time to time. */ #define DW_VERSION_DATE_STR " 2020-01-14 10:13:32-08:00 " dwarfutils-20200114/libdwarf/libdwarfdefs.h000066400000000000000000000024441361531463500205430ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* libdwarfdefs.h */ #ifndef LIBDWARFDEFS_H #define LIBDWARFDEFS_H #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #define DWARF_HALF_SIZE 2 #endif /* LIBDWARFDEFS_H */ dwarfutils-20200114/libdwarf/malloc_check.c000066400000000000000000000226051361531463500205070ustar00rootroot00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* malloc_check.c For checking dealloc completeness. This code is as simple as possible and works ok for reasonable size allocation counts. It treats allocation as global, and so will not work very well if an application opens more than one Dwarf_Debug. */ #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include "config.h" #include "dwarf_incl.h" #include "malloc_check.h" #ifdef WANT_LIBBDWARF_MALLOC_CHECK /* To turn off printing every entry, just change the define to set PRINT_MALLOC_DETAILS 0. */ #define PRINT_MALLOC_DETAILS 0 #define MC_TYPE_UNKNOWN 0 #define MC_TYPE_ALLOC 1 #define MC_TYPE_DEALLOC 2 struct mc_data_s { struct mc_data_s *mc_prev; unsigned long mc_address; /* Assumes this is large enough to hold a pointer! */ long mc_alloc_number; /* Assigned in order by when record created. */ unsigned char mc_alloc_code; /* Allocation code, libdwarf. */ unsigned char mc_type; unsigned char mc_dealloc_noted; /* Used on an ALLOC node. */ unsigned char mc_dealloc_noted_count; /* Used on an ALLOC node. */ }; /* */ #define HASH_TABLE_SIZE 10501 static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE]; static long mc_data_list_size = 0; static char *alloc_type_name[MAX_DW_DLA + 1] = { "", "DW_DLA_STRING", "DW_DLA_LOC", "DW_DLA_LOCDESC", "DW_DLA_ELLIST", "DW_DLA_BOUNDS", "DW_DLA_BLOCK", "DW_DLA_DEBUG", "DW_DLA_DIE", "DW_DLA_LINE", "DW_DLA_ATTR", "DW_DLA_TYPE", "DW_DLA_SUBSCR", "DW_DLA_GLOBAL", "DW_DLA_ERROR", "DW_DLA_LIST", "DW_DLA_LINEBUF", "DW_DLA_ARANGE", "DW_DLA_ABBREV", "DW_DLA_FRAME_OP", "DW_DLA_CIE", "DW_DLA_FDE", "DW_DLA_LOC_BLOCK", "DW_DLA_FRAME_BLOCK", "DW_DLA_FUNC", "DW_DLA_TYPENAME", "DW_DLA_VAR", "DW_DLA_WEAK", "DW_DLA_ADDR", "DW_DLA_ABBREV_LIST", "DW_DLA_CHAIN", "DW_DLA_CU_CONTEXT", "DW_DLA_FRAME", "DW_DLA_GLOBAL_CONTEXT", "DW_DLA_FILE_ENTRY", "DW_DLA_LINE_CONTEXT", "DW_DLA_LOC_CHAIN", "DW_DLA_HASH_TABLE", "DW_DLA_FUNC_CONTEXT", "DW_DLA_TYPENAME_CONTEXT", "DW_DLA_VAR_CONTEXT", "DW_DLA_WEAK_CONTEXT", "DW_DLA_PUBTYPES_CONTEXT" /* Don't forget to expand this list if the list of codes expands. */ }; static unsigned hash_address(unsigned long addr) { unsigned long a = addr >> 2; return a % HASH_TABLE_SIZE; } #if PRINT_MALLOC_DETAILS static void print_alloc_dealloc_detail(unsigned long addr, int code, char *whichisit) { fprintf(stderr, "%s addr 0x%lx code %d (%s) entry %ld\n", whichisit, addr, code, alloc_type_name[code], mc_data_list_size); } #else #define print_alloc_dealloc_detail(a,b,c) /* nothing */ #endif /* Create a zeroed struct or die. */ static void * newone(void) { struct mc_data_s *newd = malloc(sizeof(struct mc_data_s)); if (newd == 0) { fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size); exit(1); } memset(newd, 0, sizeof(struct mc_data_s)); return newd; } /* Notify checker that get_alloc has allocated user data. */ void dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code) { struct mc_data_s *newd = newone(); unsigned long addr = (unsigned long) addr_in; struct mc_data_s **base = &mc_data_hash[hash_address(addr)]; print_alloc_dealloc_detail(addr, code, "alloc "); newd->mc_address = addr; newd->mc_alloc_code = code; newd->mc_type = MC_TYPE_ALLOC; newd->mc_alloc_number = mc_data_list_size; newd->mc_prev = *base; *base = newd; newd->mc_alloc_number = mc_data_list_size; mc_data_list_size += 1; } static void print_entry(char *msg, struct mc_data_s *data) { fprintf(stderr, "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n", msg, (long) data->mc_address, data->mc_alloc_code, alloc_type_name[data->mc_alloc_code], (data->mc_type == MC_TYPE_ALLOC) ? "alloc " : (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown", (unsigned) data->mc_dealloc_noted, (unsigned) data->mc_dealloc_noted_count); } /* newd is a 'dealloc'. */ static long balanced_by_alloc_p(struct mc_data_s *newd, long *addr_match_num, struct mc_data_s **addr_match, struct mc_data_s *base) { struct mc_data_s *cur = base; for (; cur; cur = cur->mc_prev) { if (cur->mc_address == newd->mc_address) { if (cur->mc_type == MC_TYPE_ALLOC) { if (cur->mc_alloc_code == newd->mc_alloc_code) { *addr_match = cur; *addr_match_num = cur->mc_alloc_number; return cur->mc_alloc_number; } else { /* code mismatch */ *addr_match = cur; *addr_match_num = cur->mc_alloc_number; return -1; } } else { /* Unbalanced new/del */ *addr_match = cur; *addr_match_num = cur->mc_alloc_number; return -1; } } } return -1; } /* A dealloc is to take place. Ensure it balances an alloc. */ void dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code) { struct mc_data_s *newd = newone(); long prev; long addr_match_num = -1; struct mc_data_s *addr_match = 0; unsigned long addr = (unsigned long) addr_in; struct mc_data_s **base = &mc_data_hash[hash_address(addr)]; print_alloc_dealloc_detail(addr, code, "dealloc "); newd->mc_address = (unsigned long) addr; newd->mc_alloc_code = code; newd->mc_type = MC_TYPE_DEALLOC; newd->mc_prev = *base; prev = balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base); if (prev < 0) { fprintf(stderr, "Unbalanced dealloc at index %ld\n", mc_data_list_size); print_entry("new", newd); fprintf(stderr, "addr-match_num? %ld\n", addr_match_num); if (addr_match) { print_entry("prev entry", addr_match); if (addr_match->mc_dealloc_noted > 1) { fprintf(stderr, "Above is Duplicate dealloc!\n"); } } abort(); exit(3); } addr_match->mc_dealloc_noted = 1; addr_match->mc_dealloc_noted_count += 1; if (addr_match->mc_dealloc_noted_count > 1) { fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num); print_entry("new dealloc entry", newd); print_entry("bad alloc entry", addr_match); } *base = newd; mc_data_list_size += 1; } /* Final check for leaks. */ void dwarf_malloc_check_complete(char *msg) { long i = 0; long total = mc_data_list_size; long hash_slots_used = 0; long max_chain_length = 0; fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total); for (; i < HASH_TABLE_SIZE; ++i) { struct mc_data_s *cur = mc_data_hash[i]; long cur_chain_length = 0; if (cur == 0) continue; ++hash_slots_used; for (; cur; cur = cur->mc_prev) { ++cur_chain_length; if (cur->mc_type == MC_TYPE_ALLOC) { if (cur->mc_dealloc_noted) { if (cur->mc_dealloc_noted > 1) { fprintf(stderr, " Duplicate dealloc! entry %ld\n", cur->mc_alloc_number); print_entry("duplicate dealloc", cur); } continue; } else { fprintf(stderr, "malloc no dealloc, entry %ld\n", cur->mc_alloc_number); print_entry("dangle", cur); } } else { /* mc_type is MC_TYPE_DEALLOC, already checked */ } } if (cur_chain_length > max_chain_length) { max_chain_length = cur_chain_length; } } fprintf(stderr, "mc hash table slots=%ld, " "used=%ld, maxchain=%ld\n", (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length); return; } #else extern void *libdwarf_an_unused_function_so_not_empty_c_file(void); #endif /* WANT_LIBBDWARF_MALLOC_CHECK */ dwarfutils-20200114/libdwarf/malloc_check.h000066400000000000000000000036561361531463500205210ustar00rootroot00000000000000/* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* malloc_check.h */ /* A simple libdwarf-aware malloc checker. define WANT_LIBBDWARF_MALLOC_CHECK and rebuild libdwarf do make a checking-for-alloc-mistakes libdwarf. NOT recommended for production use. When defined, also add malloc_check.c to the list of files in Makefile. */ #undef WANT_LIBBDWARF_MALLOC_CHECK /*#define WANT_LIBBDWARF_MALLOC_CHECK 1 */ #ifdef WANT_LIBBDWARF_MALLOC_CHECK void dwarf_malloc_check_alloc_data(void * addr,unsigned char code); void dwarf_malloc_check_dealloc_data(void * addr,unsigned char code); void dwarf_malloc_check_complete(char *wheremsg); /* called at exit of app */ #else /* !WANT_LIBBDWARF_MALLOC_CHECK */ #define dwarf_malloc_check_alloc_data(a,b) /* nothing */ #define dwarf_malloc_check_dealloc_data(a,b) /* nothing */ #define dwarf_malloc_check_complete(a) /* nothing */ #endif /* WANT_LIBBDWARF_MALLOC_CHECK */ dwarfutils-20200114/libdwarf/memcpy_swap.h000066400000000000000000000030131361531463500204240ustar00rootroot00000000000000/* Copyright (C) 2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef MEMCPY_SWAP_H #define MEMCPY_SWAP_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len); /* It's inconvenient to use memcpy directly as it uses size_t and that requires */ void _dwarf_memcpy_noswap_bytes(void *s1, const void *s2, unsigned long len); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* MEMCPY_SWAP_H */ dwarfutils-20200114/libdwarf/mips_extensions.mm000066400000000000000000001374571361531463500215350ustar00rootroot00000000000000\." \." the following line may be removed if the ff ligature works on your machine .lg 0 \." set up heading formats .ds HF 3 3 3 3 3 2 2 .ds HP +2 +2 +1 +0 +0 .nr Hs 5 .nr Hb 5 \." ============================================== \." Put current date in the following at each rev .ds vE rev 1.18, 31 March 2005 \." ============================================== \." ============================================== .ds | | .ds ~ ~ .ds ' ' .if t .ds Cw \&\f(CW .if n .ds Cw \fB .de Cf \" Place every other arg in Cw font, beginning with first .if \\n(.$=1 \&\*(Cw\\$1\fP .if \\n(.$=2 \&\*(Cw\\$1\fP\\$2 .if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP .if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4 .if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP .if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6 .if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP .if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8 .if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\ *(Cw .. .nr Cl 4 .SA 1 .TL MIPS Extensions to DWARF Version 2.0 .AF "" .AU "Silicon Graphics Computer Systems" .PF "'\*(vE'- \\\\nP -''" .AS 1 This document describes the MIPS/Silicon Graphics extensions to the "DWARF Information Format" (version 2.0.0 dated July 27, 1993). DWARF3 draft 8 (or draft 9) is out as of 2005, and is mentioned below where applicable. MIPS/IRIX compilers emit DWARF2 (with extensions). .P Rather than alter the base documents to describe the extensions we provide this separate document. .P The extensions documented here are subject to change. .P It also describes known bugs resulting in incorrect dwarf usage. .P \*(vE .AE .MT 4 .H 1 "INTRODUCTION" .P This document describes MIPS extensions to the DWARF debugging information format. The extensions documented here are subject to change at any time. .H 1 "64 BIT DWARF" .P The DWARF2 spec has no provision for 64 bit offsets. SGI-IRIX/MIPS Elf64 objects contain DWARF 2 with all offsets (and addresses) as 64bit values. This non-standard extension was adopted in 1992. Nothing in the dwarf itself identifies the dwarf as 64bit. This extension 64bit-offset dwarf cannot be mixed with 32bit-offset dwarf in a single object or executable, and SGI-IRIX/MIPS compilers and tools do not mix the sizes. .P In 2001 DWARF3 adopted a very different 64bit-offset format which can be mixed usefully with 32bit-offset DWARF2 or DWARF3. It is not very likely SGI-IRIX/MIPS compilers will switch to the now-standard DWARF3 64bit-offset scheme, but such a switch is theoretically possible and would be a good idea. .P SGI-IRIX/MIPS Elf32 objects contain DWARF2 with all offsets (and addresses) 32 bits. .H 1 "How much symbol information is emitted" The following standard DWARF V2 sections may be emitted: .AL .LI Section .debug_abbrev contains abbreviations supporting the .debug_info section. .LI Section .debug_info contains Debug Information Entries (DIEs). .LI Section .debug_frame contains stack frame descriptions. .LI Section .debug_line contains line number information. .LI Section .debug_aranges contains address range descriptions. .LI Section .debug_pubnames contains names of global functions and data. .P The following are MIPS extensions. Theses were created to allow debuggers to know names without having to look at the .debug_info section. .LI Section .debug_weaknames is a MIPS extension containing .debug_pubnames-like entries describing weak symbols. .LI Section .debug_funcnames is a MIPS extension containing .debug_pubnames-like entries describing file-static functions (C static functions). The gcc extension of nested subprograms (like Pascal) adds non-global non-static functions. These should be treated like static functions and gcc should add such to this section so that IRIX libexc(3C) will work correctly. Similarly, Ada functions which are non-global should be here too so that libexc(3C) can work. Putting it another way, every function (other than inline code) belongs either in .debug_pubnames or in .debug_funcnames or else libexc(3C) cannot find the function name. .LI Section .debug_varnames is a MIPS extension containing .debug_pubnames-like entries describing file-static data symbols (C static variables). .LI Section .debug_typenames is a MIPS extension containing .debug_pubnames-like entries describing file-level types. .P The following are not currently emitted. .LI Section .debug_macinfo Macro information is not currently emitted. .LI Section .debug_loc Location lists are not currently emitted. .LI Section .debug_str The string section is not currently emitted. .LE .H 2 "Overview of information emitted" We emit debug information in 3 flavors. We mention C here. The situation is essentially identical for f77, f90, and C++. .AL .LI "default C" We emit line information and DIEs for each subprogram. But no local symbols and no type information. Frame information is output. The DW_AT_producer string has the optimization level: for example "-O2". We put so much in the DW_AT_producer that the string is a significant user of space in .debug_info -- this is perhaps a poor use of space. When optimizing the IRIX CC/cc option -DEBUG:optimize_space eliminates such wasted space. Debuggers only currently use the lack of -g of DW_AT_producer as a hint as to how a 'step' command should be interpreted, and the rest of the string is not used for anything (unless a human looks at it for some reason), so if space-on-disk is an issue, it is quite appropriate to use -DEBUG:optimize_space and save disk space. Every function definition (not inline instances though) is mentioned in either .debug_pubnames or .debug_funcnames. This is crucial to allow libexc(3C) stack-traceback to work and show function names (for all languages). .LI "C with full symbols" All possible info is emitted. DW_AT_producer string has all options that might be of interest, which includes -D's, -U's, and the -g option. These options look like they came from the command line. We put so much in the DW_AT_producer that the string is a significant user of space in .debug_info. this is perhaps a poor use of space. Debuggers only currently use the -g of DW_AT_producer as a hint as to how a 'step' command should be interpreted, and the rest of the string is not used for anything (unless a human looks at it for some reason). Every function definition (not inline instances though) is mentioned in either .debug_pubnames or .debug_funcnames. This is crucial to allow libexc(3C) stack-traceback to work and show function names (for all languages). .LI "Assembler (-g, non -g are the same)" Frame information is output. No type information is emitted, but DIEs are prepared for globals. .LE .H 2 "Detecting 'full symbols' (-g)" The debugger depends on the existence of the DW_AT_producer string to determine if the compilation unit has full symbols or not. It looks for -g or -g[123] and accepts these as full symbols but an absent -g or a present -g0 is taken to mean that only basic symbols are defined and there are no local symbols and no type information. .P In various contexts the debugger will think the program is stripped or 'was not compiled with -g' unless the -g is in the DW_AT_producer string. .H 2 "DWARF and strip(1)" The DWARF section ".debug_frame" is marked SHF_MIPS_NOSTRIP and is not stripped by the strip(1) program. This is because the section is needed for doing stack back traces (essential for C++ and Ada exception handling). .P All .debug_* sections are marked with elf type SHT_MIPS_DWARF. Applications needing to access the various DWARF sections must use the section name to discriminate between them. .H 2 "Evaluating location expressions" When the debugger evaluates location expressions, it does so in 2 stages. In stage one it simply looks for the trivial location expressions and treats those as special cases. .P If the location expression is not trivial, it enters stage two. In this case it uses a stack to evaluate the expression. .P If the application is a 32-bit application, it does the operations on 32-bit values (address size values). Even though registers can be 64 bits in a 32-bit program all evaluations are done in 32-bit quantities, so an attempt to calculate a 32-bit quantity by taking the difference of 2 64-bit register values will not work. The notion is that the stack machine is, by the dwarf definition, working in address size units. .P These values are then expanded to 64-bit values (addresses or offsets). This extension does not involve sign-extension. .P If the application is a 64-bit application, then the stack values are all 64 bits and all operations are done on 64 bits. .H 3 "The fbreg location op" Compilers shipped with IRIX 6.0 and 6.1 do not emit the fbreg location expression and never emit the DW_AT_frame_base attribute that it depends on. However, this changes with release 6.2 and these are now emitted routinely. .H 1 "Frame Information" .H 2 "Initial Instructions" The DWARF V2 spec provides for "initial instructions" in each CIE (page 61, section 6.4.1). However, it does not say whether there are default values for each column (register). .P Rather than force every CIE to have a long list of bytes to initialize all 32 integer registers, we define that the default values of all registers (as returned by libdwarf in the frame interface) are 'same value'. This is a good choice for many non-register-windows implementations. .H 2 "Augmentation string in debug_frame" The augmentation string we use in shipped compilers (up thru irix6.2) is the empty string. IRIX6.2 and later has an augmentation string the empty string ("") or "z" or "mti v1" where the "v1" is a version number (version 1). .P We do not believe that "mti v1" was emitted as the augmentation string in any shipped compiler. .P .H 3 "CIE processing based on augmentation string:" If the augmentation string begins with 'z', then it is followed immediately by a unsigned_leb_128 number giving the code alignment factor. Next is a signed_leb_128 number giving the data alignment factor. Next is a unsigned byte giving the number of the return address register. Next is an unsigned_leb_128 number giving the length of the 'augmentation' fields (the length of augmentation bytes, not including the unsigned_leb_128 length itself). As of release 6.2, the length of the CIE augmentation fields is 0. What this means is that it is possible to add new augmentations, z1, z2, etc and yet an old consumer to understand the entire CIE as it can bypass the augmentation it does not understand because the length of the augmentation fields is present. Presuming of course that all augmentation fields are simply additional information, not some 'changing of the meaning of an existing field'. Currently there is no CIE data in the augmentation for things beginning with 'z'. .P If the augmentation string is "mti v1" or "" then it is followed immediately by a unsigned_leb_128 number giving the code alignment factor. Next is a signed_leb_128 number giving the data alignment factor. Next is a unsigned byte giving the number of the return address register. .P If the augmentation string is something else, then the code alignment factor is assumed to be 4 and the data alignment factor is assumed to be -1 and the return address register is assumed to be 31. Arbitrarily. The library (libdwarf) assumes it does not understand the rest of the CIE. .P .H 3 "FDE processing based on augmentation" If the CIE augmentation string for an fde begins with 'z' then the next FDE field after the address_range field is an unsigned_leb_128 number giving the length of the 'augmentation' fields, and those fields follow immediately. .H 4 "FDE augmentation fields" .P If the CIE augmentation string is "mti v1" or "" then the FDE is exactly as described in the Dwarf Document section 6.4.1. .P Else, if the CIE augmentation string begins with "z" then the next field after the FDE augmentation length field is a Dwarf_Sword size offset into exception tables. If the CIE augmentation string does not begin with "z" (and is neither "mti v1" nor "") the FDE augmentation fields are skipped (not understood). Note that libdwarf actually (as of MIPSpro7.3 and earlier) only tests that the initial character of the augmentation string is 'z', and ignores the rest of the string, if any. So in reality the test is for a _prefix_ of 'z'. .P If the CIE augmentation string neither starts with 'z' nor is "" nor is "mti v1" then libdwarf (incorrectly) assumes that the table defining instructions start next. Processing (in libdwarf) will be incorrect. .H 2 "Stack Pointer recovery from debug_frame" There is no identifiable means in DWARF2 to say that the stack register is recovered by any particular operation. A 'register rule' works if the caller's stack pointer was copied to another register. An 'offset(N)' rule works if the caller's stack pointer was stored on the stack. However if the stack pointer is some register value plus/minus some offset, there is no means to say this in an FDE. For MIPS/IRIX, the recovered stack pointer of the next frame up the stack (towards main()) is simply the CFA value of the current frame, and the CFA value is precisely a register (value of a register) or a register plus offset (value of a register plus offset). This is a software convention. .H 1 "egcs dwarf extensions (egcs-1.1.2 extensions)" This and following egcs sections describe the extensions currently shown in egcs dwarf2. Note that egcs has chosen to adopt tag and attribute naming as if their choices were standard dwarf, not as if they were extensions. However, they are properly numbered as extensions. .H 2 "DW_TAG_format_label 0x4101" For FORTRAN 77, Fortran 90. Details of use not defined in egcs source, so unclear if used. .H 2 "DW_TAG_function_template 0x4102" For C++. Details of use not defined in egcs source, so unclear if used. .H 2 "DW_TAG_class_template 0x4103" For C++. Details of use not defined in egcs source, so unclear if used. .H 2 "DW_AT_sf_names 0x2101" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_src_info 0x2102" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_mac_info 0x2103" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_src_coords 0x2104" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_body_begin 0x2105" Apparently only output in DWARF1, not DWARF2. .H 2 "DW_AT_body_end 0x2106" Apparently only output in DWARF1, not DWARF2. .H 1 "egcs .eh_frame (non-sgi) (egcs-1.1.2 extensions)" egcs-1.1.2 (and earlier egcs) emits by default a section named .eh_frame for ia32 (and possibly other platforms) which is nearly identical to .debug_frame in format and content. This section is used for helping handle C++ exceptions. .P Because after linking there are sometimes zero-ed out bytes at the end of the eh_frame section, the reader code in dwarf_frame.c considers a zero cie/fde length as an indication that it is the end of the section. .P .H 2 "CIE_id 0" The section is an ALLOCATED section in an executable, and is therefore mapped into memory at run time. The CIE_pointer (aka CIE_id, section 6.4.1 of the DWARF2 document) is the field that distinguishes a CIE from an FDE. The designers of the egcs .eh_frame section decided to make the CIE_id be 0 as the CIE_pointer definition is .in +2 the number of bytes from the CIE-pointer in the FDE back to the applicable CIE. .in -2 In a dwarf .debug_frame section, the CIE_pointer is the offset in .debug_frame of the CIE for this fde, and since an offset can be zero of some CIE, the CIE_id cannot be 0, but must be all 1 bits . Note that the dwarf2.0 spec does specify the value of CIE_id as 0xffffffff (see section 7.23 of v2.0.0), though earlier versions of this extensions document incorrectly said it was not specified in the dwarf document. .H 2 "augmentation eh" The augmentation string in each CIE is "eh" which, with its following NUL character, aligns the following word to a 32bit boundary. Following the augmentation string is a 32bit word with the address of the __EXCEPTION_TABLE__, part of the exception handling data for egcs. .H 2 "DW_CFA_GNU_window_save 0x2d" This is effectively a flag for architectures with register windows, and tells the unwinder code that it must look to a previous frame for the correct register window set. As of this writing, egcs gcc/frame.c indicates this is for SPARC register windows. .H 2 "DW_CFA_GNU_args_size 0x2e" DW_CFA_GNU_args_size has a single uleb128 argument which is the size, in bytes, of the function's stack at that point in the function. .H 2 "__EXCEPTION_TABLE__" A series of 3 32bit word entries by default: 0 word: low pc address 1 word: high pc address 2 word: pointer to exception handler code The end of the table is signaled by 2 words of -1 (not 3 words!). .H 1 "Interpretations of the DWARF V2 spec" .H 2 "template TAG spellings" The DWARF V2 spec spells two attributes in two ways. DW_TAG_template_type_param (listed in Figure 1, page 7) is spelled DW_TAG_template_type_parameter in the body of the document (section 3.3.7, page 28). We have adopted the spelling DW_TAG_template_type_param. .P DW_TAG_template_value_param (listed in Figure 1, page 7) is spelled DW_TAG_template_value_parameter in the body of the document (section 3.3.7, page 28). We have adopted the spelling DW_TAG_template_value_parameter. .P We recognize that the choices adopted are neither consistently the longer nor the shorter name. This inconsistency was an accident. .H 2 DW_FORM_ref_addr confusing Section 7.5.4, Attribute Encodings, describes DW_FORM_ref_addr. The description says the reference is the size of an address on the target architecture. This is surely a mistake, because on a 16bit-pointer-architecture it would mean that the reference could not exceed 16 bits, which makes only a limited amount of sense as the reference is from one part of the dwarf to another, and could (in theory) be *on the disk* and not limited to what fits in memory. Since MIPS is 32 bit pointers (at the smallest) the restriction is not a problem for MIPS/SGI. The 32bit pointer ABIs are limited to 32 bit section sizes anyway (as a result of implementation details). And the 64bit pointer ABIs currently have the same limit as a result of how the compilers and tools are built (this has not proven to be a limit in practice, so far). .P This has been clarified in the DWARF3 spec and the IRIX use of DW_FORM_ref_addr being an offset is correct. .H 2 "Section .debug_macinfo in a debugger" It seems quite difficult, in general, to tie specific text(code) addresses to points in the stream of macro information for a particular compilation unit. So it's been difficult to see how to design a consumer interface to libdwarf for macro information. .P The best (simple to implement, easy for a debugger user to understand) candidate seems to be that the debugger asks for macros of a given name in a compilation unit, and the debugger responds with *all* the macros of that name. .H 3 "only a single choice exists" If there is exactly one, that is usable in expressions, if the debugger is able to evaluate such. .H 3 "multiple macros with same name". If there are multiple macros with the same name in a compilation unit, the debugger (and the debugger user and the application programmer) have a problem: confusion is quite possible. If the macros are simple the debugger user can simply substitute by hand in an expression. If the macros are complicated hand substitution will be impractical, and the debugger will have to identify the choices and let the debugger user choose an interpretation. .H 2 "Section 6.1.2 Lookup by address problem" Each entry is a beginning-address followed by a length. And the distinguished entry 0,0 is used to denote the end of a range of entries. .P This means that one must be careful not to emit a zero length, as in a .o (object file) the beginning address of a normal entry might be 0 (it is a section offset after all), and the resulting 0,0 would be taken as end-of-range, not as a valid entry. A dwarf dumper would have trouble with such data in an object file. .P In an a.out or shared object (dynamic shared object, DSO) no text will be at address zero so in such this problem does not arise. .H 2 "Section 5.10 Subrange Type Entries problem" It is specified that DW_AT_upper_bound (and lower bound) must be signed entries if there is no object type info to specify the bound type (Sec 5.10, end of section). One cannot tell (with some dwarf constant types) what the signedness is from the form itself (like DW_FORM_data1), so it is necessary to determine the object and type according to the rules in 5.10 and then if all that fails, the type is signed. It's a bit complicated and earlier versions of mips_extensions incorrectly said signedness was not defined. .H 2 "Section 5.5.6 Class Template Instantiations problem" Lots of room for implementor to canonicalize template declarations. Ie various folks won't agree. This is not serious since a given compiler will be consistent with itself and debuggers will have to cope! .H 2 "Section 2.4.3.4 # 11. operator spelling" DW_OP_add should be DW_OP_plus (page 14) (this mistake just one place on the page). .H 2 "No clear specification of C++ static funcs" There is no clear way to tell if a C++ member function is a static member or a non-static member function. (dwarf2read.c in gdb 4.18, for example, has this observation) .H 2 "Misspelling of DW_AT_const_value" Twice in appendix 1, DW_AT_const_value is misspelled as DW_AT_constant_value. .H 2 "Mistake in Atribute Encodings" Section 7.5.4, "Attribute Encodings" has a brief discussion of "constant" which says there are 6 forms of constants. It is incorrect in that it fails to mention (or count) the block forms, which are clearly allowed by section 4.1 "Data Object Entries" (see entry number 9 in the numbered list, on constants). .H 2 "DW_OP_bregx" The description of DW_OP_bregx in 2.4.3.2 (Register Based Addressing) is slightly misleading, in that it lists the offset first. As section 7.7.1 (Location Expression) makes clear, in the encoding the register number comes first. .H 1 "MIPS attributes" .H 2 "DW_AT_MIPS_fde" This extension to Dwarf appears only on subprogram TAGs and has as its value the offset, in the .debug_frame section, of the fde which describes the frame of this function. It is an optimization of sorts to have this present. .H 2 "DW_CFA_MIPS_advance_loc8 0x1d" This obvious extension to dwarf line tables enables encoding of 8 byte advance_loc values (for cases when such must be relocatable, and thus must be full length). Applicable only to 64-bit objects. .H 2 "DW_TAG_MIPS_loop 0x4081" For future use. Not currently emitted. Places to be emitted and attributes that this might own not finalized. .H 2 "DW_AT_MIPS_loop_begin 0x2002" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_tail_loop_begin 0x2003" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_epilog_begin 0x2004" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_loop_unroll_factor 0x2005" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_software_pipeline_depth 0x2006" For future use. Not currently emitted. Attribute form and content not finalized. .H 2 "DW_AT_MIPS_linkage_name 0x2007" The rules for mangling C++ names are not part of the C++ standard and are different for different versions of C++. With this extension, the compiler emits both the DW_AT_name for things with mangled names (recall that DW_AT_name is NOT the mangled form) and also emits DW_AT_MIPS_linkage_name whose value is the mangled name. .P This makes looking for the mangled name in other linker information straightforward. It also is passed (by the debugger) to the libmangle routines to generate names to present to the debugger user. .H 2 "DW_AT_MIPS_stride 0x2008" F90 allows assumed shape arguments and pointers to describe non-contiguous memory. A (runtime) descriptor contains address, bounds and stride information - rank and element size is known during compilation. The extent in each dimension is given by the bounds in a DW_TAG_subrange_type, but the stride cannot be represented in conventional dwarf. DW_AT_MIPS_stride was added as an attribute of a DW_TAG_subrange_type to describe the location of the stride. Used in the MIPSpro 7.2 (7.2.1 etc) compilers. .P If the stride is constant (ie: can be inferred from the type in the usual manner) DW_AT_MIPS_stride is absent. .P If DW_AT_MIPS_stride is present, the attribute contains a reference to a DIE which describes the location holding the stride, and the DW_AT_stride_size field of DW_TAG_array_type is ignored if present. The value of the stride is the number of 4 byte words between elements along that axis. .P This applies to .nf a) Intrinsic types whose size is greater or equal to 4bytes ie: real*4,integer*8 complex etc, but not character types. b) Derived types (ie: structs) of any size, unless all components are of type character. .fi .H 2 "DW_AT_MIPS_abstract_name 0x2009" This attribute only appears in a DA_TAG_inlined_subroutine DIE. The value of this attribute is a string. When IPA inlines a routine and the abstract origin is in another compilation unit, there is a problem with putting in a reference, since the ordering and timing of the creation of references is unpredicatable with reference to the DIE and compilation unit the reference refers to. .P Since there may be NO ordering of the compilation units that allows a correct reference to be done without some kind of patching, and since even getting the information from one place to another is a problem, the compiler simply passes the problem on to the debugger. .P The debugger must match the DW_AT_MIPS_abstract_name in the concrete inlined instance DIE with the DW_AT_MIPS_abstract_name in the abstract inlined subroutine DIE. .P A dwarf-consumer-centric view of this and other inline issues could be expressed as follows: .nf If DW_TAG_subprogram If has DW_AT_inline is abstract instance root If has DW_AT_abstract_origin, is out-of-line instance of function (need abstract origin for some data) (abstract root in same CU (conceptually anywhere a ref can reach, but reaching outside of CU is a problem for ipa: see DW_AT_MIPS_abstract_name)) If has DW_AT_MIPS_abstract_name is abstract instance root( must have DW_AT_inline) and this name is used to match with the abstract root If DW_TAG_inline_subroutine Is concrete inlined subprogram instance. If has DW_AT_abstract_origin, it is a CU-local inline. If it has DW_AT_MIPS_abstract_name it is an inline whose abstract root is in another file (CU). .fi .H 2 "DW_AT_MIPS_clone_origin 0x200a" This attribute appears only in a cloned subroutine. The procedure is cloned from the same compilation unit. The value of this attribute is a reference to the original routine in this compilation unit. .P The 'original' routine means the routine which has all the original code. The cloned routines will always have been 'specialized' by IPA. A routine with DW_AT_MIPS_clone_origin will also have the DW_CC_nocall value of the DW_AT_calling_convention attribute. .H 2 "DW_AT_MIPS_has_inlines 0x200b" This attribute may appear in a DW_TAG_subprogram DIE. If present and it has the value True, then the subprogram has inlined functions somewhere in the body. .P By default, at startup, the debugger may not look for inlined functions in scopes inside the outer function. .P This is a hint to the debugger to look for the inlined functions so the debugger can set breakpoints on these in case the user requests 'stop in foo' and foo is inlined. .H 2 "DW_AT_MIPS_stride_byte 0x200c" Created for f90 pointer and assumed shape arrays. Used in the MIPSpro 7.2 (7.2.1 etc) compilers. A variant of DW_AT_MIPS_stride. This stride is interpreted as a byte count. Used for integer*1 and character arrays and arrays of derived type whose components are all character. .H 2 "DW_AT_MIPS_stride_elem 0x200d" Created for f90 pointer and assumed shape arrays. Used in the MIPSpro 7.2 (7.2.1 etc) compilers. A variant of DW_AT_MIPS_stride. This stride is interpreted as a byte-pair (2 byte) count. Used for integer*2 arrays. .H 2 "DW_AT_MIPS_ptr_dopetype 0x200e" See following. .H 2 "DW_AT_MIPS_allocatable_dopetype 0x200f" See following. .H 2 "DW_AT_MIPS_assumed_shape_dopetype 0x2010" DW_AT_MIPS_assumed_shape_dopetype, DW_AT_MIPS_allocatable_dopetype, and DW_AT_MIPS_ptr_dopetype have an attribute value which is a reference to a Fortran 90 Dope Vector. These attributes are introduced in MIPSpro7.3. They only apply to f90 arrays (where they are needed to describe arrays never properly described before in debug information). C, C++, f77, and most f90 arrays continue to be described in standard dwarf. .P The distinction between these three attributes is the f90 syntax distinction: keywords 'pointer' and 'allocatable' with the absence of these keywords on an assumed shape array being the third case. .P A "Dope Vector" is a struct (C struct) which describes a dynamically-allocatable array. In objects with full debugging the C struct will be in the dwarf information (of the f90 object, represented like C). A debugger will use the link to find the main struct DopeVector and will use that information to decode the dope vector. At the outer allocatable/assumed-shape/pointer the DW_AT_location points at the dope vector (so debugger calculations use that as a base). .H 2 "Overview of debugger use of dope vectors" Fundamentally, we build two distinct representations of the arrays and pointers. One, in dwarf, represents the statically-representable information (the types and variable/type-names, without type size information). The other, using dope vectors in memory, represents the run-time data of sizes. A debugger must process the two representations in parallel (and merge them) to deal with user expressions in a debugger. .H 2 "Example f90 code for use in explanation" [Note We want dwarf output with *exactly* this little (arbitrary) example. Not yet available. end Note] Consider the following code. .nf type array_ptr real :: myvar real, dimension (:), pointer :: ap end type array_ptr type (array_ptr), allocatable, dimension (:) :: arrays allocate (arrays(20)) do i = 1,20 allocate (arrays(i)%ap(i)) end do .fi arrays is an allocatable array (1 dimension) whose size is not known at compile time (it has a Dope Vector). At run time, the allocate statement creats 20 array_ptr dope vectors and marks the base arrays dopevector as allocated. The myvar variable is just there to add complexity to the example :-) .nf In the loop, arrays(1)%ap(1) is allocated as a single element array of reals. In the loop, arrays(2)%ap(2) is allocated as an array of two reals. ... In the loop, arrays(20)%ap(20) is allocated as an array of twenty reals. .fi .H 2 "the problem with standard dwarf and this example" .sp In dwarf, there is no way to find the array bounds of arrays(3)%ap, for example, (which are 1:3 in f90 syntax) since any location expression in an ap array lower bound attribute cannot involve the 3 (the 3 is known at debug time and does not appear in the running binary, so no way for the location expression to get to it). And of course the 3 must actually index across the array of dope vectors in 'arrays' in our implementation, but that is less of a problem than the problem with the '3'. .sp Plus dwarf has no way to find the 'allocated' flag in the dope vector (so the debugger can know when the allocate is done for a particular arrays(j)%ap). .sp Consequently, the calculation of array bounds and indices for these dynamically created f90 arrays is now pushed of into the debugger, which must know the field names and usages of the dope vector C structure and use the field offsets etc to find data arrays. C, C++, f77, and most f90 arrays continue to be described in standard dwarf. At the outer allocatable/assumed-shape/pointer the DW_AT_location points at the dope vector (so debugger calculations use that as a base). .P It would have been nice to design a dwarf extension to handle the above problems, but the methods considered to date were not any more consistent with standard dwarf than this dope vector centric approach: essentially just as much work in the debugger appeared necessary either way. A better (more dwarf-ish) design would be welcome information. .H 2 "A simplified sketch of the dwarf information" [Note: Needs to be written. end Note] .H 2 "A simplified sketch of the dope vector information" [Note: This one is simplified. Details left out that should be here. Amplify. end Note] This is an overly simplified version of a dope vector, presented as an initial hint. Full details presented later. .nf struct simplified{ void *base; // pointer to the data this describes long el_len; int assoc:1 int ptr_alloc:1 int num_dims:3; struct dims_s { long lb; long ext; long str_m; } dims[7]; }; .fi Only 'num_dims' elements of dims[] are actually used. .H 2 "The dwarf information" Here is dwarf information from the compiler for the example above, as printed by dwarfdump(1) .nf [Note: The following may not be the test. Having field names with '.' in the name is not such a good idea, as it conflicts with the use of '.' in dbx extended naming. Something else, like _$, would be much easier to work with in dbx (customers won't care about this, for the most part, but folks working on dbx will, and in those rare circumstances when a customer cares, the '.' will be a real problem in dbx.). Note that to print something about .base., in dbx one would have to do whatis `.base.` where that is the grave accent, or back-quote I am using. With extended naming one do whatis `.dope.`.`.base.` which is hard to type and hard to read. end Note] <2>< 388> DW_TAG_array_type DW_AT_name .base. DW_AT_type <815> DW_AT_declaration yes(1) <3>< 401> DW_TAG_subrange_type DW_AT_lower_bound 0 DW_AT_upper_bound 0 <2>< 405> DW_TAG_pointer_type DW_AT_type <388> DW_AT_byte_size 4 DW_AT_address_class 0 <2>< 412> DW_TAG_structure_type DW_AT_name .flds. DW_AT_byte_size 28 <3>< 421> DW_TAG_member DW_AT_name el_len DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 0 <3>< 436> DW_TAG_member DW_AT_name assoc DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 0 DW_AT_bit_size 1 DW_AT_data_member_location DW_OP_consts 4 <3>< 453> DW_TAG_member DW_AT_name ptr_alloc DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 1 DW_AT_bit_size 1 DW_AT_data_member_location DW_OP_consts 4 <3>< 474> DW_TAG_member DW_AT_name p_or_a DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 2 DW_AT_bit_size 2 DW_AT_data_member_location DW_OP_consts 4 <3>< 492> DW_TAG_member DW_AT_name a_contig DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 4 DW_AT_bit_size 1 DW_AT_data_member_location DW_OP_consts 4 <3>< 532> DW_TAG_member DW_AT_name num_dims DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 29 DW_AT_bit_size 3 DW_AT_data_member_location DW_OP_consts 8 <3>< 572> DW_TAG_member DW_AT_name type_code DW_AT_type <841> DW_AT_byte_size 0 DW_AT_bit_offset 0 DW_AT_bit_size 32 DW_AT_data_member_location DW_OP_consts 16 <3>< 593> DW_TAG_member DW_AT_name orig_base DW_AT_type <841> DW_AT_data_member_location DW_OP_consts 20 <3>< 611> DW_TAG_member DW_AT_name orig_size DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 24 <2>< 630> DW_TAG_structure_type DW_AT_name .dope_bnd. DW_AT_byte_size 12 <3>< 643> DW_TAG_member DW_AT_name lb DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 0 <3>< 654> DW_TAG_member DW_AT_name ext DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 4 <3>< 666> DW_TAG_member DW_AT_name str_m DW_AT_type <815> DW_AT_data_member_location DW_OP_consts 8 <2>< 681> DW_TAG_array_type DW_AT_name .dims. DW_AT_type <630> DW_AT_declaration yes(1) <3>< 694> DW_TAG_subrange_type DW_AT_lower_bound 0 DW_AT_upper_bound 0 <2>< 698> DW_TAG_structure_type DW_AT_name .dope. DW_AT_byte_size 44 <3>< 707> DW_TAG_member DW_AT_name base DW_AT_type <405> DW_AT_data_member_location DW_OP_consts 0 <3>< 720> DW_TAG_member DW_AT_name .flds DW_AT_type <412> DW_AT_data_member_location DW_OP_consts 4 <3>< 734> DW_TAG_member DW_AT_name .dims. DW_AT_type <681> DW_AT_data_member_location DW_OP_consts 32 <2>< 750> DW_TAG_variable DW_AT_type <815> DW_AT_location DW_OP_fbreg -32 DW_AT_artificial yes(1) <2>< 759> DW_TAG_variable DW_AT_type <815> DW_AT_location DW_OP_fbreg -28 DW_AT_artificial yes(1) <2>< 768> DW_TAG_variable DW_AT_type <815> DW_AT_location DW_OP_fbreg -24 DW_AT_artificial yes(1) <2>< 777> DW_TAG_array_type DW_AT_type <815> DW_AT_declaration yes(1) <3>< 783> DW_TAG_subrange_type DW_AT_lower_bound <750> DW_AT_count <759> DW_AT_MIPS_stride <768> <2>< 797> DW_TAG_variable DW_AT_decl_file 1 DW_AT_decl_line 1 DW_AT_name ARRAY DW_AT_type <698> DW_AT_location DW_OP_fbreg -64 DW_OP_deref <1>< 815> DW_TAG_base_type DW_AT_name INTEGER_4 DW_AT_encoding DW_ATE_signed DW_AT_byte_size 4 <1>< 828> DW_TAG_base_type DW_AT_name INTEGER_8 DW_AT_encoding DW_ATE_signed DW_AT_byte_size 8 <1>< 841> DW_TAG_base_type DW_AT_name INTEGER*4 DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 4 <1>< 854> DW_TAG_base_type DW_AT_name INTEGER*8 DW_AT_encoding DW_ATE_unsigned DW_AT_byte_size 8 .fi .H 2 "The dope vector structure details" A dope vector is the following C struct, "dopevec.h". Not all the fields are of use to a debugger. It may be that not all fields will show up in the f90 dwarf (since not all are of interest to debuggers). .nf [Note: Need details on the use of each field. And need to know which are really 32 bits and which are 32 or 64. end Note] The following struct is a representation of all the dope vector fields. It suppresses irrelevant detail and may not exactly match the layout in memory (a debugger must examine the dwarf to find the fields, not compile this structure into the debugger!). .nf struct .dope. { void *base; // pointer to data struct .flds. { long el_len; // length of element in bytes? unsigned int assoc:1; //means? unsigned int ptr_alloc:1; //means? unsigned int p_or_a:2; //means? unsigned int a_contig:1; // means? unsigned int num_dims: 3; // 0 thru 7 unsigned int type_code:32; //values? unsigned int orig_base; //void *? means? long orig_size; // means? } .flds; struct .dope_bnd. { long lb ; // lower bound long ext ; // means? long str_m; // means? } .dims[7]; } .fi .H 2 "DW_AT_MIPS_assumed_size 0x2011" This flag was invented to deal with f90 arrays. For example: .nf pointer (rptr, axx(1)) pointer (iptr, ita(*)) rptr = malloc (100*8) iptr = malloc (100*4) .fi This flag attribute has the value 'yes' (true, on) if and only if the size is unbounded, as iptr is. Both may show an explicit upper bound of 1 in the dwarf, but this flag notifies the debugger that there is explicitly no user-provided size. So if a user asks for a printout of the rptr allocated array, the default will be of a single entry (as there is a user slice bound in the source). In contrast, there is no explicit upper bound on the iptr (ita) array so the default slice will use the current bound (a value calculated from the malloc size, see the dope vector). Given explicit requests, more of rptr(axx) can me shown than the default. .H 1 "Line information and Source Position" DWARF does not define the meaning of the term 'source statement'. Nor does it define any way to find the first user-written executable code in a function. .P It does define that a source statement has a file name, a line number, and a column position (see Sec 6.2, Line Number Information of the Dwarf Version 2 document). We will call those 3 source coordinates a 'source position' in this document. We'll try not to accidentally call the source position a 'line number' since that is ambiguous as to what it means. .H 2 "Definition of Statement" .P A function prolog is a statement. .P A C, C++, Pascal, or Fortran statement is a statement. .P Each initialized local variable in C,C++ is a statement in that its initialization generates a source position. This means that x =3, y=4; is two statements. .P For C, C++: The 3 parts a,b,c in for(a;b;c) {d;} are individual statements. The condition portion of a while() and do {} while() is a statement. (of course d; can be any number of statements) .P For Fortran, the controlling expression of a DO loop is a statement. Is a 'continue' statement in Fortran a DWARF statement? .P Each function return, whether user coded or generated by the compiler, is a statement. This is so one can step over (in a debugger) the final user-coded statement (exclusive of the return statement if any) in a function wile not leaving the function scope. .P .H 2 "Finding The First User Code in a Function" .nf Consider: int func(int a) { /* source position 1 */ float b = a; /* source position 2 */ int x; x = b + 2; /* source position 3 */ } /* source position 4 */ .fi .P The DIE for a function gives the address range of the function, including function prolog(s) and epilog(s) .P Since there is no scope block for the outer user scope of a function (and thus no beginning address range for the outer user scope: the DWARF committee explicitly rejected the idea of having a user scope block) it is necessary to use the source position information to find the first user-executable statement. .P This means that the user code for a function must be presumed to begin at the code location of the second source position in the function address range. .P If a function has exactly one source position, the function presumably consists solely of a return. .P If a function has exactly two source positions, the function may consist of a function prolog and a return or a single user statement and a return (there may be no prolog code needed in a leaf function). In this case, there is no way to be sure which is the first source position of user code, so the rule is to presume that the first address is user code. .P If a function consists of 3 or more source positions, one should assume that the first source position is function prolog and the second is the first user executable code. .H 2 "Using debug_frame Information to find first user statement" In addition to the line information, the debug_frame information can be useful in determining the first user source line. .P Given that a function has more than 1 source position, Find the code location of the second source position, then examine the debug_frame information to determine if the Canonical Frame Address (cfa) is updated before the second source position code location. If the cfa is updated, then one can be pretty sure that the code for the first source position is function prolog code. .P Similarly, if the cfa is restored in the code for a source position, the source position is likely to represent a function exit block. .H 2 "Debugger Use Of Source Position" Command line debuggers, such as dbx and gdb, will ordinarily want to consider multiple statements on one line to be a single statement: doing otherwise is distressing to users since it causes a 'step' command to appear to have no effect. .P An exception for command line debuggers is in determining the first user statement: as detailed above, there one wants to consider the full source position and will want to consider the function return a separate statement. It is difficult to make the function return a separate statement 'step' reliably however if a function is coded all on one line or if the last line of user code before the return is on the same line as the return. .P A graphical debugger has none of these problems if it simply highlights the portion of the line being executed. In that case, stepping will appear natural even stepping within a line. .H 1 "Known Bugs" Up through at least MIPSpro7.2.1 the compiler has been emitting form DW_FORM_DATA1,2, or 4 for DW_AT_const_value in DW_TAG_enumerator. And dwarfdump and debuggers have read this with dwarf_formudata() or form_sdata() and gotten some values incorrect. For example, a value of 128 was printed by debuggers as a negative value. Since dwarfdump and the compilers were not written to use the value the same way, their output differed. For negative enumerator values the compiler has been emitting 32bit values in a DW_FORM_DATA4. The compiler should probably be emitting a DW_FORM_sdata for enumerator values. And consumers of enumerator values should then call form_sdata(). However, right now, debuggers should call form_udata() and only if it fails, call form_sdata(). Anything else will break backward compatibility with the objects produced earlier. .SK .S .TC 1 1 4 .CS dwarfutils-20200114/libdwarf/mips_extensions.pdf000066400000000000000000001610661361531463500216660ustar00rootroot00000000000000%PDF-1.2 %쏢 5 0 obj <> stream xXrF}W[`Sɲ2 ?ڂ4-9v/ãDzTdS݅@NQJ(fĮCOU[j fV;0ۺ JvEDOtU)VЈse$* P‡KGy%vپ%"hXME$Wp5Zu3J5adCԴM"ﶡP䓜iənm{D <SMjm;Bd(Sh.4xKw{rJ̨Lyτ̻)V𵅲)wJPQ }! j%XMŃb*;r4bC's++i.?82T3FRˍl"\t%Mq6$'=V٠7M& ;dTvdɷbMe&+̓cYr X[/r#^_ rT=dK_*+} N,kC j4/׆uU$ :=mmU6Q b߷ &syHf$&rn'QƉg3rtH3SI/|( ȗ:}0\ 5b*9]f羉L}l.|g]/qwgoV%_8n`£ݑ}n&m>D-P$h.޴;{"U3zR*: lM^hp^ !dendstream endobj 6 0 obj 1771 endobj 12 0 obj <> stream xYrܸ}WTV IŲnc+TY)Łfq1ɑVˌd\`_Nw їYnO" O喽8l5(gհi2jk(R!@BNH~ 궽ea|컱QWUsӲޔ N0†xXgwKsoI1#SDj_{S6ցg"f"<d1ce EՐ(zjúĔ':dO` Il \Vqs s+ӗ]uM6^uOab,x*wCuoʧ߉__*x$g \i@fD,8$ģTdrSQ3ӄP Uog9;򔟆:&(c.KF"F!5z׻]wŖtxr㌀jL/gK3=% d*V5mljXZb= ^kO@d"yXڄ:iģ2JȤcdfes"TNDd(k =I|_ڜ"!eGy痧fDmw:KC.<>.\̰W۪.:ֽ q492Y%X 7UqѓHؓ{& m'f/Q9i0BB ;ܱj@ZpvitLh=ŃK_+9(}OXѢEu.2":qfUM]5kSͺg'fn8Q-9LJԇG3~uT|0mnV!˩MgZ[~LZ|5IN6޹\e3}k=ec>Q['#>S~Sֻ([\);:U1c'\2ݩQn̸l{8$qO<#M=IOH9jX7`sfՀf5X>/@r:.mQڑZFv–q?:yXu[_骫~_ Q$]KjAVԛvHX=FXJL@{uGL{b%{1I/u/ N3_ljZ7,f7u1ꖎ$Wj,vѾifވkW#XfMTJ<61dɹD',qО]ZѯQDI37m%71M7ytfGSE٫1z`FFM<4QPl_,z}o=0yUaih2TJ!л_I58^Is{&91 %x*l޹A~ rl, %f_mcB0]k6J!Ɠ<x cK#(b/)D- +_m]~@*`2ҀBltF)u88_ѱs0}n*7ѤjqrŃH=9?Hl> stream xX]s6}ׯTk}6mh'vCSĵD2$\|vI'qιb.XLg}\->-yG}d_/$Oٺ^|>ۅ's˓hVa WL*)zyI|OBd*s3t87-ql5c&djsEGXNfMF7/"J{pc[C9z`44U8맦kG6&'B~IbC;64ps҃kv7ׇFluseNr^>w^F5[jz)pHXX"y^8%W6̺:jGд0Uԅw揚)y). O;v<3nhGûPÏ2_jevZ/]+i)]l%<^8U;W5A~ R^x7I N ,ˋ5Nad]{x6p_uit;i\[f!$_2tmؾ3rE'عP$8*hw$*Lb4$"mg a[j \E(VEG >ᯉ52vGmANB|nWT VzDRl9m̪|nZ>ƩjkM ԝv%uDQ1!sXpZjRynkpM޿;j,likpNuSPRg^HV]K0gO]Gq5 ~9Ni@4rq.Pc[Gh o[ȗ^D缽P/M]dpqݩ1 p"ċߎ>*7EҏhdiE5_Rwġw7ǁdTg8V;MiV ۯ/vz)m2 N]4KSɽBM7'F8Rrwh}bJ}%́ʥJ owI4E!-q?6W $ :*#Hj6ii%ݐN)$zj^%B$ԩAT~klQN+`a@!Ӭ2 $K_<.m&'tTVHAU׺Hshxm%LYC2zTv|p_7{2VDŽz\ XàRqUk[82PM&2G :p2 dմm]]"ǭ)%l ~6S -BDt'(^d94z *Q٤h;hlV>")\ Z!Wg50lS3BvW66[ouèbY!ė@օtDOMW()%@!-y}&CəbQgk3L0`+F%xctA]9OӀ=-(!fHˆ*D%;o"D?.HW5:KWWg7#SOrgeL\ ͫ̾`6t.`[톍$r6rcާ@4IT iV{IzyY GO\dw+K<4CD7szE2J:Jȁxop&dөB fU[9`@. Wc?t0֧!ze42F|Khҍm.3T_ U΀ğ%> stream xYk۸_AŘz4΢-Hlq_sIJg4hA0c"se~c!,{6 6{L6߿KvL& Ø%Z~,rv 'lS*f!WdCeaP/Y벿vu煌xDT^ex~n;%ESԋ~ Xg24 k|1s)HDvqZ=,)RZ7u ϒ4 ̎Uw9㦠-FDpmm2mǺp0;{x:Æau3G($8PDF!:sjL<2XZM@TE"Ot}GƺP,2E4K,NOo<=ž"E*B`]+ >=Po0SΝqw@E߷z!\i{cL]twH4*u}dRqfx_H@l2Z5O@)wzk*C\ V @\7$yfhr&ؗ΋X,΢{d񒐩CB3Zs3EhB[W|2voB-C]enE\2IO/cX#q[P{G@P( )@(3gwɺٰCX8 6-+07OOcpwHg qᢨjwExҠ#zsqy3".?ӓzZP TBA~zKE)MS5|n]<8y[~6hF+ 80 {}XQ5r-OM&%u2jP1g͖= >g47#Pg޴cz{vr#*QKJ\E b:q&Ev҇)X|OE_ǶF f]fvK0mzҺÈ9/"Y렣ua,\(Ȧ9G+mqaa+*j")@iM @yMHѡX z8-E! jcr4婬fCe]n GgzxN2K0V=hK .'"5=~͓vԱ=3̶GV'4d1\?=8YT}d&0Z;AjGgЀJO;j;L,ڌK-xflb$vвB9KO$F|g=;QX5G2.>U4q]g6y;V *́=Ad5pb.^4WV[F1f ,rGloe*_n(7swpT:5uK!aR!.r$IDڠ @V2$ѕk4(% cI ^ik"X{ k~R,7VUBXe#F%P_svDIۏY? zr ZwggRž>y_dS[RʩcOfm'n(m̟̥(Ѩ4BeÛ,/ DA+ÀbTXZ%ٕ LNf)z? >*EJ~ Tu4*SPM>{B(ჁPgD@+i¶J T› %SʳБӫj}g-52W<Y j7V]Lm7'{eS$ʜ@]T&rmHg:q!'CiܛFp#.<4ueH4̻[l(S~yd eta4SgxhgSo* uw<Р| +Ԗ C- MNY<ݍ&F0LG79iWaiIq$n L)t|S<{64Ƕ$_lfU5vL0ɥ%IwTϔrҿ5fV&à05s{]")c>`~=F)N b{l[8Sɢ5'21ۄYv3Ջ:L ͋0s͗}hד)_0gD^9:jUmnһ7w/vlo'.yKٿI|Ps.D}@*_'E<3Ug._B:jA6L67 D ơgqc H2Knb0KC~ZjEendstream endobj 21 0 obj 2582 endobj 24 0 obj <> stream xYkoܸ_A5X#Rԃ&n&M[ . gF4v_s4v]Q}{,忯g1vg o=)^3`2yg,W]Ϣe\\;V/e,gn["%z'ϹKbz9:t sEԮMW͎ݖٰaq7PU,}y˰Rv;^Hi|eÝa޾9yCGoێ n 5d($[mgٮjzP wm})"'їĂK139*w6 `KK/eQ>*ks!|LcLn7Yg[I%5|Q#ʍGHBfAGZ6 Q@-J GeWWm=;\5P5[ߕAhZ(Xه.:?\9tѪ`=@P5J^L}'q+4CZoi(׿y'j3PV9F$epb2* 0q}=g/= )')!!`fݎq莵`(UYӺ /s-OFxTDZR_4:%_ !EJb.4vv32a>f_%]1!ܮ"I"щllS(-8 .<*vd1'!"Os.8c|tKscs qsK s t W]BFajB$s3VZշ{NRAH4B ix"N] aؿWџfsixIay1 e^P8Id0gYHU"gKMaMix'dZ^_^4ۓzՌ6VR׳BؽifhGdiΎEDho.y("M@˪n}jyuRA9 Iynh7ת0!fQ(b$v Bo*t,{*XZWI/4 4n{Iv#Yr$"ԽKj6%m7% 9sItqA4:MkN| k,-8-٧H䩀o|.Cmg"δHHI93ugi"GtqKzbf< 2Ӓ;'h\'3'Aػ9ϋĤGEG8$ӵ_4^0Z];!(D=1LcdC'uqG-.ۢ7ҪƁ[H\15TXuv9A7ͦĀŋlgu*Sv7ruRۤ OqgL9P5(@}u;Q=mxס3 BGͅx:ѧsbYPsw eoA9x:41KYe r{+a~]]{2Dzkӗ?OJbeI~0尪[S Ā8f Tu6cNџNIq/߳> stream xXے۸}W-T< yekS\TOJEĘ-Iٞ|}N )+޲QHCݧOn4 \2A/^~iF;̿-~QEۏ}WfkJ I oJbFjxNDXߡ2&#+4q% Kg1%9Ê; -2x$_%'Dİd-2f6oDb Sw#D6̖ĜֶUgs*yI7V, fD+'Ŵ4ó=l֘0b-fbM9*bktH.8Jt6c?\j SNTBo s]Y=>h3^40٨Գ 3 zXW/}~' R s Hӓ lKݝ, 2u>ΰ Kd4h;d-0iBޔvqMݽyF~Ǿ5SMտЇ#>2*LL`@6#W#dY%2sV#iLwά U`5;\,H${}]7K |w \^ѻǷoq+``պnY*Jf?/tu* mґ{0amqlMϔ N?5FlĤg" 2.=.P2 O1HI14wX՗GmĹ̓6MZe^L#,849y%߼zJET*3֧5ַ(OG"sә 6JhoDgFy|3> stream xYkb/%y1qlc<\[؅(5%*$ey{ј+놌YCE۲̙S4 1%aБsv"בֹ V/u֭a, {M(e$1#ck'nyy:w.m -wUȥSlr}YQ ."T与\f4 Wt NN,2Mm#%łr$8 `C46OZejlYD*IߴGi2gǺ=!Kb_i:h-e !8&Ĺ^FA5D@!(< qq)Pqcq>qȌN> աGX~^|y$|i0kmŴ=U!s*ͩKfT; wm'*MgQ9dL]Cۍ B3aa }%M0ө1v;2瓨\d9 l)o'"GER>?7QuiTz ꁋa)=af?w{sM$ѳ݂sjTg}T2yJbn !w^`?V<|j^r2Ȧ7(RKEhy^NMO-ҐEgVN.hYq=(TK¥bLM0mLNP&Gm@<#3'*㦩מ/KIf9>r%A<º?|x'H\И39acj+4qcib?'Ps٫I٥HlׄODR|o.cqMe|c mnω;נ885ֺkĂy)^ڰ,}ߛ"}KJO*VtژOB*rȻqUtnz0QU,_3SYFMCGf.'åZܭ!L̀a;3FX;S4g0*WSWlǺ1¶mO\g$Pص ]}c gwJH('D>_h!!%uW 6GoY2;*:!iү'K7gCUX]m}xP[9넭GwWZF:S^u,\ܿq &R`(وTN4T`5G)SCiӲ6qF:e&ԟ=bg?=_ n9endstream endobj 33 0 obj 2853 endobj 36 0 obj <> stream xX]6|ׯ=J[SU$)כ_=wMLOO >X*9b/=>Gs߮ĶY}. ǹ(TlOhSn߰Vot\ȼ*ja0$iJ4U"x%/VIr?DrgתUUr;ՍmM_7"jkQWx [=U`?XU;^}ܨ"*MF1z1Q|Ɉݓ?Xj:!/eW;!LVqUN7v`:3퍘z'dʝ:Mmbz)@(=wmVI)a# 36dHtUVns>8'뤒IYM'Dz,SZ!4J6b2kB[vgnע3f?n'7xSMM\2 t-t2II=8Ro; _<[KЧx?B)\aL

pD G(uQ`K384hjK9z"*0a 0LYq:=jq>h*sd6. UQI]^uWF86qԯO[/ )~7.2w^EV"}Ń⇺m`]XLfEv仺u8*ER9YI(wߵH|: |ǥs^v92_8Yr "C3}ᗺGbnx{qs"IH {p4|))d!DV:dzv]^n M!wOA ?}C,_cVCEHpazV2d.fj ",ao.k`S82/9AU/rցtI skgyC}B!ŏӴK[rgC>GL2Ś=Bp!\y=` &tlN2D!KTZRpꙊњL!aF>)^=s\P.!^ =˜^L쯕*I9೥;Td[l[k ق:KdRTO0pܓ/k5}ꣵ@3J) Mg1~U7G G>ĉ,V3Zc; \m~u_ tDrY&es6_xZwl|;h.O>{O} ;FJ{Y32g`VPVTRH=5|$Iݬ!ځd[?'nn\g xB[50'FxvF0ǰN.Zc Pyۏ`nIi5p.= ]U_7EG~FnM,^%ðdgg@Euk}h;ɱF^?_,HFoܠrw9IU [\L:LRa(d$Pw5ZG~1ď1֗W&x]Ө,}f/k_AGjvv(U</߿U~a/Ӭj4fH3wCϮp] v/)9_HFXܻ ۮ1¼4z<%N]#]Lq:”ZK,oVk@s\G;&)*m.g8[/UJ UW?H>^92!2_Bj&B& EWZ6 :v2: ێc2 mۣG X9sh~4:6Mk4#u6,wְr3vV+iDmG⺐W_f̓~"ıVkc|=:x'ClnSa?ϳ[`H7Y |U5y4cg|B"A,;:H/,8d4D4K#h0zi+*Eg7ēЃ4W= WM;ߙw8w(y! ॣudL/|$o.d1HQyPurzم4/)M),@g`J&Y+DAC7ʦ$^WG"+fy)Uߠ/429qٕO/ 40otuۛrG7L{2L蛌oaoA}B>ɭJHPi5ػ4,\+WGendstream endobj 37 0 obj 2578 endobj 40 0 obj <> stream xXێ6}W;#Rm:I0L210 Ch[YrtK>HʷNݗ}X4vK$ԩS\~gng̈́yGg.gGlY̾ff &Ar?̟/$e8aJٲ{2? e"s?LTƳW~^k&”cKݧ<覯ڦ=@D vY`[̈́w|In2xf!6{/ '}䊇\ 6 Y{]>fKv_GHDCe{oU^ߵc]fw0i}zكw09g_.5R\9=h1 Jb6Ɔs~\P"Ky짖"Iq&g{EsNQm2DU̬ݰ޼ap{ 76p \;iY+OsD -VmXn~;c|2!9kn-q=x%n#;`Uö)Pv68TE^]3v #\ wiLNpg},(@48s;xyUzVsˢHzy=g+κ'.NdL)g&H}!ęm 6HBcYptc;_̛iA NA{[R <0t5ony&0t\6E[W$>6 2{jnn㩡lUzʪ/ƾw%s3qÞvUc}Blr振'2pL{ O4L"./$;]).6(USuc{D"WJj_X^׭gyORqr򤶽en!g?oohg֌t3vF ",H8rzF\(cx1 ROo_IqdB9J]ud> stream xXے۸}W-w9KMjQj4)EAf(Rs)j]yI}McK&Y}Ż+(N/[?aIG"fIi Vr"VX-N;S&\)qU_ ֗E}\k2Dp6ւ߷oÈGJ!}ke;s,k&>(!BڱBf/"^E!Ob+ڳk.1)x(2Chƍp,y 6tCۚ9}o|}[J`a=޳{|z** Ϋߴ %3'pm,^Yą iۡnRI)fSUC^M됋^CNF8t_E0.-ĖD@%ZJ'aƳ48nk\n:҇ ~]?/t+9*?moV::!1\ u͡7y&cdl6۽9U Cͥ oկn"RӹY'qx%U\G.aP2a>#W_1:c90y۳zlծGyӇ%;89>&4P<2i-J*l9z\ͽB"ALHRT :ˎ``cٔ5%cn04K~QcOemcYX!1Nxg)0'<)wb4W*I^~J(Q~4\sp1|Մ|PIKGn5 6o|,cO}>+Ofi87j`'U$G}c)ZJH@hOqq C$iW$hc'eeU9W+=orhגnCcuZVq!ܹK"dk*1:﯆"Mg 'ѻF4(JOFA 3Q5u>(5h7 o)Pbs0Go2h pꣻXijPNsqfAg.Hv~ l#+1S3 ^pR!? 1N]lTpÆKWbd?:Ga W0O>(Gj2|gM A3M9=.$`2Dla õf되c^)Yv,w$Dq;]E'(؀RMy'DBygc$z8ХsON@nBswKwSUe\[93I)?Ҏ 6!IB:Ca޹ynjF`h@z? n3Bt($|zQgmH&2&* J8\ꮘbd y}m)6/_l'h-R<@P!ggxsV-<=}H߹/jȮ(5^߈ʾ4#u!N `sn',x]^Hw z1o,wpdξ]/~ş^eN@endstream endobj 45 0 obj 2073 endobj 48 0 obj <> stream xXo~_EĊ~[=Rܵמ,ӎZ[Ir_)vnw[^|B!YT8LXElq-y *E?U3cR@) bf<㙐}/9ӱPa8?EtFun,V??Xw}[._Tet5HBjP*F Kx:V}[*ް޿x4E۱fxAH8\zX-~)|_~l2r𒯪z_fN9}|Ã8W"4bث;I Ĵbp2w tD"[iZ>=b {$C%Ɓ'0z.ִ[V6c/٩{:mޛ;W6ʄNt:8n>z8pGҚ-lKsϺ > M1>T̠,wCy.SOi1)4VYًz-zv8u=,FqJgs<+$ 萮gxHMKZB |"Ib>̥ˢ:2wZ`1TW+ai$;btO(N {/q΃Ԡ%{@8n=7TÔo6*-4]XZdqQlN fKG/& +:m0WKJ4J O[ Z*TDŎc@b$ Յp '?˖pC<Ӌuj0#1C*Ghx4ۀpfšDrЗ.m? rW ĀYAڀF?1F S$hD}0_̱?ZBwQ3 ,hAI QȚ3b͖E Z/[i,揄Ȫd,SvNY3᫢hmJ> bTB&KwngNR\ 3j.) y%7|N0bLpzc\J[GfDOݭN9@+Ë oTο[u(L"W)i߬vJM04趤-HIdgg " 79*[6ʃ&uytthth |B㻗W9F )=Ӓ\bpeplzxn_ endstream endobj 49 0 obj 2039 endobj 52 0 obj <> stream xXrF}WLE`B13ͱ7[TnL o p("&ܯsAvڗ-$Js>}tϼc,/D~yw#s=fu#yV͋3jsc &'Qʲ8f]L")p?+V2JXlƼoNl7 ")r KVnK6l5f<,$f8Gݱ}ybM;]۾ecufmzU{ԎVI&"VY}y(( k!yUEM~8XmN̜Q3X(UU^PfK9wj[➕l[7 D&诖Ʃ[ZFCcz64w@ф 8ؠFc"Il=䛶ee3"g*7Ҝ ,@3f7*2ʥ,%A%HNYq8 Eϔd0d< +x>XoSD̀=myЬEuk`ȆCײK&Od7 VC]oݎCBdRBO% T)@"2$2 - XLfdO2xgD3[<.S4@s4U- U;674Oq r Af&*&TJ"2Mj[veeaQZwP J)xS4&l!72+w >n^ȵ(;Dc9zpP$)#$4LNl|"N-ǔC~ʭQaPק CYwpZǞej|pB"2`2)ᾡD3E0~27 e'),Ekؾ۵(Ǻymg&mH*all?Fqˍ{V[]6=W? Kʕ( w=\1rŒ*s6DA&ç^y .x%޶$+3 cT_yDs9+PbKj,PEj^}Ւm$۷0_J|W_P7܃FݚCVvܴ<]g@=|c3cᨵkn82n/'C= T _d<|c;g8H!@]|3ezSˇޤ-Z핍 &R$Z$ rc 5E  338/8!xzV 2w $ٺ "i:3읭 T'z$klbkCc _Y|׭ui1ttȦU9/8.NdOR,l zv's괳oH Jnl¡#$r.inK>=,rSzٔ+OT^uvDf}~J~&0s ==涛cVgYƹ-kCT7S@hddmļy1qɔ`ߗ+.l='|Iendstream endobj 53 0 obj 2348 endobj 56 0 obj <> stream xXMoW%05+q4dvd=؋--P,+>I3"CvWUWz_EJїW+=$c٭T~׌Wv*$JEbw\[VIFZz}3bVEI(3sNEQm J,."idxy(s8Q U2vvGzPI,52w[Pz[q*iL#kEq0MiTC]'@x욦 .uuph9'#ʾ/NcOo-{-- Ӥjr>ONʞoetlb#h;_oĩ!ފg[4oS1AM%tZۗ#%gzVN{~{$:Q? Qu"l*O ;He"fYS؈GQ.-81Fe*UR+2o;#p<հ9L֣8p(~3cpjN܏:̥x/BW݇Q疭n{Sz?5\ 7S}fN#7:?X l\^o ,KaQ11 vR X\+y)UIozS:}"n@ [K;mǙt8e[O!Mck`= Vus];;Ү]?{3II'aAX+C"̃S4%f"N0N9MCv mUhw!ǎqͬAvh]X8x4akM/ܫ8 J#k5НjiNS«(.7ˡRVӨcڎ (S Uq\8]2?>JD6Yٰb900L A}֭ Ń8X)Sx6N%)a%nsi;G527gmFg )'h:FCNѨI)%ga,їԶ-@-#b+>43 H ZQeAwN!Ed '6|Uy DqUE$gưil!"w~` G!h+[ٮ VWieUH."ϼaXt,)i7u7;Bq ڄ(Sb3?HIآLFXafM 24@$s4.31xl'E9 ` 5+ Q%'!,d;$^Liӗke8F|kk%]znuZ-[Ar|=  `/ܶTǹD g4{jTI{4>Y]X,h0`T%Kj}..XeNAXԖ#H崼n*ӞTdl`C!g`Z {:ܥ7 hq>f 79P6H˸4LY>T2IN||Uh5- 7ma8K^U5~JY$ܕt (0i|܈?ye;cȱ̪FY,W!D/BTU-xJl;6`q'y_hp(O潿Y~}&^>Mc7P 5K5q#_g9,Z=h͓p_/endstream endobj 57 0 obj 2133 endobj 60 0 obj <> stream xWnF}6wOmv$C!{4y9#S}!G݇6dUN*".XDϺDu#~=jy=7`q,YloPl,Qi}Vq3i 'ŚVdXwL" >jOOrh: B1y_㉓gɟi7 |k`COv]o5#=xoy8@o<zOw{=g/f(`h8*ⷓ{iF]~e+8NR3r[,LGKKmy8tvޙ?\YjWW {`LM^Ԛ8,XӔ6|uW'ٲx81\)ITAg2܂$|1kKҳ=\4UAJ۝ㆿ Eimq *6\I&s(V<]#"v DZaئ4i9vm=;(L`t0,oE RAߞ-&p@)5{$(a $7iFk 7+ a妹e ]S%TLQ'\k;ZqjǺ"ϺzX;L*Y]~{t<)[eBTի@CDYL55kle8ܼMwUǎǭYdȴ$j?b+=i޹[#f*h[QU,8v> stream xXn8}W[e u-Z *-1wmɡٯ!um 0 9#K@ j?o(w1\‹$~cA"C"K؄GАQ034",@W1 L0 66KefY S*rhj5[32Lu'eVe׋ frX鸀kϿ*쪾Aklh@U$Y -+[J]*3SpwkLavrSHL8ϒ~4+\[nut>p:d ,k:oIG|35a4/FՕKUM K)M9r@&c^,3+sFj\>O(6Vx~O!Lҋ1 $/O 7)mb}>f@3hZ~K!Yݝ ՌQ]C3y;㯌.bdo=4"o8hHhп)KH̳xt6h㛲QLz!?.g)PX>x߯_{Fendstream endobj 65 0 obj 920 endobj 68 0 obj <> stream xX[k0~c#ɲ5J0놡05vf~$u6]0ń]|DǹEЅM; -ۯ~Z r\Α[#!0:Q*Kl!?Q(!Mx;c\blV1a#e\ý5zhҢʢy.1` 4b愓l ̓fB_ap 0 &`BwvA\M69.,f):8>*#]ѢI:"FW&(o CXKnAJPy˯]D٪O& 4*q(րcyVA]!,QO r8`Έ1V;Xqn+.~&RʳbIׯߢ}**~vDvPUI-'?=")#&A.J.^xu^9*^ը救ny̫T`TVT$; g1F݋çi?*Y'A1* j 7 m_|@gʼ쾷XP)UOx}  xKb>7Gendstream endobj 69 0 obj 758 endobj 72 0 obj <> stream xXmk8_^uI) KspxmecMmܯ,{&4ݦefFhf`@}:7@#EۙlG^7D 9 `FC fo?`N@$ BQ/gѿ֧hm-Q;q'Ϗ2) :3(ϯquI"o hU~wcE;:LZ\bnъDkO'hs}e'F}SBd@€(wIV~_ձq,B=OƔu*k\@ƎdaѢlԘ)&yQIz>*MzMX78:ShS#bE*(J~AeV@Q@f{)e4ˋz{IwT(xJ2z%5>㏶I'-۱  lc} 1%TyJOcpFӋ``Ez.K i %U_:Pmj햮L]ofΣMLۅ ; ( ~ { ?Ea=!Jyv :r.S;güJʅy8-WNeTJ'W L L_ԷRIzSki0qTyf2ů趈JJ72L=NS;˼} {ӓYn?+sV?P}!ݝ,k/@v2S¨ 2+iij{vVD^| 2]eyXw6q\d;H{P=:?޸$3y9V)@khb#l l[*wްYq佶g"endstream endobj 73 0 obj 919 endobj 76 0 obj <> stream xW[o6~8"fH-5(:lVCZtq%:n6fE[}ߡ8瞫zgfœ{j.IB}v;~dGd[ 9mlO LİȊ<s⑈/#`Bpi˖M^+xy]|LrL c\B2fed, ͵=^vu:1ɗ.ͽVw踩'Ht:O4qY>>sN9C$\a-o^-V<Ozq >kqj/p5흾JNa&6ID4񮽢* s{jzVzי} n|pxdqo)Sv_L#Pjd\axV7 n۪jqcx{B{W < sXM` Scʕ3[#W&@0 UekK~+UUw [ t 9#dwEkL0ZdL"ac980endstream endobj 77 0 obj 1377 endobj 80 0 obj <> stream xuXnH}WԛD,µ`N:4ҍL"LQ(3\.5Hw9soaY1+WVшͮjNu5O(c9 Ed &Oca;lb.҈Mo67ˋTpbzf=Bm5[Oi„{0b=DNf:b4>8c/2{V2^pb ḅUWw0Ƀi,==ޗ;f QdԠPu1Նk'?}[2;i)g^ibzVGNL9hl\N {}m*qؒ 5ۑ4$~ZLtGi+'h5˖JF3=N!A,ceË8LO"ڃq `]ߨ5`*Yӆ ycCO,nnfzML`rf&{ԪdM‘bAjG7UGI`ُh5h<BcLWevڲj$:kCpX {QgS%a t4f/Xc尌,O'e金J >A!M'e6bԮ ES[2&eE~h;b)s|S $;!Aw*Rk !A3)7,¼׫.f^LiɱʡKYUԜc |h3)0׆c%LIE#s^ou| afee^"FQzlU Tl}Bf M 6kcC̲R7W3w[uI:g z$E*|t* l ?ޖZ+4)Kk?Ki_8IUǩ ~)7!$@ޡpʰ=˦E[TD_~XƅDD9,L]bMh7ϾAO-Oۋ4éeu}rUyX{,sX71 (eY\d#v%E j=\z2ݾ}}LSa1cXeo93lXbbbn*H6KrKίW:fT7\~<ɸfvdJɾŤ>`m . -?//?g-endstream endobj 81 0 obj 2083 endobj 84 0 obj <> stream xXko7_oQY'.\dݬ5jfy6UCi_tlpR8k>dA=mn380rhT"EkөD/9bF">A0½ׯ5X[-cw/BMN0/}0Oewn50U@5\AW)5dސznQWmd)PbqKe1=WRrxU1K-sB8p}c W 85+2)YD[ T%S04#>TMkx !?a<Y,V@R9ie2''_Y3է^E}\HTܢUEb(ٔ(jEvDInkZZdn-yX΄5?)НWȀG\N¢EI!~N%F䶵+S0eYECNȎ|C5z d(܋&kYgm;:b f Wg.xL> eeeI~08 >Y5ׂg%[~{c$vѹ D>8XLL}JCilA58oMD- f./؋ qfT=13{a s>niyv1q Lh!ZUیdwLPN;gv`ggXT96 ;u7?ӗNy CTǩyJpҖ*xt.h`$´*Mq"//:نg(L*m`AYl]<0ф /$9d5n`v,Je~evR0Ofkm" ZϽHAǽ*G=הwyߩĪ AD# QpR@0\vBC!%B::"w@ۀїz^1)?>zZW{.QXx'<'mvh>N_d2leӻ|9=VŨp/iU{pH/Z 78;h)&S59 4c0[j#ۡTZ1,aw4ΒZ;p<^+SioBc DeSdIEpNz| :Vi9=nMjE:C\5F, $X<}_p}z:uιD_3}L jח(ڱS/Qm) `C_ PM#x!@ad47=J7H&< l4XOǜ^US9IjhhDV'4G Ppa;];3$`;\.ڡ?a5ٲ>jTzܭC 36Leob> stream xX]|ׯQLٜ$Wv:EIDE$>=R^I f ?{{Z{/_n*I5Li ̜,U%z DFS(m妽P)/@_qݗK+_ !8R\4j Lj^zJ%&H[isĀ j%kM /H.]C3de0&Hrg~]LT# BaQbЩS&\v*Tꑻb&zfF35"P;%΄Ub"v1_5 MYqKrCǨJAll'< %[ZG>7joVlk`j]ͫwӳ-P*Vj\yQ[G WInKv;{yJ{[$^]y>V۲̯#4K ǰڜzW3:k .sYtZ1М)1#_xd^ 2g?XՅvt.0ñu:PL"gΫzS&yCC٭&B NJMZNr0+i{c+!Qp4ˡwM{k/x>t y::1T :؃6yuϟUaN,yWV)50*`gu`R;yGÑP<eɠgФ Lwe\pthM~"q-R"KGaKxꋡNd@\ T \9/`RFe]NgYzjD%L|"|Dv )a~V>MHv7r*>M.r(~]R'郧>|be;C7Lȶ:ksʒr X eT3|lk 9>}(Mwv0U ʧfNq]@sg jVIN&Xw(C+]Jy&HgA~J 9d1J~Ss.!Դ{*]ĭܕD< z+z1fo Bu 'ѱk31>u4Up %p ҰU>(6L)7MŔj9"M:4n95Ǔִ?Vv7gRA+bUrMT1yE@$&ȭ#$D>BY;?cX]vt[>c+Qa(Nn[.L!28c%0(]趞bԹU?V6p40*k݅ GkUE|㮻r7v{$"ԒړL߹2tVIׄ;V8"NV J 6{U7}84DŽexYsHn:ހ8o<~ى,jSfWv_OL]X-ue:zDb߱>L,xU1Ӹ9!wL G7t"?o>endstream endobj 89 0 obj 2320 endobj 92 0 obj <> stream xMO 0 9n`kkς7 on(!<%fRw0OΒzD0&X|TQՎ:b(iő&#9u!m!Qy#oЌ6 L L<שBxBy/:{Fxyf ,5Iendstream endobj 93 0 obj 170 endobj 96 0 obj <> stream x]o6+xWE.M.ÐtHAeGme;([v- H/9_l1 W@!bA4$4i |zu.OA`ˆHޜ n0#PQ/.@D$2WgO㋫ % ŏLXK 9Q;  P_  y4>FH!s{C0F::Z`eT:N $LS)| : xݡb\Q"mr勢i%Vy+Lw, &z$QΫ" 0}C(xZqNDk0 S."X{Ju7yz7]>;tsʎ$Z$xG%/}?3m;>Gr*o1T9ƈxܣ3ࡻxpoF U";/3SH*kV>|7 hh:,r*ס߈u9SR FIqp#qV">W"G}9> 'eY/0aM '"_6},hE/gf50w+i.Sϋ#t_ 3N|/}cK|p~ԚZ/ Q!s[nY #cH?|jO,M^*ں Y3"K&YHoJuUX[jٲTDKX_G<%8g5<vHHi5ui?5%h+(%:߻<@[!@`*lB1$^/WWU%i8t)uRۺ] u =X/d} Ie$޶ن.A S( endstream endobj 97 0 obj 1397 endobj 100 0 obj <> stream x[F)F VtṇR5MXCT! c/]  ]*qx9s. }FofmF>-m9SG~P!\ξz? 0ޕwj6Uk*j Cp3Lae6,pqw7EN}#~HtCߐP/:Z߰>8ZI҂B'AE 59(~aa`"/7v }p,*"^h*95PZ%zJ}#gP/~V8ɲZ?D#\9㳃?T3S:摷$u%H#җPQq pAN 6(>Wxn-Jo);KA0AZjkq"2ÈNb>dU~z]uhh|&<!zY$`v{]yW6mR˘C4}':š> zUHȤ7/ک:iZgdL8;Nbg J̋| 9Sc.]_^x]oRޗi? 1yy7_ͩvh$/bN|z8g9吤B/)n/rvyna Gh <4\ ]BJWOs>&+1hj9ѰSl"H]-e]EvvC;w$nq<)zbq Mn]vFRxCo*Ä gHNO[ jyH'0xk瑼K6*s%5c)b+͝顀g Ary=y0OV=q(}˓5 03_ppYӢ(,Vu;d*1e1ۤR 'I,}\^Ay.ՏFj, -2ufCet)gD2=ɓinqsO -|[dra> stream xMo0stkD8Thgkh6lv*+2c1\')(mC YU{)Q=ݓ #KrT͚C7yrwOHzEf,RkܩJ{tv,ȁ O/qM-ߟ-k[.{˂)"keLc{D5~U!oJ8kǮpn\q_ޡd p%)8bGv::7ِ0LMA"-ڱkJ׬ue[[' $w)-yO "iղɽB-FګY/Z{GBH)ܻ\MDZDh{uCx;GSs$NRŊJ}ķMJ/mjPg?󡈸Rf3sd *gendstream endobj 105 0 obj 604 endobj 109 0 obj <> stream xmT]o0}W\e0_1TVNZ@IH ikCL2}=c% {]+0 .b)A E`RAHC ɷLVMBu1'lY"iYOcF> stream x+T03T0A(e\\`(¥d`h``dngib`h˥Quendstream endobj 115 0 obj 82 endobj 4 0 obj <> /Contents 5 0 R >> endobj 11 0 obj <> /Contents 12 0 R >> endobj 15 0 obj <> /Contents 16 0 R >> endobj 19 0 obj <> /Contents 20 0 R >> endobj 23 0 obj <> /Contents 24 0 R >> endobj 27 0 obj <> /Contents 28 0 R >> endobj 31 0 obj <> /Contents 32 0 R >> endobj 35 0 obj <> /Contents 36 0 R >> endobj 39 0 obj <> /Contents 40 0 R >> endobj 43 0 obj <> /Contents 44 0 R >> endobj 47 0 obj <> /Contents 48 0 R >> endobj 51 0 obj <> /Contents 52 0 R >> endobj 55 0 obj <> /Contents 56 0 R >> endobj 59 0 obj <> /Contents 60 0 R >> endobj 63 0 obj <> /Contents 64 0 R >> endobj 67 0 obj <> /Contents 68 0 R >> endobj 71 0 obj <> /Contents 72 0 R >> endobj 75 0 obj <> /Contents 76 0 R >> endobj 79 0 obj <> /Contents 80 0 R >> endobj 83 0 obj <> /Contents 84 0 R >> endobj 87 0 obj <> /Contents 88 0 R >> endobj 91 0 obj <> /Contents 92 0 R >> endobj 95 0 obj <> /Contents 96 0 R >> endobj 99 0 obj <> /Contents 100 0 R >> endobj 103 0 obj <> /Contents 104 0 R >> endobj 107 0 obj <> >> endobj 108 0 obj <> /Contents 109 0 R >> endobj 112 0 obj <> >> endobj 113 0 obj <> /Contents 114 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 11 0 R 15 0 R 19 0 R 23 0 R 27 0 R 31 0 R 35 0 R 39 0 R 43 0 R 47 0 R 51 0 R 55 0 R 59 0 R 63 0 R 67 0 R 71 0 R 75 0 R 79 0 R 83 0 R 87 0 R 91 0 R 95 0 R 99 0 R 103 0 R 107 0 R 108 0 R 112 0 R 113 0 R ] /Count 29 >> endobj 1 0 obj <> endobj 10 0 obj <> endobj 14 0 obj <> endobj 18 0 obj <> endobj 22 0 obj <> endobj 26 0 obj <> endobj 30 0 obj <> endobj 34 0 obj <> endobj 38 0 obj <> endobj 42 0 obj <> endobj 46 0 obj <> endobj 50 0 obj <> endobj 54 0 obj <> endobj 58 0 obj <> endobj 62 0 obj <> endobj 66 0 obj <> endobj 70 0 obj <> endobj 74 0 obj <> endobj 78 0 obj <> endobj 82 0 obj <> endobj 86 0 obj <> endobj 90 0 obj <> endobj 94 0 obj <> endobj 98 0 obj <> endobj 102 0 obj <> endobj 106 0 obj <> endobj 111 0 obj <> endobj 116 0 obj <> endobj 8 0 obj <> endobj 7 0 obj <> endobj 9 0 obj <> endobj 2 0 obj <>endobj xref 0 117 0000000000 65535 f 0000054086 00000 n 0000055335 00000 n 0000053825 00000 n 0000049728 00000 n 0000000015 00000 n 0000001856 00000 n 0000055202 00000 n 0000055137 00000 n 0000055268 00000 n 0000054134 00000 n 0000049870 00000 n 0000001876 00000 n 0000004476 00000 n 0000054182 00000 n 0000050014 00000 n 0000004497 00000 n 0000007280 00000 n 0000054221 00000 n 0000050158 00000 n 0000007301 00000 n 0000009955 00000 n 0000054260 00000 n 0000050302 00000 n 0000009976 00000 n 0000012784 00000 n 0000054299 00000 n 0000050446 00000 n 0000012805 00000 n 0000014667 00000 n 0000054338 00000 n 0000050590 00000 n 0000014688 00000 n 0000017613 00000 n 0000054377 00000 n 0000050734 00000 n 0000017634 00000 n 0000020284 00000 n 0000054416 00000 n 0000050878 00000 n 0000020305 00000 n 0000022359 00000 n 0000054455 00000 n 0000051022 00000 n 0000022380 00000 n 0000024525 00000 n 0000054494 00000 n 0000051166 00000 n 0000024546 00000 n 0000026657 00000 n 0000054533 00000 n 0000051310 00000 n 0000026678 00000 n 0000029098 00000 n 0000054572 00000 n 0000051454 00000 n 0000029119 00000 n 0000031324 00000 n 0000054611 00000 n 0000051598 00000 n 0000031345 00000 n 0000033211 00000 n 0000054650 00000 n 0000051742 00000 n 0000033232 00000 n 0000034224 00000 n 0000054689 00000 n 0000051886 00000 n 0000034244 00000 n 0000035074 00000 n 0000054719 00000 n 0000052030 00000 n 0000035094 00000 n 0000036085 00000 n 0000054749 00000 n 0000052174 00000 n 0000036105 00000 n 0000037554 00000 n 0000054779 00000 n 0000052318 00000 n 0000037575 00000 n 0000039730 00000 n 0000054818 00000 n 0000052462 00000 n 0000039751 00000 n 0000042017 00000 n 0000054857 00000 n 0000052606 00000 n 0000042038 00000 n 0000044430 00000 n 0000054896 00000 n 0000052750 00000 n 0000044451 00000 n 0000044693 00000 n 0000054935 00000 n 0000052894 00000 n 0000044713 00000 n 0000046182 00000 n 0000054965 00000 n 0000053038 00000 n 0000046203 00000 n 0000047983 00000 n 0000054995 00000 n 0000053184 00000 n 0000048005 00000 n 0000048683 00000 n 0000055026 00000 n 0000053331 00000 n 0000053431 00000 n 0000048704 00000 n 0000049531 00000 n 0000055057 00000 n 0000053578 00000 n 0000053678 00000 n 0000049552 00000 n 0000049708 00000 n 0000055106 00000 n trailer << /Size 117 /Root 1 0 R /Info 2 0 R /ID [(k CIʇԖ)(k CIʇԖ)] >> startxref 55446 %%EOF dwarfutils-20200114/libdwarf/pdfbld.sh000077500000000000000000000017311361531463500175260ustar00rootroot00000000000000#!/bin/sh # This is meant to be done by hand # when changes made. Not done during build or install. # Just use the built pdf to install. # Run in the libdwarf source directory. c="n" p="n" if [ $# -lt 1 ] then echo "Usage: pdfbld.sh [-a] [-c] [-p]" echo "where: -c formats libdwarf2.1.pdf" echo "where: -p formats libdwarf2p.1.pdf" echo "where: -a formats both" exit 1 fi for i in $* do case $i in -a) c="y" ; p="y" shift ;; -c) c="y" shift ;; -p) p="y" shift ;; *) echo "Giving up: unknown argument use argument -a or -c or -p" exit 1 ;; esac done set -x TROFF=/usr/bin/groff #TROFFDEV="-T ps" PSTOPDF=/usr/bin/ps2pdf if [ $c = "y" ] then pr -t -e libdwarf2.1.mm | tbl | $TROFF -mm >libdwarf2.1.ps $PSTOPDF libdwarf2.1.ps libdwarf2.1.pdf fi if [ $p = "y" ] then pr -t -e libdwarf2p.1.mm | tbl | $TROFF -mm >libdwarf2p.1.ps $PSTOPDF libdwarf2p.1.ps libdwarf2p.1.pdf fi rm -f libdwarf2.1.ps rm -f libdwarf2p.1.ps dwarfutils-20200114/libdwarf/pro_alloc.c000066400000000000000000000145421361531463500200560ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2019. David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_alloc.h" #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #ifdef HAVE_INTTYPES_H #include #endif /* HAVE_INTTYPES_H */ #include "dwarf_tsearch.h" /* When each block is allocated, there is a two-word structure allocated at the beginning so the block can go on a list. The address returned is the address *after* the two pointers at the start. But this allows us to be given a pointer to a generic block, and go backwards to find the list-node. Then we can remove this block from it's list without the need to search through a linked list in order to remove the node. It also allows us to 'delete' a memory block without needing the dbg structure. We still need the dbg structure on allocation so that we know which linked list to add the block to. Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc. That structure should be set up by hand, and the two list pointers should be initialized to point at the node itself. That initializes the doubly linked list. */ #define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t))) #define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t))) /* dbg should be NULL only when allocating dbg itself. In that case we initialize it to an empty circular doubly-linked list. */ Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size) { void *sp; memory_list_t *lp = NULL; memory_list_t *dbglp = NULL; memory_list_t *nextblock = NULL; /* alloc control struct and data block together for performance reasons */ lp = (memory_list_t *) malloc(size + sizeof(memory_list_t)); if (lp == NULL) { /* should throw an error */ return NULL; } /* point to 'size' bytes just beyond lp struct */ sp = LIST_TO_BLOCK(lp); memset(sp, 0, size); if (dbg == NULL) { lp->next = lp->prev = lp; } else { /* I always have to draw a picture to understand this part. */ dbglp = BLOCK_TO_LIST(dbg); nextblock = dbglp->next; /* Insert between dbglp and nextblock */ dbglp->next = lp; lp->prev = dbglp; lp->next = nextblock; nextblock->prev = lp; } return sp; } /* This routine is only here in case a caller of an older version of the library is calling this for some reason. This does nothing! No need to remove this block. In theory the user might be depending on the fact that we used to just 'free' this. In theory they might also be passing a block that they got from libdwarf. So we don't know if we should try to remove this block from our global list. Safest just to do nothing at this point. !!! This function is deprecated! Don't call it inside libdwarf or outside of it. Does nothing! !!! */ void dwarf_p_dealloc(UNUSEDARG Dwarf_Small * ptr) { return; } /* The dbg structure is not needed here anymore. */ void _dwarf_p_dealloc(UNUSEDARG Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */ { memory_list_t *lp; lp = BLOCK_TO_LIST(ptr); /* Remove from a doubly linked, circular list. Read carefully, use a white board if necessary. If this is an empty list, the following statements are no-ops, and will write to the same memory location they read from. This should only happen when we deallocate the dbg structure itself. */ if (lp == lp->next) { /* The list has a single item, itself. */ lp->prev = 0; lp->next = 0; } else if (lp->next == lp->prev) { /* List had exactly two entries. Reduce it to one, cutting lp out. */ memory_list_t * remaining = lp->next; remaining->next = remaining; remaining->prev = remaining; } else { /* Multi=entry. Just cut lp out. */ lp->prev->next = lp->next; lp->next->prev = lp->prev; lp->prev = lp->next = 0; } free((void*)lp); } static void _dwarf_str_hashtab_freenode(void * nodep) { free(nodep); } /* This routine deallocates all the nodes on the dbg list, and then deallocates the dbg structure itself. */ void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg) { memory_list_t *dbglp; memory_list_t *base_dbglp; if (dbg == NULL) { /* should throw an error */ return; } base_dbglp = BLOCK_TO_LIST(dbg); dbglp = base_dbglp->next; while (dbglp != base_dbglp) { memory_list_t*next = dbglp->next; _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp)); dbglp = next; } dwarf_tdestroy(dbg->de_debug_str_hashtab, _dwarf_str_hashtab_freenode); dwarf_tdestroy(dbg->de_debug_line_str_hashtab, _dwarf_str_hashtab_freenode); free((void *)base_dbglp); } dwarfutils-20200114/libdwarf/pro_alloc.h000066400000000000000000000027131361531463500200600ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #ifndef PRO_ALLOC_H #define PRO_ALLOC_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned); void dwarf_p_dealloc(Dwarf_Small * ptr); /* DO NOT USE. */ void _dwarf_p_dealloc(Dwarf_P_Debug,Dwarf_Small * ptr); void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PRO_ALLOC_H */ dwarfutils-20200114/libdwarf/pro_arange.c000066400000000000000000000260271361531463500202220ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_arange.h" #include "pro_section.h" #include "pro_reloc.h" #define SIZEOFT32 4 /* This function adds another address range to the list of address ranges for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Signed symbol_index, Dwarf_Error * error) { int res = 0; res = dwarf_add_arange_b(dbg, begin_address, length, symbol_index, /* end_symbol_index */ 0, /* offset_from_end_sym */ 0, error); if (res != DW_DLV_OK) { return 0; } return 1; } /* This function adds another address range to the list of address ranges for the given Dwarf_P_Debug. It returns DW_DLV_ERROR on error, and DW_DLV_OK otherwise. */ Dwarf_Unsigned dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) { int res = 0; res = dwarf_add_arange_c(dbg,begin_address,length, symbol_index, end_symbol_index, offset_from_end_sym,error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_arange_c(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) { Dwarf_P_Arange arange; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } arange = (Dwarf_P_Arange) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s)); if (arange == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } arange->ag_begin_address = begin_address; arange->ag_length = length; arange->ag_symbol_index = symbol_index; arange->ag_end_symbol_index = end_symbol_index; arange->ag_end_symbol_offset = offset_from_end_sym; if (dbg->de_arange == NULL) dbg->de_arange = dbg->de_last_arange = arange; else { dbg->de_last_arange->ag_next = arange; dbg->de_last_arange = arange; } dbg->de_arange_count++; return DW_DLV_OK; } int _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Total num of bytes in .debug_aranges section. */ Dwarf_Unsigned arange_num_bytes = 0; /* Adjustment to align the start of the actual address ranges on a boundary aligned with twice the address size. */ Dwarf_Small remainder = 0; /* Total number of bytes excluding the length field. */ Dwarf_Unsigned adjusted_length = 0; /* Points to first byte of .debug_aranges buffer. */ Dwarf_Small *arange = 0; /* Fills in the .debug_aranges buffer. */ Dwarf_Small *arange_ptr = 0; /* Scans the list of address ranges provided by user. */ Dwarf_P_Arange given_arange = 0; /* Used to fill in 0. */ const Dwarf_Signed big_zero = 0; int extension_word_size = dbg->de_64bit_extension ? 4 : 0; int offset_size = dbg->de_dwarf_offset_size; int upointer_size = dbg->de_pointer_size; /* All dwarf versions so far use 2 here. */ Dwarf_Half version = 2; int res = 0; /* ***** BEGIN CODE ***** */ /* Size of the .debug_aranges section header. */ arange_num_bytes = extension_word_size + offset_size + /* Size of length field. */ DWARF_HALF_SIZE + /* Size of version field. */ offset_size + /* Size of .debug_info offset. */ sizeof(Dwarf_Small) + /* Size of address size field. */ sizeof(Dwarf_Small); /* Size of segment size field. */ /* Adjust the size so that the set of aranges begins on a boundary that aligned with twice the address size. This is a Libdwarf requirement. */ remainder = arange_num_bytes % (2 * upointer_size); if (remainder != 0) arange_num_bytes += (2 * upointer_size) - remainder; /* Add the bytes for the actual address ranges. */ arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1); GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES], arange, (unsigned long) arange_num_bytes, error); arange_ptr = arange; if (extension_word_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *)&v4[0] , SIZEOFT32, extension_word_size); arange_ptr += extension_word_size; } /* Write the total length of .debug_aranges section. */ adjusted_length = arange_num_bytes - offset_size - extension_word_size; { Dwarf_Unsigned du = adjusted_length; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &du, sizeof(du), offset_size); arange_ptr += offset_size; } /* Write the version as 2 bytes. */ { Dwarf_Half verstamp = version; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &verstamp, sizeof(verstamp), DWARF_HALF_SIZE); arange_ptr += DWARF_HALF_SIZE; } /* Write the .debug_info offset. This is always 0. */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), offset_size); arange_ptr += offset_size; { unsigned long count = dbg->de_arange_count + 1; int res2 = 0; Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[DEBUG_ARANGES]; if (dbg->de_relocate_pair_by_symbol) { count = (3 * dbg->de_arange_count) + 1; } /* The following is a small optimization: not needed for correctness. Does nothing if preloc->pr_first_block is non-null */ res2 = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, p_reloc, count); if (res2 != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } } /* reloc for .debug_info */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES, extension_word_size + offset_size + DWARF_HALF_SIZE, dbg->de_sect_name_idx[DEBUG_INFO], dwarf_drt_data_reloc, offset_size); if (res == DW_DLV_NO_ENTRY) { return res; } if (res == DW_DLV_ERROR) { _dwarf_p_error(dbg, error,DW_DLE_RELOCS_ERROR); return res; } /* Write the size of addresses. */ *arange_ptr = dbg->de_pointer_size; arange_ptr++; /* Write the size of segment addresses. This is zero for MIPS architectures. */ *arange_ptr = 0; arange_ptr++; /* Skip over the padding to align the start of the actual address ranges to twice the address size. */ if (remainder != 0) arange_ptr += (2 * upointer_size) - remainder; /* The arange address, length are pointer-size fields of the target machine. */ for (given_arange = dbg->de_arange; given_arange != NULL; given_arange = given_arange->ag_next) { /* Write relocation record for beginning of address range. */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset */ (long) given_arange->ag_symbol_index, dwarf_drt_data_reloc, upointer_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Copy beginning address of range. */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &given_arange->ag_begin_address, sizeof(given_arange->ag_begin_address), upointer_size); arange_ptr += upointer_size; if (dbg->de_relocate_pair_by_symbol && given_arange->ag_end_symbol_index != 0 && given_arange->ag_length == 0) { /* symbolic reloc, need reloc for length What if we really know the length? If so, should use the other part of 'if'. */ Dwarf_Unsigned val; res = dbg->de_relocate_pair_by_symbol(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset */ given_arange->ag_symbol_index, given_arange->ag_end_symbol_index, dwarf_drt_first_of_length_pair, upointer_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* arange pre-calc so assem text can do .word end - begin + val (gets val from stream) */ val = given_arange->ag_end_symbol_offset - given_arange->ag_begin_address; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &val, sizeof(val), upointer_size); arange_ptr += upointer_size; } else { /* plain old length to copy, no relocation at all */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &given_arange->ag_length, sizeof(given_arange->ag_length), upointer_size); arange_ptr += upointer_size; } } WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), upointer_size); arange_ptr += upointer_size; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), upointer_size); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_arange.h000066400000000000000000000032751361531463500202270ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* If ag_end_symbol_index is zero, ag_length must be known and non-zero. Deals with length being known costant or fr assembler output, not known. */ struct Dwarf_P_Arange_s { Dwarf_Addr ag_begin_address; /* known address or for symbolic assem output, offset of symbol */ Dwarf_Addr ag_length; /* zero or address or offset */ Dwarf_Unsigned ag_symbol_index; Dwarf_P_Arange ag_next; Dwarf_Unsigned ag_end_symbol_index; /* zero or index/id of end symbol */ Dwarf_Addr ag_end_symbol_offset; /* known address or for symbolic assem output, offset of end symbol */ }; dwarfutils-20200114/libdwarf/pro_die.c000066400000000000000000000630641361531463500175300ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include #include #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_util.h" #include "pro_alloc.h" #include "pro_die.h" #include "pro_section.h" #include "dwarf_tsearch.h" #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif #define TRUE 1 #define FALSE 0 /* This function creates a new die. tag: tag of the new die to be created parent,child,left,right: specify neighbors of the new die. Only one of these may be non-null */ Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { Dwarf_P_Die created = 0; int res = 0; res = dwarf_new_die_a(dbg,tag,parent,child, left,right,&created,error); if (res != DW_DLV_OK) { return (Dwarf_P_Die)DW_DLV_BADADDR; } return created; } /* New September 2016. Preferred as error checking is easier, no need for ugly cast. */ int dwarf_new_die_a(Dwarf_P_Debug dbg, Dwarf_Tag tag, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_P_Die *die_out, Dwarf_Error *error) { Dwarf_P_Die ret_die = 0; int res = 0; ret_die = (Dwarf_P_Die) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s)); if (ret_die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC, DW_DLV_ERROR); } ret_die->di_parent = NULL; ret_die->di_left = NULL; ret_die->di_right = NULL; ret_die->di_child = NULL; ret_die->di_last_child = NULL; ret_die->di_tag = tag; ret_die->di_dbg = dbg; ret_die->di_marker = 0; res = dwarf_die_link_a(ret_die, parent, child, left, right, error); if (res != DW_DLV_OK) { _dwarf_p_dealloc(dbg,(Dwarf_Small *)ret_die); ret_die = 0; } else { *die_out = ret_die; } return res; } /* This function links up a die to specified neighbors parent,child,left,right: specify neighbors of the new die. Only one of these may be non-null This is the original version. Use dwarf_die_link_a() instead as that function is easier to use (in checking for error). */ Dwarf_P_Die dwarf_die_link(Dwarf_P_Die new_die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { int res = 0; res = dwarf_die_link_a(new_die,parent,child,left,right,error); if (res != DW_DLV_OK) { return (Dwarf_P_Die)DW_DLV_BADADDR; } return new_die; } /* New September 2016. Error return easier to deal with than dwarf_die_link(). */ int dwarf_die_link_a(Dwarf_P_Die new_die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { /* Count the # of non null neighbors. */ int n_nulls = 0; if (parent != NULL) { n_nulls++; if (new_die->di_parent != NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP, DW_DLV_ERROR); } new_die->di_parent = parent; if (parent->di_child) { /* di_last_child identifies the last sibling, the die we want to attach new_die to. */ /* ASSERT: if di_child is set so is di_last_child. */ Dwarf_P_Die former_lastchild = parent->di_last_child; parent->di_last_child = new_die; /* Attach to the new die to end of the sibling list. */ former_lastchild->di_right = new_die; new_die->di_left = former_lastchild; } else { parent->di_child = new_die; parent->di_last_child = new_die; } } if (child != NULL) { n_nulls++; new_die->di_child = child; new_die->di_last_child = child; if (child->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, DW_DLV_ERROR); } else { child->di_parent = new_die; } } if (left != NULL) { n_nulls++; new_die->di_left = left; if (left->di_right) { /* There's already a right sibling of left, insert the new die in the list. */ new_die->di_right = left->di_right; left->di_right->di_left = new_die; } left->di_right = new_die; if (new_die->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, DW_DLV_ERROR); } else { new_die->di_parent = left->di_parent; } } if (right != NULL) { n_nulls++; new_die->di_right = right; if (right->di_left) { /* There is already a left sibling of the right die, insert the new die in the list. */ new_die->di_left = right->di_left; right->di_left->di_right = new_die; } right->di_left = new_die; if (new_die->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, DW_DLV_ERROR); } else { new_die->di_parent = right->di_parent; } } if (n_nulls > 1) { /* Multiple neighbors! error! */ DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS, DW_DLV_ERROR); } return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_die_marker(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); } die->di_marker = marker; return 0; } int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_ERROR); } die->di_marker = marker; return DW_DLV_OK; } Dwarf_Unsigned dwarf_get_die_marker(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned * marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); } *marker = die->di_marker; return 0; } int dwarf_get_die_marker_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned * marker, Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_ERROR); } *marker = die->di_marker; return DW_DLV_ERROR; } /*--------------------------------------------------------- This function adds a die to dbg struct. It should be called using the root of all the dies. ---------------------------------------------------------*/ /* Original form of this call.. dwarf_add_die_to_debug_a() is preferred now. */ Dwarf_Unsigned dwarf_add_die_to_debug(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) { int res = dwarf_add_die_to_debug_a(dbg,first_die,error); if (res == DW_DLV_ERROR) { return DW_DLV_NOCOUNT; } return 0; } /* New September 2016. The new and preferred form. */ int dwarf_add_die_to_debug_a(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) { if (first_die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_ERROR); } if (first_die->di_tag != DW_TAG_compile_unit) { DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_ERROR); } dbg->de_dies = first_die; return DW_DLV_OK; } int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int uwordb_size = dbg->de_dwarf_offset_size; /* Add AT_stmt_list attribute */ new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } new_attr->ar_attribute = DW_AT_stmt_list; new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { DWARF_P_DBG_ERROR(NULL,DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = 0; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } _dwarf_pro_add_at_to_die(first_die, new_attr); return DW_DLV_OK; } static int _dwarf_debug_str_compare_func(const void *l,const void *r) { const struct Dwarf_P_debug_str_entry_s*el = l; const struct Dwarf_P_debug_str_entry_s*er = r; char *lname = 0; char *rname = 0; int ir = 0; if (el->dse_has_table_offset) { /* When set the name is in the debug_str table. */ /* ASSERT: dse_dbg->de_debug_str->ds_data is non-zero. ASSERT: dse_name NULL. */ lname = el->dse_dbg->de_debug_str->ds_data + el->dse_table_offset; } else { /* ASSERT: dse_name non-null */ lname = el->dse_name; } if (er->dse_has_table_offset) { /* When set the name is in the debug_str table. */ /* ASSERT: dse_dbg->de_debug_str->ds_data is non-zero. ASSERT: dse_name NULL. */ rname = er->dse_dbg->de_debug_str->ds_data + er->dse_table_offset; } else { /* ASSERT: dse_name non-null */ rname = er->dse_name; } ir = strcmp(lname,rname); return ir; } static void debug_str_entry_free_func(void *m) { free(m); } static int make_debug_str_entry(Dwarf_P_Debug dbg, struct Dwarf_P_debug_str_entry_s **mt_out, char *name, unsigned slen, unsigned char has_offset, Dwarf_Unsigned offset_in_table, Dwarf_Error *error) { struct Dwarf_P_debug_str_entry_s *mt = (struct Dwarf_P_debug_str_entry_s *)calloc( sizeof(struct Dwarf_P_debug_str_entry_s),1); if (!mt) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } mt->dse_slen = slen; mt->dse_table_offset = 0; mt->dse_dbg = dbg; if (has_offset) { mt->dse_has_table_offset = TRUE; mt->dse_table_offset = offset_in_table; mt->dse_name = 0; } else { /* ASSERT: name != NULL */ mt->dse_has_table_offset = FALSE; /* We just set dse_table_offset so it has a known value, though nothing should refer to dse_table_offset because dse_has_table_offset is FALSE.*/ mt->dse_table_offset = 0; mt->dse_name = name; } *mt_out = mt; return DW_DLV_OK; } #define STRTAB_BASE_ALLOC_SIZE 2048 static int insert_debug_str_data_string(Dwarf_P_Debug dbg, char *name, unsigned slen, Dwarf_P_Section_Data sd, Dwarf_Unsigned*adding_at_offset, Dwarf_Error * error) { Dwarf_Unsigned current_offset = 0; if (!sd->ds_data) { Dwarf_Unsigned initial_alloc = STRTAB_BASE_ALLOC_SIZE; Dwarf_Unsigned base_insert_offset = 0; /* Inserting our first string. The GNU linker refuses to commonize strings if the section starts with a NUL byte, so start with real string, using a base_insert_offset of 0. */ if ( (slen + base_insert_offset) >= STRTAB_BASE_ALLOC_SIZE) { initial_alloc = slen *2+ base_insert_offset; } if (initial_alloc < slen) { _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND); return DW_DLV_ERROR; } sd->ds_data = calloc(1,initial_alloc); if (!sd->ds_data) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } sd->ds_orig_alloc = initial_alloc; *adding_at_offset = base_insert_offset; sd->ds_nbytes = slen + base_insert_offset; strcpy(sd->ds_data+base_insert_offset,name); return DW_DLV_OK; } current_offset = sd->ds_nbytes; if ( (current_offset + slen) >= sd->ds_orig_alloc) { unsigned updated_length = sd->ds_orig_alloc; char *newbuf = 0; if (slen > updated_length) { /* Very long string passed in. */ updated_length = slen *2; } else { updated_length = updated_length *2; } if (updated_length < sd->ds_orig_alloc) { _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND); return DW_DLV_ERROR; } newbuf = calloc(1,updated_length); if (!newbuf) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(newbuf,sd->ds_data,sd->ds_nbytes); free(sd->ds_data); sd->ds_data = newbuf; sd->ds_orig_alloc = updated_length; newbuf = 0; } strcpy(sd->ds_data + current_offset,name); sd->ds_nbytes += slen; *adding_at_offset = current_offset; return DW_DLV_OK; } /* Find the string offset using the hash table, and if not known, insert the new string. */ int _dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg, char *name, enum dwarf_which_hash whash, unsigned slen, /* includes space for trailing NUL */ Dwarf_Unsigned *offset_in_debug_str, Dwarf_Error *error) { struct Dwarf_P_debug_str_entry_s *mt = 0; struct Dwarf_P_debug_str_entry_s *mt2 = 0; struct Dwarf_P_debug_str_entry_s *retval = 0; struct Dwarf_P_debug_str_entry_s *re = 0; int res = 0; Dwarf_Unsigned adding_at_offset = 0; void **hashtab = 0; Dwarf_P_Section_Data sd = 0; struct Dwarf_P_Str_stats_s * stats = 0; switch (whash) { case _dwarf_hash_debug_str: hashtab = &dbg->de_debug_str_hashtab; sd = dbg->de_debug_str; stats = &dbg->de_stats.ps_strp; break; case _dwarf_hash_debug_line_str: hashtab = &dbg->de_debug_line_str_hashtab; sd = dbg->de_debug_line_str; stats = &dbg->de_stats.ps_line_strp; break; case _dwarf_hash_debug_str_sup: default: /* Not supported or unknown. */ _dwarf_p_error(dbg, error, DW_DLE_STRING_HASHTAB_IDENTITY_ERROR); return DW_DLV_ERROR; } res = make_debug_str_entry(dbg,&mt,name, slen,FALSE, 0, error); if (res != DW_DLV_OK) { return res; } /* We do a find as we do not want the string pointer passed in to be in the hash table, we want a pointer into the debug_str table in the hash table. */ retval = dwarf_tfind(mt,(void *const*)hashtab, _dwarf_debug_str_compare_func); if (retval) { stats->ps_strp_reused_count++; stats->ps_strp_reused_len += slen; re = *(struct Dwarf_P_debug_str_entry_s **)retval; *offset_in_debug_str = re->dse_table_offset; debug_str_entry_free_func(mt); return DW_DLV_OK; } /* We know the string is not in .debug_str data yet. Insert it into the big string table and get that offset. */ debug_str_entry_free_func(mt); mt = 0; res = insert_debug_str_data_string(dbg,name,slen,sd, &adding_at_offset, error); if (res != DW_DLV_OK) { return res; } /* The name is in the string table itself, so use that pointer and offset for the string. */ res = make_debug_str_entry(dbg,&mt2, 0, slen,TRUE,adding_at_offset,error); if (res != DW_DLV_OK) { return res; } retval = dwarf_tsearch(mt2, (void *)hashtab, _dwarf_debug_str_compare_func); if (!retval) { debug_str_entry_free_func(mt2); _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* This indirection is one of the surprises in using tsearch... */ re = *(struct Dwarf_P_debug_str_entry_s **)retval; if (re != mt2) { debug_str_entry_free_func(mt2); /* Found it in hash tab: illogical as the tsearch_find should have found it. */ _dwarf_p_error(dbg, error, DW_DLE_ILLOGICAL_TSEARCH); return DW_DLV_ERROR; } stats->ps_strp_count_debug_str++; stats->ps_strp_len_debug_str += slen; /* we added it to hash, do not free mt2 (which == re). */ *offset_in_debug_str = re->dse_table_offset; return DW_DLV_OK; } /* Returns DW_DLV_OK or DW_DLV_ERROR. */ int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr, Dwarf_P_Debug dbg, char *name, Dwarf_Error *error) { int form = dbg->de_debug_default_str_form; unsigned slen = strlen(name)+1; if (form == DW_FORM_string || slen <= dbg->de_dwarf_offset_size) { new_attr->ar_nbytes = slen; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, slen); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } dbg->de_stats.ps_str_count++; dbg->de_stats.ps_str_total_length += slen; strcpy(new_attr->ar_data, name); new_attr->ar_attribute_form = DW_FORM_string; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ return DW_DLV_OK; } if (form == DW_FORM_strp) { int uwordb_size = dbg->de_dwarf_offset_size; Dwarf_Unsigned offset_in_debug_str = 0; int res = 0; res = _dwarf_insert_or_find_in_debug_str(dbg,name, _dwarf_hash_debug_str,slen, &offset_in_debug_str,error); if(res != DW_DLV_OK) { return res; } new_attr->ar_attribute_form = form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; /* During transform to disk a symbol index will be applied. */ new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } { Dwarf_Unsigned du = offset_in_debug_str; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } return DW_DLV_OK; } _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM); return DW_DLV_ERROR; } /*------------------------------------------------------------------- Add AT_name attribute to die ---------------------------------------------------------------------*/ /* Original function. dwarf_add_AT_name_a() is the suggested alternative. */ Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_name_a(die, name, &a, error); if (res == DW_DLV_ERROR) { return (Dwarf_P_Attribute)(DW_DLV_BADADDR); } return a; } /* New December 2018. */ int dwarf_add_AT_name_a(Dwarf_P_Die die, char *name, Dwarf_P_Attribute *newattr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int res = 0; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_name; res = _dwarf_pro_set_string_attr(new_attr,die->di_dbg,name,error); if (res != DW_DLV_OK) { return DW_DLV_ERROR; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(die, new_attr); *newattr_out = new_attr; return DW_DLV_OK; } /*-------------------------------------------------------------------- Add AT_comp_dir attribute to die --------------------------------------------------------------------*/ Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_comp_dir_a(ownerdie, current_working_directory, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)(DW_DLV_BADADDR); } return a; } int dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int res = 0; if (ownerdie == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_comp_dir; res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg, current_working_directory,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned offset, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int uwordb_size = dbg->de_dwarf_offset_size; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_MIPS_fde; new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = offset; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } _dwarf_pro_add_at_to_die(die, new_attr); return DW_DLV_OK; } /* Sept 2016: returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned offset, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int uwordb_size = dbg->de_dwarf_offset_size; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_macro_info; new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; new_attr->ar_next = NULL; new_attr->ar_reloc_len = uwordb_size; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = offset; WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } _dwarf_pro_add_at_to_die(die, new_attr); return DW_DLV_OK; } /* Updates the list of attributes on this Dwarf_P_Die */ void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr) { if (die->di_last_attr) { /* Inserts new attr at the end */ die->di_last_attr->ar_next = attr; die->di_last_attr = attr; die->di_n_attr++; } else { die->di_n_attr = 1; die->di_attrs = die->di_last_attr = attr; } } dwarfutils-20200114/libdwarf/pro_die.h000066400000000000000000000046011361531463500175250ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* This struct holds the abbreviation table, before they are written on disk. Holds a linked list of abbreviations, each consisting of a bitmap for attributes and a bitmap for forms */ typedef struct Dwarf_P_Abbrev_s *Dwarf_P_Abbrev; struct Dwarf_P_Abbrev_s { Dwarf_Unsigned abb_idx; /* index of abbreviation */ Dwarf_Tag abb_tag; /* tag of die */ Dwarf_Ubyte abb_children; /* if children are present */ Dwarf_Unsigned *abb_attrs; /* holds names of attrs */ Dwarf_Unsigned *abb_forms; /* forms of attributes */ /* 0 but if DW_FORM_implicit_value is value */ Dwarf_Signed *abb_implicits; int abb_n_attr; /* num of attrs = # of forms */ Dwarf_P_Abbrev abb_next; }; /* used in pro_section.c */ int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned offset, Dwarf_Error * error); int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error); int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Unsigned offset, Dwarf_Error * error); int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr, Dwarf_P_Debug dbg, char *name, Dwarf_Error *error); /* adds an attribute to a die */ void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr); dwarfutils-20200114/libdwarf/pro_dnames.c000066400000000000000000000037701361531463500202340ustar00rootroot00000000000000/* Copyright 2018-2018 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_arange.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_dnames.h" #define FALSE 0 #define TRUE 1 int dwarf_force_debug_names(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_P_Dnames dn; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } dn = (Dwarf_P_Dnames) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Dnames_s)); if (dn == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (!dbg->de_dnames) { dbg->de_dnames = dn; } dn->dn_create_section = TRUE; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_dnames.h000066400000000000000000000051711361531463500202360ustar00rootroot00000000000000/* Copyright (C) 2018 David Anderson All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* The numbers here are almost all 32 bits. Not long long ever. In the public function interfaces we'll use Dwarf_Unsigned though, for call consistency with everything else. Here we use Dwarf_Unsigned to avoid having to even know what is or is not 32 bits. */ typedef Dwarf_Unsigned dn_type; struct Dwarf_P_Dnames_Head_s { Dwarf_Unsigned dh_unit_length; unsigned dh_version; dn_type dh_comp_unit_count; dn_type dh_local_type_unit_count; dn_type dh_foreign_type_unit_count; dn_type dh_bucket_count; dn_type dh_name_count; dn_type dh_abbrev_table_size; dn_type dh_augmentation_string_size; const char * dh_augmentation_string; }; struct Dwarf_P_Dnames_uarray_s { dn_type dne_allocated; dn_type dne_used; dn_type *dne_values; }; struct Dwarf_P_Dnames_sarray_s { dn_type dne_allocated; dn_type dne_used; Dwarf_Sig8 *dne_values; }; struct Dwarf_P_Dnames_s { Dwarf_Small dn_create_section; struct Dwarf_P_Dnames_Head_s dn_header; struct Dwarf_P_Dnames_uarray_s dn_cunit_offset; struct Dwarf_P_Dnames_uarray_s dn_tunit_offset; struct Dwarf_P_Dnames_sarray_s dn_sunit_sigs; struct Dwarf_P_Dnames_uarray_s dn_buckets; /* Hashes count applies to string offsets and entry offsets arrays too. */ struct Dwarf_P_Dnames_uarray_s dn_hashes; struct Dwarf_P_Dnames_uarray_s dn_string_offsets; struct Dwarf_P_Dnames_uarray_s dn_entry_pool; Dwarf_Small *dn_index_entry_pool; Dwarf_Small dn_index_entry_pool_size; Dwarf_Small dn_index_entry_pool_used; }; dwarfutils-20200114/libdwarf/pro_encode_nm.c000066400000000000000000000060641361531463500207130ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_encode_nm.h" #define MORE_BYTES 0x80 #define DATA_MASK 0x7f #define DIGIT_WIDTH 7 #define SIGN_BIT 0x40 /* Encode val as a leb128. This encodes it as an unsigned number. */ /* Return DW_DLV_ERROR or DW_DLV_OK. space to write leb number is provided by caller, with caller passing length. number of bytes used returned thru nbytes arg */ int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, char *space, int splen) { char *a; char *end = space + splen; a = space; do { unsigned char uc; if (a >= end) { return DW_DLV_ERROR; } uc = val & DATA_MASK; val >>= DIGIT_WIDTH; if (val != 0) { uc |= MORE_BYTES; } *a = uc; a++; } while (val); *nbytes = (int)(a - space); return DW_DLV_OK; } /* return DW_DLV_ERROR or DW_DLV_OK. ** space to write leb number is provided by caller, with caller ** passing length. ** number of bytes used returned thru nbytes arg ** encodes a signed number. */ int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, char *space, int splen) { char *str; Dwarf_Signed sign = -(value < 0); int more = 1; char *end = space + splen; str = space; do { unsigned char byte = value & DATA_MASK; value >>= DIGIT_WIDTH; if (str >= end) { return DW_DLV_ERROR; } /* Remaining chunks would just contain the sign bit, and this chunk has already captured at least one sign bit. */ if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) { more = 0; } else { byte |= MORE_BYTES; } *str = byte; str++; } while (more); *nbytes = (int)(str - space); return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_encode_nm.h000066400000000000000000000026271361531463500207210ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Bytes needed to encode a number. Not a tight bound, just a reasonable bound. */ #define ENCODE_SPACE_NEEDED (2*sizeof(Dwarf_Unsigned)) int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, char *space, int splen); int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, char *space, int splen); dwarfutils-20200114/libdwarf/pro_error.c000066400000000000000000000065101361531463500201110ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #ifdef HAVE_STDLIB_H #include /* for exit(), C89 malloc */ #endif /* HAVE_STDLIB_H */ #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" extern char *_dwarf_errmsgs[]; /* This function performs error handling as described in the libdwarf consumer document section 3. Dbg is the Dwarf_P_debug structure being processed. Error is a pointer to the pointer to the error descriptor that will be returned. Errval is an error code listed in dwarf_error.h. The error number may be retrieved from the Dwarf_Error by calling dwarf_errno(). The error string implied by the error number may be retrieved from the Dwarf_Error by calling dwarf_errmsg(). */ void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, Dwarf_Unsigned errval) { Dwarf_Error errptr; if (errval > DW_DLE_LAST) { /* We do not expect to ever see such an error number, DW_DLE_LO_USER is not used. */ fprintf(stderr,"ERROR VALUE: %lu - %s\n", (unsigned long) errval, "this error value is unknown to libdwarf."); } /* Allow NULL dbg on entry, since sometimes that can happen and we want to report the upper-level error, not this one. */ if (error != NULL) { errptr = (Dwarf_Error) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s)); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure\n"); abort(); } errptr->er_errval = (Dwarf_Signed) errval; *error = errptr; return; } if (dbg != NULL && dbg->de_errhand != NULL) { errptr = (Dwarf_Error) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s)); if (errptr == NULL) { fprintf(stderr, "Could not allocate Dwarf_Error structure\n"); abort(); } errptr->er_errval = (Dwarf_Signed) errval; dbg->de_errhand(errptr, dbg->de_errarg); return; } abort(); } dwarfutils-20200114/libdwarf/pro_error.h000066400000000000000000000030411361531463500201120ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Handle error passing in the name of the Dwarf_P_Debug User must supply {} around the macro. Putting the {} here leads to macro uses that don't look like C. The error argument to dwarf_error is hard coded here as 'error' */ #define DWARF_P_DBG_ERROR(dbg,errval,retval) \ _dwarf_p_error(dbg,error,errval); return(retval); struct Dwarf_Error_s { Dwarf_Signed er_errval; }; void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, Dwarf_Unsigned errval); dwarfutils-20200114/libdwarf/pro_expr.c000066400000000000000000000434761361531463500177520ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2019 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_expr.h" #define SIZEOFT16 2 #define SIZEOFT32 4 #define SIZEOFT64 8 /* This function creates a new expression struct that can be used to build up a location expression. */ Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_P_Expr ret_expr; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (NULL); } ret_expr = (Dwarf_P_Expr) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s)); if (ret_expr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return (NULL); } ret_expr->ex_dbg = dbg; return (ret_expr); } Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_Unsigned len = 0; int res = 0; res = dwarf_add_expr_gen_a(expr,opcode, val1,val2,&len,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return len; } int dwarf_add_expr_gen_a(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Unsigned *stream_length_out, Dwarf_Error * error) { /* 2* since used to concatenate 2 leb's below */ char encode_buffer[2 * ENCODE_SPACE_NEEDED]; char encode_buffer2[ENCODE_SPACE_NEEDED]; int res = 0; Dwarf_P_Debug dbg = 0; /* Give the buffer where the operands are first going to be assembled the largest alignment. */ Dwarf_Unsigned operand_buffer[10]; /* Size of the byte stream buffer that needs to be memcpy-ed. */ int operand_size = 0; /* Points to the byte stream for the first operand, and finally to the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ Dwarf_Small *operand = 0; /* Size of the byte stream for second operand. */ int operand2_size = 0; /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ Dwarf_Small *next_byte_ptr = 0; /* Offset past the last byte written into Dwarf_P_Expr_s. */ int next_byte_offset = 0; /* ***** BEGIN CODE ***** */ if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } dbg = expr->ex_dbg; if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } operand = NULL; operand_size = 0; switch (opcode) { case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: res = _dwarf_pro_encode_signed_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_regx: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: break; case DW_OP_addr: _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); return DW_DLV_ERROR; case DW_OP_const1u: case DW_OP_const1s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1); operand_size = 1; break; case DW_OP_const2u: case DW_OP_const2s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); operand_size = 2; break; case DW_OP_const4u: case DW_OP_const4s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32); operand_size = SIZEOFT32; break; case DW_OP_const8u: case DW_OP_const8s: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8); operand_size = 8; break; case DW_OP_constu: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_consts: res = _dwarf_pro_encode_signed_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_fbreg: res = _dwarf_pro_encode_signed_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_bregx: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; /* put this one directly into 'operand' at tail of prev value */ res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size, ((char *) operand) + operand_size, sizeof(encode_buffer2)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand_size += operand2_size; case DW_OP_dup: case DW_OP_drop: break; case DW_OP_pick: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, (const void *) &val1, sizeof(val1), 1); operand_size = 1; break; case DW_OP_over: case DW_OP_swap: case DW_OP_rot: case DW_OP_deref: case DW_OP_xderef: break; case DW_OP_deref_size: case DW_OP_xderef_size: operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, (const void *) &val1, sizeof(val1), 1); operand_size = 1; break; case DW_OP_abs: case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_neg: case DW_OP_not: case DW_OP_or: case DW_OP_plus: break; case DW_OP_plus_uconst: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: break; case DW_OP_le: case DW_OP_ge: case DW_OP_eq: case DW_OP_lt: case DW_OP_gt: case DW_OP_ne: break; case DW_OP_skip: case DW_OP_bra: /* FIX: unhandled! OP_bra, OP_skip! */ _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); return DW_DLV_ERROR; case DW_OP_piece: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; case DW_OP_nop: break; case DW_OP_push_object_address: /* DWARF3 */ break; case DW_OP_call2: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT16); operand_size = SIZEOFT16; break; case DW_OP_call4: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32); operand_size = SIZEOFT32; break; case DW_OP_call_ref: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), dbg->de_dwarf_offset_size); operand_size = dbg->de_dwarf_offset_size; break; case DW_OP_form_tls_address: /* DWARF3f */ break; case DW_OP_call_frame_cfa: /* DWARF3f */ break; case DW_OP_bit_piece: /* DWARF3f */ res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; /* put this one directly into 'operand' at tail of prev value */ res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size, ((char *) operand) + operand_size, sizeof(encode_buffer2)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } operand_size += operand2_size; break; default: _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); return DW_DLV_ERROR; } next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } next_byte_ptr = &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; *next_byte_ptr = opcode; next_byte_ptr++; if (operand) { memcpy(next_byte_ptr, operand, operand_size); } expr->ex_next_byte_offset = next_byte_offset; *stream_length_out = next_byte_offset; return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_addr_b(Dwarf_P_Expr expr, Dwarf_Unsigned addr, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int res = 0; res = dwarf_add_expr_addr_c(expr,addr,sym_index, &length,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return length; } int dwarf_add_expr_addr_c(Dwarf_P_Expr expr, Dwarf_Unsigned addr, Dwarf_Unsigned sym_index, Dwarf_Unsigned *stream_length_out, Dwarf_Error * error) { Dwarf_P_Debug dbg; Dwarf_Small *next_byte_ptr; Dwarf_Unsigned next_byte_offset; int upointer_size; if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return (DW_DLV_ERROR); } dbg = expr->ex_dbg; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } upointer_size = dbg->de_pointer_size; next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); return (DW_DLV_ERROR); } next_byte_ptr = &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; *next_byte_ptr = DW_OP_addr; next_byte_ptr++; WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr, sizeof(addr), upointer_size); if (expr->ex_reloc_offset != 0) { _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); return (DW_DLV_ERROR); } expr->ex_reloc_sym_index = sym_index; expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; expr->ex_next_byte_offset = next_byte_offset; *stream_length_out = next_byte_offset; return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned addr, Dwarf_Signed sym_index, Dwarf_Error * error) { Dwarf_Unsigned length = 0; int res = 0; Dwarf_P_Debug dbg = 0; if (sym_index < 0) { _dwarf_p_error(dbg, error, DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD); return DW_DLV_NOCOUNT; } res = dwarf_add_expr_addr_c(expr, (Dwarf_Unsigned)addr, (Dwarf_Unsigned)sym_index, &length,error); if (res != DW_DLV_OK) { return (Dwarf_Unsigned)DW_DLV_NOCOUNT; } return length; } Dwarf_Unsigned dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) { Dwarf_Unsigned l = 0; int res = 0; res = dwarf_expr_current_offset_a(expr,&l,error); if (res != DW_DLV_OK) { return (DW_DLV_NOCOUNT); } return l; } int dwarf_expr_current_offset_a(Dwarf_P_Expr expr, Dwarf_Unsigned * stream_length_out, Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } *stream_length_out = expr->ex_next_byte_offset; return DW_DLV_OK; } void dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return; } expr->ex_next_byte_offset=0; } Dwarf_Addr dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Unsigned * length, Dwarf_Error * error) { Dwarf_Small *addr = 0; int res = 0; res = dwarf_expr_into_block_a(expr,length,&addr,error); if (res != DW_DLV_OK) { return (DW_DLV_BADADDR); } return (Dwarf_Addr)(uintptr_t)addr; } int dwarf_expr_into_block_a(Dwarf_P_Expr expr, Dwarf_Unsigned * length, Dwarf_Small ** address, Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (length != NULL) *length = expr->ex_next_byte_offset; *address = &(expr->ex_byte_stream[0]); return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_expr.h000066400000000000000000000025051361531463500177430ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define MAXIMUM_LOC_EXPR_LENGTH 20 struct Dwarf_P_Expr_s { Dwarf_Small ex_byte_stream[MAXIMUM_LOC_EXPR_LENGTH]; Dwarf_P_Debug ex_dbg; Dwarf_Unsigned ex_next_byte_offset; Dwarf_Unsigned ex_reloc_sym_index; Dwarf_Unsigned ex_reloc_offset; }; dwarfutils-20200114/libdwarf/pro_finish.c000066400000000000000000000063231361531463500202420ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2018 David Anderson. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" /* This routine deallocates all memory, and does some finishing up This is the original version using a badly designed return value approach. Please use dwarf_producer_finish_a() instead. */ /*ARGSUSED*/ Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error * error) { int res = dwarf_producer_finish_a(dbg,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } /* This routine deallocates all memory, and does some finishing up. New September 2016. */ int dwarf_producer_finish_a(Dwarf_P_Debug dbg, Dwarf_Error * error) { if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } /* this frees all blocks, then frees dbg. */ _dwarf_p_dealloc_all(dbg); return DW_DLV_OK ; } /* FIXME: Add stats for debug_line_str. */ int dwarf_pro_get_string_stats(Dwarf_P_Debug dbg, Dwarf_Unsigned * str_count, Dwarf_Unsigned * str_total_length, Dwarf_Unsigned * strp_count_debug_str, Dwarf_Unsigned * strp_len_debug_str, Dwarf_Unsigned * strp_reused_count, Dwarf_Unsigned * strp_reused_len, Dwarf_Error * error) { struct Dwarf_P_Str_stats_s* ps = 0; if (!dbg) { _dwarf_p_error(dbg, error, DW_DLE_IA); return DW_DLV_ERROR; } if (dbg->de_version_magic_number !=PRO_VERSION_MAGIC ) { _dwarf_p_error(dbg, error, DW_DLE_VMM); return DW_DLV_ERROR; } *str_count = dbg->de_stats.ps_str_count; *str_total_length = dbg->de_stats.ps_str_total_length; ps = &dbg->de_stats.ps_strp; *strp_count_debug_str = ps->ps_strp_count_debug_str; *strp_len_debug_str = ps->ps_strp_len_debug_str; *strp_reused_count = ps->ps_strp_reused_count; *strp_reused_len = ps->ps_strp_reused_len; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_forms.c000066400000000000000000001466101361531463500201140ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2007-2013 David Anderson. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_die.h" #include "pro_expr.h" #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif /* Indicates no relocation needed. */ #define NO_ELF_SYM_INDEX 0 #ifdef WORDS_BIGENDIAN #define ASNAR(t,s,l) \ do { \ unsigned tbyte = sizeof(t) - l; \ t = 0; \ dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\ } while (0) #else /* LITTLE ENDIAN */ #define ASNAR(t,s,l) \ do { \ t = 0; \ dbg->de_copy_word(&t,&s[0],l); \ } while (0) #endif /* end LITTLE- BIG-ENDIAN */ #ifdef WORDS_BIGENDIAN #define ASNOUT(t,s,l) \ do { \ unsigned sbyte = 0; \ char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ sbyte = sizeof(s) - l; \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ } while (0) #else /* LITTLEENDIAN */ #define ASNOUT(t,s,l) \ do { \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ p = (const char *)(&s); \ memcpy(t,(const void *)p,l); \ dbg->de_copy_word(t,(const void *)p,l); \ } while (0) #endif /* ENDIANNESS */ #ifdef WORDS_BIGENDIAN #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + \ sizeof(dest) - length) < 0) { \ memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\ sizeof(dest) - length); \ } \ } while (0) #else /* LITTLE ENDIAN */ #define SIGN_EXTEND(dest, length) \ do { \ if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \ memcpy((char *)&dest+length, \ "\xff\xff\xff\xff\xff\xff\xff\xff", \ sizeof(dest) - length); \ } \ } while (0) #endif /* ! LITTLE_ENDIAN */ /* This function adds an attribute whose value is a target address to the given die. The attribute is given the name provided by attr. The address is given in pc_value. */ static int local_add_AT_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed form, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error); /* old interface */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; if (sym_index < 0) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } res = dwarf_add_AT_targ_address_c(dbg, ownerdie, attr, pc_value, (Dwarf_Unsigned) sym_index, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } /* New interface, replacing dwarf_add_AT_targ_address. Essentially just makes sym_index a Dwarf_Unsigned so for symbolic relocations it can be a full address. */ Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_targ_address_c(dbg, ownerdie,attr,pc_value,sym_index, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_targ_address_c(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; switch (attr) { case DW_AT_low_pc: case DW_AT_high_pc: /* added to support location lists */ /* no way to check that this is a loclist-style address though */ case DW_AT_location: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_frame_base: case DW_AT_segment: case DW_AT_static_link: case DW_AT_use_location: case DW_AT_vtable_elem_location: case DW_AT_const_value: /* Gcc can generate this as address. */ case DW_AT_entry_pc: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_addr, pc_value, sym_index,attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_ref_address_a(dbg,ownerdie, attr,pc_value,sym_index,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_ref_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; switch (attr) { case DW_AT_type: case DW_AT_import: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* FIXME: For DWARF3 and later this call is problematic as DW_FORM_ref_addr is really an offset in .debug_info , not an address. */ res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_ref_addr, pc_value, sym_index,attr_out, error); return res; } /* Make sure attribute types are checked before entering here. */ static int local_add_AT_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed form, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int upointer_size = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } upointer_size = dbg->de_pointer_size; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } /* attribute types have already been checked */ /* switch (attr) { ... } */ new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = form; new_attr->ar_nbytes = upointer_size; new_attr->ar_rel_symidx = sym_index; new_attr->ar_reloc_len = upointer_size; new_attr->ar_next = 0; if (sym_index != NO_ELF_SYM_INDEX) { new_attr->ar_rel_type = dbg->de_ptr_reloc; } else { new_attr->ar_rel_type = R_MIPS_NONE; } new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, upointer_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &pc_value, sizeof(pc_value), upointer_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* Pass in array (ie a pointer to) of Dwarf_Signed with input_array_length elements. A block of bytes is created with the sleb data in it. A pointer to the glob of bytes is returned through the output_block pointer and its length through output_block_len pointer. */ int dwarf_compress_integer_block_a( Dwarf_P_Debug dbg, Dwarf_Unsigned input_array_length, Dwarf_Signed * input_array, Dwarf_Unsigned *output_block_len, void ** output_block_returned, Dwarf_Error* error ) { Dwarf_Unsigned output_length_in_bytes = 0; char * output_block = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; unsigned u = 0; char * ptr = 0; int remain = 0; int result = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } /* First compress everything to find the total size. */ output_length_in_bytes = 0; for (u=0; ude_ar_data_attribute_form is data4 or data8 and dwarf4 changes the definition for such on DW_AT_high_pc. DWARF 3: the FORM here has no defined meaning for dwarf3. DWARF 4: the FORM here means that for DW_AT_high_pc the value is not a high address but is instead an offset from a (separate) DW_AT_low_pc. The intent for DWARF4 is that this is not a relocated address at all. Instead a simple offset. But this should NOT be called for a simple non-relocated offset. So do not call this with an attr of DW_AT_high_pc. Use dwarf_add_AT_unsigned_const() (for example) instead of dwarf_add_AT_dataref when the value is a simple offset . */ int dwarf_add_AT_dataref_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; /* TODO: Add checking here */ res = local_add_AT_address_a(dbg, ownerdie, attr, dbg->de_ar_data_attribute_form, pc_value, sym_index, attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; /* TODO: Add checking here */ res = local_add_AT_address_a(dbg, ownerdie, attr, dbg->de_ar_data_attribute_form, pc_value, sym_index, &a, error); if (res != DW_DLV_OK) { return((Dwarf_P_Attribute)DW_DLV_BADADDR); } return a; } Dwarf_P_Attribute dwarf_add_AT_block( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_Error *error) { int res = 0; Dwarf_P_Attribute new_attr = 0; res = dwarf_add_AT_block_a(dbg,ownerdie,attr, block_data,block_size,&new_attr,error); if (res != DW_DLV_OK) { return((Dwarf_P_Attribute)DW_DLV_BADADDR); } return new_attr; } int dwarf_add_AT_block_a( Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, Dwarf_P_Attribute* attr_out, Dwarf_Error *error) { Dwarf_P_Attribute new_attr = 0; int result = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int len_size = 0; char * attrdata = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } /* I don't mess with block1, block2, block4, not worth the effort */ /* So, encode the length into LEB128 */ result = _dwarf_pro_encode_leb128_nm(block_size, &len_size, encode_buffer,sizeof(encode_buffer)); if (result != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Allocate the new attribute */ new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* Fill in the attribute */ new_attr->ar_attribute = attr; new_attr->ar_attribute_form = DW_FORM_block; new_attr->ar_nbytes = len_size + block_size; new_attr->ar_next = 0; new_attr->ar_data = attrdata = (char *) _dwarf_p_get_alloc(dbg, len_size + block_size); if (new_attr->ar_data == NULL) { /* free the block we got earlier */ _dwarf_p_dealloc(dbg, (unsigned char *) new_attr); _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } /* write length and data to attribute data buffer */ memcpy(attrdata, encode_buffer, len_size); attrdata += len_size; memcpy(attrdata, block_data, block_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes whose value is an unsigned constant. It determines the size of the value field from the value of the constant. */ Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_unsigned_const_a(dbg, ownerdie,attr,value, &a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; Dwarf_Small size = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } switch (attr) { case DW_AT_ordering: case DW_AT_byte_size: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_inline: case DW_AT_language: case DW_AT_visibility: case DW_AT_virtuality: case DW_AT_accessibility: case DW_AT_address_class: case DW_AT_calling_convention: case DW_AT_encoding: case DW_AT_identifier_case: case DW_AT_MIPS_loop_unroll_factor: case DW_AT_MIPS_software_pipeline_depth: break; case DW_AT_decl_column: case DW_AT_decl_file: case DW_AT_decl_line: case DW_AT_const_value: case DW_AT_start_scope: case DW_AT_stride_size: /* DW_AT_bit_stride is DWARF3 name */ case DW_AT_count: case DW_AT_high_pc: /* DWARF5: allowing const udata high_pc */ case DW_AT_associated: case DW_AT_allocated: case DW_AT_upper_bound: case DW_AT_lower_bound: case DW_AT_call_file: case DW_AT_call_line: case DW_AT_data_member_location: case DW_AT_trampoline: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* Compute the number of bytes needed to hold constant. */ if (value <= UCHAR_MAX) { attr_form = DW_FORM_data1; size = 1; } else if (value <= USHRT_MAX) { attr_form = DW_FORM_data2; size = 2; } else if (value <= UINT_MAX) { attr_form = DW_FORM_data4; size = 4; } else { attr_form = DW_FORM_data8; size = 8; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ new_attr->ar_nbytes = size; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &value, sizeof(value), size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes whose value is an signed constant. It determines the size of the value field from the value of the constant. */ Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_signed_const_a(dbg, ownerdie,attr,value,&a,error); if(res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_signed_const_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; Dwarf_Small size = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } switch (attr) { case DW_AT_lower_bound: case DW_AT_upper_bound: case DW_AT_const_value: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_byte_size: case DW_AT_count: case DW_AT_byte_stride: case DW_AT_bit_stride: case DW_AT_allocated: case DW_AT_associated: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* Compute the number of bytes needed to hold constant. */ if (value >= SCHAR_MIN && value <= SCHAR_MAX) { attr_form = DW_FORM_data1; size = 1; } else if (value >= SHRT_MIN && value <= SHRT_MAX) { attr_form = DW_FORM_data2; size = 2; } else if (value >= INT_MIN && value <= INT_MAX) { attr_form = DW_FORM_data4; size = 4; } else { attr_form = DW_FORM_data8; size = 8; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ new_attr->ar_nbytes = size; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &value, sizeof(value), size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes whose value is a location expression. */ Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error * error) { int res = 0; Dwarf_P_Attribute a = 0; res = dwarf_add_AT_location_expr_a(dbg,ownerdie,attr, loc_expr,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } /* Preferred interface as of December 2018 */ int dwarf_add_AT_location_expr_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; char *len_str = 0; int len_size = 0; Dwarf_Unsigned block_size = 0; char *block_dest_ptr = 0; int do_len_as_int = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } if (loc_expr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL); return DW_DLV_ERROR; } if (loc_expr->ex_dbg != dbg) { _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD); return DW_DLV_ERROR; } block_size = loc_expr->ex_next_byte_offset; switch (attr) { case DW_AT_location: case DW_AT_string_length: case DW_AT_const_value: case DW_AT_use_location: case DW_AT_return_addr: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_static_link: case DW_AT_vtable_elem_location: case DW_AT_lower_bound: case DW_AT_upper_bound: case DW_AT_count: case DW_AT_associated: case DW_AT_allocated: case DW_AT_data_location: case DW_AT_byte_stride: case DW_AT_bit_stride: case DW_AT_byte_size: case DW_AT_bit_size: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } /* Compute the number of bytes needed to hold constant. This is a bit fake in that the size will never be particularly large and always < UINT_MAX. */ if (block_size <= UCHAR_MAX) { attr_form = DW_FORM_block1; len_size = 1; do_len_as_int = 1; } else if (block_size <= USHRT_MAX) { attr_form = DW_FORM_block2; len_size = 2; do_len_as_int = 1; } else if (block_size <= UINT_MAX) { attr_form = DW_FORM_block4; len_size = 4; do_len_as_int = 1; } else { attr_form = DW_FORM_block; res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } len_str = (char *) encode_buffer; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = attr_form; new_attr->ar_reloc_len = dbg->de_pointer_size; if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) { new_attr->ar_rel_type = dbg->de_ptr_reloc; } else { new_attr->ar_rel_type = R_MIPS_NONE; } new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; new_attr->ar_rel_offset = loc_expr->ex_reloc_offset + len_size; new_attr->ar_nbytes = block_size + len_size; new_attr->ar_next = 0; new_attr->ar_data = block_dest_ptr = (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } if (do_len_as_int) { WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size, sizeof(block_size), len_size); } else { /* Is uleb number form, DW_FORM_block. See above. */ memcpy(block_dest_ptr, len_str, len_size); } block_dest_ptr += len_size; if (block_size > sizeof(loc_expr->ex_byte_stream)) { /* ex_byte_stream has a fixed max value. */ _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); return DW_DLV_ERROR; } memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds attributes of reference class. The references here are local CU references, not DW_FORM_ref_addr. The offset field is 4 bytes for 32-bit objects, and 8-bytes for 64-bit objects. Otherdie is the that is referenced by ownerdie. For reference attributes, the ar_data and ar_nbytes are not needed. Instead, the ar_ref_die points to the other die, and its di_offset value is used as the reference value. */ static int _dwarf_add_AT_reference_internal_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, int check_otherdie, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } if (check_otherdie && (otherdie == NULL)) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } switch (attr) { case DW_AT_count: case DW_AT_sibling: case DW_AT_byte_size: case DW_AT_bit_offset: case DW_AT_bit_size: case DW_AT_discr: case DW_AT_import: case DW_AT_common_reference: case DW_AT_containing_type: case DW_AT_default_value: case DW_AT_lower_bound: case DW_AT_bit_stride: /* Early name is DW_AT_stride_size */ case DW_AT_upper_bound: case DW_AT_abstract_origin: case DW_AT_base_types: case DW_AT_friend: case DW_AT_namelist_item: case DW_AT_priority: case DW_AT_specification: case DW_AT_type: case DW_AT_allocated: case DW_AT_associated: case DW_AT_byte_stride: case DW_AT_extension: case DW_AT_trampoline: case DW_AT_small: case DW_AT_object_pointer: case DW_AT_signature: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form; new_attr->ar_nbytes = dbg->de_dwarf_offset_size; new_attr->ar_reloc_len = dbg->de_dwarf_offset_size; new_attr->ar_ref_die = otherdie; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_next = 0; /* Add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* Allowing the target die to be identified later. */ int dwarf_add_AT_reference_c(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 0, attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 1, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)DW_DLV_BADADDR; } return a; } /* Allowing the target die to be identified later. */ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 0, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)DW_DLV_BADADDR; } return a; } int dwarf_fixup_AT_reference_die(Dwarf_P_Debug dbg, Dwarf_Half attrnum, Dwarf_P_Die sourcedie, Dwarf_P_Die targetdie, Dwarf_Error *error) { Dwarf_P_Attribute a = 0; Dwarf_P_Attribute cur = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } for(cur = sourcedie->di_attrs; cur; cur = cur->ar_next) { if (attrnum == cur->ar_attribute) { a = cur; break; } } if(!a) { _dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_NULL); return DW_DLV_ERROR; } if(a->ar_ref_die) { _dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_DUP); return DW_DLV_ERROR; } a->ar_ref_die = targetdie; return DW_DLV_OK; } /* This function adds attributes of the flag class. */ Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_flag_a(dbg,ownerdie,attr,flag, &a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_flag_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Small flag, Dwarf_P_Attribute * attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attr; new_attr->ar_attribute_form = DW_FORM_flag; new_attr->ar_nbytes = 1; new_attr->ar_reloc_len = 0; /* not used */ new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, 1); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, &flag, 1); /* Add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* This function adds values of attributes belonging to the string class. */ Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_string_a(dbg, ownerdie,attr,string,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_string_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int res = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } switch (attr) { /* See also: pro_section.c for same strings attribute list. */ case DW_AT_comp_dir: case DW_AT_const_value: case DW_AT_linkage_name:/* DWARF5, but ok for any version really.*/ case DW_AT_MIPS_abstract_name: case DW_AT_MIPS_linkage_name: case DW_AT_name: case DW_AT_producer: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); return DW_DLV_ERROR; } break; } new_attr->ar_attribute = attr; res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg, string,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, char *string_value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_const_value_string_a(ownerdie, string_value,&a,error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute) DW_DLV_BADADDR; } return a; } int dwarf_add_AT_const_value_string_a(Dwarf_P_Die ownerdie, char *string_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; int res = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = DW_AT_const_value; res = _dwarf_pro_set_string_attr(new_attr,dbg, string_value,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_with_ref_sig8_a(ownerdie, attrnum,sig8_in,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_with_ref_sig8_a(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_P_Attribute * attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_ref_sig8; new_attr->ar_nbytes = sizeof (Dwarf_Sig8); new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, sizeof(Dwarf_Sig8)); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data,sig8_in,sizeof(Dwarf_Sig8)); new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_producer_a(ownerdie, producer_string,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute)DW_DLV_BADADDR); } return a; } int dwarf_add_AT_producer_a(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; int res = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = DW_AT_producer; res = _dwarf_pro_set_string_attr(new_attr,dbg, producer_string,error); if (res != DW_DLV_OK) { return res; } /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { int res = 0; res = dwarf_add_AT_any_value_sleb_a( ownerdie,DW_AT_const_value, signed_value, attr_out, error); return res; } Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_any_value_sleb_a( ownerdie,DW_AT_const_value, signed_value, &a, error); if (res != DW_DLV_OK) { return (Dwarf_P_Attribute)DW_DLV_BADADDR; } return a; } int dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *outattr, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_P_Debug dbg = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_implicit_const; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; /* The value will go in the abbrev section. Not the DIE. Encoding done with abbrev generation. */ new_attr->ar_data = 0; new_attr->ar_nbytes = 0; new_attr->ar_implicit_const = signed_value; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *outattr = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_Error * error) { int res = 0; Dwarf_P_Attribute a = 0; res = dwarf_add_AT_any_value_sleb_a(ownerdie, attrnum, signed_value, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int leb_size = 0; Dwarf_P_Debug dbg = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_sdata; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, leb_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, encode_buffer, leb_size); new_attr->ar_nbytes = leb_size; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } /* AT_const_value, uleb */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_Error * error) { Dwarf_P_Attribute a =0; int res = 0; res = dwarf_add_AT_any_value_uleb_a( ownerdie,DW_AT_const_value, unsigned_value, &a, error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_const_value_unsignedint_a(Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { return dwarf_add_AT_any_value_uleb_a( ownerdie,DW_AT_const_value, unsigned_value, attr_out, error); } int dwarf_add_AT_data16(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Form_Data16 * ptr_to_val, Dwarf_P_Attribute * attr_return, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int val_size = sizeof(Dwarf_Form_Data16); Dwarf_P_Debug dbg = 0; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_data16; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, val_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, ptr_to_val->fd_data, val_size); new_attr->ar_nbytes = val_size; _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_return = new_attr; return DW_DLV_OK; } Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_Error * error) { Dwarf_P_Attribute a = 0; int res = 0; res = dwarf_add_AT_any_value_uleb_a(ownerdie, attrnum,unsigned_value,&a,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Attribute) DW_DLV_BADADDR); } return a; } int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_P_Attribute * attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int leb_size; Dwarf_P_Debug dbg = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int res; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_udata; new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ new_attr->ar_next = 0; res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, leb_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } memcpy(new_attr->ar_data, encode_buffer, leb_size); new_attr->ar_nbytes = leb_size; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); *attr_out = new_attr; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_frame.c000066400000000000000000000567051361531463500200650ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2017 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_encode_nm.h" #include "pro_frame.h" #define SIZEOFT16 2 #define SIZEOFT32 4 #define SIZEOFT64 8 #ifdef WORDS_BIGENDIAN #define ASNOUT(t,s,l) \ do { \ unsigned sbyte = 0; \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ sbyte = sizeof(s) - l; \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ } while (0) #else /* LITTLEENDIAN */ #define ASNOUT(t,s,l) \ do { \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)p,l); \ } while (0) #endif /* ENDIANNESS */ static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm inst); /* This function adds a cie struct to the debug pointer. Its in the form of a linked list. augmenter: string reps augmentation (implementation defined) code_align: alignment of code data_align: alignment of data init_bytes: byts having initial instructions init_n_bytes: number of bytes of initial instructions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small return_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; res = dwarf_add_frame_cie_a(dbg,augmenter, code_align, data_align,return_reg,init_bytes, init_n_bytes, &index,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return index; } int dwarf_add_frame_cie_a(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small code_align, Dwarf_Small data_align, Dwarf_Small return_reg, Dwarf_Ptr init_bytes, Dwarf_Unsigned init_n_bytes, Dwarf_Unsigned * cie_index_out, Dwarf_Error * error) { Dwarf_P_Cie curcie; char *tmpaug = 0; if (dbg->de_frame_cies == NULL) { dbg->de_frame_cies = (Dwarf_P_Cie) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); if (dbg->de_frame_cies == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } curcie = dbg->de_frame_cies; dbg->de_n_cie = 1; dbg->de_last_cie = curcie; } else { curcie = dbg->de_last_cie; curcie->cie_next = (Dwarf_P_Cie) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); if (curcie->cie_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } curcie = curcie->cie_next; dbg->de_n_cie++; dbg->de_last_cie = curcie; } curcie->cie_version = 1; if (dbg->de_output_version > 2) { curcie->cie_version = dbg->de_output_version; } else { /* V2 dwarf has debug_frame as version 1, there is no 2 used in this section. */ curcie->cie_version = 1; } tmpaug = (char *)_dwarf_p_get_alloc(dbg,strlen(augmenter)+1); if (!tmpaug) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } strcpy(tmpaug,augmenter); curcie->cie_aug = tmpaug; curcie->cie_code_align = code_align; curcie->cie_data_align = data_align; curcie->cie_ret_reg = return_reg; curcie->cie_inst = (char *) init_bytes; curcie->cie_inst_bytes = (long) init_n_bytes; curcie->cie_next = NULL; *cie_index_out = dbg->de_n_cie; return DW_DLV_OK; } /* This functions adds a fde struct to the debug pointer. Its in the form of a linked list. die: subprogram/function die corresponding to this fde cie: cie referred to by this fde, obtained from call to add_frame_cie() routine. virt_addr: beginning address code_len: length of code reps by the fde */ /*ARGSUSED*/ /* pretend all args used */ Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; res = dwarf_add_frame_fde_c(dbg, fde, die, cie, virt_addr, code_len, symidx, 0, 0,&index, error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return index; } /* There is no dwarf_add_frame_fde_a */ /*ARGSUSED10*/ Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned symidx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; res = dwarf_add_frame_fde_c(dbg,fde,die,cie, virt_addr,code_len,symidx,symidx_of_end, offset_from_end_sym,&index,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return index; } /* New December 2018 */ int dwarf_add_frame_fde_c(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned symidx_of_end, Dwarf_Addr offset_from_end_sym, Dwarf_Unsigned *index_to_fde, UNUSEDARG Dwarf_Error * error) { Dwarf_P_Fde curfde; fde->fde_die = die; fde->fde_cie = (long) cie; fde->fde_initloc = virt_addr; fde->fde_r_symidx = symidx; fde->fde_addr_range = code_len; fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET; fde->fde_exception_table_symbol = 0; fde->fde_end_symbol_offset = offset_from_end_sym; fde->fde_end_symbol = symidx_of_end; fde->fde_dbg = dbg; curfde = dbg->de_last_fde; if (curfde == NULL) { dbg->de_frame_fdes = fde; dbg->de_last_fde = fde; dbg->de_n_fde = 1; } else { curfde->fde_next = fde; dbg->de_last_fde = fde; dbg->de_n_fde++; } *index_to_fde = dbg->de_n_fde; return DW_DLV_OK; } /* This function adds information to an fde. The fde is linked into the linked list of fde's maintained in the Dwarf_P_Debug structure. dbg: The debug descriptor. fde: The fde to be added. die: subprogram/function die corresponding to this fde cie: cie referred to by this fde, obtained from call to add_frame_cie() routine. virt_addr: beginning address code_len: length of code reps by the fde symidx: The symbol id of the symbol wrt to which relocation needs to be performed for 'virt_addr'. offset_into_exception_tables: The start of exception tables for this function (indicated as an offset into the exception tables). A value of -1 indicates that there is no exception table entries associated with this function. exception_table_symbol: The symbol id of the section for exception tables wrt to which the offset_into_exception_tables will be relocated. */ Dwarf_Unsigned dwarf_add_frame_info(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Error * error) { Dwarf_Unsigned fde_index = 0; int res = 0; res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, code_len, symidx, /* end_symbol */ 0, /* offset_from_end */ 0, offset_into_exception_tables, exception_table_symbol, &fde_index, error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return fde_index; } /*ARGSUSED*/ /* pretend all args used */ Dwarf_Unsigned dwarf_add_frame_info_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned end_symidx, Dwarf_Unsigned offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, UNUSEDARG Dwarf_Error * error) { Dwarf_Unsigned fde_index = 0; int res = 0; res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, code_len, symidx, end_symidx, offset_from_end_symbol, offset_into_exception_tables, exception_table_symbol, &fde_index, error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return fde_index; } int dwarf_add_frame_info_c(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Unsigned virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Unsigned end_symidx, Dwarf_Unsigned offset_from_end_symbol, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, Dwarf_Unsigned *fde_index_out, UNUSEDARG Dwarf_Error * error) { Dwarf_P_Fde curfde; fde->fde_die = die; fde->fde_cie = (long) cie; fde->fde_initloc = virt_addr; fde->fde_r_symidx = symidx; fde->fde_addr_range = code_len; fde->fde_offset_into_exception_tables = offset_into_exception_tables; fde->fde_exception_table_symbol = exception_table_symbol; fde->fde_end_symbol_offset = offset_from_end_symbol; fde->fde_end_symbol = end_symidx; fde->fde_dbg = dbg; curfde = dbg->de_last_fde; if (curfde == NULL) { dbg->de_frame_fdes = fde; dbg->de_last_fde = fde; dbg->de_n_fde = 1; } else { curfde->fde_next = fde; dbg->de_last_fde = fde; dbg->de_n_fde++; } *fde_index_out = dbg->de_n_fde; return DW_DLV_OK; } /* This is an alternate to inserting frame instructions one instruction at a time. But use either this or instruction level, not both in one fde. */ int dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes, Dwarf_Error *error) { if (len == 0) { return DW_DLV_OK; } if (fde->fde_block || fde->fde_inst) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK, DW_DLV_ERROR); } fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len); memcpy(fde->fde_block,ibytes,len); fde->fde_inst_block_size = len; fde->fde_n_bytes += len; return DW_DLV_OK; } /* Create a new fde. */ Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_P_Fde fde = 0; int res = 0; res = dwarf_new_fde_a(dbg,&fde,error); if (res != DW_DLV_OK) { return (Dwarf_P_Fde) DW_DLV_BADADDR; } return fde; } int dwarf_new_fde_a(Dwarf_P_Debug dbg, Dwarf_P_Fde *fde_out, Dwarf_Error * error) { Dwarf_P_Fde fde; fde = (Dwarf_P_Fde) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); if (fde == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, DW_DLV_ERROR); } fde->fde_dbg = dbg; fde->fde_uwordb_size = dbg->de_dwarf_offset_size; *fde_out = fde; return DW_DLV_OK; } /* Add a cfe_offset instruction to the fde passed in. */ Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error * error) { int res = 0; res = dwarf_fde_cfa_offset_a(fde,reg,offset,error); if (res != DW_DLV_OK) { return (Dwarf_P_Fde) DW_DLV_BADADDR; } return fde; } int dwarf_fde_cfa_offset_a(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, Dwarf_Error * error) { Dwarf_Ubyte opc, regno; char *ptr = 0; Dwarf_P_Frame_Pgm curinst; int nbytes = 0; int res = 0; char buff1[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, DW_DLV_ERROR); } opc = DW_CFA_offset; regno = reg; if (regno & 0xc0) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,DW_DLV_ERROR); } opc = opc | regno; /* lower 6 bits are register number */ curinst->dfp_opcode = opc; res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return DW_DLV_OK; } /* Generic routine to add opcode to fde instructions. val1 and val2 are parameters whose interpretation depends on the 'op'. This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as these ops normally are addresses or (DW_CFA_set_loc) or code lengths (DW_DVA_advance_loc*) and such must be represented with relocations and symbol indices for DW_DLC_SYMBOLIC_RELOCATIONS. This does not treat all DW_CFA instructions yet. For certain operations a val? value must be signed (though passed in as unsigned here). Does not check that the frame version is 3(for dwarf3) or 4 (for dwarf4) or 5 when applying operations that are only valid for particular versions. */ Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { int res = 0; res = dwarf_add_fde_inst_a(fde,op,val1,val2,error); if (res != DW_DLV_OK) { return ((Dwarf_P_Fde) DW_DLV_BADADDR); } return fde; } /* December 2018. A more sensible return value. */ int dwarf_add_fde_inst_a(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; int nbytes = 0; int nbytes1 = 0; int nbytes2 = 0; Dwarf_Ubyte db = 0; Dwarf_Half dh = 0; Dwarf_Unsigned du = 0; char *ptr = 0; int res = 0; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; /* This is a hack telling the code when to transform a value to a signed leb number. */ int signed_second = 0; int signed_first = 0; buff1[0] = 0; buff2[0] = 0; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); return DW_DLV_ERROR; } switch (op) { case DW_CFA_advance_loc: { if (val1 <= 0x3f) { db = val1; op |= db; } else if (!(val1& ~0xff)) { op = DW_CFA_advance_loc1; db = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, 1); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy((void *) ptr, (const void *) &db, 1); nbytes = 1; } else if (!(val1& (~(Dwarf_Unsigned)0xffff))) { if (sizeof(dh) < SIZEOFT16) { _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } op = DW_CFA_advance_loc2; dh = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT16); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } /* No byte swapping, assuming running at target endianness. */ ASNOUT((void *) ptr, dh, SIZEOFT16); nbytes = SIZEOFT16; } else if (!(val1& ~(Dwarf_Unsigned)0xffffffff)) { if (sizeof(du) < SIZEOFT32) { _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } op = DW_CFA_advance_loc4; du = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT32); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ASNOUT((void *) ptr, du, SIZEOFT32); nbytes = SIZEOFT32; } else { if (sizeof(du) < SIZEOFT64) { _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } op = DW_CFA_MIPS_advance_loc8; du = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT64); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } /* No byte swapping, assuming running at target endianness. */ ASNOUT((void *) ptr, du, SIZEOFT64); nbytes = SIZEOFT64; } break; } case DW_CFA_offset: if (val1 <= MAX_6_BIT_VALUE) { db = val1; op |= db; res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); } else { op = DW_CFA_offset_extended; goto two_leb; } break; case DW_CFA_offset_extended_sf: /* DWARF3 */ signed_second = 1; goto two_leb; case DW_CFA_offset_extended: goto two_leb; case DW_CFA_undefined: case DW_CFA_same_value: goto one_leb; case DW_CFA_val_offset: goto two_leb; case DW_CFA_val_offset_sf: signed_second = 1; goto two_leb; case DW_CFA_def_cfa_sf: signed_second = 1; goto two_leb; case DW_CFA_register: case DW_CFA_def_cfa: two_leb: res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } if (!signed_second) { res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); } else { Dwarf_Signed val2s = val2; res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2, buff2, sizeof(buff2)); } if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); nbytes = nbytes1 + nbytes2; break; case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ signed_first = 1; goto one_leb; case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_offset: one_leb: if (!signed_first) { res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, buff1, sizeof(buff1)); } else { Dwarf_Signed val1s = val1; res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes, buff1, sizeof(buff1)); } if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); break; case DW_CFA_def_cfa_expression: /* DWARF3 */ /* FIXME: argument is dwarf expr, not handled yet. */ case DW_CFA_expression: /* DWARF3 */ /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. FIXME: not handled yet. */ case DW_CFA_val_expression: /* DWARF3f */ /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. FIXME: not handled yet. */ default: _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); return DW_DLV_ERROR; } curinst->dfp_opcode = op; curinst->dfp_args = ptr; curinst->dfp_nbytes = nbytes; curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); return DW_DLV_OK; } /* Instructions are added to an fde in the form of a linked list. This function manages the linked list. */ void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst) { if (fde->fde_last_inst) { fde->fde_last_inst->dfp_next = curinst; fde->fde_last_inst = curinst; fde->fde_n_inst++; fde->fde_n_bytes += (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); } else { fde->fde_last_inst = curinst; fde->fde_inst = curinst; fde->fde_n_inst = 1; fde->fde_n_bytes = (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); } } dwarfutils-20200114/libdwarf/pro_frame.h000066400000000000000000000073631361531463500200660ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Largest register value that can be coded into the opcode since there are only 6 bits in the register field. */ #define MAX_6_BIT_VALUE 0x3f /* This struct holds debug_frame instructions */ typedef struct Dwarf_P_Frame_Pgm_s *Dwarf_P_Frame_Pgm; struct Dwarf_P_Frame_Pgm_s { Dwarf_Ubyte dfp_opcode; /* opcode - includes reg # */ char * dfp_args; /* operands */ Dwarf_Unsigned dfp_nbytes; /* number of bytes in args */ Dwarf_P_Frame_Pgm dfp_next; }; /* This struct has cie related information. Used to gather data from user program, and later to transform to disk form */ struct Dwarf_P_Cie_s { Dwarf_Half cie_version; /* augmentation. The string is an strdup() copy and on freeing the Dwarf_P_Cie the string must be freed. */ char *cie_aug; Dwarf_Ubyte cie_code_align; /* alignment of code */ Dwarf_Sbyte cie_data_align; Dwarf_Ubyte cie_ret_reg; /* return register # */ char *cie_inst; /* initial instruction */ long cie_inst_bytes; /* no of init_inst */ Dwarf_P_Cie cie_next; }; /* producer fields */ struct Dwarf_P_Fde_s { Dwarf_Unsigned fde_unused1; /* function/subr die for this fde */ Dwarf_P_Die fde_die; /* index to asso. cie */ Dwarf_Unsigned fde_cie; /* Address of first location of the code this frame applies to If fde_end_symbol non-zero, this represents the offset from the symbol indicated by fde_r_symidx */ Dwarf_Addr fde_initloc; /* Relocation symbol for address of the code this frame applies to. */ Dwarf_Unsigned fde_r_symidx; /* Bytes of instr for this fde, if known */ Dwarf_Unsigned fde_addr_range; /* linked list of instructions we will put in fde. */ Dwarf_P_Frame_Pgm fde_inst; /* number of instructions in fde */ Dwarf_Signed fde_n_inst; /* number of bytes of inst in fde */ Dwarf_Signed fde_n_bytes; /* offset into exception table for this function. */ Dwarf_Signed fde_offset_into_exception_tables; /* The symbol for the exception table elf section. */ Dwarf_Unsigned fde_exception_table_symbol; /* pointer to last inst */ Dwarf_P_Frame_Pgm fde_last_inst; Dwarf_P_Fde fde_next; /* The symbol and offset of the end symbol. When fde_end_symbol is non-zero we must represent the */ Dwarf_Addr fde_end_symbol_offset; Dwarf_Unsigned fde_end_symbol; int fde_uwordb_size; Dwarf_P_Debug fde_dbg; /* If fde_block is non-null, then it is the set of instructions. so we should use it rather than fde_inst. */ Dwarf_Unsigned fde_inst_block_size; void *fde_block; }; dwarfutils-20200114/libdwarf/pro_funcs.c000066400000000000000000000041221361531463500200730ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_section.h" /* This function adds another function name to the list of function names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_funcname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *function_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, function_name, dwarf_snk_funcname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_funcname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *function_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, function_name, dwarf_snk_funcname, error); return res; } dwarfutils-20200114/libdwarf/pro_incl.h000066400000000000000000000053031361531463500177110ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2012 David Anderson. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Windows specific header files */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #ifdef DWARF_WITH_LIBELF #ifdef HAVE_ELF_H /* does includes of elf.h libelf.h here. */ #include #elif defined(HAVE_LIBELF_H) /* On one platform without elf.h this gets Elf32_Rel type defined (a required type). */ #include /* Consider the other known directory too */ #elif defined(HAVE_LIBELF_LIBELF_H) #include #endif /* HAVE_ELF_H or HAVE_LIBELF*H */ #endif /* DWARF_WITH_LIBELF */ #if defined(sun) #include #include #endif /* The target address is given: the place in the source integer is to be determined. */ #ifdef WORDS_BIGENDIAN #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word(dest, \ ((const char *)source) +(srclength)-(len_out),\ (len_out)) ; \ } #else /* LITTLE ENDIAN */ #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((const char *)source) , \ (len_out)) ; \ } #endif /* BIG- LITTLE-ENDIAN */ #if defined(sparc) && defined(sun) #define REL32 Elf32_Rela #define REL64 Elf64_Rela #define REL_SEC_PREFIX ".rela" #else #define REL32 Elf32_Rel #define REL64 Elf64_Rel #define REL_SEC_PREFIX ".rel" #endif dwarfutils-20200114/libdwarf/pro_init.c000066400000000000000000000352261361531463500177310ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2017 David Anderson, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_line.h" #include "memcpy_swap.h" #include "pro_section.h" /* for MAGIC_SECT_NO */ #include "pro_reloc_symbolic.h" #include "pro_reloc_stream.h" #include "dwarf_tsearch.h" #include "dwarfstring.h" #define IS_64BITPTR(dbg) ((dbg)->de_flags & DW_DLC_POINTER64 ? 1 : 0) #define ISA_IA64(dbg) ((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0) struct isa_relocs_s { const char *name_; int reloc32_; int reloc64_; int segrel_; /* only used if IRIX */ }; #ifndef TRUE #define TRUE 1 #endif /*TRUE*/ #ifndef FALSE #define FALSE 0 #endif /*FALSE*/ /* Some of these may be the wrong relocation for DWARF relocations. FIXME. Most will be unusable without additional effort as they have not been tested. */ #define R_MIPS_32 2 #define R_MIPS_64 18 #define R_MIPS_SCN_DISP 32 #define R_386_32 1 #define R_386_64 0 /* impossible */ #define R_X86_64_32 10 #define R_X86_64_64 1 #define R_SPARC_UA32 23 #define R_SPARC_UA64 54 #define R_ARM_ABS32 2 #define R_ARM_ABS64 0 /* impossible */ #define R_AARCH64_ABS32 258 #define R_AARCH64_ABS64 257 #define R_IA64_DIR32LSB 0x25 #define R_IA64_DIR64LSB 0x27 #define R_PPC_REL32 26 #define R_PPC_REL64 44 #define R_PPC64_REL32 R_PPC_REL32 #define R_PPC64_REL64 44 static struct isa_relocs_s isa_relocs[] = { {"irix", R_MIPS_32,R_MIPS_64,R_MIPS_SCN_DISP}, {"mips", R_MIPS_32,R_MIPS_64,0}, {"x86", R_386_32, R_386_64,0}, {"x86_64",R_X86_64_32,R_X86_64_64,0}, {"ia64", R_IA64_DIR32LSB,R_IA64_DIR64LSB,0}, {"arm64", R_AARCH64_ABS32,R_AARCH64_ABS64,0}, {"arm", R_ARM_ABS32,R_ARM_ABS64,0}, {"ppc", R_PPC_REL32,R_PPC_REL64,0}, {"ppc64", R_PPC64_REL32,R_PPC64_REL64,0}, {"sparc", R_SPARC_UA32,R_SPARC_UA64,0}, /* The last entry MUST be all zeros. */ {0,0,0,0} }; static int common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, const char *dwarf_version, const char *extrainfo, int *error_ret); /* This function sets up a new dwarf producing region. flags: Indicates type of access method, one of DW_DLC* macros func(): Used to create a new object file, a call back function errhand(): Error Handler provided by user errarg: Argument to errhand() error: returned error value */ /* We want the following to have an elf section number that matches 'nothing' */ static struct Dwarf_P_Section_Data_s init_sect = { MAGIC_SECT_NO, 0, 0, 0, 0 }; static struct Dwarf_P_Section_Data_s init_sect_debug_str = { MAGIC_SECT_NO, 0, 0, 0, 0 }; static struct Dwarf_P_Section_Data_s init_sect_debug_line_str = { MAGIC_SECT_NO, 0, 0, 0, 0 }; /* New April 2014. Replaces all previous producer init functions. It adds a string to select the relevant ABI/ISA and a string defining the selected DWARF version to output. There are some overlaps between the flags and the ISA/ABI string choices. ( it is neither strictly ABI nor strictly ISA name, but a useful name for both.) Generally, the function inteprets these in a tolerant fashion, so inconsistencies in the selections are not noticed...but they may have a surprising effect. The extra string is a way to allow new options without changing the interface. The idea is the caller might supply a list of such things as one string, comma-separated. The interface is not intended to allow spaces or tabs in the names, so don't do that :-) If no extra strings are needed (none are defined initially) then pass a NULL pointer or an empty string as the 'extra' parameter. */ int dwarf_producer_init(Dwarf_Unsigned flags, Dwarf_Callback_Func func, Dwarf_Handler errhand, Dwarf_Ptr errarg, void * user_data, const char *isa_name, /* See isa_reloc_s. */ const char *dwarf_version, /* V2 V3 V4 or V5. */ const char *extra, /* Extra input strings, comma separated. */ Dwarf_P_Debug *dbg_returned, Dwarf_Error * error) { Dwarf_P_Debug dbg = 0; int res = 0; int err_ret = 0; dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Debug_s)); if (dbg == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s)); /* For the time being */ if (func == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, DW_DLV_ERROR); } dbg->de_callback_func = func; dbg->de_errhand = errhand; dbg->de_errarg = errarg; dbg->de_user_data = user_data; res = common_init(dbg, flags,isa_name,dwarf_version, extra,&err_ret); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, err_ret, DW_DLV_ERROR); } *dbg_returned = dbg; return DW_DLV_OK; } int dwarf_pro_set_default_string_form(Dwarf_P_Debug dbg, int form, UNUSEDARG Dwarf_Error * error) { if (form != DW_FORM_string && form != DW_FORM_strp) { _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM); return DW_DLV_ERROR; } dbg->de_debug_default_str_form = form; return DW_DLV_OK; } static int set_reloc_numbers(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Unsigned flags, const char *abiname) { struct isa_relocs_s *isap = 0; if (!abiname) { return DW_DLV_NO_ENTRY; } for(isap = &isa_relocs[0]; ;isap++) { if (!isap->name_) { /* No more names known. Never found the one we wanted. */ return DW_DLV_NO_ENTRY; } if (!strcmp(abiname,isap->name_)) { if (dbg->de_pointer_size == 4) { dbg->de_ptr_reloc = isap->reloc32_; } else { dbg->de_ptr_reloc = isap->reloc64_; } if (dbg->de_dwarf_offset_size == 4) { dbg->de_offset_reloc = isap->reloc32_; } else { dbg->de_offset_reloc = isap->reloc64_; } /* segrel only meaningful for IRIX, otherwise harmless, unused. */ dbg->de_exc_reloc = isap->segrel_; return DW_DLV_OK; } } /* UNREACHED */ } /* This is the Daniel J Bernstein hash function originally posted to Usenet news. http://en.wikipedia.org/wiki/List_of_hash_functions or http://stackoverflow.com/questions/10696223/reason-for-5381-number-in-djb-hash-function). See Also DWARF5 Section 7.33 */ static DW_TSHASHTYPE _dwarf_string_hashfunc(const char *str) { DW_TSHASHTYPE up = 0; DW_TSHASHTYPE hash = 5381; int c = 0; /* Extra parens suppress warning about assign in test. */ while ((c = *str++)) { hash = hash * 33 + c ; } up = hash; return up; } static DW_TSHASHTYPE key_simple_string_hashfunc(const void *keyp) { struct Dwarf_P_debug_str_entry_s* mt = (struct Dwarf_P_debug_str_entry_s*) keyp; const char *str = 0; if (mt->dse_has_table_offset) { /* ASSERT: mt->dse_dbg->de_debug_str->ds_data not zero. */ str = (const char *)mt->dse_dbg->de_debug_str->ds_data + mt->dse_table_offset; } else { /* ASSERT: dse_name != 0 */ str = (const char *)mt->dse_name; } return _dwarf_string_hashfunc(str); } static int common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, const char *dwarf_version, const char *extra, int *err_ret) { unsigned int k = 0; int res = 0; dbg->de_version_magic_number = PRO_VERSION_MAGIC; dbg->de_n_debug_sect = 0; dbg->de_debug_sects = &init_sect; dbg->de_debug_str = &init_sect_debug_str; dbg->de_debug_line_str = &init_sect_debug_line_str; dbg->de_current_active_section = &init_sect; dbg->de_flags = flags; /* DW_DLC_POINTER32 assumed. */ dbg->de_pointer_size = 4; /* Standard DWARF 64bit offset, length field 12 bytes */ dbg->de_dwarf_offset_size = 4; dbg->de_elf_offset_size = 4; dbg->de_64bit_extension = 0; dbg->de_big_endian = (dbg->de_flags&DW_DLC_TARGET_BIGENDIAN)? TRUE:FALSE; /* DW_DLC_POINTER64 is identical to DW_DLC_SIZE_64 */ if(dbg->de_flags & DW_DLC_POINTER64) { dbg->de_pointer_size = 8; } if(dbg->de_flags & DW_DLC_OFFSET64) { dbg->de_pointer_size = 8; dbg->de_dwarf_offset_size = 4; dbg->de_64bit_extension = 0; /* When dwarf_offset_size == 8 then for standard dwarf set de_64bit_extension to 1. */ dbg->de_elf_offset_size = 8; } else { if(dbg->de_flags & DW_DLC_IRIX_OFFSET64) { dbg->de_pointer_size = 8; dbg->de_big_endian = TRUE; dbg->de_dwarf_offset_size = 8; dbg->de_64bit_extension = 0; dbg->de_elf_offset_size = 8; } } if(abiname && (!strcmp(abiname,"irix"))) { dbg->de_irix_exc_augmentation = 1; } else { dbg->de_irix_exc_augmentation = 0; } /* We must set reloc numbers even if doing symbolic relocations because we use the numbers up until we are generating debug. A zero is interpreted as no relocations. So ensure we have real relocations. */ res = set_reloc_numbers(dbg,flags,abiname); if (res != DW_DLV_OK) { *err_ret = DW_DLE_BAD_ABINAME; return DW_DLV_ERROR; } dbg->de_output_version = 2; if(dwarf_version) { if (!strcmp(dwarf_version,"V2")) { dbg->de_output_version = 2; } else if (!strcmp(dwarf_version,"V3")) { dbg->de_output_version = 3; } else if (!strcmp(dwarf_version,"V4")) { dbg->de_output_version = 4; } else if (!strcmp(dwarf_version,"V5")) { dbg->de_output_version = 5; } else { *err_ret = DW_DLE_VERSION_STAMP_ERROR; return DW_DLV_ERROR; } } _dwarf_init_default_line_header_vals(dbg); res = _dwarf_log_extra_flagstrings(dbg,extra,err_ret); if (res == DW_DLV_ERROR) { return res; } if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { dbg->de_relocation_record_size = sizeof(struct Dwarf_Relocation_Data_s); } else { /* This is only going to work when the HOST == TARGET, surely? */ #ifdef DWARF_WITH_LIBELF #if HAVE_ELF64_GETEHDR dbg->de_relocation_record_size = ((dbg->de_pointer_size == 8)? sizeof(REL64) : sizeof(REL32)); #else dbg->de_relocation_record_size = sizeof(REL32); #endif #else /* DWARF_WITH_LIBELF */ *err_ret = DW_DLE_NO_STREAM_RELOC_SUPPORT; return DW_DLV_ERROR; #endif /* DWARF_WITH_LIBELF */ } /* For .debug_str creation. */ dwarf_initialize_search_hash(&dbg->de_debug_str_hashtab, key_simple_string_hashfunc,0); dbg->de_debug_default_str_form = DW_FORM_string; dwarf_initialize_search_hash(&dbg->de_debug_line_str_hashtab, key_simple_string_hashfunc,0); if (dbg->de_dwarf_offset_size == 8) { if (dbg->de_output_version <= 3) { dbg->de_ar_data_attribute_form = DW_FORM_data8; } else { dbg->de_ar_data_attribute_form = DW_FORM_sec_offset; } dbg->de_ar_ref_attr_form = DW_FORM_ref8; } else { if (dbg->de_output_version <= 3) { dbg->de_ar_data_attribute_form = DW_FORM_data4; } else { dbg->de_ar_data_attribute_form = DW_FORM_sec_offset; } dbg->de_ar_ref_attr_form = DW_FORM_ref4; } if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { dbg->de_relocate_by_name_symbol = _dwarf_pro_reloc_name_symbolic; dbg->de_relocate_pair_by_symbol = _dwarf_pro_reloc_length_symbolic; dbg->de_transform_relocs_to_disk = _dwarf_symbolic_relocs_to_disk; } else { #ifdef DWARF_WITH_LIBELF if (IS_64BITPTR(dbg)) { dbg->de_relocate_by_name_symbol = _dwarf_pro_reloc_name_stream64; } else { dbg->de_relocate_by_name_symbol = _dwarf_pro_reloc_name_stream32; } dbg->de_relocate_pair_by_symbol = 0; dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk; #else /* DWARF_WITH_LIBELF */ *err_ret = DW_DLE_NO_STREAM_RELOC_SUPPORT; return DW_DLV_ERROR; #endif /* DWARF_WITH_LIBELF */ } for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k]; prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK; } /* First assume host, target same endianness FIXME */ dbg->de_same_endian = 1; dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; #ifdef WORDS_BIGENDIAN /* host is big endian, so what endian is target? */ if (flags & DW_DLC_TARGET_LITTLEENDIAN) { dbg->de_same_endian = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #else /* little endian */ /* host is little endian, so what endian is target? */ if (flags & DW_DLC_TARGET_BIGENDIAN) { dbg->de_same_endian = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #endif /* !WORDS_BIGENDIAN */ return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_line.c000066400000000000000000000373531361531463500177200ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_encode_nm.h" #include "pro_line.h" static int _dwarf_pro_add_line_entry(Dwarf_P_Debug, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned symidx, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Ubyte opc, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error); /* Add a entry to the line information section file_index: index of file in file entries, obtained from add_file_entry() call. This function actually calls _dwarf_pro_add_line_entry(), with an extra parameter, the opcode. Done so that interface calls dwarf_lne_set_address() and dwarf_lne_end_sequence() can use this internal routine. The return value of the original interfaces is really signed. Bogus interface. With dwarf_add_line_entry_c the interface is corrected. */ Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error) { Dwarf_Unsigned retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, is_bb_begin, opc, isepilbeg,isprolend,isa,discriminator, error); if (retval != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } int dwarf_add_line_entry_c(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error) { int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, is_bb_begin, opc, isepilbeg,isprolend,isa,discriminator, error); return retval; } /* The return value is really signed. Bogus interface.*/ Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned line_no, Dwarf_Signed col_no, /* Wrong, should be unsigned. */ Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Error * error) { int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; Dwarf_Bool isepilbeg = 0; Dwarf_Bool isprolend = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, is_bb_begin, opc, isepilbeg, isprolend, isa, discriminator, error); if (retval != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } void _dwarf_init_default_line_header_vals(Dwarf_P_Debug dbg) { dbg->de_line_inits.pi_linetable_version = dbg->de_output_version; dbg->de_line_inits.pi_default_is_stmt = /* is false pro_line.h */ DEFAULT_IS_STMT; dbg->de_line_inits.pi_minimum_instruction_length = /* is 1 or 4 depending on ifdefs in pro_line.h */ MIN_INST_LENGTH; dbg->de_line_inits.pi_maximum_operations_per_instruction = /* Assuming the instruction set is not VLIW, used in the line table */ 1; dbg->de_line_inits.pi_opcode_base = /* is 10 in pro_line.h but should be 13 in DWARF3 and later. */ OPCODE_BASE; dbg->de_line_inits.pi_line_base = /* is -1 in pro_line.h */ LINE_BASE; dbg->de_line_inits.pi_line_range = /* is 4 in pro_line.h */ LINE_RANGE; /* Applies to line table and everywhere else for a CU. */ dbg->de_line_inits.pi_address_size = dbg->de_pointer_size; /* Assuming no segments. */ dbg->de_line_inits.pi_segment_selector_size = 0; dbg->de_line_inits.pi_segment_size = 0; } /* Ask to emit DW_LNE_set_address opcode explicitly. Used by be to emit start of a new .text section, or to force a relocated address into debug line information entry. */ Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error * error) { int res = 0; res = dwarf_lne_set_address_a(dbg,offs,symidx,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } int dwarf_lne_set_address_a(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error * error) { int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned file_index = 0; Dwarf_Unsigned line_no = 0; Dwarf_Signed col_no = 0; Dwarf_Bool is_stmt = 0; Dwarf_Bool is_bb = 0; Dwarf_Bool isepilbeg = 0; Dwarf_Bool isprolend = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; opc = DW_LNE_set_address; retval = _dwarf_pro_add_line_entry(dbg, file_index, offs, symidx, line_no, col_no, is_stmt, is_bb, opc, isepilbeg, isprolend, isa, discriminator, error); return retval; } /* Ask to emit end_seqence opcode. Used normally at the end of a compilation unit. Can also be used in the middle if there are gaps in the region described by the code address. */ Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr end_address, Dwarf_Error * error) { int retval = 0; retval = dwarf_lne_end_sequence_a(dbg,end_address,error); if (retval != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return 0; } int dwarf_lne_end_sequence_a(Dwarf_P_Debug dbg, Dwarf_Addr end_address, Dwarf_Error * error) { Dwarf_Ubyte opc = 0; int retval = 0; Dwarf_Unsigned file_index = 0; Dwarf_Unsigned symidx = 0; Dwarf_Unsigned line_no = 0; Dwarf_Bool is_stmt = 0; Dwarf_Bool is_bb = 0; Dwarf_Signed col_no = 0;/* Wrong, should be unsigned. */ Dwarf_Bool isepilbeg = 0; Dwarf_Bool isprolend = 0; Dwarf_Unsigned isa = 0; Dwarf_Unsigned discriminator = 0; opc = DW_LNE_end_sequence; retval = _dwarf_pro_add_line_entry(dbg, file_index, end_address, symidx, line_no, col_no, is_stmt, is_bb, opc, isepilbeg, isprolend, isa, discriminator, error); return retval; } /* As of December 2018 this returns DW_DLV_OK, DW_DLV_ERROR not 0, DW_DLV_NOCOUNT*/ /* Add an entry in the internal list of lines mantained by producer. Opc indicates if an opcode needs to be generated, rather than just an entry in the matrix. During opcodes generation time, these opcodes will be used. */ static int _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned symidx, Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Ubyte opc, Dwarf_Bool isepilbeg, Dwarf_Bool isprolend, Dwarf_Unsigned isa, Dwarf_Unsigned discriminator, Dwarf_Error * error) { if (dbg->de_lines == NULL) { dbg->de_lines = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (dbg->de_lines == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } dbg->de_last_line = dbg->de_lines; _dwarf_pro_reg_init(dbg,dbg->de_lines); } else { dbg->de_last_line->dpl_next = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (dbg->de_last_line->dpl_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } dbg->de_last_line = dbg->de_last_line->dpl_next; _dwarf_pro_reg_init(dbg,dbg->de_last_line); } dbg->de_last_line->dpl_address = code_address; dbg->de_last_line->dpl_file = (unsigned long) file_index; dbg->de_last_line->dpl_line = (unsigned long) line_no; dbg->de_last_line->dpl_column = (unsigned long) col_no; dbg->de_last_line->dpl_is_stmt = is_stmt_begin; dbg->de_last_line->dpl_basic_block = is_bb_begin; dbg->de_last_line->dpl_opc = opc; dbg->de_last_line->dpl_r_symidx = symidx; dbg->de_last_line->dpl_prologue_end = isprolend; dbg->de_last_line->dpl_epilogue_begin = isepilbeg; dbg->de_last_line->dpl_isa = isa; dbg->de_last_line->dpl_discriminator = discriminator; return DW_DLV_OK; } /* Add a directory declaration to the debug_line section. Stored in linked list. */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Error * error) { Dwarf_Unsigned index = 0; int res = 0; /* DW_DLV_NOCOUNT on error, de_n_inc_dirs on success. */ res = dwarf_add_directory_decl_a(dbg,name,&index,error); if (res != DW_DLV_OK) { return (Dwarf_Unsigned)DW_DLV_NOCOUNT; } return index; } int dwarf_add_directory_decl_a(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned *index_in_directories, Dwarf_Error * error) { if (dbg->de_inc_dirs == NULL) { dbg->de_inc_dirs = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_inc_dirs == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_ERROR); } dbg->de_last_inc_dir = dbg->de_inc_dirs; dbg->de_n_inc_dirs = 1; } else { dbg->de_last_inc_dir->dfe_next = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_last_inc_dir->dfe_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_ERROR); } dbg->de_last_inc_dir = dbg->de_last_inc_dir->dfe_next; dbg->de_n_inc_dirs++; } dbg->de_last_inc_dir->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); if (dbg->de_last_inc_dir->dfe_name == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_ERROR); } strcpy(dbg->de_last_inc_dir->dfe_name, name); dbg->de_last_inc_dir->dfe_next = NULL; *index_in_directories = dbg->de_n_inc_dirs; return DW_DLV_OK; } /* Add a file entry declaration to the debug_line section. Stored in linked list. The data is immediately encoded as leb128 and stored in Dwarf_P_F_Entry_s struct. */ Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Error * error) { Dwarf_Unsigned filecount = 0; int res = 0; res = dwarf_add_file_decl_a(dbg,name,dir_idx, time_mod,length,&filecount,error); if (res != DW_DLV_OK) { return DW_DLV_NOCOUNT; } return filecount; } int dwarf_add_file_decl_a(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, Dwarf_Unsigned length, Dwarf_Unsigned *file_entry_count_out, Dwarf_Error * error) { Dwarf_P_F_Entry cur; char *ptr = 0; int nbytes_idx, nbytes_time, nbytes_len; char buffidx[ENCODE_SPACE_NEEDED]; char bufftime[ENCODE_SPACE_NEEDED]; char bufflen[ENCODE_SPACE_NEEDED]; int res = 0; if (dbg->de_file_entries == NULL) { dbg->de_file_entries = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_file_entries == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, DW_DLV_ERROR); } cur = dbg->de_file_entries; dbg->de_last_file_entry = cur; dbg->de_n_file_entries = 1; } else { cur = dbg->de_last_file_entry; cur->dfe_next = (Dwarf_P_F_Entry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (cur->dfe_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, DW_DLV_ERROR); } cur = cur->dfe_next; dbg->de_last_file_entry = cur; dbg->de_n_file_entries++; } cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); if (cur->dfe_name == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } strcpy((char *) cur->dfe_name, name); res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx, buffidx, sizeof(buffidx)); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY impossible */ DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time, bufftime, sizeof(bufftime)); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY impossible */ DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len, bufflen, sizeof(bufflen)); if (res != DW_DLV_OK) { /* DW_DLV_NO_ENTRY impossible */ DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR,DW_DLV_ERROR); } cur->dfe_args = (char *) _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len); if (cur->dfe_args == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } ptr = cur->dfe_args; memcpy((void *) ptr, buffidx, nbytes_idx); ptr += nbytes_idx; memcpy((void *) ptr, bufftime, nbytes_time); ptr += nbytes_time; memcpy((void *) ptr, bufflen, nbytes_len); cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len; cur->dfe_next = NULL; *file_entry_count_out = dbg->de_n_file_entries; return DW_DLV_OK; } /* Initialize a row of the matrix for line numbers, meaning initialize the struct corresponding to it */ void _dwarf_pro_reg_init(Dwarf_P_Debug dbg, Dwarf_P_Line cur_line) { cur_line->dpl_address = 0; cur_line->dpl_file = 1; cur_line->dpl_line = 1; cur_line->dpl_column = 0; cur_line->dpl_is_stmt = dbg->de_line_inits.pi_default_is_stmt; cur_line->dpl_basic_block = false; cur_line->dpl_next = NULL; cur_line->dpl_prologue_end = 0; cur_line->dpl_epilogue_begin = 0; cur_line->dpl_isa = 0; cur_line->dpl_discriminator = 0; cur_line->dpl_opc = 0; } dwarfutils-20200114/libdwarf/pro_line.h000066400000000000000000000077311361531463500177220ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2017 David Anderson All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #define DW_LINE_VERSION2 2 #define DW_LINE_VERSION3 3 #define DW_LINE_VERSION4 4 #if defined(__i386) || defined(__x86_64) #define MIN_INST_LENGTH 1 #elif defined(__s390__) || defined(__s390x__) /* Correct value unknown. This is temporary as we need a better way to set this (in dwarfgen). This at least works for dwarfgen testing at this point, avoids an error. */ #define MIN_INST_LENGTH 1 #else /* 1 is not necessarily the most efficient (space-wise) for various architectures, but will allow line tables to be generated without error if the input expects the min length to be 1. When using dwarfgen the setting should be that of the output arch, not the host (unless the two essentially match). */ #define MIN_INST_LENGTH 4 #endif #define DEFAULT_IS_STMT false /* line base and range are temporarily defines. They need to be calculated later. */ #define LINE_BASE -1 #define LINE_RANGE 4 #define OPCODE_BASE 10 /* DWARF2. 13 in DWARF3, 4, 5 */ #define MAX_OPCODE 255 /* This struct holds file or include_dir entries for the statement prologue. Defined in pro_line.h */ struct Dwarf_P_F_Entry_s { char *dfe_name; Dwarf_P_F_Entry dfe_next; /* DWARF 2,3,4, files only not inc dirs */ char *dfe_args; /* has dir index, time of modification, length in bytes. Encodes as leb128 */ int dfe_nbytes; /* number of bytes in args */ /* Dwarf5 Use or not depends on file_name_entry_format actually used. */ unsigned dfe_index; Dwarf_Unsigned dfe_timestamp; unsigned dfe_size; unsigned char dfe_md5[16]; }; /* Struct holding line number information for each of the producer line entries */ struct Dwarf_P_Line_s { /* code address */ Dwarf_Addr dpl_address; /* file index, index into file entry */ Dwarf_Unsigned dpl_file; /* line number */ Dwarf_Unsigned dpl_line; /* column number */ Dwarf_Unsigned dpl_column; /* whether its a beginning of a stmt */ Dwarf_Ubyte dpl_is_stmt; /* whether its a beginning of basic blk */ Dwarf_Ubyte dpl_basic_block; /* used to store opcodes set_address, and end_seq */ Dwarf_Ubyte dpl_opc; /* Used only for relocations. Has index of symbol relative to which relocation has to be done (the S part in S + A) */ Dwarf_Unsigned dpl_r_symidx; Dwarf_P_Line dpl_next; Dwarf_Ubyte dpl_prologue_end; /* DWARF3 */ Dwarf_Ubyte dpl_epilogue_begin; /* DWARF3 */ Dwarf_Unsigned dpl_isa; /* DWARF3 */ Dwarf_Unsigned dpl_discriminator; /* DWARF4 */ }; /* to initialize state machine registers, definition in pro_line.c */ void _dwarf_pro_reg_init(Dwarf_P_Debug dbg,Dwarf_P_Line); void _dwarf_init_default_line_header_vals(Dwarf_P_Debug dbg); dwarfutils-20200114/libdwarf/pro_log_extra_flag_strings.c000066400000000000000000000227661361531463500235210ustar00rootroot00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "dwarfstring.h" /* in the producer_init extras string. Handles hex and decimal. Not octal. Used a very small number of times, so performance not an issue. */ /* err will be used...shortly */ static int translatetosigned(char *s,Dwarf_Signed *v, UNUSEDARG int *err) { unsigned char *cp = (unsigned char *)s; unsigned char *digits = (unsigned char *)s; int signmult = 1; Dwarf_Signed l = 0; if (*cp == '0' && (*(cp+1) == 'x'|| (*(cp+1) == 'X'))) { digits += 2; cp = digits; for( ; *cp; cp++) { l = l << 4; switch (*cp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': l += (*cp - '0'); break; case 'a': case 'A': l += 10; break; case 'b': case 'B': l += 11; break; case 'c': case 'C': l += 12; break; case 'd': case 'D': l += 13; break; case 'e': case 'E': l += 14; break; case 'f': case 'F': l += 15; break; default: #ifdef TESTING printf("ERROR in hex string \"%s\" " "bad character 0x%x, line %d %s\n", s,*cp,__LINE__,__FILE__); #endif *err = DW_DLE_HEX_STRING_ERROR; return DW_DLV_ERROR; } } *v = l; return DW_DLV_OK; } else if (*cp == '-') { signmult = -1; digits ++; } cp = digits; for( ; *cp; cp++) { l = l * 10; switch (*cp) { case '9': case '8': case '7': case '6': case '5': case '4': case '3': case '2': case '1': case '0': l += (*cp - '0'); break; default: #ifdef TESTING printf("ERROR in decimal string \"%s\", " "bad character 0x%x, line %d %s\n", s,*cp,__LINE__,__FILE__); #endif *err = DW_DLE_DECIMAL_STRING_ERROR; return DW_DLV_ERROR; } } *v = signmult * l; return DW_DLV_OK; } static int update_named_field(Dwarf_P_Debug dbg, dwarfstring *cmsname,dwarfstring *cmsvalue, int *err) { char *name = dwarfstring_string(cmsname); char *value = dwarfstring_string(cmsvalue); Dwarf_Signed v = 0; int res; res = translatetosigned(value,&v,err); if (res != DW_DLV_OK) { return res; } if ( dwarfstring_strlen(cmsvalue) == 0) { return DW_DLV_NO_ENTRY; } /* The value in the string is a number, but always quite a small number. */ if (!strcmp(name,"default_is_stmt")) { dbg->de_line_inits.pi_default_is_stmt = (unsigned)v; } else if (!strcmp(name,"minimum_instruction_length")) { dbg->de_line_inits.pi_minimum_instruction_length = (unsigned)v; } else if (!strcmp(name,"maximum_operations_per_instruction")) { dbg->de_line_inits.pi_maximum_operations_per_instruction = (unsigned)v; } else if (!strcmp(name,"opcode_base")) { dbg->de_line_inits.pi_opcode_base = (unsigned)v; } else if (!strcmp(name,"line_base")) { dbg->de_line_inits.pi_line_base = (int)v; } else if (!strcmp(name,"line_range")) { dbg->de_line_inits.pi_line_range = (int)v; } else if (!strcmp(name,"linetable_version")) { dbg->de_line_inits.pi_linetable_version = (unsigned)v; dbg->de_output_version = (unsigned)v; } else if (!strcmp(name,"segment_selector_size")) { dbg->de_line_inits.pi_segment_selector_size = (unsigned)v; } else if (!strcmp(name,"segment_size")) { dbg->de_line_inits.pi_segment_size = (unsigned)v; } else if (!strcmp(name,"address_size")) { dbg->de_line_inits.pi_address_size = (unsigned)v; dbg->de_pointer_size = (unsigned)v; } else { #ifdef TESTING printf("ERROR due to unknown string \"%s\", line %d %s\n", name,__LINE__,__FILE__); #endif *err = DW_DLE_PRO_INIT_EXTRAS_UNKNOWN; return DW_DLV_ERROR; } return DW_DLV_OK; } static int update_named_value(Dwarf_P_Debug dbg, dwarfstring*cms, int *err) { char * str = dwarfstring_string(cms); char *cp = str; char * value_start = 0; dwarfstring cmsname; dwarfstring cmsvalue; unsigned slen = 0; int res = 0; dwarfstring_constructor(&cmsname); dwarfstring_constructor(&cmsvalue); for ( ; *cp && *cp != '=' && *cp != ' '; cp++) { } if (! *cp) { /* Ignore this, it's empty or has no =value clause */ dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); /* FIXME *err */ return DW_DLV_NO_ENTRY; } if (*cp == ' ') { /* Trailing spaces, no = is an input bug. */ dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); #ifdef TESTING printf("ERROR due to trailing spaces before = in \"%s\", line %d %s\n", cp,__LINE__,__FILE__); #endif *err = DW_DLE_PRO_INIT_EXTRAS_ERR; return DW_DLV_ERROR; } slen = cp - str; dwarfstring_append_length(&cmsname,str,slen); cp++; value_start = cp; for ( ; *cp && *cp != ' '; cp++) { } slen = cp - value_start; if (slen) { dwarfstring_append_length(&cmsvalue,value_start,slen); } else { dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); return DW_DLV_NO_ENTRY; } res = update_named_field(dbg,&cmsname,&cmsvalue,err); dwarfstring_destructor(&cmsname); dwarfstring_destructor(&cmsvalue); return res; } static int find_next_comma(const char *base,const char **nextcomma) { const char *cp = base; for( ; *cp ; ++cp) { if (*cp == ',') { *nextcomma = cp; return DW_DLV_OK; } } /* Encountered end of string, should not happen as we ensured a last string. */ *nextcomma = cp; return DW_DLV_OK; } /* Publicly visible in in libdwarf to enable easy testing of the code here. */ int _dwarf_log_extra_flagstrings(Dwarf_P_Debug dbg, const char *extra, int *err) { int res = 0; const char *nextcharloc = 0; const char *nextcomma = 0; dwarfstring cms; dwarfstring input; if (!extra || !*extra) { /* Nothing to do. */ return DW_DLV_NO_ENTRY; } dwarfstring_constructor(&cms); dwarfstring_constructor(&input); dwarfstring_append(&input,(char *)extra); /* Adding a final , simplifies logic here. */ dwarfstring_append(&input,(char *)","); nextcharloc = dwarfstring_string(&input); while (1) { dwarfstring_reset(&cms); find_next_comma(nextcharloc,&nextcomma); { unsigned len = nextcomma - nextcharloc; if (len > 0) { dwarfstring_append_length(&cms,(char *)nextcharloc, len); res = update_named_value(dbg,&cms,err); if (res == DW_DLV_ERROR) { dwarfstring_destructor(&cms); dwarfstring_destructor(&input); return res; } } else {/* else empty, */ } if (!(nextcomma[1])) { dwarfstring_destructor(&cms); dwarfstring_destructor(&input); return DW_DLV_OK; } nextcharloc = nextcomma+1; } } dwarfstring_destructor(&input); dwarfstring_destructor(&cms); return DW_DLV_OK; } /* ===== end Initialization using string=value,string2=valu2 (etc) */ dwarfutils-20200114/libdwarf/pro_macinfo.c000066400000000000000000000326651361531463500204060ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_macinfo.h" /* I don't much like the error strings this generates, since like the rest of libdwarf they are simple strings with no useful numbers in them. But that's not something I can fix without more work than I have time for right now. davea Nov 94. */ /* these are gross overestimates of the number of ** bytes needed to store a number in LEB form. ** Just estimates, and since blocks are reasonable size, ** the end-block waste is small. ** Of course the waste is NOT present on disk. */ #define COMMAND_LEN ENCODE_SPACE_NEEDED #define LINE_LEN ENCODE_SPACE_NEEDED #define BASE_MACINFO_MALLOC_LEN 2048 static int libdwarf_compose_begin(Dwarf_P_Debug dbg, int code, size_t maxlen, int *compose_error_type) { unsigned char *nextchar; struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; if (curblk == 0) { struct dw_macinfo_block_s *newb; size_t len; /* initial allocation */ size_t blen = BASE_MACINFO_MALLOC_LEN; if (blen < maxlen) { blen = 2 * maxlen; } len = sizeof(struct dw_macinfo_block_s) + blen; newb = (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); if (!newb) { *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; return DW_DLV_ERROR; } newb->mb_data = (char *) newb + sizeof(struct dw_macinfo_block_s); newb->mb_avail_len = blen; newb->mb_used_len = 0; newb->mb_macinfo_data_space_len = blen; dbg->de_first_macinfo = newb; dbg->de_current_macinfo = newb; curblk = newb; } else if (curblk->mb_avail_len < maxlen) { struct dw_macinfo_block_s *newb; size_t len; /* no space left in block: allocate a new block */ size_t blen = dbg->de_current_macinfo->mb_macinfo_data_space_len * 2; if (blen < maxlen) { blen = 2 * maxlen; } len = sizeof(struct dw_macinfo_block_s) + blen; newb = (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); if (!newb) { *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; return DW_DLV_ERROR; } newb->mb_data = (char *) newb + sizeof(struct dw_macinfo_block_s); newb->mb_avail_len = blen; newb->mb_used_len = 0; newb->mb_macinfo_data_space_len = blen; dbg->de_first_macinfo->mb_next = newb; dbg->de_current_macinfo = newb; curblk = newb; } /* now curblk has enough room */ dbg->de_compose_avail = curblk->mb_avail_len; dbg->de_compose_used_len = curblk->mb_used_len; nextchar = (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); *nextchar = code; dbg->de_compose_avail--; ++dbg->de_compose_used_len; return DW_DLV_OK; } static void libdwarf_compose_add_string(Dwarf_P_Debug dbg, const char *string, size_t len) { struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; unsigned char *nextchar; nextchar = (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); len += 1; /* count the null terminator */ memcpy(nextchar, string, len); dbg->de_compose_avail -= len; dbg->de_compose_used_len += len; return; } static int libdwarf_compose_add_line(Dwarf_P_Debug dbg, Dwarf_Unsigned line, int *compose_error_type) { struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; unsigned char *nextchar; int res; int nbytes; nextchar = (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); /* Put the created leb number directly into the macro buffer If dbg->de_compose_avail is > INT_MAX this will not work as the 'int' will look negative to _dwarf_pro_encode_leb128_nm! */ res = _dwarf_pro_encode_leb128_nm(line, &nbytes, (char *) nextchar, (int) dbg->de_compose_avail); if (res != DW_DLV_OK) { *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; return DW_DLV_ERROR; } dbg->de_compose_avail -= nbytes; dbg->de_compose_used_len += nbytes; return DW_DLV_OK; } /* This function actually 'commits' the space used by the preceeding calls. */ static int libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type) { struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) { *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; return DW_DLV_ERROR; } curblk->mb_avail_len = dbg->de_compose_avail; curblk->mb_used_len = dbg->de_compose_used_len; return DW_DLV_OK; } int dwarf_def_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned line, char *macname, char *macvalue, Dwarf_Error * error) { size_t len; size_t len2; size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } if (macname == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); return (DW_DLV_ERROR); } len = strlen(macname) + 1; if (len == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); return (DW_DLV_ERROR); } if (macvalue) { len2 = strlen(macvalue) + 1; } else { len2 = 0; } /* 1 for space character we add */ length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1; res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_add_line(dbg, line, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } libdwarf_compose_add_string(dbg, macname, len); libdwarf_compose_add_string(dbg, " ", 1); if (macvalue) { libdwarf_compose_add_string(dbg, " ", 1); libdwarf_compose_add_string(dbg, macvalue, len2); } res = libdwarf_compose_complete(dbg, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } return DW_DLV_OK; } int dwarf_undef_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned line, char *macname, Dwarf_Error * error) { size_t len; size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } if (macname == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); return (DW_DLV_ERROR); } len = strlen(macname) + 1; if (len == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); return (DW_DLV_ERROR); } length_est = COMMAND_LEN + LINE_LEN + len; res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_add_line(dbg, line, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } libdwarf_compose_add_string(dbg, macname, len); res = libdwarf_compose_complete(dbg, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } return DW_DLV_OK; } int dwarf_start_macro_file(Dwarf_P_Debug dbg, Dwarf_Unsigned fileindex, Dwarf_Unsigned linenumber, Dwarf_Error * error) { size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } length_est = COMMAND_LEN + LINE_LEN + LINE_LEN; res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_add_line(dbg, fileindex, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_add_line(dbg, linenumber, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } return DW_DLV_OK; } int dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error) { size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } length_est = COMMAND_LEN; res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est, &compose_error_type); if (res == DW_DLV_ERROR) { _dwarf_p_error(dbg, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_complete(dbg, &compose_error_type); if (res == DW_DLV_ERROR) { _dwarf_p_error(dbg, error, compose_error_type); return res; } return res; } int dwarf_vendor_ext(Dwarf_P_Debug dbg, Dwarf_Unsigned constant, char *string, Dwarf_Error * error) { size_t len; size_t length_est; int res; int compose_error_type; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } if (string == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); return (DW_DLV_ERROR); } len = strlen(string) + 1; if (len == 0) { _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); return (DW_DLV_ERROR); } length_est = COMMAND_LEN + LINE_LEN + len; res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_add_line(dbg, constant, &compose_error_type); if (res != DW_DLV_OK) { _dwarf_p_error(NULL, error, compose_error_type); return (DW_DLV_ERROR); } libdwarf_compose_add_string(dbg, string, len); libdwarf_compose_complete(dbg, &compose_error_type); return DW_DLV_OK; } int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Total num of bytes in .debug_macinfo section. */ Dwarf_Unsigned mac_num_bytes; /* Points to first byte of .debug_macinfo buffer. */ Dwarf_Small *macinfo; /* Fills in the .debug_macinfo buffer. */ Dwarf_Small *macinfo_ptr; /* Used to scan the section data buffers. */ struct dw_macinfo_block_s *m_prev; struct dw_macinfo_block_s *m_sect; /* Get the size of the debug_macinfo data */ mac_num_bytes = 0; for (m_sect = dbg->de_first_macinfo; m_sect != NULL; m_sect = m_sect->mb_next) { mac_num_bytes += m_sect->mb_used_len; } /* The final entry has a type code of 0 to indicate It is final for this CU Takes just 1 byte. */ mac_num_bytes += 1; GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO], macinfo, (unsigned long) mac_num_bytes, error); macinfo_ptr = macinfo; m_prev = 0; for (m_sect = dbg->de_first_macinfo; m_sect != NULL; m_sect = m_sect->mb_next) { memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len); macinfo_ptr += m_sect->mb_used_len; if (m_prev) { _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); m_prev = 0; } m_prev = m_sect; } *macinfo_ptr = 0; /* the type code of 0 as last entry */ if (m_prev) { _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); m_prev = 0; } dbg->de_first_macinfo = NULL; dbg->de_current_macinfo = NULL; *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_macinfo.h000066400000000000000000000022631361531463500204020ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); dwarfutils-20200114/libdwarf/pro_opaque.h000066400000000000000000000500201361531463500202520ustar00rootroot00000000000000/* Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2011-2017 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "libdwarfdefs.h" #define true 1 #define false 0 /* The DISTINGUISHED VALUE is 4 byte value defined by DWARF since DWARF3. */ #define DISTINGUISHED_VALUE_ARRAY(x) unsigned char x[4] = { 0xff,0xff,0xff,0xff } #define DISTINGUISHED_VALUE 0xffffffff /* 64bit extension flag */ /* to identify a cie */ #define DW_CIE_ID ~(0x0) #define DW_CIE_VERSION 1 typedef signed char Dwarf_Sbyte; typedef unsigned char Dwarf_Ubyte; typedef signed short Dwarf_Shalf; /* On any change that makes libdwarf producer incompatible, increment this number. 1->2->3 ... */ #define PRO_VERSION_MAGIC 0xdead1 #define DWARF_HALF_SIZE 2 #define DWARF_32BIT_SIZE 4 #define DWARF_64BIT_SIZE 8 /* producer: This struct is used to hold information about all debug* sections. On creating a new section, section names and indices are added to this struct definition in pro_section.h */ typedef struct Dwarf_P_Section_Data_s *Dwarf_P_Section_Data; /* producer: This struct holds file entries or include file entries for the statement prologue. Defined in pro_line.h */ typedef struct Dwarf_P_F_Entry_s *Dwarf_P_F_Entry; /* producer: This struct holds information for each cie. Defn in pro_frame.h */ typedef struct Dwarf_P_Cie_s *Dwarf_P_Cie; /* producer: Struct to hold line number information, different from Dwarf_Line opaque type. */ typedef struct Dwarf_P_Line_s *Dwarf_P_Line; /* producer: Struct to hold information about address ranges. */ typedef struct Dwarf_P_Simple_nameentry_s *Dwarf_P_Simple_nameentry; typedef struct Dwarf_P_Simple_name_header_s *Dwarf_P_Simple_name_header; typedef struct Dwarf_P_Arange_s *Dwarf_P_Arange; typedef struct Dwarf_P_Per_Reloc_Sect_s *Dwarf_P_Per_Reloc_Sect; typedef struct Dwarf_P_Per_Sect_String_Attrs_s *Dwarf_P_Per_Sect_String_Attrs; typedef struct Dwarf_P_Dnames_s *Dwarf_P_Dnames; /* Defined to get at the elf section numbers and section name indices in symtab for the dwarf sections Must match .rel.* names in _dwarf_rel_section_names exactly. */ #define DEBUG_INFO 0 #define DEBUG_LINE 1 #define DEBUG_ABBREV 2 #define DEBUG_FRAME 3 #define DEBUG_ARANGES 4 #define DEBUG_PUBNAMES 5 #define DEBUG_FUNCNAMES 6 #define DEBUG_TYPENAMES 7 #define DEBUG_VARNAMES 8 #define DEBUG_WEAKNAMES 9 #define DEBUG_MACINFO 10 /* DWARF 2,3,4 only */ #define DEBUG_LOC 11 #define DEBUG_RANGES 12 #define DEBUG_TYPES 13 #define DEBUG_PUBTYPES 14 #define DEBUG_NAMES 15 /* DWARF5. aka dnames */ #define DEBUG_STR 16 #define DEBUG_LINE_STR 17 #define DEBUG_MACRO 18 /* DWARF 5. */ #define DEBUG_LOCLISTS 19 /* DWARF 5. */ #define DEBUG_RNGLISTS 20 /* DWARF 5. */ /* Maximum number of debug_* sections not including the relocations */ #define NUM_DEBUG_SECTIONS 21 /* The FORM codes available are defined in DWARF5 on page 158, DW_LNCT_path */ struct Dwarf_P_Line_format_s { /* DW_LNCT_path etc. */ unsigned def_content_type; /* DW_FORM_string or DW_FORM_strp or DW_FORM_strp or DW_FORM_strp_sup or for dwo, some others. */ unsigned def_form_code; }; #define DW_LINE_FORMATS_MAX 6 /* Describes the data needed to generate line table header info so we can vary the init at runtime. */ struct Dwarf_P_Line_Inits_s { unsigned pi_linetable_version; /* line table version number */ unsigned pi_default_is_stmt; /* default value for is_stmt */ /* Size of the smallest instruction, in bytes. */ unsigned pi_minimum_instruction_length; /* Normally opcode_base is determined by pi_version, but we allow manual setting here so we can generate data like GNU with a DWARF3 opcode base in a DWARF2 section. This determines how much of the header_opcode_lengths table is emitted in the line table header */ unsigned pi_opcode_base; int pi_line_base; /* For line table header. */ int pi_line_range; /* For line table header. */ /* Make this >1 for VLIW machines. DWARF4,DWARF5 */ unsigned pi_maximum_operations_per_instruction; /* DWARF 5 */ unsigned pi_segment_selector_size; unsigned pi_address_size; unsigned pi_segment_size; unsigned pi_directory_entry_format_count; struct Dwarf_P_Line_format_s pi_incformats[DW_LINE_FORMATS_MAX]; unsigned pi_file_entry_format_count; struct Dwarf_P_Line_format_s pi_fileformats[DW_LINE_FORMATS_MAX]; }; struct Dwarf_P_Die_s { Dwarf_Unsigned di_offset; /* offset in debug info */ char *di_abbrev; /* abbreviation */ Dwarf_Unsigned di_abbrev_nbytes; /* # of bytes in abbrev */ Dwarf_Tag di_tag; Dwarf_P_Die di_parent; /* parent of current die */ Dwarf_P_Die di_child; /* first child */ /* The last child field makes linking up children an O(1) operation, See pro_die.c. */ Dwarf_P_Die di_last_child; Dwarf_P_Die di_left; /* left sibling */ Dwarf_P_Die di_right; /* right sibling */ Dwarf_P_Attribute di_attrs; /* list of attributes */ Dwarf_P_Attribute di_last_attr; /* last attribute */ int di_n_attr; /* number of attributes */ Dwarf_P_Debug di_dbg; /* For memory management */ Dwarf_Unsigned di_marker; /* used to attach symbols to dies */ }; /* producer fields */ struct Dwarf_P_Attribute_s { Dwarf_Half ar_attribute; /* Attribute Value. */ Dwarf_Half ar_attribute_form; /* Attribute Form. */ Dwarf_P_Die ar_ref_die; /* die pointer if form ref */ char *ar_data; /* data, format given by form */ Dwarf_Unsigned ar_nbytes; /* no. of bytes of data */ Dwarf_Unsigned ar_rel_symidx; /* when attribute has a relocatable value, holds index of symbol in SYMTAB */ Dwarf_Unsigned ar_debug_str_offset; /* Offset in .debug_str if non-zero. Zero offset never assigned a string. */ Dwarf_Ubyte ar_rel_type; /* relocation type */ Dwarf_Unsigned ar_rel_offset; /* Offset of relocation within block */ char ar_reloc_len; /* Number of bytes that relocation applies to. 4 or 8. Unused and may be 0 if if ar_rel_type is R_MIPS_NONE */ Dwarf_P_Attribute ar_next; /* set if form = DW_FORM_implicit_const; */ Dwarf_Signed ar_implicit_const; }; /* A block of .debug_macinfo data: this forms a series of blocks. ** Each macinfo input is compressed immediately and put into ** the current block if room, else a newblock allocated. ** The space allocation is such that the block and the macinfo ** data are one malloc block: free with a pointer to this and the ** mb_data is freed automatically. ** Like the struct hack, but legal ANSI C. */ struct dw_macinfo_block_s { struct dw_macinfo_block_s *mb_next; unsigned long mb_avail_len; unsigned long mb_used_len; unsigned long mb_macinfo_data_space_len; char *mb_data;/* original malloc ptr. */ }; /* dwarf_sn_kind is for the array of similarly-treated name -> cu ties */ enum dwarf_sn_kind { dwarf_snk_pubname, /* .debug_pubnames */ dwarf_snk_funcname, /* SGI extension. */ dwarf_snk_weakname, /* SGI extension. */ dwarf_snk_typename, /* SGI extension. */ dwarf_snk_varname, /* SGI extension. */ dwarf_snk_pubtype, /* .debug_pubtypes */ dwarf_snk_entrycount /* this one must be last */ }; /* The calls to add a varname etc use a list of these as the list. */ struct Dwarf_P_Simple_nameentry_s { Dwarf_P_Die sne_die; char *sne_name; int sne_name_len; Dwarf_P_Simple_nameentry sne_next; }; /* An array of these, each of which heads a list of Dwarf_P_Simple_nameentry */ struct Dwarf_P_Simple_name_header_s { Dwarf_P_Simple_nameentry sn_head; Dwarf_P_Simple_nameentry sn_tail; Dwarf_Signed sn_count; /* Length that will be generated, not counting fixed header or trailer */ Dwarf_Signed sn_net_len; }; typedef int (*_dwarf_pro_reloc_name_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,/* r_offset */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length); typedef int (*_dwarf_pro_reloc_length_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,/* r_offset */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type type, int reltarget_length); typedef int (*_dwarf_pro_transform_relocs_func_ptr) (Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count); /* Each slot in a block of slots could be: a binary stream relocation entry (32 or 64bit relocation data) a SYMBOLIC relocation entry. During creation sometimes we create multiple chained blocks, but sometimes we create a single long block. Before returning reloc data to caller, we switch to a single, long-enough, block. We make counters here Dwarf_Unsigned so that we get sufficient alignment. Since we use space after the struct (at malloc time) for user data which must have Dwarf_Unsigned alignment, this struct must have that alignment too. */ struct Dwarf_P_Relocation_Block_s { Dwarf_Unsigned rb_slots_in_block; /* slots in block, as created */ Dwarf_Unsigned rb_next_slot_to_use; /* counter, start at 0. */ struct Dwarf_P_Relocation_Block_s *rb_next; char *rb_where_to_add_next; /* pointer to next slot (might be past end, depending on rb_next_slot_to_use) */ char *rb_data; /* data area */ }; /* One of these per potential relocation section So one per actual dwarf section. Left zeroed when not used (some sections have no relocations). */ struct Dwarf_P_Per_Reloc_Sect_s { unsigned long pr_reloc_total_count; /* total number of entries across all blocks */ unsigned long pr_slots_per_block_to_alloc; /* at Block alloc, this is the default number of slots to use */ int pr_sect_num_of_reloc_sect; /* sect number returned by de_callback_func() or de_callback_func_b() or_c() call, this is the sect number of the relocation section. */ /* singly-linked list. add at and ('last') with count of blocks */ struct Dwarf_P_Relocation_Block_s *pr_first_block; struct Dwarf_P_Relocation_Block_s *pr_last_block; unsigned long pr_block_count; }; #define DEFAULT_SLOTS_PER_BLOCK 3 typedef struct memory_list_s { struct memory_list_s *prev; struct memory_list_s *next; } memory_list_t; struct Dwarf_P_Per_Sect_String_Attrs_s { int sect_sa_section_number; unsigned sect_sa_n_alloc; unsigned sect_sa_n_used; Dwarf_P_String_Attr sect_sa_list; }; struct Dwarf_P_debug_str_entry_s { Dwarf_P_Debug dse_dbg; /* Name used initially with tfind. */ char *dse_name; Dwarf_Unsigned dse_slen; /* includes space for NUL terminator */ /* See dse_has_table_offset below. */ Dwarf_Unsigned dse_table_offset; /* For tsearch a hash table exists and we have a table offset. dse_dbg->de_debug_str->ds_data + dse_table_offset points to the string iff dse_has_table_offset != 0. */ unsigned char dse_has_table_offset; }; struct Dwarf_P_Str_stats_s { Dwarf_Unsigned ps_strp_count_debug_str; Dwarf_Unsigned ps_strp_len_debug_str; Dwarf_Unsigned ps_strp_len_debug_line_str; Dwarf_Unsigned ps_strp_reused_count; Dwarf_Unsigned ps_strp_reused_len; }; struct Dwarf_P_Stats_s { Dwarf_Unsigned ps_str_count; Dwarf_Unsigned ps_str_total_length; struct Dwarf_P_Str_stats_s ps_strp; struct Dwarf_P_Str_stats_s ps_line_strp; }; /* Fields used by producer */ struct Dwarf_P_Debug_s { /* Used to catch dso passing dbg to another DSO with incompatible version of libdwarf See PRO_VERSION_MAGIC */ int de_version_magic_number; Dwarf_Handler de_errhand; /* de_user_data is provided so users can use it to readily tie a callback to anything they desire. The contents are not used by libdwarf except to pass the data as a callback argument. New in June 2011. Available in dwarf_pro_init_c() and its callback function. */ void * de_user_data; Dwarf_Ptr de_errarg; /* Call back function, used to create .debug* sections. Provided By user. */ Dwarf_Callback_Func de_callback_func; /* Flags from producer_init call */ Dwarf_Unsigned de_flags; /* This holds information on debug info section stream output, including the stream data */ Dwarf_P_Section_Data de_debug_sects; /* Defaults set as DW_FORM_string, meaning not using .debug_str by default. This intended for the .debug_info section. */ int de_debug_default_str_form; /* If form DW_FORM_strp */ Dwarf_P_Section_Data de_debug_str; void *de_debug_str_hashtab; /* for tsearch */ /* .debug_line_str section data if form DW_FORM_line_strp */ Dwarf_P_Section_Data de_debug_line_str; void *de_debug_line_str_hashtab; /* for tsearch */ /* Pointer to the 'current active' section */ Dwarf_P_Section_Data de_current_active_section; /* Number of debug data streams globs. */ Dwarf_Unsigned de_n_debug_sect; /* File entry information, null terminated singly-linked list */ Dwarf_P_F_Entry de_file_entries; Dwarf_P_F_Entry de_last_file_entry; Dwarf_Unsigned de_n_file_entries; /* Has the directories used to search for source files */ Dwarf_P_F_Entry de_inc_dirs; Dwarf_P_F_Entry de_last_inc_dir; Dwarf_Unsigned de_n_inc_dirs; /* Has all the line number info for the stmt program */ Dwarf_P_Line de_lines; Dwarf_P_Line de_last_line; /* List of cie's for the debug unit */ Dwarf_P_Cie de_frame_cies; Dwarf_P_Cie de_last_cie; Dwarf_Unsigned de_n_cie; /* Singly-linked list of fde's for the debug unit */ Dwarf_P_Fde de_frame_fdes; Dwarf_P_Fde de_last_fde; Dwarf_Unsigned de_n_fde; /* First die, leads to all others */ Dwarf_P_Die de_dies; /* Pointer to chain of aranges */ Dwarf_P_Arange de_arange; Dwarf_P_Arange de_last_arange; Dwarf_Signed de_arange_count; /* debug_names de_dnames is base of dnames info before disk form */ Dwarf_P_Dnames de_dnames; Dwarf_P_Section_Data de_dnames_sect; /* macinfo controls. */ /* first points to beginning of the list during creation */ struct dw_macinfo_block_s *de_first_macinfo; /* current points to the current, unfilled, block */ struct dw_macinfo_block_s *de_current_macinfo; /* Pointer to the first section, to support reset_section_bytes */ Dwarf_P_Section_Data de_first_debug_sect; /* Handles pubnames, weaknames, etc. See dwarf_sn_kind in pro_opaque.h */ struct Dwarf_P_Simple_name_header_s de_simple_name_headers[dwarf_snk_entrycount]; /* Relocation data. not all sections will actally have relocation info, of course. de_reloc_sect, de_elf_sects, and de_sect_name_idx arrays are exactly in parallel. Not every de_elf_sect has any relocations for it, of course. */ struct Dwarf_P_Per_Reloc_Sect_s de_reloc_sect[NUM_DEBUG_SECTIONS]; int de_reloc_next_to_return; /* iterator on reloc sections (SYMBOLIC output) */ /* Used in remembering sections. See de_reloc_sect above. */ int de_elf_sects[NUM_DEBUG_SECTIONS]; /* elf sect number of the section itself, DEBUG_LINE for example */ /* Section name index or handle for the name of the symbol for DEBUG_LINE for example */ Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS]; int de_offset_reloc; /* offset reloc type, R_MIPS_32 for example. Specific to the ABI being produced. Relocates offset size field */ int de_exc_reloc; /* reloc type specific to exception table relocs. */ int de_ptr_reloc; /* standard reloc type, R_MIPS_32 for example. Specific to the ABI being produced. relocates pointer size field */ unsigned char de_irix_exc_augmentation; /* If non-zero means that producing an IRIX exception-table offset in a CIE header is allowed (depending on the augmentation string). */ unsigned char de_dwarf_offset_size; /* dwarf offset size. */ unsigned char de_elf_offset_size; /* object section offset size. */ unsigned char de_pointer_size; /* size of address in target. */ /* Added April 19, 2017. For DWARF5 */ unsigned char de_segment_selector_size; unsigned char de_relocation_record_size; /* reloc record size varies by ABI and relocation-output method (stream or symbolic) */ unsigned char de_64bit_extension;/* non-zero if creating 64 bit offsets using dwarf2-99 extension proposal */ unsigned char de_output_version; /* 2,3,4, or 5. The version number of the output. (not necessarily that of each section, which depends on the base version). */ /* Defaults will be mostly useless, but such do exist */ unsigned de_big_endian; /* if 0 target is little-endian */ int de_ar_data_attribute_form; /* data8, data4 abi &version dependent */ int de_ar_ref_attr_form; /* ref8 ref4 , abi dependent */ /* simple name relocations */ _dwarf_pro_reloc_name_func_ptr de_relocate_by_name_symbol; /* relocations for a length, requiring a pair of symbols */ _dwarf_pro_reloc_length_func_ptr de_relocate_pair_by_symbol; _dwarf_pro_transform_relocs_func_ptr de_transform_relocs_to_disk; /* following used for macro buffers */ unsigned long de_compose_avail; unsigned long de_compose_used_len; unsigned char de_same_endian; void (*de_copy_word) (void *, const void *, unsigned long); /* Add new fields at the END of this struct to preserve some hope of sensible behavior on dbg passing between DSOs linked with mismatched libdwarf producer versions. */ Dwarf_P_Marker de_markers; /* pointer to array of markers */ unsigned de_marker_n_alloc; unsigned de_marker_n_used; int de_sect_sa_next_to_return; /* Iterator on sring attrib sects */ /* String attributes data of each section. */ struct Dwarf_P_Per_Sect_String_Attrs_s de_sect_string_attr[NUM_DEBUG_SECTIONS]; /* Hold data needed to init line output flexibly. */ struct Dwarf_P_Line_Inits_s de_line_inits; struct Dwarf_P_Stats_s de_stats; }; #define CURRENT_VERSION_STAMP 2 int _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *entry_name, enum dwarf_sn_kind entrykind, Dwarf_Error * error); enum dwarf_which_hash { _dwarf_hash_debug_str, _dwarf_hash_debug_line_str, _dwarf_hash_debug_str_sup }; int _dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg, char *name, enum dwarf_which_hash, unsigned slen, /* includes space for trailing NUL */ Dwarf_Unsigned *offset_in_debug_str, Dwarf_Error *error); int _dwarf_log_extra_flagstrings(Dwarf_P_Debug dbg, const char *extra, int *err); dwarfutils-20200114/libdwarf/pro_pubnames.c000066400000000000000000000052361361531463500205760ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #include #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #include #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_section.h" /* This function adds another public name to the list of public names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_pubname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubname_name, dwarf_snk_pubname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_pubname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubname_name, dwarf_snk_pubname, error); return res; } Dwarf_Unsigned dwarf_add_pubtype(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubtype_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubtype_name, dwarf_snk_pubtype, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_pubtype_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubtype_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, pubtype_name, dwarf_snk_pubtype, error); return res; } dwarfutils-20200114/libdwarf/pro_reloc.c000066400000000000000000000174001361531463500200640ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2008-2016 David Anderson, Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_reloc.h" /* Do initial alloc of newslots slots. Fails only if malloc fails. Supposed to be called before any relocs allocated. Ignored if after any allocated. Part of an optimization, so that for a known 'newslots' relocations count we can preallocate the right size block. Called from just 2 places. We use 'slots' so we don't have to do a new allocation for every relocation, just a new allocation every n slots. slots_in_block. returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_pre_alloc_specific_reloc_slots(Dwarf_P_Debug dbg, Dwarf_P_Per_Reloc_Sect prel, Dwarf_Unsigned newslots) { unsigned long len = 0; struct Dwarf_P_Relocation_Block_s *data = 0; unsigned long slots_in_blk = (unsigned long) newslots; unsigned long rel_rec_size = dbg->de_relocation_record_size; if (prel->pr_first_block) { return DW_DLV_OK; /* do nothing */ } len = sizeof(struct Dwarf_P_Relocation_Block_s) + slots_in_blk * rel_rec_size; data = (struct Dwarf_P_Relocation_Block_s *) _dwarf_p_get_alloc(dbg, len); if (!data) { return DW_DLV_ERROR; } data->rb_slots_in_block = slots_in_blk; /* could use default here, as fallback in case our origininal estimate wrong. When we call this we presumably know what we are doing, so keep this count for now */ data->rb_next_slot_to_use = 0; data->rb_where_to_add_next = ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); data->rb_data = data->rb_where_to_add_next; prel->pr_first_block = data; prel->pr_last_block = data; prel->pr_block_count = 1; return DW_DLV_OK; } /*Do alloc of slots. Fails only if malloc fails. Only allocator used. returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index) { unsigned long len = 0; struct Dwarf_P_Relocation_Block_s *data = 0; Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index]; unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc; unsigned long rel_rec_size = dbg->de_relocation_record_size; len = sizeof(struct Dwarf_P_Relocation_Block_s) + slots_in_blk * rel_rec_size; data = (struct Dwarf_P_Relocation_Block_s *) _dwarf_p_get_alloc(dbg, len); if (!data) { return DW_DLV_ERROR; } if (prel->pr_first_block) { prel->pr_last_block->rb_next = data; prel->pr_last_block = data; prel->pr_block_count += 1; } else { prel->pr_first_block = data; prel->pr_last_block = data; prel->pr_block_count = 1; } data->rb_slots_in_block = slots_in_blk; data->rb_next_slot_to_use = 0; data->rb_where_to_add_next = ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); data->rb_data = data->rb_where_to_add_next; return DW_DLV_OK; } /* Reserve a slot. return DW_DLV_OK if succeeds. Return DW_DLV_ERROR if fails (malloc error). Use the relrec_to_fill to pass back a pointer to a slot space to use. */ int _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, int base_sec_index, void **relrec_to_fill) { struct Dwarf_P_Relocation_Block_s *data = 0; Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index]; unsigned long rel_rec_size = dbg->de_relocation_record_size; char *ret_addr = 0; data = prel->pr_last_block; if ((data == 0) || (data->rb_next_slot_to_use >= data->rb_slots_in_block)) { int res; res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index); if (res != DW_DLV_OK) { return res; } } data = prel->pr_last_block; /* now we have an empty slot */ ret_addr = data->rb_where_to_add_next; data->rb_where_to_add_next += rel_rec_size; data->rb_next_slot_to_use += 1; prel->pr_reloc_total_count += 1; *relrec_to_fill = (void *) ret_addr; return DW_DLV_OK; } /* On success returns count of .rel.* sections that are symbolic thru count_of_relocation_sections. On success, returns DW_DLV_OK. If this is not a 'symbolic' run, returns DW_DLV_NO_ENTRY. No errors are possible. */ /*ARGSUSED*/ int dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, Dwarf_Unsigned * count_of_relocation_sections, int *drd_buffer_version, UNUSEDARG Dwarf_Error * error) { if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { int i = 0; unsigned int count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) { ++count; } } *count_of_relocation_sections = (Dwarf_Unsigned) count; *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; return DW_DLV_OK; } /* Reset to start at beginning of reloc groups. */ dbg->de_reloc_next_to_return = 0; return DW_DLV_NO_ENTRY; } int dwarf_get_relocation_info(Dwarf_P_Debug dbg, Dwarf_Signed * elf_section_index, Dwarf_Signed * elf_section_index_link, Dwarf_Unsigned * relocation_buffer_count, Dwarf_Relocation_Data * reldata_buffer, Dwarf_Error * error) { int next = dbg->de_reloc_next_to_return; if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { int i = 0; for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { /* de_reloc_sect[] and de_elf_sects[] are in direct parallel. */ Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i]; int elf_sect_num = dbg->de_elf_sects[i]; if (prel->pr_reloc_total_count > 0) { /* Set up 'next' for subsequent call to dwarf_get_relocation_info(). */ dbg->de_reloc_next_to_return = i + 1; /* ASSERT: prel->pr_block_count == 1 */ *elf_section_index = prel->pr_sect_num_of_reloc_sect; /* Elf sec num in generated elf */ *elf_section_index_link = elf_sect_num; *relocation_buffer_count = prel->pr_reloc_total_count; *reldata_buffer = (Dwarf_Relocation_Data) (prel->pr_first_block->rb_data); return DW_DLV_OK; } } DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } return DW_DLV_NO_ENTRY; } dwarfutils-20200114/libdwarf/pro_reloc.h000066400000000000000000000025621361531463500200740ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_pre_alloc_specific_reloc_slots(Dwarf_P_Debug dbg, Dwarf_P_Per_Reloc_Sect p_reloc, Dwarf_Unsigned newslots); int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index); int _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, int base_sec_index, void **relrec_to_fill); dwarfutils-20200114/libdwarf/pro_reloc_stream.c000066400000000000000000000211051361531463500214340ustar00rootroot00000000000000/* Copyright (C) 2000,2001,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2016 David Anderson, Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #ifdef DWARF_WITH_LIBELF #include "libdwarfdefs.h" #include #ifdef HAVE_ELFACCESS_H #include #else /* Set r_info as defined by ELF generic ABI */ #define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t)) #define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t)) #endif #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_reloc_stream.h" /* Return DW_DLV_ERROR on malloc error or reltarget_length error. Return DW_DLV_OK otherwise */ /*ARGSUSED*/ int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length) { #if HAVE_ELF64_GETEHDR REL64 *elf64_reloc = 0; void *relrec_to_fill = 0; int res = 0; int rel_type = 0; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; if (type == dwarf_drt_data_reloc) { if (reltarget_length == dbg->de_dwarf_offset_size) { rel_type = dbg->de_offset_reloc; } else if (reltarget_length == dbg->de_pointer_size) { rel_type = dbg->de_ptr_reloc; } else { return DW_DLV_ERROR; } } else if (type == dwarf_drt_segment_rel) { rel_type = dbg->de_exc_reloc; } else { /* We are in trouble: improper use of stream relocations. Someone else will diagnose */ rel_type = 0; } elf64_reloc = (REL64 *)relrec_to_fill; elf64_reloc->r_offset = offset; Set_REL64_info(*elf64_reloc, symidx, rel_type); return DW_DLV_OK; #else /* !HAVE_ELF64_GETEHDR */ return DW_DLV_ERROR; #endif /* #if HAVE_ELF64_GETEHDR */ } /* Return DW_DLV_ERROR on malloc error or reltarget_length error. Return DW_DLV_OK otherwise a binary reloc: 32bit ABI */ int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length) { REL32 *elf32_reloc = 0; void *relrec_to_fill = 0; int res = 0; int rel_type = 0; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; if (type == dwarf_drt_data_reloc) { if (reltarget_length == dbg->de_dwarf_offset_size) { rel_type = dbg->de_offset_reloc; } else if (reltarget_length == dbg->de_pointer_size) { rel_type = dbg->de_ptr_reloc; } else { return DW_DLV_ERROR; } } else if (type == dwarf_drt_segment_rel) { rel_type = dbg->de_exc_reloc; } else { /* We are in trouble: improper use of stream relocations. Someone else will diagnose */ rel_type = 0; } elf32_reloc = (REL32*)relrec_to_fill; elf32_reloc->r_offset = (Elf32_Addr) offset; Set_REL32_info(*elf32_reloc, symidx, rel_type); return DW_DLV_OK; /* get a slot, fill in the slot entry */ } /* Return DW_DLV_OK. Never can really do anything: lengths cannot be represented as end-start in a stream. */ /*ARGSUSED*/ int _dwarf_pro_reloc_length_stream(UNUSEDARG Dwarf_P_Debug dbg, UNUSEDARG int base_sec_index, UNUSEDARG Dwarf_Unsigned offset, /* r_offset of reloc */ UNUSEDARG Dwarf_Unsigned start_symidx, UNUSEDARG Dwarf_Unsigned end_symidx, UNUSEDARG enum Dwarf_Rel_Type type, UNUSEDARG int reltarget_length) { /* get a slot, fill in the slot entry */ return DW_DLV_OK; } /* Ensure each stream is a single buffer and add that single buffer to the set of stream buffers. By creating a new buffer and copying if necessary. Free the input set of buffers if we consolidate. Return -1 on error (malloc failure) Return DW_DLV_OK on success. Any other return indicates malloc failed. */ int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count) { unsigned long total_size = 0; int i = 0; Dwarf_Error erre = 0; Dwarf_Error *error = &erre; Dwarf_Signed sec_count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect +i; Dwarf_Small *data = 0; int sec_index = 0; unsigned long ct = p_reloc->pr_reloc_total_count; unsigned len = 0; struct Dwarf_P_Relocation_Block_s *p_blk = 0; struct Dwarf_P_Relocation_Block_s *p_blk_last = 0; Dwarf_P_Per_Reloc_Sect prb = 0; if (ct == 0) { continue; } prb = &dbg->de_reloc_sect[i]; len = dbg->de_relocation_record_size; ++sec_count; total_size = ct * len; sec_index = prb->pr_sect_num_of_reloc_sect; if (sec_index == 0) { /* Call de_callback_func or de_callback_func_b or _c, getting section number of reloc section. */ int rel_section_index = 0; Dwarf_Unsigned name_idx = 0; int erri = 0; if (dbg->de_callback_func) { rel_section_index = dbg->de_callback_func(_dwarf_rel_section_names[i], /* size */ dbg->de_relocation_record_size, /* type */ SHT_REL, /* flags */ 0, /* link to symtab, which we cannot know */ 0, /* info == link to sec rels apply to */ dbg->de_elf_sects[i], &name_idx, dbg->de_user_data, &erri); } if (rel_section_index == -1) { { _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR); return (DW_DLV_ERROR); } } prb->pr_sect_num_of_reloc_sect = rel_section_index; sec_index = rel_section_index; } GET_CHUNK(dbg, sec_index, data, total_size, &erri); p_blk = p_reloc->pr_first_block; /* Following loop executes at least once. Effects the consolidation to a single block or, if already a single block, simply copies to the output buffer. And frees the input block. The new block is in the de_debug_sects list. */ while (p_blk) { unsigned long lenk = p_blk->rb_where_to_add_next - p_blk->rb_data; memcpy(data, p_blk->rb_data, lenk); data += lenk; p_blk_last = p_blk; p_blk = p_blk->rb_next; _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); } /* ASSERT: sum of len copied == total_size */ /* We have copied the input, now drop the pointers to it. For debugging, leave the other data untouched. */ p_reloc->pr_first_block = 0; p_reloc->pr_last_block = 0; } *new_sec_count = sec_count; return DW_DLV_OK; } #else /* DWARF_WITH_LIBELF */ /* avoids empty file warning if no libelf */ int dwarf_dummy_pro_reloc_stream = 2; #endif /* DWARF_WITH_LIBELF */ dwarfutils-20200114/libdwarf/pro_reloc_stream.h000066400000000000000000000034531361531463500214470ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count); dwarfutils-20200114/libdwarf/pro_reloc_symbolic.c000066400000000000000000000227761361531463500220010ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2016 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ /*#include */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_reloc_symbolic.h" #ifndef SHT_REL #define SHT_REL 9 #endif /* SHT_REL */ #ifndef SHN_UNDEF #define SHN_UNDEF 0 #endif /* SHN_UNDEF */ /* Return DW_DLV_ERROR on malloc error. Return DW_DLV_OK otherwise */ int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type type, int reltarget_length) { /* get a slot, fill in the slot entry */ void *relrec_to_fill = 0; int res = 0; struct Dwarf_Relocation_Data_s *slotp; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; slotp->drd_type = type; slotp->drd_length = reltarget_length; slotp->drd_offset = offset; slotp->drd_symbol_index = symidx; return DW_DLV_OK; } /* Return DW_DLV_ERROR on malloc error. Return DW_DLV_OK otherwise */ int _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type type, int reltarget_length) { /* get a slot, fill in the slot entry */ void *relrec_to_fill = 0; int res = 0; struct Dwarf_Relocation_Data_s *slotp1 = 0; struct Dwarf_Relocation_Data_s *slotp2 = 0; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, &relrec_to_fill); if (res != DW_DLV_OK) return res; slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; /* ASSERT: type == dwarf_drt_first_of_length_type_pair */ slotp1->drd_type = type; slotp1->drd_length = reltarget_length; slotp1->drd_offset = offset; slotp1->drd_symbol_index = start_symidx; slotp2->drd_type = dwarf_drt_second_of_length_pair; slotp2->drd_length = reltarget_length; slotp2->drd_offset = offset; slotp2->drd_symbol_index = end_symidx; return DW_DLV_OK; } /* Ensure each stream is a single buffer and add that single buffer to the set of stream buffers. By creating a new buffer and copying if necessary. (If > 1 block, reduce to 1 block) Free the input set of buffers if we consolidate. We pass back *new_sec_count as zero because we are not creating normal sections for a .o, but symbolic relocations, separately counted. Return -1 on error (malloc failure) Return DW_DLV_OK on success. Any other return indicates malloc failed. */ int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count) { int i = 0; Dwarf_Error error = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { int sec_index = 0; Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect + i; unsigned long ct = p_reloc->pr_reloc_total_count; int err = 0; if (ct == 0) { /* No relocations in here. Nothing to do. */ continue; } /* total_size = ct *len; */ sec_index = p_reloc->pr_sect_num_of_reloc_sect; if (sec_index == 0) { /* sec_index zero means we have not processed this section of relocations yet. */ /* Call de_callback_func getting section number of reloc section. */ int rel_section_index = 0; Dwarf_Unsigned name_idx = 0; /* This is a bit of a fake, as we do not really have true elf sections at all. Just the data such might contain. But this lets the caller eventually link things together: without this call we would not know what rel data goes with what section when we are asked for the real arrays. */ if (dbg->de_callback_func) { /* For symbolic relocations de_callback_func may well return 0. */ rel_section_index = dbg->de_callback_func(_dwarf_rel_section_names[i], dbg->de_relocation_record_size, /* type */ SHT_REL, /* flags */ 0, /* link to symtab, which we cannot know */ SHN_UNDEF, /* sec rels apply to */ dbg->de_elf_sects[i], &name_idx, dbg->de_user_data,&err); } if (rel_section_index == -1) { { _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR); return (DW_DLV_ERROR); } } p_reloc->pr_sect_num_of_reloc_sect = rel_section_index; } /* If pr_block_count 0 or 1 then the blocks are an array (with 0 or 1 entries) so we'll just return to the for loop. No more work to do here. */ if (p_reloc->pr_block_count < 2) { continue; } { /* Since more than one relocation on the section we now convert the list of relocation blocks into a proper array of blocks. */ struct Dwarf_P_Relocation_Block_s *new_blk = 0; struct Dwarf_P_Relocation_Block_s *p_blk = 0; Dwarf_Small *data = 0; int res = 0; p_blk = p_reloc->pr_first_block; /* Do not zero pr_sect_num_of_reloc_sect */ p_reloc->pr_reloc_total_count = 0; p_reloc->pr_first_block = 0; p_reloc->pr_last_block = 0; p_reloc->pr_block_count = 0; /* Now we know a number making a single array. Replaces DEFAULT_SLOTS_PER_BLOCK */ p_reloc->pr_slots_per_block_to_alloc = ct; /* Creating new single block for all 'ct' entries. Assigns a pointer value to pr_first_block (which means our p_reloc). It updates p_reloc->pr_first_block */ res = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, p_reloc,ct); if (res != DW_DLV_OK) { return res; } new_blk = p_reloc->pr_first_block; data = (Dwarf_Small *) new_blk->rb_data; /* The following loop does the consolidation to a single block and frees the input block(s). p_blk points to the old singly-linked-list and is the only access to that list. data is a pointer to the new array of ct entries which is our target(destination) of the copies. */ do { struct Dwarf_P_Relocation_Block_s *p_blk_last = 0; /* len identifies the data in all the slots in use in this block. */ unsigned long len = p_blk->rb_where_to_add_next - p_blk->rb_data; memcpy(data, p_blk->rb_data, len); data += len; p_blk_last = p_blk; p_blk = p_blk->rb_next; _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); } while (p_blk); /* ASSERT: the dangling p_blk list all dealloc'd which is really a no-op, all deallocations take place at producer_finish(). */ /* ASSERT: sum of len copied == total_size */ new_blk->rb_next_slot_to_use = ct; new_blk->rb_where_to_add_next = (char *) data; p_reloc->pr_reloc_total_count = ct; /* Have now created a single block, but no change in slots used (pr_reloc_total_count) */ } } /* There is no section data with symbolic, so there is no count. */ *new_sec_count = 0; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_reloc_symbolic.h000066400000000000000000000031411361531463500217670ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ Dwarf_Unsigned symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset, /* r_offset of reloc */ Dwarf_Unsigned start_symidx, Dwarf_Unsigned end_symidx, enum Dwarf_Rel_Type, int reltarget_length); int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count); dwarfutils-20200114/libdwarf/pro_section.c000066400000000000000000003557741361531463500204470ustar00rootroot00000000000000/* Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_util.h" #include "pro_encode_nm.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_line.h" #include "pro_frame.h" #include "pro_die.h" #include "pro_macinfo.h" #include "pro_types.h" #include "pro_dnames.h" #ifndef SHN_UNDEF #define SHN_UNDEF 0 #endif /* SHN_UNDEF */ #ifndef SHF_MIPS_NOSTRIP /* if this is not defined, we probably don't need it: just use 0 */ #define SHF_MIPS_NOSTRIP 0 #endif #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifdef WORDS_BIGENDIAN #define ASNOUT(t,s,l) \ do { \ unsigned sbyte = 0; \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ sbyte = sizeof(s) - l; \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ } while (0) #else /* LITTLEENDIAN */ #define ASNOUT(t,s,l) \ do { \ const char *p = 0; \ if (l > sizeof(s)) { \ _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ return DW_DLV_ERROR; \ } \ p = (const char *)(&s); \ dbg->de_copy_word(t,(const void *)p,l); \ } while (0) #endif /* ENDIANNESS */ #define SIZEOFT32 4 struct Dwarf_Sort_Abbrev_s { Dwarf_Unsigned dsa_attr; Dwarf_Unsigned dsa_form; Dwarf_Signed dsa_implicitvalue; Dwarf_P_Attribute dsa_attrp; }; /* Must match up with pro_section.h defines of DEBUG_INFO etc and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela" see pro_incl.h */ const char *_dwarf_rel_section_names[] = { REL_SEC_PREFIX ".debug_info", REL_SEC_PREFIX ".debug_line", REL_SEC_PREFIX ".debug_abbrev", /* Nothing here refers to anything. */ REL_SEC_PREFIX ".debug_frame", REL_SEC_PREFIX ".debug_aranges", REL_SEC_PREFIX ".debug_pubnames", REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */ REL_SEC_PREFIX ".debug_typenames", /* sgi extension */ REL_SEC_PREFIX ".debug_varnames", /* sgi extension */ REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */ REL_SEC_PREFIX ".debug_macinfo", REL_SEC_PREFIX ".debug_loc", REL_SEC_PREFIX ".debug_ranges", REL_SEC_PREFIX ".debug_types", /* new in DWARF4 */ REL_SEC_PREFIX ".debug_pubtypes", /* new in DWARF3 */ REL_SEC_PREFIX ".debug_names", /* DWARF5 aka dnames */ REL_SEC_PREFIX ".debug_str", /* Nothing here refers to anything.*/ REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */ REL_SEC_PREFIX ".debug_line_str", /* DWARF5. Nothing referselsewhere */ REL_SEC_PREFIX ".debug_macro", /* DWARF5. */ REL_SEC_PREFIX ".debug_loclists", /* DWARF5. */ REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */ }; /* names of sections. Ensure that it matches the defines in pro_section.h, in the same order Must match also _dwarf_rel_section_names above */ const char *_dwarf_sectnames[] = { ".debug_info", ".debug_line", ".debug_abbrev", ".debug_frame", ".debug_aranges", ".debug_pubnames", ".debug_funcnames", /* sgi extension */ ".debug_typenames", /* sgi extension */ ".debug_varnames", /* sgi extension */ ".debug_weaknames", /* sgi extension */ ".debug_macinfo", ".debug_loc", ".debug_ranges", ".debug_types", /* new in DWARF4 */ ".debug_pubtypes", /* new in DWARF3 */ ".debug_names", /* new in DWARF5. aka dnames */ ".debug_str", ".debug_line_str", /* new in DWARF5 */ ".debug_macro", /* new in DWARF5 */ ".debug_loclists", /* new in DWARF5 */ ".debug_rnglists", /* new in DWARF5 */ }; static const Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */ 1, /* DW_LNS_advance_pc */ 1, /* DW_LNS_advance_line */ 1, /* DW_LNS_set_file */ 1, /* DW_LNS_set_column */ 0, /* DW_LNS_negate_stmt */ 0, /* DW_LNS_set_basic_block */ 0, /* DW_LNS_const_add_pc */ 1, /* DW_LNS_fixed_advance_pc */ /* The following for DWARF3 and DWARF4, though GNU uses these in DWARF2 as well. */ 0, /* DW_LNS_set_prologue_end */ 0, /* DW_LNS_set_epilogue_begin */ 1, /* DW_LNS_set_isa */ }; /* struct to hold relocation entries. Its mantained as a linked list of relocation structs, and will then be written at as a whole into the relocation section. Whether its 32 bit or 64 bit will be obtained from Dwarf_Debug pointer. */ typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel; struct Dwarf_P_Rel_s { Dwarf_P_Rel dr_next; void *dr_rel_datap; }; typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head; struct Dwarf_P_Rel_Head_s { struct Dwarf_P_Rel_s *drh_head; struct Dwarf_P_Rel_s *drh_tail; }; static int _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); #if 0 static void dump_bytes(char * msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; printf("%s len %ld ",msg,len); for (; cur < end; cur++) { printf("%02x ", *cur); } printf("\n"); } #endif #if 0 static void print_single_abbrev(Dwarf_P_Abbrev c, unsigned idx) { unsigned j = 0; printf(" %2u idx %2u tag 0x%x attrct %2u\n",idx, (unsigned)c->abb_idx, (unsigned)c->abb_tag, (unsigned)c->abb_n_attr); for ( ; j < (unsigned)c->abb_n_attr; ++j) { printf(" %2u attr 0x%2x form 0x%2x impl val %" DW_PR_DSd "\n", j, (unsigned)c->abb_attrs[j], (unsigned)c->abb_forms[j]); (unsigned)c->abb_implicits[j]); } } static void print_curabbrev(const char *where, Dwarf_P_Abbrev curabbrev) { Dwarf_P_Abbrev ca = 0; unsigned i = 0; for(ca = curabbrev; ca ; ca = ca->abb_next,++i) { printf("ABBREV %u from %s\n",i,where); print_single_abbrev(ca,i); } } #endif /* These macros used as return value for _dwarf_pro_get_opc. */ #define OPC_INCS_ZERO -1 #define OPC_OUT_OF_RANGE -2 #define LINE_OUT_OF_RANGE -3 /* Given address advance and line advance, it gives either special opcode, or a number < 0 FIXME: Check all three negative values. Are any negatives really hard errors? */ static int _dwarf_pro_get_opc( struct Dwarf_P_Line_Inits_s *inits, Dwarf_Unsigned addr_adv, int line_adv) { int line_base = inits->pi_line_base; int line_range =inits->pi_line_range; Dwarf_Unsigned factored_adv = 0; factored_adv = addr_adv / inits->pi_minimum_instruction_length; if (line_adv == 0 && factored_adv == 0) { return OPC_INCS_ZERO; } if (line_adv >= line_base && line_adv < line_base + line_range) { int opc = 0; opc = (line_adv - line_base) + (factored_adv * line_range) + inits->pi_opcode_base; if (opc > 255) { return OPC_OUT_OF_RANGE; } return opc; } return LINE_OUT_OF_RANGE; } /* OFFSET_PLUS_EXTENSION_SIZE is the size of the 'length' field in total. Which may be 4,8, or 12 bytes! 4 is standard DWARF2. 8 is non-standard MIPS-IRIX 64-bit. 12 is standard DWARF3 for 64 bit offsets. Used in various routines: local variable names must match the names here. */ #define OFFSET_PLUS_EXTENSION_SIZE (offset_size + extension_size) /* Return TRUE if we need the section, FALSE otherwise If any of the 'line-data-related' calls were made including file or directory entries, produce .debug_line . */ static int dwarf_need_debug_line_section(Dwarf_P_Debug dbg) { if (dbg->de_output_version > 4) { return FALSE; } if (dbg->de_lines == NULL && dbg->de_file_entries == NULL && dbg->de_inc_dirs == NULL) { return FALSE; } return TRUE; } /* DWARF5 only. */ static int dwarf_need_debug_names_section(Dwarf_P_Debug dbg) { if (dbg->de_output_version < 5) { return FALSE; } if (!dbg->de_dnames) { return FALSE; } if (!dbg->de_dnames->dn_create_section) { return FALSE; } return TRUE; } /* Convert debug information to a format such that it can be written on disk. Called exactly once per execution. This is the traditional interface. Bad interface design. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) { Dwarf_Signed count = 0; int res = 0; res = dwarf_transform_to_disk_form_a(dbg, &count,error); if (res == DW_DLV_ERROR) { return DW_DLV_NOCOUNT; } return count; } /* Convert debug information to a format such that it can be written on disk. Called exactly once per execution. This is the interface design used with the consumer interface, so easier for callers to work with. */ int dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg, Dwarf_Signed *count, Dwarf_Error * error) { /* Section data in written out in a number of buffers. Each _generate_*() function returns a cumulative count of buffers for all the sections. dwarf_get_section_bytes() returns pointers to these buffers one at a time. */ Dwarf_Signed nbufs = 0; int sect = 0; int err = 0; Dwarf_Unsigned du = 0; if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } /* Create dwarf section headers */ for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) { long flags = 0; switch (sect) { case DEBUG_INFO: if (dbg->de_dies == NULL) { continue; } break; case DEBUG_LINE: if (dwarf_need_debug_line_section(dbg) == FALSE) { continue; } break; case DEBUG_ABBREV: if (dbg->de_dies == NULL) { continue; } break; case DEBUG_FRAME: if (dbg->de_frame_cies == NULL) { continue; } flags = SHF_MIPS_NOSTRIP; break; case DEBUG_ARANGES: if (dbg->de_arange == NULL) { continue; } break; case DEBUG_PUBNAMES: if (dbg->de_simple_name_headers[dwarf_snk_pubname]. sn_head == NULL) { continue; } break; case DEBUG_PUBTYPES: if (dbg->de_simple_name_headers[dwarf_snk_pubtype]. sn_head == NULL) { continue; } break; case DEBUG_STR: if (dbg->de_debug_str->ds_data == NULL) { continue; } break; case DEBUG_FUNCNAMES: if (dbg->de_simple_name_headers[dwarf_snk_funcname]. sn_head == NULL) { continue; } break; case DEBUG_TYPENAMES: if (dbg->de_simple_name_headers[dwarf_snk_typename]. sn_head == NULL) { continue; } break; case DEBUG_VARNAMES: if (dbg->de_simple_name_headers[dwarf_snk_varname]. sn_head == NULL) { continue; } break; case DEBUG_WEAKNAMES: if (dbg->de_simple_name_headers[dwarf_snk_weakname]. sn_head == NULL) { continue; } break; case DEBUG_MACINFO: if (dbg->de_first_macinfo == NULL) { continue; } break; case DEBUG_NAMES: /* DWARF5 */ if (dwarf_need_debug_names_section(dbg) == FALSE) { continue; } break; case DEBUG_LOC: /* Not handled yet. */ continue; case DEBUG_RANGES: /* Not handled yet. */ continue; case DEBUG_TYPES: /* Not handled yet. */ continue; case DEBUG_MACRO: /* Not handled yet. */ continue; case DEBUG_LOCLISTS: /* Not handled yet. */ continue; case DEBUG_RNGLISTS: /* Not handled yet. */ continue; case DEBUG_LINE_STR: if (dwarf_need_debug_line_section(dbg) == FALSE) { continue; } /* Not handled yet. */ continue; default: /* logic error: missing a case */ DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } { int new_base_elf_sect = 0; if (dbg->de_callback_func) { new_base_elf_sect = dbg->de_callback_func(_dwarf_sectnames[sect], /* rec size */ 1, SECTION_TYPE, flags, SHN_UNDEF, 0, &du, dbg->de_user_data, &err); } if (new_base_elf_sect == -1) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } dbg->de_elf_sects[sect] = new_base_elf_sect; dbg->de_sect_name_idx[sect] = du; } } nbufs = 0; /* Changing the order in which the sections are generated may cause problems because of relocations. */ if (dwarf_need_debug_line_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debugline(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_frame_cies) { int res = _dwarf_pro_generate_debugframe(dbg,&nbufs,error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_first_macinfo) { /* For DWARF 2,3,4 only */ /* Need new code for DWARF5 macro info. FIXME*/ int res = _dwarf_pro_transform_macro_info_to_disk(dbg, &nbufs,error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_dies) { int res= _dwarf_pro_generate_debuginfo(dbg, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_debug_str->ds_data) { int res = _dwarf_pro_generate_debug_str(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_debug_line_str->ds_data) { int res = _dwarf_pro_generate_debug_line_str(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_arange) { int res = _dwarf_transform_arange_to_disk(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_output_version < 5) { if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_pubname, DEBUG_PUBNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_pubtype, DEBUG_PUBTYPES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_funcname, DEBUG_FUNCNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_typename, DEBUG_TYPENAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_varname, DEBUG_VARNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { int res = _dwarf_transform_simplename_to_disk(dbg, dwarf_snk_weakname, DEBUG_WEAKNAMES, &nbufs, error); if (res == DW_DLV_ERROR) { return res; } } } if (dwarf_need_debug_names_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_names(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } #if 0 /* FIXME: TODO new sections */ if (dwarf_need_debug_macro_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_macro(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dwarf_need_debug_loclists_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_loclists(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } if (dwarf_need_debug_rnglists_section(dbg) == TRUE) { int res = _dwarf_pro_generate_debug_rnglists(dbg,&nbufs, error); if (res == DW_DLV_ERROR) { return res; } } #endif { Dwarf_Signed new_chunks = 0; int res = 0; res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR, DW_DLV_ERROR); } nbufs += new_chunks; } *count = nbufs; return DW_DLV_OK; } static int write_fixed_size(Dwarf_Unsigned val, Dwarf_P_Debug dbg, int elfsectno, Dwarf_Unsigned size, unsigned * size_out, Dwarf_Error* error) { unsigned char *data = 0; GET_CHUNK_ERR(dbg, elfsectno, data, size, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &val, sizeof(val), size); *size_out = size; return DW_DLV_OK; } static int write_ubyte(unsigned val, Dwarf_P_Debug dbg, int elfsectno, unsigned *len_out, Dwarf_Error* error) { Dwarf_Ubyte db = val; unsigned char *data = 0; unsigned len = sizeof(Dwarf_Ubyte); GET_CHUNK_ERR(dbg, elfsectno, data, len, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), len); *len_out = 1; return DW_DLV_OK;; } static int pretend_write_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, unsigned *uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; int nbytes = 0; int res = 0; res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR , DW_DLV_ERROR); } *uval_len_out = nbytes; return DW_DLV_OK; } static int write_sval(Dwarf_Signed val, Dwarf_P_Debug dbg, int elfsectno, unsigned *sval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; unsigned char *data = 0; int nbytes = 0; int res = _dwarf_pro_encode_signed_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } GET_CHUNK(dbg, elfsectno, data, nbytes, error); memcpy((void *) data, (const void *) buff1, nbytes); *sval_len_out = nbytes; return DW_DLV_OK; } /* This one does not allocate a chunk, uses an already existing chunk. data points into that existing chunk. */ static int append_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, unsigned char *data, unsigned * uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; int nbytes = 0; int res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } memcpy((void *) data, (const void *) buff1, nbytes); *uval_len_out = nbytes; return DW_DLV_OK; } static int write_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, int elfsectno, unsigned * uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; unsigned char *data = 0; int nbytes = 0; int res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } GET_CHUNK_ERR(dbg, elfsectno, data, nbytes, error); memcpy((void *) data, (const void *) buff1, nbytes); *uval_len_out = nbytes; return DW_DLV_OK; } static unsigned write_opcode_uval(int opcode, Dwarf_P_Debug dbg, int elfsectno, Dwarf_Unsigned val, unsigned *len_out, Dwarf_Error* error) { unsigned ublen = 0; int res = 0; unsigned uvlen = 0; res = write_ubyte(opcode,dbg,elfsectno,&ublen,error); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = write_uval(val,dbg,elfsectno,&uvlen,error); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } *len_out = ublen +uvlen; return DW_DLV_OK; } static int determine_form_size(Dwarf_P_Debug dbg, unsigned format_count, struct Dwarf_P_Line_format_s *format, unsigned *size_out, Dwarf_Bool write_out, unsigned char *data, Dwarf_Error *error) { unsigned calculated_size = 0; unsigned n = 0; int res = 0; /* entry format itself */ calculated_size += sizeof_ubyte(dbg); /* Space for the format details. */ for(n = 0; n < format_count; ++n) { struct Dwarf_P_Line_format_s *lf = format+n; unsigned val_len = 0; unsigned val_len2 = 0; if (write_out) { res = append_uval(lf->def_content_type, dbg, data, &val_len,error); } else { res = pretend_write_uval(lf->def_content_type, dbg, &val_len,error); } data += val_len; if(res != DW_DLV_OK) { return res; } if (write_out) { res = append_uval(lf->def_form_code, dbg, data, &val_len2,error); } else { res = pretend_write_uval(lf->def_form_code, dbg, &val_len2,error); } if(res != DW_DLV_OK) { return res; } data += val_len2; calculated_size += val_len + val_len2; } *size_out = calculated_size; return DW_DLV_OK; } static int determine_file_content_size(Dwarf_P_Debug dbg, Dwarf_P_F_Entry entry_list, Dwarf_Unsigned format_count, struct Dwarf_P_Line_format_s *format, unsigned *size_out, Dwarf_Bool write_out, unsigned char *data, Dwarf_Error *error) { unsigned calculated_size = 0; unsigned count_len = 0; Dwarf_P_F_Entry cur = 0; Dwarf_P_F_Entry nxt = 0; unsigned n = 0; int res = 0; Dwarf_Unsigned offset_size = 0; offset_size = dbg->de_dwarf_offset_size; res = pretend_write_uval(format_count,dbg, &count_len,error); if(res != DW_DLV_OK) { return res; } calculated_size += count_len; cur = entry_list; for(n = 0; cur; n++,cur = nxt) { unsigned f = 0; nxt = cur->dfe_next; for( ; f < format_count; f++) { struct Dwarf_P_Line_format_s *lf = format+f; unsigned ctype = lf->def_content_type; unsigned cform = lf->def_form_code; switch (ctype) { case DW_LNCT_path: { switch(cform) { case DW_FORM_string: { unsigned slen = strlen(cur->dfe_name) +1; calculated_size += slen; if (write_out) { strcpy((char *)data, cur->dfe_name); data += slen; } } break; case DW_FORM_strp: { unsigned slen = strlen(cur->dfe_name) +1; if (write_out) { Dwarf_Unsigned stroffset = 0; res = _dwarf_insert_or_find_in_debug_str( dbg, cur->dfe_name, _dwarf_hash_debug_str, slen, &stroffset,error); if (res != DW_DLV_OK) { return res; } WRITE_UNALIGNED(dbg, (void *) data, (const void *) &stroffset, sizeof(stroffset), offset_size); data += offset_size; } calculated_size += offset_size; } break; case DW_FORM_line_strp: { unsigned slen = strlen(cur->dfe_name) +1; if (write_out) { Dwarf_Unsigned stroffset = 0; res = _dwarf_insert_or_find_in_debug_str( dbg, cur->dfe_name, _dwarf_hash_debug_line_str, slen, &stroffset,error); if (res != DW_DLV_OK) { return res; } WRITE_UNALIGNED(dbg, (void *) data, (const void *) &stroffset, sizeof(stroffset), offset_size); data += offset_size; } calculated_size += offset_size; } break; case DW_FORM_strp_sup: /* Following in dwo only. */ case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2: case DW_FORM_strx3: case DW_FORM_strx4: default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); break; } } break; case DW_LNCT_directory_index: { switch(cform) { case DW_FORM_data1: calculated_size += 1; if (write_out) { unsigned char ub = cur->dfe_index; *data = ub; data += 1; } break; case DW_FORM_data2: calculated_size += DWARF_HALF_SIZE; if (write_out) { Dwarf_Half uh = cur->dfe_index; memcpy(data,&uh,DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; } break; case DW_FORM_udata: { unsigned val_len = 0; if (write_out) { res = append_uval(cur->dfe_index, dbg, data, &val_len,error); data += val_len; } else { res = pretend_write_uval(cur->dfe_index, dbg, &val_len,error); } if (res != DW_DLV_OK) { return res; } calculated_size += val_len; } break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; case DW_LNCT_timestamp: { switch(cform) { case DW_FORM_udata: { unsigned val_len = 0; if (write_out) { res = append_uval(cur->dfe_timestamp, dbg, data, &val_len,error); data += val_len; } else { res = pretend_write_uval(cur->dfe_timestamp, dbg, &val_len,error); } if (res != DW_DLV_OK) { return res; } calculated_size += val_len; } break; case DW_FORM_data4: { calculated_size += DWARF_32BIT_SIZE; if (write_out) { ASNOUT(data,cur->dfe_timestamp, DWARF_32BIT_SIZE); data += DWARF_32BIT_SIZE; } } break; case DW_FORM_data8: /* As of 2017 there is no 8 byte timestamp defined, though it does have to happen. before 2038. */ calculated_size += DWARF_64BIT_SIZE; if (write_out) { Dwarf_Unsigned u8 = cur->dfe_index; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &u8, sizeof(u8), DWARF_64BIT_SIZE); data += DWARF_64BIT_SIZE; } break; case DW_FORM_block: default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; case DW_LNCT_size: { switch(cform) { case DW_FORM_data1: calculated_size += 1; if (write_out) { unsigned char ub = cur->dfe_index; *data = ub; data += 1; } break; case DW_FORM_data2: calculated_size += DWARF_HALF_SIZE; if (write_out) { Dwarf_Half uh = cur->dfe_index; memcpy(data,&uh,DWARF_HALF_SIZE); } break; case DW_FORM_data4: calculated_size += DWARF_32BIT_SIZE; if (write_out) { ASNOUT(data,cur->dfe_index, DWARF_32BIT_SIZE); data += DWARF_32BIT_SIZE; } break; case DW_FORM_data8: calculated_size += DWARF_64BIT_SIZE; if (write_out) { Dwarf_Unsigned u8 = cur->dfe_index; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &u8, sizeof(u8), DWARF_64BIT_SIZE); data += DWARF_64BIT_SIZE; } break; case DW_FORM_udata: { unsigned val_len = 0; if (write_out) { res = append_uval(cur->dfe_size, dbg, data, &val_len,error); data += val_len; } else { res = pretend_write_uval(cur->dfe_size, dbg, &val_len,error); } if (res != DW_DLV_OK) { return res; } calculated_size += val_len; } break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; case DW_LNCT_MD5: { switch(cform) { case DW_FORM_data16: if (write_out) { memcpy(data,cur->dfe_md5,sizeof(cur->dfe_md5)); data += 16; } calculated_size += 16; break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); } } break; default: DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_CODE_UNKNOWN, DW_DLV_ERROR); } } } *size_out = calculated_size; return DW_DLV_OK; } static int calculate_size_of_line_header5(Dwarf_P_Debug dbg, struct Dwarf_P_Line_Inits_s *inits, unsigned *prolog_size_out, Dwarf_Error *error) { unsigned prolog_size = 0; int offset_size = dbg->de_dwarf_offset_size; int extension_size = dbg->de_64bit_extension ? 4 : 0; int res = 0; prolog_size += OFFSET_PLUS_EXTENSION_SIZE + sizeof_uhalf(dbg) + /* version # */ sizeof_ubyte(dbg) + /* address_size */ sizeof_ubyte(dbg) + /* segment_selector_size */ offset_size + /* header length */ sizeof_ubyte(dbg) + /* min_instr length */ sizeof_ubyte(dbg) + /* maximum_operations_per_instruction */ sizeof_ubyte(dbg) + /* default is_stmt */ sizeof_ubyte(dbg) + /* linebase */ sizeof_ubyte(dbg) + /* linerange */ sizeof_ubyte(dbg); /* opcode base */ /* For maximum_operations_per_instruction. */ prolog_size += sizeof_ubyte(dbg); /* standard_opcode_lengths table len */ prolog_size += inits->pi_opcode_base-1; { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_directory_entry_format_count, inits->pi_incformats, &fsize,FALSE,0,error); if (res != DW_DLV_OK) { return res; } prolog_size += fsize; } { unsigned dir_count_len = 0; res = determine_file_content_size(dbg, dbg->de_inc_dirs, dbg->de_line_inits.pi_directory_entry_format_count, dbg->de_line_inits.pi_incformats, &dir_count_len, FALSE,0, error); if (res != DW_DLV_OK) { return res; } prolog_size += dir_count_len; } { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_file_entry_format_count, inits->pi_fileformats, &fsize, FALSE,0, error); if (res != DW_DLV_OK) { return res; } prolog_size += fsize; } { unsigned file_count_len = 0; res = determine_file_content_size(dbg, dbg->de_file_entries, dbg->de_line_inits.pi_file_entry_format_count, dbg->de_line_inits.pi_fileformats, &file_count_len, FALSE,0, error); if (res != DW_DLV_OK) { return res; } prolog_size += file_count_len; } *prolog_size_out = prolog_size; return DW_DLV_OK; } /* For DWARF 2,3,4 */ static int calculate_size_of_line_header4(Dwarf_P_Debug dbg, struct Dwarf_P_Line_Inits_s *inits, unsigned *prolog_size_out, UNUSEDARG Dwarf_Error *error) { Dwarf_P_F_Entry curdir = 0; Dwarf_P_F_Entry curentry = 0; unsigned prolog_size = 0; int offset_size = dbg->de_dwarf_offset_size; int extension_size = dbg->de_64bit_extension ? 4 : 0; prolog_size += OFFSET_PLUS_EXTENSION_SIZE + sizeof_uhalf(dbg) + /* version # */ offset_size + /* header length */ sizeof_ubyte(dbg) + /* min_instr length */ sizeof_ubyte(dbg) + /* default is_stmt */ sizeof_ubyte(dbg) + /* linebase */ sizeof_ubyte(dbg) + /* linerange */ sizeof_ubyte(dbg); /* opcode base */ if (inits->pi_linetable_version == DW_LINE_VERSION4) { /* For maximum_operations_per_instruction. */ prolog_size += sizeof_ubyte(dbg); } /* standard_opcode_lengths table len */ prolog_size += inits->pi_opcode_base-1; /* include directories */ curdir = dbg->de_inc_dirs; while (curdir) { prolog_size += strlen(curdir->dfe_name) + 1; curdir = curdir->dfe_next; } prolog_size++; /* last null following last directory entry. */ /* file entries */ curentry = dbg->de_file_entries; while (curentry) { prolog_size += strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; curentry = curentry->dfe_next; } prolog_size++; /* last null byte */ *prolog_size_out = prolog_size; return DW_DLV_OK; } /* Generate debug_line section Dwarf2, dwarf3 headers are the same (DW3 acknowledges 64bit). DWARF4 adds the maximum_operations_per_instruction field. DWARF5 adds address size and address selector size and replaces the entire directories/files list with very different stuff. */ static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Signed * nbufs, Dwarf_Error * error) { Dwarf_P_F_Entry curdir = 0; Dwarf_P_F_Entry curentry = 0; Dwarf_P_Line curline = 0; Dwarf_P_Line prevline = 0; struct Dwarf_P_Line_Inits_s *inits = 0; /* all data named cur* are used to loop thru linked lists */ int sum_bytes = 0; unsigned prolog_size = 0; unsigned char *data = 0; /* holds disk form data */ int elfsectno = 0; unsigned char *start_line_sec = 0; /* pointer to the buffer at section start */ /* temps for memcpy */ Dwarf_Unsigned du = 0; Dwarf_Ubyte db = 0; Dwarf_Half dh = 0; int res = 0; Dwarf_Half version = dbg->de_output_version; int offset_size = dbg->de_dwarf_offset_size; Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0; Dwarf_Ubyte address_size = dbg->de_pointer_size; sum_bytes = 0; elfsectno = dbg->de_elf_sects[DEBUG_LINE]; inits = &dbg->de_line_inits; if (version < 5) { res = calculate_size_of_line_header4(dbg,inits,&prolog_size, error); } else if (version == 5) { res = calculate_size_of_line_header5(dbg,inits,&prolog_size, error); } else { _dwarf_p_error(dbg, error,DW_DLE_VERSION_STAMP_ERROR ); return DW_DLV_ERROR; } if (res != DW_DLV_OK) { return res; } /* Allocate a chunk, put address in 'data' */ GET_CHUNK_ERR(dbg, elfsectno, data, prolog_size, error); start_line_sec = data; /* Copy the prologue data into 'data' */ /* total_length */ du = 0; if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } /* We will adjust this later, we do not know the full length of the line_section content for this cu yet. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; dh = inits->pi_linetable_version; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, sizeof(dh), DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; if (version == 5 ) { /* address size, seg sel size now */ db = inits->pi_address_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(db)); data += sizeof(db); db = inits->pi_segment_size; /* segment selector size */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(db)); data += sizeof(db); } { /* header length (called prolog length in DWARF2) This we do know, we calculated the prolog length already and it is prolog_size so just */ Dwarf_Unsigned sofar = data - start_line_sec; du = prolog_size - sofar - offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; } db = inits->pi_minimum_instruction_length; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); if (inits->pi_linetable_version == 4 || inits->pi_linetable_version == 5) { db = inits->pi_maximum_operations_per_instruction; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); } db = inits->pi_default_is_stmt; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = inits->pi_line_base; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = inits->pi_line_range; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = inits->pi_opcode_base; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len, inits->pi_opcode_base-1, inits->pi_opcode_base-1); data += inits->pi_opcode_base-1; if (version < 5) { /* copy over include directories */ curdir = dbg->de_inc_dirs; while (curdir) { strcpy((char *) data, curdir->dfe_name); data += strlen(curdir->dfe_name) + 1; curdir = curdir->dfe_next; } *data = '\0'; /* last null */ data++; /* copy file entries */ curentry = dbg->de_file_entries; while (curentry) { strcpy((char *) data, curentry->dfe_name); data += strlen(curentry->dfe_name) + 1; /* copies of leb numbers, no endian issues */ memcpy((void *) data, (const void *) curentry->dfe_args, curentry->dfe_nbytes); data += curentry->dfe_nbytes; curentry = curentry->dfe_next; } *data = '\0'; data++; } else if (version == 5) { { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_directory_entry_format_count, inits->pi_incformats, &fsize, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += fsize; } { unsigned dir_count_len = 0; res = determine_file_content_size(dbg, dbg->de_inc_dirs, inits->pi_directory_entry_format_count, inits->pi_incformats, &dir_count_len, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += dir_count_len; } { unsigned fsize = 0; res = determine_form_size(dbg, inits->pi_file_entry_format_count, inits->pi_fileformats, &fsize, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += fsize; } { unsigned file_count_len = 0; res = determine_file_content_size(dbg, dbg->de_file_entries, dbg->de_line_inits.pi_file_entry_format_count, dbg->de_line_inits.pi_fileformats, &file_count_len, TRUE,data, error); if (res != DW_DLV_OK) { return res; } data += file_count_len; } } { Dwarf_Unsigned sofar = data - start_line_sec; if (sofar != prolog_size) { /* We miscalculated something. */ _dwarf_p_error(dbg, error, DW_DLE_LINE_HEADER_LENGTH_BOTCH); return DW_DLV_ERROR; } sum_bytes += prolog_size; } curline = dbg->de_lines; prevline = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (prevline == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } _dwarf_pro_reg_init(dbg,prevline); /* generate opcodes for line numbers */ while (curline) { int opc = 0; int no_lns_copy = 0; /* if lns copy opcode does not need to be generated, if special opcode or end sequence */ Dwarf_Unsigned addr_adv = 0; int line_adv = 0; /* supposed to be a reasonably small number, so the size should not be a problem. ? */ no_lns_copy = 0; if (curline->dpl_opc != 0) { int inst_bytes = 0; /* no of bytes in extended opcode */ unsigned writelen = 0; switch (curline->dpl_opc) { case DW_LNE_end_sequence: /* Advance pc to end of text section. */ addr_adv = curline->dpl_address - prevline->dpl_address; if (addr_adv > 0) { res = write_opcode_uval(DW_LNS_advance_pc,dbg, elfsectno, addr_adv/inits->pi_minimum_instruction_length, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_address = curline->dpl_address; } /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write length of extended opcode */ inst_bytes = sizeof(Dwarf_Ubyte); res = write_uval(inst_bytes,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write extended opcode */ res = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* reset value to original values */ _dwarf_pro_reg_init(dbg,prevline); no_lns_copy = 1; /* this is set only for end_sequence, so that a dw_lns_copy is not generated */ break; case DW_LNE_set_address: /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write length of extended opcode */ inst_bytes = sizeof(Dwarf_Ubyte) + address_size; res = write_uval(inst_bytes,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* write extended opcode */ res = write_ubyte(DW_LNE_set_address,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* reloc for address */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_LINE, sum_bytes, /* r_offset */ curline->dpl_r_symidx, dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, DW_DLV_ERROR); } /* write offset (address) */ du = curline->dpl_address; res = write_fixed_size(du,dbg,elfsectno, address_size,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_address = curline->dpl_address; no_lns_copy = 1; break; case DW_LNE_define_file: /* Not supported, all add-file entries are added via dbg -> de_file_entries, which adds to the line table header. */ no_lns_copy = 1; break; case DW_LNE_set_discriminator: {/* DWARF4 */ unsigned val_len = 0; /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write len of opcode + value here. */ res = pretend_write_uval(curline->dpl_discriminator, dbg, &val_len,error); if (res != DW_DLV_OK) { return res; } val_len++; res = write_uval(val_len +1,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write opcode */ res = write_ubyte(DW_LNE_set_discriminator, dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write the value itself. */ res = write_uval(curline->dpl_discriminator, dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; no_lns_copy = 1; } break; } } else { unsigned writelen = 0; if (inits->pi_opcode_base >12) { /* We have the newer standard opcodes DW_LNS_set_prologue_end, DW_LNS_set_epilogue_end, DW_LNS_set_isa, we do not write them if not in the table. DWARF3 and DWARF4 */ /* Should we check if a change? These reset automatically in the line processing/reading engine, so I think no check of prevline is wanted. */ if (curline->dpl_epilogue_begin) { res = write_ubyte(DW_LNS_set_epilogue_begin,dbg, elfsectno,&writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } if (curline->dpl_prologue_end) { res = write_ubyte(DW_LNS_set_prologue_end,dbg, elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } if (curline->dpl_isa != prevline->dpl_isa) { res = write_opcode_uval(DW_LNS_set_isa,dbg, elfsectno, curline->dpl_isa, &writelen ,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } } if (curline->dpl_file != prevline->dpl_file) { db = DW_LNS_set_file; res = write_opcode_uval(db,dbg, elfsectno, curline->dpl_file,&writelen ,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_file = curline->dpl_file; } if (curline->dpl_column != prevline->dpl_column) { db = DW_LNS_set_column; res = write_opcode_uval(db,dbg, elfsectno, curline->dpl_column , &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_column = curline->dpl_column; } if (curline->dpl_is_stmt != prevline->dpl_is_stmt) { res = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_is_stmt = curline->dpl_is_stmt; } if (curline->dpl_basic_block == true && prevline->dpl_basic_block == false) { res = write_ubyte(DW_LNS_set_basic_block,dbg, elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = curline->dpl_basic_block; } if (curline->dpl_discriminator) { /* This is dwarf4, but because it is an extended op not a standard op, we allow it without testing version. GNU seems to set this from time to time. */ unsigned val_len = 0; /* first null byte */ db = 0; res = write_ubyte(db,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write len of opcode + value here. */ res = pretend_write_uval(curline->dpl_discriminator, dbg, &val_len,error); if (res != DW_DLV_OK) { return res; } val_len ++; res = write_uval(val_len +1,dbg,elfsectno, &writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write opcode */ res = write_ubyte(DW_LNE_set_discriminator, dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; /* Write the value itself. */ res = write_uval(curline->dpl_discriminator, dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; } addr_adv = curline->dpl_address - prevline->dpl_address; line_adv = (int) (curline->dpl_line - prevline->dpl_line); if ((addr_adv % MIN_INST_LENGTH) != 0) { DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, DW_DLV_ERROR); } opc = _dwarf_pro_get_opc(inits,addr_adv, line_adv); if (opc > 0) { /* Use special opcode. */ no_lns_copy = 1; res = write_ubyte(opc,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_address = curline->dpl_address; prevline->dpl_line = curline->dpl_line; } else { /* opc says use standard opcodes. */ if (addr_adv > 0) { db = DW_LNS_advance_pc; res = write_opcode_uval(db,dbg, elfsectno, addr_adv/inits->pi_minimum_instruction_length, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_address = curline->dpl_address; } if (line_adv != 0) { db = DW_LNS_advance_line; res = write_ubyte(db,dbg, elfsectno, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; res = write_sval(line_adv,dbg, elfsectno, &writelen, error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_line = curline->dpl_line; } } } /* ends else for opc <= 0 */ if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq generate a matrix line */ unsigned writelen = 0; res = write_ubyte(DW_LNS_copy,dbg,elfsectno,&writelen,error); if (res != DW_DLV_OK) { return res; } sum_bytes += writelen; prevline->dpl_basic_block = false; } curline = curline->dpl_next; } /* write total length field */ du = sum_bytes - OFFSET_PLUS_EXTENSION_SIZE; { start_line_sec += extension_size; WRITE_UNALIGNED(dbg, (void *) start_line_sec, (const void *) &du, sizeof(du), offset_size); } *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } /* Generate debug_frame section */ static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno = 0; int i = 0; int firsttime = 1; Dwarf_P_Cie curcie = 0; Dwarf_P_Fde curfde = 0; unsigned char *data = 0; Dwarf_Unsigned du = 0; Dwarf_Ubyte db = 0; long *cie_offs = 0; /* Holds byte offsets for links to fde's */ unsigned long cie_length = 0; int cie_no = 0; Dwarf_Ubyte offset_size = dbg->de_dwarf_offset_size; Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0; Dwarf_Ubyte address_size = dbg->de_pointer_size; Dwarf_Unsigned cur_off = 0; /* current offset of written data, held for relocation info */ elfsectno = dbg->de_elf_sects[DEBUG_FRAME]; curcie = dbg->de_frame_cies; cie_length = 0; cie_offs = (long *) _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie); if (cie_offs == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } /* Generate cie number as we go along. This writes all CIEs first before any FDEs, which is rather different from the order a compiler might like (which might be each CIE followed by its FDEs then the next CIE, and so on). */ cie_no = 1; while (curcie) { char *code_al = 0; int codeal_bytes = 0; char *data_al = 0; int data_align_bytes = 0; int pad = 0; /* Pad for padding to align cies and fdes */ int res = 0; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; char buff3[ENCODE_SPACE_NEEDED]; char *augmentation = 0; char *augmented_al = 0; long augmented_fields_length = 0; int irix_auglen_v0 = 0; Dwarf_Half version = curcie->cie_version; res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align, &codeal_bytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } /* Before April 1999, the following was using an unsigned encode. That worked ok even though the decoder used the correct signed leb read, but doing the encode correctly (according to the dwarf spec) saves space in the output file and is completely compatible. Note the actual stored amount on MIPS was 10 bytes (!) to store the value -4. (hex)fc ffffffff ffffffff 01 The libdwarf consumer consumed all 10 bytes too! old version res = _dwarf_pro_encode_leb128_nm(curcie->cie_data_align, below is corrected signed version. */ res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align, &data_align_bytes, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } code_al = buff1; data_al = buff2; /* get the correct offset */ if (firsttime) { cie_offs[cie_no - 1] = 0; firsttime = 0; } else { cie_offs[cie_no - 1] = cie_offs[cie_no - 2] + (long) cie_length + OFFSET_PLUS_EXTENSION_SIZE; } cie_no++; augmentation = curcie->cie_aug; cie_length = offset_size + /* cie_id */ sizeof(Dwarf_Ubyte) + /* cie version */ strlen(curcie->cie_aug) + 1 + /* augmentation */ codeal_bytes + /* code alignment factor */ data_align_bytes + /* data alignment factor */ sizeof(Dwarf_Ubyte) + /* return reg address */ curcie->cie_inst_bytes; if (dbg->de_irix_exc_augmentation && (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0)) { /* IRIX specific. */ augmented_fields_length = 0; res = _dwarf_pro_encode_leb128_nm(augmented_fields_length, &irix_auglen_v0, buff3, sizeof(buff3)); augmented_al = buff3; if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } cie_length += irix_auglen_v0 ; /* augmentation length */ } if (version >= 4) { /* address size, segment selector size */ cie_length += 1 +1; } pad = (int) PADDING(cie_length, address_size); cie_length += pad; /* Now we have the cie length with padding, allocate a buffer for that plus the header length. */ GET_CHUNK_ERR(dbg, elfsectno, data, cie_length + OFFSET_PLUS_EXTENSION_SIZE, error); if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } du = cie_length; /* total length of cie */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; /* cie-id is a special value. */ du = DW_CIE_ID; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; db = curcie->cie_version; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); strcpy((char *) data, curcie->cie_aug); data += strlen(curcie->cie_aug) + 1; if (curcie->cie_version >= 4) { /* emit address-size, segment selector size */ db = dbg->de_pointer_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); db = dbg->de_segment_selector_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); } memcpy((void *) data, (const void *) code_al, codeal_bytes); data += codeal_bytes; memcpy((void *) data, (const void *) data_al, data_align_bytes); data += data_align_bytes; db = curcie->cie_ret_reg; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); if (dbg->de_irix_exc_augmentation && strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { /* IRIX only */ memcpy((void *) data, (const void *) augmented_al, irix_auglen_v0); data += irix_auglen_v0; } memcpy((void *) data, (const void *) curcie->cie_inst, curcie->cie_inst_bytes); data += curcie->cie_inst_bytes; for (i = 0; i < pad; i++) { *data = DW_CFA_nop; data++; } curcie = curcie->cie_next; } /* calculate current offset */ cur_off = cie_offs[cie_no - 2] + cie_length + OFFSET_PLUS_EXTENSION_SIZE; /* write out fde's */ curfde = dbg->de_frame_fdes; while (curfde) { Dwarf_P_Frame_Pgm curinst = 0; long fde_length = 0; int pad2 = 0; Dwarf_P_Cie cie_ptr = 0; Dwarf_Unsigned cie_index = 0; /* index is a global in string.h, so don't name anything index. */ Dwarf_Unsigned indx = 0; int oet_length = 0; int afl_length = 0; int res = 0; int v0_augmentation = 0; char afl_buff[ENCODE_SPACE_NEEDED]; /* Find the CIE associated with this fde. */ cie_ptr = dbg->de_frame_cies; cie_index = curfde->fde_cie; indx = 1; /* The cie_index of the first cie is 1, not 0. */ while (cie_ptr && indx < cie_index) { cie_ptr = cie_ptr->cie_next; indx++; } if (cie_ptr == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, DW_DLV_ERROR); } fde_length = curfde->fde_n_bytes + OFFSET_PLUS_EXTENSION_SIZE + /* cie pointer */ address_size + /* initial loc */ address_size; /* address range */ if (dbg->de_irix_exc_augmentation && strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { v0_augmentation = 1; oet_length = DWARF_32BIT_SIZE; /* encode the length of augmented fields. */ res = _dwarf_pro_encode_leb128_nm(oet_length, &afl_length, afl_buff, sizeof(afl_buff)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } fde_length += afl_length + /* augmented field length */ oet_length; /* exception_table offset */ } if (curfde->fde_die) { /* IRIX/MIPS extension: Using fde offset, generate DW_AT_MIPS_fde attribute for the die corresponding to this fde. */ res = _dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error); if (res != DW_DLV_OK) { return res; } } /* store relocation for cie pointer */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_FRAME, cur_off + OFFSET_PLUS_EXTENSION_SIZE /* r_offset */, dbg->de_sect_name_idx[DEBUG_FRAME], dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res ); } /* store relocation information for initial location */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_FRAME, cur_off + OFFSET_PLUS_EXTENSION_SIZE + address_size /* r_offset */, curfde->fde_r_symidx, dwarf_drt_data_reloc, address_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res); } /* Store the relocation information for the offset_into_exception_info field, if the offset is valid (0 is a valid offset). */ if (v0_augmentation && curfde->fde_offset_into_exception_tables >= 0) { res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_FRAME, /* r_offset, where in cie this field starts */ cur_off + OFFSET_PLUS_EXTENSION_SIZE + offset_size + 2 * address_size + afl_length, curfde->fde_exception_table_symbol, dwarf_drt_segment_rel, DWARF_32BIT_SIZE); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res); } } /* adjust for padding */ pad2 = (int) PADDING(fde_length, address_size); fde_length += pad2; /* write out fde */ GET_CHUNK(dbg, elfsectno, data, fde_length + OFFSET_PLUS_EXTENSION_SIZE, error); du = fde_length; { if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } /* length */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; /* offset to cie */ du = cie_offs[curfde->fde_cie - 1]; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; du = curfde->fde_initloc; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), address_size); data += address_size; if (dbg->de_relocate_pair_by_symbol && curfde->fde_end_symbol != 0 && curfde->fde_addr_range == 0) { /* symbolic reloc, need reloc for length What if we really know the length? If so, should use the other part of 'if'. */ Dwarf_Unsigned val; res = dbg->de_relocate_pair_by_symbol(dbg, DEBUG_FRAME, cur_off + 2 * offset_size + address_size, /* r_offset */ curfde->fde_r_symidx, curfde->fde_end_symbol, dwarf_drt_first_of_length_pair, address_size); if (res != DW_DLV_OK) { { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } } /* arrange pre-calc so assem text can do .word end - begin + val (gets val from stream) */ val = curfde->fde_end_symbol_offset - curfde->fde_initloc; WRITE_UNALIGNED(dbg, data, (const void *) &val, sizeof(val), address_size); data += address_size; } else { du = curfde->fde_addr_range; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), address_size); data += address_size; } } if (v0_augmentation) { /* IRIX only. */ /* write the encoded augmented field length. */ Dwarf_Signed dsw = 0; memcpy((void *) data, (const void *) afl_buff, afl_length); data += afl_length; /* write the offset_into_exception_tables field. */ dsw = (Dwarf_Signed)curfde->fde_offset_into_exception_tables; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw, sizeof(dsw), DWARF_32BIT_SIZE); data += DWARF_32BIT_SIZE; } curinst = curfde->fde_inst; if (curfde->fde_block) { unsigned long size = curfde->fde_inst_block_size; memcpy((void *) data, (const void *) curfde->fde_block, size); data += size; } else { while (curinst) { db = curinst->dfp_opcode; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); memcpy((void *) data, (const void *) curinst->dfp_args, curinst->dfp_nbytes); data += curinst->dfp_nbytes; curinst = curinst->dfp_next; } } /* padding */ for (i = 0; i < pad2; i++) { *data = DW_CFA_nop; data++; } cur_off += fde_length + offset_size; curfde = curfde->fde_next; } *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } /* These functions remember all the markers we see along with the right offset in the .debug_info section so that we can dump them all back to the user with the section info. */ static int marker_init(Dwarf_P_Debug dbg, unsigned count) { dbg->de_marker_n_alloc = count; dbg->de_markers = NULL; if (count > 0) { dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) * dbg->de_marker_n_alloc); if (dbg->de_markers == NULL) { dbg->de_marker_n_alloc = 0; return DW_DLV_ERROR; } } return DW_DLV_OK; } static int marker_add(Dwarf_P_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned marker) { if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) { unsigned n = dbg->de_marker_n_used++; dbg->de_markers[n].ma_offset = offset; dbg->de_markers[n].ma_marker = marker; return DW_DLV_OK; } return DW_DLV_ERROR; } Dwarf_Signed dwarf_get_die_markers(Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, /* pointer to a pointer */ Dwarf_Unsigned * marker_count, Dwarf_Error * error) { int res = 0; res = dwarf_get_die_markers_a(dbg,marker_list,marker_count, error); if (res == DW_DLV_ERROR) { return DW_DLV_BADADDR; } return 0; } int dwarf_get_die_markers_a(Dwarf_P_Debug dbg, Dwarf_P_Marker * marker_list, /* pointer to a pointer */ Dwarf_Unsigned * marker_count, Dwarf_Error * error) { if (marker_list == NULL || marker_count == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) { DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR); } *marker_list = dbg->de_markers; *marker_count = dbg->de_marker_n_used; return DW_DLV_OK; } /* These functions provide the offsets of DW_FORM_string attributes in the section section_index. These information will enable a producer app that is generating assembly text output to easily emit those attributes in ascii form without having to decode the byte stream. */ static int string_attr_init (Dwarf_P_Debug dbg, Dwarf_Signed section_index, unsigned count) { Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; sect_sa->sect_sa_n_alloc = count; sect_sa->sect_sa_list = NULL; if (count > 0) { sect_sa->sect_sa_section_number = section_index; sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_String_Attr_s) * sect_sa->sect_sa_n_alloc); if (sect_sa->sect_sa_list == NULL) { sect_sa->sect_sa_n_alloc = 0; return DW_DLV_ERROR; } } return DW_DLV_OK; } static int string_attr_add (Dwarf_P_Debug dbg, Dwarf_Signed section_index, Dwarf_Unsigned offset, Dwarf_P_Attribute attr) { Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) { unsigned n = sect_sa->sect_sa_n_used++; sect_sa->sect_sa_list[n].sa_offset = offset; sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes; return DW_DLV_OK; } return DW_DLV_ERROR; } int dwarf_get_string_attributes_count(Dwarf_P_Debug dbg, Dwarf_Unsigned * count_of_sa_sections, int *drd_buffer_version, UNUSEDARG Dwarf_Error *error) { int i = 0; unsigned int count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) { ++count; } } *count_of_sa_sections = (Dwarf_Unsigned) count; *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; return DW_DLV_OK; } int dwarf_get_string_attributes_info(Dwarf_P_Debug dbg, Dwarf_Signed *elf_section_index, Dwarf_Unsigned *sect_sa_buffer_count, Dwarf_P_String_Attr *sect_sa_buffer, UNUSEDARG Dwarf_Error *error) { int i = 0; int next = dbg->de_sect_sa_next_to_return; for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i]; if (sect_sa->sect_sa_n_used > 0) { dbg->de_sect_sa_next_to_return = i + 1; *elf_section_index = sect_sa->sect_sa_section_number; *sect_sa_buffer_count = sect_sa->sect_sa_n_used; *sect_sa_buffer = sect_sa->sect_sa_list; return DW_DLV_OK; } } return DW_DLV_NO_ENTRY; } static int has_sibling_die_already(Dwarf_P_Die d) { Dwarf_P_Attribute a = 0; for(a = d->di_attrs; a ; a = a->ar_next) { if(a->ar_attribute == DW_AT_sibling) { return TRUE; } } return FALSE; } /* For DW_FORM_strp we need to set the symindex so we need to check that such applies. */ static int if_relocatable_string_form(Dwarf_P_Debug dbg, Dwarf_P_Attribute curattr, int *debug_str_reloc, Dwarf_Error *error) { if (curattr->ar_rel_type == R_MIPS_NONE) { *debug_str_reloc = 0; return DW_DLV_OK; } if (curattr->ar_attribute_form != DW_FORM_strp) { _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL); return DW_DLV_ERROR; } if (curattr->ar_rel_type != dbg->de_offset_reloc) { _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL); return DW_DLV_ERROR; } *debug_str_reloc = 1; return DW_DLV_OK; } /* Tries to see if given attribute and form combination of the attr exists in the given abbreviation. abbrevs and attrs are sorted in attrnum order. */ static int _dwarf_pro_match_attr(Dwarf_P_Attribute attr, Dwarf_P_Abbrev abbrev, int no_attr) { int i = 0; Dwarf_P_Attribute curatp = attr; for (i = 0; i < no_attr && curatp; i++,curatp = curatp->ar_next ) { if (curatp->ar_attribute != abbrev->abb_attrs[i] || curatp->ar_attribute_form != abbrev->abb_forms[i]) { return 0; } /* If either is implicit_const need special check for matching val. */ if (curatp->ar_attribute_form == DW_FORM_implicit_const) { if (abbrev->abb_forms[i] == DW_FORM_implicit_const) { if (curatp->ar_implicit_const != abbrev->abb_implicits[i]) { return 0; } } else { return 0; } } else { if (abbrev->abb_forms[i] == DW_FORM_implicit_const) { return 0; } } } return 1; } static int verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s *sortab, int attrcount) { int k = 0; unsigned preva = 0; struct Dwarf_Sort_Abbrev_s *ab = sortab; if (attrcount < 2) { return DW_DLV_OK; } for(k = 0; k < attrcount; ++k,++ab) { if (k) { if (preva >= ab->dsa_attr) { return DW_DLV_ERROR; } } preva = ab->dsa_attr; } return DW_DLV_OK; } static int abcompare(const void *l_in, const void *r_in) { struct Dwarf_Sort_Abbrev_s *l = (struct Dwarf_Sort_Abbrev_s *)l_in; struct Dwarf_Sort_Abbrev_s *r = (struct Dwarf_Sort_Abbrev_s *)r_in; if (l->dsa_attr < r->dsa_attr) { return -1; } if (l->dsa_attr > r->dsa_attr) { return +1; } /* ASSERT: This never happens in correct dwarf. */ return 0; } /* Handles abbreviations. It takes a die, searches through current list of abbreviations for a matching one. If it finds one, it returns a pointer to the abbrev through the ab_out pointer, and if it does not, it returns a new abbrev through the ab_out pointer. The die->die_attrs are sorted by attribute and the curabbrev attrs are too. It is up to the user of this function to link it up to the abbreviation head. If it is a new abbrev abb_idx has 0. */ static int _dwarf_pro_getabbrev(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_P_Abbrev head, Dwarf_P_Abbrev*ab_out,Dwarf_Error *error) { Dwarf_P_Abbrev curabbrev = 0; Dwarf_P_Attribute curattr = 0; int match = 0; Dwarf_Unsigned *forms = 0; Dwarf_Unsigned *attrs = 0; Dwarf_Signed *implicits = 0; int attrcount = die->di_n_attr; curabbrev = head; /* Loop thru the currently known abbreviations needed to see if we can share an existing abbrev. */ while (curabbrev) { if ((die->di_tag == curabbrev->abb_tag) && ((die->di_child != NULL && curabbrev->abb_children == DW_CHILDREN_yes) || (die->di_child == NULL && curabbrev->abb_children == DW_CHILDREN_no)) && (attrcount == curabbrev->abb_n_attr)) { /* There is a chance of a match, basic characterists match. Now Check the attrs and forms. */ curattr = die->di_attrs; match = _dwarf_pro_match_attr(curattr, curabbrev, (int) curabbrev->abb_n_attr); if (match == 1) { /* This tag/children/abbrev-list matches the incoming die needs exactly. Reuse this abbreviation. */ *ab_out = curabbrev; return DW_DLV_OK; } } curabbrev = curabbrev->abb_next; } /* no match, create new abbreviation */ if (attrcount) { forms = (Dwarf_Unsigned *) _dwarf_p_get_alloc(die->di_dbg, sizeof(Dwarf_Unsigned) * attrcount); if (forms == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } attrs = (Dwarf_Unsigned *) _dwarf_p_get_alloc(die->di_dbg, sizeof(Dwarf_Unsigned) * attrcount); if (attrs == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } implicits = (Dwarf_Signed *) _dwarf_p_get_alloc(die->di_dbg, sizeof(Dwarf_Signed) * attrcount); if (implicits == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } } curattr = die->di_attrs; if (forms && attrs && attrcount) { struct Dwarf_Sort_Abbrev_s *sortab = 0; struct Dwarf_Sort_Abbrev_s *ap = 0; int k = 0; int res = 0; sortab = (struct Dwarf_Sort_Abbrev_s *) malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount); if(!sortab) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } /* ASSERT curattr->ar_next chain length == attrcount */ ap = sortab; for(; curattr; ++ap, curattr = curattr->ar_next) { ap->dsa_attr = curattr->ar_attribute; ap->dsa_form = curattr->ar_attribute_form; ap->dsa_implicitvalue = curattr->ar_implicit_const; ap->dsa_attrp = 0; } qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s), abcompare); ap = sortab; k = 0; res = verify_ab_no_dups(sortab,attrcount); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg,DW_DLE_DUP_ATTR_ON_DIE,DW_DLV_ERROR); } for( ; k < attrcount; ++k,++ap) { attrs[k] = ap->dsa_attr; forms[k] = ap->dsa_form; implicits[k] = ap->dsa_implicitvalue; } free(sortab); } curabbrev = (Dwarf_P_Abbrev) _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s)); if (curabbrev == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } if (die->di_child == NULL) { curabbrev->abb_children = DW_CHILDREN_no; } else { curabbrev->abb_children = DW_CHILDREN_yes; } curabbrev->abb_tag = die->di_tag; curabbrev->abb_attrs = attrs; curabbrev->abb_forms = forms; curabbrev->abb_implicits = implicits; curabbrev->abb_n_attr = attrcount; curabbrev->abb_idx = 0; curabbrev->abb_next = NULL; *ab_out = curabbrev; return DW_DLV_OK; } /* Generate debug_info and debug_abbrev sections */ /* DWARF 2,3,4 */ static int generate_debuginfo_header_2(Dwarf_P_Debug dbg, unsigned *abbrev_offset_io, unsigned char **data_io, int *cu_header_size_out, Dwarf_Small **abbr_off_ptr_out, Dwarf_Half version, int extension_size, Dwarf_Ubyte address_size, Dwarf_Error * error) { unsigned abbrev_offset = 0; unsigned char * data = 0; int offset_size = dbg->de_dwarf_offset_size; int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; int cu_header_size = 0; Dwarf_Unsigned du = 0; Dwarf_Small *abbr_off_ptr = 0; /* write cu header. abbrev_offset used to generate relocation record below */ abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE + DWARF_HALF_SIZE ; cu_header_size = abbrev_offset + offset_size + sizeof(Dwarf_Ubyte); GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size, error); if (extension_size) { /* This for a dwarf-standard 64bit offset. */ DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } abbr_off_ptr = data; du = 0; /* length of debug_info, not counting this field itself (unknown at this point). */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, sizeof(version), DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; du = 0;/* offset into abbrev table, not yet known. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size, sizeof(address_size), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); /* We have filled the chunk we got with GET_CHUNK. At this point we no longer dare use "data" as a pointer any longer except to refer to that first small chunk for the cu header to update the section length. */ *abbrev_offset_io = abbrev_offset; *data_io = data; *cu_header_size_out = cu_header_size; *abbr_off_ptr_out = abbr_off_ptr; return DW_DLV_OK; } /* DWARF 5 */ static int generate_debuginfo_header_5(Dwarf_P_Debug dbg, unsigned *abbrev_offset_io, unsigned char **data_io, int *cu_header_size_out, Dwarf_Small **abbr_off_ptr_out, Dwarf_Half version, Dwarf_Ubyte unit_type, int extension_size, Dwarf_Ubyte address_size, Dwarf_Error *error) { int offset_size = dbg->de_dwarf_offset_size; unsigned abbrev_offset = 0; unsigned char * data = 0; int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; int cu_header_size = 0; Dwarf_Unsigned du = 0; Dwarf_Small *abbr_off_ptr = 0; /* write cu header. abbrev_offset used to generate relocation record below */ abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE + DWARF_HALF_SIZE + /* version stamp */ sizeof(unit_type) + sizeof(Dwarf_Ubyte); cu_header_size = abbrev_offset + offset_size; GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size, error); if (extension_size) { /* Impossible in DW5, really, is for IRIX64. But we allow it. */ DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } abbr_off_ptr = data; du = 0; /* length of debug_info, not counting this field itself (unknown at this point). */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, sizeof(version), DWARF_HALF_SIZE); data += DWARF_HALF_SIZE; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &unit_type, sizeof(unit_type), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size, sizeof(address_size), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); du = 0;/* offset into abbrev table, not yet known. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), offset_size); data += offset_size; /* We have filled the chunk we got with GET_CHUNK. At this point we no longer dare use "data" as a pointer any longer except to refer to that first small chunk for the cu header to update the section length. */ *abbrev_offset_io = abbrev_offset; *data_io = data; *cu_header_size_out = cu_header_size; *abbr_off_ptr_out = abbr_off_ptr; return DW_DLV_OK; } /* Write out debug_abbrev section */ static int write_out_debug_abbrev(Dwarf_P_Debug dbg, Dwarf_P_Abbrev abbrev_head, Dwarf_Error * error) { Dwarf_P_Abbrev curabbrev = abbrev_head; unsigned char *data = 0; int res = 0; int abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; while (curabbrev) { int idx = 0; unsigned lebcount = 0; Dwarf_Ubyte db = 0; res = write_uval(curabbrev->abb_idx,dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } res = write_uval(curabbrev->abb_tag,dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } db = curabbrev->abb_children; res = write_ubyte(db,dbg,abbrevsectno,&lebcount,error); if (res != DW_DLV_OK) { return res; } /* add attributes and forms */ for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { res =write_uval(curabbrev->abb_attrs[idx], dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } res =write_uval(curabbrev->abb_forms[idx], dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } if (curabbrev->abb_forms[idx] == DW_FORM_implicit_const){ res =write_sval(curabbrev->abb_implicits[idx], dbg,abbrevsectno, &lebcount,error); if (res != DW_DLV_OK) { return res; } } } /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */ GET_CHUNK_ERR(dbg, abbrevsectno, data, 2, error); *data = 0; data++; *data = 0; curabbrev = curabbrev->abb_next; } /* one zero, for end of cu, see dwarf2 sec 7.5.3 */ GET_CHUNK_ERR(dbg, abbrevsectno, data, 1, error); *data = 0; return DW_DLV_OK; } static int sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die, Dwarf_Error *error) { struct Dwarf_Sort_Abbrev_s *sortab = 0; struct Dwarf_Sort_Abbrev_s *ap = 0; Dwarf_P_Attribute at = 0; Dwarf_P_Attribute sorted_attrlist = 0; Dwarf_P_Attribute sorted_tail = 0; int attrcount = die->di_n_attr; int res = 0; unsigned ct = 0; int k = 0; if (attrcount < 2) { return DW_DLV_OK; } sortab = (struct Dwarf_Sort_Abbrev_s *) malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount); if(!sortab) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } /* ASSERT at->ar_next chain length == attrcount */ ap = sortab; at = die->di_attrs; for(; at; ++ap, at = at->ar_next) { ap->dsa_attr = at->ar_attribute; ap->dsa_form = at->ar_attribute_form; ap->dsa_attrp = at; ++ct; } qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s), abcompare); res = verify_ab_no_dups(sortab,attrcount); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DUP_ATTR_ON_DIE, DW_DLV_ERROR); } ap = sortab; k = 0; for( ; k < attrcount; ++k,++ap) { Dwarf_P_Attribute localptr = ap->dsa_attrp; if (!sorted_attrlist) { sorted_attrlist = localptr; sorted_tail = sorted_attrlist; localptr->ar_next = 0; continue; } sorted_tail->ar_next = localptr; sorted_tail = localptr; localptr->ar_next = 0; } /* Now replace the list with the same pointers but in order sorted by attribute. */ die->di_attrs = sorted_attrlist; free(sortab); return DW_DLV_OK; } static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno_of_debug_info = 0; unsigned char *data = 0; int cu_header_size = 0; Dwarf_P_Abbrev curabbrev = 0; Dwarf_P_Abbrev abbrev_head = 0; Dwarf_P_Abbrev abbrev_tail = 0; Dwarf_P_Die curdie = 0; Dwarf_P_Die first_child = 0; Dwarf_Unsigned dw = 0; Dwarf_Unsigned du = 0; Dwarf_Half dh = 0; Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */ int n_abbrevs = 0; unsigned abbrev_offset = 0; int res = 0; unsigned marker_count = 0; unsigned string_attr_count = 0; unsigned string_attr_offset = 0; Dwarf_Small *abbr_off_ptr = 0; int offset_size = dbg->de_dwarf_offset_size; /* extension_size is oddly names. The standard calls for a 64bit offset to have a 4 byte 0xffff while original IRIX64 did not. So if dbg->de_64bit_extension set this is a standard DWARF 64bit offset and if de_64bit_extension not set this is non-standard IRIX64 64 bit offset. */ Dwarf_Half version = dbg->de_output_version; int extension_size = dbg->de_64bit_extension ? 4 : 0; /* For now just assume DW_UT_compile FIXME */ Dwarf_Ubyte unit_type = DW_UT_compile; Dwarf_Ubyte address_size = 0; elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; address_size = dbg->de_pointer_size; if (version < 5) { res = generate_debuginfo_header_2(dbg, &abbrev_offset, &data, &cu_header_size, &abbr_off_ptr, version, extension_size, address_size, error); if (res != DW_DLV_OK) { return res; } } else if (version == 5) { res = generate_debuginfo_header_5(dbg, &abbrev_offset, &data, &cu_header_size, &abbr_off_ptr, version, unit_type, extension_size, address_size, error); if (res != DW_DLV_OK) { return res; } } else { DWARF_P_DBG_ERROR(dbg, DW_DLE_VERSION_STAMP_ERROR, DW_DLV_ERROR); } curdie = dbg->de_dies; /* Create AT_macro_info if appropriate */ if( version < 5) { if (dbg->de_first_macinfo != NULL) { res = _dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error); if (res != DW_DLV_OK) { return res; } } } else { /* FIXME need to add code to emit DWARF5 macro data. */ #if 0 res = _dwarf_pro_add_AT_macro5_info(dbg, curdie, 0, error); #endif } /* Create AT_stmt_list attribute if necessary */ if (dwarf_need_debug_line_section(dbg) == TRUE) { res =_dwarf_pro_add_AT_stmt_list(dbg, curdie, error); if (res != DW_DLV_OK) { return res; } } die_off = cu_header_size; /* Relocation for abbrev offset in cu header store relocation record in linked list */ res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_INFO, abbrev_offset /* r_offset */, dbg->de_sect_name_idx[DEBUG_ABBREV], dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } /* Pass 0: only top level dies, add at_sibling attribute to those dies with children, but if and only if there is no sibling attribute already. */ first_child = curdie->di_child; while (first_child && first_child->di_right) { if (first_child->di_child) { if (!has_sibling_die_already(first_child)) { dwarf_add_AT_reference(dbg, first_child, DW_AT_sibling, first_child->di_right, error); } } first_child = first_child->di_right; } /* Pass 1: create abbrev info, get die offsets, calc relocations */ abbrev_head = abbrev_tail = NULL; marker_count = 0; string_attr_count = 0; while (curdie != NULL) { int nbytes = 0; Dwarf_P_Attribute curattr = 0; char *space = 0; int cres = 0; char buff1[ENCODE_SPACE_NEEDED]; curdie->di_offset = die_off; if (curdie->di_marker != 0) { marker_count++; } cres =sort_die_attrs(dbg,curdie,error); if (cres != DW_DLV_OK) { /* DW_DLV_NO_ENTRY is impossible. */ return cres; } /* Find or create a final abbrev record for the debug_abbrev section we will write (below). */ cres = _dwarf_pro_getabbrev(dbg,curdie, abbrev_head,&curabbrev, error); if (cres != DW_DLV_OK) { return cres; } if (abbrev_head == NULL) { n_abbrevs = 1; curabbrev->abb_idx = n_abbrevs; abbrev_tail = abbrev_head = curabbrev; } else { /* Check if it is a new abbreviation, if yes, add to tail */ if (curabbrev->abb_idx == 0) { n_abbrevs++; curabbrev->abb_idx = n_abbrevs; abbrev_tail->abb_next = curabbrev; abbrev_tail = curabbrev; } } /* We know the abbrev number to use now. So create the bytes of the leb with the value and save those bytes in di_abbrev, we will emit in Pass 2 (below). */ cres = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes, buff1, sizeof(buff1)); if (cres != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } space = _dwarf_p_get_alloc(dbg, nbytes); if (space == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } memcpy(space, buff1, nbytes); curdie->di_abbrev = space; curdie->di_abbrev_nbytes = nbytes; die_off += nbytes; /* The abbrev and DIE attr lists match, so the die abbrevs are in the correct order, curdie->di_attrs. */ /* Now we attach the attributes list to the die. */ curattr = curdie->di_attrs; while (curattr) { if (curattr->ar_rel_type != R_MIPS_NONE) { int rres=0; switch (curattr->ar_attribute) { case DW_AT_stmt_list: curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_LINE]; break; case DW_AT_MIPS_fde: curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_FRAME]; break; case DW_AT_macro_info: curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_MACINFO]; break; /* See also: pro_forms.c for same strings attribute list. */ case DW_AT_comp_dir: case DW_AT_const_value: case DW_AT_linkage_name: /* DWARF5 */ case DW_AT_MIPS_abstract_name: case DW_AT_MIPS_linkage_name: case DW_AT_name: case DW_AT_producer: { int is_debug_str = 0; int nres = if_relocatable_string_form(dbg,curattr, &is_debug_str,error); if (nres != DW_DLV_OK) { return res; } if (is_debug_str) { curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_STR]; } } break; default: break; } rres = dbg->de_relocate_by_name_symbol(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset,/* r_offset */ curattr->ar_rel_symidx, dwarf_drt_data_reloc, curattr->ar_reloc_len); if (rres != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } } if (curattr->ar_attribute_form == DW_FORM_string) { string_attr_count++; } die_off += curattr->ar_nbytes; curattr = curattr->ar_next; } /* Depth first access to all the DIEs. */ if (curdie->di_child) { curdie = curdie->di_child; } else { while (curdie != NULL && curdie->di_right == NULL) { curdie = curdie->di_parent; /* See -nonrootsibling- below */ if (curdie != NULL) { die_off++; } } if (curdie != NULL) { curdie = curdie->di_right; } } } /* end while (curdie != NULL), the per-die loop */ res = marker_init(dbg, marker_count); if (res == DW_DLV_ERROR) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } res = string_attr_init(dbg, DEBUG_INFO, string_attr_count); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } /* Pass 2: Write out the die information Here 'data' is a temporary, one block for each GET_CHUNK. 'data' is overused. */ curdie = dbg->de_dies; while (curdie != NULL) { Dwarf_P_Attribute curattr; if (curdie->di_marker != 0) { res = marker_add(dbg, curdie->di_offset, curdie->di_marker); if (res == DW_DLV_ERROR) { DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } } /* Index to abbreviation table */ GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, curdie->di_abbrev_nbytes, error); memcpy((void *) data, (const void *) curdie->di_abbrev, curdie->di_abbrev_nbytes); /* Attribute values - need to fill in all form attributes */ curattr = curdie->di_attrs; string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes; while (curattr) { GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, (unsigned long) curattr->ar_nbytes, error); switch (curattr->ar_attribute_form) { case DW_FORM_ref1: { Dwarf_Ubyte db = 0; if (curattr->ar_ref_die->di_offset > (unsigned) 0xff) { DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } db = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); break; } case DW_FORM_ref2: { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffff) { DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } dh = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, sizeof(dh), DWARF_HALF_SIZE); break; } case DW_FORM_ref_addr: { /* curattr->ar_ref_die == NULL! DW_FORM_ref_addr doesn't take a CU-offset. This is different than other refs. This value will be set by the user of the producer library using a relocation. No need to set a value here. */ break; } case DW_FORM_ref4: { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffffffff) { DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } dw = (Dwarf_Unsigned) curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dw, sizeof(dw), DWARF_32BIT_SIZE); break; } case DW_FORM_ref8: du = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, sizeof(du), DWARF_64BIT_SIZE); break; case DW_FORM_ref_udata: { /* unsigned leb128 offset */ int nbytesx; char buff1[ENCODE_SPACE_NEEDED]; res = _dwarf_pro_encode_leb128_nm(curattr-> ar_ref_die-> di_offset, &nbytesx, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } memcpy(data, buff1, nbytesx); break; } default: if(curattr->ar_nbytes) { memcpy((void *) data, (const void *) curattr->ar_data, curattr->ar_nbytes); } break; } if (curattr->ar_attribute_form == DW_FORM_string) { string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr); } string_attr_offset += curattr->ar_nbytes; curattr = curattr->ar_next; } /* depth first search */ if (curdie->di_child) { curdie = curdie->di_child; } else { while (curdie != NULL && curdie->di_right == NULL) { /* -nonrootsibling- A null die should only be written for terminating siblings, not the root. Adding a terminating die for the root will cause, after object files are linked, warnings to be generated with newer versions of readelf. */ if (!curdie->di_parent) { /* The parent is not a DIE so ending a sibling chain makes no sense (wastes a byte). */ break; } GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, 1, error); *data = '\0'; curdie = curdie->di_parent; } if (curdie != NULL) curdie = curdie->di_right; } } /* end while (curdir != NULL) */ /* Write out debug_info size, now that we know it This is back-patching the CU header we created above. */ du = die_off - OFFSET_PLUS_EXTENSION_SIZE; WRITE_UNALIGNED(dbg, (void *) abbr_off_ptr, (const void *) &du, sizeof(du), offset_size); data = 0; /* Emphasise not usable now */ res = write_out_debug_abbrev(dbg, abbrev_head, error); if (res != DW_DLV_OK) { return res; } *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed *nbufs, Dwarf_Error * error UNUSEDARG) { #if 0 int elfsectno_of_debug_names = dbg->de_elf_sects[DEBUG_NAMES]; FIXME: Needs implementation unsigned char *data = 0; GET_CHUNK(dbg, elfsectno_of_debug_names, data, dbg->de_debug_names->ds_nbytes, error); memcpy(data,dbg->de_debug_names->ds_data,dbg->de_debug_names->ds_nbytes); #endif *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno_of_debug_str = 0; unsigned char *data = 0; elfsectno_of_debug_str = dbg->de_elf_sects[DEBUG_STR]; GET_CHUNK(dbg, elfsectno_of_debug_str, data, dbg->de_debug_str->ds_nbytes, error); memcpy(data,dbg->de_debug_str->ds_data,dbg->de_debug_str->ds_nbytes); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } static int _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error) { int elfsectno_of_debug_line_str = 0; unsigned char *data = 0; elfsectno_of_debug_line_str = dbg->de_elf_sects[DEBUG_LINE_STR]; GET_CHUNK(dbg, elfsectno_of_debug_line_str, data, dbg->de_debug_line_str->ds_nbytes, error); memcpy(data,dbg->de_debug_line_str->ds_data, dbg->de_debug_line_str->ds_nbytes); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } /* Get a buffer of section data. section_idx is the elf-section number that this data applies to. length shows length of returned data This is the original format. Hard to check for error. */ /*ARGSUSED*/ /* pretend all args used */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed dwarf_section, Dwarf_Signed * section_idx, Dwarf_Unsigned * length, Dwarf_Error * error) { Dwarf_Ptr s_bytes = 0; int res = 0; res = dwarf_get_section_bytes_a(dbg, dwarf_section, section_idx, length, &s_bytes, error); if (res == DW_DLV_ERROR) { return (Dwarf_Ptr)DW_DLV_BADADDR; } if (res == DW_DLV_NO_ENTRY) { return NULL; } return s_bytes; } /* Get a buffer of section data. section_idx is the elf-section number that this data applies to. length shows length of returned data This is the September 2016 format. Preferred. */ int dwarf_get_section_bytes_a(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed dwarf_section, Dwarf_Signed * section_idx, Dwarf_Unsigned * length, Dwarf_Ptr * section_bytes, Dwarf_Error * error) { Dwarf_Ptr buf = 0; if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } *section_bytes = 0; *length = 0; if (dbg->de_debug_sects == 0) { /* no more data !! */ return DW_DLV_NO_ENTRY; } if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { /* no data ever entered !! */ return DW_DLV_NO_ENTRY; } *section_idx = dbg->de_debug_sects->ds_elf_sect_no; *length = dbg->de_debug_sects->ds_nbytes; buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; /* Here is the iterator so the next call gets the next section. */ dbg->de_debug_sects = dbg->de_debug_sects->ds_next; /* We may want to call the section stuff more than once: see dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ *section_bytes = buf; return DW_DLV_OK; } /* No errors possible. */ void dwarf_reset_section_bytes(Dwarf_P_Debug dbg) { dbg->de_debug_sects = dbg->de_first_debug_sect; /* No need to reset; commented out decrement. dbg->de_n_debug_sect = ???; */ dbg->de_reloc_next_to_return = 0; dbg->de_sect_sa_next_to_return = 0; } /* Storage handler. Gets either a new chunk of memory, or a pointer in existing memory, from the linked list attached to dbg at de_debug_sects, depending on size of nbytes Assume dbg not null, checked in top level routine Returns a pointer to the allocated buffer space for the lib to fill in, predincrements next-to-use count so the space requested is already counted 'used' when this returns (ie, reserved). */ Dwarf_Small * _dwarf_pro_buffer(Dwarf_P_Debug dbg, int elfsectno, unsigned long nbytes) { Dwarf_P_Section_Data cursect = 0; cursect = dbg->de_current_active_section; /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must not match any legit section number. test to have just two clauses (no NULL pointer test) See dwarf_producer_init(). */ if ((cursect->ds_elf_sect_no != elfsectno) || ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc) ) { /* Either the elf section has changed or there is not enough space in the current section. Create a new Dwarf_P_Section_Data_s for the chunk. and have space 'on the end' for the buffer itself so we just do one malloc (not two). */ unsigned long space = nbytes; if (nbytes < CHUNK_SIZE) space = CHUNK_SIZE; cursect = (Dwarf_P_Section_Data) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Section_Data_s) + space); if (cursect == NULL) { return (NULL); } /* _dwarf_p_get_alloc zeroes the space... */ cursect->ds_data = (char *) cursect + sizeof(struct Dwarf_P_Section_Data_s); cursect->ds_orig_alloc = space; cursect->ds_elf_sect_no = elfsectno; cursect->ds_nbytes = nbytes; /* reserve this number of bytes of space for caller to fill in */ /* Now link on the end of the list, and mark this one as the current one */ if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { /* The only entry is the special one for 'no entry' so delete that phony one while adding this initial real one. */ dbg->de_debug_sects = cursect; dbg->de_current_active_section = cursect; dbg->de_first_debug_sect = cursect; } else { dbg->de_current_active_section->ds_next = cursect; dbg->de_current_active_section = cursect; } dbg->de_n_debug_sect++; return ((Dwarf_Small *) cursect->ds_data); } /* There is enough space in the current buffer */ { Dwarf_Small *space_for_caller = (Dwarf_Small *) (cursect->ds_data + cursect->ds_nbytes); cursect->ds_nbytes += nbytes; return space_for_caller; } } dwarfutils-20200114/libdwarf/pro_section.h000066400000000000000000000076161361531463500204410ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions (C) 2016 David Anderson . All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* relocation section names */ extern const char *_dwarf_rel_section_names[]; /* section names */ extern const char *_dwarf_sectnames[]; /* struct to hold relocation entries. Its mantained as a linked list of relocation structs, and will then be written at as a whole into the relocation section. Whether its 32 bit or 64 bit will be obtained from Dwarf_Debug pointer. */ /* struct stores a chunk of data pertaining to a section */ struct Dwarf_P_Section_Data_s { int ds_elf_sect_no; /* elf section number */ char *ds_data; /* data contained in section */ unsigned long ds_nbytes; /* bytes of data used so far */ unsigned long ds_orig_alloc; /* bytes allocated originally */ Dwarf_P_Section_Data ds_next; /* next on the list */ }; /* Used to allow a dummy initial struct (which we drop before it gets used This must not match any legitimate 'section' number. */ #define MAGIC_SECT_NO -3 /* Size of chunk of data allocated in one alloc Not clear if this is the best size. Used to be just 4096 for user data, the section data struct was a separate malloc. */ #define CHUNK_SIZE (4096 - sizeof (struct Dwarf_P_Section_Data_s)) /* chunk alloc routine - if chunk->ds_data is nil, it will alloc CHUNK_SIZE bytes, and return pointer to the beginning. If chunk is not nil, it will see if there's enoungh space for nbytes in current chunk, if not, add new chunk to linked list, and return a char * pointer to it. Return null if unsuccessful. */ Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno, unsigned long nbytes); /* GET_CHUNK_ERROR is new Sept 2016 to use DW_DLV_ERROR. */ #define GET_CHUNK_ERR(dbg,sectno,ptr,nbytes,error) \ { \ (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ if ((ptr) == NULL) { \ DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,DW_DLV_ERROR); \ } \ } #define GET_CHUNK(dbg,sectno,ptr,nbytes,error) \ { \ (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ if ((ptr) == NULL) { \ DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1); \ } \ } int _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed *nbufs, Dwarf_Error * error); /* These are for creating ELF section type codes. We are not trying to match any particulare ABI's settings for section type. In the producer, see de_callback_func() calls. If SHT_MIPS_DWARF was defined sometimes that was the value taken: 0x7000001e If it's important to someone then passing in a string like SHT=0x7000001e to the 'extra' argument of dwarf_producer_init() would work nicely (leading/trailing spaces are allowed, as is a NULL pointer instead of a string). One is a convenient default for testing purposes. */ #define SECTION_TYPE 1 /* SHT_PROGBITS in Elf. */ dwarfutils-20200114/libdwarf/pro_types.c000066400000000000000000000213351361531463500201260ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011-2019 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_alloc.h" #include "pro_section.h" #include "pro_types.h" #define SIZEOFT32 4 /* This function adds another type name to the list of type names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_typename(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, type_name, dwarf_snk_typename, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_typename_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *type_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, type_name, dwarf_snk_typename, error); return res; } /* The following is the generic 'add a simple name entry' for any of the simple name sections. See enum dwarf_sn_kind in pro_opaque.h */ int _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *entry_name, enum dwarf_sn_kind entrykind, Dwarf_Error * error) { Dwarf_P_Simple_nameentry nameentry; Dwarf_P_Simple_name_header hdr; char *name; int uword_size; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } if (die == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); return DW_DLV_ERROR; } nameentry = (Dwarf_P_Simple_nameentry) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Simple_nameentry_s)); if (nameentry == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1); if (name == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } strcpy(name, entry_name); nameentry->sne_die = die; nameentry->sne_name = name; nameentry->sne_name_len = strlen(name); uword_size = dbg->de_dwarf_offset_size; hdr = &dbg->de_simple_name_headers[entrykind]; if (hdr->sn_head == NULL) hdr->sn_head = hdr->sn_tail = nameentry; else { hdr->sn_tail->sne_next = nameentry; hdr->sn_tail = nameentry; } hdr->sn_count++; hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1; return DW_DLV_OK; } /* _dwarf_transform_simplename_to_disk writes ".rel.debug_pubnames", ".rel.debug_funcnames", sgi extension ".rel.debug_typenames", sgi extension ".rel.debug_varnames", sgi extension ".rel.debug_weaknames", sgi extension to disk. section_index indexes one of those sections. entrykind is one of those 'kind's. */ int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in de_elf_sects etc */ Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Used to fill in 0. */ const Dwarf_Signed big_zero = 0; /* Used to scan the section data buffers. */ Dwarf_P_Section_Data debug_sect; Dwarf_Signed debug_info_size; Dwarf_P_Simple_nameentry nameentry_original; Dwarf_P_Simple_nameentry nameentry; Dwarf_Small *stream_bytes; Dwarf_Small *cur_stream_bytes_ptr; Dwarf_Unsigned stream_bytes_count; Dwarf_Unsigned adjusted_length; /* count excluding length field */ int uword_size = dbg->de_dwarf_offset_size; int extension_size = dbg->de_64bit_extension ? 4 : 0; Dwarf_P_Simple_name_header hdr; /* ***** BEGIN CODE ***** */ debug_info_size = 0; for (debug_sect = dbg->de_debug_sects; debug_sect != NULL; debug_sect = debug_sect->ds_next) { /* We want the size of the .debug_info section for this CU because the dwarf spec requires us to output it below so we look for it specifically. */ if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) { debug_info_size += debug_sect->ds_nbytes; } } hdr = &dbg->de_simple_name_headers[entrykind]; /* Size of the .debug_typenames (or similar) section header. */ stream_bytes_count = extension_size + uword_size + /* Size of length field. */ DWARF_HALF_SIZE + /* Size of version field. */ uword_size + /* Size of .debug_info offset. */ uword_size; /* Size of .debug_names. */ nameentry_original = hdr->sn_head; /* add in the content size */ stream_bytes_count += hdr->sn_net_len; /* Size of the last 0 offset. */ stream_bytes_count += uword_size; /* Now we know how long the entire section is */ GET_CHUNK(dbg, dbg->de_elf_sects[section_index], stream_bytes, (unsigned long) stream_bytes_count, error); cur_stream_bytes_ptr = stream_bytes; if (extension_size) { DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *)&v4[0],SIZEOFT32 , extension_size); cur_stream_bytes_ptr += extension_size; } /* Write the adjusted length of .debug_*names section. */ adjusted_length = stream_bytes_count - uword_size - extension_size; WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &adjusted_length, sizeof(adjusted_length), uword_size); cur_stream_bytes_ptr += uword_size; /* Write the version as 2 bytes. */ { Dwarf_Half verstamp = CURRENT_VERSION_STAMP; WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &verstamp, sizeof(verstamp), DWARF_HALF_SIZE); cur_stream_bytes_ptr += DWARF_HALF_SIZE; } /* Write the offset of the compile-unit. */ WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &big_zero, sizeof(big_zero), uword_size); cur_stream_bytes_ptr += uword_size; /* now create the relocation for the compile_unit offset */ { int res = dbg->de_relocate_by_name_symbol(dbg, section_index, extension_size + uword_size + DWARF_HALF_SIZE /* r_offset */ , /* debug_info section name symbol */ dbg->de_sect_name_idx[DEBUG_INFO], dwarf_drt_data_reloc, uword_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } } /* Write the size of .debug_info section. */ WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &debug_info_size, sizeof(debug_info_size), uword_size); cur_stream_bytes_ptr += uword_size; for (nameentry = nameentry_original; nameentry != NULL; nameentry = nameentry->sne_next) { /* Copy offset of die from start of compile-unit. */ WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &nameentry->sne_die->di_offset, sizeof(nameentry->sne_die->di_offset), uword_size); cur_stream_bytes_ptr += uword_size; /* Copy the type name. */ strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name); cur_stream_bytes_ptr += nameentry->sne_name_len + 1; } WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &big_zero, sizeof(big_zero), uword_size); *nbufs = dbg->de_n_debug_sect; return DW_DLV_OK; } dwarfutils-20200114/libdwarf/pro_types.h000066400000000000000000000024271361531463500201340ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* pro_types.h */ int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index,/* in de_elf_sects etc */ Dwarf_Signed *nbufs_out, Dwarf_Error * error); dwarfutils-20200114/libdwarf/pro_util.h000066400000000000000000000027051361531463500177440ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2014-2014 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ /* Definition of sizes of types. Independent of target or host, these are. */ #define sizeof_ubyte(dbg) 1 #define sizeof_uhalf(dbg) DWARF_HALF_SIZE /* Computes amount of padding necessary to align n to a k-boundary. */ /* Important: Assumes n, k both GREATER than zero. */ #define PADDING(n, k) ( (k)-1 - ((n)-1)%(k) ) dwarfutils-20200114/libdwarf/pro_vars.c000066400000000000000000000042611361531463500177340ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif #include "pro_incl.h" #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" #include "pro_section.h" /* This function adds another variable name to the list of variable names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_varname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, var_name, dwarf_snk_varname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_varname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, var_name, dwarf_snk_varname, error); return res; } dwarfutils-20200114/libdwarf/pro_weaks.c000066400000000000000000000042431361531463500200730ustar00rootroot00000000000000/* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2011 David Anderson. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Further, this software is distributed without any warranty that it is free of the rightful claim of any third person regarding infringement or the like. Any license provided herein, whether implied or otherwise, applies only to this software file. Patent licenses, if any, provided herein do not apply to combinations of this program with other software, or any other product whatsoever. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #ifdef HAVE_ELFACCESS_H #include #endif /* HAVE_ELFACCESS_H */ #ifdef HAVE_STDDEF_H #include #endif /* HAVE_STDDEF_H */ #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "pro_error.h" /* This function adds another weak name to the list of weak names for the given Dwarf_P_Debug. It returns 0 on error, and 1 otherwise. */ Dwarf_Unsigned dwarf_add_weakname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, weak_name, dwarf_snk_weakname, error); if (res != DW_DLV_OK) { return 0; } return 1; } int dwarf_add_weakname_a(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error * error) { int res = 0; res = _dwarf_add_simple_name_entry(dbg, die, weak_name, dwarf_snk_weakname, error); return res; } dwarfutils-20200114/libdwarf/runtests.sh000077500000000000000000000021531361531463500201610ustar00rootroot00000000000000#!/bin/sh # # Intended to be run only on local machine. # Run in the libdwarf directory # Run only after config.h created in a configure # in the source directory top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/libdwarf goodcount=0 failcount=0 echo "TOP topsrc $top_srcdir topbld $top_blddir localsrc $srcdir" chkres() { r=$1 m=$2 if [ $r -ne 0 ] then echo "FAIL $m. Exit status was $r" failcount=`expr $failcount + 1` else goodcount=`expr $goodcount + 1` fi } CC=cc CFLAGS="-g -O2 -I$top_blddir -I$top_srcdir/libdwarf -I$top_blddir/libdwarf" $CC $CFLAGS $srcdir/dwarf_leb_test.c $srcdir/dwarf_leb.c $srcdir/pro_encode_nm.c -o dwarfleb chkres $? "compiling dwarfleb test" ./dwarfleb chkres $? "Running dwarfleb test" rm ./dwarfleb $CC $CFLAGS $srcdir/dwarf_tied_test.c $srcdir/dwarf_tied.c $srcdir/dwarf_tsearchhash.c -o dwarftied chkres $? "compiling dwarftied test" ./dwarftied chkres $? "Running dwarftiedtest test" rm ./dwarftied if [ $failcount -ne 0 ] then echo "FAIL $failcount in libdwarf/runtests.sh" exit 1 fi exit 0 dwarfutils-20200114/libdwarf/test_dwarfstring.c000066400000000000000000000212401361531463500214660ustar00rootroot00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include /* for printf */ #include #include #include "dwarfstring.h" #ifndef TRUE #define TRUE 1 #endif /* TRUE */ #ifndef FALSE #define FALSE 0 #endif /* FALSE */ static int errcount; static void check_string(const char *msg,char *exp, char *actual,int line) { if(!strcmp(exp,actual)) { return; } printf("FAIL %s expected \"%s\" got \"%s\" test line %d\n", msg,exp,actual,line); ++errcount; } static void check_value(const char *msg,unsigned long exp, unsigned long actual,int line) { if(exp == actual) { return; } printf("FAIL %s expected %lu got %lu test line %d\n", msg,exp,actual,line); ++errcount; } static int test1(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0; char *bigstr = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbyyyybbbbbbbbbbbbccc"; dwarfstring_constructor(&g); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,"abc"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abc ",(char *)"abc",d,__LINE__); res = dwarfstring_append(&g,"xy"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abcxy ",(char *)"abcxy",d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); res = dwarfstring_append(&g,bigstr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected bigstring ",bigstr,d,__LINE__); biglen = dwarfstring_strlen(&g); check_value("expected 120 ",strlen(bigstr),biglen,__LINE__); dwarfstring_append_length(&g,"xxyyzz",3); biglen = dwarfstring_strlen(&g); check_value("expected 123 ",strlen(bigstr)+3,biglen,__LINE__); dwarfstring_destructor(&g); return 0; } static int test2(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0; char *bigstr = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbbbbbbbbbbbbbbbbbccc" "ccccccbbbbbyyyybbbbbbbbbbbbccc"; dwarfstring_constructor_fixed(&g,10); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,"abc"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abc ",(char *)"abc",d,__LINE__); res = dwarfstring_append(&g,"xy"); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected abcxy ",(char *)"abcxy",d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor_fixed(&g,3); res = dwarfstring_append(&g,bigstr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected bigstring ",bigstr,d,__LINE__); biglen = dwarfstring_strlen(&g); check_value("expected 120 ",strlen(bigstr),biglen,__LINE__); dwarfstring_destructor(&g); return 0; } static int test3(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0; char *bigstr = "a012345"; char *targetbigstr = "a012345xy"; dwarfstring_constructor_fixed(&g,10); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,bigstr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected a012345 ",(char *)bigstr,d,__LINE__); res = dwarfstring_append_length(&g,"xyzzz",2); check_value("expected TRUE ",TRUE,res,__LINE__); check_value("expected 9 ", 9,(unsigned)dwarfstring_strlen(&g), __LINE__); d = dwarfstring_string(&g); check_string("expected a012345xy ", (char *)targetbigstr,d,__LINE__); dwarfstring_destructor(&g); return 0; } static int test4(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0; char *mystr = "a01234"; char *targetmystr = "a01234xyz"; char fixedarea[7]; dwarfstring_constructor_static(&g,fixedarea,sizeof(fixedarea)); d = dwarfstring_string(&g); check_string("expected empty string",(char *)expstr,d,__LINE__); res = dwarfstring_append(&g,mystr); check_value("expected TRUE ",TRUE,res,__LINE__); d = dwarfstring_string(&g); check_string("expected a01234 ",(char *)mystr,d,__LINE__); if (d != fixedarea) { printf(" FAIL reallocated but should not line %d ", __LINE__); ++errcount; } res = dwarfstring_append(&g,"xyz"); d = dwarfstring_string(&g); check_string("expected a01234xyz ",(char *)targetmystr, d,__LINE__); check_value("expected 9",9,dwarfstring_strlen(&g),__LINE__); if (d == fixedarea) { printf(" FAIL not reallocated but should be! line %d ", __LINE__); ++errcount; } dwarfstring_destructor(&g); return 0; } static int test5(int tnum) { struct dwarfstring_s g; char *d = 0; const char *expstr = ""; int res = 0; unsigned long biglen = 0x654a; signed long lminus= -55; char *mystr = "a01234"; char *targetmystr = "a01234xyz"; dwarfstring_constructor(&g); dwarfstring_append_printf_s(&g,"initialstring-%s-finalstring", mystr); d = dwarfstring_string(&g); expstr = "initialstring-a01234-finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"initialstring--0x%x-finalstring", biglen); d = dwarfstring_string(&g); expstr = "initialstring--0x654a-finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_i(&g,"initialstring: %d (", lminus); dwarfstring_append_printf_u(&g,"0x%08x) -finalstring", lminus); d = dwarfstring_string(&g); expstr = "initialstring: -55 (0xffffffffffffffc9) -finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"smallhex (0x%08x) -finalstring", biglen); d = dwarfstring_string(&g); expstr = "smallhex (0x0000654a) -finalstring"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); dwarfstring_constructor(&g); dwarfstring_append_printf_u(&g,"longlead (%08u) -end", 20); d = dwarfstring_string(&g); expstr = "longlead (00000020) -end"; check_string("from pct-s",(char *)expstr,d,__LINE__); dwarfstring_destructor(&g); return 0; return 0; } int main() { test1(1); test2(2); test3(3); test4(3); test5(3); if (errcount) { exit(1); } exit(0); } dwarfutils-20200114/libdwarf/test_extra_flag_strings.c000066400000000000000000000173161361531463500230320ustar00rootroot00000000000000/* Copyright (c) 2019-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "libdwarfdefs.h" #include #include #include #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include "pro_incl.h" #include "dwarf.h" #include "libdwarf.h" #include "pro_opaque.h" #include "dwarfstring.h" static int errcount; /* int _dwarf_log_extra_flagstrings(Dwarf_P_Debug dbg, const char *extra, int *err) */ static void resetdbg(Dwarf_P_Debug dbg) { memset(dbg,0,sizeof(struct Dwarf_P_Debug_s)); } #if 0 "default_is_stmt" "minimum_instruction_length" "maximum_operations_per_instruction" "opcode_base" "line_base" "line_range" "linetable_version" "segment_selector_size" "segment_size" dbg->de_line_inits.pi_default_is_stmt = (unsigned)v; dbg->de_line_inits.pi_minimum_instruction_length = (unsigned)v; dbg->de_line_inits.pi_maximum_operations_per_instruction = (unsigned)v; dbg->de_line_inits.pi_opcode_base = (unsigned)v; dbg->de_line_inits.pi_line_base = (int)v; dbg->de_line_inits.pi_line_range = (int)v; dbg->de_line_inits.pi_linetable_version = (unsigned)v; dbg->de_line_inits.pi_segment_selector_size = (unsigned)v; dbg->de_line_inits.pi_segment_size = (unsigned)v; #endif /* 0 */ const char * returnvalstr(int res) { if (res == DW_DLV_OK) return "DW_DLV_OK"; if (res == DW_DLV_NO_ENTRY) return "DW_DLV_NO_ENTRY"; if (res == DW_DLV_ERROR) return "DW_DLV_ERROR"; return "Unknown"; } static void check_expected(int exp, int got, int err_exp, int err_got, Dwarf_Signed exp_val, Dwarf_Signed got_val, int line) { if ( exp != got) { ++errcount; printf("Expected res %s, got %s line %d\n", returnvalstr(exp), returnvalstr(got),line); } if ( err_exp != err_got) { ++errcount; printf("Expected err code %d, got %d line %d\n", err_exp,err_got,line); } if ( exp_val != got_val) { ++errcount; printf("Expected value %" DW_PR_DSd ", got %" DW_PR_DSd " line %d\n", exp_val,got_val,line); } } static void test1(Dwarf_P_Debug dbg) { int res = 0; int err = 0; res = _dwarf_log_extra_flagstrings(dbg,"default_is_stmt=1",&err); check_expected(DW_DLV_OK,res,0,err,1,dbg->de_line_inits.pi_default_is_stmt, __LINE__); err = 0; res = _dwarf_log_extra_flagstrings(dbg,0,&err); check_expected(DW_DLV_NO_ENTRY,res,0,err,0,0, __LINE__); err = 0; res = _dwarf_log_extra_flagstrings(dbg,"",&err); check_expected(DW_DLV_NO_ENTRY,res,0,err,0,0, __LINE__); err = 0; resetdbg(dbg); res = _dwarf_log_extra_flagstrings(dbg,",line_base=-1,",&err); check_expected(DW_DLV_OK,res,0,err,-1,dbg->de_line_inits.pi_line_base, __LINE__); err = 0; resetdbg(dbg); res = _dwarf_log_extra_flagstrings(dbg,",,line_base=-1,,",&err); check_expected(DW_DLV_OK,res,0,err,-1,dbg->de_line_inits.pi_line_base, __LINE__); resetdbg(dbg); err = 0; res = _dwarf_log_extra_flagstrings(dbg,",,line_base =-1,,",&err); check_expected(DW_DLV_ERROR,res,err,DW_DLE_PRO_INIT_EXTRAS_ERR,dbg->de_line_inits.pi_line_base,0, __LINE__); } static void test2(Dwarf_P_Debug dbg) { int res = 0; int err = 0; resetdbg(dbg); err = 0; res = _dwarf_log_extra_flagstrings(dbg, "default_is_stmt=1,line_base=2",&err); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_default_is_stmt,1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_base,2, __LINE__); resetdbg(dbg); err = 0; /* intentional typo here */ res = _dwarf_log_extra_flagstrings(dbg, "minimum_instruction_lengty=3," "maximum_operations_per_instruction=4",&err); check_expected(DW_DLV_ERROR,res, err,DW_DLE_PRO_INIT_EXTRAS_UNKNOWN, dbg->de_line_inits.pi_minimum_instruction_length, 0, __LINE__); check_expected(DW_DLV_ERROR,res, err,DW_DLE_PRO_INIT_EXTRAS_UNKNOWN, dbg->de_line_inits.pi_maximum_operations_per_instruction, 0, __LINE__); resetdbg(dbg); err = 0; res = _dwarf_log_extra_flagstrings(dbg, "default_is_stmt=1," "minimum_instruction_length=2," "maximum_operations_per_instruction=3," "opcode_base=4," "line_base=5," "line_range=6," "linetable_version=7," "segment_selector_size=8," "segment_size=9", &err); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_default_is_stmt,1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_minimum_instruction_length,2, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_maximum_operations_per_instruction,3, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_opcode_base,4, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_base,5, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_range,6, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_linetable_version,7, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_segment_selector_size,8, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_segment_size,9, __LINE__); } static void test3(Dwarf_P_Debug dbg) { int res = 0; int err = 0; /* The following identical to a current dwarfgen.cc use. */ res = _dwarf_log_extra_flagstrings(dbg, "opcode_base=13," "minimum_instruction_length=1," "line_base=-1," "line_range=4",&err); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_opcode_base,13, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_minimum_instruction_length,1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_base,-1, __LINE__); check_expected(DW_DLV_OK,res,err,0, dbg->de_line_inits.pi_line_range,4, __LINE__); } int main() { struct Dwarf_P_Debug_s sdbg; Dwarf_P_Debug dbg = &sdbg; resetdbg(dbg); test1(dbg); resetdbg(dbg); test2(dbg); resetdbg(dbg); test3(dbg); if (errcount) { return 1; } return 0; } dwarfutils-20200114/libdwarf/test_linkedtopath.c000066400000000000000000000332721361531463500216320ustar00rootroot00000000000000/* Copyright (c) 2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #ifdef HAVE_MALLOC_H /* Useful include for some Windows compilers. */ #include #endif /* HAVE_MALLOC_H */ #include #ifdef HAVE_ELF_H #include #endif /* HAVE_ELF_H */ #ifdef HAVE_UNISTD_H #include /* lseek read close */ #endif /* HAVE_UNISTD_H */ #include /* for open() */ #include /* for open() */ #include /* for open() */ #include #include "dwarf_incl.h" #include "dwarf_alloc.h" #include "dwarf_error.h" #include "dwarf_util.h" #include "dwarfstring.h" #include "dwarf_debuglink.h" static int errcount = 0; /* dummy func we do not need real one */ int _dwarf_load_section(Dwarf_Debug dbg, struct Dwarf_Section_s *section, Dwarf_Error * error) { return DW_DLV_OK; } /* A horrible fake version for these tests */ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval) { static struct Dwarf_Error_s stuff; stuff.er_errval = errval; *error = &stuff; } /* literal copy from dwarf_error.c */ Dwarf_Unsigned dwarf_errno(Dwarf_Error error) { if (!error) { return (0); } return (error->er_errval); } /* A literal copy from dwarf_util.c */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *strptr, void *areaendptr, int suggested_error, Dwarf_Error*error) { Dwarf_Small *start = areaptr; Dwarf_Small *p = strptr; Dwarf_Small *end = areaendptr; if (p < start) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (p >= end) { _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (dbg->de_assume_string_in_bounds) { /* This NOT the default. But folks can choose to live dangerously and just assume strings ok. */ return DW_DLV_OK; } while (p < end) { if (*p == 0) { return DW_DLV_OK; } ++p; } _dwarf_error(dbg,error,DW_DLE_STRING_NOT_TERMINATED); return DW_DLV_ERROR; } static void check_svalid(int expret,int gotret,int experr,int goterr,int line, char *filename_in) { if (expret != gotret) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expret,gotret,line,filename_in); } if (experr != goterr) { errcount++; printf("ERROR expected errcode %d, got %d line %d %s\n", experr,goterr,line,filename_in); } } static void test1(Dwarf_Debug dbg) { char testbuffer[1000]; char *area = testbuffer; char * str = testbuffer; const char *msg = "This is a simple string for testing."; int res = 0; char *end = testbuffer +100; int errcode = 0; Dwarf_Error error = 0; testbuffer[0] = 0; strcpy(testbuffer,msg); /* The error value is arbitrary, not realistic. */ res = _dwarf_check_string_valid(dbg, area,str, end,DW_DLE_CORRUPT_GNU_DEBUGID_STRING, &error); check_svalid(DW_DLV_OK,res, 0,dwarf_errno(error), __LINE__,__FILE__); end = testbuffer +10; res = _dwarf_check_string_valid(dbg, area,str, end,DW_DLE_STRING_NOT_TERMINATED, &error); check_svalid(DW_DLV_ERROR, res, DW_DLE_STRING_NOT_TERMINATED, dwarf_errno(error), __LINE__,__FILE__); end = testbuffer +10; area = end +2; res = _dwarf_check_string_valid(dbg,area,str, end,DW_DLE_CORRUPT_GNU_DEBUGID_STRING, &error); check_svalid(DW_DLV_ERROR,res, DW_DLE_CORRUPT_GNU_DEBUGID_STRING, dwarf_errno(error), __LINE__,__FILE__); } static void checkjoin(int expret,int gotret,char*expstr,char*gotstr, int line, const char *filename_in) { if (expret != gotret) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expret,gotret,line,filename_in); } if (strcmp(expstr,gotstr)) { errcount++; printf("ERROR expected string \"%s\", got \"%s\" line %d %s\n", expstr,gotstr,line,filename_in); } } #if 0 int _dwarf_pathjoinl(dwarfstring *target,dwarfstring * input); #endif static void test2(Dwarf_Debug dbg) { dwarfstring targ; dwarfstring inp; int res = 0; dwarfstring_constructor(&targ); dwarfstring_constructor(&inp); dwarfstring_append(&targ,"/a/b"); dwarfstring_append(&inp,"foo"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"/a/b/foo", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_append(&targ,"gef"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/foo", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"gef/"); dwarfstring_append(&inp,"/jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/jkl/", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"gef/"); dwarfstring_append(&inp,"jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/jkl/", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"gef"); dwarfstring_append(&inp,"jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"gef/jkl/", dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&inp,"/jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"/jkl/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&inp,"jkl/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"jkl/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"jkl"); dwarfstring_append(&inp,"pqr/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"jkl/pqr/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_reset(&targ); dwarfstring_reset(&inp); dwarfstring_append(&targ,"/"); dwarfstring_append(&inp,"/"); res = _dwarf_pathjoinl(&targ,&inp); checkjoin(DW_DLV_OK,res,"/",dwarfstring_string(&targ), __LINE__,__FILE__); dwarfstring_destructor(&targ); dwarfstring_destructor(&inp); } static void checklinkedto(int expret,int gotret, int expcount,int gotcount,int line, char *filename_in) { if (expret != gotret) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expret,gotret,line,filename_in); } if (expcount != gotcount) { errcount++; printf("ERROR expected return %d, got %d line %d %s\n", expcount,gotcount,line,filename_in); } } static void printpaths(unsigned count,char **array,dwarfstring *fullpath) { unsigned i = 0; printf("linkstring full path: %s\n", dwarfstring_string(fullpath)); printf("\n"); printf(" Paths:\n"); for(i = 0 ; i < count ; ++i) { char *s = array[i]; printf(" [%2d] \"%s\"\n",i,s); } printf("\n"); } #if 0 int _dwarf_construct_linkedto_path( char **global_prefixes_in, unsigned length_global_prefixes_in, char *pathname_in, char *link_string_in, /* from debug link */ unsigned char *crc_in, /* from debug_link, 4 bytes */ unsigned builid_length, /* from gnu buildid */ unsigned char *builid, /* from gnu buildid */ char ***paths_out, unsigned *paths_out_length, int *errcode); #endif static unsigned char buildid[20] = { 0x11,0x22,0x33, 0x44, 0x21,0x22,0x23, 0x44, 0xa1,0xa2,0xa3, 0xa4, 0xb1,0xb2,0xb3, 0xb4, 0xc1,0xc2,0xc3, 0xc4 }; /* Since we don't find the files here this is not a good test. However, the program is used by rundebuglink.sh */ static void test3(Dwarf_Debug dbg) { char * executablepath = "a/b"; char * linkstring = "de"; dwarfstring result; char ** global_prefix = 0; unsigned global_prefix_count = 2; unsigned global_prefix_len = 0; unsigned char crc[4]; unsigned buildid_length = 20; char **paths_returned = 0; unsigned paths_returned_count = 0; int errcode = 0; Dwarf_Error error = 0; int res = 0; dwarfstring linkstring_fullpath; unsigned i = 0; crc[0] = 0x12; crc[1] = 0x34; crc[2] = 0x56; crc[3] = 0xab; global_prefix_len = (global_prefix_count+1) * sizeof(void *); res = dwarf_add_debuglink_global_path(dbg, "/usr/lib/debug",&error); if (res != DW_DLV_OK){ ++errcount; printf("Adding debuglink global path failed line %d %s\n", __LINE__,__FILE__); exit(1); } res = dwarf_add_debuglink_global_path(dbg, "/fake/lib/debug",&error); if (res != DW_DLV_OK){ ++errcount; printf("Adding debuglink global path failed line %d %s\n", __LINE__,__FILE__); exit(1); } dbg->de_path = executablepath; dwarfstring_constructor(&result); dwarfstring_constructor(&linkstring_fullpath); res =_dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, executablepath, linkstring, &linkstring_fullpath, crc, buildid, buildid_length, &paths_returned,&paths_returned_count, &errcode); checklinkedto(DW_DLV_OK,res,6,paths_returned_count, __LINE__,__FILE__); printpaths(paths_returned_count,paths_returned,&linkstring_fullpath); free(paths_returned); paths_returned = 0; paths_returned_count = 0; errcode = 0; dwarfstring_reset(&linkstring_fullpath); dwarfstring_reset(&result); executablepath = "ge"; linkstring = "h/i"; res =_dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, executablepath,linkstring, &linkstring_fullpath, crc, buildid, buildid_length, &paths_returned,&paths_returned_count, &errcode); checklinkedto(DW_DLV_OK,res,6,paths_returned_count, __LINE__,__FILE__); printpaths(paths_returned_count,paths_returned,&linkstring_fullpath); free(paths_returned); paths_returned = 0; paths_returned_count = 0; errcode = 0; dwarfstring_reset(&result); dwarfstring_reset(&linkstring_fullpath); executablepath = "/somewherespecial/a/b/ge"; linkstring = "h/i"; res =_dwarf_construct_linkedto_path( (char **)dbg->de_gnu_global_paths, dbg->de_gnu_global_path_count, executablepath,linkstring, &linkstring_fullpath, crc, buildid, buildid_length, &paths_returned,&paths_returned_count, &errcode); checklinkedto(DW_DLV_OK,res,6,paths_returned_count, __LINE__,__FILE__); printpaths(paths_returned_count,paths_returned,&linkstring_fullpath); free(paths_returned); free(global_prefix); paths_returned = 0; paths_returned_count = 0; for (i = 0; i < dbg->de_gnu_global_path_count; ++i) { free((char *) dbg->de_gnu_global_paths[i]); dbg->de_gnu_global_paths[i] = 0; } free(dbg->de_gnu_global_paths); dbg->de_gnu_global_paths = 0; errcode = 0; dwarfstring_destructor(&result); dwarfstring_destructor(&linkstring_fullpath); } int main() { Dwarf_Debug dbg = 0; struct Dwarf_Debug_s db; dbg = &db; memset(dbg,0,sizeof(db)); #if 0 dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; #ifdef WORDS_BIGENDIAN dbg->de_big_endian_object = 1; if (endianness == DW_OBJECT_LSB ) { 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_OBJECT_MSB ) { dbg->de_same_endian = 0; dbg->de_big_endian_object = 1; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #endif /* !WORDS_BIGENDIAN */ #endif test1(dbg); test2(dbg); test3(dbg); if (errcount) { return 1; } return 0; } dwarfutils-20200114/libdwarf/testdebuglink.sh000077500000000000000000000007111361531463500211340ustar00rootroot00000000000000#!/bin/sh # Verify the printed output of of test_linkedto top_blddir=`pwd`/.. if [ x$DWTOPSRCDIR = "x" ] then top_srcdir=$top_blddir else top_srcdir=$DWTOPSRCDIR fi srcdir=$top_srcdir/libdwarf ./test_linkedtopath >junk.ltp which dos2unix if [ $? -eq 0 ] then dos2unix junk.ltp fi diff $srcdir/baseline.ltp junk.ltp if [ $? -ne 0 ] then echo "FAIL base test " echo "To update baseline: mv junk.ltp $srcdir/baseline.ltp" exit 1 fi exit 0 dwarfutils-20200114/ltmain.sh000066400000000000000000011714741361531463500157770ustar00rootroot00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2014-01-07.03; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do eval $_G_hook '"$@"' # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift done func_quote_for_eval ${1+"$@"} func_run_hooks_result=$func_quote_for_eval_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # func_quote_for_eval ${1+"$@"} # my_options_prep_result=$func_quote_for_eval_result # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # ;; # *) set dummy "$_G_opt" "$*"; shift; break ;; # esac # done # # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # func_quote_for_eval ${1+"$@"} # my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # # You'll alse need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options_result+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result=$func_run_hooks_result } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $_G_opt && break case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: dwarfutils-20200114/m4/000077500000000000000000000000001361531463500144605ustar00rootroot00000000000000dwarfutils-20200114/m4/dw_compiler.m4000066400000000000000000000046671361531463500172430ustar00rootroot00000000000000dnl Copyright (C) 2018 Vincent Torri dnl This code is public domain and can be freely used or copied. dnl Macro that check if compiler flags are available dnl Macro that checks for a C compiler flag availability dnl dnl _DWARF_CHECK_C_COMPILER_FLAG(FLAGS) dnl AC_SUBST : DWARF_CFLAGS_WARN dnl have_flag: yes or no. AC_DEFUN([_DWARF_CHECK_C_COMPILER_FLAG], [dnl dnl store in options -Wfoo if -Wno-foo is passed option="m4_bpatsubst([[$1]], [-Wno-], [-W])" CFLAGS_save="${CFLAGS}" CFLAGS="${CFLAGS} ${option}" AC_LANG_PUSH([C]) AC_MSG_CHECKING([whether the C compiler supports $1]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]])], [have_flag="yes"], [have_flag="no"]) AC_MSG_RESULT([${have_flag}]) AC_LANG_POP([C]) CFLAGS="${CFLAGS_save}" AS_IF( [test "x${have_flag}" = "xyes"], [DWARF_CFLAGS_WARN="${DWARF_CFLAGS_WARN} [$1]"]) AC_SUBST(DWARF_CFLAGS_WARN)dnl ]) dnl DWARF_CHECK_C_COMPILER_FLAGS(FLAGS) dnl Checks if FLAGS are supported and add to DWARF_CLFAGS. dnl dnl It will first try every flag at once, if one fails we will try dnl them one by one. AC_DEFUN([DWARF_CHECK_C_COMPILER_FLAGS], [dnl _DWARF_CHECK_C_COMPILER_FLAG([$1]) AS_IF( [test "${have_flag}" != "yes"], [m4_foreach_w([flag], [$1], [_DWARF_CHECK_C_COMPILER_FLAG(m4_defn([flag]))])]) ]) dnl Macro that checks for a C++ compiler flag availability dnl dnl _DWARF_CHECK_CXX_COMPILER_FLAG(FLAGS) dnl AC_SUBST : DWARF_CXXFLAGS_WARN dnl have_flag: yes or no. AC_DEFUN([_DWARF_CHECK_CXX_COMPILER_FLAG], [dnl dnl store in options -Wfoo if -Wno-foo is passed option="m4_bpatsubst([[$1]], [-Wno-], [-W])" CXXFLAGS_save="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${option}" AC_LANG_PUSH([C++]) AC_MSG_CHECKING([whether the C++ compiler supports $1]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[]])], [have_flag="yes"], [have_flag="no"]) AC_MSG_RESULT([${have_flag}]) AC_LANG_POP([C++]) CXXFLAGS="${CXXFLAGS_save}" AS_IF( [test "x${have_flag}" = "xyes"], [DWARF_CXXFLAGS_WARN="${DWARF_CXXFLAGS_WARN} [$1]"]) AC_SUBST(DWARF_CXXFLAGS_WARN)dnl ]) dnl DWARF_CHECK_CXX_COMPILER_FLAGS(FLAGS) dnl Checks if FLAGS are supported and add to DWARF_CXXLFAGS. dnl dnl It will first try every flag at once, if one fails we will try dnl them one by one. AC_DEFUN([DWARF_CHECK_CXX_COMPILER_FLAGS], [dnl _DWARF_CHECK_CXX_COMPILER_FLAG([$1]) AS_IF( [test "${have_flag}" != "yes"], [m4_foreach_w([flag], [$1], [_DWARF_CHECK_CXX_COMPILER_FLAG(m4_defn([flag]))])]) ]) dwarfutils-20200114/m4/libtool.m4000066400000000000000000011261711361531463500163770ustar00rootroot00000000000000# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ]) # serial 58 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_PREPARE_CC_BASENAME # ----------------------- m4_defun([_LT_PREPARE_CC_BASENAME], [ # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in @S|@*""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } ])# _LT_PREPARE_CC_BASENAME # _LT_CC_BASENAME(CC) # ------------------- # It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, # but that macro is also expanded into generated libtool script, which # arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], [m4_require([_LT_PREPARE_CC_BASENAME])dnl AC_REQUIRE([_LT_DECL_SED])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl func_cc_basename $1 cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the 'libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to 'config.status' so that its # declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags='_LT_TAGS'dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into 'config.status', and then the shell code to quote escape them in # for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ '$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test 0 != $[#] do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try '$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 _LT_COPYING _LT_LIBTOOL_TAGS # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE _LT_PREPARE_MUNGE_PATH_LIST _LT_PREPARE_CC_BASENAME # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test yes = "$lt_cv_ld_force_load"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script that will find a shell with a builtin # printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf case `/usr/bin/file conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `/usr/bin/file conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `/usr/bin/file conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ]) if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) ]) ]) ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links=nottested if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test no = "$hard_links"; then AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_PREPARE_MUNGE_PATH_LIST # --------------------------- # Make sure func_munge_path_list() is defined correctly. m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], [[# func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x@S|@2 in x) ;; *:) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ;; x:*) eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; *::*) eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ;; *) eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ;; esac } ]])# _LT_PREPARE_PATH_LIST # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown AC_ARG_VAR([LT_SYS_LIBRARY_PATH], [User-defined run-time library search path.]) case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], [Detected run-time system search path for libraries]) _LT_DECL([], [configure_time_lt_sys_library_path], [2], [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$1"; then lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], [if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi]) rm -f conftest.i conftest2.i conftest.out]) ])# _LT_PATH_DD # _LT_CMD_TRUNCATE # ---------------- # find command to truncate a binary pipe m4_defun([_LT_CMD_TRUNCATE], [m4_require([_LT_PATH_DD]) AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], [printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) _LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], [Command to truncate a binary pipe]) ])# _LT_CMD_TRUNCATE # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # _LT_DLL_DEF_P([FILE]) # --------------------- # True iff FILE is a Windows DLL '.def' file. # Keep in sync with func_dll_def_p in the libtool script AC_DEFUN([_LT_DLL_DEF_P], [dnl test DEF = "`$SED -n dnl -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl -e q dnl Only consider the first "real" line $1`" dnl ])# _LT_DLL_DEF_P # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([nm_interface], [lt_cv_nm_interface], [1], [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) case $host_os in os2*) _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS=$save_LDFLAGS]) if test yes = "$lt_cv_irix_exported_symbol"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi _LT_TAGVAR(link_all_deplibs, $1)=no else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; osf3*) if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC=$lt_save_CC ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported shrext_cmds=.dll _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(GCC, $1)=$GXX _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case @S|@2 in .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)=$prev$p else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$G77 _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS dwarfutils-20200114/m4/ltoptions.m4000066400000000000000000000342621361531463500167640ustar00rootroot00000000000000# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option '$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the 'shared' and # 'disable-shared' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the 'static' and # 'disable-static' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the 'fast-install' # and 'disable-fast-install' LT_INIT options. # DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- # implement the --with-aix-soname flag, and support the `aix-soname=aix' # and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT # is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) AC_ARG_WITH([aix-soname], [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], [case $withval in aix|svr4|both) ;; *) AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ;; esac lt_cv_with_aix_soname=$with_aix_soname], [AC_CACHE_VAL([lt_cv_with_aix_soname], [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) with_aix_soname=$lt_cv_with_aix_soname]) AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac _LT_DECL([], [shared_archive_member_spec], [0], [Shared archive member basename, for filename based shared library versioning on AIX])dnl ])# _LT_WITH_AIX_SONAME LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac], [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) dwarfutils-20200114/m4/ltsugar.m4000066400000000000000000000104401361531463500164020ustar00rootroot00000000000000# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) dwarfutils-20200114/m4/ltversion.m4000066400000000000000000000012731361531463500167520ustar00rootroot00000000000000# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 4179 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.6]) m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.6' macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) dwarfutils-20200114/m4/lt~obsolete.m4000066400000000000000000000137741361531463500173100ustar00rootroot00000000000000# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) dwarfutils-20200114/missing000077500000000000000000000153301361531463500155410ustar00rootroot00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2014 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dwarfutils-20200114/scripts/000077500000000000000000000000001361531463500156275ustar00rootroot00000000000000dwarfutils-20200114/scripts/BLDLIBDWARF000077500000000000000000000016671361531463500173030ustar00rootroot00000000000000#!/bin/sh # BLDLIBDWARF l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" bldone () { t=$1 cd $t # The following distclean will fail on a clean directory # Ignore the failure make distclean ./configure if [ $? != 0 ] then echo build failed exit fi make if [ $? != 0 ] then echo build failed exit fi cd .. } bldone libdwarf bldone dwarfdump dwarfutils-20200114/scripts/BLDLIBDWARFTAR000077500000000000000000000031701361531463500176410ustar00rootroot00000000000000#!/bin/sh # #newpref sets directory name with date, more #like normal linux packages. l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" if [ $# != 1 ] then echo Usage: BLDLIBDWARFTAR yyyymmdd echo Example: BLDLIBDWARFTAR 20040108 exit 1 fi echo "This does not do UPDATEDWARFDUMPVERSION.sh" echo "Make sure there are no unwanted files" echo "in the code directories as all the files get" echo "copied to the release tar file." dat=$1 tmpf=dwarf tmpdir=/var/tmp # cptopublic knows /var/tmp/dwarf is the target sh $sloc/CPTOPUBLIC nouv newpref=dwarf-${dat} newf=libdwarf-${dat}.tar echo src is $tmpdir/$tmpf tmp is $newpref target is $newf echo ============ $newpref $newf ========== echo First create $tmpdir/$newpref with the latest source. cd $tmpdir if [ ! -d $tmpf ] then echo No $tmpdir/dwarf present! Do nothing. exit 0 fi rm -rf $newpref cp -rp $tmpf $newpref # Alter date below before using.e rm -f ${newf} ${newf}.gz tar cf /var/tmp/$newf $newpref gzip ${newf} hm=/home/davea/web4/gweb/pagedata cp ${newf}.gz $hm ls -l $tmpdir/${newf}.gz ls -l $hm/${newf}.gz exit 0 dwarfutils-20200114/scripts/BLDTESTDIR000066400000000000000000000101551361531463500172140ustar00rootroot00000000000000#!/bin/sh # #newpref sets directory name with date, more #like normal linux packages. echo This is largely obsolete. exit 1 if [ $# != 1 ] then echo Usage: BLDTESTDIR yyyymmdd echo Example: BLDTESTDIR 20100501 exit 1 fi dat=$1 tmpdir=/var/tmp cd dwarftest basenewpref=dwarftest-${dat} newpref=$tmpdir/dwarftest-${dat} newf=dwarftest-${dat}.tar echo ============ $newpref $newf ========== echo First create /var/tmp/$newpref with the latest source. rm -rf $newpref mkdir $newpref for i in zero/Makefile \ allen1/README \ allen1/todd-allen-gcc-4.4.4-bin.exe \ zero/TEST \ zero/zero.cc \ sandnes2/cu_dir_added_to_complete_path.c \ sandnes2/README \ sandnes2/RUNTEST.sh \ sandnes2/cu_dir_added_to_complete_path.elf \ dwarf4/dd2g4.5dwarf-4 \ dwarf4/ddg4.5dwarf-4 \ dwarf4/README \ moshe/a.out.t \ moshe/hello \ moshe/hello.c \ moshe/README \ moshe/t.c \ lloyd/arange.elf \ lloyd/README \ cell/c_malloc.o \ cell/README \ test-eh/Makefile \ test-eh/eh-frame.cc \ test-eh/test-eh.386 \ test-eh/test-eh.c \ test-eh/eh-frame.386 \ CLEANUP \ ChangeLog2010 \ ChangeLog2009 \ test-alex2/test.c \ test-alex2/README \ test-alex2/RUNTEST \ test-alex2/bugemail \ test-alex2/orig.a.out \ sun/sunelf1 \ sun/sparc1-a.out \ linkonce/linkonce.txt \ linkonce/test.cpp \ linkonce/comdattest.o \ libdwarf.a \ louzon/README \ louzon/ppcobj.o \ cristi3/foo.cpp \ cristi3/cristibadobj \ cristi3/README \ arm/README \ arm/armcc-test-dwarf3 \ arm/armcc-test-dwarf2 \ ia64/hxdump.c \ ia64/mytry.ia64 \ ia64/mytry.cpp \ ia64/README \ ia64/hxdump.ia64 \ PICKUPBIN \ test_harmless \ findcu/cutest.c \ findcu/README \ findcu/cutestobj.save \ findcu/RUNTEST \ TEST \ macinfo/test.c \ macinfo/a.out3.4 \ macinfo/a.out4.3 \ macinfo/README \ RUNALL.sh \ testcase/testcase.c \ testcase/Makefile \ testcase/README \ testcase/testcase \ testcase/BLD \ testcase/verify \ dwarfextract/test2.c \ dwarfextract/Makefile \ dwarfextract/test1.base \ dwarfextract/test1.c \ dwarfextract/runtests.sh \ dwarfextract/test1.h \ dwarfextract/dwarfextract.c \ val_expr/libpthread-2.5.so \ ChangeLog \ frame1/frame1.orig \ frame1/frame1.c \ frame1/README \ frame1/frame1.exe.save \ frame1/frame1.base \ frame1/runtest.sh \ cristi2/libpthread-2.4.so \ cristi2/README \ cristi2/libc-2.5.so \ x86/README \ x86/dwarfdumpv4.3 \ kartashev2/Makefile \ kartashev2/bar.cc \ kartashev2/foo.cc \ kartashev2/combined.o \ test_harmless.c \ libdwoldframecol.a \ atefail/README \ atefail/ig_server \ modula2/README \ modula2/write-fixed \ shihhuangti/t1.o \ shihhuangti/tcombined.o \ shihhuangti/README.txt \ shihhuangti/t2.o \ dwarfdump.conferr1 \ DWARFTEST.sh \ moore/README \ moore/simplec.o \ moore/RUNTEST.sh \ moore/simplec.c \ moore/djpeg.v850 \ README.txt \ ppc2/README \ ppc2/powerpc-750-linux-gnu-hello-static.txt \ ppc2/powerpc-750-linux-gnu-hello-static \ sparc/README \ sparc/tcombined.o \ sandnes/Test1.elf \ sandnes/README \ wynn/unoptimised.axf \ wynn/README.txt \ COPYING \ SINGLE \ mutatee/test1.mutatee_gcc.exe \ mucci/main.gcc \ mucci/a.out.mucci \ mucci/main.o \ mucci/README \ mucci/main.c \ mucci/main.pathcc \ mucci/stream.o \ mucci/main.o.pathcc \ mucci/main.o.gcc \ test_dwarfnames.c \ legendre/frame_test.c \ legendre/libmpich.so.1.0 \ legendre/README \ legendre/RUNTEST.sh \ ref_addr/README \ ref_addr/ELF3.elf \ test-array/Makefile \ test-array/array.c \ test-array/test-array \ BLD \ irix64/libc.so \ test-alex1/test.c \ test-alex1/bug \ test-alex1/RUNTEST \ test-alex1/bugemail \ test-alex1/BLD \ test-alex1/RUNIT \ test-alex1/orig.a.out \ BLDTAR \ kartashev/README \ kartashev/combined.o \ irixn32/dwarfdump \ irixn32/libc.so \ RUN \ verifyall.cc \ dwarfdump.O \ dwarfdump.conf \ ia32/libc.so.6 \ ia32/preloadable_libintl.so \ ia32/mytry.ia32 \ ia32/libpfm.so.3 \ ia32/libpt_linux_x86_r.so.1 \ enciso2/README \ enciso2/test_templates.cpp \ enciso2/template.elf \ enciso2/test_templates.o do d=`dirname $i` if ! [ -d $newpref/$d ] then mkdir $newpref/$d fi cp -p $i $newpref/$i done cd $tmpdir # Alter date below before using.e rm -f ${newf} ${newf}.gz tar cf /var/tmp/$newf $basenewpref gzip ${newf} hm=/home/davea/sgiweb3/pagedata cp ${newf}.gz $hm ls -l $tmpdir/${newf}.gz ls -l $hm/${newf}.gz exit 0 dwarfutils-20200114/scripts/CLEANUP000066400000000000000000000015351361531463500166450ustar00rootroot00000000000000#!/bin/bash # CLEANUP l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" # Won't work unless configure was done. make distclean # Some unlikely but possible files no one wants: rm -f libdwarf/BLD rm -f dwarfdump/BLD rm -f dwarfgen/configure.lineno rm -f ALLd* rm -f junk* */junk* rm -f *~ */*~ dwarfutils-20200114/scripts/CPTARTOWEBDIR000077500000000000000000000012121361531463500175620ustar00rootroot00000000000000#!/bin/sh # Pass in the name of the new release # with any appropriate path designation # name should be /*libdwarf-*.tar.gz if [ $# -ne 1 ]: then echo Requires path to a tar.gz file exit 1 fi full=$1 b=`basename $full` t=/home/davea/web4/gweb/pagedata if [ -f "$t/$b" ] then echo "file already present, running cmp." cmp "$full" "$t/$b" >/dev/null if [ $? -ne 0 ] then echo "Not the same file content. Fix this!" exit 1 else echo "Content already there. Ok." fi else echo "Copied $full to $t/$b" cp "$full" "$t/$b" fi set -x ls -l "$t/$b" md5sum "$t/$b" echo " " sha512sum "$t/$b" | fold -w 32 exit 0 dwarfutils-20200114/scripts/CPTOPUBLIC000077500000000000000000000024441361531463500172250ustar00rootroot00000000000000 #!/bin/sh # CPTOPUBLIC [uv] [nouv] # This is used in (copied into) each script to adjust # our location to the code directory above dwarfdump, libdwarf, etc. # This is the original copy (not used directly). l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" usemsg() { echo "CPTOPUBLIC [uv] [nouv]" echo "where uv means update version strings " echo "where nouv means do not update version strings " echo "One of uv or nouv is required..." } if [ $# -ne 1 ] then usemsg exit 1 fi uver="n" case $1 in uv) uver="y" ;; nouv) uver="n" ;; *) usemsg ; exit 1 ;; esac s=/home/davea/dwarf/code cd $s pwd t=/var/tmp/dwarf echo target is $t if [ $uver = "y" ] then sh $sloc/UPDATEDWARFDUMPVERSION.sh fi rm -rf $t mkdir $t cp -rp * $t dwarfutils-20200114/scripts/CREATINGARELEASE000066400000000000000000000071321361531463500200530ustar00rootroot00000000000000 This is an checklist of the steps in creating a new release. In hopes this will prevent omissions. DavidA. 30 November 2012 Source here means libdwarf/dwarfdump/dwarfgen source (in Git). Tests here means the regression tests (in another Git repository). In the Source: Update the source and build with your changes. Update the appropriate ChangeLog file so every file in Git which changes (except ChangeLog and NEWS) are in ChangeLog. (at year end, move ChangeLog to ChangeLogyyyy where yyyy is the year ending and create a new empty ChangeLog) Use dicheck (also in sourceforge) to verify indentation of all .h .cc and .c files is consistent. Ensure all interfaces in libdwarf that are call able by users are in libdwarf.h and are documented in libdwarf2.1.mm or libdwarf2p.1.mm and that any changes in the .mm also mean you inserted a version and date change in the date lines near the front of that .mm. Then regenerate the pdf if any changes. Run any small preliminary tests that seem applicable. In the Tests: Create any new tests that seem applicable. Add the appropriate lines to DWARFTEST.sh which actually does the test running. RUNALL.sh Runs one test of the new dwarfdump/libdwarf executable against the previously saved dwarfdump/libdwarf executable. The notion of keeping baseline test output and simply comparing output of a previous release vs the new candidate release would involve saving some really large files. So the present test suite instead runs each test with two dwarfdump* versions and compares the output. To run all the tests, most of which compare the (committed in tests) dwarfdump against your new source: sh PICKUPBIN # This picks up latest source and compiles # (for some files multiple times) # It is essential before each test run. sh RUNALL.sh # This runs the tests 3 times with different # dwarfdump[2] and different comparisons To check for failure: grep FAIL ALL* If there are any FAILS decide if they are real failures (in which case fix the Source and retest) or are in fact the output change that is expected given the Source changes. In case all tests pass: cp dwarfdump dwarfdump.O commit the updated .O executables as the new baseline good dwarfdump for the next test run. In the Source: sh UPDATEDWARFDUMPVERSION.sh #updates the version string a libdwarf header file (libdwarf/dwarf_version.h). Update dwarfdump[2]/ChangeLog files to reflect the new version. commit the new version string. If this has been done recently enough that users won't see the current version string it need not be done at this time. The release version is in configure.ac. Currently 20181024 git push origin master # Push to sourceforge. # We use 20181024 as an example below, use the current date. mkdir /tmp/bld cd /tmp/bld /configure make dist md5sum libdwarf-20181024.tar.gz sha512sum libdwarf-20181024.tar.gz | fold -w 32 # To get unforgeable checksums for the tar.gz file # md5sum is weak, but the pair should be # a strong confirmation. # The fold(1) is just to make the web # release page easier to work with. git tag -a 20181024 -m 'Release 20181024' git push origin 20181024 # push the tag In the Tests: git push origin master git tag -a 20181024 -m 'Release 20181024' git push origin 20181024 # push the tag Update web pages so that the new release is visible to users and copy the tar.gz to the appropriate web site. dwarfutils-20200114/scripts/ChangeLog000066400000000000000000000002611361531463500174000ustar00rootroot000000000000002020-01-14 David Anderson * buildandreleasetest.sh: The script element that finds the version in configure.ac now also allows for 202xmmdd versions, not just 201xmmdd dwarfutils-20200114/scripts/ChangeLog2018000066400000000000000000000017221361531463500177160ustar00rootroot000000000000002018-09-21 David Anderson * buildandreleasetest.sh: Now uses the 2nd-generation release as source and does a cmake to verify cmake works. The new test lines added at the end (about line 129) but /tmp/cmakebld directory setup occurs early in this script. 2018-08-02 David Anderson * FIX-CONFIGURE-TIMES: Added another cautionary check before doing anything. 2018-08-01 David Anderson * FIX-CONFIGURE-TIMES: Was not cautious enough about whether it was in the right place and also was fussy about the top-level name being 'code'. Both issues fixed. 2018-07-16 David Anderson * CLEANUP: Now uses distclean so deleted a few lines here. * fixlibdwarfelf.sh: Used by configure to create libdwarf.h from libdwarf.h.in * generatedcasetext.c: A utility used to generate a ctype-like table for converting to uri-style. The table exists in dwarfdump so this C file likely will not be used again. dwarfutils-20200114/scripts/FIX-CONFIGURE-TIMES000066400000000000000000000036601361531463500204030ustar00rootroot00000000000000#/bin/sh # After doing a copy of the source tree (as by 'cp -r') # the timestamps are not always # such that a build will work. File timestamps matter # with the new configure. # If the 'configure ; make' ends in failure with a message about # aclocal-1.15 being missing then this script # will likely fix that problem. # With 'cp -rp' the problem should not arise. # Note that one user found the command: # touch aclocal.m4 Makefile.am configure Makefile.in # sufficient to avoid the problem. l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` cdtarg=. sloc=$l/scripts rightplace() { for i in dwarfdump dwarfgen libdwarf dwarfexample m4 scripts do if [ ! -d $i ] then echo "$i is not a directory of $1." echo "we are not in the right place to touch configure etc" echo "to fix the missing aclocal-1.15 problem." echo "No action taken" exit 1 fi done } if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" echo "We appear to start in libdwarf scripts directory" echo "Change directory .." cd .. echo "Are we in the right directory now?" `pwd` rightplace `pwd` echo "Yes, we are in the right directory." else echo "Are we in the right directory?" rightplace `pwd` echo "Yes, we are in the right directory." fi l=`pwd` echo "Now touch files to get timestamps usable." for i in \ m4/ax_prog_cc_for_build.m4 \ m4/dw_compiler.m4 \ dwarfexample/Makefile.am \ dwarfdump/Makefile.am \ Makefile.am \ dwarfgen/Makefile.am \ libdwarf/Makefile.am \ configure.ac \ ltmain.sh \ m4/libtool.m4 \ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ m4/lt~obsolete.m4 \ aclocal.m4 \ configure \ config.h.in \ ar-lib \ compile \ config.guess \ config.sub \ install-sh \ missing \ INSTALL \ Makefile.in \ dwarfdump/Makefile.in \ dwarfexample/Makefile.in \ dwarfgen/Makefile.in \ depcomp \ test-driver \ libdwarf/Makefile.in do sleep 1 #echo "now touch $i" touch $i done dwarfutils-20200114/scripts/GETTOTOP000066400000000000000000000015111361531463500170150ustar00rootroot00000000000000# This is used in (copied into) each script to adjust # our location to the code directory above dwarfdump, libdwarf, etc. # If not invoked from code or code/scripts it exits. # This is the original copy (not used directly). l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" dwarfutils-20200114/scripts/REBLDLIBDWARF000077500000000000000000000017021361531463500175200ustar00rootroot00000000000000#!/bin/sh # Assume configure done recently. l=`pwd` echo $l lb=`basename $l` ld=`dirname $l` #echo " lb: $lb" #echo " ld: $ld" cdtarg=. sloc=$l/scripts if [ x$lb = "xscripts" ] then #echo "ld: $ld" ldb=`basename $ld` #echo "ldb: $ldb" if [ x$ldb = "xcode" ] then cdtarg=.. sloc=$l else echo "Run from */code, not $l , giving up." exit 1 fi cd $cdtarg if [ $? -ne 0 ] then echo "cd $cdtarg failed, giving up." exit 1 fi else if [ x$lb = "xcode" ] then cdtarg="." else echo "Run from */code, not $l , giving up." exit 1 fi # No need to cd. fi l=`pwd` #echo "Now at $l" #echo "sloc $sloc" cd $sloc/libdwarf if [ $? != 0 ] then echo build failed exit fi make if [ $? != 0 ] then echo build failed exit fi cd .. cd $sloc/dwarfdump if [ $? != 0 ] then echo build failed exit fi # rm in case we changed libdwarf. rm dwarfdump make if [ $? != 0 ] then echo build failed exit fi cd .. dwarfutils-20200114/scripts/RUNPY000066400000000000000000000010431361531463500164650ustar00rootroot00000000000000# Run in the libdwarf directory # These enable simple checking that the source, header, # and documentation match up. No need to peruse # long lists of function names. # example: # fldiff junknonhdr junknonmm # fldiff junknonhdr junknonsrc d=../scripts # These versions show original line numbers. Sometimes useful. $d/funcfinderhdr.py >junknhdr $d/funcfindermm.py >junknmm $d/funcfindersrcs.py >junknsrc $d/funcfinderhdr.py --nonumbers >junknonhdr $d/funcfindermm.py --nonumbers >junknonmm $d/funcfindersrcs.py --nonumbers >junknonsrc dwarfutils-20200114/scripts/SETUP_MASTER_TREE000066400000000000000000000062461361531463500203540ustar00rootroot00000000000000#!/bin/sh echo "Largely out of date, fix before running" exit 1; #modify this before running. cat > tarlist.tmp < tarlist.tmp < $sloc/UPD.awk <<\EOF BEGIN { if (ARGC <= 2) { print "Bogus use of awk file, requires arg" exit 1 } else { v=ARGV[1] ARGV[1]="" } } $0 ~ /#define DW_VERSION_DATE_STR/ { print $1, $2, "\"",v,"\"" } $0 !~ /^#define DW_VERSION_DATE_STR/ { print $0 } EOF awk -f $sloc/UPD.awk "$x" $l/libdwarf/libdwarf_version.h >t mv t $l/libdwarf/libdwarf_version.h dwarfutils-20200114/scripts/baseconfig.h000066400000000000000000000051151361531463500201020ustar00rootroot00000000000000/* baseconfig.h. Maintained by hand for buildstandardsource.sh */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Only defined here, done for the benefit if buildstandardsource.sh */ #define BUILD_STANDARD_SOURCE 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Fake. For buildstandardsource.sh */ #define PACKAGE_VERSION "20190101" /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define 1 if need nonstandard printf format for 64bit */ /* #undef HAVE_NONSTANDARD_PRINTF_64_FORMAT */ /* Set to 1 if old frame columns are enabled. */ /* #undef HAVE_OLD_FRAME_CFA_COL */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SGIDEFS_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Set to 1 if __attribute__ ((unused)) is available. */ #define HAVE_UNUSED_ATTRIBUTE 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ /* Define 1 if want to allow Windows full path detection */ /* #undef HAVE_WINDOWS_PATH */ /* Set to 1 if zlib decompression is available. */ #define HAVE_ZLIB 1 /* Define to 1 if you have the header file. */ #define HAVE_ZLIB_H 1 /* Define to the sub-directory where libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ dwarfutils-20200114/scripts/buildandreleasetest.sh000066400000000000000000000130471361531463500222130ustar00rootroot00000000000000#!/bin/sh # A script verifying the distribution gets all needed files # for building, including 'make check' # First, get the current configure.ac version into v: # if stdint.h does not define uintptr_t and intptr_t # Then dwarfgen (being c++) will not build # Use --disable-libelf to disable reliance on libelf # and dwarfgen. # To just eliminate dwarfgen build/test/install use --disable-dwarfgen. genopta="--enable-dwarfgen" genoptb="-DBUILD_DWARFGEN=ON" libelfopt='' wd=`pwd` nonstdprintf= while [ $# -ne 0 ] do case $1 in --disable-libelf ) genopta='' ; genoptb='' libelfopt=$1 ; shift ;; --enable-libelf ) shift ;; --disable-dwarfgen ) genopta='' ; genoptb='' ; shift ;; --enable-nonstandardprintf ) nonstdprintf=$1 ; shift ;; * ) echo "Unknown buildandreleasetest.sh option $1. Error." ; exit 1 ;; esac done if [ -f ./configure.ac ] then f=./configure.ac else if [ -f ../configure.ac ] then f=../configure.ac else echo "FAIL Running distribution test from the wrong place." exit fi fi v=`grep -o '20[1-2][0-9][0-9][0-9][0-9][0-9]'< $f | head -n 1` if [ x$v = "x" ] then echo FAIL did not get configure.ac version exit 1 fi configloc=$wd/configure rm -rf /tmp/dwbld rm -rf /tmp/dwinstall rm -rf /tmp/dwinstallrel rm -rf /tmp/dwinstallrelbld rm -rf /tmp/dwbigendianbld rm -rf /tmp/dwinstallrelbldall rm -f /tmp/dwrelease.tar.gz rm -rf /tmp/dwreleasebld rm -rf /tmp/cmakebld mkdir /tmp/dwbld if [ $? -ne 0 ] then echo FAIL A1 mkdir exit 1 fi mkdir /tmp/dwinstall if [ $? -ne 0 ] then echo FAIL A2 mkdir exit 1 fi mkdir /tmp/dwinstallrel if [ $? -ne 0 ] then echo FAIL A3 mkdir exit 1 fi mkdir /tmp/dwinstallrelbld if [ $? -ne 0 ] then echo FAIL A3b mkdir exit 1 fi mkdir /tmp/dwinstallrelbldall if [ $? -ne 0 ] then echo FAIL A3c mkdir /tmp/dwinstallrelbldall exit 1 fi mkdir /tmp/dwbigendianbld if [ $? -ne 0 ] then echo FAIL A3bigend mkdir /tmp/dwbigendianbld exit 1 fi mkdir /tmp/cmakebld if [ $? -ne 0 ] then echo FAIL A3d mkdir /tmp/cmakebld exit 1 fi echo "dirs created empty" echo cd /tmp/dwbld cd /tmp/dwbld if [ $? -ne 0 ] then echo FAIL A cd $v exit 1 fi echo "now: $configloc --prefix=/tmp/dwinstall $libelfopt $nonstdprintf" $configloc --prefix=/tmp/dwinstall $libelfopt $nonstdprintf if [ $? -ne 0 ] then echo FAIL A4a configure fail exit 1 fi echo "TEST: initial (dwinstall) make install" make install if [ $? -ne 0 ] then echo FAIL A4b make install exit 1 fi ls -lR /tmp/dwinstall make dist ls -1 *tar.gz >/tmp/dwrelset ct=`wc < /tmp/dwrelset` echo "count of gz files $ct" cp *.tar.gz /tmp/dwrelease.tar.gz cd /tmp if [ $? -ne 0 ] then echo FAIL B2 cd /tmp exit 1 fi tar -zxf /tmp/dwrelease.tar.gz ls -d *dw* ################ echo "TEST: now cd libdwarf-$v for second build install" cd /tmp/dwinstallrelbld if [ $? -ne 0 ] then echo FAIL C cd /tmp/dwinstallrelbld exit 1 fi echo "TEST: now second install install, prefix /tmp/dwinstallrel" echo "TEST: Expecting src in /tmp/libdwarf-$v" /tmp/libdwarf-$v/configure --enable-wall --prefix=/tmp/dwinstallrel $libelfopt $nonstdprintf if [ $? -ne 0 ] then echo FAIL C2 configure fail exit 1 fi echo "TEST: In dwinstallrelbld make install from /tmp/libdwarf-$v/configure" make install if [ $? -ne 0 ] then echo FAIL C3 final install fail exit 1 fi ls -lR /tmp/dwinstallrel echo "TEST: Now lets see if make check works" make check if [ $? -ne 0 ] then echo FAIL make check C4 exit 1 fi ################ ################ echo "TEST: now cd libdwarf-$v for big-endian build (not runnable) " cd /tmp/dwbigendianbld if [ $? -ne 0 ] then echo FAIL C be1 /tmp/dwbigendianbld exit 1 fi echo "TEST: now second install install, prefix /tmp/dwinstallrel" echo "TEST: Expecting src in /tmp/libdwarf-$v" echo "TEST: /tmp/libdwarf-$v/configure $genopta --enable-wall --enable-dwarfexample --prefix=/tmp/dwinstallrel $libelfopt $nonstdprintf" /tmp/libdwarf-$v/configure $genopta --enable-wall --enable-dwarfexample --prefix=/tmp/dwinstallrel $libelfopt $nonstdprintf if [ $? -ne 0 ] then echo FAIL be2 configure fail exit 1 fi echo "#define WORDS_BIGENDIAN 1" >> config.h echo "TEST: Compile In dwbigendianbld make from /tmp/libdwarf-$v/configure" make if [ $? -ne 0 ] then echo FAIL be3 Build failed exit 1 fi ################ cd /tmp/dwinstallrelbldall if [ $? -ne 0 ] then echo FAIL Ca cd /dwinstallrelbldall exit 1 fi echo "TEST: Now configure from source dir /tmp/libdwarf-$v/ in build dir /tmp/dwinstallrelbldall" /tmp/libdwarf-$v/configure --enable-wall --enable-dwarfexample $genopta $nonstdprintf if [ $? -ne 0 ] then echo FAIL C9 /tmp/libdwarf-$v/configure exit 1 fi make if [ $? -ne 0 ] then echo FAIL C9 /tmp/libdwarf-$v/configure make exit 1 fi cd /tmp/cmakebld if [ $? -ne 0 ] then echo FAIL C10 cd /tmp/cmakebld exit 1 fi havecmake=n which cmake >/dev/null if [ $? -eq 0 ] then havecmake=y echo "We have cmake and can test it." fi if [ $havecmake = "y" ] then echo "TEST: Now cmake from source dir /tmp/libdwarf-$v/ in build dir /tmp/cmakebld" cmake $genoptb -DWALL=ON -DBUILD_DWARFEXAMPLE=ON -DDO_TESTING=ON /tmp/libdwarf-$v/ if [ $? -ne 0 ] then echo "FAIL C10b cmake in /tmp/cmakebld" exit 1 fi make if [ $? -ne 0 ] then echo "FAIL C10c cmake make in /tmp/cmakebld" exit 1 fi make test if [ $? -ne 0 ] then echo "FAIL C10d cmake make test in /tmp/cmakebld" exit 1 fi ctest -R self if [ $? -ne 0 ] then echo "FAIL C10e ctest -R self in /tmp/cmakebld" exit 1 fi else echo "cmake is not installed so not tested." fi exit 0 dwarfutils-20200114/scripts/buildstandardsource.sh000066400000000000000000000032431361531463500222260ustar00rootroot00000000000000# # Use to build the .c and .h source based on static information # in libdwarf.h.in and dwarf_errmsg_list.h and the dwarfdump *.list files. # If you change any of those you should run this script # (which, for non-linux non-unix may mean some changes of this script # or of scripts/libbuild.sh or scripts.ddbuild.sh or baseconfig.h) # # This script is by David Anderson and hereby put into the public domain # for anyone to use in any way. # cp scripts/baseconfig.h config.h if [ $? -ne 0 ] then echo "FAIL getting base config.h for .c .h builing.Runningfrom wrong place?" exit 1 fi cd libdwarf if [ $? -ne 0 ] then echo "FAIL cd to libdwarf. Running buildstandardsource.sh from the wrong place" exit 1 fi cp libdwarf.h.in libdwarf.h sed 's/struct Elf/struct _Elf/g' ub_temp cmp ub_temp generated_libdwarf.h.in if [ $? -ne 0 ] then # Since cmake does not copy ; sensibly we will # provide a unique version for _Elf platforms. # libdwarf.h.in differs from generated_libdwarf.h.in: * update the latter. mv ub_temp generated_libdwarf.h.in fi rm ub_temp sh ../scripts/libbuild.sh if [ $? -ne 0 ] then echo "FAIL libbuild.sh. " exit 1 fi cd .. if [ $? -ne 0 ] then echo "FAIL cd back to top-level" exit 1 fi cd dwarfdump if [ $? -ne 0 ] then echo "FAIL cd to dwarfdump. Running buildstandardsource.sh from the wrong place" exit 1 fi sh ../scripts/ddbuild.sh if [ $? -ne 0 ] then echo "FAIL building dwarfdump .c .h source" exit 1 fi cd .. if [ $? -ne 0 ] then echo "FAIL second cd back to top-level" exit 1 fi rm -f config.h rm -f libdwarf/libdwarf.h echo "PASS. The .c and .h files are built" exit 0 dwarfutils-20200114/scripts/conddef.py000077500000000000000000000053361361531463500176150ustar00rootroot00000000000000#! /usr/bin/env python3 #conddef.py.py #Copyright (c) 2018, David Anderson #All rights reserved. # #Redistribution and use in source and binary forms, with #or without modification, are permitted provided that the #following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the following # disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND #CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, #INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE #ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR #CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; #LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN #CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR #OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, #EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #Reads #define x y #lines #and turns them into #ifndef x #define x y #endif import os import sys def getfirstthree(s): out = "" if len(s) >= 3: out = "".join((s[0],s[1],s[2])) return out def reader(path): try: file = open(path,"r") except IOError as message: print("File could not be opened: ", message,file=sys.stderr) sys.exit(1) out = [] iline = 0 saveword = "" for line in file: iline = int(iline) + 1 l2 = line.rstrip() wds = l2.split() if len(wds) < 3: continue if wds[0] != "#define": continue mdef = wds[1] val = wds[2] out+= [(mdef,val)] file.close() return out if __name__ == '__main__': filename = "" if len(sys.argv) == 3: if sys.argv[1] == "--infile": filename = sys.argv[2] else: print("argument ", sys.argv[1]," ignored") else: print("Usage: conddef.py --infile ") sys.exit(1) full_list = reader(filename) maxlen = 16 for f in full_list: (mdef,val) = f dlen = len(mdef) if int(dlen) > int(maxlen): maxlen = int(dlen) pstr = "#define %-" + str(maxlen) + "s %s" initial = "" for f in full_list: (mdef,val) = f ourthree = getfirstthree(mdef) if initial != ourthree: print("") initial = ourthree print("#ifndef",mdef) print(pstr % (mdef,val)) print("#endif") dwarfutils-20200114/scripts/dateorder000066400000000000000000000003411361531463500175210ustar00rootroot00000000000000# This uses GNU options, and is not intended to # work on other than Linux. # Not something to use except in special undefined circumstances. find . -type f -printf '%T@ %P\n' | sort -n | awk '{print $2}' |grep -v '^.git' dwarfutils-20200114/scripts/ddbuild.sh000066400000000000000000000046021361531463500175740ustar00rootroot00000000000000# ddbuild.sh # A primitive build. # Intended for simple non-elf builds on systems # with no libelf, no elf.h, no libz. # This script is by David Anderson and hereby # put into the public domain # for anyone to use in any way. # Requires a basic config.h at top level d=`pwd` db=`basename $d` if [ x$db != "xdwarfdump" ] then echo FAIL Run this in the dwarfdump directory. exit 1 fi set -x top_builddir=.. top_srcdir=.. CC="gcc -g -I.. -I../libdwarf" EXEXT=.exe cp $top_builddir/libdwarf/dwarf_names.c . cp $top_builddir/libdwarf/dwarf_names.h . $CC -DTRIVIAL_NAMING dwarf_names.c common.c \ dwarf_tsearchbal.c \ dwgetopt.c \ esb.c \ makename.c \ naming.c \ sanitized.c \ tag_attr.c \ tag_common.c -o tag_attr_build$EXEXT if [ $? -ne 0 ] then echo tag_attr_build compile fail exit 1 fi $CC -DTRIVIAL_NAMING dwarf_names.c common.c \ dwarf_tsearchbal.c \ dwgetopt.c \ esb.c \ makename.c \ naming.c \ sanitized.c \ tag_common.c \ tag_tree.c -o tag_tree_build$EXEXT if [ $? -ne 0 ] then echo tag_tree_build compile fail exit 1 fi rm -f tmp-t1.c cp $top_srcdir/dwarfdump/tag_tree.list tmp-t1.c $CC -E tmp-t1.c >tmp-tag-tree-build1.tmp ./tag_tree_build$EXEXT -s -i tmp-tag-tree-build1.tmp -o dwarfdump-tt-table.h if [ $? -ne 0 ] then echo tag_tree_build 1 FAIL exit 1 fi rm -f tmp-tag-tree-build1.tmp rm -f tmp-t1.c rm -f tmp-t2.c cp $top_srcdir/dwarfdump/tag_attr.list tmp-t2.c $CC -DTRIVIAL_NAMING -I$top_srcdir/libdwarf -E tmp-t2.c >tmp-tag-attr-build2.tmp ./tag_attr_build$EXEXT -s -i tmp-tag-attr-build2.tmp -o dwarfdump-ta-table.h if [ $? -ne 0 ] then echo tag_attr_build 2 FAIL exit 1 fi rm -f tmp-tag-attr-build2.tmp rm -f tmp-t2.c rm -f tmp-t3.c cp $top_srcdir/dwarfdump/tag_attr_ext.list tmp-t3.c $CC -I$top_srcdir/libdwarf -DTRIVIAL_NAMING -E tmp-t3.c > tmp-tag-attr-build3.tmp ./tag_attr_build$EXEXT -e -i tmp-tag-attr-build3.tmp -o dwarfdump-ta-ext-table.h if [ $? -ne 0 ] then echo tag_attr_build 3 FAIL exit 1 fi rm -f tmp-tag-attr-build3.tmp rm -f tmp-t3.c rm -f tmp-t4.c cp $top_srcdir/dwarfdump/tag_tree_ext.list tmp-t4.c $CC -I$top_srcdir/libdwarf -DTRIVIAL_NAMING -E tmp-t4.c > tmp-tag-tree-build4.tmp ./tag_tree_build$EXEXT -e -i tmp-tag-tree-build4.tmp -o dwarfdump-tt-ext-table.h if [ $? -ne 0 ] then echo tag_tree_build 4 compile fail exit 1 fi rm -f tmp-tag-tree-build4.tmp rm -f tmp-t4.c rm -f tag_attr_build$EXEXT rm -f tag_tree_build$EXEXT exit 0 dwarfutils-20200114/scripts/fixlibdwarfelf.sh000066400000000000000000000006131361531463500211530ustar00rootroot00000000000000#!/bin/sh if [ $# -ne 3 ] then echo "ERROR fixlibdwarfelf.sh wrong argument count: $#" exit 1 fi # Yes means use struct _Elf, no means use struct Elf yorn=$1 srcdir=$2/libdwarf builddir=$3/libdwarf #echo "dadebug $yourn $srcdir $builddir" if [ x$yorn = "xno" ] then cp $srcdir/libdwarf.h.in $builddir/libdwarf.h else cp $srcdir/generated_libdwarf.h.in $builddir/libdwarf.h fi exit 0 dwarfutils-20200114/scripts/funcfinderhdr.py000077500000000000000000000053641361531463500210350ustar00rootroot00000000000000#! /usr/bin/env python3 #funcfinderhdr.py #Copyright (c) 2018, David Anderson #All rights reserved. # #Redistribution and use in source and binary forms, with #or without modification, are permitted provided that the #following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the following # disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND #CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, #INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE #ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR #CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; #LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN #CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR #OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, #EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #Reads libdwarf.h.in and produces a concise list #of the declared functions, sorted by function name. # Run as # funcfinderhdr.py # or # funcfinderhdr.py --nonumbers import os import sys def looks_like_func(s): fwds = s.split("(") if len(fwds) < 2: #print("Not func",fwds) return "n","","","" if fwds[1].startswith(")") == 1: return "n","","","" fwds2 = fwds[0].split(" ") if len(fwds2) < 2: #print("Not func",fwds) return "n","","","" if len(fwds2) == 2: return "y",fwds2[1],fwds2[0],"" if len(fwds2) == 3: return "y",fwds2[2],fwds2[0],fwds2[1] return "n","","","" def reader(path): try: file = open(path,"r") except IOError as message: print("File could not be opened: ", message,file=sys.stderr) sys.exit(1) out = [] iline = 0 saveword = "" for line in file: iline = int(iline) + 1 l2 = line.rstrip() #if wds[0] != ".H 3 ": #print(wds[0]) isf,func,reta,retb = looks_like_func(l2) if isf == "y": out += [(func,reta,retb,iline)] file.close() return out if __name__ == '__main__': showlinenum = "y" if len(sys.argv) > 1: if sys.argv[1] == "--nonumbers": showlinenum = "n" else: print("argument ", sys.argv[1],"ignored") full_list = reader("libdwarf.h.in"); full_list.sort() for f in full_list: if showlinenum == "y": print(f) else: print(f[0],f[1]) dwarfutils-20200114/scripts/funcfindermm.py000077500000000000000000000054161361531463500206670ustar00rootroot00000000000000#! /usr/bin/env python3 #funcfindermm.py #Copyright (c) 2018, David Anderson #All rights reserved. # #Redistribution and use in source and binary forms, with #or without modification, are permitted provided that the #following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the following # disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND #CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, #INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE #ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR #CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; #LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN #CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR #OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, #EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys #Reads libdwarf2p.1.mm and produces a concise list #of the documented functions, sorted by function name. # Run as # funcfindermm.py # or # funcfindermm.py --nonumbers # \f(CWint dwarf_producer_init( def looks_like_func(s): fwds = s.split("(") if len(fwds) < 2: #print("Not func",fwds) return "n","","" if fwds[1].startswith(")"): return "n","","" fwds2 = fwds[0].split(" ") if len(fwds2) < 2: #print("Not func",fwds) return "n","","" return "y",fwds2[1],fwds2[0] def reader(path): try: file = open(path,"r") except IOError as message: print("File could not be opened: ", message,file=sys.stderr) sys.exit(1) out = [] iline = 0 for line in file: iline = int(iline) + 1 l2 = line.rstrip() wds = l2.split('W'); #if wds[0] != ".H 3 ": if len(wds) < 2: continue if not wds[0].startswith("\\"): continue #print(wds[0]) if wds[0] != "\\f(C": continue isf,func,ret = looks_like_func(wds[1]) if isf == "y": out += [(func,ret,iline)] file.close() return out if __name__ == '__main__': showlinenum = "y" if len(sys.argv) > 1: if sys.argv[1] == "--nonumbers": showlinenum = "n" else: print("argument ", sys.argv[1],"ignored") funcl = reader("libdwarf2p.1.mm"); funcl.sort() for f in funcl: if showlinenum == "y": print(f) else: print(f[0],f[1]) dwarfutils-20200114/scripts/funcfindersrcs.py000077500000000000000000000066561361531463500212370ustar00rootroot00000000000000#! /usr/bin/env python3 #funcfindersrcs.py #Copyright (c) 2018, David Anderson #All rights reserved. # #Redistribution and use in source and binary forms, with #or without modification, are permitted provided that the #following conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the following # disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # #THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND #CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, #INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES #OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE #ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR #CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT #NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; #LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) #HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN #CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR #OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, #EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys #Reads the producer code source and produces a concise list #of the implemented functions, sorted by function name. # Run as # funcfindersrcs.py # or # funcfindersrcs.py --nonumbers filelist = [ "pro_alloc.c", "pro_alloc.c", "pro_arange.c", "pro_die.c", "pro_dnames.c", "pro_encode_nm.c", "pro_error.c", "pro_expr.c", "pro_finish.c", "pro_forms.c", "pro_frame.c", "pro_funcs.c", "pro_init.c", "pro_line.c", "pro_macinfo.c", "pro_pubnames.c", "pro_reloc.c", "pro_reloc_stream.c", "pro_reloc_symbolic.c", "pro_section.c", "pro_types.c", "pro_vars.c", "pro_weaks.c", "dwarf_util.c", "dwarf_util.c", ] def looks_like_func(s): fwds = s.split("(") if len(fwds) < 2: #print("Not func",fwds) return "n","","","" fwds2 = fwds[0].split(" ") if len(fwds2) < 2: #print("Not func",fwds) return "n","","","" if len(fwds2) == 2: return "y",fwds2[1],fwds2[0],"" if len(fwds2) == 3: return "y",fwds2[2],fwds2[0],fwds2[1] return "n","","","" def reader(path): try: file = open(path,"r") except IOError as message: print("File could not be opened: ", message,file=sys.stderr) sys.exit(1) out = [] iline = 0 prevline = '' all_the_lines = file.read().splitlines() file.close() #print("No. Lines:",len(all_the_lines)) for line in all_the_lines: l2 = line.rstrip() iline = int(iline) + 1 if l2.startswith(" ") == 1: continue if l2.startswith("/") == 1: continue if l2.startswith("dwarf_") == 1: l3 = l2.split("("); if len(l3) < 2: printf(" dadebug odd-a ",l3); continue if l3[1].startswith(")") == 1: continue out += [(l3[0],prev,iline,path)] else: prev=l2.strip() return out if __name__ == '__main__': showlinenum = "y" if len(sys.argv) > 1: if sys.argv[1] == "--nonumbers": showlinenum = "n" else: print("argument ", sys.argv[1],"ignored") funcl = [] for path in filelist: funcl += reader(path) funcl.sort() for f in funcl: if showlinenum == "y": print(f) else: print(f[0],f[1]) dwarfutils-20200114/scripts/libbuild.sh000066400000000000000000000021421361531463500177500ustar00rootroot00000000000000# libbuild.sh # Build the .c .h needed for libdwarf. # Intended for simple non-elf builds on systems # This script is by David Anderson and hereby put into the public domain # for anyone to use in any way. # Requires a basic config.h at top level # Possibly cp scripts/baseconfig.h config.h # Run this from the libdwarf directory. d=`pwd` db=`basename $d` if [ x$db != "xlibdwarf" ] then echo FAIL Run this in the libdwarf directory. exit 1 fi set -x CC="gcc -g -I.." $CC gennames.c dwgetopt.c -o gennames rm -f dwarf_names.h dwarf_names.c dwarf_names_enum.h dwarf_names_new.h ./gennames -i . -o . if [ $? -ne 0 ] then echo gennames fail exit 1 fi $CC dwarf_test_errmsg_list.c -o errmsg_check if [ $? -ne 0 ] then echo build errmsgcheck fail exit 1 fi # This produces no output. # If it fails it indicates a problem with the DW_DLE names or strings. # If it passes there is no problem. grep DW_DLE libdwarf.h.in >errmsg_check_list ./errmsg_check -f errmsg_check_list if [ $? -ne 0 ] then echo errmsg check fail exit 1 fi rm -f gennames rm -f errmsg_check_list rm -f errmsg_check exit 0 dwarfutils-20200114/test-driver000077500000000000000000000110401361531463500163320ustar00rootroot00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2013-07-13.22; # UTC # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: dwarfutils-20200114/tsearch/000077500000000000000000000000001361531463500155715ustar00rootroot00000000000000dwarfutils-20200114/tsearch/ChangeLog000066400000000000000000000000271361531463500173420ustar00rootroot000000000000002020-01-05 placeholder dwarfutils-20200114/tsearch/ChangeLog2014000066400000000000000000000011441361531463500176520ustar00rootroot000000000000002014-12-09: David Anderson * dwarf_tsearchhash.c(tsearch_inner): Add check for NULL so we do not just coredump if out of memory. * dwarf_tsearchred.c(tsearch_inner): Add check for NULL so we do not just coredump if out of memory. 2014-09-10: David Anderson * dwarf_tsearchhash.c(calculate_allowed_fill): Moved a declaration to avoid using C99 feature. 2014-08-04: David Anderson * dwarf_tsearchhash.c: Changed to avoid compiler warnings about const casts whereever possible. 2014-01-29: David Anderson * All files: All added. Trailing whitespace removed. dwarfutils-20200114/tsearch/ChangeLog2015000066400000000000000000000002061361531463500176510ustar00rootroot000000000000002015-09-15 David Anderson * dwarf_tsearchred.c: Fixed indentation errors. 2015-01-01 David Anderson * A new year begins. dwarfutils-20200114/tsearch/ChangeLog2016000066400000000000000000000027321361531463500176600ustar00rootroot000000000000002016-02-17 David Anderson * tsearch/config.h: Add some things convenient for testing. * tsearch/dwarf_tsearch.c: Convenient for some testing. * dwarf_tsearch.h: Modifications aid in testing tsearch. 2016-02-07 David Anderson * RUNTEST: the script had a couple of problems (typos). Fixed. Added comments about running the tests. * dwarf_tsearch.h: Provide a default DW_TSHASHTYPE for tsearchhash and use DW_TSHASHTYPE. * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchred.c: Use DW_TSHASHTYPE. * dwarf_tsearchhash.c: use DW_TSHASHTYPE, add UNUSEDARG use. Now the primes list starts at 79, not 5 (the low numbers were really only for basic testing). Add UNUSEDARG though it is defined as empty here (it is for gcc to suppress some warnings). * tsearch_tester.c: Use DW_TSHASHTYPE. Changed one error message to help match with input test files. 2016-02-07 David Anderson * All .h, .c: Changed the return type of the hashfunc to be DW_TSHASHTYPE so it can easily be overridden. Unsigned long did not work well on a P64, IL32 environment. Now it is easy to use -D to for folks in such an environment. 2016-01-20 David Anderson * dwarf_tsearchbal.c: Deleted the unused little function rotatex(). 2016-01-14 David Anderson * dwarf_tsearchtester.c: Fixed compilation warnings (some of them). * dwarf_tsearchbal.c: Added a comment. dwarfutils-20200114/tsearch/ChangeLog2017000066400000000000000000000003031361531463500176510ustar00rootroot000000000000002017-01-23 David Anderson * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c(dwarf_tsearch): In case memory exausted the function could leak a small amount of memory. dwarfutils-20200114/tsearch/ChangeLog2018000066400000000000000000000023741361531463500176640ustar00rootroot000000000000002018-09-11 David Anderson & Carlos Alberto Enciso * dwarf_tsearchhash.c: Remove trailing blank. Now matches version in libdwarf. * dwarf_tsearchbal.c: Change int to size_t where applicable. Fix too-long lines in a couple places 2018-07-20 David Anderson * dwarf_tsearchhash.c: Added UNUSEDARG where appropriate. 2018-07-16 David Anderson * dwarf_tsearch.h: Corrected obsolete web references. Refined HAVE_STDAFX_H ifdef. Realigned text formatting for a better presentation. * config.h: Undef HAVE_STDAFX_H. This is hand coded, not generated. Never changes. 2018-07-10 David Anderson * dwarf_tsearchbal.c,dwarf_tsearchbin.c,dwarf_tsearchepp.c, dwarf_tsearchhash.c,dwarf_tsearchred.c: Removed dependency on dwarf_incl.h. All we need is appropriate definition of UNUSEDARG macro. * ESSAY.txt: Fixed a typo and made line lengths more even. 2018-07-14 David Anderson * config.h: Removed leading blank line. * dwarf_tsearch.h: Removed three trailing blank lines. 2018-07-13 David Anderson * dwarf_tsearchbal.c,dwarf_tsearch.c, dwarf_tsearchhash.c, dwarf_tsearchbin.c,dwarf_tsearchepp.c,dwarf_tsearchred.c: Removed 3 trailing blank lines from each. dwarfutils-20200114/tsearch/ESSAY.txt000066400000000000000000000363161361531463500172270ustar00rootroot00000000000000Some thoughts about tsearch. David Anderson Updated 15 February 2014 Updated 24 June 2018 (fixing a typo and regularizing line lengths). Tsearch() was defined and implemented fairly early in the history of UNIX, but I don't know exactly when. The earliest documentation I have is from the 1991 edition of UNIX System V Release 4 Programmer's Reference Manual. It is useful because it enables one to make a searchable tree of, well, any data one might have need to search. Tsearch never needs to understand the format of the data. The functions defined there are tsearch(), tfind(), tdelete(), and twalk(). The description is just as difficult to understand as the documentation in release 3.54 of the Linux man-pages project (the most recent I have on hand). The Single Unix Specification page on tsearch() etc is slightly different text from the Programmer's Reference Manual and the Linux man page, but no clearer. The confusion is partly due to the interface definition. Until the late 20th century only limited attention was given to interface design. By the late 20th century it seems clear that any newly designed tsearch-like functionality would have a significantly different interface. An example of an improved interface is the GNU/Linux function hsearch_r(). Making the return value a small integer defining what the function actually did (and using other arguments to return additional values as necessary) significantly simplifies the discussion. Here though we are talking about the old and standard interface. We attempt to clarify the messy parts. See the examples provided for actual code. The functions and tables of tsearch are not thread safe. Nor thread-aware. Any access to one of tables at the same time the table is being updated will lead to chaos eventually. Any table tsearch maintains consists of records of undefined (meaning the definition is local to the internals) content each record of which contains, as one element, a copy of a KEY pointer. In the following I freely use tsearch for dwarf_tsearch etc. The functionality and interfaces are identical. ========= Further reading The canonical reference for binary trees and the algorithm reference for most of the tsearch code is Donald E. Knuth, "The Art of Computer Programming" Volume 3 Sorting and Searching, Second Edition. "Algorithms" Fourth Edition, Robert Sedgewick and Kevin Wayne, is the basis for the red-black tree coding. Wikipedia has quite a few entries of interest. http://en.wikipedia.org/wiki/Self-balancing_binary_search_tree http://en.wikipedia.org/wiki/Tree_traversal http://en.wikipedia.org/wiki/Red–black_tree are just a few. After implementing tsearch I looked briefly at some other projects. freecode.net: See the 'GNU libavl' project. The libavl libary is a GNU project in C with each tree type having a uniquely-named but consistent set of interfaces. The interface design is much more sensible than Unix TSEARCH. You will probably find it in most any Linux distribution. The 2.0.3 tarfile source has no configure step and the 2.0.3 Makefile failed for me, it placed -lm too early on the command line building texitree means the version mentioned on freecode.net: ftp://ftp.gnu.org/pub/gnu/avl/avl-2.0.3.tar.gz is rather old but shows internal evidence of last being updated in 2007 (*.pdf and other file timestamps in the tar file). The Makefile fails for me doing plain 'make'. Doing 'make program' to just build the source works fine. The interface definitions are more sensible than tsearch, rb_delete returns the deleted item when it succeeds, for example. freecode.net: See the 'libredblack' project. This project tarfile was last updated in 2003. It is on sourceforge at http://sourceforge.net/projects/redblacktree/ Implemented in C. Configure worked (version 1.3) but the make step failed running the python app ./rbgen due to the presence of the string %prefix on line 9 of rbgen. Removing that one line of python commentary from Eric Raymond fixed the build! There is a good amount of C #define magic making it harder to read the source than one might expect. The interface definitions are more sensible than tsearch, rb_delete returns the deleted item when it succeeds, for example. freecode.net: See the project 'Template based B+ Tree'. Is in C++ and can be used for searches which are file or memory based through use of C++ templates by the implemenation. Have not attempted to build it. ========= tsearch: void *tsearch(const void *key, void **rootp, int (*compar)(const void *l, const void *r)); Our terminology comes from the above declaration. tsearch() returns a pointer. If tsearch fails due to an out of memory or internal error it returns NULL. Otherwise it returns a non-null pointer (see Return value, below). KEY: First we will define KEY as it is ordinarily used. KEY is a pointer to an object you define and initialize. The object must remain in stable storage for as long as the table has a copy of the KEY pointing to the object. Example: struct mystruct *key_a = malloc(sizeof(struct mystruct)); initialize(key_a, my data to fill in struct...); void *r = tsearch(key_a,&treeroot,comparfunc); ROOTP: This must be the address of a void* datum. Before the first call of tsearch the value of *rootp must be NULL (set by you somehow). The contents are maintained by tsearch thereafter. COMPAR: A function you write whose argments (when tsearch internals call it) are KEY pointers from two records (your records). The function should return -1 if the record KEY l points to is considered less than the recorda KEY r points to. Return zero if the values are considered to match. Return 1 otherwise. Example: int comparefunc(const void *l,const void *r) { struct mystruct *lp = l; struct mystruct *rp = r; if(lp->myv < rp->myv) return -1; if(lp->myv == rp->myv) return 0; return 1; } Of course the comparison need not be of simple values, it could involve anything. This is just a simple sketch. Return value: If tsearch() returns NULL something went wrong. There was insufficient memory or an internal error of some kind. Lets call the KEY passed in KEYa. Otherwise tsearch() returns a pointer to a KEY for this object. Dereference to get an actual KEY (a pointer to your object). Lets call this dereferenced KEY key_deref. struct mystruct *key_deref = *(struct mystruct *)r; if KEYa == key_deref then: KEYa was added to the tree. Hence the tree now has a copy of the value of key_a. else: KEYa matched a record in the tree and you need to free any space you allocated to build the key for this tsearch call. In our example: free(key_a). I hope the above clarifies the use of tsearch somewhat. ============ Tfind: void *find(const void *key, void **rootp, int (*compar)(const void *l, const void *r)); The interfaces are the same but the return value is (in contrast with tsearch) reasonably clear: A non-null return is a key (pointer). It never adds a new record, it simple tries to find a record. A NULL return means either that the search-ed for record did not exist or that something internal went wrong or perhaps that something incorrect was detected at runtime in the arguments passed in. ============ Tdelete: void *tdelete(const void *key, void **rootp, int (*compar)(const void *l, const void *r)); The arguments are the same as tsearch/tfind, but the return value is a bit odd. If something goes wrong or if the record does not exist, it returns NULL. That is straightforward. If the record is deleted tdelete is supposed to return a pointer to the parent of the deleted record. The content of the deleted record is NOT deleted. If the record deleted was the last record in the tree, a NULL is returned and *rootp is set to NULL. Thus restoring initial conditions of an empty tree. If the record deleted was the root (of the records in the tree as of the call) then what is this supposed to return? No available documentation suggests an answer. The current dwarf_tdelete implementations return some record or other in this case. In the case of dwarf_tdelete() for a hash 'tree' if the node was the last in a hash chain then NULL is returned. (ugly, but it is difficult to figure out what else to do). All this means that it is a waste of time to inspect the return value from tdelete. So to do a tdelete and do any necessary memory free do: key = xxxx t = tfind(key,&root,compar_func) if (t) { tdelete(key,&root,compar_func) } free key free r where what 'free key' means is to free whatever 'key = xxxx' allocated. Which means do the same for 'free r'. Of course if your keys point into to a static array of data then free is unnecessary, but how often will the data be in static memory? And if it is in static storage, why do any free at all? ============ Tdestroy: void *tdestroy((void * root, void (*free_node)(void * key)); This frees all memory the tree system has and along the way it calls 'free_node' for each node in the tree. It empties the tree, but, oddly, the root argument is a simple pointer to the root, not a pointer-to-pointer. Hence this routine can free the tree, but cannot assign a NULL to the root. So you should do root = 0; after calling tdestroy(). ============ Twalk: void *twalk((const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); ============ Tdump: void tdump(const void *rootp, char *(*keyprint)(const void *key), const char * msg); This is unique to the dwarf_tsearch library. It prints (to standard out) a representation of the tree. The output is indented one space per level and ordered such that turning the output 90 degrees clockwise shows a kind of picture of the tree structure in the way trees are normally shown in books. It may be of slight interest for debugging trees if the trees are not too large. The 'msg' argument is just a character string of interest to you, something identifying the output. It is printed once and otherwise ignored. The 'keyprint' argument is a pointer to a function you write. The function is called for each node in turn. It should return a pointer to a string with whatever data from the passed-in-by-tdump key you wish to show. Normally the pointer returned from keyprint should be pointing to a static area so there is no issue with memory leakage to worry about. tdump will print the returned string immediately and will not refer to it again. ============ tsearch use using pointers (declarations left out): The struct here is entirely ours: tsearch neither knows nor cares how it is laid out. mt = struct example_tentry *mt = (struct example_tentry *)calloc(sizeof(struct example_tentry),1); mt->mt_key = keyvalue; mt->mt_data = datavalue; errno = 0; /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on %d, give up insertrecsbypointer\n",i); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if(re != mt) { /* found existing entry. */ mt_free_func(mt); } else { /* New entry mt was added. */ } } In this case the mt_compare_func() might if using a struct look like: int mt_compare_func(const void *l, const void *r) { const struct example_tentry *ml = l; const struct example_tentry *mr = r; /* If the key were a string, one could use strcmp() instead of the comparisons here */ if(ml->mt_key < mr->mt_key) { return -1; } if(ml->mt_key > mr->mt_key) { return 1; } return 0; } ============ tsearch use using values (declarations left out): void *mt = (void *)key; errno = 0; /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, value_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on %d, give up insertrecsbypointer\n",i); exit(1); } else { /* successful search.mt might have been added by the call, or maybe it was already in the tree. It is impossible to tell which */ } In this case the value_compare_func might look like: int value_compare_func(const void *l, const void *r) { VALTYPE lp = (VALTYPE)l; VALTYPE rp = (VALTYPE)r; if(lp < rp) { return -1; } if(lp > rp) { return 1; } return 0; } In this case the free_node function would look like void free_node { /* Do nothing. */ } In this case, there is never any free() calls you need to make as the key is not a pointer to anything. =================== If I were designing the interfaces in 2014 I might do as follows. I think the GNU hsearch_r interfaces are a fine approach and could be extended to tsearch(). But I propose something slightly different. struct tsearch_base; /* opaque struct, content defined by the search code, content not made public */ int compare_func(void *l, void*r); /* you define comparison function */ int free_func(void *n); /* you define free function */ None of the proposed interfaces touch errno. All functions return 0 on success and an errno on failure. They return EINVAL if an argument is incorrect somehow. int tcreate(struct tsearch_base **base,compare_func,free_func) allocate a struct_tsearch_base record and puts a pointer to it in *base. Records the compare and free_func pointers. A call on this by uses is a requirement . returns: ENOMEM if out of memory. EINVAL if something wrong with an argument or an internal problem. int tsearch(void *key,struct tsearch_base *base); returns: ENOMEM if out of memory. EINVAL if something wrong with an argument or an internal problem. int tfind(void *key,struct tsearch_base *base); returns: ESRCH if not found. EINVAL if something wrong with an argument or an internal problem. int tdelete(void *key,struct tsearch_base *base,void **keyout); If successful, tdelete deletes the record key identifies and returns that record's recorded key through *keyout. So if a free()or other action is required you can take that action. The 'base' struct tsearch_base record is NOT freed, it remains, whether the tree has any records left or not. returns: ESRCH if key not found. EINVAL if something wrong with an argument or an internal problem. int tsize(struct tsearch_base *base,unsigned long*count_out); Stores a count of the records currently recorded in the tree in *count_out. EINVAL if something wrong with an argument or an internal problem. int tdestroy(struct tsearch_base **base); A call is a requirement on users -- to free up the tree space. Calls free_func on each node in the tree and frees all tree memory and does *base = NULL to reset your tree pointer. returns: EINVAL if something wrong with an argument or an internal problem. ================= dwarfutils-20200114/tsearch/Makefile000066400000000000000000000054701361531463500172370ustar00rootroot00000000000000 EXTRA=-Wsign-compare -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wold-style-definition -Wno-pointer-sign # -Wcast-qual causes issue. We cast away const with # respect to create keyptr in places as we will actually eventually # request (calling code we do not control) that data possibly # be freed (and hence is changed). OPTS= -g -Wall $(EXTRA) -Wextra -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Wmissing-prototypes -Wdeclaration-after-statement -Wbad-function-cast -Wmissing-parameter-type -Wnested-externs CC = gcc HDR=dwarf_tsearch.h config.h TESTMAIN = tsearch_tester.c TS = dwarf_tsearchbin.c TSE = dwarf_tsearchepp.c TSH = dwarf_tsearchhash.c TSR = dwarf_tsearchred.c TSB = dwarf_tsearchbal.c TESTMAINOBJ = tsearch_testerstd.o all: binarysearch eppingerdel hashsearch gnusearch redblack balancedsearch tsearch_testerstd.o: $(TESTMAIN) $(HDR) $(CC) $(OPTS) -c $(TESTMAIN) -o tsearch_testerstd.o dwarf_tsearchbin.o: $(TS) $(HDR) $(CC) $(OPTS) -c $(TS) binarysearch: dwarf_tsearchbin.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchbin.o -o binarysearch dwarf_tsearchbal.o: $(TSB) $(HDR) $(CC) $(OPTS) -c $(TSB) balancedsearch: dwarf_tsearchbal.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchbal.o -o balancedsearch dwarf_tsearchepp.o: $(TSE) $(HDR) $(CC) $(OPTS) -c $(TSE) eppingerdel: dwarf_tsearchepp.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchepp.o -o eppingerdel dwarf_tsearchhash.o: $(TSH) $(HDR) $(CC) $(OPTS) -c $(TSH) hashsearch: dwarf_tsearchhash.o $(TESTMAIN) $(HDR) $(CC) $(OPTS) -DHASHSEARCH -c $(TESTMAIN) -o tsearch_testerhash.o $(CC) $(OPTS) tsearch_testerhash.o dwarf_tsearchhash.o -o hashsearch # Needs a special compile of tsearch_tester. gnusearch: $(TESTMAINOBJ) $(HDR) $(TESTMAIN) $(CC) $(OPTS) -DLIBC_TSEARCH -c $(TESTMAIN) -o tsearch_testergnu.o $(CC) $(OPTS) tsearch_testergnu.o -o gnusearch dwarf_tsearchred.o: $(TSR) $(HDR) $(CC) $(OPTS) -c $(TSR) redblack: dwarf_tsearchred.o $(TESTMAINOBJ) $(HDR) $(CC) $(OPTS) $(TESTMAINOBJ) dwarf_tsearchred.o -o redblack valgrind: valgrind -v --leak-check=full ./binarysearch valgrind -v --leak-check=full ./eppingerdel valgrind -v --leak-check=full ./hashsearch valgrind -v --leak-check=full ./gnusearch valgrind -v --leak-check=full ./redblack valgrind -v --leak-check=full ./balancedsearch test: all sh RUNTEST clean: rm -f junk* rm -f *.o rm -f gnusearch rm -f redblack rm -f binarysearch rm -f simplesearch rm -f eppingerdel rm -f hashsearch rm -f balancedsearch rm -f testfail rm -f testpass rm -f testfailerrs dwarfutils-20200114/tsearch/README000066400000000000000000000143561361531463500164620ustar00rootroot00000000000000David Anderson. January 2014. In 2013 I realized I could simplify some code in libdwarf (another project) by removing some complicated and messy special memory allocation code. Substituting by use of malloc/free and a table of used values. The used-values needed to a preserve a special feature of the original allocations related to a special handle: any allocations would be freed by closing the special handle. So I decided to implement various searches (mostly tree searches) using the tsearch interface definitions. I wrote these using a dwarf_ prefix to distinguish these from any libc implementation and to make the source fit in easily with libdwarf conventions. I added a tsearch() implementation using hashing too. The GNU-only hsearch() function does not let the hash grow (the tsearch() hash here grows automatically as needed) and has no hdelete() or hwalk() capability, so hsearch() and friends did not seem like a good interface set even though the GNU-designed hsearch_r() interface set is nicely designed. The attached C code is a small set of implementations of C search code. Based on algorithms in Knuth Volume 3 (2nd Ed) and Sedgewick 4th Edition. All the code here is implemented by me. I have never read the source to any other implementations of the tsearch algorighms or interfaces so this is a clean-room implementation. The hash version weakens the correspondence to tree based tsearch because, well, it's not a tree. So twalk() behaves differently than a tree-based version and an initialization. Non-GNU libc usually has no tdestroy(). The set of functions here provides a tdestroy() for all the tree/hash function sets here. ================== WHY TSEARCH? The interfaces are of a well-known design. While the interfaces are based on an obsolete style of writing interfaces, they are a known set. So the routines provided here are a direct substitution. The tdestroy() function is available in GNU libc, but is not part of the standard tsearch() set, nor is tdestroy() defined in the Single Unix Specification. The hash version of tdelete() cannot always return a non-null value even if there are records left. Not being a tree at all, it would cost runtime to provide a non-null return in some cases even when there are records left from tdelete(). The return value from tdelete() is problematic in all versions, since it purports to return the parent of the deleted node, but what if the deleted node was the root? ================== LICENSING: I wanted this to be usable in any context, hence the use of the BSD open-source license. ================== INTERFACE ODDITIES: It's not really easy to understand whether any given call is returning success, action succeeded tsearch success - added record tsearch success - record already in tree fail due to internal error or improper argument. requested action impossible (tfind() fails to find a record, or tdelete() fails to find the record to delete) Speaking of C here, so, there is no try/catch available. It might have been nice if twalk() let the user-provided action code indicate to twalk() that the user wanted it to stop walking the tree. I won't be changing the interface though. I am staying with the standard interfaces. ================== DOCUMENTATION ODDITIES: The GNU/Linux man pages on tsearch() and friends are nearly useless as you won't understand how to use the functions from reading that man page. The prototype for tfind() in the man page is slightly wrong while the headers in are correct. ================== IMPLEMENTATION ODDITIES: The code uses names like dwarf_tsearch() instead of just tsearch() so one can have both this tsearch() and GNU or a standard tsearch code available simultaneously with no interference at runtime. The code here operates like GNU or UNIX tsearch() but is internally incompatible. We'll usually refer to tsearch() not dwarf_tsearch() (etc) but we mean either and both unless otherwise specified here. The use of tsearch() and friends is a little tricky. That is just the way it is. The best reference is the code in tsearch_tester.c. See the trivial set of #defines in tsearch_tester.c that result in a standard-based naming of the functions. The return value from tdelete() is particularly problematic because it purports to return a pointer to another record than the one deleted, yet no such record necessarily exists. And in the case of The hash version requires use of the new function dwarf_initialize_search_hash() to provide a hashing function. And the hash version does not set the root pointer to NULL on tdelete() of the last record, since that would result in losing the hashing function pointer. Use tdestroy() to free up any remaining space. dwarf_tdump() is an invention and unique to this code. It is for debugging. It prints a representation of the data in the tree or hash to stdout. The #include .h file set used here makes it much easier for me to move these files to another project as necessary. You will probably want to revise the #include set a little. ================== OTHER DIRECTORIES: testdata contains a set of sample allocations, where lines starting with 'a' mean add and 'd' means delete. These are used for testing the library code. scripts contains some python scripts for converting results produced by printf added to libdwarf alloca() code. These were used massage the print output from running dwarfdump on real object files into the testcase/* format. It is unlikely you will find them much use except as starting points. ================== REFERENCES: Donald E Knuth, The Art of Computer Programming Volume 3, Second Edition. (Quite difficult to interpret some parts of Knuth's algorithms, but then I always found Knuth hard to understand. Still, Knuth is the essential source for algorithms.) The Open Group, The Single UNIX Specification, Version 3(2001). The Single Unix Specification (or whatever it is called now) is a reference source everyone should have. Robert Sedgewick and Kevin Wayne, Algorithms (4th Ed). This is the crucial reference on red-black trees. There is a crucial fix in the errata of the 3rd printing. In addition, in dwarf_tsearchred.c in two places I had to fix things, look for 'Mistake' in the source. http://www.prevanders.net/tsearch.html dwarfutils-20200114/tsearch/RUNTEST000066400000000000000000000053651361531463500166710ustar00rootroot00000000000000 # test2 is supposed to fail, do not expect success. # With -byvalue it gets one error, without -byvalue it gets two. # test17 is also supposed to fail, it adds 8 twice. myexit=0 #The following line assumes the test cases have been #placed in a directory named 'testcases' and #that the .gz versions expanded. #The tsearch test data is in the #libdwarf regression tests (available from sourceforge) #in the directory # tsearchtests # It's best to copy the tests from regressiontests # into 'testcases' # Not change what b refers to. # gunzip the .gz files in testcases, not in regressiontets # DO NOT expect testpass to match testpass.base # as there are pointers being printed. # fldiff (or other graphical diff) on them will show the patterns match. b=testcases #These test expecting failure. echo >testfail for opts in "" -byvalue do for test in $b/test2 $b/test17 do for app in ./binarysearch ./eppingerdel ./balancedsearch ./redblack ./gnusearch ./hashsearch do name=`basename $app` echo '====' $name $opts $test '====' >>testfail $app $opts $test >>testfail done done done diff $b/testfail.base testfail if [ $? -ne 0 ] then echo FAIL because testfail got unexpected output. myexit=1 fi echo >testpass for opts in "" -byvalue do for app in ./binarysearch ./eppingerdel ./balancedsearch ./redblack ./gnusearch ./hashsearch do name=`basename $app` echo '====' $name $opts '====' >>testpass $app $opts >>testpass done done for opts in "" -byvalue do for test in $b/action-F-dwgenb-dwarfgen.log $b/action-f-v-v-irix64-libc.so.log \ $b/action-i-dwarf4-dd2g4.5dwarf-4.log \ $b/action-l-irix64-libc.so.log \ $b/test10 \ $b/test11 \ $b/test11b \ $b/test11c \ $b/test18 \ $b/test32 \ $b/test547 \ $b/test6 \ $b/test64 \ $b/test8 \ $b/test9 do for app in ./binarysearch ./eppingerdel ./balancedsearch ./redblack ./gnusearch ./hashsearch do name=`basename $app` echo '====' $name $opts $test '====' >>testpass $app $opts $test >>testpass done done done diff $b/testpass.base testpass if [ $? -ne 0 ] then echo FAIL because testpass got unexpected output. echo "No surprise, there are pointers being printed" echo "try fldiff $b/testpass.base testpass" myexit=1 fi lcb=`wc -l < $b/testpass.base` lcn=`wc -l < testpass` echo if [ $lcb -eq $lcn ] then echo "Line counts match: $b/testpass.base testpass" else echo "Line counts NO NOT match: $b/testpass.base testpass" fi grep error testpass >testpasserrs grep FAIL testpass >>testpasserrs ct=`wc -l #include "stdlib.h" /* for exit() */ #ifndef UNUSEDARG #define UNUSEDARG #endif dwarfutils-20200114/tsearch/dwarf_tsearch.c000066400000000000000000000037171361531463500205610ustar00rootroot00000000000000/* Copyright (c) 2013-2014, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined(TSEARCH_USE_BAL) #include "dwarf_tsearchbal.c" #elif defined(TSEARCH_USE_BIN) #include "dwarf_tsearchbin.c" #elif defined(TSEARCH_USE_EPP) #include "dwarf_tsearchepp.c" #elif defined(TSEARCH_USE_HASH) #include "dwarf_tsearchhash.c" #elif defined(TSEARCH_USE_RED) #include "dwarf_tsearchred.c" #else #error Missing tsearch algorithm #endif dwarfutils-20200114/tsearch/dwarf_tsearch.h000066400000000000000000000077641361531463500205740ustar00rootroot00000000000000#ifndef DWARF_TSEARCH_H #define DWARF_TSEARCH_H /* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The following interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source code of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. See https://www.prevanders.net/tsearch.html and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional interface here, but to avoid interfering with libc implementations or code using libc implementations, we change all the names. */ #include "config.h" /* SN-Carlos: Windows specific */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ /* The hashfunc return is now easily changed with cc -Duintptr_t or something. */ #ifndef DW_TSHASHTYPE #define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through the callback function in dwarf_twalk(); */ typedef enum { dwarf_preorder, dwarf_postorder, dwarf_endorder, dwarf_leaf } DW_VISIT; /* void * return values are actually void **key so you must dereference these once to get a key you passed in. */ void *dwarf_tsearch(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void *dwarf_tfind(const void * /*key*/, void *const * /*rootp*/, int (* /*compar*/)(const void *, const void *)); /* dwarf_tdelete() returns NULL if it cannot delete anything or if the tree is now empty (if empty, *rootp is set NULL by dwarf_tdelete()). If the delete succeeds and the tree is non-empty returns a pointer to the parent node of the deleted item, unless the deleted item was at the root, in which case the returned pointer relates to the new root. */ void *dwarf_tdelete(const void * /*key*/, void ** /*rootp*/, int (* /*compar*/)(const void *, const void *)); void dwarf_twalk(const void * /*root*/, void (* /*action*/)(const void * /*nodep*/, const DW_VISIT /*which*/, const int /*depth*/)); /* dwarf_tdestroy() cannot set the root pointer NULL, you must do so on return from dwarf_tdestroy(). */ void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, char *(* /*keyprint*/)(const void *), const char *msg); /* Returns NULL and does nothing unless the implemenation used uses a hash tree. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); #endif /* DWARF_TSEARCH_H */ dwarfutils-20200114/tsearch/dwarf_tsearchbal.c000066400000000000000000000700731361531463500212370ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2 And based on chapter 6.2.3 Balanced Trees (sometimes call AVL trees) Algorithm A and the sketch on deletion. The wikipedia page on AVL trees is also quite useful. A Key equation is: bal-factor-node-k = height-left-subtree - height-right-subtree We don't know the absolute height, but we do know the balance factor of the pointed-to subtrees (-1,0, or 1). And we always know if we are adding or deleting a node. */ #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif /* _WIN32 */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #ifdef HAVE_STDINT_H #include /* For uintptr_t */ #endif /* HAVE_STDINT_H */ #include /* for printf */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" #define IMPLEMENTD15 1 #ifdef DW_CHECK_CONSISTENCY struct ts_entry; void dwarf_check_balance(struct ts_entry *head,int finalprefix); #endif /* head is a special link. rlink points to root node. head-> llink is a tree depth value. Using a pointer. root = head->rlink. The keypointer and balance fields of the head node are not used. Might be sensible to use the head balance field as a tree depth instead of using llink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. We will request free, so const void * is not quite right. */ void *keyptr; int balance; /* Knuth 6.2.3 algorithm A */ struct ts_entry * llink; struct ts_entry * rlink; }; static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[40]; /* This is a safe sprintf. No need for esb here. */ len = sprintf(number,"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG unsigned long(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging, mainly. We print the tree with the head node unnumbered and the root node called level 0. In Knuth algorithms where we have p[k] when k is zero k refers to the head node. Handy as then the root node is not special at all. But here it just looks better as shown, perhaps. The ordering here is so that if you turned an output page with the left side at the top then the tree sort of just shows up nicely in what most think of as a normal way. */ static void tdump_inner(struct ts_entry *t, char *(keyprint)(const void *), const char *descr, int level) { const char * keyv = ""; if(!t) { return; } tdump_inner(t->rlink,keyprint,"right",level+1); printlevel(level); if(t->keyptr) { keyv = keyprint(t->keyptr); } printf("0x%08" DW_PR_DUx " " "<%s %s> " " " "%s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", keyv, t->balance, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); tdump_inner(t->llink,keyprint,"left ",level+1); } #ifdef DW_CHECK_CONSISTENCY /* Checking that a tree (or sub tree) is in balance. Only meaningful for balanced trees. Returns the depth. */ int dwarf_check_balance_inner(struct ts_entry *t,int level,int maxdepth, int *founderror,const char *prefix) { int l = 0; int r = 0; if(level > maxdepth) { printf("%s Likely internal erroneous link loop, got to depth %d.\n", prefix,level); exit(1); } if(!t) { return 0; } if(!t->llink && !t->rlink) { if (t->balance != 0) { printf("%s: Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return 1; } l = dwarf_check_balance_inner(t->llink,level+1,maxdepth, founderror,prefix); r = dwarf_check_balance_inner(t->rlink,level+1,maxdepth, founderror,prefix); if (l ==r && t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " d should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; return l+1; } if(l > r) { if( (l-r) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " l %d r %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, l,r); (*founderror)++; } if (t->balance != -1) { printf("%s Balance at 0x%" DW_PR_DUx " should be -1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } return l+1; } if(r != l) { if( (r-l) != 1) { printf("%s depth mismatch at 0x%" DW_PR_DUx " r %d l %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, r,l); (*founderror)++; } if (t->balance != 1) { printf("%s Balance at 0x%" DW_PR_DUx " should be 1 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } else { if (t->balance != 0) { printf("%s Balance at 0x%" DW_PR_DUx " should be 0 is %d.\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, t->balance); (*founderror)++; } } return r+1; } void dwarf_check_balance(struct ts_entry *head,int finalprefix) { const char *prefix = 0; int maxdepth = 0; size_t headdepth = 0; int errcount = 0; int depth = 0; struct ts_entry*root = 0; if(finalprefix) { prefix = "BalanceError:"; } else { prefix = "BalanceWarn:"; } if(!head) { printf("%s check balance null tree ptr\n",prefix); return; } root = head->rlink; headdepth = head->llink - (struct ts_entry *)0; if(!root) { printf("%s check balance null tree ptr\n",prefix); return; } maxdepth = headdepth+10; /* Counting in levels, not level number of top level. */ headdepth++; depth = dwarf_check_balance_inner(root,depth,maxdepth,&errcount,prefix); if (depth != headdepth) { printf("%s Head node says depth %lu, it is really %d\n", prefix, (unsigned long)headdepth, depth); ++errcount; } if(errcount) { printf("%s error count %d\n",prefix,errcount); } return; } #endif /* Dumping the tree to stdout. */ void dwarf_tdump(const void*headp_in, char *(*keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)headp_in; struct ts_entry *root = 0; size_t headdepth = 0; if(!head) { printf("dumptree null tree ptr : %s\n",msg); return; } headdepth = head->llink - (struct ts_entry *)0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " tree-depth %d: %s\n", (Dwarf_Unsigned)(uintptr_t)head, (int)headdepth, msg); root = head->rlink; if(!root) { printf("Empty tree\n"); return; } tdump_inner(root,keyprint,"top",0); } static void setlink(struct ts_entry*t,int a,struct ts_entry *x) { if(a < 0) { t->llink = x; } else { t->rlink = x; } } static struct ts_entry* getlink(struct ts_entry*t,int a) { if(a < 0) { return(t->llink); } return(t->rlink); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } /* We will eventually ask it be freed, so being const void * in is not quite right. */ e->keyptr = (void *)key; e->balance = 0; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *q = allocate_ts_entry(key); if (!q) { /* out of memory */ return NULL; } setlink(p,kc,q); /* Non-NULL means inserted. */ return q; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if(q) { *inserted = 1; } return q; } /* Algorithm A of Knuth 6.2.3, balanced tree. key is pointer to a user data area containing the key and possibly more. We could recurse on this routine, but instead we iterate (like Knuth does, but using for(;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* head, int (*compar)(const void *, const void *), int*inserted, UNUSEDARG struct ts_entry **nullme, UNUSEDARG int * comparres) { /* t points to parent of p */ struct ts_entry *t = head; /* p moves down tree, p starts as root. */ struct ts_entry *p = head->rlink; /* s points where rebalancing may be needed. */ struct ts_entry *s = p; struct ts_entry *r = 0; struct ts_entry *q = 0; int a = 0; int kc = 0; for(;;) { /* A2. */ kc = compar(key,p->keyptr); if(kc) { /* A3 and A4 handled here. */ q = getlink(p,kc); if(!q) { /* Does step A5. */ q = tsearch_inner_do_insert(key,kc,inserted,p); if (!q) { /* Out of memory. */ return q; } break; /* to A5. */ } if(q->balance) { t = p; s = q; } p = q; continue; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* A5: work already done. */ /* A6: */ { /* Balance factors on nodes betwen S and Q need to be changed from zero to +-1 */ int kc2 = compar(key,s->keyptr); if (kc2 < 0) { a = -1; } else { a = 1; } r = p = getlink(s,a); while (p != q) { int kc3 = compar(key,p->keyptr); if(kc3 < 0) { p->balance = -1; p = p->llink; } else if (kc3 > 0) { p->balance = 1; p = p->rlink; } else { /* ASSERT: p == q */ break; } } } /* A7: */ { if(! s->balance) { /* Tree has grown higher. */ s->balance = a; /* Counting in pointers, not integers. Ugh. */ head->llink = head->llink + 1; return q; } if(s->balance == -a) { /* Tree is more balanced */ s->balance = 0; return q; } if (s->balance == a) { /* Rebalance. */ if(r->balance == a) { /* single rotation, step A8. */ p = r; setlink(s,a,getlink(r,-a)); setlink(r,-a,s); s->balance = 0; r->balance = 0; } else if (r->balance == -a) { /* double rotation, step A9. */ p = getlink(r,-a); setlink(r,-a,getlink(p,a)); setlink(p,a,r); setlink(s,a,getlink(p,-a)); setlink(p,-a,s); if(p->balance == a) { s->balance = -a; r->balance = 0; } else if (p->balance == 0) { s->balance = 0; r->balance = 0; } else if (p->balance == -a) { s->balance = 0; r->balance = a; } p->balance = 0; } else { fprintf(stderr,"Impossible balanced tree situation!\n"); /* Impossible. Cannot be here. */ exit(1); } } else { fprintf(stderr,"Impossible balanced tree situation!!\n"); /* Impossible. Cannot be here. */ exit(1); } } /* A10: */ if (s == t->rlink) { t->rlink = p; } else { t->llink = p; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry **headp = (struct ts_entry **)headin; struct ts_entry *head = 0; struct ts_entry *r = 0; int inserted = 0; /* kcomparv should be ignored */ int kcomparv = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!headp) { return NULL; } head = *headp; if (!head) { struct ts_entry *root = 0; head = allocate_ts_entry(0); if(!head) { return NULL; } root = allocate_ts_entry(key); if(!root) { free(head); return NULL; } head->rlink = root; /* head->llink is used for the depth, as a count */ /* head points to the special head node ... */ *headin = head; return (void *)(&(root->keyptr)); } r = tsearch_inner(key,head,compar,&inserted,&nullme,&kcomparv); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search without insert. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry * const *phead = (struct ts_entry * const*)rootp; struct ts_entry *head = 0; struct ts_entry *p = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } p = head->rlink; while(p) { int kc = compar(key,p->keyptr); if(!kc) { return (void *)(&(p->keyptr)); } p = getlink(p,kc); } return NULL; } /* Used for an array of records used in the deletion code. k == 0 for the special head node which is never matched by input. k == 1 etc. */ struct pkrecord { struct ts_entry *pk; int ak; /* Is -1 or +1 */ }; /* Here we rearrange the tree so the node p to be deleted is a node with a null left link. With that done we can fix pkarray and then we can use the pkarray to rebalance. It's a bit long, so we refactor out the code from where it is called. The rearrangement is Algorithm 6.2.2D in Knuth. PRECONDITION: p,p->rlink, pp non-null. RETURNS: new high index of pkarray. */ static unsigned rearrange_tree_so_p_llink_null( struct pkrecord * pkarray, unsigned k, UNUSEDARG struct ts_entry *head, struct ts_entry *r, struct ts_entry *p, UNUSEDARG int pak, UNUSEDARG struct ts_entry *pp, int ppak) { struct ts_entry *s = 0; unsigned k2 = 0; /* indexing pkarray */ int pbalance = p->balance; /* Step D3 */ /* Since we are going to modify the tree by movement of a node down the tree a ways, we need to build pkarray with the (not yet found) new next node, in pkarray[k], not p. The deletion will be of p, but by then p will be moved in the tree so it has a null left link. P's possibly-non-null right link */ k2 = k; k2++; r = p->rlink; pkarray[k2].pk = r; pkarray[k2].ak = -1; s = r->llink; /* Move down and left to get a null llink. */ while (s->llink) { k2++; r = s; s = r->llink; pkarray[k2].pk = r; pkarray[k2].ak = -1; } /* Now we move S up in place (in the tree) of the node P we will delete. and p replaces s. Finally winding up with a newly shaped balanced tree. */ { struct ts_entry *tmp = 0; int sbalance = s->balance; s->llink = p->llink; r->llink = p; p->llink = 0; tmp = p->rlink; p->rlink = s->rlink; s->rlink = tmp; setlink(pp,ppak,s); s->balance = pbalance; p->balance = sbalance; /* Now the tree is rearranged and still in balance. */ /* Replace the previous k position entry with S. We trace the right link off of the moved S node. */ pkarray[k].pk = s; pkarray[k].ak = 1; r->llink = p->rlink; /* Now p is out of the tree and we start the rebalance at r. pkarray Index k2. */ } /* Step D4 */ free(p); return k2; } /* Returns deleted node parent unless the head changed. Returns NULL if wanted node not found or the tree is now empty or the head node changed. Sets *did_delete if it found and deleted a node. Sets *tree_empty if there are no more user nodes present. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *head, int (*compar)(const void *, const void *), int *tree_empty, int *did_delete ) { struct ts_entry *p = 0; struct ts_entry *pp = 0; struct pkrecord * pkarray = 0; size_t depth = head->llink - (struct ts_entry *)0; unsigned k = 0; /* Allocate extra, head is on the stack we create here and the depth might increase. */ depth = depth + 4; pkarray = calloc(sizeof(struct pkrecord),depth); if(!pkarray) { /* Malloc fails, we could abort... */ return NULL; } k = 0; pkarray[k].pk=head; pkarray[k].ak=1; p = head->rlink; while(p) { int kc = 0; k++; kc = compar(key,p->keyptr); pkarray[k].pk = p; pkarray[k].ak = kc; if(!kc) { break; } p = getlink(p,kc); } if(!p) { /* Node to delete never found. */ free(pkarray); return NULL; } { struct ts_entry *t = 0; struct ts_entry *r = 0; int pak = 0; int ppak = 0; p = pkarray[k].pk; pak = pkarray[k].ak; pp = pkarray[k-1].pk; ppak = pkarray[k-1].ak; /* Found a match. p to be deleted. */ t = p; *did_delete = 1; if(!t->rlink) { if(k == 1 && !t->llink) { *tree_empty = 1; /* upper level will fix up head node. */ free(t); free(pkarray); return NULL; } /* t->llink might be NULL. */ setlink(pp,ppak,t->llink); /* ASSERT: t->llink NULL or t->llink has no children, balance zero and balance of t->llink not changing. */ k--; /* Step D4. */ free(t); goto balance; } #ifdef IMPLEMENTD15 /* Step D1.5 */ if(!t->llink) { setlink(pp,ppak,t->rlink); /* we change the left link off ak */ k--; /* Step D4. */ free(t); goto balance; } #endif /* IMPLEMENTD15 */ /* Step D2 */ r = t->rlink; if (!r->llink) { /* We decrease the height of the right tree. */ r->llink = t->llink; setlink(pp,ppak,r); pkarray[k].pk = r; pkarray[k].ak = 1; /* The following essential line not mentioned in Knuth AFAICT. */ r->balance = t->balance; /* Step D4. */ free(t); goto balance; } /* Step D3, we rearrange the tree and pkarray so the balance step can work. step D2 is insufficient so not done. */ k = rearrange_tree_so_p_llink_null(pkarray,k, head,r, p,pak,pp,ppak); goto balance; } /* Now use pkarray decide if rebalancing needed and, if needed, to rebalance. k here matches l-1 in Knuth. */ balance: { unsigned k2 = k; /* We do not want a test in the for() itself. */ for( ; 1 ; k2--) { struct ts_entry *pk = 0; int ak = 0; int bk = 0; if (k2 == 0) { /* decreased in height */ head->llink--; goto cleanup; } pk = pkarray[k2].pk; if (!pk) { /* Nothing here to work with. Move up. */ continue; } ak = pkarray[k2].ak; bk = pk->balance; if(bk == ak) { pk->balance = 0; continue; } if(bk == 0) { pk->balance = -ak; goto cleanup; } /* ASSERT: bk == -ak. We will use bk == adel here (just below). */ /* Rebalancing required. Here we use (1) and (2) in 6.2.3 to adjust the nodes */ { /* Rebalance. We use s for what is called A in Knuth Case 1, Case 2 page 461. r For what is called B. So the link movement logic looks similar to the tsearch insert case.*/ struct ts_entry *r = 0; struct ts_entry *s = 0; struct ts_entry *pa = 0; int pak = 0; int adel = -ak; s = pk; r = getlink(s,adel); pa = pkarray[k2-1].pk; pak = pkarray[k2-1].ak; if(r->balance == adel) { /* case 1. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,r); s->balance = 0; r->balance = 0; continue; } else if (r->balance == -adel) { /* case 2 */ /* x plays the role of p in step A9 */ struct ts_entry*x = getlink(r,-adel); setlink(r,-adel,getlink(x,adel)); setlink(x,adel,r); setlink(s,adel,getlink(x,-adel)); setlink(x,-adel,s); /* A10 in tsearch. */ setlink(pa,pak,x); if(x->balance == adel) { s->balance = -adel; r->balance = 0; } else if (x->balance == 0) { s->balance = 0; r->balance = 0; } else if (x->balance == -adel) { s->balance = 0; r->balance = adel; } x->balance = 0; continue; } else { /* r->balance == 0 case 3 we do a single rotation and we are done. */ setlink(s,adel,getlink(r,-adel)); setlink(r,-adel,s); setlink(pa,pak,r); r->balance = -adel; /*s->balance = r->balance = 0; */ goto cleanup; } } } } cleanup: free(pkarray); #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif return pp; } void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int tree_empty = 0; int did_delete = 0; if (!phead) { return NULL; } head = *phead; if (!head) { return NULL; } if (!head->rlink) { return NULL; } parentp = tdelete_inner(key,head,compar,&tree_empty,&did_delete); if(tree_empty) { head->rlink = 0; head->llink = 0; free(head); *phead = 0; return NULL; } /* ASSERT: head->rlink non-null. */ if(did_delete) { if (!parentp) { parentp = head->rlink; } return (void *)(&(parentp->keyptr)); } /* Not deleted */ return NULL; } static void dwarf_twalk_inner(struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if(p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if(p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(!root) { return; } /* Get to actual tree. */ dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if(p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if(p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(root) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } dwarfutils-20200114/tsearch/dwarf_tsearchbin.c000066400000000000000000000351241361531463500212470ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2, algorithm T and Algorithm D. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #include /* for printf */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* INVARIANT: The head node has no user data. head->llink is null, head->rlink points to the real user top node (root of the user tree). So the physical top node we call 'head'. No user data. The user top node we call 'root' here. It has a user key. Though we intend that head->rlink be non-NULL except briefly when a tdelete removes the last node (in which case we remove the head too before returning) the code is a bit cautious and tests for a non-NULL head->rlink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. */ const void *keyptr; struct ts_entry * llink; struct ts_entry * rlink; }; /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging. Prints the level number and indents 1 space per level. That won't work very well for a deep tree, so perhaps we should clamp at some number of indent spaces? */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* For debugging. This prints the nodes with the parent (in each case) in between the children. So it is a tree with root at the left. */ static void dumptree_inner(const struct ts_entry *t, char *(* keyprint)(const void *), const char *descr, int level) { const char *v = ""; if(!t) { return; } dumptree_inner(t->rlink,keyprint,"left ",level+1); if(t->keyptr) { v = keyprint(t->keyptr); } printlevel(level); printf("0x%08" DW_PR_DUx " <%s %s> %s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", v, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); dumptree_inner(t->llink,keyprint,"right",level+1); } static void setlink(struct ts_entry*t,int a,struct ts_entry *x) { if(a < 0) { t->llink = x; } else { t->rlink = x; } } static struct ts_entry* getlink(struct ts_entry*t,int a) { if(a < 0) { return(t->llink); } return(t->rlink); } /* Dumping the tree to stdout. */ void dwarf_tdump(const void*rootin, char *(* keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)rootin; const struct ts_entry *root = 0; if(!head) { printf("dwarf_tdump null tree ptr : %s\n",msg); return; } root = head->rlink; if(!root) { printf("dwarf_tdump empty tree : %s\n",msg); return; } printf("dwarf_tdump tree head : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)head,msg); printf("dwarf_tdump tree root : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)root,msg); dumptree_inner(root,keyprint,"top",0); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } e->keyptr = key; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *e = allocate_ts_entry(key); if (!e) { /* out of memory */ return NULL; } setlink(p,kc,e); /* Non-NULL means inserted. */ return e; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if(q) { *inserted = 1; } return q; } /* Algorithm T of Knuth 6.2.2.2 key is pointer to a user data area containing the key and possibly more. We iterate like Knuth does, but using for(;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* localrootp, int (*compar)(const void *, const void *), int*inserted) { struct ts_entry* p = localrootp; for(;;) { struct ts_entry *r = 0; /* T2. */ int kc = compar(key,p->keyptr); if(kc < 0) { /* T3. */ struct ts_entry *l = p->llink; if (l) { p = l; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } else if (kc > 0 ) { /* T4. */ struct ts_entry *r2 = p->rlink; if (r2) { p = r2; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } /* Can never get here. */ return 0; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headpin, int (*compar)(const void *, const void *)) { struct ts_entry *head = 0; struct ts_entry *root = 0; struct ts_entry *r = 0; int inserted = 0; if(!headpin) { return NULL; } head = (struct ts_entry *)*headpin; if(head) { root = head->rlink; } if(!head || !root) { int allocatedhead = 0; if(!head) { head = allocate_ts_entry(0); allocatedhead = 1; } if(!head) { return NULL; } root = allocate_ts_entry(key); if(!root) { if(allocatedhead) { free(head); } return NULL; } head->rlink = root; *headpin = head; return (void *)(&(root->keyptr)); } root = head->rlink; r = tsearch_inner(key,root,compar,&inserted); if (!r) { return NULL; } /* Was this found or inserted? Value is the same either way, but the pointer to return is not the same! */ /* Discards const. Required by the interface definition. */ return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const*headppin, int (*compar)(const void *, const void *)) { struct ts_entry *head = (struct ts_entry *)*headppin; struct ts_entry **proot = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; if(!headppin) { return NULL; } head = (struct ts_entry *)*headppin; if(!head) { return NULL; } proot = &head->rlink; root = *proot; if(!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; } void * dwarf_tdelete(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry *phead = 0; struct ts_entry **rootp = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int parentcomparv = 0; int done = 0; if (!headin) { return NULL; } phead = (struct ts_entry *)*headin; if (!phead) { return NULL; } rootp = &phead->rlink; root = phead->rlink; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { break; } parentp = p; parentcomparv = kc; p = getlink(p,kc); } if(!p) { return NULL; } { /* In Knuth Algorithm D, the parenthetical comment "(For example, if Q===RLINK(P) for some P we would set RLINK(P)<- LLINK(T).)" informs us that Q is assumed to be a conceptual name for some RLINK or LLINK, not a C local variable. In the rest of this algorithm variables can be ordinary C pointers, but not true for Q. Hence in the following we use *q to set Q. */ struct ts_entry **q = 0; struct ts_entry *t = 0; struct ts_entry *r = 0; struct ts_entry *s = 0; int emptied_a_leaf = 0; /* Either we found root (to remove) or we have a parentp and the parent mismatched the key so parentcomparv is != 0 */ if (p == root) { q = rootp; } else if (parentcomparv < 0) { q = &parentp->llink; } else /* (parentcomparv > 0) */ { q = &parentp->rlink; } /* D1. Here *q is what Knuth calls q. */ t = *q; r = t->rlink; if (!r) { *q = t->llink; done = 1; } else { /* D2. */ if (!r->llink) { r->llink = t->llink; *q = r; done = 1; } } while (!done) { /* D3. */ s = r->llink; if(s->llink) { r = s; continue; } s->llink = t->llink; r->llink = s->rlink; s->rlink = t->rlink; *q = s; done = 1; } /* Step D4. */ if(!t->llink && !t->rlink) { emptied_a_leaf = 1; } free(t); if(emptied_a_leaf) { if (p == root) { /* The tree is completely empty now. Free the special head node. Notify the caller. */ free(phead); *headin = 0; return NULL; } } if(!parentp) { /* The item we found was at top of tree, found == root. We have a new root node. We return it, there is no parent. Other than one might say, the fake parent phead (with only rlink, but that has no key so we ignore). */ return (void *)(&(root->keyptr)); } return (void *)(&(parentp->keyptr)); } return NULL; } static void dwarf_twalk_inner(const struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if(p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if(p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *headin, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)headin; const struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(!root) { return; } dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if(p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if(p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } /* Discards const. Required by the interface definition. */ free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. The user must zero out the head node, we have no way to do that in the defined interface. */ void dwarf_tdestroy(void *headin, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)headin; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(head) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } dwarfutils-20200114/tsearch/dwarf_tsearchepp.c000066400000000000000000000362021361531463500212610ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.2.2, algorithm T and Algorithm D. Algorithm D here is with Eppinger's left/right reflection in delete (J L Eppinger CACM26 (1983),663-669, 27 (1984),235). */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #include /* for printf */ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* INVARIANT: The head node has no user data. head->llink is null, head->rlink points to the real user top node (root of the user tree). So the physical top node we call 'head'. No user data. The user top node we call 'root' here. It has a user key. Though we intend that head->rlink be non-NULL except briefly when a tdelete removes the last node (in which case we remove the head too before returning) the code is a bit cautious and tests for a non-NULL head->rlink. */ struct ts_entry { /* Keyptr points to a pointer to a record the user saved, the user record contains the user's key itself and perhaps more. */ const void *keyptr; struct ts_entry * llink; struct ts_entry * rlink; }; /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE(*hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } /* For debugging. Prints the level number and indents 1 space per level. That won't work very well for a deep tree, so perhaps we should clamp at some number of indent spaces? */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } /* For debugging */ static void dumptree_inner(const struct ts_entry *t, char *(* keyprint)(const void *), const char *descr, int level) { const char *v = ""; if(!t) { return; } dumptree_inner(t->rlink,keyprint,"left ",level+1); if(t->keyptr) { v = keyprint(t->keyptr); } printlevel(level); printf("0x%08" DW_PR_DUx " <%s %s> %s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", v, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); dumptree_inner(t->llink,keyprint,"right",level+1); } static struct ts_entry* getlink(struct ts_entry*t,int a) { if(a < 0) { return(t->llink); } return(t->rlink); } /* Dumping the tree to stdout. */ void dwarf_tdump(const void*rootin, char *(* keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)rootin; const struct ts_entry *root = 0; if(!head) { printf("dwarf_tdump null tree ptr : %s\n",msg); return; } root = head->rlink; if(!root) { printf("dwarf_tdump empty tree : %s\n",msg); return; } printf("dwarf_tdump tree head : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)head, msg); printf("dwarf_tdump tree root : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)root, msg); dumptree_inner(root,keyprint,"top",0); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } e->keyptr = key; e->llink = 0; e->rlink = 0; return e; } /* Knuth step T5, the insert. */ static struct ts_entry * tsearch_insert_k(const void *key,int kc, struct ts_entry *p) { struct ts_entry *e = allocate_ts_entry(key); if (!e) { /* out of memory */ return NULL; } if( kc < 0) { p->llink = e; } else { p->rlink = e; } /* Non-NULL means inserted. */ return e; } /* Knuth step T5. */ static struct ts_entry * tsearch_inner_do_insert(const void *key, int kc, int * inserted, struct ts_entry* p) { struct ts_entry *q = 0; q = tsearch_insert_k(key,kc,p); if(q) { *inserted = 1; } return q; } /* Algorithm T of Knuth 6.2.2.2 key is pointer to a user data area containing the key and possibly more. We iterate like Knuth does, but using for(;;) instead of go-to. */ static struct ts_entry * tsearch_inner( const void *key, struct ts_entry* localrootp, int (*compar)(const void *, const void *), int*inserted) { struct ts_entry* p = localrootp; for(;;) { struct ts_entry *r = 0; /* T2. */ int kc = compar(key,p->keyptr); if(kc < 0) { /* T3. */ struct ts_entry *l = p->llink; if (l) { p = l; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } else if (kc > 0 ) { /* T4. */ struct ts_entry *r2 = p->rlink; if (r2) { p = r2; continue; } /* T5 */ r = tsearch_inner_do_insert(key,kc,inserted,p); return r; } /* K = KEY(P) in Knuth. */ /* kc == 0, we found the entry we search for. */ return p; } return 0; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headpin, int (*compar)(const void *, const void *)) { struct ts_entry *head = 0; struct ts_entry *root = 0; struct ts_entry *r = 0; int inserted = 0; if(!headpin) { return NULL; } head = (struct ts_entry *)*headpin; if(head) { root = head->rlink; } if(!head || !root) { int allocatedhead = 0; if(!head) { head = allocate_ts_entry(0); allocatedhead = 1; } if(!head) { return NULL; } root = allocate_ts_entry(key); if(!root) { if (allocatedhead) { free(head); } return NULL; } head->rlink = root; *headpin = head; return (void *)(&(root->keyptr)); } root = head->rlink; r = tsearch_inner(key,root,compar,&inserted); if (!r) { return NULL; } /* Was this found or inserted? Value is the same either way, but the pointer to return is not the same! */ /* Discards const. Required by the interface definition. */ return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const*headppin, int (*compar)(const void *, const void *)) { struct ts_entry *head = (struct ts_entry *)*headppin; struct ts_entry **proot = 0; struct ts_entry *root = 0; struct ts_entry *p = 0; if(!headppin) { return NULL; } head = (struct ts_entry *)*headppin; if(!head) { return NULL; } proot = &head->rlink; root = *proot; if(!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; } void * dwarf_tdelete(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct ts_entry *phead = 0; struct ts_entry **rootp = 0; struct ts_entry *root = 0; struct ts_entry * p= 0; /* If a leaf is found, we have to null a parent link or the root */ struct ts_entry * parentp = 0; int parentcomparv = 0; int done = 0; /* We don't really care much if multiple tree tables use this simultaneously. This left/right is a practical thing not supported by known theory, according to Knuth. We start with eppingerleftr=1 because that happens to show a different tree than standard knuth in one of our standard tsearch regression test sequences. */ static unsigned eppingerleft = 1; if (!headin) { return NULL; } phead = (struct ts_entry *)*headin; if (!phead) { return NULL; } rootp = &phead->rlink; root = phead->rlink; if (!root) { return NULL; } p = root; while(p) { int kc = compar(key,p->keyptr); if (!kc) { break; } parentp = p; parentcomparv = kc; p = getlink(p,kc); } if(!p) { return NULL; } { struct ts_entry **q = 0; struct ts_entry *t = 0; struct ts_entry *s = 0; int emptied_a_leaf = 0; /* Either we found root (to remove) or we have a parentp and the parent mismatched the key so parentcomparv is != 0 */ if (p == root) { q = rootp; } else if (parentcomparv < 0) { q = &parentp->llink; } else /* (parentcomparv > 0) */ { q = &parentp->rlink; } /* D1. *q is what Knuth calls q. */ t = *q; if(!eppingerleft) { struct ts_entry *r = 0; eppingerleft = 1; r = t->rlink; if (!r) { *q = t->llink; done = 1; } else { /* D2. */ if (!r->llink) { r->llink = t->llink; *q = r; done = 1; } } while (!done) { /* D3. */ s = r->llink; if(s->llink) { r = s; continue; } s->llink = t->llink; r->llink = s->rlink; s->rlink = t->rlink; *q = s; done = 1; } } else { struct ts_entry *l = 0; eppingerleft = 0; l = t->llink; if (!l) { *q = t->rlink; done = 1; } else { /* D2. */ if (!l->rlink) { l->rlink = t->rlink; *q = l; done = 1; } } while (!done) { /* D3. */ s = l->rlink; if(s->rlink) { l = s; continue; } s->rlink = t->rlink; l->rlink = s->llink; s->llink = t->llink; *q = s; done = 1; } } /* Step D4. */ if(!t->llink && !t->rlink) { emptied_a_leaf = 1; } free(t); if(emptied_a_leaf) { if (p == root) { /* The tree is completely empty now. Free the special head node. Notify the caller. */ free(phead); *headin = 0; return NULL; } } if(!parentp) { /* The item we found was at top of tree, found == root. We have a new root node. We return it, there is no parent. */ return (void *)(&(root->keyptr)); } return (void *)(&(parentp->keyptr)); } return NULL; } static void dwarf_twalk_inner(const struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if(p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if(p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *headin, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)headin; const struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(!root) { return; } dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if(p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if(p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } /* Discards const. Required by the interface definition. */ free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. The user must zero out the head node, we have no way to do that in the defined interface. */ void dwarf_tdestroy(void *headin, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)headin; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(head) { dwarf_tdestroy_inner(root,free_node,0); } free(head); } dwarfutils-20200114/tsearch/dwarf_tsearchhash.c000066400000000000000000000464341361531463500214300ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch or any hashing code. An additional interface is added (compared to a real tsearch) to let the caller identify a 'hash' function with each hash table (called a tree below, but that is a misnomer). So read 'tree' below as hash table. See http://www.prevanders.net/tsearch.html for information and an example of use. Based on Knuth, chapter 6.4 This uses a hash based on the key. Collision resolution is by chaining. twalk() and tdestroy() walk in a random order. The 'preorder' etc labels mean nothing in a hash, so everything is called a leaf. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() etc */ #include /* for printf() */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #define DW_PR_DUu "I64u" #else #define DW_PR_DUx "llx" #define DW_PR_DUu "llu" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* A table of primes used to size and resize the hash table. From public sources of prime numbers, arbitrarily chosen to approximately double in size at each step. */ static unsigned long primes[] = { #if 0 /* for testing only */ 5,11, 17,23, 31, 47, 53, #endif 79, 1009, 5591, 10007, 21839, 41413, 99907, 199967, 400009, 800029, 1600141, 3000089, 6000121, 12000257, 24000143, 48000203, 100000127, 200001611, 400000669, 800000573, 0 /* Here we are giving up */ }; static unsigned long allowed_fill_percent = 90; struct hs_base { unsigned long tablesize_; unsigned long tablesize_entry_index_; unsigned long allowed_fill_; /* Record_count means number of active records, counting all records on chains. When the record_count is > 90% of a full tablesize_ we redo the table before adding a new entry. */ unsigned long record_count_; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ struct ts_entry * hashtab_; DW_TSHASHTYPE (*hashfunc_)(const void *key); }; struct ts_entry { const void * keyptr; /* So that a keyptr of 0 (if added) is not confused with an empty hash slot, we must mark used slots as used in the hash tab */ unsigned char entryused; struct ts_entry *next; }; enum search_intent_t { want_insert, only_find, want_delete }; static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, struct ts_entry **parent_ptr); static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), int depth); /* A trivial integer-based percentage calculation. Percents >100 are reasonable for a hash-with-chains situation (even if they might not be the best choice for performance). */ static unsigned long calculate_allowed_fill(unsigned long fill_percent, unsigned long ct) { unsigned long v = 0; if(ct < 100000) { unsigned long v2 = (ct *fill_percent)/100; return v2; } v = (ct /100)*fill_percent; return v; } /* Initialize the hash and pass in the hash function. If the entry count needed is unknown, pass in 0 as a count estimate, but if the number of hash entries needed can be estimated, pass in the estimate (which need not be prime, we actually use the nearest higher prime from the above table). If the estimated count is Return the tree base, or return NULL if insufficient memory. */ void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE(*hashfunc)(const void *key), unsigned long size_estimate) { unsigned long prime_to_use = primes[0]; unsigned entry_index = 0; unsigned k = 0; struct hs_base *base = 0; base = *(struct hs_base **)treeptr; if(base) { /* initalized already. */ return base ; } base = calloc(sizeof(struct hs_base),1); if(!base) { /* Out of memory. */ return NULL ; } prime_to_use = primes[0]; while(size_estimate && (size_estimate > prime_to_use)) { k = k +1; prime_to_use = primes[k]; if(prime_to_use == 0) { /* Oops. Too large. */ free(base); return NULL; } entry_index = k; } base->tablesize_ = prime_to_use; base->allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if( base->allowed_fill_< (base->tablesize_/2)) { free(base); /* Oops. We are in trouble. Coding mistake here. */ return NULL; } base->record_count_ = 0; base->tablesize_entry_index_ = entry_index; /* hashtab_ is an array of hs_entry, indexes 0 through tablesize_ -1. */ base->hashfunc_ = hashfunc; base->hashtab_ = calloc(sizeof(struct ts_entry),base->tablesize_); if(!base->hashtab_) { free(base); return NULL; } *treeptr = base; return base; } /* We don't really care whether hashpos or chainpos are 32 or 64 bits. 32 suffices. */ static void print_entry(struct ts_entry *t,const char *descr, char *(* keyprint)(const void *), unsigned long hashpos, unsigned long chainpos) { char *v = 0; if(!t->entryused) { return; } v = keyprint(t->keyptr); printf( "[%4lu.%02lu] 0x%08" DW_PR_DUx " %s\n", hashpos,chainpos, (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, v, descr); } /* For debugging */ static void dumptree_inner(const struct hs_base *h, char *(* keyprint)(const void *), const char *descr, int printdetails) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; unsigned long hashused = 0; unsigned long maxchainlength = 0; unsigned long chainsgt1 = 0; printf("dumptree head ptr : 0x%08" DW_PR_DUx " size %" DW_PR_DUu " entries %" DW_PR_DUu " allowed %" DW_PR_DUu " %s\n", (Dwarf_Unsigned)(uintptr_t)h, (Dwarf_Unsigned)h->tablesize_, (Dwarf_Unsigned)h->record_count_, (Dwarf_Unsigned)h->allowed_fill_, descr); for( ; ix < tsize; ix++,p++) { unsigned long chainlength = 0; struct ts_entry*n = 0; int chainpos = 0; if(p->entryused) { ++hashused; chainlength = 1; if(printdetails) { print_entry(p,"head",keyprint,ix,chainpos); } } chainpos++; for(n = p->next; n ; n = n->next) { chainlength++; if(printdetails) { print_entry(n,"chain",keyprint,ix,chainpos); } } if(chainlength > maxchainlength) { maxchainlength = chainlength; } if (chainlength > 1) { chainsgt1++; } } printf("Hashtable: %lu of %lu hash entries used.\n",hashused,tsize); printf("Hashtable: %lu chains length longer than 1. \n",chainsgt1); printf("Hashtable: %lu is maximum chain length.\n",maxchainlength); } /* Dumping the tree. */ void dwarf_tdump(const void*headp_in, char *(* keyprint)(const void *), const char *msg) { const struct hs_base *head = (const struct hs_base *)headp_in; if(!head) { printf("dumptree null tree ptr : %s\n",msg); return; } dumptree_inner(head,keyprint,msg,1); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } e->keyptr = key; e->entryused = 1; e->next = 0; return e; } static void resize_table(struct hs_base *head, int (*compar)(const void *, const void *)) { struct hs_base newhead; unsigned new_entry_index = 0; unsigned long prime_to_use = 0; /* Copy the values we have. */ newhead = *head; /* But drop the hashtab_ from new. calloc below. */ newhead.hashtab_ = 0; newhead.record_count_ = 0; new_entry_index = head->tablesize_entry_index_ +1; prime_to_use = primes[new_entry_index]; if(prime_to_use == 0) { /* Oops, too large. Leave table size as is, though it will get slow as it overfills. */ return; } newhead.tablesize_ = prime_to_use; newhead.allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if( newhead.allowed_fill_< (newhead.tablesize_/2)) { /* Oops. We are in trouble. */ return; } newhead.tablesize_entry_index_ = new_entry_index; newhead.hashtab_ = calloc(sizeof(struct ts_entry),newhead.tablesize_); if(!newhead.hashtab_) { /* Oops, too large. Leave table size as is, though things will get slow as it overfills. */ free(newhead.hashtab_); return; } { /* Insert all the records from the old table into the new table. */ int fillnewfail = 0; unsigned long ix = 0; unsigned long tsize = head->tablesize_; struct ts_entry *p = &head->hashtab_[0]; for( ; ix < tsize; ix++,p++) { int inserted = 0; struct ts_entry*n = 0; if(fillnewfail) { break; } if(p->keyptr) { tsearch_inner(p->keyptr, &newhead,compar, want_insert, &inserted, 0); if(!inserted) { fillnewfail = 1; break; } } for(n = p->next; n ; n = n->next) { inserted = 0; tsearch_inner(n->keyptr, &newhead,compar, want_insert, &inserted, 0); if(!inserted) { fillnewfail = 1; break; } } } if(fillnewfail) { free(newhead.hashtab_); return; } } /* Now get rid of the chain entries of the old table. */ dwarf_tdestroy_inner(head,0,0); /* Now get rid of the old table itself. */ free(head->hashtab_); head->hashtab_ = 0; *head = newhead; return; } /* Inner search of the hash and synonym chains. */ static struct ts_entry * tsearch_inner( const void *key, struct hs_base* head, int (*compar)(const void *, const void *), const enum search_intent_t intent, int*inserted, /* owner_ptr used for delete. Only set if the to-be-deleted item is on a chain, not in the hashtab. Points to the item pointing to the to-be-deleted-item.*/ struct ts_entry **owner_ptr) { struct ts_entry *s =0; struct ts_entry *c =0; struct ts_entry *q =0; int kc = 0; DW_TSHASHTYPE keyhash = 0; DW_TSHASHTYPE hindx = 0; struct ts_entry *chain_parent = 0; if(! head->hashfunc_) { /* Not fully initialized. */ return NULL; } keyhash = head->hashfunc_(key); if (intent == want_insert) { if( head->record_count_ > head->allowed_fill_) { resize_table(head,compar); } } hindx = keyhash%head->tablesize_; s = &head->hashtab_[hindx]; if(!s->entryused) { /* Not found. */ if(intent != want_insert) { return NULL; } /* Insert in the base hash table in an empty slot. */ *inserted = 1; head->record_count_++; s->keyptr = (const void *)key; s->entryused = 1; s->next = 0; return s; } kc = compar(key,s->keyptr); if(kc == 0 ) { /* found! */ if(want_delete) { *owner_ptr = 0; } return (void *)&(s->keyptr); } chain_parent = s; for(c = s->next; c; c = c->next) { kc = compar(key,c->keyptr); if(kc == 0 ) { /* found! */ if(want_delete) { *owner_ptr = chain_parent; } return (void *)&(c->keyptr); } chain_parent = c; } if(intent != want_insert) { return NULL; } /* Insert following head record of the chain. */ q = allocate_ts_entry(key); if (!q) { return q; } q->next = s->next; s->next = q; head->record_count_++; *inserted = 1; return q; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headin, int (*compar)(const void *, const void *)) { struct hs_base **rootp = (struct hs_base **)headin; struct hs_base *head = *rootp; struct ts_entry *r = 0; int inserted = 0; /* nullme won't be set. */ struct ts_entry *nullme = 0; if (!head) { /* something is wrong here, not initialized. */ return NULL; } r = tsearch_inner(key,head,compar,want_insert,&inserted,&nullme); if (!r) { return NULL; } return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const *rootp, int (*compar)(const void *, const void *)) { /* Nothing will change, but we discard const so we can use tsearch_inner(). */ struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *r = 0; /* inserted flag won't be set. */ int inserted = 0; /* nullme won't be set. */ struct ts_entry * nullme = 0; /* Get to actual tree. */ if (!head) { return NULL; } r = tsearch_inner(key,head,compar,only_find,&inserted,&nullme); if(!r) { return NULL; } return (void *)(&(r->keyptr)); } /* Unlike the simple binary tree case, a fully-empty hash situation does not null the *rootp */ void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct hs_base **proot = (struct hs_base **)rootp; struct hs_base *head = *proot; struct ts_entry *found = 0; /* inserted flag won't be set. */ int inserted = 0; struct ts_entry * parentp = 0; if (!head) { return NULL; } found = tsearch_inner(key,head,compar,want_delete,&inserted, &parentp); if(found) { if(parentp) { /* Delete a chain entry. */ head->record_count_--; parentp->next = found->next; /* We free our storage. It would be up to caller to do a tfind to find a record and delete content if necessary. */ free(found); return (void *)&(parentp->keyptr); } /* So found is the head of a chain. */ if(found->next) { /* Delete a chain entry, pull up to hash tab, freeing up the chain entry. */ struct ts_entry *pullup = found->next; *found = *pullup; free(pullup); head->record_count_--; return (void *)&(found->keyptr); } else { /* Delete a main hash table entry. Problem: what the heck to return as a keyptr pointer? Well, we return NULL. As in the standard tsearch, returning NULL does not mean failure! Here it just means 'empty chain somewhere'. */ head->record_count_--; found->next = 0; found->keyptr = 0; found->entryused = 0; return NULL; } } return NULL; } static void dwarf_twalk_inner(const struct hs_base *h, struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth), UNUSEDARG unsigned level) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; for( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; if(p->keyptr) { action((void *)(&(p->keyptr)),dwarf_leaf,level); } for(n = p->next; n ; n = n->next) { action((void *)(&(n->keyptr)),dwarf_leaf,level); } } } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, UNUSEDARG const int depth)) { const struct hs_base *head = (const struct hs_base *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->hashtab_; /* Get to actual tree. */ dwarf_twalk_inner(head,root,action,0); } static void dwarf_tdestroy_inner(struct hs_base*h, void (*free_node)(void *nodep), UNUSEDARG int depth) { unsigned long ix = 0; unsigned long tsize = h->tablesize_; struct ts_entry *p = &h->hashtab_[0]; for( ; ix < tsize; ix++,p++) { struct ts_entry*n = 0; struct ts_entry*prev = 0; if(p->keyptr && p->entryused) { if(free_node) { free_node((void *)(p->keyptr)); } --h->record_count_; } /* Now walk and free up the chain entries. */ for(n = p->next; n ; ) { if(free_node) { free_node((void *)(n->keyptr)); } --h->record_count_; prev = n; n = n->next; free(prev); } } } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. It is up to the caller to zero out anything pointing to head (ie, that has the value rootp holds) after this returns. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct hs_base *head = (struct hs_base *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->hashtab_; dwarf_tdestroy_inner(head,free_node,0); free(root); free(head); } dwarfutils-20200114/tsearch/dwarf_tsearchred.c000066400000000000000000000552701361531463500212550ustar00rootroot00000000000000/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* The interfaces follow tsearch (See the Single Unix Specification) but the implementation is written without reference to the source of any version of tsearch. See http://www.prevanders.net/tsearch.html for information and an example of use. Implements a red-black tree. Based on Sedgewick "Algorithms" 4th Edition. Right now showing Kindle 'locations', I do not have page numbers. On a Kindle, the insert algorithm is found at Location 7930, and rotate{left,right} precede that a little. Delete as a topic starts at location 7938. Delete supporting algos are at about location 8155. We insert a ts_entry node as head that has a NULL llink and an rlink pointing to the real tree root so that the use does not see the root changing in flight. Kindle location 7808. Red-black BSTs are BSTs with red and black links satisfying: a)Red links lean left b)No node has two red links connected to it. c)The tree has 'perfect black balance': every path from the root to a null link has the same number of black links. Sedgewick defines: a 3-node is a pair of 2-nodes with a red link that leans left. So a 2-node is a node which is not marked red and whose llink is not marked red. */ #include "config.h" #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif #include "stdlib.h" /* for free() */ #include /* for printf */ #ifdef HAVE_STDINT_H #include /* for uintptr_t */ #endif /* HAVE_STDINT_H */ /* This must match the types and print options found in libdwarf.h. */ #define Dwarf_Unsigned unsigned long long #if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) #define DW_PR_DUx "I64x" #else #define DW_PR_DUx "llx" #endif /* DW_PR defines */ #include "dwarf_tsearch.h" #define TRUE 1 #define RED 1 #define FALSE 0 #define BLACK 0 #ifdef DW_CHECK_CONSISTENCY struct ts_entry; void dwarf_check_balance(struct ts_entry *head,int finalprefix); #endif /* DW_CHECK_CONSISTENCY */ struct ts_entry { /* Keyptr usually points to a a record the user saved, the user record contains the user's key itself and perhaps more. However, the values actually present are controlled by the user. */ const void *keyptr; /* Non-zero (RED) red indicates the link pointing into this node is red, otherwise it is a black link pointing to this node. A null llink or rlink (below) means the llink or rlink (respectively) is considered black. */ unsigned char color; struct ts_entry * llink; struct ts_entry * rlink; }; /* Not needed for this set of functions. */ void * dwarf_initialize_search_hash( void **treeptr, UNUSEDARG DW_TSHASHTYPE ( * hashfunc)(const void *key), UNUSEDARG unsigned long size_estimate) { return *treeptr; } static int isred(const struct ts_entry*n) { if(n && n->color == RED) { return TRUE; } return FALSE; } /* Meaning the node is not part of a 3-node. We define NULL as a 2-node. */ static int is_twonode(const struct ts_entry *h) { if(!h) { return TRUE; } if(isred(h)) { return FALSE; } if(isred(h->llink)) { return FALSE; } return TRUE; } #if 0 /* DEBUG ONLY */ static const char * printnode(struct ts_entry*n) { static char b[400]; if(!n) { return "Null node"; } snprintf(b,sizeof(b),"0x%x 2-node %d red %d l 0x%x r 0x%x", (unsigned)n, is_twonode(n), n->color, (unsigned)n->llink, (unsigned)n->rlink); return b; } /* For debugging. Use this to call dumptree_inner from inside this file. */ static char * v_keyprint(const void *l) { unsigned long v = (unsigned long)l; static char buf [50]; snprintf(buf,sizeof(buf),"0x%08" DW_PR_DUx, (Dwarf_Unsigned)(uintptr_t)v); return buf; } #endif /* DEBUG ONLY */ /* Prints the level number and indents 1 space per level. That won't work very well for a deep tree, so perhaps we should clamp at some number of indent spaces? */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } static void dumptree_inner(const struct ts_entry *t, char *(* keyprint)(const void *), const char *descr, int level) { const char *v = ""; if(!t) { return; } dumptree_inner(t->rlink,keyprint,"right",level+1); if(t->keyptr) { v = keyprint(t->keyptr); } printlevel(level); printf("0x%08" DW_PR_DUx " <%s %s> <2-node %d red %u> %s\n", (Dwarf_Unsigned)(uintptr_t)t, (Dwarf_Unsigned)(uintptr_t)t->keyptr, t->keyptr?"key ":"null", v, is_twonode(t), t->color, (Dwarf_Unsigned)(uintptr_t)t->llink, (Dwarf_Unsigned)(uintptr_t)t->rlink, descr); dumptree_inner(t->llink,keyprint,"left ",level+1); } /* Dumping the tree to stdout. */ void dwarf_tdump(const void*rootin, char *(* keyprint)(const void *), const char *msg) { const struct ts_entry *head = (const struct ts_entry *)rootin; const struct ts_entry *root = 0; if(!head) { printf("dwarf_tdump null tree ptr : %s\n",msg); return; } root = head->rlink; if(!root) { printf("dwarf_tdump empty tree : %s\n",msg); return; } printf("dwarf_tdump tree head : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)head,msg); printf("dwarf_tdump tree root : 0x%08" DW_PR_DUx " %s\n", (Dwarf_Unsigned)(uintptr_t)root,msg); dumptree_inner(root,keyprint,"top",0); fflush(stdout); } #ifdef DW_CHECK_CONSISTENCY /* Checking that a tree (or sub tree) is in balance. Only meaningful for balanced trees. Returns the count of black links. a)Red links lean left b)No node has two red links connected to it. c)The tree has 'perfect black balance': every path from the root to a null link has the same number of black links. */ struct balance_s { int countset_; int blackcount_; void *firstcount_; }; static struct balance_s zerobal; static void check_or_set(struct ts_entry*t, int* errcount, struct balance_s *balcount, int linkcount, const char *prefix) { if (!balcount->countset_) { balcount->blackcount_ = linkcount; balcount->countset_ = 1; balcount->firstcount_ = t; return; } if(balcount->blackcount_ == linkcount) { return; } printf("%s Black link count does not match: node 0x%" DW_PR_DUx " %d vs 0x%" DW_PR_DUx " %d\n", prefix, Dwarf_Unsigned(uintptr_t)t, linkcount, (Dwarf_Unsignedbalcount->firstcount_, balcount->blackcount_); ++(*errcount); } int dwarf_check_balance_inner(struct ts_entry *t, int level, int maxdepth, int blacklinkcount, struct balance_s *balcount, int *founderror,const char *prefix) { int redcount = 0; int leftbcount = blacklinkcount; int rightbcount = blacklinkcount; if(level > maxdepth) { printf("%s Likely internal erroneous link loop, got to depth %d.\n", prefix,level); exit(1); } if(!t) { return 0; } redcount = isred(t) + isred(t->llink) + isred(t->rlink); if (redcount > 1) { printf("%s red count error error at node 0x%" DW_PR_DUx ": %d\n", prefix, (Dwarf_Unsigned)(uintptr_t)t, redcount); (*founderror)++; } if(isred(t->rlink)) { printf("%s red right link an error at node 0x%" DW_PR_DUx "\n", prefix, (Dwarf_Unsigned)(uintptr_t)t) (*founderror)++; } if(t->llink) { if(!isred(t->llink)) { leftbcount++; } } else { check_or_set(t,founderror,balcount,leftbcount,prefix); } if(t->rlink) { if(!isred(t->rlink)) { rightbcount++; } } else { check_or_set(t,founderror,balcount,rightbcount,prefix); } dwarf_check_balance_inner(t->llink,level+1,maxdepth, leftbcount,balcount,founderror,prefix); dwarf_check_balance_inner(t->rlink,level+1,maxdepth, rightbcount,balcount,founderror,prefix); return isred(t); } void dwarf_check_balance(struct ts_entry *head,int finalprefix) { const char *prefix = 0; int maxdepth = 1000; /* prevent runaway loop. */ int errcount = 0; int depth = 0; int blackcount = 0; struct balance_s balancect; struct ts_entry*root = 0; if(finalprefix) { prefix = "BalanceError:"; } else { prefix = "BalanceWarn:"; } balancect = zerobal; if(!head) { printf("%s check balance null tree ptr\n",prefix); return; } root = head->rlink; if(!root) { printf("%s check balance null tree ptr\n",prefix); return; } /* Counting in levels, not level number of top level. */ depth = dwarf_check_balance_inner(root,depth,maxdepth, blackcount, &balancect,&errcount,prefix); if(errcount) { printf("%s error count %d\n",prefix,errcount); } return; } #endif /* DW_CHECK_CONSISTENCY */ static struct ts_entry* getlink(struct ts_entry*t,int a) { if(a < 0) { return(t->llink); } return(t->rlink); } static struct ts_entry * allocate_ts_entry(const void *key) { struct ts_entry *e = (struct ts_entry *) malloc(sizeof(struct ts_entry)); if(!e) { return NULL; } e->keyptr = key; e->color = BLACK; /* That is, set black. */ e->llink = 0; e->rlink = 0; return e; } static void flipcolors(struct ts_entry*h) { /* Sedgewick does not verify llink rlink non-null? */ h->color = RED; if(h->llink) h->llink->color = BLACK; if(h->rlink) h->rlink->color = BLACK; } /* Kindle loc 7840. */ static struct ts_entry* rotateleft(struct ts_entry *h) { struct ts_entry *x = h->rlink; h->rlink = x->llink; x->llink = h; x->color = h->color; h->color = RED; return x; } /* Kindle loc 7848. */ static struct ts_entry* rotateright(struct ts_entry *h) { struct ts_entry *x = h->llink; h->llink = x->rlink; x->rlink = h; x->color = h->color; h->color = RED; return x; } static struct ts_entry* moveredright(struct ts_entry *h) { flipcolors(h); /* In 4th Ed. book had ! before isred, corrected in errata, Oct 2012. */ if(isred(h->llink->llink)) { h = rotateright(h); } return h; } /* Kindle loc 8155. */ static struct ts_entry* moveredleft(struct ts_entry *h) { flipcolors(h); /* Added test for h->rlink.. davea. */ if(h->rlink && isred(h->rlink->llink)) { h->rlink = rotateright(h->rlink); h = rotateleft(h); } return h; } static struct ts_entry * tsearch_insert( const void *key, struct ts_entry* h, int (*compar)(const void *, const void *), int*inserted, struct ts_entry **insertednode) { int kc = 1; if(!h) { h = allocate_ts_entry(key); if (!h) { return h; } h->color = RED; *inserted = TRUE; *insertednode = h; return h; } kc = compar(key,h->keyptr); if(kc < 0) { struct ts_entry *t = tsearch_insert(key,h->llink,compar,inserted, insertednode); if(!t) { /* out of memory */ return t; } h->llink = t; } else if (kc > 0) { struct ts_entry *t = tsearch_insert(key,h->rlink,compar,inserted, insertednode); if(!t) { /* out of memory */ return t; } h->rlink = t; } else { /* Found existing. Return it. */ return h; } /* Now fix up links so left is red and right is black. */ if(isred(h->rlink) && !isred(h->llink)) { /* Maintaining red on left. */ /* insert is between. */ h = rotateleft(h); } if(isred(h->llink) && isred(h->llink->llink)) { /* Avoiding sequencial red links, turning into paired reds fixed just below. */ h = rotateright(h); } if(isred(h->llink) && isred(h->rlink)) { /* Pair reds below h,flip to black. */ flipcolors(h); } return h; } /* Search and, if missing, insert. */ void * dwarf_tsearch(const void *key, void **headpin, int (*compar)(const void *, const void *)) { struct ts_entry **headp = (struct ts_entry **)headpin; struct ts_entry *head = *headp; struct ts_entry *root = 0; struct ts_entry *r = 0; struct ts_entry *insertednode = 0; int inserted = 0; if (!head) { struct ts_entry *rhead = 0; struct ts_entry *r2 = 0; rhead = allocate_ts_entry(0); if(!rhead) { return NULL; } r2 = allocate_ts_entry(key); if(!r2) { free(rhead); return NULL; } *headp = rhead; rhead->rlink = r2; r2->color = BLACK; return (void *)&(r2->keyptr); } root = head->rlink; r = tsearch_insert(key,root,compar,&inserted,&insertednode); if (!r) { return NULL; } #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif /* DW_CHECK_CONSISTENCY */ if (inserted) { /* Discards const. Required by the interface definition. */ /* root might change, but never the head pointer, so no need to update *headp. Do need to update head.rlink as balancing might have changed root node. */ head->rlink = r; return (void *)&(insertednode->keyptr); } /* Discards const. Required by the interface definition. */ return (void *)&(r->keyptr); } /* Search. */ void * dwarf_tfind(const void *key, void *const*rootp, int (*compar)(const void *, const void *)) { struct ts_entry **phead = (struct ts_entry **)rootp; struct ts_entry *head = *phead; struct ts_entry *p = 0; if (!head) { return NULL; } p = head->rlink; while( p) { int kc = compar(key,p->keyptr); if (!kc) { return (void *)&(p->keyptr); } p = getlink(p,kc); } return NULL; } static void complementcolors( struct ts_entry *h) { h->color = !h->color; if(h->llink) { h->llink->color = !h->llink->color; } if(h->rlink) { h->rlink->color = !h->rlink->color; } } /* Kindle loc 8155. */ static struct ts_entry * balance( struct ts_entry *h) { if(!h) { return NULL; } if(isred(h->rlink)) { h = rotateleft(h); } /* The following from the insert code. loc 7930. plus complementcolors() */ if(isred(h->rlink) && !isred(h->llink)) { h = rotateleft(h); } if(isred(h->llink) && isred(h->llink->llink)) { h = rotateright(h); } if(isred(h->llink) && isred(h->rlink)) { complementcolors(h); } return h; } /* Kindle Location 8154. */ /* This finds the min record that findmin will find and delete. Meaning the record with llink NULL, descending left links. */ static struct ts_entry * findmin(struct ts_entry *h) { if(!h) { return NULL; } while (h->llink) { h = h->llink; } return h; } /* At Loc 8154 in Kindle. We copied out relevant data, so now delete the lowest key record (possibly while reorganizing the tree). Invariant: current node is not a 2-node. */ static struct ts_entry * deletemin(struct ts_entry *h) { if(!h->llink) { /* Found minimum with key > key to delete. Sedgewick does not do this, so something is wrong somewhere. Mistake in Sedgewick? */ return h->rlink; } if(!isred(h->llink) && !isred(h->llink->llink)) { h = moveredleft(h); } h->llink = deletemin(h->llink); h = balance(h); return h; } enum delete_result_e { dr_unknown, dr_notfound, dr_deleted, dr_noteparent }; /* Kindle location 8168 for the algorithm. */ static struct ts_entry * tdelete_inner(const void *key, struct ts_entry *h, int (*compar)(const void *, const void *), struct ts_entry **parent, enum delete_result_e *dr) { int kc = 0; if(!h) { *dr = dr_notfound; return NULL; } kc = compar(key,h->keyptr); if(kc < 0) { if(!isred(h->llink) && (h->llink && !isred(h->llink->llink))) { h = moveredleft(h); } h->llink = tdelete_inner(key,h->llink, compar, parent,dr); if( *dr == dr_noteparent) { *dr = dr_deleted; *parent = h; } } else { if (isred(h->llink)) { h = rotateright(h); } kc = compar(key,h->keyptr); if (!kc && !h->rlink) { struct ts_entry *l = h->llink; /* This is a case where h is deleted (it matches our key value) and no rlink means it is end of chain at right, so it is replaced with left (corrected by davea). */ free(h); *dr = dr_noteparent; return l; } /* Fixed test. Mistake in Sedgewick. Unless both links off h are non-null we crash. */ if(h->rlink && h->llink && !isred(h->rlink) && !isred(h->rlink->llink)) { h = moveredright(h); } kc = compar(key,h->keyptr); if(!kc) { struct ts_entry *r = 0; /* ASSERT: We have non-null rlink. */ r = findmin(h->rlink); h->keyptr = r->keyptr; h->rlink = deletemin(h->rlink); /* r is the node we are to delete. r value moved to h so we keep the changed h. */ free(r); *dr = dr_noteparent; } else { h->rlink = tdelete_inner(key,h->rlink,compar,parent,dr); if( *dr == dr_noteparent) { *parent = h; *dr = dr_deleted; } } } h = balance(h); return h; } void * dwarf_tdelete(const void *key, void **rootp, int (*compar)(const void *, const void *)) { struct ts_entry **proot = (struct ts_entry **)rootp; struct ts_entry *head = *proot; struct ts_entry *p= 0; struct ts_entry *root= 0; struct ts_entry *parent= 0; enum delete_result_e dr = dr_unknown; if (!head) { return NULL; } root = p = head->rlink; if (!p) { return NULL; } if (!isred(p->llink) && !isred(p->rlink)) { p->color = RED; } p = tdelete_inner(key,root,compar,&parent,&dr); if( dr == dr_unknown || dr == dr_notfound ) { return NULL; } if (dr == dr_noteparent) { parent = p; dr = dr_deleted; } /* INVARIANT: dr == dr_deleted. */ if(p) { /* ASSERT: parent non-null */ root = p; root->color = BLACK; /* We have a root, might be unchanged (or changed). */ head->rlink = root; #ifdef DW_CHECK_CONSISTENCY dwarf_check_balance(head,1); #endif /* DW_CHECK_CONSISTENCY */ /* ASSERT: any rebalancing would leave parent set to the same parent node, just links might have changed and it might not literally be parent due to rebalancing. */ return(void *)(&(parent->keyptr)); } /* The tree is empty. Remove it. */ free(head); *rootp = NULL; return NULL; } static void dwarf_twalk_inner(const struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, const int depth), unsigned level) { if (!p->llink && !p->rlink) { action((const void *)(&(p->keyptr)),dwarf_leaf,level); return; } action((const void *)(&(p->keyptr)),dwarf_preorder,level); if(p->llink) { dwarf_twalk_inner(p->llink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_postorder,level); if(p->rlink) { dwarf_twalk_inner(p->rlink,action,level+1); } action((const void *)(&(p->keyptr)),dwarf_endorder,level); } void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, const int depth)) { const struct ts_entry *head = (const struct ts_entry *)rootp; const struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(!root) { return; } dwarf_twalk_inner(root,action,0); } static void dwarf_tdestroy_inner(struct ts_entry*p, void (*free_node)(void *nodep), int depth) { if(p->llink) { dwarf_tdestroy_inner(p->llink,free_node,depth+1); p->llink = 0; } if(p->rlink) { dwarf_tdestroy_inner(p->rlink,free_node,depth+1); p->rlink = 0; } /* Discards const. Required by the interface definition. */ free_node((void *)p->keyptr); free(p); } /* Walk the tree, freeing all space in the tree and calling the user's callback function on each node. */ void dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) { struct ts_entry *head = (struct ts_entry *)rootp; struct ts_entry *root = 0; if(!head) { return; } root = head->rlink; if(!root) { free(head); return; } dwarf_tdestroy_inner(root,free_node,0); free(head); } dwarfutils-20200114/tsearch/scripts/000077500000000000000000000000001361531463500172605ustar00rootroot00000000000000dwarfutils-20200114/tsearch/scripts/TEST.sh000066400000000000000000000001621361531463500203720ustar00rootroot00000000000000 set -x python concatlines.py comparatorsample.new diff comparatorsample comparatorsample.new dwarfutils-20200114/tsearch/scripts/badsample000066400000000000000000000006051361531463500211340ustar00rootroot00000000000000 0.00 856 === -s -v dwgenb/dwarfgen 0.00 760 === -ta -v dwgenb/dwarfgen 0.00 760 === -tf -v dwgenb/dwarfgen 0.00 752 === -y -v dwgenb/dwarfgen 0.00 756 === -w -v dwgenb/dwarfgen 0.00 936 === -N -v dwgenb/dwarfgen 0.00 1380 === -b -v -v dwgenb/dwarfgen 0.01 1208 === -c -v -v dwgenb/dwarfgen 0.00 792 === -f -v -v dwgenb/dwarfgen 1.13 2172 === -F -v -v dwgenb/dwarfgen dwarfutils-20200114/tsearch/scripts/comparator.py000066400000000000000000000051401361531463500220010ustar00rootroot00000000000000#!/usr/bin/python3 # Tries to make sense of a group of timeing runs. # From running a debug dwarfdump. # David Anderson March 2013. import sys def myreadin(name): l = [] try: file = open(name,"r"); except IOError as message: print(" File could not be opened:", message,file=sys.stderr) sys.exit(1) while(1): try: rec = file.readline() except: break if len(rec) < 1: break line = rec.strip() if len(line) < 1: # Ignore empty lines continue l += [line] #print("line ",line) return l def splitup(rec): w = rec.split() rest = "" ct=2 while ct < len(w): rest = rest + " " +w[ct] ct += 1 return (len(w),float(w[0]),float(w[1]),rest) def computebasename(n): s = n.split("/") v = len(s) if v == 1: return n return s[v-1] def absdiff(a,b): if float(a) < float(b): return float(b) - float(a) return float(a) - float(b) ct = 0 print( len(sys.argv)) if len(sys.argv) <= 1: print("Nothing to do") sys.exit(1) argn = 1; filenames=[] files=[] filelen=0; minrtdiff = 1.0 minsizediff = 50 while argn < len(sys.argv): name = sys.argv[argn] if name == "-drt": argn += 1 minrtdiff = float(sys.argv[argn]) argn += 1 continue if name == "-dsz": argn += 1 minsizediff = float(sys.argv[argn]) argn += 1 continue print("argv[",argn,"] = ", name) r = myreadin(name) if filelen == 0: filelen = len(r) else: if filelen != len(r): print("file len mismatch",filelen, " vs ",len(r), " on ",name) print(len(r)) basename = computebasename(name) filenames += [basename] files += [r] argn += 1 print(len(files)," files read") lnum=0 while lnum < filelen: fnum = 0; basell = 0 basernt = 0.0 basesz = 0.0 basedet = "" basename = "" linereport="n" while fnum < len(filenames): name = filenames[fnum] #print(" line ",lnum," file ",name) lines = files[fnum] ll,rnt,sz,det = splitup(lines[lnum]) if fnum == 0: basename = name basell = ll basernt = rnt basesz = sz basedet = det else: if det != basedet: print("mismatch line ",lnum, "file ", basename, " vs ",name) print basedet , " vs ", det sys.exit(1) rntdiff = absdiff(rnt,basernt) szdiff = absdiff(basesz,sz) if rntdiff < minrtdiff: if szdiff < minsizediff: fnum = fnum + 1 continue if linereport == "n": linereport = "y" print " " print basename, basernt, basesz, print name, rnt,sz,det fnum += 1 lnum += 1 sys.exit(0) dwarfutils-20200114/tsearch/scripts/comparatorsample000066400000000000000000000006531361531463500225600ustar00rootroot00000000000000 0.00 856 === -s -v dwgenb/dwarfgen 0.00 760 === -ta -v dwgenb/dwarfgen 0.00 760 === -tf -v dwgenb/dwarfgen 0.00 760 === -tv -v dwgenb/dwarfgen 0.00 752 === -y -v dwgenb/dwarfgen 0.00 756 === -w -v dwgenb/dwarfgen 0.00 936 === -N -v dwgenb/dwarfgen 0.00 1380 === -b -v -v dwgenb/dwarfgen 0.01 1208 === -c -v -v dwgenb/dwarfgen 0.00 792 === -f -v -v dwgenb/dwarfgen 1.13 2172 === -F -v -v dwgenb/dwarfgen dwarfutils-20200114/tsearch/scripts/concatlines.py000066400000000000000000000037571361531463500221500ustar00rootroot00000000000000#!/usr/bin/python3 # extracts a couple preferred numbers from the /bin/time output # interspersed with script output... # From running a debug dwarfdump. # David Anderson March 2013. import sys def extractnum(w): r = "" dot="n" for c in w: if c.isdigit(): r = r + c continue if c == '.': dot = "y" r = r + c continue return r,dot return r,dot def istime(w): """ Return "y" if the number looks like a time: d*.d* """ t,d = extractnum(w) if len(t) < 4: return "n" if d == "n": return "n" if w[0].isdigit(): if w[1].isdigit: return "y" elif w[1] == '.': return "y" return "n" def findfinal(d): beforenums = "y" wds = d.split() o= "" o2 = "" for w in wds: if istime(w) == "y": beforenums = "n" if beforenums == "y": o += " " o += w continue else: if w.endswith("user"): t = "" for c in w: if not c == "u": t += c else: o2 += " " o2 += t elif w.endswith("maxresident)k"): t = "" for c in w: if not c == "m": t += c else: o2 += " " o2 += t else: ign = "" return (o,o2) final = "" myfile = sys.stdin ct = 0 #if len(sys.argv) > 1: # print("argv[1] = ", sys.argv[1]) # v = sys.argv[1] # if v == "-t": # testonly = "y" # elif v == "-v": # testonly = "v" # else: # print("Argument: ", v, " unknown, exiting.") # sys.exit(1) while 1: #if int(ct) > 5: # break; ct = ct + 1 try: rec = myfile.readline() except: print(final) break if len(rec) < 1: f,v = findfinal(final) print(v,f) break; if rec.startswith("===") == 1: f,v = findfinal(final) print(v,f) final = rec.strip() else: if rec.startswith("Command") == 1: disc = rec.strip() else: final += " " final += rec.strip() dwarfutils-20200114/tsearch/scripts/concatlinesample000066400000000000000000000033601361531463500225260ustar00rootroot00000000000000=== -s -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 856maxresident)k 0inputs+0outputs (0major+292minor)pagefaults 0swaps === -ta -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 760maxresident)k 0inputs+0outputs (0major+244minor)pagefaults 0swaps === -tf -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 760maxresident)k 0inputs+0outputs (0major+244minor)pagefaults 0swaps === -tv -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 760maxresident)k 0inputs+0outputs (0major+245minor)pagefaults 0swaps === -y -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 752maxresident)k 0inputs+0outputs (0major+242minor)pagefaults 0swaps === -w -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 756maxresident)k 0inputs+0outputs (0major+243minor)pagefaults 0swaps === -N -v dwgenb/dwarfgen 0.00user 0.00system 0:00.01elapsed 44%CPU (0avgtext+0avgdata 936maxresident)k 0inputs+0outputs (0major+288minor)pagefaults 0swaps === -b -v -v dwgenb/dwarfgen 0.00user 0.00system 0:00.01elapsed 47%CPU (0avgtext+0avgdata 1380maxresident)k 0inputs+0outputs (0major+467minor)pagefaults 0swaps === -c -v -v dwgenb/dwarfgen Command exited with non-zero status 1 0.01user 0.00system 0:00.03elapsed 62%CPU (0avgtext+0avgdata 1208maxresident)k 0inputs+0outputs (0major+355minor)pagefaults 0swaps === -f -v -v dwgenb/dwarfgen 0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 792maxresident)k 0inputs+0outputs (0major+252minor)pagefaults 0swaps === -F -v -v dwgenb/dwarfgen 1.13user 0.00system 0:01.20elapsed 94%CPU (0avgtext+0avgdata 2172maxresident)k 0inputs+0outputs (0major+606minor)pagefaults 0swaps dwarfutils-20200114/tsearch/scripts/secondsample000066400000000000000000000006531361531463500216640ustar00rootroot00000000000000 0.00 856 === -s -v dwgenb/dwarfgen 0.00 760 === -ta -v dwgenb/dwarfgen 0.00 760 === -tf -v dwgenb/dwarfgen 0.00 760 === -tv -v dwgenb/dwarfgen 0.00 752 === -y -v dwgenb/dwarfgen 0.00 756 === -w -v dwgenb/dwarfgen 0.00 936 === -N -v dwgenb/dwarfgen 0.00 1380 === -b -v -v dwgenb/dwarfgen 0.01 1208 === -c -v -v dwgenb/dwarfgen 0.00 792 === -f -v -v dwgenb/dwarfgen 1.13 2172 === -F -v -v dwgenb/dwarfgen dwarfutils-20200114/tsearch/scripts/testin000066400000000000000000000000341361531463500205060ustar00rootroot00000000000000=======a b c d ========e f dwarfutils-20200114/tsearch/tsearch.c000066400000000000000000000141201361531463500173640ustar00rootroot00000000000000/* Copyright David Anderson 2010-2014. This is free software. Permission hereby granted for anyone to copy or use this code for any purpose without restriction. Attribution may be given or may not, it is your choice. September 8, 2011: The tdelete example code was wrong in that it did not clean up entirely. So was the tsearch example code. Both are now fixed (it's surprisingly difficult to do this all correctly, but then the available documentation is at best a hint). The GNU/Linux tsearch man page (in the man-page 3.54 edition) suggests that tdestroy() takes a pointer to a variable which points to the root. In reality tdestroy() takes a pointer to the root. As revealed by trying tdestroy() both ways. */ /* tsearch() tfind() tdelete() twalk() tdestroy() example. */ #include #include #include #include #include /* __USE_GNU exposes the GNU tdestroy() function, a function that is not mentioned by the Single Unix Specification. */ #define __USE_GNU 1 #include /* The struct is trivially usable to implement a set or map (mapping an integer to a string). The following struct is the example basis because that is the capability I wanted to use. tsearch has no idea what data is involved, only the comparison function mt_compare_func() and the free function mt_free_func() (passed in to tsearch calls) know what data is involved. Making tsearch very flexible indeed. Obviously the use of a struct is arbitrary, it is just an example. */ struct my_tentry { unsigned mt_key; /* When using this as a set of mt_key the mt_name field is set to 0 (NULL). */ char * mt_name; }; /* We allow a NULL name so this struct acts sort of like a set and sort of like a map. */ struct my_tentry * make_my_tentry(unsigned k,char *name) { struct my_tentry *mt = (struct my_tentry *)calloc(sizeof(struct my_tentry),1); if(!mt) { printf("calloc fail\n"); exit(1); } mt->mt_key = k; if(name) { mt->mt_name = strdup(name); } return mt; } void mt_free_func(void *mt_data) { struct my_tentry *m = mt_data; if(!m) { return; } free(m->mt_name); free(mt_data); return; } int mt_compare_func(const void *l, const void *r) { const struct my_tentry *ml = l; const struct my_tentry *mr = r; if(ml->mt_key < mr->mt_key) { return -1; } if(ml->mt_key > mr->mt_key) { return 1; } return 0; } void walk_entry(const void *mt_data,VISIT x,int level) { struct my_tentry *m = *(struct my_tentry **)mt_data; printf("<%d>Walk on node %s %u %s \n", level, x == preorder?"preorder": x == postorder?"postorder": x == endorder?"endorder": x == leaf?"leaf": "unknown", m->mt_key,m->mt_name); return; } int main() { unsigned i; void *tree1 = 0; #define RECMAX 3 for(i = 0 ; i < RECMAX ; ++i) { int k = 0; char kbuf[40]; char dbuf[60]; struct my_tentry *mt = 0; struct my_tentry *retval = 0; snprintf(kbuf,sizeof(kbuf),"%u",i); strcpy(dbuf," data for "); strcat(dbuf,kbuf); /* Do it twice so we have test the case where tsearch adds and one where it finds an existing record. */ for (k = 0; k < 2 ;++k) { mt = make_my_tentry(i,dbuf); errno = 0; /* tsearch adds an entry if its not present already. */ retval = tsearch(mt,&tree1, mt_compare_func ); if(retval == 0) { printf("Fail ENOMEM\n"); exit(1); } else { struct my_tentry *re = 0; re = *(struct my_tentry **)retval; if(re != mt) { printf("found existing ok %u\n",i); /* Prevents data leak: mt was already present. */ mt_free_func(mt); } else { printf("insert ok %u\n",i); /* New entry mt was added. */ } } } } for(i = 0 ; i < 5 ; ++i) { char kbuf[40]; char dbuf[60]; dbuf[0] = 0; struct my_tentry *mt = 0; struct my_tentry *retval = 0; snprintf(kbuf,sizeof(kbuf),"%u",i); mt = make_my_tentry(i,dbuf); retval = tfind(mt,&tree1,mt_compare_func); if(!retval) { if(i < RECMAX) { printf("Fail TSRCH on %s is FAILURE\n",kbuf); exit(1); } else { printf("Fail TSRCH on %s is ok\n",kbuf); } } else { printf("found ok %u\n",i); } mt_free_func(mt); } twalk(tree1,walk_entry); { struct my_tentry *mt = 0; struct my_tentry *re3 = 0; void *r = 0; mt = make_my_tentry(1,0); r = tfind(mt,&tree1,mt_compare_func); if (r) { /* This is what tdelete will delete. tdelete just removes the reference from the tree, it does not actually delete the memory for the entry itself. */ re3 = *(struct my_tentry **)r; r = tdelete(mt,&tree1,mt_compare_func); /* We don't want the 'test' node left around. */ mt_free_func(mt); if(r) { struct my_tentry *re2 = 0; re2 = *(struct my_tentry **)r; printf("tdelete returned parent: %u %s\n", re2->mt_key, re2->mt_name); } else { printf("tdelete returned NULL, tree now empty.\n"); } /* Delete the content of the node that tdelete removed. */ mt_free_func(re3); } else { /* There is no node like this to delete. */ /* We don't want the 'test' node left around. */ mt_free_func(mt); } } twalk(tree1,walk_entry); tdestroy(tree1,mt_free_func); printf("PASS tsearch test.\n"); exit(0); } dwarfutils-20200114/tsearch/tsearch_tester.c000066400000000000000000001016131361531463500207560ustar00rootroot00000000000000/* Copyright (c) 2014, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Testing tsearch etc. tsearch [-adds] [-std] -byvalue inputfile ... If one or more inputfile is listed then 'standard' tests are not done. If -std is given then (even with inputfile) standard tests are done. If -adds is given then extra tdump output is generated from one of the test driver functions. If -showa is given then extra output is generated identifying some some add/delete actions. If -byvalue is given then the tests are run using values not pointes. Run like this it is impossible to differentiate whether dwarf_tsearch() adds a new tree entry or just finds an existing one. In the right circumstances this approach is useful in that it is a bit faster than the default. See applybyvalue() and applybypointer. For timing tests, you probably want to compile with -DFULL_SPEED_RUN */ #include "config.h" #include #include #include #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include "dwarf_tsearch.h" /* These defines rename the call targets to Unix standard names (or to nothing where there is no standard version). */ #ifdef LIBC_TSEARCH #define _GNU_SOURCE /* for tdestroy */ #define __USE_GNU /* tdestroy */ #include #define dwarf_tsearch(a,b,c) tsearch(a,b,c) #define dwarf_tfind(a,b,c) tfind(a,b,c) #define dwarf_tdelete(a,b,c) tdelete(a,b,c) #define dwarf_twalk(a,b) twalk(a,b) #define dwarf_tdestroy(a,b) tdestroy(a,b) #define dwarf_tdump(a,c,d) #define dwarf_initialize_search_hash(a,b,c) #define DW_VISIT VISIT #define dwarf_preorder preorder #define dwarf_postorder postorder #define dwarf_endorder endorder #define dwarf_leaf leaf #endif /* LIBC_TSEARCH */ /* The struct is trivially usable to implement a set or map (mapping an integer to a string). The following struct is the example basis because that is the capability I wanted to use. tsearch has no idea what data is involved, only the comparison function mt_compare_func() and the free function mt_free_func() (passed in to tsearch calls) know what data is involved. Making tsearch very flexible indeed. Obviously the use of a struct (and this particular struct) is arbitrary, it is just an example. */ struct example_tentry { unsigned mt_key; /* When using this as a set of mt_key the mt_name field is set to 0 (NULL). */ char * mt_name; }; /* used to hold test data */ struct myacts { char action_; unsigned addr_; }; /* Another example of tree content is a simple value. Since the tree contains a pointer for each object we save, we can only directly save a value that fits in a pointer. */ typedef unsigned VALTYPE; enum insertorder { increasing, decreasing, balanced }; static int applybypointer(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage); static int applybyvalue(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage); int(*applyby)(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage); static const int increaseorder[] = {1,2,3,4,5,6}; static const int decreaseorder[] = {6,5,4,3,2,1}; /* The following a pseudo-random order. */ static const int balanceorder[] = {3,6,2,5,4,1}; /* From real code exposing a bug: */ static struct myacts sequence1[] = { {'a', 0x33c8}, {'a', 0x34d8}, {'a', 0x35c8}, {'a', 0x3640}, {'a', 0x3820}, {'a', 0x38d0}, {'a', 0x3958}, {'a', 0x39e8}, {'a', 0x3a78}, {'a', 0x3b08}, {'a', 0x3b98}, {'a', 0x3c28}, {'a', 0x3cb8}, {'d', 0x3c28}, {'a', 0x3d48}, {'d', 0x3cb8}, {'a', 0x3dd8}, {'d', 0x3d48}, {'a', 0x3e68}, {'d', 0x3dd8}, {'a', 0x3ef8}, {'a', 0x3f88}, {'d', 0x3e68}, {'a', 0x4018}, {'d', 0x3ef8}, {0,0} }; static struct myacts sequence2[] = { {'a', 0x931d2e0}, {'a', 0x931d340}, {'a', 0x931d378}, {'a', 0x931d3b8}, {'a', 0x931d0b0}, {'a', 0x931f7f8}, {'d', 0x931f7f8}, {'d', 0x931d378}, {'a', 0x931d378}, {'a', 0x931f7f8}, {'d', 0x931f7f8}, {'a', 0x931f7f8}, {'d', 0x931f7f8}, {'a', 0x931f9a8}, {'a', 0x931f9f0}, {'a', 0x931fa38}, {'a', 0x93224c0}, {'a', 0x93224f0}, {'a', 0x9322538}, {'a', 0x9322568}, {'a', 0x93225b0}, {'a', 0x93225e0}, {'a', 0x9322628}, {'a', 0x9322658}, {'a', 0x93226a0}, {'a', 0x93226d0}, {'d', 0x93224c0}, {'d', 0x9322538}, {'d', 0x93225b0}, {'d', 0x9322628}, {'d', 0x93226a0}, {'a', 0x931f918}, {'d', 0x931f918}, {'a', 0x931f918}, {0,0} }; /* This test is meant to ensure we can add a value with key of zero. */ static struct myacts sequence3[] = { {'a', 0x0}, {'a', 0xffffffff}, {'a', 0xffff}, {0,0} }; static struct myacts sequential64[] = { {'a', 1}, {'a', 2}, {'a', 3}, {'a', 4}, {'a', 5}, {'a', 6}, {'a', 7}, {'a', 8}, {'a', 9}, {'a', 10}, {'a', 11}, {'a', 12}, {'a', 13}, {'a', 14}, {'a', 15}, {'a', 16}, {'a', 17}, {'a', 18}, {'a', 19}, {'a', 20}, {'a', 21}, {'a', 22}, {'a', 23}, {'a', 24}, {'a', 25}, {'a', 26}, {'a', 27}, {'a', 28}, {'a', 29}, {'a', 30}, {'a', 31}, {'a', 32}, {'a', 33}, {'a', 34}, {'a', 35}, {'a', 36}, {'a', 37}, {'a', 38}, {'a', 39}, {'a', 40}, {'a', 41}, {'a', 42}, {'a', 43}, {'a', 44}, {'a', 45}, {'a', 46}, {'a', 47}, {'a', 48}, {'a', 49}, {'a', 50}, {'a', 51}, {'a', 52}, {'a', 53}, {'a', 54}, {'a', 55}, {'a', 56}, {'a', 57}, {'a', 58}, {'a', 59}, {'a', 60}, {'a', 61}, {'a', 62}, {'a', 63}, {'a', 64}, {0,0} }; static int runstandardtests = 1; static int g_hideactions = 1; /* showallactions is for debugging tree add/delete and should almost always be zero. */ static int g_showallactions = 0; static char filetest1name[2000]; static struct myacts *filetest1 = 0; static char filetest2name[2000]; static struct myacts *filetest2 = 0; static char filetest3name[2000]; static struct myacts *filetest3 = 0; static char filetest4name[2000]; static struct myacts *filetest4 = 0; static int get_record_id(enum insertorder ord,int indx) { int i = 0; switch(ord) { case increasing: i = increaseorder[indx]; break; case decreasing: i = decreaseorder[indx]; break; case balanced: i = balanceorder[indx]; break; default: printf("FAIL, internal error in test code\n"); exit(1); } return i; } /* We allow a NULL name so this struct acts sort of like a set and sort of like a map. */ static struct example_tentry * make_example_tentry(unsigned k,char *name) { struct example_tentry *mt = (struct example_tentry *)calloc(sizeof(struct example_tentry),1); if(!mt) { printf("calloc fail\n"); exit(1); } mt->mt_key = k; if(name) { mt->mt_name = strdup(name); } return mt; } static void mt_free_func(void *mt_data) { struct example_tentry *m = mt_data; if(!m) { return; } free(m->mt_name); free(mt_data); return; } #ifdef HASHSEARCH static DW_TSHASHTYPE mt_hashfunc(const void *keyp) { /* our key here is particularly simple. */ const struct example_tentry *ml = keyp; return ml->mt_key; } #endif /* HASHSEARCH */ static void printlevel(int level) { int len = 0; int targetlen = 4 + level; int shownlen = 0; char number[10]; len = snprintf(number,sizeof(number),"<%d>",level); printf("%s",number); shownlen = len; while(shownlen < targetlen) { putchar(' '); ++shownlen; } } static int mt_compare_func(const void *l, const void *r) { const struct example_tentry *ml = l; const struct example_tentry *mr = r; if(ml->mt_key < mr->mt_key) { return -1; } if(ml->mt_key > mr->mt_key) { return 1; } return 0; } static void walk_entry(const void *mt_data,DW_VISIT x,int level) { const struct example_tentry *m = *(const struct example_tentry **)mt_data; printlevel(level); printf("Walk on node %s %u %s \n", x == dwarf_preorder?"preorder": x == dwarf_postorder?"postorder": x == dwarf_endorder?"endorder": x == dwarf_leaf?"leaf": "unknown", m->mt_key,m->mt_name); return; } static void value_only_walk_entry(const void *data,DW_VISIT x,int level) { VALTYPE val = (VALTYPE)(uintptr_t)data; printlevel(level); printf("Walk on node %s 0x%lu\n", x == dwarf_preorder?"preorder": x == dwarf_postorder?"postorder": x == dwarf_endorder?"endorder": x == dwarf_leaf?"leaf": "unknown", (unsigned long)val); return; } #ifndef LIBC_TSEARCH static char * mt_keyprint(const void *v) { static char buf[50]; const struct example_tentry *mt = (const struct example_tentry *)v; buf[0] = 0; snprintf(buf,sizeof(buf),"0x%08x",(unsigned)mt->mt_key); return buf; } static char * value_keyprint(const void *v) { VALTYPE val = (VALTYPE)(uintptr_t)v; static char buf[50]; buf[0] = 0; snprintf(buf,sizeof(buf),"0x%08lx",(unsigned long)val); return buf; } #endif /* LIBC_TSEARCH */ static int insertrecsbypointer(int max, void **tree, const enum insertorder order) { int indx = 0; for(indx = 0 ; indx < max ; ++indx) { int i = 0; int k = 0; char kbuf[40]; char dbuf[60]; struct example_tentry *mt = 0; struct example_tentry *retval = 0; i = get_record_id(order,indx); snprintf(kbuf,sizeof(kbuf),"%u",i); strcpy(dbuf," data for "); strcat(dbuf,kbuf); printf("insertrec %d\n",i); /* Do it twice so we have test the case where tsearch adds and one where it finds an existing record. */ for (k = 0; k < 2 ;++k) { mt = make_example_tentry(i,dbuf); errno = 0; /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on %d, give up insertrecsbypointer\n",i); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if(re != mt) { if(!k) { printf("FAIL found existing an error %u\n",i); mt_free_func(mt); return 1; } else { printf("found existing ok %u\n",i); } /* Prevents data leak: mt was already present. */ mt_free_func(mt); } else { if(!k) { printf("insert new ok %u\n",i); } else { printf("FAIL new found but expected existing %u\n",i); } /* New entry mt was added. */ } } } } return 0; } static int findrecsbypointer(int max,int findexpected, const void **tree, const enum insertorder order) { int indx = 0; for(indx = 0 ; indx < max ; ++indx) { char kbuf[40]; char dbuf[60]; struct example_tentry *mt = 0; struct example_tentry *retval = 0; int i = 0; dbuf[0] = 0; kbuf[0] = 0; i = get_record_id(order,indx); snprintf(kbuf,sizeof(kbuf),"%u",i); mt = make_example_tentry(i,dbuf); printf("findrec %d\n",i); retval = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if(!retval) { if(indx < findexpected) { mt_free_func(mt); printf("FAIL tfind on %s is FAILURE\n",kbuf); return 1; } else { printf("Not found with tfind on %s is ok\n",kbuf); } } else { printf("found ok %u\n",i); if(indx >= findexpected) { mt_free_func(mt); printf("FAIL: found with tfind on %s is FAILURE\n",kbuf); return 1; } else { printf("Found with tfind on %s is ok\n",kbuf); } } mt_free_func(mt); } return 0; } /* The dodump flag is so we can distinguish binarysearch actions from the binarysearch with eppinger mods easily in the test output. The difference is slight and not significant, but the difference is what we look for when we look. */ static int delrecsbypointer(int max,int findexpected, void **tree,const enum insertorder order,int dodump) { int indx = 0; for (indx = 0; indx < max; indx++) { struct example_tentry *mt = 0; struct example_tentry *re3 = 0; void *r = 0; int i = 0; i = get_record_id(order,indx); printf("delrec %d\n",i); mt = make_example_tentry(i,0); r = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (r) { /* This is what tdelete will delete. tdelete just removes the reference from the tree, it does not actually delete the memory for the entry itself. In fact there is no way to know for sure what was done just given the return from tdelete. You just just assume the delete worked and use the tfind result to delete your contents if you want to.*/ re3 = *(struct example_tentry **)r; if(indx < findexpected) { ; } else { mt_free_func(mt); printf("FAIL delrecsbypointer should not have found record to delete for %d\n",i); return 1; } r = dwarf_tdelete(mt,tree,mt_compare_func); if (! *tree) { printf("tree itself now empty\n"); } /* We don't want the 'test' node left around. */ if(r) { /* If the node deleted was root, r is really the new root, not the parent. Or r is non-null but bogus. (so don't print). */ printf("tdelete returned parent or something.\n"); } else { printf("tdelete returned NULL, tree now empty.\n"); #ifdef HASHSEARCH printf("Only really means some hash chain is now empty.\n"); #endif /* HASHSEARCH */ } mt_free_func(mt); mt_free_func(re3); } else { if(indx >= findexpected) { ; } else { mt_free_func(mt); printf("FAIL delrecsbypointer should have found record to delete for %d\n",i); return 1; } /* There is no node like this to delete. */ /* We don't want the 'test' node left around. */ mt_free_func(mt); } if (dodump) { dwarf_tdump( *tree,mt_keyprint,"In Delrecs"); } dwarf_twalk( *tree,walk_entry); } return 0; } /* mt must point to data in static storage for this to make any sense. Malloc()ed data or unique static data for this instance mt points at. For example, if there was an immobile array and make_example_tentry() somehow selected a unique entry. */ static int insertonebypointer(void **tree, unsigned long addr,int ct) { struct example_tentry *mt = 0; void *retval = 0; mt = make_example_tentry(addr,0); /* tsearch adds an entry if its not present already. */ retval = dwarf_tsearch(mt,tree, mt_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on rec %d adr 0x%lu," " error in insertonebypointer\n", ct,(unsigned long)addr); exit(1); } else { struct example_tentry *re = 0; re = *(struct example_tentry **)retval; if(re != mt) { /* Found existing, error. */ printf("insertonebypointer rec %d addr %lu 0x%lx found record" " preexisting, error\n", ct, (unsigned long)addr, (unsigned long)addr); mt_free_func(mt); return 1; } else { /* inserted new entry, make sure present. */ #ifndef FULL_SPEED_RUN struct example_tentry *mt2 = make_example_tentry(addr,0); retval = dwarf_tfind(mt2,tree,mt_compare_func); mt_free_func(mt2); if(!retval) { printf("insertonebypointer record %d addr 0x%lu " "failed to add as desired," " error\n", ct,(unsigned long)addr); return 1; } #endif /* FULL_SPEED_RUN */ } } return 0; } /* For tfind and tdelete one can use static data and take its address for mt instead of using malloc/free. */ static int deleteonebypointer(void **tree, unsigned addr,int ct) { struct example_tentry *mt = 0; struct example_tentry *re3 = 0; void *r = 0; int err=0; mt = make_example_tentry(addr,0); r = dwarf_tfind(mt,(void *const*)tree,mt_compare_func); if (r) { re3 = *(struct example_tentry **)r; dwarf_tdelete(mt,tree,mt_compare_func); mt_free_func(mt); mt_free_func(re3); } else { printf("deleteonebypointer could not find rec %d ! error! addr" " 0x%lx\n", ct,(unsigned long)addr); mt_free_func(mt); err = 1; } return err; } #ifdef HASHSEARCH /* Only needed for hash based search in a tsearch style. */ #define INITTREE(x,y) x = dwarf_initialize_search_hash(&(x),(y),0) #else #define INITTREE(x,y) #endif /* HASHSEARCH */ static const char * describe_action(char a) { static const char* ad = "add "; static const char* de = "delete "; static const char* un = "unknown"; switch(a) { case 'a': return ad; case 'd': return de; } return un; } static int applybypointer(struct myacts *m, const char *msg, int hideactions, UNUSEDARG int printwalk, UNUSEDARG int dumpeverystage) { unsigned ct = 1; void *treesq1 = 0; int errcount = 0; INITTREE(treesq1,mt_hashfunc); printf("special sequence %s\n",msg); for(; m->action_ != 0; m++,ct++) { if(!hideactions) { printf("Action %2u: %s 0x%x val 0x%x\n",ct, describe_action(m->action_), m->action_,m->addr_); } if(m->action_ == 'a') { errcount += insertonebypointer(&treesq1,m->addr_,ct); continue; } if(m->action_ == 'd') { errcount += deleteonebypointer(&treesq1,m->addr_,ct); continue; } printf("Fail applybypointer, bad action %s entry %d.\n",msg,ct); return 1; } dwarf_tdestroy(treesq1,mt_free_func); return errcount; } #ifdef HASHSEARCH static DW_TSHASHTYPE value_hashfunc(const void *keyp) { VALTYPE up = (VALTYPE )(uintptr_t)keyp; return up; } #endif /* HASHFUNC */ static int value_compare_func(const void *l, const void *r) { VALTYPE lp = (VALTYPE)(uintptr_t)l; VALTYPE rp = (VALTYPE)(uintptr_t)r; if(lp < rp) { return -1; } if(lp > rp) { return 1; } return 0; } /* Nothing to free for the 'value' example. */ static void value_node_free(UNUSEDARG void *valp) { } static int insertbyvalue(void **tree, VALTYPE addr,int ct) { void *retval = 0; /* tsearch adds an entry if its not present already. */ /* Since in this test we do not malloc anything there is no free needed either. Instead we just let tsearch store the value in the pointer in the tree. */ VALTYPE newval = addr; retval = dwarf_tsearch((void *)(uintptr_t)newval, tree, value_compare_func ); if(retval == 0) { printf("FAIL ENOMEM in search on item %d, value %lu, " "error in insertbyvalue\n", ct, (unsigned long)newval); exit(1); } else { /* Since we insert a value there is no possible distinction to be made between newly-inserted and found-in-tree. */ #ifndef FULL_SPEED_RUN { /* For debugging. */ VALTYPE mt2 = addr; retval = dwarf_tfind((void *)(uintptr_t)mt2, tree,value_compare_func); if(!retval) { printf("insertone record %d value 0x%lu failed to add" " as desired, error\n", ct,(unsigned long)mt2); return 1; } } #endif /*FULL_SPEED_RUN */ } return 0; } static int deletebyvalue(void **tree, unsigned addr,int ct) { void *r = 0; int err=0; VALTYPE newval = addr; /* We are not mallocing, so nothing to free he tree holds simple values for us. */ r = dwarf_tfind((void *)(uintptr_t)newval, (void *const*)tree,value_compare_func); if (r) { void *r2 = dwarf_tdelete((void *)(uintptr_t)newval, tree,value_compare_func); if(r2) { /* tdelete returned parent */ } else { /* tdelete returned NULL, tree now empty */ } } else { printf("deletebyvalue action %d could not find rec! error!" " addr 0x%x\n", addr,ct); err = 1; } return err; } /* This demonstrates using a simple integer as the value saved, as itself, not a pointer, per-se. The various flags are not important except in that they can help in case bugs still exist. */ static int applybyvalue(struct myacts *m, const char *msg, int hideactions, int printwalk, int dumpeverystage) { unsigned ct = 1; void *treesq1 = 0; int errcount = 0; INITTREE(treesq1,value_hashfunc); printf("special sequence %s\n",msg); for(; m->action_ != 0; m++,ct++) { if(!hideactions) { printf("Action %2u: %s 0x%x val 0x%x\n",ct, describe_action(m->action_), m->action_,m->addr_); } if(m->action_ == 'a') { errcount += insertbyvalue(&treesq1,m->addr_,ct); if(ct == 0) { printf("Add done. action# %2d value 0x%x\n", ct,m->addr_); dwarf_tdump(treesq1,value_keyprint,"first sequence2 added"); } else if(dumpeverystage) { dwarf_tdump(treesq1,value_keyprint,"after add"); } continue; } if(m->action_ == 'd') { errcount += deletebyvalue(&treesq1,m->addr_,ct); if(dumpeverystage) { printf("Delete done. action# %2d value 0x%x\n", ct,m->addr_); dwarf_tdump(treesq1,value_keyprint,"after delete"); } continue; } printf("Fail applybyvalue, bad action %s entry %d.\n",msg,ct); return 1; } if(printwalk) { printf("Twalk start, simple value \n"); dwarf_twalk(treesq1,value_only_walk_entry); printf("Twalk end, simple value\n"); dwarf_tdump(treesq1,value_keyprint,"tdump simple value from applybyvalue"); } dwarf_tdestroy(treesq1,value_node_free); return errcount; } static int standard_tests(void) { void *tree1 = 0; int errcount = 0; if(applyby == applybypointer) { printf("Test with increasing input\n"); INITTREE(tree1,mt_hashfunc); errcount += insertrecsbypointer(3,&tree1,increasing); errcount += findrecsbypointer(6,3,(const void **)&tree1,increasing); dwarf_twalk(tree1,walk_entry); dwarf_tdump(tree1,mt_keyprint,"Dump Tree from increasing input"); errcount += delrecsbypointer(6,3,&tree1,increasing,0); #ifdef HASHSEARCH dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; #endif if(tree1) { printf("FAIL: delrecsbypointer of increasing did not empty the tree.\n"); exit(1); } printf("Test twalk with empty tree\n"); dwarf_twalk(tree1,walk_entry); INITTREE(tree1,mt_hashfunc); printf("Insert decreasing, try tdestroy\n"); errcount += insertrecsbypointer(6,&tree1,decreasing); dwarf_twalk(tree1,walk_entry); dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; INITTREE(tree1,mt_hashfunc); printf("Now test with decreasing input and test twalk and tdelete\n"); errcount += insertrecsbypointer(5,&tree1,decreasing); errcount += findrecsbypointer(6,5,(const void **)&tree1,decreasing); dwarf_twalk(tree1,walk_entry); dwarf_tdump(tree1,mt_keyprint,"Dump Tree from decreasing input"); errcount += delrecsbypointer(6,5,&tree1,decreasing,0); #ifdef HASHSEARCH dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; #endif if(tree1) { printf("FAIL: delrecsbypointer of decreasing did not empty the tree.\n"); exit(1); } INITTREE(tree1,mt_hashfunc); printf("Now test with balanced input and test twalk and tdelete\n"); errcount += insertrecsbypointer(4,&tree1,balanced); errcount += findrecsbypointer(6,4,(const void **)&tree1,balanced); dwarf_twalk(tree1,walk_entry); dwarf_tdump(tree1,mt_keyprint,"Dump Tree from balanced input"); errcount += delrecsbypointer(6,4,&tree1,balanced,1); #ifdef HASHSEARCH dwarf_tdestroy(tree1,mt_free_func); tree1 = 0; #endif if(tree1) { printf("FAIL: delrecsbypointer of balanced did not empty the tree.\n"); exit(1); } dwarf_twalk(tree1,walk_entry); if (errcount > 0) { printf("FAIL tsearch test.\n"); exit(1); } errcount += applyby(&sequence1[0],"Sequence 1", g_hideactions,0,0); errcount += applyby(&sequence2[0],"Sequence 2, a", g_hideactions,0,0); } else { errcount += applyby(&sequence2[0],"Sequence 2, b", g_hideactions,0,0); errcount += applyby(&sequence3[0],"Sequence 3", g_hideactions,0,0); errcount += applyby(&sequential64[0],"Sequential 64", g_hideactions,1,0); } return errcount; } static int getaddr(const char *in, unsigned long *addrout) { unsigned long int res = 0; errno = 0; res = strtoul(in,0,0); if(errno) { return 1; } *addrout = res; return 0; } /* Valid input lines start with # (the rest of the line ignored) or a 12345 or d 0x12345 meaning add a tree record or delete one, respectively. Where the value is the key. Leading spaces on a line are not allowed. Only a single space after the 'a' or 'd' and before the value is allowed. */ static int build_filetest(struct myacts **tout, char *pathout, const char *filename,FILE *f) { char buffer[500]; char * buf = &buffer[0]; size_t bufsize = sizeof(buffer); size_t filelen = 0; size_t ct = 0; int done = 0; size_t ixout = 0; struct myacts *recordacts = 0; while(!done) { ssize_t charsread = 0; bufsize = sizeof(buffer); charsread = getline(&buf,&bufsize,f); if(charsread < 0) { done = 1; break; } ++filelen; } rewind(f); /* Leave zeroed entry (at least one) at the end. */ recordacts = calloc(sizeof(struct myacts),filelen+2); *tout = recordacts; strcpy(pathout,filename); done = 0; for(ct = 0; !done && ( ct < filelen); ++ct) { ssize_t charsread = 0; charsread = getline(&buf,&bufsize,f); if(charsread < 0) { done = 1; break; } if(buf[0] == '#') { continue; } if(buf[0] == 'a' && buf[1] == ' ') { int readaddrfail = 0; unsigned long addr = 0; recordacts[ixout].action_ = 'a'; readaddrfail = getaddr(&buf[2],&addr); if(readaddrfail) { fprintf(stderr,"Improper value input, line %lu of file %s\n" "%s\n", (unsigned long)ct,filename,buf); return 1; } recordacts[ixout].addr_ = addr; } else if(buf[0] == 'd' && buf[1] == ' ') { int readaddrfail = 0; unsigned long addr = 0; recordacts[ixout].action_ = 'd'; readaddrfail = getaddr(&buf[2],&addr); if(readaddrfail) { fprintf(stderr,"Improper value input, line %lu of file %s\n" "%s\n", (unsigned long)ct,filename,buf); return 1; } recordacts[ixout].addr_ = addr; } else { fprintf(stderr,"Improper input, line %lu of file %s\n" "%s\n", (unsigned long)ct,filename,buf); return 1; } ixout++; } return 0; } static int fill_in_filetest(const char *filename) { FILE *f = 0; int errcount = 0; f = fopen(filename,"r"); if (!f) { fprintf(stderr,"Open of %s failed",filename); return 1; } if(!filetest1) { errcount += build_filetest(&filetest1,filetest1name,filename,f); } else if(!filetest2) { errcount += build_filetest(&filetest2,filetest2name,filename,f); } else if(!filetest3) { errcount += build_filetest(&filetest3,filetest3name,filename,f); } else if(!filetest4) { errcount += build_filetest(&filetest4,filetest4name,filename,f); } else { printf("Exceeded limit on input files. %s ignored\n",filename); errcount = 1; } fclose(f); return errcount; } static void print_usage(const char *a, const char *b,const char *app) { fprintf(stderr,"%s : %s\n",a,b); fprintf(stderr,"run as\n"); fprintf(stderr," %s [-std] [samplefile]...\n",app); fprintf(stderr,"By default runs standard tests\n"); fprintf(stderr,"with pathnames, standard tests are not run\n"); fprintf(stderr,"unless -std passed in as first arg.\n"); exit(1); } static void readargs(int argc, char **argv) { int ix = 0; int notedstd = 0; int defaultstd = 1; if(argc < 2) { /* No arguments, take defaults. */ return; } for(ix = 1; ix ~|_/_+zmR[K)>Oh@]̹sw}?O?Q_җQĬڽ{w~i- OjŊ0Fz0o~Git_R7o2dׯ_߫W'ȭ[4hɒ%w܁W\'N|Wimmmgg>}zkk+'?m?9x-¬ή>{#GFdzjժK.n ]5E?C{쑍WΝ;_?W tظQe0XGQFp ?=vԩS `G׬YG9|ѣG,m۶KKK~ҤI'N8p[om?~M7566^wu̪~ɓEEExp&\mΝ/ra{pqE\y8Fb?nу>cǎ3gDgU/3^w:j:u ހfȑfz饗pkxFm?|p>O&`ѯGm4.\vII ^/Y <߾ꪫ {b ]vaj< thF+P°m?9EQ_bee~tPϙ3SSSÎΜ9-jիWㅆ߲e lfѯGm t$ƎKm?ܻwoGb# nq]w)WI7 \w/>`ً\~l-n -w{U7C܊aÆ3v,PnqEщwУQE+ w)..?G5_q72^_BN0#"`J0{*hQyąnp4.֭ӡ{(.[<51=ʔՀ0ZxWUz&:}qA|Gy<.;сp ĞyeVb=Ec)e_ؿa 0Gə~tXرc)mx7. ;w~ _NE= ~_`4uq^iӦMׯ?Obvk_|y{{;.[K0܌0s]o>|8@}᜼<\Cuu5:xə*.8|0~ΔolWp1cTcR'?xkk+Okyn݊%777==CKԩSheፑ}L ؾ};\ 3=裏c-gJ|^я~f\չs>`_|뭷Z)]m Oo 8J Ktymꌦs$̣tTJP-;NFpB_%=A~ ?裵kb4ƈ#8 %Jeb:ZzMMٳ]8vgt ,g%Jeb:Z#~a4hpiLG%2o1-:~8$<2 LG%"1-w]t)[p4LGeb:^g̘qe!w i%JLo1-zt"Pg4*k(3LÒpLcBZ|m ѫI|}9YId8K@uɖt;,;1*--Ex֡Ckoo?9Y`:Q fdKh}l\x.WFΥKx4Hkk9Y`:Q F[B#:D'wKYYjԄJ;'L'ñ 6p vAc%["GQu.iiiEs,t2%p 6fuɖ tTwfЙ|9Y`:%RZ"DQKBDQk /MbZ>>0j`sOؑ.A,QDӡ8pC HXg9I$fϞ=zh-XM'9?V6+,,D7GXL+1ݾ}ZZZ00%ҫP z/\l!ef`p2n߾xc=_~h:x _,==C33tL2vض6!TA0xƮK 843|Lw5^xѓh:j *E4}9r$CVTC Ea t"p/$0 M琕d1"t"P|} %j.qKp…  1ѸqxF)BL'İ%u)6m4sLt AiUUFq,++ƏϾYU`"n߾}gΜ@u`޽g͚5tL YYYIưs:.''u>L;w.T?PL Hư%uܥ;D󉪅/D3) ub:gb^W] o3 ̧L fRg3saVh`1TrZLgr邨c:_($BWRbprELLJӅ<,Whll?~+#=hӹKc^tv}+V觐N*0+[XX!k8GMZV׵k Fjhh={6p9s)$b_X[[;eȱQ] ?DbyԤ%aeze 6ظ _6maÆ9~ $᮲d8F$tWB ^gwɒ%c?Db6o6p5oiE=꧐HzEt3-R[ua:".\ ӰtTS\u#J1:5KMMI3?<׏@ǔ2\lt`JIIМe.1%1W-dSVu{aaիWcjêp=EbԩSc:* GצkmmEorg=zVѣ ܥm,yĎ;\Bt+1n>qw}WXt_sF*z]Ν˒G={V{u͔ĘT VN:n8a96޾} =e{r)<OBj1UcW_}u񙙙JJJtW_}رcQvwQWBG8P:S%1G… )(cEtmƋ/.Z[pQv~]hMP:JbL*l95//F|!G=΀(X*8NP:t^KL! +)1UsK! 3tT566 (Lw4]DH!,ΌQ K@a"*=D 8 ?~uQc:*;.C`sJ\%1 UtGӅ_: D ƾRc:* ǎ9·DӅ_:6BtƔĘ1d9"-=D oĘ/tQ..12ǨLt1Jl(U"#$8w|?wD݈Dcز:IgctZhX׉'b5hР%K8C,SSSٙ:nC)[\å &pd7l0Ȳ`9s[-DcJJJEEjIգ Ç?z(KZPP7Bkoo6mim޼y7Q ~b=Sfk*#g},_*+9N/Ej,.RKM#쵸9pu,e4X*)}"q &"$^#;29tDC?EFpB/EtЕ*ƛ2qa2:M1h:wKhǗ/_·ٝ\vv;z>Mn ]?֭[榧;]8 t_tGӹ[BWøMɓ'DN>ݑGF!1YtGӹ[BYuut iw̙Z-Y'mnAa2:c1.X]D1yu5 )֦u t/ӡ($q0l t u6F##!Bt"N$c:ġ̰% u ^eV2C^999b1Dj&hPLju]yJh;9JOOX" ӹ'qm tBNX0lF=tR 8"3HZL{n$-n۶m4'#dzūyr݉$|LtLJ8:.s*}Wf8?["(^c:Rdz2f͘.-qL&;dz 1lzq^YℓUGӹu0iz"̫/ .T49/=|'nKE>UT,*2DcW^yQ >9Km ,+KKvm6ϛ7іÀT>ՕYWթ2/>}Ѧ&R MS]T-q[ʐQC.̤n 7R遝>t+ȧ\f2m)Cz[J0YHuM_З.]c`G*GN E#/t/_cK[ES(&8JyiL>KII1Ur`110:4Ҙ\>knn6U40#&"/tx-en*&ZLgr)Cwpۅ0P112Ҙ|Ldl)Cw) T8AV0ә\ʐJJM."μU7\)d}.$..\@_f_7ν}0sGsob)M6͜9]lo۶aӧc ҂1+CdiәthNs|\< ljkk?i$8e`Lb:w4FaNNn=* q1b /(5Z/V>3,Q,eXTTtwBWfX=;v>$Esx֊ O>tAx1c'^>c0C\eep~} |&t-qX]D1y%y^ZL'ĭy8ZҢ*]2ƕA NL'ĭy8Z)&b`y\3BL1o'RK>z9λ1K.q@gRvb: p9Nz)&z뭜wNdp.&RK^)bavhw2t*k1#ŭy5ZULzxa_ &K0 ÷D1鵇jv"㈇s`mtw#tB @q$zx9#1}SpWSSr;GRRROduvG%<9^铜Xw1...f+2\x:FS,d?H|5b!^9Ԭ'9 SL^EG 6rt=:yE8} ó+2 #qcpGWUU%1}I%x RdM s#qeCshC8O4 1Fl'wFǀ}3Qr&(JHz"̫ u~vus$1^YsTTT(y&K7 hn{ "c:cxJߴiӕ3mg҂!C0ى(CG##Ș~w1|~t\ w_uvb:eee $c՘U ] X7Puvb:hJtԘ.`c K <*LG1dL'̧T`:8+𢇈I`wu:1D)1-=4OW7QLzt&;+ z,1y%V-+%fLu /eȹ{Y!2(#/+TyKrn+ϑ$$1HKc,IMMպ!iJrqKČ#py9.RoQRsBre,faVy\w@ueJW9!%bJb+T\ sW{!3'btyiLP]%K{fW*Hs+[8hJJ+Tۥ Wb=qeb:E],t+(,] U K[[e\.dser:^ ¢w)//K{nt0ـAdɋ*E`\rLGN:^S4ZXT1.#/ZLIIktX6]T1. θpӃE^% .]@s4 r~˖G^ztT.k( [S"/y9!d%8 _R􀻬[nL0rQ9KKK1f@|B\;#16_%2`4oKUTMMMݠ8qD  >1ˆ<55)))UUUr-Ƹ֬YӟЍI}!%2sKU60|G}xlp'//O#)Ma_[[뮻g̛7oȑۺucrsswe,'nɠLaH^{=cïorrrpNff&\/jiiiϟp:*ŋ B%ᴱgKۊC#GlٲeѢEhz cg?CF)**S;Q@TNRƳ%HGvx6=f u/nH2FV\)Ai'jn ߢ CD`:mM˼IJb`:o\ԖEFpB/Yᘼ`Xqa2:ӹ1yı]8vgt ,g%.$LK:݅#N8`hNX@0q,GF!I%+ ǒ.FI`hNX@0q,Qp0y%QEd|E Eb`.kٌ\zk "10?v=X=_Rk1ݎ;01Cgչ[UG2RN@b`k1^T<~{ΝpcWnIZZ:&t,HkkbI&TN5ʒ:u4M I㹆;Vb:l㮮YO& }ukkk8%vlthjb੠٥I}E40S:Lb`k1pU4`IdtTO 1ttw_yLT0YIENDB`PK=D styles.xmlY[o6~߯0hɒ耶(z;#Q2WJHʗ"-Y#~CsAXypn~aiJbJX\帐G 2kŊ!AĪ@9+X +jWz)3M঴9UXa[nܔN8OVX)A1K$əJOko+e ~?_ςh\z;\YqQI`b"Q`9h} 4;'S$xXrL+ve4['ǙC2*IS6Gr;5L_SRU1'mtS1LU&ٵ0 s97(}(8z, ojՁEa\mɹj777L 'oB 4rR8dD ^PN#8NطT^ .vBQmz;F5mYlk_ag*aKrDBlYU>[ xCÒ2h.4/VSa7[Y? rTez~A&]𠲤5~+Fa$>xnƻ:S`N ٮ͝p_^OChUx83Wmo8H էЋ`l1Q @$Q5$@ԩ{Ά=&KY|;mbux4.#u>qB=g`WglJV94)2! /ET4OJ^ p1<]ϰvP|3kFԺc W FgS.힪T}EGV֞^yFlYr-tR}gS~[;!//r38U3A^ۣwLJu vU9?RhD{lt|1z_-Kر쳋Pi@§C',-qE "Lg?GDWI?UOH8Ai9kfDO3on-&8G3ܯO*y4 s o3yqUՀnIHx/ r<(׼rF0<:XT=bÄ8AdLʺJ`\oj H5L24N,EN5̛q.>$Wc "Qϓ'S]tL5ƫ$RLiQ1,cF\UC{Ez$`iF2oS!uVe\RXJ]sU/3^ jLF=WsoI|DM荄G*87T]q1hDbI|/.>4JΟtz28>I}O=-:>b CM,(Td4z.NKU-xHݏSUWԐL!ULHd1[߾%XRuRu;ڴWfg;u")Z*Ձ.u]Rpʳm_}łzGi @ xs#7^wf >N\cw= 1vD-# m\> i'J[.^0 pY51åcdmTEQ4#*mJ6dסR࠯[pc Ձ AcBTi hO<{ڲPpWcCS(v4ԿV;J.!mt_qQWhS9Com,wPˀqPf)ky-ޯ@IP'[;;swMI\ҕÏM;`нlm/xGF_:Ҵ ]Jvm: 숹kPMIgg\MT=);i`G R >Z)zvd`R@$vD-i U*~" uufwiJ}ӆnR(hm{yl_ꣽ7}E-u!ZAYN`<!&"/*-ITsy>=KyKJ<}ZR*~|ݡ|Ae QK|@|L~U_ PKz-@ PK=Dmeta.xmlO0$EXzڪ==ֱ#c6o_0%m=o=|VYiBR&~~CE|_GMԷM9mӪ-#/iF嬕_?rOSrJeCuFp@IAbPa9/zBeWFA㭫FYp jFhE,Ҕʳ$U^b~^=q8N/}&*p*|yS2΍2%4˺ʲj4}97FmRŔgt> Ad'O #*R2<ُԮ@_jP|C!Pbk.utPK}0?PK=D manifest.rdf͓n0؉{*6*t>ۉQGC4hKd^.ލX/+~ UO9"n,AKeՍYْ?? *8II{0ԏ`PK5\ EPK=Dl9..mimetypePK=DOH$$TThumbnails/thumbnail.pngPK=DO) $styles.xmlPK=Dz-@  *content.xmlPK=Dvl4meta.xmlPK=D}0? u6settings.xmlPK=Dh ;manifest.rdfPK=D'<Configurations2/accelerator/current.xmlPK=D=Configurations2/images/Bitmaps/PK=D5\ E[=META-INF/manifest.xmlPK |>