Bump to v0.11.1

This commit is contained in:
Jeremy Rifkin 2024-12-03 23:07:45 -06:00
parent 97fd68c602
commit fe09ca800b
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
36 changed files with 1537 additions and 877 deletions

11
CMakeLists.txt vendored
View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
project(libdwarf VERSION 0.11.0 project(libdwarf VERSION 0.11.1
DESCRIPTION "Library to access DWARF debugging information" DESCRIPTION "Library to access DWARF debugging information"
HOMEPAGE_URL "https://github.com/davea42/libdwarf-code.git" HOMEPAGE_URL "https://github.com/davea42/libdwarf-code.git"
LANGUAGES C CXX) LANGUAGES C CXX)
@ -183,7 +183,9 @@ else()
message(STATUS "intptr_t value considered NO ") message(STATUS "intptr_t value considered NO ")
endif() endif()
message(STATUS "ENABLE_DECOMPRESSION : " ${ENABLE_DECOMPRESSION})
if (ENABLE_DECOMPRESSION) if (ENABLE_DECOMPRESSION)
#message(STATUS "In ENABLE_DECOMPRESSION setup: TRUE")
# Zlib and ZSTD need to be found otherwise disable it # Zlib and ZSTD need to be found otherwise disable it
if(NOT TARGET ZLIB::ZLIB) if(NOT TARGET ZLIB::ZLIB)
find_package(ZLIB) find_package(ZLIB)
@ -226,9 +228,14 @@ if (ENABLE_DECOMPRESSION)
set(HAVE_ZSTD_H TRUE) set(HAVE_ZSTD_H TRUE)
set(BUILT_WITH_ZLIB_AND_ZSTD TRUE) set(BUILT_WITH_ZLIB_AND_ZSTD TRUE)
endif() endif()
message(STATUS "Found libzstd : ${zstd_FOUND}")
message(STATUS "Found zlib : ${ZLIB_FOUND}")
message(STATUS "Build with zlib and zstd: ${BUILT_WITH_ZLIB_AND_ZSTD}")
else()
message(STATUS "Build with zlib and zstd: NO")
endif () endif ()
message(STATUS "CMAKE_SIZEOF_VOID_P ... " ${CMAKE_SIZEOF_VOID_P} ) message(STATUS "CMAKE_SIZEOF_VOID_P ... : ${CMAKE_SIZEOF_VOID_P}")
# DW_FWALLXX are gnu C++ options. # DW_FWALLXX are gnu C++ options.
if (WALL) if (WALL)

View File

@ -5,12 +5,13 @@ rm -rfv cmake src CMakeLists.txt COPYING
echo "Fetching" echo "Fetching"
git clone https://github.com/davea42/libdwarf-code.git git clone https://github.com/davea42/libdwarf-code.git
cd libdwarf-code cd libdwarf-code
#git checkout "6216e185863f41d6f19ab850caabfff7326020d7" # v0.8.0 # git checkout "6216e185863f41d6f19ab850caabfff7326020d7" # v0.8.0
#git checkout "8b0bd09d8c77d45a68cb1bb00a54186a92b683d9" # v0.9.0 # git checkout "8b0bd09d8c77d45a68cb1bb00a54186a92b683d9" # v0.9.0
#git checkout "8cdcc531f310d1c5ae61da469d8056bdd36b77e7" # v0.9.1 + cmake fixes # 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 # git checkout "45ef8e2763f65c31b27cc38bed197b84dc1441d4" # v0.10.2
git checkout "285d9d34f3e9f56cc1c487d0055f6dc54a9c54a1" # v0.11.0 # git checkout "285d9d34f3e9f56cc1c487d0055f6dc54a9c54a1" # v0.11.0
git checkout "909af3e46b68335df6c4a901ddd256ffa0d193d2" # v0.11.1
cd .. cd ..
echo "Copying files" echo "Copying files"
mkdir -p src/lib mkdir -p src/lib

View File

