Pull new version of libdwarf

This commit is contained in:
Jeremy 2024-07-02 22:31:01 -06:00
parent 87401f22cd
commit 1071709d04
No known key found for this signature in database
GPG Key ID: 3E11861CB34E158C
29 changed files with 911 additions and 386 deletions

14
CMakeLists.txt vendored
View File

@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.5)
project(libdwarf VERSION 0.9.1 LANGUAGES C CXX)
project(libdwarf VERSION 0.10.1
DESCRIPTION "Library to access DWARF debugging information"
HOMEPAGE_URL "https://github.com/davea42/libdwarf-code.git"
LANGUAGES C CXX)
# libdwarf
option(BUILD_NON_SHARED "build archive library libdwarf[p].a" TRUE)
@ -119,10 +122,8 @@ include(CheckCSourceCompiles)
include(CheckCSourceRuns)
include(CheckSymbolExists)
### Version also appears in configure.ac
set(VERSION 0.9.2)
set(PACKAGE_VERSION "\"${VERSION}\"")
set(PACKAGE_NAME "libdwarf" )
set(PACKAGE_STRING "\"${PACKAGE_NAME} ${VERSION}\"")
set(PACKAGE_BUGREPORT "https://github.com/davea42/libdwarf-code/issues")
set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
string(REGEX REPLACE "[\"]" "" tarname1 "${PACKAGE_STRING}" )
string(REGEX REPLACE "[^a-zA-Z0-9_]" "-" tarname "${tarname1}" )
set(PACKAGE_TARNAME "\"${tarname}\"" )
@ -244,7 +245,7 @@ endif()
# unset(DW_LIBDWARF_STATIC)
#endif()
configure_file(cmake/config.h.cmake config.h)
configure_file(cmake/config.h.in config.h)
if(BUILD_NON_SHARED)
set(DW_LIBDWARF_STATIC -DLIBDWARF_STATIC)
@ -257,6 +258,7 @@ endif()
include(GNUInstallDirs)
add_subdirectory(src/lib/libdwarf)
add_subdirectory(doc)
if ( BUILD_DWARFDUMP )
add_subdirectory(src/bin/dwarfdump)

View File

@ -56,20 +56,22 @@
/* Name of package */
#cmakedefine PACKAGE
#define PACKAGE_VERSION "@PROJECT_VERSION@"
/* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
/* Define to the full name of this package. */
#cmakedefine PACKAGE_NAME libdwarf
#define PACKAGE_NAME "@PROJECT_NAME@"
/* Define to the full name and version of this package. */
#cmakedefine PACKAGE_STRING "${PACKAGE_NAME} ${VERSION}"
#define PACKAGE_STRING "@PACKAGE_STRING@"
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME
/* Define to the home page for this package. */
#cmakedefine PACKAGE_URL "${tarname}" )
#define PACKAGE_URL "@PROJECT_HOMEPAGE_URL@"
/* If using the C implementation of alloca, define if you know the
@ -86,9 +88,6 @@
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION}
/* Version number of package */
#cmakedefine VERSION ${VERSION}
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD

View File

@ -8,7 +8,8 @@ cd libdwarf-code
#git checkout "6216e185863f41d6f19ab850caabfff7326020d7" # v0.8.0
#git checkout "8b0bd09d8c77d45a68cb1bb00a54186a92b683d9" # v0.9.0
#git checkout "8cdcc531f310d1c5ae61da469d8056bdd36b77e7" # v0.9.1 + cmake fixes
git checkout "5e43a5ab73cb00c8a46660b361366a8c9c3c93c9" # v0.9.2
# git checkout "5e43a5ab73cb00c8a46660b361366a8c9c3c93c9" # v0.9.2
git checkout "45ef8e2763f65c31b27cc38bed197b84dc1441d4" # v0.10.2
cd ..
echo "Copying files"
mkdir -p src/lib

View File