@ -135,5 +135,10 @@ install(EXPORT libdwarfTargets
FILE libdwarf-targets.cmake FILE libdwarf-targets.cmake
NAMESPACE libdwarf:: NAMESPACE libdwarf::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf") DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf")
export(
TARGETS dwarf
NAMESPACE libdwarf::
FILE "${PROJECT_BINARY_DIR}/libdwarf-targets.cmake"
)
install(FILES "${PROJECT_BINARY_DIR}/src/lib/libdwarf/libdwarf.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") install(FILES "${PROJECT_BINARY_DIR}/src/lib/libdwarf/libdwarf.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(FILES "${PROJECT_SOURCE_DIR}/cmake/Findzstd.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf") install(FILES "${PROJECT_SOURCE_DIR}/cmake/Findzstd.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf")

View File

@ -749,6 +749,8 @@ string_is_in_debug_section(Dwarf_Debug dbg,void * space)
It is too late to change the documentation. */ It is too late to change the documentation. */
void *result = 0; void *result = 0;
/* The alloc tree can be in main or tied or both. */
result = dwarf_tfind((void *)space, result = dwarf_tfind((void *)space,
&dbg->de_alloc_tree,simple_compare_function); &dbg->de_alloc_tree,simple_compare_function);
if (!result) { if (!result) {
@ -849,9 +851,6 @@ dwarf_dealloc(Dwarf_Debug dbg,
unsigned int type = 0; unsigned int type = 0;
char * malloc_addr = 0; char * malloc_addr = 0;
struct reserve_data_s * r = 0; struct reserve_data_s * r = 0;
#if 0
Dwarf_Bool check_errmsg_list = FALSE;
#endif
if (!space) { if (!space) {
#ifdef DEBUG_ALLOC #ifdef DEBUG_ALLOC
@ -884,6 +883,9 @@ dwarf_dealloc(Dwarf_Debug dbg,
return; return;
#endif /* DEBUG_ALLOC*/ #endif /* DEBUG_ALLOC*/
} }
if (dbg && alloc_type == DW_DLA_ERROR) {
dbg = dbg->de_errors_dbg;
}
if (dbg && dbg->de_alloc_tree) { if (dbg && dbg->de_alloc_tree) {
/* If it's a string in debug_info etc doing /* If it's a string in debug_info etc doing
(char *)space - DW_RESERVE is totally bogus. */ (char *)space - DW_RESERVE is totally bogus. */
@ -969,9 +971,6 @@ dwarf_dealloc(Dwarf_Debug dbg,
if (ep->er_static_alloc == DE_MALLOC) { if (ep->er_static_alloc == DE_MALLOC) {
/* This is special, we had no arena /* This is special, we had no arena
but have a full special area as normal. */ but have a full special area as normal. */
#if 0
check_errmsg_list = TRUE;
#endif
#ifdef DEBUG_ALLOC #ifdef DEBUG_ALLOC
printf("DEALLOC does free, DE_MALLOC line %d %s\n", printf("DEALLOC does free, DE_MALLOC line %d %s\n",
__LINE__,__FILE__); __LINE__,__FILE__);

View File

@ -196,6 +196,15 @@ dwarf_debug_addr_table(Dwarf_Debug dbg,
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
tab.da_dbg = dbg; tab.da_dbg = dbg;
tablelen = 0;
if (arealen <= 4) {
_dwarf_error_string(dbg,error,
DW_DLE_SECTION_SIZE_ERROR,
"DW_DLE_SECTION_SIZE_ERROR: "
"The end of a .debug_addr header record is missing, "
"corrupt DWARF");
return DW_DLV_ERROR;
}
tablelen = arealen - 4; /* 4: the rest of the header */ tablelen = arealen - 4; /* 4: the rest of the header */
tab.da_length = tablelen; tab.da_length = tablelen;
curlocaloffset = offset_size + exten_size; curlocaloffset = offset_size + exten_size;

View File

@ -1694,8 +1694,27 @@ isformrefval(Dwarf_Debug dbg,Dwarf_Half form,
Dwarf_Unsigned *bytesread, Dwarf_Unsigned *bytesread,
Dwarf_Error *error) Dwarf_Error *error)
{ {
Dwarf_Unsigned localval =0; Dwarf_Unsigned localval = 0;
if (poolptr >= endpool) {
dwarfstring m;
const char * formname = 0;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_DEBUG_NAMES_OFF_END: "
"Reading data of form 0x%02x ",form);
dwarf_get_FORM_name((unsigned int)form,&formname);
dwarfstring_append_printf_s(&m,
"%s from entrypool would read "
"off the end of the pool",
(char *)formname);
_dwarf_error_string(dbg,error,
DW_DLE_DEBUG_NAMES_OFF_END,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
switch(form) { switch(form) {
case DW_FORM_ref1: case DW_FORM_ref1:
*val = *poolptr; *val = *poolptr;
@ -1771,6 +1790,7 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
/* make error or harmless error? */ /* make error or harmless error? */
return DW_DLV_NO_ENTRY; return DW_DLV_NO_ENTRY;
} }
if (index_of_abbrev >= dn->dn_abbrev_instance_count) { if (index_of_abbrev >= dn->dn_abbrev_instance_count) {
/* make error or harmless error? */ /* make error or harmless error? */
return DW_DLV_NO_ENTRY; return DW_DLV_NO_ENTRY;
@ -1854,6 +1874,10 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
array_of_offsets[n] = val; array_of_offsets[n] = val;
continue; continue;
} else if (form == DW_FORM_flag_present) {
array_of_offsets[n] = 1;
/* No change to poolptr or pooloffset */
continue;
} else { } else {
Dwarf_Unsigned val = 0; Dwarf_Unsigned val = 0;
res =isformrefval(dbg,form,poolptr, res =isformrefval(dbg,form,poolptr,
@ -1863,7 +1887,7 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
} }
if (res == DW_DLV_OK) { if (res == DW_DLV_OK) {
poolptr += bytesread; poolptr += bytesread;
if (poolptr > endpool) { if (poolptr >= endpool) {
_dwarf_error_string(dbg,error, _dwarf_error_string(dbg,error,
DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET, DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET,
"DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET:" "DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET:"
@ -1871,7 +1895,6 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
" of the entrypool"); " of the entrypool");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
poolptr += bytesread;
pooloffset += bytesread; pooloffset += bytesread;
array_of_offsets[n] = val; array_of_offsets[n] = val;
continue; continue;

View File

@ -1185,7 +1185,6 @@ _dwarf_setup_base_address(Dwarf_Debug dbg,
{ {
int lres = 0; int lres = 0;
Dwarf_Half form = 0; Dwarf_Half form = 0;
/* If the form is indexed, we better have /* If the form is indexed, we better have
seen DW_AT_addr_base.! */ seen DW_AT_addr_base.! */
lres = dwarf_whatform(attr,&form,error); lres = dwarf_whatform(attr,&form,error);
@ -1226,6 +1225,8 @@ _dwarf_setup_base_address(Dwarf_Debug dbg,
if it was DW_AT_entry_pc with no DW_AT_low_pc if it was DW_AT_entry_pc with no DW_AT_low_pc
Allowing DW_AT_entry_pc */ Allowing DW_AT_entry_pc */
cucon->cc_low_pc_present = TRUE; cucon->cc_low_pc_present = TRUE;
cucon->cc_base_address_present = TRUE;
cucon->cc_base_address = cucon->cc_low_pc;
} else { } else {
/* Something is badly wrong. */ /* Something is badly wrong. */
return lres; return lres;
@ -1290,6 +1291,8 @@ set_producer_type(Dwarf_Die die,
} }
if (_dwarf_prod_contains("Metrowerks",producer)) { if (_dwarf_prod_contains("Metrowerks",producer)) {
cu_context->cc_producer = CC_PROD_METROWERKS; cu_context->cc_producer = CC_PROD_METROWERKS;
} else if (_dwarf_prod_contains("Apple",producer)) {
cu_context->cc_producer = CC_PROD_Apple;
} }
} }
@ -1318,7 +1321,6 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
cu_context = cudie->di_cu_context; cu_context = cudie->di_cu_context;
version_stamp = cu_context->cc_version_stamp; version_stamp = cu_context->cc_version_stamp;
alres = dwarf_attrlist(cudie, &alist, alres = dwarf_attrlist(cudie, &alist,
&atcount,error); &atcount,error);
if (alres != DW_DLV_OK) { if (alres != DW_DLV_OK) {
@ -1445,10 +1447,6 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
int res = 0; int res = 0;
Dwarf_Bool is_info = cucon->cc_is_info; Dwarf_Bool is_info = cucon->cc_is_info;
#if 0
res = dwarf_global_formref(attr,
&at_ranges_offset,error);
#endif
res = _dwarf_internal_global_formref_b(attr, res = _dwarf_internal_global_formref_b(attr,
/* avoid recurse creating context */ 1, /* avoid recurse creating context */ 1,
&at_ranges_offset, &at_ranges_offset,
@ -1519,14 +1517,14 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
udres = _dwarf_internal_global_formref_b(attr, udres = _dwarf_internal_global_formref_b(attr,
/* avoid recurse creating context */ 1, /* avoid recurse creating context */ 1,
&cucon->cc_addr_base, &cucon->cc_addr_base_offset,
&is_info, &is_info,
error); error);
if (udres == DW_DLV_OK) { if (udres == DW_DLV_OK) {
if (is_info == cucon->cc_is_info) { if (is_info == cucon->cc_is_info) {
/* Only accept if same .debug section, /* Only accept if same .debug section,
which is relevant for DWARF4 */ which is relevant for DWARF4 */
cucon->cc_addr_base_present = TRUE; cucon->cc_addr_base_offset_present = TRUE;
} }
} else { } else {
local_attrlist_dealloc(dbg,atcount,alist); local_attrlist_dealloc(dbg,atcount,alist);
@ -1551,7 +1549,10 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
it refers to .debug_ranges. it refers to .debug_ranges.
Note that this base applies when Note that this base applies when
referencing from the dwp, but NOT referencing from the dwp, but NOT
when referencing from the a.out */ when referencing from the a.out
In DW4 extension split dwarf the .debug_ranges
is always in the tied-file (executable). */
int udres = 0; int udres = 0;
Dwarf_Bool is_info = cucon->cc_is_info; Dwarf_Bool is_info = cucon->cc_is_info;
@ -1610,22 +1611,10 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
} }
} }
} }
if (low_pc_attrnum >= 0 ){ /* Only on Apple do we let entry_pc
int battr = 0; be used as base address. */
if (entry_pc_attrnum >= 0 &&
/* Prefer DW_AT_low_pc */ cucon->cc_producer == CC_PROD_Apple) {
Dwarf_Attribute attr = alist[low_pc_attrnum];
battr = _dwarf_setup_base_address(dbg,"DW_AT_low_pc",
attr,at_addr_base_attrnum, cucon,
bad_pc_form,error);
if (battr != DW_DLV_OK) {
local_attrlist_dealloc(dbg,atcount,alist);
/* Something is wrong, possibly
erroneous Macrowerks compiler. */
_dwarf_set_children_flag(cucon,cudie);
return battr;
}
} else if (entry_pc_attrnum >= 0) {
int battr = 0; int battr = 0;
/* Pretending that DW_AT_entry_pc with no /* Pretending that DW_AT_entry_pc with no
@ -1636,7 +1625,8 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
base address (DW_AT_entry_pc first appears in DWARF3). base address (DW_AT_entry_pc first appears in DWARF3).
So we allow that as an extension, So we allow that as an extension,
as a 'low_pc' if there is DW_AT_entry_pc with as a 'low_pc' if there is DW_AT_entry_pc with
no DW_AT_low_pc. 19 May 2022. */ no DW_AT_low_pc. 19 May 2022.
Also used by gcc with a DWARF4 split-dwarf extension. */
Dwarf_Attribute attr = alist[entry_pc_attrnum]; Dwarf_Attribute attr = alist[entry_pc_attrnum];
battr = _dwarf_setup_base_address(dbg,"DW_AT_entry_pc", battr = _dwarf_setup_base_address(dbg,"DW_AT_entry_pc",
attr,at_addr_base_attrnum, cucon, attr,at_addr_base_attrnum, cucon,
@ -1648,6 +1638,21 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
return battr; return battr;
} }
} }
if (low_pc_attrnum >= 0 ){
int battr = 0;
Dwarf_Attribute attr = alist[low_pc_attrnum];
battr = _dwarf_setup_base_address(dbg,"DW_AT_low_pc",
attr,at_addr_base_attrnum, cucon,
bad_pc_form,error);
if (battr != DW_DLV_OK) {
local_attrlist_dealloc(dbg,atcount,alist);
/* Something is wrong, possibly
erroneous Macrowerks compiler. */
_dwarf_set_children_flag(cucon,cudie);
return battr;
}
}
local_attrlist_dealloc(dbg,atcount,alist); local_attrlist_dealloc(dbg,atcount,alist);
alist = 0; alist = 0;
atcount = 0; atcount = 0;
@ -1655,7 +1660,10 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
return DW_DLV_OK; return DW_DLV_OK;
} }
/* Called only for DWARF4 */ /* Called only for DWARF4 and earlier
so there is consistent naming of unit_type
even though there was no such field in
DWARF2-DWARF4. */
static void static void
assign_correct_unit_type(Dwarf_CU_Context cu_context) assign_correct_unit_type(Dwarf_CU_Context cu_context)
{ {
@ -1737,7 +1745,9 @@ finish_up_cu_context_from_cudie(Dwarf_Debug dbg,
if (cu_context->cc_signature_present) { if (cu_context->cc_signature_present) {
/* For finding base data from skeleton. /* For finding base data from skeleton.
For the few fields inherited For the few fields inherited
(per the DWARF5 standard. */ (per the DWARF5 standard but for
.debug_rnglists is not interited
in spite of what DW5 says). */
res = _dwarf_find_all_offsets_via_fission(dbg, res = _dwarf_find_all_offsets_via_fission(dbg,
cu_context,error); cu_context,error);
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
@ -1952,8 +1962,8 @@ _dwarf_load_die_containing_section(Dwarf_Debug dbg,
int int
_dwarf_next_cu_header_internal(Dwarf_Debug dbg, _dwarf_next_cu_header_internal(Dwarf_Debug dbg,
Dwarf_Bool is_info, Dwarf_Bool is_info,
Dwarf_Die *cu_die_out, Dwarf_Die * cu_die_out,
Dwarf_Unsigned * cu_header_length, Dwarf_Unsigned * cu_header_length,
Dwarf_Half * version_stamp, Dwarf_Half * version_stamp,
Dwarf_Unsigned * abbrev_offset, Dwarf_Unsigned * abbrev_offset,
@ -2088,14 +2098,17 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg,
} }
{ {
Dwarf_Debug tieddbg = 0; Dwarf_Debug tieddbg = 0;
int tres = 0; int tres = DW_DLV_OK;
tieddbg = dbg->de_tied_data.td_tied_object; tieddbg = dbg->de_secondary_dbg;
if (tieddbg) { if (DBG_IS_PRIMARY(dbg) && DBG_IS_SECONDARY(tieddbg)) {
/* We are in the main, merge tied
into main cu_context */
tres = _dwarf_merge_all_base_attrs_of_cu_die( tres = _dwarf_merge_all_base_attrs_of_cu_die(
dbg, cu_context, cu_context,
tieddbg, 0, tieddbg,
0 /* we do not want the context returned */,
error); error);
} } /* Else no merge */
if (tres == DW_DLV_ERROR && error) { if (tres == DW_DLV_ERROR && error) {
/* We'll assume any errors will be /* We'll assume any errors will be
discovered later. Lets get our discovered later. Lets get our

View File

@ -688,7 +688,8 @@ static const char _dwarf_errmsgs[DW_DLE_LAST+1][DW_MAX_MSG_LEN] = {
{"DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR(503) Offset/size from " {"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 " {"DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL(504) Section size fails "
"a heuristic sanity check"} "a heuristic sanity check"},
{"DW_DLE_LLE_ERROR(505) Generic .debug_loclists read error"},
{"DW_DLE_RLE_ERROR(506) Generic .debug_rnglists read error"}
}; };
#endif /* DWARF_ERRMSG_LIST_H */ #endif /* DWARF_ERRMSG_LIST_H */

View File

@ -110,6 +110,9 @@ _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error,
{ {
_dwarf_error_string(dbg,error,errval,0); _dwarf_error_string(dbg,error,errval,0);
} }
/* Errors are all added to the de_primary_dbg, never to
de_secondary_dbg. */
void void
_dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error, _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error,
Dwarf_Signed errval,char *msg) Dwarf_Signed errval,char *msg)
@ -123,8 +126,13 @@ _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error,
/* If dbg is NULL, use the alternate error struct. However, /* If dbg is NULL, use the alternate error struct. However,
this will overwrite the earlier error. */ this will overwrite the earlier error. */
if (dbg) { if (dbg) {
/* ERRORs are always associated with
de_primary_dbg so they can be returned
up the tree of calls on the stack
safely. */
errptr = errptr =
(Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); (Dwarf_Error) _dwarf_get_alloc(dbg->de_errors_dbg,
DW_DLA_ERROR, 1);
if (!errptr) { if (!errptr) {
errptr = &_dwarf_failsafe_error; errptr = &_dwarf_failsafe_error;
errptr->er_static_alloc = DE_STATIC; errptr->er_static_alloc = DE_STATIC;
@ -182,13 +190,14 @@ _dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error,
} }
if (dbg && dbg->de_errhand != NULL) { if (dbg && dbg->de_errhand != NULL) {
errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); errptr = (Dwarf_Error) _dwarf_get_alloc(dbg->de_errors_dbg,
DW_DLA_ERROR, 1);
if (errptr == NULL) { if (errptr == NULL) {
errptr = &_dwarf_failsafe_error; errptr = &_dwarf_failsafe_error;
errptr->er_static_alloc = DE_STATIC; errptr->er_static_alloc = DE_STATIC;
} }
errptr->er_errval = errval; errptr->er_errval = errval;
dbg->de_errhand(errptr, dbg->de_errarg); dbg->de_errhand(errptr, dbg->de_errors_dbg->de_errarg);
return; return;
} }
fflush(stderr); fflush(stderr);

View File

@ -49,6 +49,27 @@
#include "dwarf_loclists.h" #include "dwarf_loclists.h"
#include "dwarf_rnglists.h" #include "dwarf_rnglists.h"
/* RETURNS DW_DLV_OK and sets values
through the return-value pointers.
Or returns DW_DLV_NO_ENTRY */
int
_dwarf_has_SECT_fission(Dwarf_CU_Context ctx,
unsigned int SECT_number,
Dwarf_Bool *hasfissionoffset,
Dwarf_Unsigned *loclistsbase)
{
struct Dwarf_Debug_Fission_Per_CU_s *fis = 0;
Dwarf_Unsigned fisindex = SECT_number;
fis = &ctx->cc_dwp_offsets;
if (fis->pcu_type && fis->pcu_size[fisindex]) {
*loclistsbase = fis->pcu_offset[fisindex];
*hasfissionoffset = TRUE;
return DW_DLV_OK;
}
return DW_DLV_NO_ENTRY;
}
/* ASSERT: dbg,cu_context, and fsd are non-NULL /* ASSERT: dbg,cu_context, and fsd are non-NULL
as the caller ensured that. as the caller ensured that.
With no DW_AT_loclists_base this computes one. */ With no DW_AT_loclists_base this computes one. */
@ -270,8 +291,13 @@ load_xu_rnglists_into_cucontext(Dwarf_Debug dbg,
if (res != DW_DLV_OK) { if (res != DW_DLV_OK) {
return res; return res;
} }
cu_context->cc_rnglists_base = cu_context->cc_rnglists_base =
buildhere->rc_offsets_off_in_sect; buildhere->rc_offsets_off_in_sect;
printf("debug SET rnglists base from rc_offsetts_off_in_sectt: "
"0x%lx lie %d\n",
(unsigned long)cu_context->cc_rnglists_base,
__LINE__);
cu_context->cc_rnglists_base_present = TRUE; cu_context->cc_rnglists_base_present = TRUE;
cu_context->cc_rnglists_base_contr_size = size; cu_context->cc_rnglists_base_contr_size = size;
/* FIXME cc_rnglists_header_length_present? */ /* FIXME cc_rnglists_header_length_present? */

View File

@ -741,7 +741,7 @@ dwarf_global_formref(Dwarf_Attribute attr,
return res; return res;
} }
/* If context_level is 0, normal call /* If context_level is 0, normal call
But if non-zero will avoid creating CU Context. */ But if non-zero will avoid creating CU Context. */
int int
dwarf_global_formref_b(Dwarf_Attribute attr, dwarf_global_formref_b(Dwarf_Attribute attr,
@ -750,13 +750,16 @@ dwarf_global_formref_b(Dwarf_Attribute attr,
Dwarf_Error * error) Dwarf_Error * error)
{ {
int res = 0; int res = 0;
int context_level = 0;
res = _dwarf_internal_global_formref_b( attr, res = _dwarf_internal_global_formref_b( attr,
0, context_level,
ret_offset, ret_offset,
offset_is_info, offset_is_info,
error); error);
return res; return res;
} }
/* If context_level is 0, normal call
But if non-zero will avoid creating CU Context. */
int int
_dwarf_internal_global_formref_b(Dwarf_Attribute attr, _dwarf_internal_global_formref_b(Dwarf_Attribute attr,
int context_level, int context_level,
@ -987,7 +990,7 @@ _dwarf_internal_global_formref_b(Dwarf_Attribute attr,
dwarfstring_constructor(&m); dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m, dwarfstring_append_printf_u(&m,
"DW_DLE_BAD_REF_FORM: The form code is 0x%x ", "DW_DLE_BAD_REF_FORM: The form code is 0x%x.. ",
formcode); formcode);
fcres = dwarf_get_FORM_name (formcode,&name); fcres = dwarf_get_FORM_name (formcode,&name);
if (fcres != DW_DLV_OK) { if (fcres != DW_DLV_OK) {
@ -1070,6 +1073,7 @@ _dwarf_get_addr_index_itself(int theform,
to a local .debug_addr or a tied file .debug_addr to a local .debug_addr or a tied file .debug_addr
so lets be cautious. */ so lets be cautious. */
#if 0 /* Attempted check for index uncertain, unwise. Ignore. */ #if 0 /* Attempted check for index uncertain, unwise. Ignore. */
/* See de_secondary_dbg before using this */
if (!dbg->de_tied_data.td_tied_object && if (!dbg->de_tied_data.td_tied_object &&
index > dbg->de_filesize) { index > dbg->de_filesize) {
_dwarf_error_string(dbg,error,DW_DLE_ATTR_FORM_OFFSET_BAD, _dwarf_error_string(dbg,error,DW_DLE_ATTR_FORM_OFFSET_BAD,
@ -1403,7 +1407,8 @@ _dwarf_allow_formudata(unsigned form)
case DW_FORM_data2: case DW_FORM_data2:
case DW_FORM_data4: case DW_FORM_data4:
case DW_FORM_data8: case DW_FORM_data8:
case DW_FORM_udata: case DW_FORM_flag:
case DW_FORM_flag_present:
case DW_FORM_loclistx: case DW_FORM_loclistx:
case DW_FORM_rnglistx: case DW_FORM_rnglistx:
return TRUE; return TRUE;
@ -1446,6 +1451,18 @@ _dwarf_formudata_internal(Dwarf_Debug dbg,
*return_uval = ret_value; *return_uval = ret_value;
*bytes_read = 1; *bytes_read = 1;
return DW_DLV_OK; return DW_DLV_OK;
case DW_FORM_flag_present:
*return_uval = 1;
*bytes_read = 0;
return DW_DLV_OK;
case DW_FORM_flag:
/* equivalent to dwarf_formflag() */
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 /* READ_UNALIGNED does the right thing as it reads
the right number bits and generates host order. the right number bits and generates host order.
@ -2082,7 +2099,8 @@ dwarf_formstring(Dwarf_Attribute attr,
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
if (dwarf_errno(alterr) == if (dwarf_errno(alterr) ==
DW_DLE_NO_TIED_FILE_AVAILABLE) { DW_DLE_NO_TIED_FILE_AVAILABLE) {
dwarf_dealloc(dbg,alterr,DW_DLA_ERROR);
dwarf_dealloc_error(dbg,alterr);
if ( attr->ar_attribute_form == if ( attr->ar_attribute_form ==
DW_FORM_GNU_strp_alt) { DW_FORM_GNU_strp_alt) {
*return_str = *return_str =
@ -2168,17 +2186,17 @@ _dwarf_get_string_from_tied(Dwarf_Debug dbg,
Dwarf_Error localerror = 0; Dwarf_Error localerror = 0;
/* Attach errors to dbg, not tieddbg. */ /* Attach errors to dbg, not tieddbg. */
tieddbg = dbg->de_tied_data.td_tied_object; if (!DBG_HAS_SECONDARY(dbg)) {
if (!tieddbg) {
_dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE); _dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE);
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
tieddbg = dbg->de_secondary_dbg;
/* The 'offset' into .debug_str is set. */ /* The 'offset' into .debug_str is set. */
res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str, res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str,
&localerror); &localerror);
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
Dwarf_Unsigned lerrno = dwarf_errno(localerror); Dwarf_Unsigned lerrno = dwarf_errno(localerror);
dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); dwarf_dealloc_error(tieddbg,localerror);
_dwarf_error(dbg,error,lerrno); _dwarf_error(dbg,error,lerrno);
return res; return res;
} }
@ -2205,7 +2223,7 @@ _dwarf_get_string_from_tied(Dwarf_Debug dbg,
&localerror); &localerror);
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
Dwarf_Unsigned lerrno = dwarf_errno(localerror); Dwarf_Unsigned lerrno = dwarf_errno(localerror);
dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); dwarf_dealloc_error(tieddbg,localerror);
_dwarf_error(dbg,error,lerrno); _dwarf_error(dbg,error,lerrno);
return res; return res;
} }

View File

@ -78,6 +78,54 @@ dwarf_init_path_dl(path true_path and globals, dbg1
#include "dwarf_error.h" #include "dwarf_error.h"
#include "dwarf_object_detector.h" #include "dwarf_object_detector.h"
/* The design of Dwarf_Debug_s data on --file-tied
data and how it is used. See also dwarf_opaque.h
and dwarf_util.c
The fields involved are
de_dbg
de_primary_dbg
de_secondary_dbg
de_errors_dbg
de_tied_data.td_tied_object
On any init completing it will be considered
primary, Call it p1.
p1->de_dbg == p1
p1->de_primary_dbg == p1
p1->de_secondary_dbg == NULL
p1->de_errors_dbg == p1
p1->de_tied_data.td_tied_object = 0
Init a second object, call it p2 (settings as above).
Call dwarf_set_tied (p1,p2) (it is ok if p2 == NULL)
p1 is as above except that
p1->de_secondary_dbg == p2
p1->de_tied_data.td_tied_object = p2;
If p2 is non-null:
p2->de_dbg == p2
p2->de_primary_dbg = p1.
p2->de_secondary_dbg = p2
p2->de_errors_dbg = p1
All this is only useful if p1 has dwo/dwp sections
(split-dwarf) and p2 has the relevant TAG_skeleton(s)
If px->de_secondary_dbg is non-null
and px->secondary_dbg == px
then px is secondary.
If x->de_secondary_dbg is non-null
and px->secondary_dbg != px
then px is primary.
If px->de_secondary_dbg is null
then px is a primary. and there
is no secondary.
Call dwarf_set_tied(p1,NULL) and both p1 and
p2 are returned to initial conditions
as before they were tied together. */
static int static int
set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error) set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error)
{ {
@ -513,31 +561,78 @@ dwarf_finish(Dwarf_Debug dbg)
tieddbg should be the executable or .o tieddbg should be the executable or .o
that has the .debug_addr section that that has the .debug_addr section that
the base dbg refers to. See Split Objects in DWARF5. the base dbg refers to. See Split Objects in DWARF5.
Or in DWARF5 maybe .debug_rnglists or .debug_loclists.
Allows setting to NULL (NULL is the default Allows calling with NULL though we really just set
of de_tied_data.td_tied_object). primary_dbg->ge_primary to de_primary_dbg, thus cutting
links between main and any previous tied-file setup.
New September 2015. New September 2015.
Logic revised Nov 2024. See dwarf_opaque.h
*/ */
int int
dwarf_set_tied_dbg(Dwarf_Debug dbg, dwarf_set_tied_dbg(Dwarf_Debug primary_dbg,
Dwarf_Debug tieddbg, Dwarf_Debug secondary_dbg,
Dwarf_Error*error) Dwarf_Error*error)
{ {
CHECK_DBG(dbg,error,"dwarf_set_tied_dbg()"); CHECK_DBG(primary_dbg,error,"dwarf_set_tied_dbg()");
if (secondary_dbg == primary_dbg) {
dbg->de_tied_data.td_tied_object = tieddbg; _dwarf_error_string(primary_dbg,error,
if (tieddbg) { DW_DLE_NO_TIED_FILE_AVAILABLE,
tieddbg->de_tied_data.td_is_tied_object = TRUE; "DW_DLE_NO_TIED_FILE_AVAILABLE: bad argument to "
"dwarf_set_tied_dbg(), tied and main must not be the "
"same pointer!");
return DW_DLV_ERROR;
}
if (secondary_dbg) {
if (primary_dbg->de_secondary_dbg ) {
_dwarf_error_string(primary_dbg,error,
DW_DLE_NO_TIED_FILE_AVAILABLE,
"DW_DLE_NO_TIED_FILE_AVAILABLE: bad argument to "
"dwarf_set_tied_dbg(), primary_dbg already has"
" a secondary_dbg!");
return DW_DLV_ERROR;
}
primary_dbg->de_tied_data.td_tied_object = secondary_dbg;
primary_dbg->de_secondary_dbg = secondary_dbg;
secondary_dbg->de_secondary_dbg = secondary_dbg;
secondary_dbg->de_errors_dbg = primary_dbg;
CHECK_DBG(secondary_dbg,error,"dwarf_set_tied_dbg() "
"dw_secondary_dbg"
"is invalid");
primary_dbg->de_secondary_dbg = secondary_dbg;
return DW_DLV_OK;
} else {
primary_dbg->de_secondary_dbg = 0;
primary_dbg->de_tied_data.td_tied_object = 0;
} }
return DW_DLV_OK; return DW_DLV_OK;
} }
/* New September 2015. */ /* New September 2015.
As of Aug 2023 this correctly returns tied_dbg
whether main or tied passed in. Before this
it would return the dbg passed in.
If there is no tied-dbg this returns main dbg. */
int int
dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out, dwarf_get_tied_dbg(Dwarf_Debug dw_dbg,
Dwarf_Error*error) Dwarf_Debug *dw_secondary_dbg_out,
Dwarf_Error *dw_error)
{ {
CHECK_DBG(dbg,error,"dwarf_get_tied_dbg()"); CHECK_DBG(dw_dbg,dw_error,"dwarf_get_tied_dbg()");
*tieddbg_out = dbg->de_tied_data.td_tied_object; *dw_secondary_dbg_out = 0;
if (DBG_IS_PRIMARY(dw_dbg)) {
if (!dw_dbg->de_secondary_dbg) {
*dw_secondary_dbg_out = dw_dbg;
return DW_DLV_OK;
}
*dw_secondary_dbg_out = dw_dbg->de_secondary_dbg;
return DW_DLV_OK;
}
if (DBG_IS_SECONDARY(dw_dbg)) {
*dw_secondary_dbg_out = dw_dbg;
return DW_DLV_OK;
}
/* Leave returned secondary_dbg_out NULL,
this should not happen */
return DW_DLV_OK; return DW_DLV_OK;
} }

View File

@ -276,10 +276,10 @@ scan_block_entries(Dwarf_Debug dbg,
Dwarf_Unsigned length = 0; Dwarf_Unsigned length = 0;
unsigned int offsetsize = 0; unsigned int offsetsize = 0;
unsigned int extensize = 0; unsigned int extensize = 0;
unsigned int sumsize = 0;
if (curptr == endptr) { if (curptr == endptr) {
*count_out = count; break;
return DW_DLV_OK;
} }
/* Not sure how the coders think about /* Not sure how the coders think about
the initial value. But the last the initial value. But the last
@ -296,10 +296,16 @@ scan_block_entries(Dwarf_Debug dbg,
} }
++count; ++count;
curptr += length -offsetsize - extensize; sumsize = offsetsize +extensize;
if (length < sumsize) {
build_errm_one_num(dbg,for_gnu_pubnames,
"Length of fde/cies header sizes 0x%" DW_PR_DUx
" is impossibly small",length,error);
return DW_DLV_ERROR;
}
curptr += length - sumsize;
curptr += 4; curptr += 4;
} }
/* NOTREACHED */
*count_out = count; *count_out = count;
return DW_DLV_OK; return DW_DLV_OK;
} }

View File

@ -217,12 +217,12 @@ _dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size)
unsigned i = 0; unsigned i = 0;
memset(dhp,0,sizeof(*dhp)); memset(dhp,0,sizeof(*dhp));
dhp->dh_maxcount = size +1; dhp->dh_maxcount = size +1;
dhp->dh_errors = (char **)calloc(dhp->dh_maxcount, sizeof(char *)); dhp->dh_errors = (char **)calloc(dhp->dh_maxcount,
sizeof(char *));
if (!dhp->dh_errors) { if (!dhp->dh_errors) {
dhp->dh_maxcount = 0; dhp->dh_maxcount = 0;
return; return;
} }
for (i = 0; i < dhp->dh_maxcount; ++i) { for (i = 0; i < dhp->dh_maxcount; ++i) {
char *newstr = char *newstr =
(char *)calloc(1, DW_HARMLESS_ERROR_MSG_STRING_SIZE); (char *)calloc(1, DW_HARMLESS_ERROR_MSG_STRING_SIZE);

View File

@ -1035,6 +1035,8 @@ dwarf_object_init_b(Dwarf_Obj_Access_Interface_a* obj,
size. */ size. */
dbg = _dwarf_get_debug(filesize); dbg = _dwarf_get_debug(filesize);
if (IS_INVALID_DBG(dbg)) { if (IS_INVALID_DBG(dbg)) {
dwarf_finish(dbg);
dbg = 0;
DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
} }
dbg->de_errhand = errhand; dbg->de_errhand = errhand;
@ -1044,6 +1046,12 @@ dwarf_object_init_b(Dwarf_Obj_Access_Interface_a* obj,
dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3; dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3;
dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL; dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL;
dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL; dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL;
dbg->de_dbg = dbg;
/* See dwarf_set_tied_dbg() dwarf_get_tied_dbg()
and comments in dwarf_opaque.h*/
dbg->de_primary_dbg = dbg;
dbg->de_secondary_dbg = 0;
dbg->de_errors_dbg = dbg;
dbg->de_obj_file = obj; dbg->de_obj_file = obj;
dbg->de_filesize = filesize; dbg->de_filesize = filesize;
@ -1099,7 +1107,7 @@ dwarf_object_init_b(Dwarf_Obj_Access_Interface_a* obj,
/* *error safe */ /* *error safe */
dwarfstring_append(&msg,dwarf_errmsg(*error)); dwarfstring_append(&msg,dwarf_errmsg(*error));
/* deallocate the soon-stale error pointer. */ /* deallocate the soon-stale error pointer. */
dwarf_dealloc(dbg,*error,DW_DLA_ERROR); dwarf_dealloc_error(dbg,*error);
/* *error safe */ /* *error safe */
*error = 0; *error = 0;
} }

View File

@ -844,9 +844,9 @@ _dwarf_internal_srclines(Dwarf_Die die,
} }
section_start = dbg->de_debug_line.dss_data; section_start = dbg->de_debug_line.dss_data;
section_end = section_start +dbg->de_debug_line.dss_size; section_end = section_start +dbg->de_debug_line.dss_size;
line_ptr = dbg->de_debug_line.dss_data + line_offset;
{ {
Dwarf_Unsigned fission_size = 0; Dwarf_Unsigned fission_size = 0;
uintptr_t line_ptr_as_uint = (uintptr_t)line_ptr;
int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
&fission_offset,&fission_size,error); &fission_offset,&fission_size,error);
if (resf != DW_DLV_OK) { if (resf != DW_DLV_OK) {
@ -856,15 +856,21 @@ _dwarf_internal_srclines(Dwarf_Die die,
/* fission_offset may be 0, and adding 0 to a null pointer /* fission_offset may be 0, and adding 0 to a null pointer
is undefined behavior with some compilers. */ is undefined behavior with some compilers. */
line_ptr_as_uint += fission_offset; if (fission_offset) {
line_ptr = (Dwarf_Small *)line_ptr_as_uint; line_ptr += fission_offset;
}
if (line_ptr > section_end) { if (line_ptr > section_end) {
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
_dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR); _dwarf_error_string(dbg, error,
DW_DLE_FISSION_ADDITION_ERROR,
"DW_DLE_FISSION_ADDITION_ERROR: "
"on retrieving the fission addition value for "
"adding that into the line table offset "
"results in running off "
"the end of the line table. Corrupt DWARF.");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
} }
section_start = dbg->de_debug_line.dss_data; section_start = dbg->de_debug_line.dss_data;
section_end = section_start +dbg->de_debug_line.dss_size; section_end = section_start +dbg->de_debug_line.dss_size;
orig_line_ptr = section_start + line_offset + fission_offset; orig_line_ptr = section_start + line_offset + fission_offset;
@ -895,7 +901,7 @@ _dwarf_internal_srclines(Dwarf_Die die,
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
line_context->lc_new_style_access = line_context->lc_new_style_access =
(unsigned char)is_new_interface; (unsigned char)is_new_interface;
line_context->lc_compilation_directory = comp_dir; line_context->lc_compilation_directory = comp_dir;
/* We are in dwarf_internal_srclines() */ /* We are in dwarf_internal_srclines() */

View File

@ -229,7 +229,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg,
err, section_length,section_end); err, section_length,section_end);
line_ptr_end = line_ptr + total_length; line_ptr_end = line_ptr + total_length;
line_context->lc_line_ptr_end = line_ptr_end; line_context->lc_line_ptr_end = line_ptr_end;
line_context->lc_length_field_length = line_context->lc_length_field_length =
(Dwarf_Half)(local_length_size + local_extension_size); (Dwarf_Half)(local_length_size + local_extension_size);
line_context->lc_section_offset = starting_line_ptr - line_context->lc_section_offset = starting_line_ptr -
dbg->de_debug_line.dss_data; dbg->de_debug_line.dss_data;
@ -2704,11 +2704,14 @@ read_line_table_program(Dwarf_Debug dbg,
/* This is an extended op code we do not know about, /* This is an extended op code we do not know about,
other than we know now many bytes it is other than we know now many bytes it is
and the op code and the bytes of operand. */ and the op code and the bytes of operand. */
Dwarf_Unsigned remaining_bytes = instr_length -1; Dwarf_Unsigned remaining_bytes = 0;
/* ptrdiff_t is generated but not named */ /* ptrdiff_t is generated but not named */
Dwarf_Unsigned space_left = Dwarf_Unsigned space_left =
(line_ptr <= line_ptr_end)? (line_ptr <= line_ptr_end)?
(line_ptr_end - line_ptr):0xfffffff; (line_ptr_end - line_ptr):0xfffffff;
if (instr_length > 0) {
remaining_bytes = instr_length -1;
}
/* By catching this here instead of PRINTING_DETAILS /* By catching this here instead of PRINTING_DETAILS
we avoid reading off of our data of interest*/ we avoid reading off of our data of interest*/

View File

@ -48,6 +48,9 @@
#include "dwarf_loc.h" #include "dwarf_loc.h"
#include "dwarf_string.h" #include "dwarf_string.h"
#define DEBUG_LOCLIST 1
#undef DEBUG_LOCLIST
static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
Dwarf_Block_c * return_block, Dwarf_Block_c * return_block,
Dwarf_Addr * lowpc, Dwarf_Addr * lowpc,
@ -1136,7 +1139,7 @@ _dwarf_original_loclist_build(Dwarf_Debug dbg,
} }
/* We need to calculate the cooked values for /* We need to calculate the cooked values for
each locldesc entry, that will be done each locldesc entry, that will be done
in dwarf_get_loclist_c(). */ in dwarf_get_loclist_d(). */
llhead->ll_bytes_total = loclist_offset - llhead->ll_bytes_total = loclist_offset -
starting_loclist_offset; starting_loclist_offset;
@ -1267,6 +1270,7 @@ cook_original_loclist_contents(Dwarf_Debug dbg,
baseaddress = llc->ld_rawhigh; baseaddress = llc->ld_rawhigh;
break; break;
} }
/* This is the only way baseaddress is used. */
case DW_LLE_offset_pair: { case DW_LLE_offset_pair: {
llc->ld_lopc = llc->ld_rawlow + baseaddress; llc->ld_lopc = llc->ld_rawlow + baseaddress;
llc->ld_highpc = llc->ld_rawhigh + baseaddress; llc->ld_highpc = llc->ld_rawhigh + baseaddress;
@ -1587,17 +1591,21 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
Dwarf_Unsigned * listlen_out, Dwarf_Unsigned * listlen_out,
Dwarf_Error * error) Dwarf_Error * error)
{ {
Dwarf_Debug dbg = 0; Dwarf_Debug dbg = 0;
Dwarf_Half form = 0; Dwarf_Half form = 0;
Dwarf_Loc_Head_c llhead = 0; Dwarf_Loc_Head_c llhead = 0;
Dwarf_CU_Context cucontext = 0; unsigned address_size = 0;
unsigned address_size = 0; Dwarf_Half cuversionstamp = 0;
Dwarf_Half cuversionstamp = 0; Dwarf_Bool is_cu = FALSE;
Dwarf_Bool is_cu = FALSE; Dwarf_Unsigned attrnum = 0;
Dwarf_Unsigned attrnum = 0; Dwarf_Bool is_dwo = 0;
Dwarf_Bool is_dwo = 0; int lkind = 0;
int setup_res = DW_DLV_ERROR; Dwarf_CU_Context ctx = 0;
int lkind = 0; Dwarf_Bool is_loclistx = FALSE;
Dwarf_Unsigned attr_val = 0;
Dwarf_Bool offset_is_info = TRUE;
int res = 0;
int setup_res = 0;
if (!attr) { if (!attr) {
_dwarf_error_string(dbg, error,DW_DLE_ATTR_NULL, _dwarf_error_string(dbg, error,DW_DLE_ATTR_NULL,
@ -1607,18 +1615,74 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
"dwarf_get_loclist_c()"); "dwarf_get_loclist_c()");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
dbg = attr->ar_dbg; setup_res = _dwarf_setup_loc(attr, &dbg,&ctx, &form, error);
CHECK_DBG(dbg,error,"dwarf_get_loclist_c()");
/* ***** BEGIN CODE ***** */
setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
if (setup_res != DW_DLV_OK) { if (setup_res != DW_DLV_OK) {
return setup_res; return setup_res;
} }
CHECK_DBG(dbg,error,"dwarf_get_loclist_c()");
if (form == DW_FORM_loclistx) {
is_loclistx = TRUE;
}
attrnum = attr->ar_attribute; attrnum = attr->ar_attribute;
cuversionstamp = cucontext->cc_version_stamp; cuversionstamp = ctx->cc_version_stamp;
address_size = cucontext->cc_address_size; address_size = ctx->cc_address_size;
is_dwo = cucontext->cc_is_dwo; is_dwo = ctx->cc_is_dwo;
lkind = determine_location_lkind(cuversionstamp,
form, is_dwo);
if (form == DW_FORM_loclistx || form == DW_FORM_sec_offset) {
/* Aimed at DWARF5 and later */
res = dwarf_global_formref_b(attr,&attr_val,
&offset_is_info,error);
if (res != DW_DLV_OK) {
return res;
}
}
if (lkind == DW_LKIND_loclists) {
if (is_loclistx) {
if (ctx->cc_loclists_base_present ||
dbg->de_loclists_context_count == 1) {
/* leave on primary.
WARNING: It is not clear whether
looking for a context count of 1
is actually correct, but it
seems to work. */
} else if (DBG_HAS_SECONDARY(dbg)){
dbg = dbg->de_secondary_dbg;
CHECK_DBG(dbg,error,
"dwarf_loclists_get_lle_head() "
"via attribute(sec)");
}
} else {
/* attr_val is .debug_loclists[.dwo]
section global offset
of a location list*/
if (!dbg->de_debug_loclists.dss_size ||
attr_val >= dbg->de_debug_loclists.dss_size) {
if (DBG_HAS_SECONDARY(dbg)) {
dbg = dbg->de_secondary_dbg;
CHECK_DBG(dbg,error,
"dwarf_loclists_get_lle_head() "
"via attribute(secb)");
} else {
/* There is an error to be
generated later */
}
}
}
res = _dwarf_load_section(dbg,
&dbg->de_debug_loclists,
error);
if (res == DW_DLV_ERROR) {
return res;
}
}
attrnum = attr->ar_attribute;
cuversionstamp = ctx->cc_version_stamp;
address_size = ctx->cc_address_size;
is_dwo = ctx->cc_is_dwo;
lkind = determine_location_lkind(cuversionstamp, lkind = determine_location_lkind(cuversionstamp,
form, is_dwo); form, is_dwo);
if (lkind == DW_LKIND_unknown) { if (lkind == DW_LKIND_unknown) {
@ -1663,27 +1727,29 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
llhead->ll_attrform = (Dwarf_Half)form; llhead->ll_attrform = (Dwarf_Half)form;
llhead->ll_dbg = dbg; llhead->ll_dbg = dbg;
llhead->ll_address_size = address_size; llhead->ll_address_size = address_size;
llhead->ll_offset_size = cucontext->cc_length_size; llhead->ll_offset_size = ctx->cc_length_size;
llhead->ll_context = cucontext; llhead->ll_context = ctx;
llhead->ll_magic = LOCLISTS_MAGIC; llhead->ll_magic = LOCLISTS_MAGIC;
llhead->ll_at_loclists_base_present = llhead->ll_at_loclists_base_present =
cucontext->cc_loclists_base_present; ctx->cc_loclists_base_present;
llhead->ll_at_loclists_base = cucontext->cc_loclists_base; llhead->ll_at_loclists_base = ctx->cc_loclists_base;
llhead->ll_cu_base_address_present = cucontext->cc_low_pc_present; llhead->ll_cu_base_address_present =
llhead->ll_cu_base_address = cucontext->cc_low_pc; ctx->cc_base_address_present;
llhead->ll_cu_addr_base = cucontext->cc_addr_base; llhead->ll_cu_base_address = ctx->cc_base_address;
llhead->ll_cu_addr_base_present =
cucontext->cc_addr_base_present; llhead->ll_cu_addr_base_offset = ctx->cc_addr_base_offset;
llhead->ll_cu_addr_base_offset_present =
ctx->cc_addr_base_offset_present;
if (lkind == DW_LKIND_loclist || if (lkind == DW_LKIND_loclist ||
lkind == DW_LKIND_GNU_exp_list) { lkind == DW_LKIND_GNU_exp_list) {
int ores = 0; int ores = 0;
/* Here we have a loclist to deal with. */ /* Here we have a loclist to deal with. */
ores = context_is_cu_not_tu(cucontext,&is_cu); ores = context_is_cu_not_tu(ctx,&is_cu);
if (ores != DW_DLV_OK) { if (ores != DW_DLV_OK) {
dwarf_dealloc_loc_head_c(llhead); dwarf_dealloc_loc_head_c(llhead);
return setup_res; return ores;
} }
ores = _dwarf_original_loclist_build(dbg, ores = _dwarf_original_loclist_build(dbg,
llhead, attr, error); llhead, attr, error);
@ -1715,7 +1781,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
int leres = 0; int leres = 0;
leres = _dwarf_loclists_fill_in_lle_head(dbg, leres = _dwarf_loclists_fill_in_lle_head(dbg,
attr,llhead,error); attr,form,attr_val,llhead,error);
if (leres != DW_DLV_OK) { if (leres != DW_DLV_OK) {
dwarf_dealloc_loc_head_c(llhead); dwarf_dealloc_loc_head_c(llhead);
return leres; return leres;

View File

@ -208,14 +208,15 @@ struct Dwarf_Loc_Head_c_s {
Dwarf_Bool ll_at_loclists_base_present; Dwarf_Bool ll_at_loclists_base_present;
Dwarf_Unsigned ll_at_loclists_base; Dwarf_Unsigned ll_at_loclists_base;
/* DW_AT_low_pc of CU or zero if none. */ /* DW_AT_low_pc originally, , perhaps interited
into dwp from skeleton. */
Dwarf_Bool ll_cu_base_address_present; Dwarf_Bool ll_cu_base_address_present;
Dwarf_Unsigned ll_cu_base_address; Dwarf_Unsigned ll_cu_base_address;
/* DW_AT_addr_base, so we can use .debug_addr /* DW_AT_addr_base, so we can use .debug_addr
if such is needed. */ if such is needed. */
Dwarf_Bool ll_cu_addr_base_present; Dwarf_Bool ll_cu_addr_base_offset_present;
Dwarf_Unsigned ll_cu_addr_base; Dwarf_Unsigned ll_cu_addr_base_offset;
Dwarf_Small * ll_llepointer; Dwarf_Small * ll_llepointer;
Dwarf_Unsigned ll_llearea_offset; Dwarf_Unsigned ll_llearea_offset;
@ -252,6 +253,8 @@ void _dwarf_loclists_head_destructor(void *l);
int _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, int _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
Dwarf_Attribute attr, Dwarf_Attribute attr,
Dwarf_Half theform,
Dwarf_Unsigned attr_val,
Dwarf_Loc_Head_c llhead, Dwarf_Loc_Head_c llhead,
Dwarf_Error *error); Dwarf_Error *error);

View File

@ -324,7 +324,7 @@ read_single_lle_entry(Dwarf_Debug dbg,
preserve a testing baseline: preserve a testing baseline:
baselines/hongg2024-02-18-m.base baselines/hongg2024-02-18-m.base
otherwise we would test against sectionsize first.*/ otherwise we would test against sectionsize first.*/
Dwarf_Unsigned sectionsize = dbg->de_debug_loclists.dss_size; Dwarf_Unsigned section_size = dbg->de_debug_loclists.dss_size;
if (data > enddata || data < startdata ) { if (data > enddata || data < startdata ) {
/* Corrupt data being read. */ /* Corrupt data being read. */
@ -334,7 +334,7 @@ read_single_lle_entry(Dwarf_Debug dbg,
"of its allowed space"); "of its allowed space");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
if (count > sectionsize) { if (count > section_size) {
/* Corrupt data being read. */ /* Corrupt data being read. */
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR, _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"DW_DLE_LOCLISTS_ERROR: " "DW_DLE_LOCLISTS_ERROR: "
@ -501,12 +501,12 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg,
} /* else no offset table */ } /* else no offset table */
buildhere->lc_offsets_off_in_sect = offset+localoff; buildhere->lc_offsets_off_in_sect = offset+localoff;
buildhere->lc_first_loclist_offset = offset+localoff+ buildhere->lc_first_loclist_offset =
lists_len; buildhere->lc_offsets_off_in_sect + lists_len;
buildhere->lc_loclists_header = startdata; buildhere->lc_loclists_header = startdata;
buildhere->lc_endaddr = startdata +buildhere->lc_length; buildhere->lc_endaddr = startdata + buildhere->lc_length;
buildhere->lc_past_last_loclist_offset = buildhere->lc_past_last_loclist_offset =
buildhere->lc_header_offset +buildhere->lc_length; buildhere->lc_header_offset + buildhere->lc_length;
*next_offset = buildhere->lc_past_last_loclist_offset; *next_offset = buildhere->lc_past_last_loclist_offset;
return DW_DLV_OK; return DW_DLV_OK;
} }
@ -719,6 +719,14 @@ dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg,
READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned, READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned,
offsetptr, offsetptr,
offset_len,error,con->lc_endaddr); offset_len,error,con->lc_endaddr);
if (targetoffset >= con->lc_length) {
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"DW_DLE_LOCLISTS_ERROR: "
"An lle target offset value is "
"Too large to be real");
return DW_DLV_ERROR;
}
if (offset_value_out) { if (offset_value_out) {
*offset_value_out = targetoffset; *offset_value_out = targetoffset;
} }
@ -797,8 +805,9 @@ int dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c head,
*loclists_base_address_present = head->ll_cu_base_address_present; *loclists_base_address_present = head->ll_cu_base_address_present;
*loclists_base_address= head->ll_cu_base_address; *loclists_base_address= head->ll_cu_base_address;
*loclists_debug_addr_base_present = head->ll_cu_addr_base_present; *loclists_debug_addr_base_present =
*loclists_debug_addr_base = head->ll_cu_addr_base; head->ll_cu_addr_base_offset_present;
*loclists_debug_addr_base = head->ll_cu_addr_base_offset;
*loclists_offset_lle_set = head->ll_llearea_offset; *loclists_offset_lle_set = head->ll_llearea_offset;
return DW_DLV_OK; return DW_DLV_OK;
} }
@ -938,10 +947,14 @@ int dwarf_get_loclist_lle(Dwarf_Debug dbg,
return res; return res;
} }
/* We have more data than we need here if the compiler
provided a loclists_base_address or provided
a DW_SECT_LOCLISTS Per_CU value set for loclists.
Or we plucked an offset from .debug_addr. */
static int static int
_dwarf_which_loclists_context(Dwarf_Debug dbg, _dwarf_which_loclists_context(Dwarf_Debug dbg,
Dwarf_CU_Context ctx, Dwarf_CU_Context ctx,
Dwarf_Unsigned loclist_offset, Dwarf_Unsigned loclist_offset /* Not always set */,
Dwarf_Unsigned *index, Dwarf_Unsigned *index,
Dwarf_Error *error) Dwarf_Error *error)
{ {
@ -951,97 +964,77 @@ _dwarf_which_loclists_context(Dwarf_Debug dbg,
Dwarf_Loclists_Context rcx = 0; Dwarf_Loclists_Context rcx = 0;
Dwarf_Unsigned rcxoff = 0; Dwarf_Unsigned rcxoff = 0;
Dwarf_Unsigned rcxend = 0; Dwarf_Unsigned rcxend = 0;
Dwarf_Unsigned loclists_base = 0;
Dwarf_Bool loclists_base_present = FALSE;
int res = 0;
Dwarf_Bool found_base = FALSE;
Dwarf_Unsigned chosen_offset = 0;
array = dbg->de_loclists_context; array = dbg->de_loclists_context;
count = dbg->de_loclists_context_count; count = dbg->de_loclists_context_count;
if (!array) { if (!array) {
return DW_DLV_NO_ENTRY; return DW_DLV_NO_ENTRY;
} }
if (count == 1) {
*index = 0;
return DW_DLV_OK;
}
if (ctx->cc_loclists_base_present) {
loclists_base_present = ctx->cc_loclists_base_present;
loclists_base = ctx->cc_loclists_base;
found_base = TRUE;
chosen_offset = loclists_base;
}
if (!found_base) {
res = _dwarf_has_SECT_fission(ctx,
DW_SECT_LOCLISTS,
&loclists_base_present,&loclists_base);
if (res == DW_DLV_OK) {
found_base = TRUE;
chosen_offset = loclists_base;
}
}
if (!found_base) {
loclists_base = loclist_offset;
chosen_offset = loclist_offset;
}
rcx = array[i]; rcx = array[i];
rcxoff = rcx->lc_header_offset; rcxoff = rcx->lc_header_offset;
rcxend = rcxoff + rcx->lc_length; rcxend = rcxoff + rcx->lc_length;
if (!ctx->cc_loclists_base_present) { /* We look at the location of each loclist context
/* We look at the location of each loclist context to find one with the offset we want */
to find one with the offset the DIE gave us. */ for ( i = 0 ; i < count; ++i) {
for ( i = 0 ; i < count; ++i) { rcx = array[i];
rcx = array[i]; rcxoff = rcx->lc_header_offset;
rcxoff = rcx->lc_header_offset; rcxend = rcxoff +
rcxend = rcxoff + rcx->lc_length;
rcx->lc_length; rcxend = rcxoff +
rcxend = rcxoff + rcx->lc_length;
rcx->lc_length; if (chosen_offset < rcxoff){
if (loclist_offset < rcxoff){ continue;
continue;
}
if (loclist_offset < rcxend ){
*index = i;
return DW_DLV_OK;
}
} }
{ if (chosen_offset < rcxend ){
dwarfstring m; *index = i;
return DW_DLV_OK;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_LOCLISTS_ERROR: loclist ran off end "
" finding target offset of"
" 0x%" DW_PR_XZEROS DW_PR_DUx ,loclist_offset);
dwarfstring_append(&m,
" Not found anywhere in .debug_loclists "
"data. Corrupted data?");
_dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
} }
} else { }
/* We have a DW_AT_loclists_base (lc_loclists_base), {
let's use it. */ dwarfstring m;
Dwarf_Unsigned lookfor = 0;;
lookfor = ctx->cc_loclists_base;
for ( i = 0 ; i < count; ++i) {
dwarfstring m;
rcx = array[i]; dwarfstring_constructor(&m);
if (rcx->lc_offsets_off_in_sect == lookfor){ dwarfstring_append_printf_u(&m,
*index = i; "DW_DLE_LOCLISTS_ERROR: loclist ran off end "
return DW_DLV_OK; " finding target offset of"
} " 0x%" DW_PR_XZEROS DW_PR_DUx ,chosen_offset);
if (rcx->lc_offsets_off_in_sect < lookfor){ dwarfstring_append(&m,
continue; " Not found anywhere in .debug_loclists[.dwo] "
} "data. Corrupted data?");
_dwarf_error_string(dbg,error,
dwarfstring_constructor(&m); DW_DLE_LOCLISTS_ERROR,
dwarfstring_append_printf_u(&m, dwarfstring_string(&m));
"DW_DLE_LOCLISTS_ERROR: loclists base of " dwarfstring_destructor(&m);
" 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
dwarfstring_append_printf_u(&m,
" was not found though we are now at base "
" 0x%" DW_PR_XZEROS DW_PR_DUx ,
rcx->lc_offsets_off_in_sect);
_dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
{
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_LOCLISTS_ERROR: loclist base of "
" 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
dwarfstring_append(&m,
" was not found anywhere in .debug_loclists "
"data. Corrupted data?");
_dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
} }
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
@ -1077,33 +1070,6 @@ alloc_rle_and_append_to_list(Dwarf_Debug dbg,
return DW_DLV_OK; 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 /* Read the group of loclists entries, and
finally build an array of Dwarf_Locdesc_c finally build an array of Dwarf_Locdesc_c
records. Attach to rctx here. records. Attach to rctx here.
@ -1226,30 +1192,32 @@ build_array_of_lle(Dwarf_Debug dbg,
*/ */
int int
_dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
Dwarf_Attribute attr, Dwarf_Attribute attr,
Dwarf_Half theform,
Dwarf_Unsigned attr_val,
Dwarf_Loc_Head_c llhead, Dwarf_Loc_Head_c llhead,
Dwarf_Error *error) Dwarf_Error *error)
{ {
int res = 0; int res = 0;
Dwarf_Unsigned loclists_contextnum = 0; Dwarf_Unsigned loclists_contextnum = 0;
Dwarf_Small *table_base = 0; Dwarf_Small *table_base = 0;
Dwarf_Small *table_entry = 0; Dwarf_Small *table_entry = 0;
Dwarf_Small *enddata = 0; Dwarf_Small *enddata = 0;
Dwarf_Loclists_Context *array = 0; Dwarf_Loclists_Context *array = 0;
Dwarf_Loclists_Context rctx = 0; Dwarf_Loclists_Context rctx = 0;
Dwarf_Unsigned entrycount = 0; Dwarf_Unsigned entrycount = 0;
unsigned offsetsize = 0; unsigned offsetsize = 0;
Dwarf_Unsigned lle_global_offset = 0; Dwarf_Unsigned lle_global_offset = 0;
Dwarf_CU_Context ctx = 0; Dwarf_CU_Context ctx = 0;
Dwarf_Unsigned offset_in_loclists = 0; Dwarf_Unsigned offset_in_loclists = 0;
Dwarf_Bool is_loclistx = FALSE; Dwarf_Bool is_loclistx = FALSE;
Dwarf_Half theform = llhead->ll_attrform; Dwarf_Unsigned secsize = 0;
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 (theform == DW_FORM_loclistx) {
is_loclistx = TRUE;
} else {
offset_in_loclists = attr_val;
}
if (!attr) { if (!attr) {
_dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL,
"DW_DLE_DBG_NULL " "DW_DLE_DBG_NULL "
@ -1258,94 +1226,90 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
"_dwarf_loclists_fill_in_lle_head()"); "_dwarf_loclists_fill_in_lle_head()");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
secsize = dbg->de_debug_loclists.dss_size;
ctx = attr->ar_cu_context; ctx = attr->ar_cu_context;
array = dbg->de_loclists_context; array = dbg->de_loclists_context;
if (theform == DW_FORM_loclistx) { if (dbg != ctx->cc_dbg) {
Dwarf_Bool offset_is_info = 0; /* is_loclistx TRUE */
is_loclistx = TRUE; /* Now find the correct secondary CU context via
res = dwarf_global_formref_b(attr, signature. */
&attr_val, &offset_is_info, error); Dwarf_CU_Context lctx = 0;
if (res != DW_DLV_OK) {
return res; if (ctx->cc_signature_present) {
} /* Looking in current dbg for the correct cu context */
} else { res = _dwarf_search_for_signature(dbg,
if (theform == DW_FORM_sec_offset) { ctx->cc_signature,
/* DW_FORM_sec_offset is not formudata , often &lctx,error);
seen in in DW5 DW_AT_location etc */
res = dwarf_global_formref(attr, &attr_val,error);
if (res != DW_DLV_OK) { if (res != DW_DLV_OK) {
if (res == DW_DLV_ERROR) {
_dwarf_error_string(dbg,error, DW_DLE_LLE_ERROR,
"DW_DLE_RLE_ERROR: a .debug_loclists "
"cu context cannot be found with the "
"correct signature");
}
return res; return res;
} else {
ctx = lctx;
} }
} else {
/* No signature. Hopeless, I think. */
_dwarf_error_string(dbg,error, DW_DLE_LLE_ERROR,
"DW_DLE_LLE_ERROR: a .debug_loclists "
"cu context cannot be found as there is "
"no signature to use");
return DW_DLV_ERROR;
} }
} }
if (is_loclistx) { /* A */
if (loclists_base_present) { if (ctx->cc_loclists_base_present) {
offset_in_loclists = loclists_base; offset_in_loclists = ctx->cc_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"
" %u" ,attr_val);
dwarfstring_append(&m,
" 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;
}
ctx->cc_loclists_base_present = TRUE;
ctx->cc_loclists_base = ibase;
offset_in_loclists = ibase;
}
} else { } else {
offset_in_loclists = attr_val; offset_in_loclists = attr_val;
} }
res = _dwarf_which_loclists_context(dbg,ctx,
offset_in_loclists, if (offset_in_loclists >= secsize) {
&loclists_contextnum,error); _dwarf_error_string(dbg,error, DW_DLE_LLE_ERROR,
if (res != DW_DLV_OK) { "DW_DLE_LLE_ERROR: a .debug_loclists offset "
return res; "is greater than the loclists section size");
return DW_DLV_ERROR;
} }
/* B */
{
res = _dwarf_which_loclists_context(dbg,ctx,
offset_in_loclists,
&loclists_contextnum,error);
if (res == DW_DLV_OK) {
/* FALL THROUGH */
} else if (res == DW_DLV_NO_ENTRY) {
loclists_contextnum = 0;
/* FALL THROUGH */
} else {
return res;
}
}
/* C */
rctx = array[loclists_contextnum]; rctx = array[loclists_contextnum];
table_base = rctx->lc_offsets_array; table_base = rctx->lc_offsets_array;
entrycount = rctx->lc_offset_entry_count; entrycount = rctx->lc_offset_entry_count;
offsetsize = rctx->lc_offset_size; offsetsize = rctx->lc_offset_size;
enddata = rctx->lc_endaddr; enddata = rctx->lc_endaddr;
if (is_loclistx) { if (is_loclistx && attr_val >= entrycount) {
if (attr_val >= entrycount) { dwarfstring m;
dwarfstring m;
dwarfstring_constructor(&m); dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&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); " %u" ,attr_val);
dwarfstring_append_printf_u(&m, dwarfstring_append_printf_u(&m,
" too large for table of %u " " too large for table of %u "
"entries.",entrycount); "entries.",entrycount);
_dwarf_error_string(dbg,error, _dwarf_error_string(dbg,error,
DW_DLE_LOCLISTS_ERROR, DW_DLE_LOCLISTS_ERROR,
dwarfstring_string(&m)); dwarfstring_string(&m));
dwarfstring_destructor(&m); dwarfstring_destructor(&m);
return DW_DLV_ERROR; return DW_DLV_ERROR;
}
} }
llhead->ll_localcontext = rctx; llhead->ll_localcontext = rctx;
llhead->ll_index = loclists_contextnum; llhead->ll_index = loclists_contextnum;
@ -1354,21 +1318,49 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
llhead->ll_address_size = rctx->lc_address_size; llhead->ll_address_size = rctx->lc_address_size;
llhead->ll_segment_selector_size = llhead->ll_segment_selector_size =
rctx->lc_segment_selector_size; rctx->lc_segment_selector_size;
/* D */
if (is_loclistx) { if (is_loclistx) {
Dwarf_Unsigned table_entryval = 0; Dwarf_Unsigned table_entryval = 0;
Dwarf_Unsigned globaloff = 0;
table_entry = attr_val*offsetsize + table_base; table_entry = attr_val*offsetsize + table_base;
/* No malloc here yet so no leak if the macro returns /* No malloc here yet so no leak if the macro returns
DW_DLV_ERROR */ DW_DLV_ERROR */
READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned, READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned,
table_entry,offsetsize,error,enddata); table_entry,offsetsize,error,enddata);
lle_global_offset = rctx->lc_offsets_off_in_sect + if (table_entryval >= rctx->lc_length) {
table_entryval; _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"DW_DLE_LOCLISTS_ERROR: "
"A DW_FORM_loclistx value is too large for "
"the space in .debug_loclists[.dwo]");
return DW_DLV_ERROR;
}
globaloff = rctx->lc_offsets_off_in_sect + table_entryval;
lle_global_offset = globaloff;
if (lle_global_offset >= secsize) {
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"DW_DLE_LOCLISTS_ERROR: "
"A DW_FORM_loclistx global offset is too large to "
"the space in .debug_loclists[.dwo]");
return DW_DLV_ERROR;
}
} else { } else {
lle_global_offset = attr_val; lle_global_offset = attr_val;
if (lle_global_offset >= secsize) {
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
"DW_DLE_LOCLISTS_ERROR: "
"A loclist global offset is too large for "
"the space in .debug_loclists[.dwo]");
return DW_DLV_ERROR;
}
} }
/* E */
llhead->ll_end_data_area = enddata; llhead->ll_end_data_area = enddata;
llhead->ll_cu_base_address_present =
ctx->cc_base_address_present;
llhead->ll_cu_base_address = ctx->cc_base_address;
llhead->ll_dbg = dbg;
llhead->ll_llearea_offset = lle_global_offset; llhead->ll_llearea_offset = lle_global_offset;
llhead->ll_llepointer = lle_global_offset + llhead->ll_llepointer = lle_global_offset +

View File

@ -119,14 +119,20 @@ static struct macho_sect_names_s {
{ "__debug_aranges", ".debug_aranges" }, { "__debug_aranges", ".debug_aranges" },
{ "__debug_frame", ".debug_frame" }, { "__debug_frame", ".debug_frame" },
{ "__debug_info", ".debug_info" }, { "__debug_info", ".debug_info" },
{ "__debug_addr", ".debug_addr" },
{ "__debug_line", ".debug_line" }, { "__debug_line", ".debug_line" },
{ "__debug_rnglists", ".debug_rnglists" },
{ "__debug_loclists", ".debug_loclists" },
{ "__debug_macinfo", ".debug_macinfo" }, { "__debug_macinfo", ".debug_macinfo" },
{ "__debug_loc", ".debug_loc" }, { "__debug_loc", ".debug_loc" },
{ "__debug_pubnames", ".debug_pubnames" }, { "__debug_pubnames", ".debug_pubnames" },
{ "__debug_pubtypes", ".debug_pubtypes" }, { "__debug_pubtypes", ".debug_pubtypes" },
{ "__debug_str", ".debug_str" }, { "__debug_str", ".debug_str" },
{ "__debug_str_offs", ".debug_str_offsets" },
{ "__debug_line_str", ".debug_line_str" },
{ "__debug_ranges", ".debug_ranges" }, { "__debug_ranges", ".debug_ranges" },
{ "__debug_macro", ".debug_macro" }, { "__debug_macro", ".debug_macro" },
{ "__debug_names", ".debug_names" },
{ "__debug_gdb_scri", ".debug_gdb_scripts" } { "__debug_gdb_scri", ".debug_gdb_scripts" }
}; };

View File

@ -331,7 +331,10 @@ dwarf_get_macro_details(Dwarf_Debug dbg,
break; break;
case DW_MACINFO_end_file: case DW_MACINFO_end_file:
if (--depth == 0) { if (depth) {
--depth;
}
if (!depth) {
/* done = 1; no, do not stop here, /* done = 1; no, do not stop here,
at least one gcc had at least one gcc had
the wrong depth settings in the the wrong depth settings in the

View File

@ -653,7 +653,7 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context,
*macro_string = *macro_string =
(char *)"<Error: DW_FORM_str_sup-got-error>"; (char *)"<Error: DW_FORM_str_sup-got-error>";
} }
dwarf_dealloc(dbg,lerr,DW_DLA_ERROR); dwarf_dealloc_error(dbg,lerr);
} else { } else {
*macro_string = "<DW_FORM_str_sup-no-entry>"; *macro_string = "<DW_FORM_str_sup-no-entry>";
} }

View File

@ -1,5 +1,5 @@
/* Generated routines, do not edit. */ /* Generated routines, do not edit. */
/* Generated for source version 0.9.3 */ /* Generated for source version 0.11.1 */
/* BEGIN FILE */ /* BEGIN FILE */

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
Portions Copyright (C) 2007-2023 David Anderson. All Rights Reserved. Portions Copyright (C) 2007-2024 David Anderson. All Rights Reserved.
Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
This program is free software; you can redistribute it This program is free software; you can redistribute it
@ -70,6 +70,31 @@
.debug_tu_index - - - 5 .debug_tu_index - - - 5
*/ */
#define DBG_IS_SECONDARY(p) ((p) && (p)->de_secondary_dbg && \
((p)->de_secondary_dbg == (p)))
#define DBG_IS_PRIMARY(p) ((p) && ((!(p)->de_secondary_dbg) || \
((p)->de_secondary_dbg && ((p)->de_secondary_dbg != (p)))))
#define DBG_HAS_SECONDARY(p) (DBG_IS_PRIMARY(p) && \
(DBG_IS_SECONDARY((p)->de_secondary_dbg)))
#define DEBUG_PRIMARY_DBG 1 /* only for debugging */
#undef DEBUG_PRIMARY_DBG
#ifdef DEBUG_PRIMARY_DBG
const char *
_dwarf_basename(const char *full);
void
_dwarf_print_is_primary(const char *msg,Dwarf_Debug p,int line,
const char *filepath);
void
_dwarf_dump_prim_sec(const char *msg,Dwarf_Debug p, int line,
const char *filepath);
void
_dwarf_dump_optional_fields(const char *msg,
Dwarf_CU_Context context,
int line,
const char *filepath);
#endif /* DEBUG_PRIMARY_DBG */
struct Dwarf_Rnglists_Context_s; struct Dwarf_Rnglists_Context_s;
typedef struct Dwarf_Rnglists_Context_s *Dwarf_Rnglists_Context; typedef struct Dwarf_Rnglists_Context_s *Dwarf_Rnglists_Context;
@ -111,6 +136,7 @@ struct Dwarf_Attribute_s {
}; };
#define CC_PROD_METROWERKS 1 #define CC_PROD_METROWERKS 1
#define CC_PROD_Apple 2 /* Apple clang */
/* /*
This structure provides the context for a compilation unit. This structure provides the context for a compilation unit.
@ -228,8 +254,17 @@ struct Dwarf_CU_Context_s {
Dwarf_Bool cc_signature_present; /* Meaning type signature Dwarf_Bool cc_signature_present; /* Meaning type signature
in TU header or, for CU header, signature in CU DIE. */ in TU header or, for CU header, signature in CU DIE. */
/* cc_low_pc[_present] is applied as base address of
of rnglists and loclists when reading an rle_head,
compied into cc_cu_base_address. Comes from
CU_DIE, not rnglists or loclists */
Dwarf_Bool cc_low_pc_present; Dwarf_Bool cc_low_pc_present;
Dwarf_Bool cc_addr_base_present; /* Not TRUE in .dwo */
/* From CU_DIE. Copied from cc_low_pc_present.
Used as default base address for rnglists, loclists.
in a DWARF5 dwo, inherited from skeleton (tieddbg). */
Dwarf_Bool cc_base_address_present;
Dwarf_Bool cc_cu_die_has_children; Dwarf_Bool cc_cu_die_has_children;
Dwarf_Bool cc_dwo_name_present; Dwarf_Bool cc_dwo_name_present;
@ -243,6 +278,9 @@ struct Dwarf_CU_Context_s {
cc_cu_die_global_sec_offset is meaningful. */ cc_cu_die_global_sec_offset is meaningful. */
Dwarf_Bool cc_cu_die_offset_present; Dwarf_Bool cc_cu_die_offset_present;
Dwarf_Bool cc_at_ranges_offset_present; Dwarf_Bool cc_at_ranges_offset_present;
/* About: DW_AT_addr_base in CU DIE,
offset to .debug_addr table */
Dwarf_Bool cc_addr_base_offset_present;
/* If present, is base address of CU. In DWARF2 /* If present, is base address of CU. In DWARF2
nothing says what attribute is the base address. nothing says what attribute is the base address.
@ -256,8 +294,13 @@ struct Dwarf_CU_Context_s {
In DWARF3, DWARF4 DW_AT_low_pc is specifically In DWARF3, DWARF4 DW_AT_low_pc is specifically
mentioned as the base address. */ mentioned as the base address. */
Dwarf_Unsigned cc_low_pc; Dwarf_Unsigned cc_low_pc;
/* from DW_AT_addr_base in CU DIE, offset to .debug_addr table */ /* from DW_AT_addr_base in CU DIE, offset to .debug_addr table */
Dwarf_Unsigned cc_addr_base; /* Zero in .dwo */ Dwarf_Unsigned cc_addr_base_offset; /* Zero in .dwo */
/* From cc_low_pc, used as initial base_address
in processing loclists and rnglists */
Dwarf_Unsigned cc_base_address;
/* DW_SECT_LINE */ /* DW_SECT_LINE */
Dwarf_Bool cc_line_base_present; /*DW5 */ Dwarf_Bool cc_line_base_present; /*DW5 */
@ -542,19 +585,13 @@ struct Dwarf_Tied_Data_s {
Pointer to the tied_to Dwarf_Debug*/ Pointer to the tied_to Dwarf_Debug*/
Dwarf_Debug td_tied_object; 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. /* Used for Type Unit signatures.
Type Units are in .debug_types in DW4 Type Units are in .debug_types in DW4
but in .debug_info in DW5. but in .debug_info in DW5.
Some .debug_info point to them symbolically Some .debug_info point to them symbolically
via DW_AT_signature attributes. via DW_AT_signature attributes.
If non-zero is a dwarf_tsearch 'tree'. If non-zero is a dwarf_tsearch 'tree'.
Only non-zero if td_is_tied_object is set and Only non-zero if
we had a reason to build the search tree.. we had a reason to build the search tree..
Type Units have a Dwarf_Sig8 signature Type Units have a Dwarf_Sig8 signature
in the header, and such is recorded here. in the header, and such is recorded here.
@ -563,7 +600,7 @@ struct Dwarf_Tied_Data_s {
signatures in split-dwarf (dwo/dwp) sections. signatures in split-dwarf (dwo/dwp) sections.
The Key for each record is a Dwarf_Sig8 (8 bytes). The Key for each record is a Dwarf_Sig8 (8 bytes).
The data for each is a pointer to a Dwarf_CU_context The data for each is a pointer to a Dwarf_CU_Context
record in this dbg (cu_context in record in this dbg (cu_context in
one of tied dbg's de_cu_context_list). */ one of tied dbg's de_cu_context_list). */
void *td_tied_search; void *td_tied_search;
@ -599,6 +636,15 @@ struct Dwarf_Debug_s {
structure and contents. */ structure and contents. */
struct Dwarf_Obj_Access_Interface_a_s *de_obj_file; struct Dwarf_Obj_Access_Interface_a_s *de_obj_file;
/* See dwarf_generic_init.c comments on the
use of the next four fields. And see
DBG_IS_SECONDARY(p) DBG_IS_PRIMARY(p)
DBG_HAS_SECONDARY(p) below and also dwarf_util.c */
struct Dwarf_Debug_s * de_dbg;
struct Dwarf_Debug_s * de_primary_dbg;
struct Dwarf_Debug_s * de_secondary_dbg;
struct Dwarf_Debug_s * de_errors_dbg;
Dwarf_Handler de_errhand; Dwarf_Handler de_errhand;
Dwarf_Ptr de_errarg; Dwarf_Ptr de_errarg;
@ -958,8 +1004,7 @@ int _dwarf_search_for_signature(Dwarf_Debug dbg,
Dwarf_CU_Context *context_out, Dwarf_CU_Context *context_out,
Dwarf_Error *error); Dwarf_Error *error);
int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_CU_Context context,
Dwarf_CU_Context context,
Dwarf_Debug tieddbg, Dwarf_Debug tieddbg,
Dwarf_CU_Context *tiedcontext_out, Dwarf_CU_Context *tiedcontext_out,
Dwarf_Error *error); Dwarf_Error *error);
@ -1155,9 +1200,22 @@ _dwarf_internal_global_formref_b(Dwarf_Attribute attr,
Dwarf_Bool * offset_is_info, Dwarf_Bool * offset_is_info,
Dwarf_Error * error); Dwarf_Error * error);
int _dwarf_skip_leb128(char * /*leb*/, int
Dwarf_Unsigned * /*leblen*/, _dwarf_has_SECT_fission(Dwarf_CU_Context ctx,
char * /*endptr*/); unsigned int SECT_number, /* example: DW_SECT_RNGLISTS */
Dwarf_Bool *hasfissionoffset,
Dwarf_Unsigned *loclistsbase);
int _dwarf_skip_leb128(char * leb,
Dwarf_Unsigned * leblen,
char * endptr);
/* Used for DW_AT_ranges to get base address along with
dwarf_lowpc() */
int
_dwarf_entrypc(Dwarf_Die die,
Dwarf_Addr *return_addr,
Dwarf_Error *error);
int _dwarf_get_suppress_debuglink_crc(void); int _dwarf_get_suppress_debuglink_crc(void);
void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig, int lineno); void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig, int lineno);

View File

@ -566,7 +566,8 @@ _dwarf_pe_load_dwarf_section_headers(
if (sec_outp->VirtualSize > if (sec_outp->VirtualSize >
((Dwarf_Unsigned)2000* ((Dwarf_Unsigned)2000*
(Dwarf_Unsigned)1000* (Dwarf_Unsigned)1000*
(Dwarf_Unsigned)1000)) { (Dwarf_Unsigned)1000) &&
(sec_outp->VirtualSize > pep->pe_filesize)) {
/* Likely unreasonable. /* Likely unreasonable.
the hard limit written this way the hard limit written this way
simply for clarity. simply for clarity.
@ -574,7 +575,8 @@ _dwarf_pe_load_dwarf_section_headers(
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL; *errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
if (sec_outp->VirtualSize > limit) { if (sec_outp->VirtualSize > limit &&
0 == pep->pe_is_64bit ) {
/* Likely totally unreasonable. Bad. */ /* Likely totally unreasonable. Bad. */
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL; *errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
return DW_DLV_ERROR; return DW_DLV_ERROR;

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Cropyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved.
Portions Copyright (C) 2007-2022 David Anderson. All Rights Reserved. Portions Copyright (C) 2007-2022 David Anderson. All Rights Reserved.
Portions Copyright 2012 SN Systems Ltd. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved.
Portions Copyright 2020 Google All rights reserved. Portions Copyright 2020 Google All rights reserved.
@ -814,7 +814,13 @@ _dwarf_get_value_ptr(Dwarf_Die die,
of debug_info or debug_types or a of debug_info or debug_types or a
section is unreasonably sized or we are section is unreasonably sized or we are
pointing to two different sections? */ pointing to two different sections? */
_dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD); _dwarf_error_string(dbg,error,
DW_DLE_DIE_ABBREV_BAD,
"DW_DLE_DIE_ABBREV_BAD: in calculating the "
"size of a value based on abbreviation data "
"we find there is not enough room in "
"the .debug_info "
"section to contain the attribute value.");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
} }
@ -839,6 +845,7 @@ dwarf_die_text(Dwarf_Die die,
res = dwarf_attr(die,attrnum,&attr,&lerr); res = dwarf_attr(die,attrnum,&attr,&lerr);
dbg = die->di_cu_context->cc_dbg; dbg = die->di_cu_context->cc_dbg;
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dbg,lerr);
return DW_DLV_NO_ENTRY; return DW_DLV_NO_ENTRY;
} }
if (res == DW_DLV_NO_ENTRY) { if (res == DW_DLV_NO_ENTRY) {
@ -967,7 +974,7 @@ dwarf_attr(Dwarf_Die die,
Error returned here is on dbg, not tieddbg. Error returned here is on dbg, not tieddbg.
This looks for DW_AT_addr_base and if present This looks for DW_AT_addr_base and if present
adds it in appropriately. adds it in appropriately.
You should use _dwarf_look_in_local_and_tied_by_index() Use _dwarf_look_in_local_and_tied_by_index()
instead of this, in general. instead of this, in general.
*/ */
static int static int
@ -986,12 +993,12 @@ _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
Dwarf_Byte_Ptr sectionend = 0; Dwarf_Byte_Ptr sectionend = 0;
Dwarf_Unsigned sectionsize = 0; Dwarf_Unsigned sectionsize = 0;
address_base = context->cc_addr_base; address_base = context->cc_addr_base_offset;
res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error); res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error);
if (res != DW_DLV_OK) { if (res != DW_DLV_OK) {
/* Ignore the inner error, report something meaningful */ /* Ignore the inner error, report something meaningful */
if (res == DW_DLV_ERROR && error) { if (res == DW_DLV_ERROR && error) {
dwarf_dealloc(dbg,*error, DW_DLA_ERROR); dwarf_dealloc_error(dbg,*error);
*error = 0; *error = 0;
} }
_dwarf_error(dbg,error, _dwarf_error(dbg,error,
@ -1046,6 +1053,10 @@ _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
return DW_DLV_OK; return DW_DLV_OK;
} }
/* Looks for an address (Dwarf_Addr) value vi an
index into debug_addr. If it fails with
DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION we
find a context in tieddbg and look there. */
int int
_dwarf_look_in_local_and_tied_by_index( _dwarf_look_in_local_and_tied_by_index(
Dwarf_Debug dbg, Dwarf_Debug dbg,
@ -1063,11 +1074,12 @@ _dwarf_look_in_local_and_tied_by_index(
error && dwarf_errno(*error) == error && dwarf_errno(*error) ==
DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
&& dbg->de_tied_data.td_tied_object) { && dbg->de_tied_data.td_tied_object) {
/* see also DBG_HAS_SECONDARY macro */
int res3 = 0; int res3 = 0;
/* We do not want to leak error structs... */ /* We do not want to leak error structs... */
/* *error safe */ /* *error safe */
dwarf_dealloc(dbg,*error,DW_DLA_ERROR); dwarf_dealloc_error(dbg,*error);
*error = 0; /* *error safe */ *error = 0; /* *error safe */
/* Any error is returned on dbg, /* Any error is returned on dbg,
not tieddbg. */ not tieddbg. */
@ -1104,9 +1116,11 @@ dwarf_debug_addr_index_to_addr(Dwarf_Die die,
error); error);
return res; return res;
} }
/* ASSERT: /* ASSERT:
attr_form == DW_FORM_GNU_addr_index || attr_form == DW_FORM_GNU_addr_index ||
attr_form == DW_FORM_addrx attr_form == DW_FORM_addrx
We are looking for data in .debug_addr,
which could be in base file or in tied-file..
*/ */
int int
_dwarf_look_in_local_and_tied(Dwarf_Half attr_form, _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
@ -1127,23 +1141,6 @@ _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
if (res2 != DW_DLV_OK) { if (res2 != DW_DLV_OK) {
return res2; return res2;
} }
#if 0 /* An error check that is probably incorect. */
Dwarf_Unsigned addrtabsize = 0;
addrtabsize = dbg->de_debug_addr.dss_size;
If there is no .debug_addr the error here should
not be reported as will report that
via _dwarf_look_in_local_and_tied_by_index
if (!dbg->de_tied_data.td_tied_object &&
(index_to_addr > dbg->de_filesize ||
index_to_addr > addrtabsize ||
(index_to_addr*context->cc_address_size) > addrtabsize)) {
_dwarf_error_string(dbg,error,DW_DLE_ATTR_FORM_OFFSET_BAD,
"DW_DLE_ATTR_FORM_OFFSET_BAD "
"Looking for an index from an addr FORM "
"we find an impossibly large value. Corrupt DWARF");
return DW_DLV_ERROR;
}
#endif
/* error is returned on dbg, not tieddbg. */ /* error is returned on dbg, not tieddbg. */
res2 = _dwarf_look_in_local_and_tied_by_index( res2 = _dwarf_look_in_local_and_tied_by_index(
dbg,context,index_to_addr,return_addr,error); dbg,context,index_to_addr,return_addr,error);
@ -1151,8 +1148,10 @@ _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
} }
int static int
dwarf_lowpc(Dwarf_Die die, _dwarf_lowpc_internal(Dwarf_Die die,
Dwarf_Half attrnum,
const char *msg,
Dwarf_Addr *return_addr, Dwarf_Addr *return_addr,
Dwarf_Error *error) Dwarf_Error *error)
{ {
@ -1173,7 +1172,7 @@ dwarf_lowpc(Dwarf_Die die,
dbg = context->cc_dbg; dbg = context->cc_dbg;
address_size = context->cc_address_size; address_size = context->cc_address_size;
offset_size = context->cc_length_size; offset_size = context->cc_length_size;
res = _dwarf_get_value_ptr(die, DW_AT_low_pc, res = _dwarf_get_value_ptr(die, attrnum,
&attr_form,&info_ptr,0,error); &attr_form,&info_ptr,0,error);
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
return res; return res;
@ -1182,11 +1181,12 @@ dwarf_lowpc(Dwarf_Die die,
return res; return res;
} }
version = context->cc_version_stamp; version = context->cc_version_stamp;
class = dwarf_get_form_class(version,DW_AT_low_pc, class = dwarf_get_form_class(version,attrnum,
offset_size,attr_form); offset_size,attr_form);
if (class != DW_FORM_CLASS_ADDRESS) { if (class != DW_FORM_CLASS_ADDRESS) {
/* Not the correct form for DW_AT_low_pc */ /* Not a correct FORM for low_pc or entry_pc */
_dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS); _dwarf_error_string(dbg, error, DW_DLE_LOWPC_WRONG_CLASS,
(char *)msg);
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
@ -1209,6 +1209,30 @@ dwarf_lowpc(Dwarf_Die die,
*return_addr = ret_addr; *return_addr = ret_addr;
return DW_DLV_OK; return DW_DLV_OK;
} }
int
dwarf_lowpc(Dwarf_Die die,
Dwarf_Addr *return_addr,
Dwarf_Error *error)
{
int res = 0;
res = _dwarf_lowpc_internal (die,DW_AT_low_pc,
"DW_AT_low_pc data unavailable",
return_addr,error);
return res;
}
int
_dwarf_entrypc(Dwarf_Die die,
Dwarf_Addr *return_addr,
Dwarf_Error *error)
{
int res = 0;
res = _dwarf_lowpc_internal (die,DW_AT_entry_pc,
"DW_AT_entry_pc and DW_AT_low_pc data unavailable",
return_addr,error);
return res;
}
/* If 'die' contains the DW_AT_type attribute, it returns /* If 'die' contains the DW_AT_type attribute, it returns
the (global) offset referenced by the attribute through the (global) offset referenced by the attribute through
@ -1245,10 +1269,14 @@ dwarf_dietype_offset(Dwarf_Die die,
} }
/* Only a few values are inherited from the tied /* Only a few values are inherited from the tied
file. Not rnglists or loclists base offsets. */ file. Not rnglists or loclists base offsets?
merging into main context (dwp) from tieddbg (Skeleton).
and returning a pointer to the tiedcontext created here.
(such contexts are freed by dwarf_finish on the tied
object file).
*/
int int
_dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_CU_Context context,
Dwarf_CU_Context context,
Dwarf_Debug tieddbg, Dwarf_Debug tieddbg,
Dwarf_CU_Context *tiedcontext_out, Dwarf_CU_Context *tiedcontext_out,
Dwarf_Error *error) Dwarf_Error *error)
@ -1267,31 +1295,53 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg,
&tiedcontext, &tiedcontext,
error); error);
if ( res == DW_DLV_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; return res;
} }
if ( res == DW_DLV_NO_ENTRY) { if ( res == DW_DLV_NO_ENTRY) {
return res; return res;
} }
if (!context->cc_low_pc_present) { if (tiedcontext->cc_low_pc_present) {
/* A dwo/dwp will not have this, merge from tied
Needed for rnglists/loclists
*/
context->cc_low_pc_present = context->cc_low_pc_present =
tiedcontext->cc_low_pc_present; tiedcontext->cc_low_pc_present;
context-> cc_low_pc= context-> cc_low_pc =
tiedcontext->cc_low_pc; tiedcontext->cc_low_pc;
} }
if (!context->cc_addr_base_present) {
context-> cc_addr_base_present = if (tiedcontext->cc_base_address_present) {
tiedcontext->cc_addr_base_present; context->cc_base_address_present =
context-> cc_addr_base= tiedcontext->cc_base_address_present;
tiedcontext->cc_addr_base; context-> cc_base_address =
tiedcontext->cc_base_address;
} }
if (context->cc_version_stamp == DW_CU_VERSION4 && if (tiedcontext->cc_addr_base_offset_present) {
!context->cc_ranges_base_present) { /* This is a base-offset, not an address. */
context->cc_ranges_base_present = context-> cc_addr_base_offset_present =
tiedcontext->cc_ranges_base_present; tiedcontext->cc_addr_base_offset_present;
context->cc_ranges_base = context-> cc_addr_base_offset=
tiedcontext->cc_ranges_base;; tiedcontext->cc_addr_base_offset;
}
if (context->cc_version_stamp == DW_CU_VERSION4 ||
context->cc_version_stamp == DW_CU_VERSION5) {
#if 0 /* we do not inherit cc_rnglists_base_present */
/* This inheritance has been removed from DWARF6
during 2024. */
if (!context->cc_rnglists_base_present) {
context->cc_rnglists_base_present =
tiedcontext->cc_rnglists_base_present;
context->cc_rnglists_base =
tiedcontext->cc_rnglists_base;
}
#endif
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 (!context->cc_str_offsets_tab_present) { if (!context->cc_str_offsets_tab_present) {
context-> cc_str_offsets_tab_present = context-> cc_str_offsets_tab_present =
@ -1458,7 +1508,7 @@ dwarf_highpc_b(Dwarf_Die die,
*/ */
int int
_dwarf_get_addr_from_tied(Dwarf_Debug dbg, _dwarf_get_addr_from_tied(Dwarf_Debug primary_dbg,
Dwarf_CU_Context context, Dwarf_CU_Context context,
Dwarf_Unsigned index, Dwarf_Unsigned index,
Dwarf_Addr *addr_out, Dwarf_Addr *addr_out,
@ -1471,25 +1521,21 @@ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
Dwarf_Unsigned addrtabsize = 0; Dwarf_Unsigned addrtabsize = 0;
if (!context->cc_signature_present) { if (!context->cc_signature_present) {
_dwarf_error(dbg, error, DW_DLE_NO_SIGNATURE_TO_LOOKUP); _dwarf_error(primary_dbg, error,
DW_DLE_NO_SIGNATURE_TO_LOOKUP);
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
tieddbg = dbg->de_tied_data.td_tied_object; if (!DBG_HAS_SECONDARY(primary_dbg)) {
if (!tieddbg) { _dwarf_error(primary_dbg, error,
_dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE); DW_DLE_NO_TIED_ADDR_AVAILABLE);
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
if (!context->cc_addr_base_present) { tieddbg = primary_dbg->de_secondary_dbg;
/* Does not exist. */
return DW_DLV_NO_ENTRY;
}
res = _dwarf_search_for_signature(tieddbg, res = _dwarf_search_for_signature(tieddbg,
context->cc_signature, context->cc_signature,
&tiedcontext, &tiedcontext,
error); error);
if (res == DW_DLV_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; return res;
} }
if ( res == DW_DLV_NO_ENTRY) { if ( res == DW_DLV_NO_ENTRY) {
@ -1500,7 +1546,8 @@ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
if ( (index > tieddbg->de_filesize || if ( (index > tieddbg->de_filesize ||
index > addrtabsize || index > addrtabsize ||
(index*tiedcontext->cc_address_size) > addrtabsize)) { (index*tiedcontext->cc_address_size) > addrtabsize)) {
_dwarf_error_string(dbg,error,DW_DLE_ATTR_FORM_OFFSET_BAD, _dwarf_error_string(primary_dbg,error,
DW_DLE_ATTR_FORM_OFFSET_BAD,
"DW_DLE_ATTR_FORM_OFFSET_BAD " "DW_DLE_ATTR_FORM_OFFSET_BAD "
"Looking for an index from an addr FORM " "Looking for an index from an addr FORM "
"we find an impossibly large index value for the tied " "we find an impossibly large index value for the tied "
@ -1513,8 +1560,6 @@ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
&local_addr, &local_addr,
error); error);
if ( res == DW_DLV_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; return res;
} }
if ( res == DW_DLV_NO_ENTRY) { if ( res == DW_DLV_NO_ENTRY) {
@ -1814,6 +1859,7 @@ dw_get_special_offset(Dwarf_Half attrnum,
} }
return DW_FORM_CLASS_LOCLISTPTR; return DW_FORM_CLASS_LOCLISTPTR;
} }
case DW_AT_GNU_locviews:
case DW_AT_sibling: case DW_AT_sibling:
case DW_AT_byte_size : case DW_AT_byte_size :
case DW_AT_bit_offset : case DW_AT_bit_offset :
@ -1843,6 +1889,8 @@ dw_get_special_offset(Dwarf_Half attrnum,
case DW_AT_object_pointer: case DW_AT_object_pointer:
case DW_AT_signature: case DW_AT_signature:
return DW_FORM_CLASS_REFERENCE; return DW_FORM_CLASS_REFERENCE;
case DW_AT_GNU_entry_view:
return DW_FORM_CLASS_CONSTANT;
case DW_AT_MIPS_fde: /* SGI/IRIX extension */ case DW_AT_MIPS_fde: /* SGI/IRIX extension */
return DW_FORM_CLASS_FRAMEPTR; return DW_FORM_CLASS_FRAMEPTR;
default: break; default: break;

View File

@ -46,6 +46,9 @@
#include "dwarf_util.h" #include "dwarf_util.h"
#include "dwarf_string.h" #include "dwarf_string.h"
#define DEBUG_RANGES 1
#undef DEBUG_RANGES
struct ranges_entry { struct ranges_entry {
struct ranges_entry *next; struct ranges_entry *next;
Dwarf_Ranges cur; Dwarf_Ranges cur;
@ -129,7 +132,6 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg,
int res = DW_DLV_ERROR; int res = DW_DLV_ERROR;
Dwarf_Unsigned ranges_base = 0; Dwarf_Unsigned ranges_base = 0;
Dwarf_Debug localdbg = dbg; Dwarf_Debug localdbg = dbg;
Dwarf_Error localerror = 0;
/* default for dwarf_get_ranges() */ /* default for dwarf_get_ranges() */
Dwarf_Half die_version = 3; Dwarf_Half die_version = 3;
@ -140,7 +142,8 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg,
CHECK_DBG(dbg,error,"dwarf_get_ranges_b()"); CHECK_DBG(dbg,error,"dwarf_get_ranges_b()");
address_size = localdbg->de_pointer_size; /* default */ address_size = localdbg->de_pointer_size; /* default */
if (die) { if (die) {
/* printing by raw offset from DW_AT_ranges attribute. /* printing DW_AT_ranges attribute. and the local DIE
it belongs to.
If we wind up using the tied file the die_version If we wind up using the tied file the die_version
had better match! It cannot be other than a match. had better match! It cannot be other than a match.
Can return DW_DLV_ERROR, not DW_DLV_NO_ENTRY. Can return DW_DLV_ERROR, not DW_DLV_NO_ENTRY.
@ -187,16 +190,18 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg,
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
return res; return res;
} }
/* FIX. HAS_TIED or ? */
if (res == DW_DLV_NO_ENTRY) { if (res == DW_DLV_NO_ENTRY) {
/* data is in a.out, not dwp */ /* data is in a.out, not dwp */
localdbg = dbg->de_tied_data.td_tied_object; if (!DBG_HAS_SECONDARY(dbg)) {
if (!localdbg) {
return DW_DLV_NO_ENTRY; return DW_DLV_NO_ENTRY;
} }
localdbg = dbg->de_secondary_dbg;
res = _dwarf_load_section(localdbg, res = _dwarf_load_section(localdbg,
&localdbg->de_debug_ranges, &localerror); &localdbg->de_debug_ranges, error);
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
_dwarf_error_mv_s_to_t(localdbg,&localerror,dbg,error); /* Error will automatically be put on dbg (main
dbg), not localdbg (tieddbg) as of late 2024. */
return res; return res;
} }
if (res == DW_DLV_NO_ENTRY) { if (res == DW_DLV_NO_ENTRY) {
@ -248,12 +253,6 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg,
section_end = localdbg->de_debug_ranges.dss_data + section_end = localdbg->de_debug_ranges.dss_data +
localdbg->de_debug_ranges.dss_size; localdbg->de_debug_ranges.dss_size;
rangeptr = localdbg->de_debug_ranges.dss_data; rangeptr = localdbg->de_debug_ranges.dss_data;
#if 0
if (!rangeslocal) {
/* printing ranges where range source is dwp,
here we just assume present. */
}
#endif
rangeptr += rangesoffset; rangeptr += rangesoffset;
beginrangeptr = rangeptr; beginrangeptr = rangeptr;
@ -366,6 +365,12 @@ dwarf_dealloc_ranges(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf,
dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES); dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES);
} }
/* Also used to determine DIE base_address,
but that was wrong.
Only a CU_die DW_AT_low_pc can provide
a CU-wide base address and that is done when a CU is first
read, and available as cucontext->cc_base_address
and cc_base_address_present. */
static int static int
_dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg, _dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
Dwarf_Die dw_die, Dwarf_Die dw_die,
@ -375,12 +380,11 @@ _dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
Dwarf_Unsigned *die_base_addr, Dwarf_Unsigned *die_base_addr,
Dwarf_Error *dw_error) Dwarf_Error *dw_error)
{ {
Dwarf_Bool hasatranges = FALSE; Dwarf_Bool hasatranges = FALSE;
Dwarf_Bool haslowpc = FALSE; Dwarf_Attribute attr = 0;
Dwarf_Attribute attr = 0; Dwarf_Unsigned rangeoffset_local = 0;
Dwarf_Unsigned rangeoffset_local = 0; int res = 0;
int res = 0; Dwarf_CU_Context cucon = 0;
Dwarf_Unsigned local_lowpc = 0;
res = dwarf_hasattr(dw_die,DW_AT_ranges, &hasatranges,dw_error); res = dwarf_hasattr(dw_die,DW_AT_ranges, &hasatranges,dw_error);
if (res != DW_DLV_OK) { if (res != DW_DLV_OK) {
@ -397,43 +401,27 @@ _dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
*dw_error = 0; *dw_error = 0;
} }
return res; return res;
} else {
res = dwarf_global_formref(attr,
&rangeoffset_local, dw_error);
if (res != DW_DLV_OK) {
if (res == DW_DLV_ERROR) {
dwarf_dealloc_attribute(attr);
dwarf_dealloc_error(dw_dbg,*dw_error);
*dw_error = 0;
return res;
}
}
/* rangeoffset_local was set . */
} }
res = dwarf_global_formref(attr,
&rangeoffset_local, dw_error);
if (res != DW_DLV_OK) {
if (res == DW_DLV_ERROR) {
dwarf_dealloc_attribute(attr);
dwarf_dealloc_error(dw_dbg,*dw_error);
*dw_error = 0;
return res;
}
}
cucon = dw_die->di_cu_context;
if (cucon->cc_base_address_present) {
*die_base_addr = cucon->cc_base_address;
*have_die_base_addr = TRUE;
}
/* rangeoffset_local was set . */
dwarf_dealloc_attribute(attr); dwarf_dealloc_attribute(attr);
attr = 0; attr = 0;
*have_die_ranges_offset = TRUE; *have_die_ranges_offset = TRUE;
*die_ranges_offset = rangeoffset_local; *die_ranges_offset = rangeoffset_local;
res = dwarf_hasattr(dw_die,DW_AT_low_pc,&haslowpc,dw_error);
if (res != DW_DLV_OK) {
/* Never returns DW_DLV_NO_ENTRY */
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dw_dbg,*dw_error);
*dw_error = 0;
}
return DW_DLV_OK;;
}
res = dwarf_lowpc(dw_die,&local_lowpc,dw_error);
if (res != DW_DLV_OK) {
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(dw_dbg,*dw_error);
*dw_error = 0;
}
return DW_DLV_OK;
}
*have_die_base_addr = TRUE;
*die_base_addr = local_lowpc;
return DW_DLV_OK; return DW_DLV_OK;
} }
@ -457,8 +445,6 @@ dwarf_get_ranges_baseaddress(Dwarf_Debug dw_dbg,
Dwarf_CU_Context context = 0; Dwarf_CU_Context context = 0;
Dwarf_Unsigned local_ranges_offset = 0; Dwarf_Unsigned local_ranges_offset = 0;
Dwarf_Bool local_ranges_offset_present = FALSE; Dwarf_Bool local_ranges_offset_present = FALSE;
Dwarf_Unsigned local_base_addr= 0;
Dwarf_Bool local_base_addr_present = FALSE;
Dwarf_Bool have_die_ranges_offset = FALSE; Dwarf_Bool have_die_ranges_offset = FALSE;
Dwarf_Unsigned die_ranges_offset = 0; Dwarf_Unsigned die_ranges_offset = 0;
Dwarf_Bool have_die_base_addr = FALSE; Dwarf_Bool have_die_base_addr = FALSE;
@ -520,22 +506,9 @@ dwarf_get_ranges_baseaddress(Dwarf_Debug dw_dbg,
if (dw_at_ranges_offset_present) { if (dw_at_ranges_offset_present) {
*dw_at_ranges_offset_present = local_ranges_offset_present; *dw_at_ranges_offset_present = local_ranges_offset_present;
} }
if (have_die_base_addr) { if (context->cc_base_address_present) {
local_base_addr_present = have_die_base_addr; *dw_baseaddress = context->cc_base_address;
local_base_addr = die_base_addr; *dw_known_base = context->cc_base_address_present;
} else {
if (context->cc_low_pc_present ) {
local_base_addr_present = TRUE;
local_base_addr = context->cc_low_pc;
}
}
if (dw_baseaddress) {
/* Unless cc_low_pc_present is TRUE
cc_low_pc is always zero, and it
could be zero regardless. */
*dw_baseaddress = local_base_addr;
*dw_known_base = local_base_addr_present;
} }
return DW_DLV_OK; return DW_DLV_OK;
} }

File diff suppressed because it is too large Load Diff

View File

@ -112,7 +112,7 @@ struct Dwarf_Rnglists_Entry_s {
Dwarf_Unsigned rle_raw1; Dwarf_Unsigned rle_raw1;
Dwarf_Unsigned rle_raw2; Dwarf_Unsigned rle_raw2;
/* Cooked means the raw values from the .debug_rnglists /* Cooked means the raw values from the .debug_rnglists
section translated to DIE-specific addresses. */ section translated to CU-specific addresses. */
Dwarf_Unsigned rle_cooked1; Dwarf_Unsigned rle_cooked1;
Dwarf_Unsigned rle_cooked2; Dwarf_Unsigned rle_cooked2;
Dwarf_Rnglists_Entry rle_next; Dwarf_Rnglists_Entry rle_next;
@ -148,8 +148,8 @@ struct Dwarf_Rnglists_Head_s {
/* DW_AT_addr_base, so we can use .debug_addr /* DW_AT_addr_base, so we can use .debug_addr
if such is needed. */ if such is needed. */
Dwarf_Bool rh_cu_addr_base_present; Dwarf_Bool rh_cu_addr_base_offset_present;
Dwarf_Unsigned rh_cu_addr_base; Dwarf_Unsigned rh_cu_addr_base_offset;
Dwarf_Small * rh_rlepointer; Dwarf_Small * rh_rlepointer;
Dwarf_Unsigned rh_rlearea_offset; Dwarf_Unsigned rh_rlearea_offset;
Dwarf_Small * rh_end_data_area; Dwarf_Small * rh_end_data_area;

View File

@ -87,7 +87,7 @@ add_debug_section_info(Dwarf_Debug dbg,
secdata->dss_name = name; /* Actual name from object file. */ secdata->dss_name = name; /* Actual name from object file. */
secdata->dss_standard_name = standard_section_name; secdata->dss_standard_name = standard_section_name;
secdata->dss_number = obj_sec_num; secdata->dss_number = obj_sec_num;
secdata->dss_zdebug_requires_decompress = secdata->dss_zdebug_requires_decompress =
(Dwarf_Small)havezdebug; (Dwarf_Small)havezdebug;
/* We don't yet know about SHF_COMPRESSED */ /* We don't yet know about SHF_COMPRESSED */
debug_section->ds_duperr = duperr; debug_section->ds_duperr = duperr;
@ -105,6 +105,25 @@ add_debug_section_info(Dwarf_Debug dbg,
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
/* Avoid adding offest to null s2.
This function avoids a compiler warning:
error: 'strcmp' reading 1 or more bytes
from a region of size 0
Offset is a fixed small positive number. */
static int
both_strings_nonempty(const char *s1, const char *s2, int offset)
{
const char *s3 = 0;
if (!s1 || !s2) {
return FALSE;
}
s3 = s2 + offset;
if (!s1[0] || !s3[0]) {
return FALSE;
}
return TRUE;
}
/* Return DW_DLV_OK etc. /* Return DW_DLV_OK etc.
PRECONDITION: secname and targname are non-null PRECONDITION: secname and targname are non-null
pointers to strings. */ pointers to strings. */
@ -167,8 +186,9 @@ set_up_section(Dwarf_Debug dbg,
So we add -Wnostringop-overread to the build as the error is So we add -Wnostringop-overread to the build as the error is
a false positive. We had to drop stringop-overread a false positive. We had to drop stringop-overread
references in compiler options, such turned off references in compiler options, such turned off
valuable warnings. */ valuable warnings. Oct 2024
if (postzprefix && refined the test to notice empty string */
if (both_strings_nonempty(postzprefix,targname,DPREFIXLEN) &&
!strcmp(postzprefix,targname+DPREFIXLEN)) { !strcmp(postzprefix,targname+DPREFIXLEN)) {
/* zprefix version matches the object section /* zprefix version matches the object section
name so the section is compressed and is name so the section is compressed and is

View File

@ -49,7 +49,7 @@
#include "dwarf_tsearch.h" #include "dwarf_tsearch.h"
#include "dwarf_tied_decls.h" #include "dwarf_tied_decls.h"
#if 0 /*debug dumpsignature */ #ifdef DEBUG_PRIMARY_DBG /*debug dumpsignature */
void void
_dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno)
{ {
@ -139,19 +139,8 @@ _dwarf_loop_reading_debug_info_for_cu(
it seems. Those signatures point from it seems. Those signatures point from
'normal' to 'dwo/dwp' (DWARF4) */ 'normal' to 'dwo/dwp' (DWARF4) */
int is_info = TRUE; int is_info = TRUE;
Dwarf_CU_Context startingcontext = 0;
Dwarf_Unsigned next_cu_offset = 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 (;;) { for (;;) {
int sres = DW_DLV_OK; int sres = DW_DLV_OK;
Dwarf_Half cu_type = 0; Dwarf_Half cu_type = 0;
@ -177,6 +166,9 @@ _dwarf_loop_reading_debug_info_for_cu(
&typeoffset, &typeoffset,
&next_cu_offset, &next_cu_offset,
&cu_type, error); &cu_type, error);
if (sres == DW_DLV_ERROR) {
return sres;
}
if (sres == DW_DLV_NO_ENTRY) { if (sres == DW_DLV_NO_ENTRY) {
break; break;
} }
@ -230,7 +222,10 @@ _dwarf_loop_reading_debug_info_for_cu(
return DW_DLV_OK; return DW_DLV_OK;
} }
/* If out of memory just return DW_DLV_NO_ENTRY. /* If out of memory just return DW_DLV_NO_ENTRY.
This ensures all the tied CU contexts have been
created though the caller has most likely
never tried to read CUs in the tied-file.
*/ */
int int
_dwarf_search_for_signature(Dwarf_Debug tieddbg, _dwarf_search_for_signature(Dwarf_Debug tieddbg,

View File

@ -223,7 +223,8 @@ printf("debugging: initial alloc prime to use %lu\n",prime_to_use);
/* hashtab_ is an array of hs_entry, /* hashtab_ is an array of hs_entry,
indexes 0 through tablesize_ -1. */ indexes 0 through tablesize_ -1. */
base->hashfunc_ = hashfunc; base->hashfunc_ = hashfunc;
base->hashtab_ = calloc(base->tablesize_, sizeof(struct ts_entry)); base->hashtab_ = calloc(base->tablesize_,
sizeof(struct ts_entry));
if (!base->hashtab_) { if (!base->hashtab_) {
free(base); free(base);
return NULL; return NULL;
@ -368,7 +369,8 @@ resize_table(struct hs_base *head,
return; return;
} }
newhead.tablesize_entry_index_ = new_entry_index; newhead.tablesize_entry_index_ = new_entry_index;
newhead.hashtab_ = calloc(newhead.tablesize_, sizeof(struct ts_entry)); newhead.hashtab_ = calloc(newhead.tablesize_,
sizeof(struct ts_entry));
if (!newhead.hashtab_) { if (!newhead.hashtab_) {
/* Oops, too large. Leave table size as is, though /* Oops, too large. Leave table size as is, though
things will get slow as it overfills. */ things will get slow as it overfills. */

View File

@ -70,6 +70,164 @@ dwarf_package_version(void)
{ {
return PACKAGE_VERSION; return PACKAGE_VERSION;
} }
#ifdef DEBUG_PRIMARY_DBG
/* These functions are helpers in printing data while
debugging problems.
In normal use these are not compiled or used.
Created November 2024. */
const char *
_dwarf_basename(const char *full)
{
const char *cp = full;
unsigned slashat = 0;
unsigned charnum = 0;
if (!cp) {
return "null-filepath";
}
for ( ; *cp; ++cp,++charnum) {
if (*cp == '/') {
slashat=charnum;
}
}
if (slashat) {
++slashat; /* skip showing /(slash) */
}
return (full+slashat);
}
void
_dwarf_print_is_primary(const char *msg,
Dwarf_Debug p,
int line,
const char *filepath)
{
const char *basen = 0;
basen = _dwarf_basename(filepath);
if (DBG_IS_SECONDARY(p)) {
printf("%s SECONDARY dbg 0x%lx line %d %s\n",msg,
(unsigned long)p,
line,
basen);
fflush(stdout);
return;
}
if (DBG_IS_PRIMARY(p)) {
printf("%s PRIMARY dbg 0x%lx line %d %s\n",msg,
(unsigned long)p,
line,
basen);
fflush(stdout);
return;
}
printf("%s Error in primary/secondary. %s. "
"Unknown dbg 0x%lx line %d %s\n",
msg,p?"":"null dbg passed in",
(unsigned long)p,line,basen);
fflush(stdout);
}
void
_dwarf_dump_prim_sec(const char *msg,Dwarf_Debug p, int line,
const char *filepath)
{
const char *basen = 0;
basen = _dwarf_basename(filepath);
printf("%s Print Primary/Secondary data from line %d %s",
msg,line,basen);
_dwarf_print_is_primary(msg,p,line,filepath);
printf(" dbg.............: 0x%lx\n",
(unsigned long)p);
printf(" de_dbg..........: 0x%lx\n",
(unsigned long)p->de_dbg);
printf(" de_primary_dbg..: 0x%lx\n",
(unsigned long)p->de_primary_dbg);
printf(" de_secondary_dbg: 0x%lx\n",
(unsigned long)p->de_secondary_dbg);
printf(" de_errors_dbg ..: 0x%lx\n",
(unsigned long)p->de_errors_dbg);
printf(" td_tied_object..: 0x%lx\n",
(unsigned long)p->de_tied_data.td_tied_object);
fflush(stdout);
}
void
_dwarf_dump_optional_fields(const char *msg,
Dwarf_CU_Context context,
int line,
const char *filepath)
{
const char *basen = 0;
Dwarf_Debug dbg = 0;
basen = _dwarf_basename(filepath);
printf("%s Optional Fields line %d %s\n",
msg,line,basen);
if (!context) {
printf(" ERROR: context not passed in \n");
fflush(stdout);
return;
}
dbg = context->cc_dbg;
_dwarf_print_is_primary(" For Inheritance and more",
dbg,line,filepath);
printf(" cc_signature_present.......: %d \n",
context->cc_signature_present);
_dwarf_dumpsig(" signature", &context->cc_signature,line);
printf(" cc_low_pc_present..........: %d 0x%lx\n",
context->cc_low_pc_present,
(unsigned long)context->cc_low_pc);
printf(" cc_base_address_present....: %d 0x%lx\n",
context->cc_base_address_present,
(unsigned long)context->cc_base_address);
printf(" cc_dwo_name_present........: %d %s\n",
context->cc_dwo_name_present,
context->cc_dwo_name?context->cc_dwo_name:
"no-dwo-name-");
/* useful? */
printf(" cc_at_strx_present.........: %d\n",
context->cc_at_strx_present);
/* useful? */
printf(" cc_cu_die_offset_present...: %d \n",
context->cc_cu_die_offset_present);
printf(" cc_at_ranges_offset_present: %d 0x%lx\n",
context->cc_at_ranges_offset_present,
(unsigned long)context->cc_at_ranges_offset);
printf(" cc_addr_base_offset_present: %d 0x%lx\n",
context->cc_addr_base_offset_present,
(unsigned long)context->cc_addr_base_offset);
printf(" cc_line_base_present.......: %d 0x%lx\n",
context->cc_line_base_present,
(unsigned long)context->cc_line_base);
printf(" cc_loclists_base_present...: %d 0x%lx\n",
context->cc_loclists_base_present,
(unsigned long)context->cc_loclists_base);
/* useful? */
printf(" cc_loclists_header_length_present: %d\n",
context->cc_loclists_header_length_present);
printf(" cc_str_offsets_array_offset_present: %d 0x%lx\n",
context->cc_str_offsets_array_offset_present,
(unsigned long)context->cc_str_offsets_array_offset);
/* useful? */
printf(" cc_str_offsets_tab_present.: %d \n",
context->cc_str_offsets_tab_present);
printf(" cc_macro_base_present......: %d 0x%lx\n",
context->cc_macro_base_present,
(unsigned long)context->cc_macro_base_present);
/* useful? */
printf(" cc_macro_header_length_present: %d\n",
context->cc_macro_header_length_present);
printf(" cc_ranges_base_present.....: %d 0x%lx\n",
context->cc_ranges_base_present,
(unsigned long)context->cc_ranges_base);
printf(" cc_rnglists_base_present...: %d 0x%lx\n",
context->cc_rnglists_base_present,
(unsigned long)context->cc_rnglists_base);
/* useful? */
printf(" cc_rnglists_header_length_present: %d\n",
context->cc_rnglists_header_length_present);
fflush(stdout);
}
#endif /* DEBUG_PRIMARY_DBG */
#if 0 /* dump_bytes */ #if 0 /* dump_bytes */
static void static void
@ -125,7 +283,8 @@ static void dump_hash_table(char *msg,
tab->tb_highest_used_entry); tab->tb_highest_used_entry);
for (i = 0; i < tab->tb_table_entry_count; ++i) { for (i = 0; i < tab->tb_table_entry_count; ++i) {
sprintf(buf,"Tab entry %lu:",i); sprintf(buf,sizeof(buf),
"Tab entry %lu:",i); /* Only for debug */
dump_ab_list(" ",buf,i,tab->tb_entries[i],__LINE__); dump_ab_list(" ",buf,i,tab->tb_entries[i],__LINE__);
} }
printf(" ---end hash tab---\n"); printf(" ---end hash tab---\n");
@ -1191,7 +1350,7 @@ _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
return res; return res;
} }
/* debug_info won't be meaningful without /* debug_info won't be meaningful without
.debug_rnglists and .debug_rnglists if there .debug_rnglists and .debug_loclists if there
is one or both such sections. */ is one or both such sections. */
res = dwarf_load_rnglists(dbg,0,error); res = dwarf_load_rnglists(dbg,0,error);
if (res == DW_DLV_ERROR) { if (res == DW_DLV_ERROR) {
@ -1363,53 +1522,6 @@ _dwarf_printf(Dwarf_Debug dbg,
return; return;
} }
/* Often errs and errt point to the same Dwarf_Error,
So exercise care.
All the arguments MUST be non-null, though
we deal with null errs/errt as best we can.
We ensure null dbg? will not cause problem either. */
void
_dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs,
Dwarf_Debug dbgt,Dwarf_Error *errt)
{
int mydw_errno = 0;
if (!errt) {
if (!errs) {
/* Nobody here! Surely this is impossible. */
return;
} else {
/* There is no errt to copy errs to! */
dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR);
*errs = 0;
}
return;
}
if (!errs) {
/* there is no useful errs to build errt with! */
return;
}
if (dbgs == dbgt) {
/* nothing much to do here. */
if (errs != errt) {
/* Trivial copy of an error. */
Dwarf_Error ers = *errs;
*errs = 0;
*errt = ers;
}
return;
}
/* copy errs errno to errt by building
a new errt.
variable if there is one!
Move the error from dbgs to dbgt.
Error numbers are all < 1000.
*/
mydw_errno = (int)dwarf_errno(*errs);
dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR);
*errs = 0;
_dwarf_error(dbgt,errt, mydw_errno);
}
static int static int
inthissection(struct Dwarf_Section_s *sec,Dwarf_Small *ptr) inthissection(struct Dwarf_Section_s *sec,Dwarf_Small *ptr)
{ {

View File

@ -487,8 +487,6 @@ int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die);
int _dwarf_reference_outside_section(Dwarf_Die die, int _dwarf_reference_outside_section(Dwarf_Die die,
Dwarf_Small * startaddr, Dwarf_Small * startaddr,
Dwarf_Small * pastend); 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, int _dwarf_internal_get_die_comp_dir(Dwarf_Die die,
const char **compdir_out, const char **compdir_out,

View File

@ -1,7 +1,7 @@
/* /*
Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
Portions Copyright 2008-2023 David Anderson. All rights reserved. Portions Copyright 2008-2024 David Anderson. All rights reserved.
Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved.
@ -99,10 +99,10 @@ extern "C" {
*/ */
/* Semantic Version identity for this libdwarf.h */ /* Semantic Version identity for this libdwarf.h */
#define DW_LIBDWARF_VERSION "0.11.0" #define DW_LIBDWARF_VERSION "0.11.1"
#define DW_LIBDWARF_VERSION_MAJOR 0 #define DW_LIBDWARF_VERSION_MAJOR 0
#define DW_LIBDWARF_VERSION_MINOR 11 #define DW_LIBDWARF_VERSION_MINOR 11
#define DW_LIBDWARF_VERSION_MICRO 0 #define DW_LIBDWARF_VERSION_MICRO 1
#define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_unspecified 0
#define DW_PATHSOURCE_basic 1 #define DW_PATHSOURCE_basic 1
@ -338,8 +338,8 @@ typedef struct Dwarf_Block_s {
Provides access to Dwarf_Locdesc_c, a single Provides access to Dwarf_Locdesc_c, a single
location description location description
*/ */
typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c;
typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c;
/*! @typedef Dwarf_Loc_Head_c /*! @typedef Dwarf_Loc_Head_c
provides access to any sort of location description provides access to any sort of location description
for DWARF2,3,4, or 5. for DWARF2,3,4, or 5.
@ -1477,9 +1477,11 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head;
#define DW_DLE_UNIVERSAL_BINARY_ERROR 502 #define DW_DLE_UNIVERSAL_BINARY_ERROR 502
#define DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR 503 #define DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR 503
#define DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL 504 #define DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL 504
#define DW_DLE_LLE_ERROR 505
#define DW_DLE_RLE_ERROR 506
/*! @note DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ /*! @note DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
#define DW_DLE_LAST 504 #define DW_DLE_LAST 506
#define DW_DLE_LO_USER 0x10000 #define DW_DLE_LO_USER 0x10000
/*! @} */ /*! @} */
@ -1822,11 +1824,36 @@ DW_API int dwarf_set_tied_dbg(Dwarf_Debug dw_split_dbg,
/*! @brief Use with split dwarf. /*! @brief Use with split dwarf.
Given a base Dwarf_Debug this returns Given a main Dwarf_Debug this returns
the tied Dwarf_Debug. the tied Dwarf_Debug if there is one
or else returns null(0).
Before v0.11.0 it was not defined what this
returned if the tied-Dwarf_Debug
was passed in, but it would have returned
null(0) in that case.
Unlikely anyone uses this call as Unlikely anyone uses this call as
you had the tied and base dbg when calling callers had the tied and base dbg when calling
dwarf_set_tied_dbg(). dwarf_set_tied_dbg().
@param dw_dbg
Pass in a non-null Dwarf_Debug which is either
a main-Dwarf_Debug or a tied-Dwarf_Debug.
@param dw_tieddbg_out
On success returns the applicable tied-Dwarf_Debug
through the pointer.
If dw_dbg is a tied-Dwarf_Debug the function returns
null(0) through the poiner.
If there is no tied-Dwarf_Debug (meaning there is
just a main-Dwarf_Debug) the function returns
null (0) through the pointer.
@param dw_error
If the dw_dbg is invalid or damaged then the function
returns DW_DLV_ERROR and
dw_error is set to point to the error details.
@return DW_DLV_OK or DW_DLV_ERROR.
Never returns DW_DLV_NO_ENTRY.
*/ */
DW_API int dwarf_get_tied_dbg(Dwarf_Debug dw_dbg, DW_API int dwarf_get_tied_dbg(Dwarf_Debug dw_dbg,
Dwarf_Debug * dw_tieddbg_out, Dwarf_Debug * dw_tieddbg_out,