@ -50,7 +50,7 @@ dwarf_elfstructs.h
dwarf_error.h dwarf_frame.h
dwarf_gdbindex.h dwarf_global.h dwarf_harmless.h
dwarf_gnu_index.h
dwarf_line.h dwarf_loc.h
dwarf_line.h dwarf_loc.h dwarf_loclists.h
dwarf_machoread.h dwarf_macro.h dwarf_macro5.h
dwarf_object_detector.h dwarf_opaque.h
dwarf_pe_descr.h dwarf_peread.h
@ -69,7 +69,7 @@ dwarf_macho_loader.h
dwarf_memcpy_swap.h)
set_source_group(CONFIGURATION_FILES "Configuration Files"
${PROJECT_SOURCE_DIR}/cmake/config.h.cmake
${PROJECT_SOURCE_DIR}/cmake/config.h.in
${PROJECT_BINARY_DIR}/config.h)
# The -DPIC is so we find the right DW_API value in libdwarf.h
@ -109,7 +109,7 @@ if(ZLIB_FOUND AND zstd_FOUND)
target_link_libraries(dwarf PRIVATE ZLIB::ZLIB ${ZSTD_LIB} )
endif()
set_target_properties(dwarf PROPERTIES PUBLIC_HEADER "libdwarf.h;dwarf.h")
set_target_properties(dwarf PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}")
install(TARGETS dwarf
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
@ -117,7 +117,7 @@ install(TARGETS dwarf
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
configure_file(libdwarf.pc.cmake libdwarf.pc @ONLY)
configure_file(libdwarf.pc.in libdwarf.pc @ONLY)
# The install has to be here, not in
# another CMakeLists.txt to make install work properly
@ -125,7 +125,7 @@ configure_file(libdwarf.pc.cmake libdwarf.pc @ONLY)
# for newer cmake.
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/libdwarfConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf")
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfigVersion.cmake" COMPATIBILITY SameMinorVersion)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfigVersion.cmake" VERSION "${PROJECT_VERSION}" COMPATIBILITY SameMinorVersion)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf")
install(TARGETS dwarf EXPORT libdwarfTargets
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"

View File

@ -66,6 +66,7 @@ dwarf_line.h \
dwarf_line_table_reader_common.h \
dwarf_loc.c \
dwarf_loc.h \
dwarf_loclists.h \
dwarf_locationop_read.c \
dwarf_loclists.c \
dwarf_macho_loader.h \
@ -155,7 +156,7 @@ ChangeLog2020 \
CODINGSTYLE \
dw-linetableheader.txt \
CMakeLists.txt \
libdwarf.pc.cmake \
libdwarf.pc.in \
cmake/libdwarfConfig.cmake.in \
meson.build \
NEWS \

View File

@ -158,8 +158,8 @@ extern "C" {
/* TI = Texas Instruments, for DWARF in COFF */
/* https://www.ti.com/lit/an/spraab5/spraab5.pdf?ts=1705994928599 */
#define DW_TAG_lo_user 0x4080 /* TI */
#define DW_TAG_TI_far_type 0x4080 /* TI */
#define DW_TAG_lo_user 0x4080 /* TI */
#define DW_TAG_MIPS_loop 0x4081
#define DW_TAG_TI_near_type 0x4081 /* TI */
#define DW_TAG_TI_assign_register 0x4082 /* TI */
@ -456,14 +456,13 @@ extern "C" {
/* In extensions, we attempt to include the vendor extension
in the name even when the vendor leaves it out. */
#define DW_AT_HP_block_index 0x2000 /* HP */
#define DW_AT_TI_veneer 0x2000 /* TI */
/* 0x2000 Follows extension so dwarfdump prints the
/* 0x2000 follows extension so dwarfdump prints the
most-likely-useful name. */
#define DW_AT_lo_user 0x2000
#define DW_AT_TI_veneer 0x2000 /* TI */
#define DW_AT_MIPS_fde 0x2001 /* MIPS/SGI */
#define DW_AT_TI_symbol_name 0x2001 /* TI */
#define DW_AT_MIPS_loop_begin 0x2002 /* MIPS/SGI */
@ -728,6 +727,7 @@ extern "C" {
#define DW_AT_APPLE_property 0x3fed
#define DW_AT_APPLE_objc_direct 0x3fee
#define DW_AT_APPLE_sdk 0x3fef
#define DW_AT_APPLE_origin 0x3ff0
#define DW_AT_hi_user 0x3fff
@ -1197,6 +1197,8 @@ most-likely-useful name. */
#define DW_LANG_CPP_for_OpenCL 0x0038 /* DWARF6 */
#define DW_LANG_SYCL 0x0039 /* DWARF6 */
#define DW_LANG_Ruby 0x0040 /* DWARF6 */
#define DW_LANG_Move 0x0041 /* DWARF6 */
#define DW_LANG_Hylo 0x0042 /* DWARF6 */
#define DW_LANG_lo_user 0x8000
#define DW_LANG_Mips_Assembler 0x8001 /* MIPS */
@ -1223,9 +1225,9 @@ most-likely-useful name. */
#define DW_CC_nocall 0x03
#define DW_CC_pass_by_reference 0x04 /* DWARF5 */
#define DW_CC_pass_by_value 0x05 /* DWARF5 */
#define DW_CC_lo_user 0x40
#define DW_CC_GNU_renesas_sh 0x40 /* GNU */
#define DW_CC_lo_user 0x40
#define DW_CC_GNU_borland_fastcall_i386 0x41 /* GNU */
/* ALTIUM extensions. */
@ -1404,8 +1406,8 @@ most-likely-useful name. */
#define DW_CFA_val_offset 0x14 /* DWARF3f */
#define DW_CFA_val_offset_sf 0x15 /* DWARF3f */
#define DW_CFA_val_expression 0x16 /* DWARF3f */
#define DW_CFA_lo_user 0x1c
#define DW_CFA_TI_soffset_extended 0x1c /* TI */
#define DW_CFA_lo_user 0x1c
#define DW_CFA_low_user 0x1c /* Incorrect spelling, do not use. */
/* SGI/MIPS extension. */

View File

@ -132,95 +132,135 @@ dwarf_debug_addr_table(Dwarf_Debug dbg,
if (dw_section_offset >= section_size) {
return DW_DLV_NO_ENTRY;
}
curlocaloffset = 0;
data = section_start + dw_section_offset;
READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned,
data,offset_size,exten_size,
error,
section_size,end_data);
if (arealen > section_size ||
(arealen + offset_size +exten_size) > section_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_SECTION_SIZE_ERROR: A .debug_addr "
"area size of 0x%x ",arealen);
dwarfstring_append_printf_u(&m,
"at offset 0x%x ",dw_section_offset);
dwarfstring_append_printf_u(&m,
"is larger than the entire section size of "
"0x%x. Corrupt DWARF.",section_size);
_dwarf_error_string(dbg,error,
DW_DLE_SECTION_SIZE_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
tab.da_dbg = dbg;
tablelen = arealen - 4; /* 4: the rest of the header */
tab.da_length = tablelen;
curlocaloffset = offset_size + exten_size;
offset_one_past_end = dw_section_offset
+ curlocaloffset + 4 /*rest of header */
+ tablelen;
end_data = section_start + offset_one_past_end;
tab.da_end_table = end_data;
READ_UNALIGNED_CK(dbg,version,Dwarf_Half,data,
SIZEOFT16,error,end_data);
if (version != DW_CU_VERSION5) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_VERSION_STAMP_ERROR: "
"The .debug_addr version should be 5 "
"but we find %u instead.",version);
_dwarf_error_string(dbg,error,
DW_DLE_VERSION_STAMP_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
tab.da_version = version;
data += SIZEOFT16;
curlocaloffset += SIZEOFT16;
READ_UNALIGNED_CK(dbg,address_size,Dwarf_Small,data,
1,error,end_data);
if (address_size != 4 && address_size != 8 &&
address_size != 2) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
" DW_DLE_ADDRESS_SIZE_ERROR: The "
" .debug_addr address size "
"of %u is not supported.",address_size);
_dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
tab.da_address_size = address_size;
data++;
curlocaloffset++;
if (dbg->de_debug_addr_version == DW_CU_VERSION4) {
/* Create a table from what we know. */
address_size = (Dwarf_Small)dbg->de_debug_addr_address_size;
offset_size = dbg->de_debug_addr_offset_size;
tab.da_address_size = address_size;
tab.da_length_size = offset_size;
tab.da_length = section_size;
tab.da_version = dbg->de_debug_addr_version;
end_data = section_start + section_size;
tab.da_end_table = end_data;
/* Must be zero. */
if (dw_section_offset) {
_dwarf_error_string(dbg,error,DW_DLE_DEBUG_ADDR_ERROR,
"DW_DLE_DEBUG_ADDR_ERROR: DWARF4 extension "
".debug_addr has non-zero offset. Impossible");
return DW_DLV_ERROR;
}
tab.da_table_section_offset = dw_section_offset;
tab.da_data_entries = section_start;
tab.da_entry_count= section_size/tab.da_address_size;
/* One past end of this Debug Addr Table */
tab.da_end_table = end_data;
if (tab.da_address_size != 4 && tab.da_address_size != 8 &&
tab.da_address_size != 2) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
" DW_DLE_ADDRESS_SIZE_ERROR: The "
" .debug_addr DWARF4 address size "
"of %u is not supported.",address_size);
_dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
offset_one_past_end = section_size;
tab.da_dbg = dbg;
} else {
/* all other cases, assume DWARF5 table. */
curlocaloffset = 0;
data = section_start + dw_section_offset;
READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned,
data,offset_size,exten_size,
error,
section_size,end_data);
if (arealen > section_size ||
(arealen + offset_size +exten_size) > section_size) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_SECTION_SIZE_ERROR: A .debug_addr "
"area size of 0x%x ",arealen);
dwarfstring_append_printf_u(&m,
"at offset 0x%x ",dw_section_offset);
dwarfstring_append_printf_u(&m,
"is larger than the entire section size of "
"0x%x. Corrupt DWARF.",section_size);
_dwarf_error_string(dbg,error,
DW_DLE_SECTION_SIZE_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
tab.da_dbg = dbg;
tablelen = arealen - 4; /* 4: the rest of the header */
tab.da_length = tablelen;
curlocaloffset = offset_size + exten_size;
offset_one_past_end = dw_section_offset
+ curlocaloffset + 4 /*rest of header */
+ tablelen;
end_data = section_start + offset_one_past_end;
tab.da_end_table = end_data;
READ_UNALIGNED_CK(dbg,version,Dwarf_Half,data,
SIZEOFT16,error,end_data);
if (version != DW_CU_VERSION5) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_VERSION_STAMP_ERROR: "
"The .debug_addr version should be 5 "
"but we find %u instead.",version);
_dwarf_error_string(dbg,error,
DW_DLE_VERSION_STAMP_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
tab.da_version = version;
data += SIZEOFT16;
curlocaloffset += SIZEOFT16;
READ_UNALIGNED_CK(dbg,address_size,Dwarf_Small,data,
1,error,end_data);
if (address_size != 4 && address_size != 8 &&
address_size != 2) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
" DW_DLE_ADDRESS_SIZE_ERROR: The "
" .debug_addr address size "
"of %u is not supported.",address_size);
_dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
tab.da_address_size = address_size;
data++;
curlocaloffset++;
READ_UNALIGNED_CK(dbg,segment_selector_size,Dwarf_Small,data,
1,error,end_data);
if (segment_selector_size != 0) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append(&m,
" DW_DLE_DEBUG_ADDR_ERROR: The "
" .debug_addr segment selector size "
"of non-zero is not supported.");
_dwarf_error_string(dbg,error,DW_DLE_DEBUG_ADDR_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
READ_UNALIGNED_CK(dbg,segment_selector_size,Dwarf_Small,data,
1,error,end_data);
if (segment_selector_size != 0) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append(&m,
" DW_DLE_DEBUG_ADDR_ERROR: The "
" .debug_addr segment selector size "
"of non-zero is not supported.");
_dwarf_error_string(dbg,error,DW_DLE_DEBUG_ADDR_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
/* We do not record segment selector size,
as it is not supported. */
curlocaloffset++;
data++;
tab.da_data_entries = data;
}
/* We do not record segment selector size,
as it is not supported. */
curlocaloffset++;
data++;
tab.da_data_entries = data;
/* Now we are at the beginning of the actual table */
{
Dwarf_Unsigned entry_count = 0;

View File

@ -37,6 +37,16 @@ extern "C" {
#define DW_ADDR_TABLE_MAGIC 0xfade
/* In DWARF5 each portion of .debug_addr has a header.
In a DWARF4 extension gcc emits .debug_addr
but without those headers, just with the
array of data entries, so dwarf_debugaddr.c
creates a table from data in Dwarf_Debug_S
assuming every CU has the
same address_size and version as in the initial
.debug_info CU. */
struct Dwarf_Debug_Addr_Table_s {
Dwarf_Unsigned da_magic;
Dwarf_Debug da_dbg;

View File

@ -59,6 +59,96 @@
#define MINIMUM_ADDRESS_SIZE 2
#define MAXIMUM_ADDRESS_SIZE 8
#if 0
#include "dwarf_rnglists.h" /* for debugging declaration */
static void
dumprnglists_context(Dwarf_Rnglists_Context *rnglists,
Dwarf_Unsigned count)
{
Dwarf_Rnglists_Context prc = 0;
Dwarf_Unsigned i = 0;
printf("Rnglists_Context count: 0x%lu\n",(unsigned long)count);
for ( ; i < count; ++i) {
prc = rnglists[i];
printf("[%3lu] Rnglists_Context rc_index : %lu\n",
(unsigned long)i,
(unsigned long)prc->rc_index);
printf(" hed offset : %lu\n",
(unsigned long)prc->rc_header_offset);
printf(" rc_length : %lu\n",
(unsigned long)prc->rc_length);
printf(" Version: %u offset size: "
"%u address_size: %u \n",
prc->rc_version,prc->rc_offset_size,
prc->rc_address_size);
printf(" offset_entry count : %lu\n",
(unsigned long)prc->rc_offset_entry_count);
printf(" offsets offset_ : %lu\n",
(unsigned long)prc->rc_offsets_off_in_sect);
}
}
static void
dumpcu_context_list( Dwarf_CU_Context first)
{
Dwarf_CU_Context ctx = 0;
unsigned cc = 0;
for ( ctx = first; ctx ; ctx = ctx->cc_next, ++cc) {
printf("[%3u] CU_Context rnglists_base "
" : 0x%lx\n",cc,
(unsigned long)ctx->cc_rnglists_base);
printf(" rnglists_base_contr_size: 0x%lx\n",
(unsigned long)ctx->cc_rnglists_base_contr_size);
printf(" rnglists_base_present : 0x%lx\n",
(unsigned long)ctx->cc_rnglists_base_present);
printf(" rnglists_header_length_present: %lu\n",
(unsigned long)ctx->cc_rnglists_header_length_present);
printf(" ranges_base : 0x%lx\n",
(unsigned long)ctx->cc_ranges_base);
printf(" ranges_base present : 0x%lx\n",
(unsigned long)ctx->cc_ranges_base_present);
}
}
static void
dump_rnglists_data(const char *msg,
Dwarf_Debug dbg,Dwarf_CU_Context cucon)
{
printf("Debugging dump_rnglists_data %s\n",msg);
if (!dbg->de_debug_rnglists.dss_data) {
printf("No de_rnglists section\n");
}
if (!dbg->de_rnglists_context_count) {
printf("No de_rnglists contexts\n");
} else {
dumprnglists_context(dbg->de_rnglists_context,
dbg->de_rnglists_context_count);
}
if (dbg->de_info_reading.de_cu_context_list) {
if (cucon) {
dumpcu_context_list(cucon);
} else {
dumpcu_context_list(
dbg->de_info_reading.de_cu_context_list);
}
} else {
printf("No debug_info cu contexts\n");
}
if (dbg->de_types_reading.de_cu_context_list) {
if (cucon) {
dumpcu_context_list(cucon);
} else {
dumpcu_context_list(
dbg->de_types_reading.de_cu_context_list);
}
} else {
printf("No debug_types cu contexts\n");
}
fflush(stdout);
}
#endif
static void assign_correct_unit_type(Dwarf_CU_Context cu_context);
static int find_cu_die_base_fields(Dwarf_Debug dbg,
Dwarf_CU_Context cucon,
@ -1062,6 +1152,12 @@ dwarf_next_cu_header_e(Dwarf_Debug dbg,
next_cu_offset,
header_cu_type,
error);
if (! dbg->de_debug_addr_version) {
/* To enable printing raw GNU extension .debug_addr */
dbg->de_debug_addr_version = (Dwarf_Half)*version_stamp;
dbg->de_debug_addr_offset_size = (Dwarf_Half)*offset_size;
dbg->de_debug_addr_address_size = (Dwarf_Half)*address_size;
}
return res;
}
@ -1504,7 +1600,7 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
/* Pretending that DW_AT_entry_pc with no
DW_AT_low_pc is a valid base address for
loccation lists.
location lists.
DW_AT_producer 4.2.1 (Based on Apple Inc. build 5658)
(LLVM build 2336.1.00) uses DW_AT_entry_pc as the
base address (DW_AT_entry_pc first appears in DWARF3).
@ -1971,7 +2067,7 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg,
}
if (tres == DW_DLV_ERROR && error) {
/* We'll assume any errors will be
discovered later. Lets get our CU_context
discovered later. Lets get our
finished.
if error NULL it's a caller issue
and there is nothing we can do here */

View File

@ -1968,7 +1968,9 @@ read_gs_section_group(
free(data);
return res;
}
groupmallocsize = count * sizeof(Dwarf_Unsigned);
/* Adding 1 is silly but possibly avoids a warning
from a particular compiler. */
groupmallocsize = (1+count) * sizeof(Dwarf_Unsigned);
if (groupmallocsize >= ep->f_filesize) {
free(data);
*errcode = DW_DLE_ELF_SECTION_GROUP_ERROR;

View File

@ -686,6 +686,9 @@ static const char _dwarf_errmsgs[DW_DLE_LAST+1][DW_MAX_MSG_LEN] = {
{"DW_DLE_UNIVERSAL_BINARY_ERROR(502) Error reading Mach-O "
"uninversal binary head. Corrupt Mach-O object." },
{"DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR(503) Offset/size from "
"a Mach-O universal binary has an impossible value"}
"a Mach-O universal binary has an impossible value"},
{"DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL(504) Section size fails "
"a heuristic sanity check"}
};
#endif /* DWARF_ERRMSG_LIST_H */

View File

@ -28,6 +28,7 @@
#include <config.h>
#include <string.h> /* memset() */
#include <stdlib.h> /* free() */
#if defined(_WIN32) && defined(HAVE_STDAFX_H)
#include "stdafx.h"
@ -44,6 +45,7 @@
#include "dwarf_string.h"
#include "dwarf_str_offsets.h"
#include "dwarf_loc.h"
#include "dwarf_loclists.h"
#include "dwarf_rnglists.h"
/* ASSERT: dbg,cu_context, and fsd are non-NULL
@ -81,7 +83,6 @@ load_xu_loclists_into_cucontext(Dwarf_Debug dbg,
/* Something is badly wrong. Ignore it here. */
return DW_DLV_NO_ENTRY;
}
memset(buildhere,0,sizeof(localcontxt));
res = _dwarf_internal_read_loclists_header(dbg,
0,soff_size,
dbg->de_debug_loclists.dss_data,
@ -90,18 +91,22 @@ load_xu_loclists_into_cucontext(Dwarf_Debug dbg,
buildhere,
&nextset,error);
if (res != DW_DLV_OK) {
free(buildhere->lc_offset_value_array);
buildhere->lc_offset_value_array = 0;
return res;
}
cu_context->cc_loclists_base_present = TRUE;
cu_context->cc_loclists_base_contr_size = size;
cu_context->cc_loclists_base =
buildhere->lc_offsets_off_in_sect;
free(buildhere->lc_offset_value_array);
buildhere->lc_offset_value_array = 0;
return DW_DLV_OK;
}
/*
ASSERT: dbg,cu_context, and fsd are non-NULL
ASSERT: dbg,cu_context, and fsd are non-NULL
as the caller ensured that.
If .debug_cu_index or
.debug_tu_index is present it might help us find
@ -284,6 +289,8 @@ static const char *keylist[2] = {
Then, _dwarf_make_CU_Context() calls
_dwarf_merge_all_base_attrs_of_cu_die() if there
is a tied (executable) object known.
(not all base attrs are merged from tied. Certainly not
.debug_rnglists or .debug_loclists.
Called by dwarf_die_deliv.c
*/

View File

@ -508,7 +508,6 @@ dwarf_formref(Dwarf_Attribute attr,
case DW_FORM_ref_udata: {
Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr;
Dwarf_Unsigned localoffset = 0;
DECODE_LEB128_UWORD_CK(ptr,localoffset,
dbg,error,section_end);
offset = localoffset;
@ -893,10 +892,10 @@ _dwarf_internal_global_formref_b(Dwarf_Attribute attr,
Return the index itself. */
case DW_FORM_loclistx:
case DW_FORM_rnglistx: {
unsigned length_size = cu_context->cc_length_size;
READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
attr->ar_debug_ptr, length_size,
error,section_end);
Dwarf_Unsigned val = 0;
DECODE_LEB128_UWORD_CK(attr->ar_debug_ptr,
val, dbg,error,section_end);
offset = val;
}
break;
case DW_FORM_sec_offset:
@ -1330,7 +1329,7 @@ dwarf_formaddr(Dwarf_Attribute attr,
the reference form. It is
address-sized so that the linker can easily update it, but
it is a reference inside the debug_info section. No longer
allowed. */
allowed except for Metrowerks C. */
) {
Dwarf_Small *section_end =
_dwarf_calculate_info_section_end_ptr(cu_context);

View File

@ -28,7 +28,6 @@
Fifth Floor, Boston MA 02110-1301, USA.
*/
#include <stdio.h>
/* This is #included twice. Once for
libdwarf callers and one for dwarfdump which prints

View File

@ -31,6 +31,7 @@
#include <config.h>
#include <string.h> /* memset() */
#include <stdio.h> /* for debugging printf */
#if defined(_WIN32) && defined(HAVE_STDAFX_H)
#include "stdafx.h"
@ -69,7 +70,7 @@ _dwarf_locdesc_c_constructor(Dwarf_Debug dbg, void *locd)
return DW_DLV_ERROR;
}
ldp->ld_lle_value = DW_LLE_VALUE_BOGUS;
ldp->ld_kind = DW_LKIND_unknown;
ldp->ld_lkind = DW_LKIND_unknown;
return DW_DLV_OK;
}
@ -492,7 +493,7 @@ _dwarf_loc_block_sanity_check(Dwarf_Debug dbg,
return DW_DLV_OK;
}
/* ld_kind was checked before calling this, so we
/* ld_lkind was checked before calling this, so we
know its value is an intended value. */
static const char *kindset[] = {
"DW_LKIND_expression",
@ -520,7 +521,7 @@ validate_lle_value(Dwarf_Debug dbg,
{
dwarfstring m;
if (locdesc->ld_kind != DW_LKIND_GNU_exp_list) {
if (locdesc->ld_lkind != DW_LKIND_GNU_exp_list) {
switch(locdesc->ld_lle_value) {
case DW_LLE_end_of_list:
case DW_LLE_base_addressx:
@ -539,10 +540,10 @@ validate_lle_value(Dwarf_Debug dbg,
dwarfstring_append_printf_s(&m,
"DW_DLE_LOCATION_ERROR: For location kind %s (",
(char *)get_loc_kind_str(
(Dwarf_Small)locdesc->ld_kind));
(Dwarf_Small)locdesc->ld_lkind));
dwarfstring_append_printf_u(&m,"%u) the DW_LLE value is "
"not properly set",
locdesc->ld_kind);
locdesc->ld_lkind);
dwarfstring_append_printf_u(&m," but is %u "
" which is a libdwarf bug",
locdesc->ld_lle_value);
@ -565,10 +566,10 @@ validate_lle_value(Dwarf_Debug dbg,
dwarfstring_append_printf_s(&m,
"DW_DLE_LOCATION_ERROR: For location kind %s (",
(char *)get_loc_kind_str(
(Dwarf_Small)locdesc->ld_kind));
(Dwarf_Small)locdesc->ld_lkind));
dwarfstring_append_printf_u(&m,"%u) the DW_LLEX value is "
"not properly set",
locdesc->ld_kind);
locdesc->ld_lkind);
dwarfstring_append_printf_u(&m," but is %u "
" which is a libdwarf bug",
locdesc->ld_lle_value);
@ -621,7 +622,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
Dwarf_Small *section_end = 0;
const char *section_name = 0;
Dwarf_Small *blockdataptr = 0;
unsigned lkind = loc_head->ll_kind;
unsigned lkind = loc_head->ll_lkind;
/* ***** BEGIN CODE ***** */
blockdataptr = loc_block->bl_data;
@ -716,7 +717,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
}
/* Synthesizing the DW_LLE values for the old loclist
versions. */
switch(loc_head->ll_kind) {
switch(loc_head->ll_lkind) {
case DW_LKIND_loclist: {
if (highpc == 0 && lowpc == 0) {
locdesc->ld_lle_value = DW_LLE_end_of_list;
@ -746,7 +747,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
"DW_DLE_LOCATION_ERROR: An impossible DW_LKIND"
" value of %u encountered, likely internal "
"libdwarf error or data corruption",
(unsigned)loc_head->ll_kind);
(unsigned)loc_head->ll_lkind);
_dwarf_error_string(dbg,error,
DW_DLE_LOCATION_ERROR,
dwarfstring_string(&m));
@ -758,7 +759,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg,
locdesc->ld_cents = (Dwarf_Half)op_count;
locdesc->ld_s = block_loc;
locdesc->ld_kind = lkind;
locdesc->ld_lkind = lkind;
locdesc->ld_section_offset = loc_block->bl_section_offset;
locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset;
locdesc->ld_rawlow = lowpc;
@ -1021,7 +1022,7 @@ dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header,
"dwarf_get_loclist_head_kind()");
return DW_DLV_ERROR;
}
*kind = ll_header->ll_kind;
*kind = ll_header->ll_lkind;
return DW_DLV_OK;
}
@ -1037,7 +1038,7 @@ _dwarf_original_loclist_build(Dwarf_Debug dbg,
int count_res = DW_DLV_ERROR;
int loclist_count = 0;
Dwarf_Unsigned lli = 0;
unsigned lkind = llhead->ll_kind;
unsigned lkind = llhead->ll_lkind;
unsigned address_size = llhead->ll_address_size;
Dwarf_Unsigned listlen = 0;
Dwarf_Locdesc_c llbuf = 0;
@ -1168,7 +1169,7 @@ _dwarf_original_expression_build(Dwarf_Debug dbg,
if (blkres != DW_DLV_OK) {
return blkres;
}
loc_blockc.bl_kind = llhead->ll_kind;
loc_blockc.bl_kind = llhead->ll_lkind;
loc_blockc.bl_section_offset =
(char *)loc_blockc.bl_data -
(char *)dbg->de_debug_info.dss_data;
@ -1186,7 +1187,7 @@ _dwarf_original_expression_build(Dwarf_Debug dbg,
}
loc_blockc.bl_len = loc_block.bl_len;
loc_blockc.bl_data = loc_block.bl_data;
loc_blockc.bl_kind = llhead->ll_kind;
loc_blockc.bl_kind = llhead->ll_lkind;
loc_blockc.bl_section_offset =
loc_block.bl_section_offset;
loc_blockc.bl_locdesc_offset = 0; /* not relevant */
@ -1657,7 +1658,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
return DW_DLV_ERROR;
}
llhead->ll_cuversion = cuversionstamp;
llhead->ll_kind = lkind;
llhead->ll_lkind = lkind;
llhead->ll_attrnum = (Dwarf_Half)attrnum;
llhead->ll_attrform = (Dwarf_Half)form;
llhead->ll_dbg = dbg;
@ -1779,7 +1780,7 @@ dwarf_loclist_from_expr_c(Dwarf_Debug dbg,
llhead->ll_locdesc_count = local_listlen;
llhead->ll_context = 0; /* Not available! */
llhead->ll_dbg = dbg;
llhead->ll_kind = DW_LKIND_expression;
llhead->ll_lkind = DW_LKIND_expression;
/* An empty location description (block length 0)
means the code generator emitted no variable,
@ -1823,6 +1824,7 @@ dwarf_loclist_from_expr_c(Dwarf_Debug dbg,
int
dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,
Dwarf_Unsigned index,
/* Dwarf_Unsigned lle_entry_index, */
Dwarf_Small * lle_value_out,
Dwarf_Unsigned * rawval1,
Dwarf_Unsigned * rawval2,
@ -1836,6 +1838,45 @@ dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,
Dwarf_Unsigned * expression_offset_out,
Dwarf_Unsigned * locdesc_offset_out,
Dwarf_Error * error)
{
return dwarf_get_locdesc_entry_e(
loclist_head, index,
/*0 base local index,*/
lle_value_out,
rawval1,
rawval2,
debug_addr_unavailable,
lowpc_out, /* 'cooked' value */
hipc_out, /* 'cooked' value */
loclist_expr_op_count_out,
0 /* not returning lle_bytecount*/ ,
/* Returns pointer to the specific locdesc of the index; */
locdesc_entry_out,
loclist_source_out, /* 0,1, or 2 */
expression_offset_out,
locdesc_offset_out,
error);
}
int
dwarf_get_locdesc_entry_e(Dwarf_Loc_Head_c loclist_head,
/* The context-local offset of an lle set as reverenced
by an offset_entry_table. */
Dwarf_Unsigned index,
/*Dwarf_Unsigned base_local_index, */
Dwarf_Small * lle_value_out,
Dwarf_Unsigned * rawval1,
Dwarf_Unsigned * rawval2,
Dwarf_Bool * debug_addr_unavailable,
Dwarf_Addr * lowpc_out, /* 'cooked' value */
Dwarf_Addr * hipc_out, /* 'cooked' value */
Dwarf_Unsigned * loclist_expr_op_count_out,
/* Returns pointer to the specific locdesc of the index; */
Dwarf_Unsigned * lle_bytecount,
Dwarf_Locdesc_c* locdesc_entry_out,
Dwarf_Small * loclist_source_out, /* 0,1, or 2 */
Dwarf_Unsigned * expression_offset_out,
Dwarf_Unsigned * locdesc_offset_out,
Dwarf_Error * error)
{
Dwarf_Locdesc_c descs_base = 0;
Dwarf_Locdesc_c desc = 0;
@ -1867,9 +1908,12 @@ dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head,
*debug_addr_unavailable = desc->ld_index_failed;
*loclist_expr_op_count_out = desc->ld_cents;
*locdesc_entry_out = desc;
*loclist_source_out = (Dwarf_Small)desc->ld_kind;
*loclist_source_out = (Dwarf_Small)desc->ld_lkind;
*expression_offset_out = desc->ld_section_offset;
*locdesc_offset_out = desc->ld_locdesc_offset;
if (lle_bytecount) {
*lle_bytecount = desc->ld_lle_bytecount;
}
return DW_DLV_OK;
}

View File

@ -44,60 +44,6 @@ struct Dwarf_Loc_Chain_s {
Dwarf_Loc_Chain lc_next;
};
/* Dwarf_Loclists_Context_s contains the data from
the .debug_loclists
section headers (if that section exists). Dwarf 2,3,4 .debug_loc
has no such data. The array (one of these per header in
.debug_loclists) is recorded in Dwarf_Debug. These
are filled in at startup at the same time .debug_info
is opened. Nothing of this struct is exposed to
libdwarf callers */
struct Dwarf_Loclists_Context_s {
Dwarf_Debug lc_dbg;
Dwarf_Unsigned lc_index; /* An index assigned by
libdwarf to each loclists context. Starting
with zero at the zero offset in .debug_loclists. */
/* Offset of the .debug_loclists header involved. */
Dwarf_Unsigned lc_header_offset;
Dwarf_Unsigned lc_length;
unsigned long lc_magic;
/* Many places in in libdwarf this is called length_size. */
Dwarf_Small lc_offset_size;
/* rc_extension_size is zero unless this is standard
DWARF3 and later 64bit dwarf using the extension mechanism.
64bit DWARF3 and later: rc_extension_size is 4.
64bit DWARF2 MIPS/IRIX: rc_extension_size is zero.
32bit DWARF: rc_extension_size is zero. */
Dwarf_Small lc_extension_size;
Dwarf_Small lc_address_size;
Dwarf_Small lc_segment_selector_size;
Dwarf_Half lc_version; /* 5 */
Dwarf_Unsigned lc_offset_entry_count;
/* offset in the section of the offset entries */
Dwarf_Unsigned lc_offsets_off_in_sect;
/* Do not free. Points into section memory */
Dwarf_Small * lc_offsets_array;
/* Offset in the .debug_loclists section of the
first loclist in the set of loclists for the
CU. */
Dwarf_Unsigned lc_first_loclist_offset;
Dwarf_Unsigned lc_past_last_loclist_offset;
/* pointer to 1st byte of loclist header*/
Dwarf_Small * lc_loclists_header;
/* pointer to first byte of the loclist data
for loclist involved. Do not free. */
Dwarf_Small *lc_startaddr;
/* pointer one past end of the loclist data. */
Dwarf_Small *lc_endaddr;
};
/* Contains info on an uninterpreted block of data,
the data is DWARF location expression operators. */
struct Dwarf_Block_c_s {
@ -170,13 +116,15 @@ struct Dwarf_Loc_Expr_Op_s {
Adds the DW_LLE value (new in DWARF5).
This struct is opaque. Not visible to callers. */
struct Dwarf_Locdesc_c_s {
Dwarf_Half ld_kind; /* DW_LKIND */
Dwarf_Half ld_lkind; /* DW_LKIND */
/* A DW_LLEX or DW_LLE value, real or synthesized */
Dwarf_Small ld_lle_value;
/* Failed means .debug_addr section needed but missing.
(possibly tied file needed) */
Dwarf_Bool ld_index_failed;
/* the length of data in this lle entry */
Dwarf_Unsigned ld_lle_bytecount;
unsigned long ld_magic;
/* Beginning of active range. This is actually an offset
@ -239,14 +187,14 @@ struct Dwarf_Loc_Head_c_s {
/* The CU Context of this loclist or locexpr. */
Dwarf_CU_Context ll_context;
/* DW_LKIND* */
Dwarf_Half ll_kind;
Dwarf_Half ll_lkind; /* DW_LKIND */
Dwarf_Debug ll_dbg;
unsigned long ll_magic;
/* If ll_kind == DW_LKIND_loclists the following
/* If ll_lkind == DW_LKIND_loclists the following
pointer is non-null and index is the index
of the localcontext */
Dwarf_Unsigned ll_index;
Dwarf_Unsigned ll_index;
Dwarf_Loclists_Context ll_localcontext;
/* rh_last and rh_first used during build-up.

View File

@ -50,6 +50,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "dwarf_util.h"
#include "dwarf_string.h"
#include "dwarf_loc.h"
#include "dwarf_loclists.h"
#define SIZEOFT8 1
#define SIZEOFT16 2
@ -61,18 +62,45 @@ static void
dump_bytes(const char *msg,Dwarf_Small * start, long len)
{
Dwarf_Small *end = start + len;
Dwarf_Unsigned max=16;
Dwarf_Unsigned ct=0;
Dwarf_Unsigned full=0;
Dwarf_Small *cur = start;
printf("%s (0x%lx) ",msg,(unsigned long)start);
for (; cur < end; cur++) {
printf("%s (0x%lx)\n",msg,(unsigned long)start);
for (; cur < end; cur++, ++full) {
if (!ct) {
printf("[0x%04lx] ",(unsigned long)full);
}
printf("%02x", *cur);
++ct;
if ( ct % 4 == 0) {
printf(" ");
}
if ( ct % max == 0) {
printf("\n");
ct = 0;
}
}
printf("\n");
}
#endif /*0*/
static void
free_loclists_context(Dwarf_Loclists_Context cx)
{
if (cx) {
free(cx->lc_offset_value_array);
cx->lc_offset_value_array = 0;
cx->lc_magic = 0;
free(cx);
}
}
/* Used in case of error reading the
loclists headers (not referring to Dwarf_Loc_Head_c
here), to clean up. */
here), to clean up. The chain is of
Dwarf_Loclists_Context items */
static void
free_loclists_chain(Dwarf_Debug dbg, Dwarf_Chain head)
{
@ -85,7 +113,9 @@ free_loclists_chain(Dwarf_Debug dbg, Dwarf_Chain head)
for ( ;cur; cur = next) {
next = cur->ch_next;
if (cur->ch_item) {
free(cur->ch_item);
Dwarf_Loclists_Context cx =
(Dwarf_Loclists_Context)cur->ch_item;
free_loclists_context(cx);
cur->ch_item = 0;
dwarf_dealloc(dbg,cur,DW_DLA_CHAIN);
}
@ -349,6 +379,7 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg,
Dwarf_Unsigned offset_entry_count = 0;
Dwarf_Unsigned localoff = 0;
Dwarf_Unsigned lists_len = 0;
Dwarf_Unsigned tabentrynum = 0;
READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned,
data,offset_size,exten_size,
@ -414,19 +445,55 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg,
READ_UNALIGNED_CK(dbg,segment_selector_size,unsigned,data,
SIZEOFT8,error,end_data);
buildhere->lc_segment_selector_size = segment_selector_size;
if (buildhere->lc_segment_selector_size) {
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"DW_DLE_LOCLISTS_ERROR: "
" The debug_loclists segment selector size is non-zero. "
"Not supported.");
return DW_DLV_ERROR;
}
data++;
READ_UNALIGNED_CK(dbg,offset_entry_count,Dwarf_Unsigned,data,
SIZEOFT32,error,end_data);
buildhere->lc_offset_entry_count = offset_entry_count;
data += SIZEOFT32;
if (offset_entry_count ){
buildhere->lc_offsets_array = data;
if (offset_entry_count >= (sectionlength/offset_size)) {
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"dbg,DW_DLE_LOCLISTS_ERROR: "
" The debug_loclists offset table entry "
"count exceeds the "
"section length, Corrupt dwarf");
return DW_DLV_ERROR;
}
localoff = data - startdata;
lists_len = offset_size *offset_entry_count;
if (offset_entry_count) {
buildhere->lc_offsets_array = data;
buildhere->lc_offset_value_array = (Dwarf_Unsigned *)
calloc(offset_entry_count, sizeof(Dwarf_Unsigned));
if (!buildhere->lc_offset_value_array) {
_dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL,
"dbg,DW_DLE_ALLOC_CAIL: "
" The debug_loclists offset table "
"cannot be allocated.");
return DW_DLV_ERROR;
}
for (tabentrynum = 0 ; tabentrynum < offset_entry_count;
data += SIZEOFT32,++tabentrynum ) {
Dwarf_Unsigned entry = 0;
int res = 0;
data += lists_len;
res = _dwarf_read_unaligned_ck_wrapper(dbg,
&entry,data,SIZEOFT32,end_data,error);
if (res != DW_DLV_OK) {
free(buildhere->lc_offset_value_array);
buildhere->lc_offset_value_array = 0;
return res;
}
buildhere->lc_offset_value_array[tabentrynum] = entry;
lists_len += SIZEOFT32;
}
} /* else no offset table */
buildhere->lc_offsets_off_in_sect = offset+localoff;
buildhere->lc_first_loclist_offset = offset+localoff+
@ -483,8 +550,9 @@ internal_load_loclists_contexts(Dwarf_Debug dbg,
data,end_data,offset,
newcontext,&nextoffset,error);
if (res == DW_DLV_ERROR) {
free(newcontext);
free_loclists_chain(dbg,head_chain);
free_loclists_context(newcontext);
newcontext = 0;
return DW_DLV_ERROR;
}
newcontext->lc_magic = LOCLISTS_MAGIC;
@ -495,7 +563,8 @@ internal_load_loclists_contexts(Dwarf_Debug dbg,
"DW_DLE_ALLOC_FAIL: allocating Loclists_Context"
" chain entry");
free_loclists_chain(dbg,head_chain);
free(newcontext);
free_loclists_context(newcontext);
newcontext = 0;
return DW_DLV_ERROR;
}
curr_chain->ch_item = newcontext;
@ -567,6 +636,11 @@ dwarf_load_loclists(Dwarf_Debug dbg,
return res;
}
}
/* cxt is set to a pointer to a context, which is
actually an array of pointers to such contexts, 'count'
of them. Each context has the loclists offset table
(if it has at least on entry in the table)
pointed in each cxt. */
res = internal_load_loclists_contexts(dbg,&cxt,&count,error);
if (res == DW_DLV_ERROR) {
return res;
@ -593,10 +667,7 @@ _dwarf_dealloc_loclists_context(Dwarf_Debug dbg)
loccon = dbg->de_loclists_context;
for ( ; i < dbg->de_loclists_context_count; ++i) {
Dwarf_Loclists_Context con = loccon[i];
con->lc_offsets_array = 0;
con->lc_offset_entry_count = 0;
con->lc_magic = 0;
free(con);
free_loclists_context(con);
loccon[i] = 0;
}
free(dbg->de_loclists_context);
@ -620,7 +691,6 @@ dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg,
CHECK_DBG(dbg,error,"dwarf_get_loclist_offset_index_value()");
if (!dbg->de_loclists_context_count) {
return DW_DLV_NO_ENTRY;
}
if (context_index >= dbg->de_loclists_context_count) {
return DW_DLV_NO_ENTRY;
@ -699,7 +769,7 @@ int dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c head,
"dwarf_get_loclist_head_basics()");
return DW_DLV_ERROR;
}
*lkind = (Dwarf_Small)head->ll_kind;
*lkind = (Dwarf_Small)head->ll_lkind;
*lle_count = head->ll_locdesc_count;
*lle_version = head->ll_cuversion;
*loclists_index_returned = head->ll_index;
@ -924,7 +994,6 @@ _dwarf_which_loclists_context(Dwarf_Debug dbg,
/* We have a DW_AT_loclists_base (lc_loclists_base),
let's use it. */
Dwarf_Unsigned lookfor = 0;;
lookfor = ctx->cc_loclists_base;
for ( i = 0 ; i < count; ++i) {
dwarfstring m;
@ -1003,6 +1072,33 @@ alloc_rle_and_append_to_list(Dwarf_Debug dbg,
return DW_DLV_OK;
}
static int
_dwarf_implicit_loclists_base(Dwarf_Debug dbg,
Dwarf_Unsigned indexval,
Dwarf_Unsigned *ibase)
{
Dwarf_Loclists_Context rctx = 0;
if (IS_INVALID_DBG(dbg)) {
return DW_DLV_NO_ENTRY;
}
if (!dbg->de_debug_loclists.dss_size) {
return DW_DLV_NO_ENTRY;
}
if (!dbg->de_loclists_context_count) {
return DW_DLV_NO_ENTRY;
}
/* This implicit base can only work if the 0-th
Rnglists_Context is appropriate here. */
rctx = dbg->de_loclists_context[0];
if (indexval > rctx->lc_offset_entry_count) {
/* We are not using base offset, we
will not see a DW_FORM_loclistx */
return DW_DLV_NO_ENTRY;
}
*ibase = rctx->lc_offsets_off_in_sect;
return DW_DLV_OK;
}
/* Read the group of loclists entries, and
finally build an array of Dwarf_Locdesc_c
records. Attach to rctx here.
@ -1052,19 +1148,21 @@ build_array_of_lle(Dwarf_Debug dbg,
}
eops.bl_len =opsblocksize;
eops.bl_data = ops;
eops.bl_kind = rctx->ll_kind;
eops.bl_kind = rctx->ll_lkind;
eops.bl_section_offset = opsoffset;
eops.bl_locdesc_offset = dataoffset;
e->ld_kind = rctx->ll_kind;
e->ld_lkind = rctx->ll_lkind;
e->ld_magic = LOCLISTS_MAGIC;
e->ld_lle_value = code,
e->ld_entrylen = entrylen;
e->ld_rawlow = val1;
e->ld_rawhigh = val2;
e->ld_opsblock = eops;
bytescounttotal += entrylen;
e->ld_lle_bytecount = entrylen;
data += entrylen;
bytescounttotal += entrylen;
if (code == DW_LLE_end_of_list) {
/* This terminates the entries for a loclist portion.*/
done = TRUE;
break;
}
@ -1135,61 +1233,84 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
Dwarf_Loclists_Context *array = 0;
Dwarf_Loclists_Context rctx = 0;
Dwarf_Unsigned entrycount = 0;
unsigned offsetsize = 0;
Dwarf_Unsigned lle_global_offset = 0;
unsigned offsetsize = 0;
Dwarf_Unsigned lle_global_offset = 0;
Dwarf_CU_Context ctx = 0;
Dwarf_Unsigned offset_in_loclists = 0;
Dwarf_Bool is_loclistx = FALSE;
int theform = llhead->ll_attrform;
Dwarf_Unsigned attr_val = 0;
Dwarf_Unsigned offset_in_loclists = 0;
Dwarf_Bool is_loclistx = FALSE;
Dwarf_Half theform = llhead->ll_attrform;
Dwarf_Bool loclists_base_present =
llhead->ll_at_loclists_base_present;
Dwarf_Unsigned loclists_base =
llhead->ll_at_loclists_base;
Dwarf_Unsigned attr_val = 0;
if (!attr) {
_dwarf_error_string(NULL, error,DW_DLE_DBG_NULL,
"DW_DLE_DBG_NULL "
"NULL attribute "
"argument passed to "
"_dwarf_loclists_fill_in_lle_head()");
return DW_DLV_ERROR;
}
ctx = attr->ar_cu_context;
array = dbg->de_loclists_context;
if ( theform == DW_FORM_sec_offset) {
/* DW_FORM_sec_offset is not formudata , often
seen in in DW5 DW_AT_location etc */
res = dwarf_global_formref(attr, &attr_val,error);
if (theform == DW_FORM_loclistx) {
Dwarf_Bool offset_is_info = 0;
is_loclistx = TRUE;
res = dwarf_global_formref_b(attr,
&attr_val, &offset_is_info, error);
if (res != DW_DLV_OK) {
return res;
}
offset_in_loclists = attr_val;
} else {
if (theform == DW_FORM_loclistx) {
is_loclistx = TRUE;
if (theform == DW_FORM_sec_offset) {
/* DW_FORM_sec_offset is not formudata , often
seen in in DW5 DW_AT_location etc */
res = dwarf_global_formref(attr, &attr_val,error);
if (res != DW_DLV_OK) {
return res;
}
}
res = dwarf_formudata(attr,&attr_val,error);
if (res != DW_DLV_OK) {
return res;
}
/* the context cc_loclists_base gives the offset
of the array. of offsets (if cc_loclists_base_present) */
offset_in_loclists = attr_val;
if (is_loclistx) {
if (ctx->cc_loclists_base_present) {
offset_in_loclists = ctx->cc_loclists_base;
} else if (dbg->de_loclists_context_count == 1) {
/* missing a DW_AT_loclists_base! */
offset_in_loclists = 0;
} else {
/* FIXME: check in tied file for a cc_loclists_base
possibly? Make any sense? */
}
if (is_loclistx) {
if (loclists_base_present) {
offset_in_loclists = loclists_base;
} else if (ctx->cc_is_dwo) {
/* missing a DW_AT_loclists_base! */
/* Generate a base and set as 'present'
by looking at the location offset
table that we are supposedly indexing into.
finding what the table value is.
An implicit loclists_base.
Will not work with multiple loclists! */
int ires = 0;
Dwarf_Unsigned ibase = 0;
ires = _dwarf_implicit_loclists_base(dbg,
attr_val,&ibase);
if (ires != DW_DLV_OK) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_LOCLISTS_ERROR: loclists table index of"
"DW_DLE_LOCLISTS_ERROR: loclists table"
" index of"
" %u" ,attr_val);
dwarfstring_append(&m,
" is unusable without a tied file."
);
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
" is unusable, there is no default "
" loclists base address ");
_dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
} else {
offset_in_loclists = attr_val;
ctx->cc_loclists_base_present = TRUE;
ctx->cc_loclists_base = ibase;
offset_in_loclists = ibase;
}
} else {
offset_in_loclists = attr_val;
}
res = _dwarf_which_loclists_context(dbg,ctx,
offset_in_loclists,
@ -1203,21 +1324,23 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
offsetsize = rctx->lc_offset_size;
enddata = rctx->lc_endaddr;
if (is_loclistx && attr_val >= entrycount) {
dwarfstring m;
if (is_loclistx) {
if (attr_val >= entrycount) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_LOCLISTS_ERROR: loclists table index of"
" %u" ,attr_val);
dwarfstring_append_printf_u(&m,
" too large for table of %u "
"entries.",entrycount);
_dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_LOCLISTS_ERROR: loclists table index of"
" %u" ,attr_val);
dwarfstring_append_printf_u(&m,
" too large for table of %u "
"entries.",entrycount);
_dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
}
llhead->ll_localcontext = rctx;
llhead->ll_index = loclists_contextnum;
@ -1253,7 +1376,7 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
return DW_DLV_OK;
}
#if 0 /* candiate??? for public api */
#if 0 /* candiate??? for public api. No, not usable. */
int
dwarf_get_loclists_entry_fields(
Dwarf_Loc_Head_c head,
@ -1264,6 +1387,7 @@ dwarf_get_loclists_entry_fields(
Dwarf_Unsigned *raw2,
Dwarf_Unsigned *cooked1,
Dwarf_Unsigned *cooked2,
Dwarf_Unsigned *lle_bytesize;
/* FIXME not right for loclists or their loc exprs */
Dwarf_Error *error)
{
@ -1284,6 +1408,7 @@ dwarf_get_loclists_entry_fields(
e = head->ll_locdesc + entrynum;
*entrylen = e->ld_entrylen;
*code = e->ld_lle_value;
*lle_bytesize = e->ld_lle_value /* bogus */;
*raw1 = e->ld_rawlow;
*raw2 = e->ld_rawhigh;
*cooked1 = e->ld_lopc;

86
src/lib/libdwarf/dwarf_loclists.h vendored Normal file
View File

@ -0,0 +1,86 @@
/*
Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Rese rved.
Portions Copyright (C) 2015-2023 David Anderson. All Rights Rese rved.
This program is free software; you can redistribute it
and/or modify it under the terms of version 2.1 of the
GNU Lesser General Public License as published by the Free
Software Foundation.
This program is distributed in the hope that it would be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
Further, this software is distributed without any warranty
that it is free of the rightful claim of any third person
regarding infringement or the like. Any license provided
herein, whether implied or otherwise, applies only to this
software file. Patent licenses, if any, provided herein
do not apply to combinations of this program with other
software, or any other product whatsoever.
You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write the
Free Software Foundation, Inc., 51 Franklin Street - Fifth
Floor, Boston MA 02110-1301, USA.
*/
/* Dwarf_Loclists_Context_s contains the data from
the .debug_loclists
section headers (if that section exists). Dwarf 2,3,4 .debug_loc
has no such data. The array (one of these per header in
.debug_loclists) is recorded in Dwarf_Debug. These
are filled in at startup at the same time .debug_info
is opened. Nothing of this struct is exposed to
libdwarf callers */
struct Dwarf_Loclists_Context_s {
Dwarf_Debug lc_dbg;
Dwarf_Unsigned lc_index; /* An index assigned by
libdwarf to each loclists context. Starting
with zero at the zero offset in .debug_loclists. */
/* Offset of the .debug_loclists header involved. */
Dwarf_Unsigned lc_header_offset;
Dwarf_Unsigned lc_length;
unsigned long lc_magic;
/* Many places in in libdwarf this is called length_size. */
Dwarf_Small lc_offset_size;
/* rc_extension_size is zero unless this is standard
DWARF3 and later 64bit dwarf using the extension mechanism.
64bit DWARF3 and later: rc_extension_size is 4.
64bit DWARF2 MIPS/IRIX: rc_extension_size is zero.
32bit DWARF: rc_extension_size is zero. */
Dwarf_Small lc_extension_size;
Dwarf_Small lc_address_size;
Dwarf_Small lc_segment_selector_size;
Dwarf_Half lc_version; /* 5 */
Dwarf_Unsigned lc_offset_entry_count;
/* lc_offset_entry_count values. Each local offset to
a locdesc set. We need this as a way to know
which lle entry offsets are relevant from a loclistx.
as nothing else reveals these special LLE entries. */
Dwarf_Unsigned *lc_offset_value_array;
/* offset in the section of the offset entries */
Dwarf_Unsigned lc_offsets_off_in_sect;
/* Do not free. Points into section memory */
Dwarf_Small * lc_offsets_array;
/* Offset in the .debug_loclists section of the
first loclist in the set of loclists for the
CU. */
Dwarf_Unsigned lc_first_loclist_offset;
Dwarf_Unsigned lc_past_last_loclist_offset;
/* pointer to 1st byte of loclist header*/
Dwarf_Small * lc_loclists_header;
/* pointer to first byte of the loclist data
for loclist involved. Do not free. */
Dwarf_Small *lc_startaddr;
/* pointer one past end of the loclist data. */
Dwarf_Small *lc_endaddr;
};

View File

@ -44,17 +44,19 @@ extern "C" {
#endif /* __cplusplus */
#if 0 /* Not used here. DavidA. September 2018 */
#include changed to #xnclude so casual readers will not
be confused.
/*
* This file describes the format of mach object files.
*/
#include <stdint.h>
#xnclude <stdint.h>
/*
* <mach/machine.h> 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 <mach/machine.h>
#xnclude <mach/machine.h>
/*
* <mach/vm_prot.h> is needed here for the
@ -62,15 +64,15 @@ extern "C" {
* constants that are or'ed together for the
* possible values of this type.
*/
#include <mach/vm_prot.h>
#xnclude <mach/vm_prot.h>
/*
* <machine/thread_status.h> is expected to define
* the flavors of the thread
* states and the structures of those flavors for each machine.
*/
#include <mach/machine/thread_status.h>
#include <architecture/byte_order.h>
#xnclude <mach/machine/thread_status.h>
#xnclude <architecture/byte_order.h>
#endif /* 0 */
#ifndef TYP

View File

@ -1,5 +1,5 @@
/* Generated routines, do not edit. */
/* Generated for source version 0.9.2 */
/* Generated for source version 0.9.3 */
/* BEGIN FILE */
@ -226,11 +226,11 @@ dwarf_get_TAG_name (unsigned int val,
case DW_TAG_immutable_type:
*s_out = "DW_TAG_immutable_type";
return DW_DLV_OK;
case DW_TAG_lo_user:
*s_out = "DW_TAG_lo_user";
case DW_TAG_TI_far_type:
*s_out = "DW_TAG_TI_far_type";
return DW_DLV_OK;
/* Skipping alternate spelling of value
0x4080. DW_TAG_TI_far_type */
0x4080. DW_TAG_lo_user */
case DW_TAG_MIPS_loop:
*s_out = "DW_TAG_MIPS_loop";
return DW_DLV_OK;
@ -956,10 +956,10 @@ dwarf_get_AT_name (unsigned int val,
case DW_AT_HP_block_index:
*s_out = "DW_AT_HP_block_index";
return DW_DLV_OK;
/* Skipping alternate spelling of value
0x2000. DW_AT_TI_veneer */
/* Skipping alternate spelling of value
0x2000. DW_AT_lo_user */
/* Skipping alternate spelling of value
0x2000. DW_AT_TI_veneer */
case DW_AT_MIPS_fde:
*s_out = "DW_AT_MIPS_fde";
return DW_DLV_OK;
@ -1534,6 +1534,9 @@ dwarf_get_AT_name (unsigned int val,
case DW_AT_APPLE_sdk:
*s_out = "DW_AT_APPLE_sdk";
return DW_DLV_OK;
case DW_AT_APPLE_origin:
*s_out = "DW_AT_APPLE_origin";
return DW_DLV_OK;
case DW_AT_hi_user:
*s_out = "DW_AT_hi_user";
return DW_DLV_OK;
@ -2873,6 +2876,12 @@ dwarf_get_LANG_name (unsigned int val,
case DW_LANG_Ruby:
*s_out = "DW_LANG_Ruby";
return DW_DLV_OK;
case DW_LANG_Move:
*s_out = "DW_LANG_Move";
return DW_DLV_OK;
case DW_LANG_Hylo:
*s_out = "DW_LANG_Hylo";
return DW_DLV_OK;
case DW_LANG_lo_user:
*s_out = "DW_LANG_lo_user";
return DW_DLV_OK;
@ -2944,11 +2953,11 @@ dwarf_get_CC_name (unsigned int val,
case DW_CC_pass_by_value:
*s_out = "DW_CC_pass_by_value";
return DW_DLV_OK;
case DW_CC_lo_user:
*s_out = "DW_CC_lo_user";
case DW_CC_GNU_renesas_sh:
*s_out = "DW_CC_GNU_renesas_sh";
return DW_DLV_OK;
/* Skipping alternate spelling of value
0x40. DW_CC_GNU_renesas_sh */
0x40. DW_CC_lo_user */
case DW_CC_GNU_borland_fastcall_i386:
*s_out = "DW_CC_GNU_borland_fastcall_i386";
return DW_DLV_OK;
@ -3420,11 +3429,11 @@ dwarf_get_CFA_name (unsigned int val,
case DW_CFA_val_expression:
*s_out = "DW_CFA_val_expression";
return DW_DLV_OK;
case DW_CFA_lo_user:
*s_out = "DW_CFA_lo_user";
case DW_CFA_TI_soffset_extended:
*s_out = "DW_CFA_TI_soffset_extended";
return DW_DLV_OK;
/* Skipping alternate spelling of value
0x1c. DW_CFA_TI_soffset_extended */
0x1c. DW_CFA_lo_user */
/* Skipping alternate spelling of value
0x1c. DW_CFA_low_user */
case DW_CFA_MIPS_advance_loc8:

View File

@ -307,14 +307,14 @@ struct Dwarf_CU_Context_s {
Dwarf_Bool cc_macro_header_length_present;
/* DW_SECT_RNGLISTS */
Dwarf_Unsigned cc_rnglists_base; /*DW5 */
Dwarf_Unsigned cc_rnglists_base_contr_size; /*DW5 */
/* DW_AT_GNU_ranges_base was a GNU extension that appeared
but was unused. See dwarf_die_deliv.c for details. */
Dwarf_Unsigned cc_ranges_base;
/* DW_AT_GNU_ranges_base is a GNU extension, DW4 */
Dwarf_Bool cc_ranges_base_present;
/* .debug_rnglists */
Dwarf_Unsigned cc_rnglists_base; /*DW5 */
Dwarf_Unsigned cc_rnglists_base_contr_size; /*DW5 */
Dwarf_Bool cc_rnglists_base_present; /* DW5 */
Dwarf_Bool cc_rnglists_header_length_present;
@ -826,6 +826,17 @@ struct Dwarf_Debug_s {
file is sometimes needed
and referenced.*/
struct Dwarf_Tied_Data_s de_tied_data;
/* The following two are used to detect a DWARF4
.debug_addr (a GNU extension) and attempt
to print a raw .debug_addr section. Simply
assuming the first CU seen values for these
work for everything in the GNU extenstion
.debug_addr section. Only needed if the version
here is 4 (DWARF4). */
Dwarf_Half de_debug_addr_version;
Dwarf_Half de_debug_addr_offset_size;
Dwarf_Half de_debug_addr_address_size;
};
/* New style. takes advantage of dwarfstrings capability.

View File

@ -560,23 +560,23 @@ _dwarf_pe_load_dwarf_section_headers(
Dwarf_Unsigned limit = 100*pep->pe_filesize;
if (limit < pep->pe_filesize) {
/* An overflow. Bad. */
*errcode = DW_DLE_PE_SECTION_SIZE_ERROR;
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
return DW_DLV_ERROR;
}
if (sec_outp->VirtualSize >
((Dwarf_Unsigned)200*
((Dwarf_Unsigned)2000*
(Dwarf_Unsigned)1000*
(Dwarf_Unsigned)1000)) {
/* Likely totally unreasonable.
/* Likely unreasonable.
the hard limit written this way
simply for clarity.
Hard to know what to set it to. */
*errcode = DW_DLE_PE_SECTION_SIZE_ERROR;
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
return DW_DLV_ERROR;
}
if (sec_outp->VirtualSize > limit) {
/* Likely totally unreasonable. Bad. */
*errcode = DW_DLE_PE_SECTION_SIZE_ERROR;
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
return DW_DLV_ERROR;
}
}

View File

@ -1283,18 +1283,6 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg,
context-> cc_addr_base=
tiedcontext->cc_addr_base;
}
if (!context->cc_rnglists_base_present) {
context-> cc_rnglists_base_present =
tiedcontext->cc_rnglists_base_present;
context-> cc_rnglists_base=
tiedcontext->cc_rnglists_base;
}
if (!context->cc_loclists_base_present) {
context-> cc_loclists_base_present =
tiedcontext->cc_loclists_base_present;
context-> cc_loclists_base=
tiedcontext->cc_loclists_base;
}
if (!context->cc_str_offsets_tab_present) {
context-> cc_str_offsets_tab_present =
tiedcontext->cc_str_offsets_tab_present;
@ -1309,15 +1297,6 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg,
context-> cc_str_offsets_offset_size=
tiedcontext->cc_str_offsets_offset_size;
}
/* GNU DW4 extension. */
if (!context-> cc_ranges_base_present) {
context-> cc_ranges_base_present =
tiedcontext->cc_ranges_base_present;
context-> cc_ranges_base =
tiedcontext->cc_ranges_base;
}
if (tiedcontext_out) {
*tiedcontext_out = tiedcontext;
}

View File

@ -77,23 +77,92 @@ dump_rh(const char *msg,
{
printf("Rnglists_Head: %s line %d\n",
msg,line);
printf(" count of entries: "
printf(" count of entries: %"
DW_PR_DUu
" (0x%" DW_PR_DUx ")\n",
head->rh_count,head->rh_count);
printf(" rh_rnglists : %p\n",(void *)) head->rh_rnglists);
if (head->rh_first) {
printf(" rh_first : %" DW_PR_DUu "\n", head->rh_first);
if (head->rh_last) {
printf(" rh_last : %" DW_PR_DUu "\n",head->rh_last);
}
printf(" rh_bytes total : %" DW_PR_DUu
" (0x%" DW_PR_DUx ")\n",head->rh_bytes_total,
head->rh_bytes_total);
printf(" rh__offset_size : %p\n",
(void *) head->rh_offset_size);
printf(" rh_rnglists : %p\n",(void *) head->rh_rnglists);
printf(" rh_index : %lu\n",
(unsigned long)head->rh_index);
printf(" rh_first : %lu\n",
(unsigned long)head->rh_first);
printf(" rh_last : %lu\n",
(unsigned long)head->rh_last);
printf(" rh_bytes total : %lu (0x%lx)\n",
(unsigned long)head->rh_bytes_total,
(unsigned long)head->rh_bytes_total);
printf(" CU Context : %p",(void *)head->rh_context);
printf(" Rnglists Context: %p",(void *)head->rh_localcontext);
}
#endif
#if 0
static void
dump_rc(const char *msg,
int line,
Dwarf_Rnglists_Context rc)
{
printf("Rnglists_Context %s line %d index %lu\n", msg,
line,
(unsigned long)rc->rc_index);
printf(" rc_header_offset 0x%lx\n",
(unsigned long)rc->rc_header_offset);
printf(" rc_length 0x%lx\n",
(unsigned long)rc->rc_length);
printf(" rc_offset_size 0x%lu\n",
(unsigned long)rc->rc_offset_size);
printf(" rc_version 0x%lu\n",
(unsigned long)rc->rc_version);
printf(" rc_address_size 0x%lu\n",
(unsigned long)rc->rc_address_size);
printf(" rc_address_size 0x%lu\n",
(unsigned long)rc->rc_address_size);
printf(" rc_offset_entry_count 0x%lu\n",
(unsigned long)rc->rc_offset_entry_count);
printf(" rc_offsets_off_in_sect 0x%lu\n",
(unsigned long)rc->rc_offsets_off_in_sect);
printf(" rc_first_rnglist_offset 0x%lx\n",
(unsigned long)rc->rc_first_rnglist_offset);
printf(" rc_past_last_rnglist_offset 0x%lx\n",
(unsigned long)rc->rc_past_last_rnglist_offset);
}
#endif
/* The DWARF5 standard does not make it clear that
there should be a rnglists_base even in a dwp object.
Table F.1 implies such is not needed.
gcc seems to leave it off in the dwp.
ibase is an offset in the array of offsets in a rnglist,
which only makes sense for DW_FORM_rnglistx and
in that case there is no base.
We are dealing with DW_FORM_rnglistx */
static int
_dwarf_implicit_rnglists_base(Dwarf_Debug dbg,
Dwarf_Unsigned indexval,
Dwarf_Unsigned *ibase)
{
Dwarf_Rnglists_Context rctx = 0;
if (IS_INVALID_DBG(dbg)) {
return DW_DLV_NO_ENTRY;
}
if (!dbg->de_debug_rnglists.dss_size) {
return DW_DLV_NO_ENTRY;
}
if (!dbg->de_rnglists_context_count) {
return DW_DLV_NO_ENTRY;
}
/* This implicit base can only work if the 0-th
Rnglists_Context is appropriate here. */
rctx = dbg->de_rnglists_context[0];
if (indexval > rctx->rc_offset_entry_count) {
/* We are not using base offset, we
will not see a DW_FORM_rnglistx */
return DW_DLV_NO_ENTRY;
}
*ibase = rctx->rc_offsets_off_in_sect;
return DW_DLV_OK;
}
/* Used in case of error reading the
rnglists headers (not referring to Dwarf_Rnglists_Head
@ -110,6 +179,7 @@ free_rnglists_chain(Dwarf_Debug dbg, Dwarf_Chain head)
for ( ;cur; cur = next) {
next = cur->ch_next;
if (cur->ch_item) {
/* ch_item is Dwarf_Rnglists_Context */
free(cur->ch_item);
cur->ch_item = 0;
dwarf_dealloc(dbg,cur,DW_DLA_CHAIN);
@ -350,7 +420,6 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
buildhere->rc_version = (Dwarf_Half)version;
data += SIZEOFT16;
localoff += SIZEOFT16;
READ_UNALIGNED_CK(dbg,address_size,unsigned,data,
SIZEOFT8,error,end_data);
if (address_size != 4 && address_size != 8 &&
@ -408,7 +477,6 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
if (offset_entry_count ){
buildhere->rc_offsets_array = data;
}
lists_len = offset_size *offset_entry_count;
if (offset_entry_count >= secsize_dbg ||
lists_len >= secsize_dbg) {
@ -1050,7 +1118,8 @@ dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head h)
return;
}
/* Caller will eventually free as appropriate. */
/* Appends to singly-linked list.
Caller will eventually free as appropriate. */
static int
alloc_rle_and_append_to_list(Dwarf_Debug dbg,
Dwarf_Rnglists_Head rctx,
@ -1088,24 +1157,24 @@ alloc_rle_and_append_to_list(Dwarf_Debug dbg,
in case we return DW_DLV_ERROR*/
static int
build_array_of_rle(Dwarf_Debug dbg,
Dwarf_Rnglists_Head rctx,
Dwarf_Rnglists_Head rhd,
Dwarf_Error *error)
{
int res = 0;
Dwarf_Small * data = rctx->rh_rlepointer;
Dwarf_Unsigned dataoffset = rctx->rh_rlearea_offset;
Dwarf_Small *enddata = rctx->rh_end_data_area;
unsigned address_size = (unsigned int)rctx->rh_address_size;
Dwarf_Small * data = rhd->rh_rlepointer;
Dwarf_Unsigned dataoffset = rhd->rh_rlearea_offset;
Dwarf_Small *enddata = rhd->rh_end_data_area;
unsigned address_size = (unsigned int)rhd->rh_address_size;
Dwarf_Unsigned bytescounttotal= 0;
Dwarf_Unsigned latestbaseaddr = 0;
Dwarf_Bool foundbaseaddr = FALSE;
int done = FALSE;
Dwarf_Bool no_debug_addr_available = FALSE;
if (rctx->rh_cu_base_address_present) {
if (rhd->rh_cu_base_address_present) {
/* The CU DIE had DW_AT_low_pc
and it is a base address. */
latestbaseaddr = rctx->rh_cu_base_address;
latestbaseaddr = rhd->rh_cu_base_address;
foundbaseaddr = TRUE;
}
for ( ; !done ; ) {
@ -1124,7 +1193,7 @@ build_array_of_rle(Dwarf_Debug dbg,
if (res != DW_DLV_OK) {
return res;
}
res = alloc_rle_and_append_to_list(dbg,rctx,&e,error);
res = alloc_rle_and_append_to_list(dbg,rhd,&e,error);
if (res != DW_DLV_OK) {
return res;
}
@ -1144,7 +1213,7 @@ build_array_of_rle(Dwarf_Debug dbg,
res = DW_DLV_NO_ENTRY;
} else {
res = _dwarf_look_in_local_and_tied_by_index(
dbg,rctx->rh_context,val1,&addr1,
dbg,rhd->rh_context,val1,&addr1,
error);
}
if (res != DW_DLV_OK) {
@ -1152,6 +1221,10 @@ build_array_of_rle(Dwarf_Debug dbg,
e->rle_index_failed = TRUE;
e->rle_cooked1 = 0;
foundbaseaddr = FALSE;
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dbg,*error);
*error = 0;
}
} else {
foundbaseaddr = TRUE;
e->rle_cooked1 = addr1;
@ -1163,13 +1236,17 @@ build_array_of_rle(Dwarf_Debug dbg,
res = DW_DLV_NO_ENTRY;
} else {
res = _dwarf_look_in_local_and_tied_by_index(
dbg,rctx->rh_context,val1,&addr1,
dbg,rhd->rh_context,val1,&addr1,
error);
}
if (res != DW_DLV_OK) {
no_debug_addr_available = TRUE;
e->rle_index_failed = TRUE;
e->rle_cooked1 = 0;
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dbg,*error);
*error = 0;
}
} else {
e->rle_cooked1 = addr1;
}
@ -1177,14 +1254,17 @@ build_array_of_rle(Dwarf_Debug dbg,
res = DW_DLV_NO_ENTRY;
} else {
res = _dwarf_look_in_local_and_tied_by_index(
dbg,rctx->rh_context,val2,&addr2,
dbg,rhd->rh_context,val2,&addr2,
error);
}
if (res != DW_DLV_OK) {
no_debug_addr_available = TRUE;
e->rle_index_failed = TRUE;
e->rle_cooked2 = 0;
return res;
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dbg,*error);
*error = 0;
}
} else {
e->rle_cooked2 = addr2;
}
@ -1194,7 +1274,7 @@ build_array_of_rle(Dwarf_Debug dbg,
res = DW_DLV_NO_ENTRY;
} else {
res = _dwarf_look_in_local_and_tied_by_index(
dbg,rctx->rh_context,val1,&addr1,
dbg,rhd->rh_context,val1,&addr1,
error);
}
if (res != DW_DLV_OK) {
@ -1202,8 +1282,10 @@ build_array_of_rle(Dwarf_Debug dbg,
e->rle_index_failed = TRUE;
e->rle_cooked2 = 0;
e->rle_cooked1 = 0;
return res;
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dbg,*error);
*error = 0;
}
} else {
e->rle_cooked1 = addr1;
e->rle_cooked2 = val2+addr1;
@ -1251,14 +1333,14 @@ build_array_of_rle(Dwarf_Debug dbg,
}
}
}
if (rctx->rh_count > 0) {
if (rhd->rh_count > 0) {
Dwarf_Rnglists_Entry* array = 0;
Dwarf_Rnglists_Entry cur = 0;
Dwarf_Unsigned i = 0;
/* Creating an array of pointers. */
array = (Dwarf_Rnglists_Entry*)malloc(
rctx->rh_count *sizeof(Dwarf_Rnglists_Entry));
rhd->rh_count *sizeof(Dwarf_Rnglists_Entry));
if (!array) {
_dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
"DW_DLE_ALLOC_FAIL: Out of memory in "
@ -1266,16 +1348,16 @@ build_array_of_rle(Dwarf_Debug dbg,
"into a pointer array");
return DW_DLV_ERROR;
}
cur = rctx->rh_first;
for ( ; i < rctx->rh_count; ++i) {
cur = rhd->rh_first;
for ( ; i < rhd->rh_count; ++i) {
array[i] = cur;
cur = cur->rle_next;
}
rctx->rh_rnglists = array;
rctx->rh_first = 0;
rctx->rh_last = 0;
rhd->rh_rnglists = array;
rhd->rh_first = 0;
rhd->rh_last = 0;
}
rctx->rh_bytes_total = bytescounttotal;
rhd->rh_bytes_total = bytescounttotal;
return DW_DLV_OK;
}
@ -1288,7 +1370,10 @@ dwarf_rnglists_get_rle_head(
Dwarf_Half theform,
/* attr_val is either an offset
(theform == DW_FORM_sec_offset)
or an index DW_FORM_rnglistx. */
to a specific rangelist entry set or
or a rnglistx index DW_FORM_rnglistx
at that index is the local offset of
a specific rangelist entry set. */
Dwarf_Unsigned attr_val,
Dwarf_Rnglists_Head *head_out,
Dwarf_Unsigned *entries_count_out,
@ -1325,33 +1410,50 @@ dwarf_rnglists_get_rle_head(
dbg = ctx->cc_dbg;
CHECK_DBG(dbg,error,
"dwarf_rnglists_get_rle_head() via attribute");
array = dbg->de_rnglists_context;
if (theform == DW_FORM_rnglistx) {
is_rnglistx = TRUE;
}
/* ASSERT: the 3 pointers just set are non-null */
/* the context cc_rnglists_base gives the offset
of the array. of offsets (if cc_rnglists_base_present) */
offset_in_rnglists = attr_val;
offset_in_rnglists = attr_val;
if (is_rnglistx) {
if (ctx->cc_rnglists_base_present) {
offset_in_rnglists = ctx->cc_rnglists_base;
} else if (ctx->cc_is_dwo) {
/* Generate a base and set as 'present'
by looking at the location offset
table that we are supposedly indexing into.
finding what the table value is.
An implicit rnglists_base.
Will not work with multiple rnglists! */
int ires = 0;
Dwarf_Unsigned ibase = 0;
ires = _dwarf_implicit_rnglists_base(dbg,
attr_val,&ibase);
if (ires != DW_DLV_OK) {
dwarfstring m;
} else {
/* FIXME: check in tied file for a cc_rnglists_base */
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_RNGLISTS_ERROR: rnglists table index of"
" %u" ,attr_val);
dwarfstring_append(&m,
" is unusable unless it is in a tied file."
" Possibly libdwarf is incomplete.FIXME");
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_RNGLISTS_ERROR: rnglists table"
" index of"
" %u" ,attr_val);
dwarfstring_append(&m,
" is unusable, there is no default "
" rnglists base address ");
_dwarf_error_string(dbg,error,
DW_DLE_RNGLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
ctx->cc_rnglists_base_present = TRUE;
ctx->cc_rnglists_base = ibase;
offset_in_rnglists = ibase;
}
} else {
offset_in_rnglists = attr_val;

View File

@ -63,6 +63,13 @@ struct Dwarf_Rnglists_Context_s {
unsigned rc_version; /* 5 */
Dwarf_Small rc_address_size;
Dwarf_Small rc_segment_selector_size;
/* The next three are the table of offsets.
used by DW_FORM_rnglistx.
The count may be zero if no DW_FORM_rnglistx.
If they exist the
index values in the array are offsets into area starting
with rc_first_rnglist_offset */
Dwarf_Unsigned rc_offset_entry_count;
/* offset in the section of the offset entries */
@ -70,8 +77,12 @@ struct Dwarf_Rnglists_Context_s {
/* Do not free. Points into section memory */
Dwarf_Small * rc_offsets_array;
/* End table of offsets */
/* Offset in the .debug_rnglists section of the
/* Now to the rnglists. If DW_AT_ranges FORM is
DW_FORM_sec_offset those offsets are inside
here.
Offset in the .debug_rnglists section of the
first rangelist in the set of rangelists for the
CU. */
Dwarf_Unsigned rc_first_rnglist_offset;

View File

@ -49,6 +49,7 @@
#include "dwarf_tsearch.h"
#include "dwarf_tied_decls.h"
#if 0
void
_dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno)
{
@ -62,6 +63,7 @@ _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno)
}
printf(" line %d\n",lineno);
}
#endif
void *
_dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val)
@ -129,6 +131,7 @@ _dwarf_tied_destroy_free_node(void*nodep)
static int
_dwarf_loop_reading_debug_info_for_cu(
Dwarf_Debug tieddbg,
struct Dwarf_Tied_Entry_s *targsig,
Dwarf_Error *error)
{
/* We will not find tied signatures
@ -207,11 +210,17 @@ _dwarf_loop_reading_debug_info_for_cu(
*(struct Dwarf_Tied_Data_s**) retval;
if (retent == entry) {
/* we added a record. */
return DW_DLV_OK;
int res = _dwarf_tied_compare_function(
targsig,entry);
if (!res) {
/* Found match, stop looping */
return DW_DLV_OK;
}
continue;
} else {
/* found existing, no add */
free(entry);
return DW_DLV_OK;
continue;
}
}
}
@ -253,14 +262,14 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg,
*context_out = e2->dt_context;
return DW_DLV_OK;
}
/* We now ensure all tieddbg CUs signatures
are in the td_tied_search,
The caller is NOT doing
info section read operations
on the tieddbg in this (tied)dbg, so it
cannot goof up their _dwarf_next_cu_header*(). */
res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,error);
res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,&entry,
error);
if (res == DW_DLV_ERROR) {
return res;
}

View File

@ -30,8 +30,6 @@ Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved
*/
#include "dwarf_base_types.h"
void
_dwarf_create_area_len_error(Dwarf_Debug dbg, Dwarf_Error *error,
Dwarf_Unsigned targ, Dwarf_Unsigned sectionlen);

View File

@ -99,10 +99,10 @@ extern "C" {
*/
/* Semantic Version identity for this libdwarf.h */
#define DW_LIBDWARF_VERSION "0.9.2"
#define DW_LIBDWARF_VERSION "0.10.1"
#define DW_LIBDWARF_VERSION_MAJOR 0
#define DW_LIBDWARF_VERSION_MINOR 9
#define DW_LIBDWARF_VERSION_MICRO 2
#define DW_LIBDWARF_VERSION_MINOR 10
#define DW_LIBDWARF_VERSION_MICRO 1
#define DW_PATHSOURCE_unspecified 0
#define DW_PATHSOURCE_basic 1
@ -1459,9 +1459,10 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head;
#define DW_DLE_ARITHMETIC_OVERFLOW 501
#define DW_DLE_UNIVERSAL_BINARY_ERROR 502
#define DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR 503
#define DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL 504
/*! @note DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
#define DW_DLE_LAST 503
#define DW_DLE_LAST 504
#define DW_DLE_LO_USER 0x10000
/*! @} */
@ -4578,7 +4579,7 @@ DW_API int dwarf_get_loclist_head_kind(
unsigned int * dw_lkind,
Dwarf_Error * dw_error);
/*! @brief Retrieve the details of a location expression
/*! @brief Retrieve the details(_d) of a location expression
Cooked value means the addresses from the location
description after base values applied, so they
@ -4647,6 +4648,41 @@ DW_API int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c dw_loclist_head,
Dwarf_Unsigned * dw_locdesc_offset_out,
Dwarf_Error * dw_error);
/*! @brief Retrieve the details(_e) of a location expression
Cooked value means the addresses from the location
description after base values applied, so they
are actual addresses.
debug_addr_unavailable non-zero means the record from a
Split Dwarf skeleton unit could not be accessed from
the .dwo section or dwp object so the
cooked values could not be calculated.
This is identical to dwarf_get_locdesc_entry_d except
that it adds a pointer argument so the caller can know
the size, in bytes, of the loclist DW_LLE operation
itself.
It's used by dwarfdump but it is unlikely to be of interest
to most callers..
*/
DW_API int dwarf_get_locdesc_entry_e(Dwarf_Loc_Head_c dw_loclist_head,
Dwarf_Unsigned dw_index,
Dwarf_Small * dw_lle_value_out,
Dwarf_Unsigned * dw_rawlowpc,
Dwarf_Unsigned * dw_rawhipc,
Dwarf_Bool * dw_debug_addr_unavailable,
Dwarf_Addr * dw_lowpc_cooked,
Dwarf_Addr * dw_hipc_cooked,
Dwarf_Unsigned * dw_locexpr_op_count_out,
Dwarf_Unsigned * dw_lle_bytecount,
Dwarf_Locdesc_c * dw_locentry_out,
Dwarf_Small * dw_loclist_source_out,
Dwarf_Unsigned * dw_expression_offset_out,
Dwarf_Unsigned * dw_locdesc_offset_out,
Dwarf_Error * dw_error);
/*! @brief Get the raw values from a single location operation
@param dw_locdesc
@ -4921,8 +4957,12 @@ DW_API int dwarf_get_loclist_lle( Dwarf_Debug dw_dbg,
immediate interest.
It is only intended to enable printing of the
simple .debug_addr section (by dwarfdump).
Not at all clear it is of any other use.
simple DWARF5 .debug_addr section (by dwarfdump).
When emitting DWARF4, gcc may emit a GNU-specified
.debug_addr format. If some CU has been opened then
this call will work, but the single table
will have all the entries for all CUs.
@param dw_dbg
The Dwarf_Debug of interest.

View File

@ -6,7 +6,7 @@ includedir="${prefix}/include"
Name: libdwarf
Description: DWARF debug symbols library
Version: @PACKAGE_VERSION@
Version: @PROJECT_VERSION@
Libs: -L${libdir} -ldwarf
Cflags: -I${includedir}