mirror of
https://github.com/jeremy-rifkin/libdwarf-lite.git
synced 2024-12-25 23:20:48 +08:00
Bump to v0.11.1
This commit is contained in:
parent
97fd68c602
commit
fe09ca800b
11
CMakeLists.txt
vendored
11
CMakeLists.txt
vendored
@ -1,6 +1,6 @@
|
||||
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"
|
||||
HOMEPAGE_URL "https://github.com/davea42/libdwarf-code.git"
|
||||
LANGUAGES C CXX)
|
||||
@ -183,7 +183,9 @@ else()
|
||||
message(STATUS "intptr_t value considered NO ")
|
||||
endif()
|
||||
|
||||
message(STATUS "ENABLE_DECOMPRESSION : " ${ENABLE_DECOMPRESSION})
|
||||
if (ENABLE_DECOMPRESSION)
|
||||
#message(STATUS "In ENABLE_DECOMPRESSION setup: TRUE")
|
||||
# Zlib and ZSTD need to be found otherwise disable it
|
||||
if(NOT TARGET ZLIB::ZLIB)
|
||||
find_package(ZLIB)
|
||||
@ -226,9 +228,14 @@ if (ENABLE_DECOMPRESSION)
|
||||
set(HAVE_ZSTD_H TRUE)
|
||||
set(BUILT_WITH_ZLIB_AND_ZSTD TRUE)
|
||||
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 ()
|
||||
|
||||
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.
|
||||
if (WALL)
|
||||
|
3
pull.sh
3
pull.sh
@ -10,7 +10,8 @@ cd libdwarf-code
|
||||
# git checkout "8cdcc531f310d1c5ae61da469d8056bdd36b77e7" # v0.9.1 + cmake fixes
|
||||
# git checkout "5e43a5ab73cb00c8a46660b361366a8c9c3c93c9" # v0.9.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 ..
|
||||
echo "Copying files"
|
||||
mkdir -p src/lib
|
||||
|
5
src/lib/libdwarf/CMakeLists.txt
vendored
5
src/lib/libdwarf/CMakeLists.txt
vendored
@ -135,5 +135,10 @@ install(EXPORT libdwarfTargets
|
||||
FILE libdwarf-targets.cmake
|
||||
NAMESPACE 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_SOURCE_DIR}/cmake/Findzstd.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf")
|
||||
|
11
src/lib/libdwarf/dwarf_alloc.c
vendored
11
src/lib/libdwarf/dwarf_alloc.c
vendored
@ -749,6 +749,8 @@ string_is_in_debug_section(Dwarf_Debug dbg,void * space)
|
||||
It is too late to change the documentation. */
|
||||
|
||||
void *result = 0;
|
||||
|
||||
/* The alloc tree can be in main or tied or both. */
|
||||
result = dwarf_tfind((void *)space,
|
||||
&dbg->de_alloc_tree,simple_compare_function);
|
||||
if (!result) {
|
||||
@ -849,9 +851,6 @@ dwarf_dealloc(Dwarf_Debug dbg,
|
||||
unsigned int type = 0;
|
||||
char * malloc_addr = 0;
|
||||
struct reserve_data_s * r = 0;
|
||||
#if 0
|
||||
Dwarf_Bool check_errmsg_list = FALSE;
|
||||
#endif
|
||||
|
||||
if (!space) {
|
||||
#ifdef DEBUG_ALLOC
|
||||
@ -884,6 +883,9 @@ dwarf_dealloc(Dwarf_Debug dbg,
|
||||
return;
|
||||
#endif /* DEBUG_ALLOC*/
|
||||
}
|
||||
if (dbg && alloc_type == DW_DLA_ERROR) {
|
||||
dbg = dbg->de_errors_dbg;
|
||||
}
|
||||
if (dbg && dbg->de_alloc_tree) {
|
||||
/* If it's a string in debug_info etc doing
|
||||
(char *)space - DW_RESERVE is totally bogus. */
|
||||
@ -969,9 +971,6 @@ dwarf_dealloc(Dwarf_Debug dbg,
|
||||
if (ep->er_static_alloc == DE_MALLOC) {
|
||||
/* This is special, we had no arena
|
||||
but have a full special area as normal. */
|
||||
#if 0
|
||||
check_errmsg_list = TRUE;
|
||||
#endif
|
||||
#ifdef DEBUG_ALLOC
|
||||
printf("DEALLOC does free, DE_MALLOC line %d %s\n",
|
||||
__LINE__,__FILE__);
|
||||
|
9
src/lib/libdwarf/dwarf_debugaddr.c
vendored
9
src/lib/libdwarf/dwarf_debugaddr.c
vendored
@ -196,6 +196,15 @@ dwarf_debug_addr_table(Dwarf_Debug dbg,
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
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 */
|
||||
tab.da_length = tablelen;
|
||||
curlocaloffset = offset_size + exten_size;
|
||||
|
27
src/lib/libdwarf/dwarf_debugnames.c
vendored
27
src/lib/libdwarf/dwarf_debugnames.c
vendored
@ -1696,6 +1696,25 @@ isformrefval(Dwarf_Debug dbg,Dwarf_Half form,
|
||||
{
|
||||
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) {
|
||||
case DW_FORM_ref1:
|
||||
*val = *poolptr;
|
||||
@ -1771,6 +1790,7 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
|
||||
/* make error or harmless error? */
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
|
||||
if (index_of_abbrev >= dn->dn_abbrev_instance_count) {
|
||||
/* make error or harmless error? */
|
||||
return DW_DLV_NO_ENTRY;
|
||||
@ -1854,6 +1874,10 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
|
||||
|
||||
array_of_offsets[n] = val;
|
||||
continue;
|
||||
} else if (form == DW_FORM_flag_present) {
|
||||
array_of_offsets[n] = 1;
|
||||
/* No change to poolptr or pooloffset */
|
||||
continue;
|
||||
} else {
|
||||
Dwarf_Unsigned val = 0;
|
||||
res =isformrefval(dbg,form,poolptr,
|
||||
@ -1863,7 +1887,7 @@ int dwarf_dnames_entrypool_values(Dwarf_Dnames_Head dn,
|
||||
}
|
||||
if (res == DW_DLV_OK) {
|
||||
poolptr += bytesread;
|
||||
if (poolptr > endpool) {
|
||||
if (poolptr >= endpool) {
|
||||
_dwarf_error_string(dbg,error,
|
||||
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");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
poolptr += bytesread;
|
||||
pooloffset += bytesread;
|
||||
array_of_offsets[n] = val;
|
||||
continue;
|
||||
|
81
src/lib/libdwarf/dwarf_die_deliv.c
vendored
81
src/lib/libdwarf/dwarf_die_deliv.c
vendored
@ -1185,7 +1185,6 @@ _dwarf_setup_base_address(Dwarf_Debug dbg,
|
||||
{
|
||||
int lres = 0;
|
||||
Dwarf_Half form = 0;
|
||||
|
||||
/* If the form is indexed, we better have
|
||||
seen DW_AT_addr_base.! */
|
||||
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
|
||||
Allowing DW_AT_entry_pc */
|
||||
cucon->cc_low_pc_present = TRUE;
|
||||
cucon->cc_base_address_present = TRUE;
|
||||
cucon->cc_base_address = cucon->cc_low_pc;
|
||||
} else {
|
||||
/* Something is badly wrong. */
|
||||
return lres;
|
||||
@ -1290,6 +1291,8 @@ set_producer_type(Dwarf_Die die,
|
||||
}
|
||||
if (_dwarf_prod_contains("Metrowerks",producer)) {
|
||||
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;
|
||||
version_stamp = cu_context->cc_version_stamp;
|
||||
|
||||
alres = dwarf_attrlist(cudie, &alist,
|
||||
&atcount,error);
|
||||
if (alres != DW_DLV_OK) {
|
||||
@ -1445,10 +1447,6 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
|
||||
int res = 0;
|
||||
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,
|
||||
/* avoid recurse creating context */ 1,
|
||||
&at_ranges_offset,
|
||||
@ -1519,14 +1517,14 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
|
||||
|
||||
udres = _dwarf_internal_global_formref_b(attr,
|
||||
/* avoid recurse creating context */ 1,
|
||||
&cucon->cc_addr_base,
|
||||
&cucon->cc_addr_base_offset,
|
||||
&is_info,
|
||||
error);
|
||||
if (udres == DW_DLV_OK) {
|
||||
if (is_info == cucon->cc_is_info) {
|
||||
/* Only accept if same .debug section,
|
||||
which is relevant for DWARF4 */
|
||||
cucon->cc_addr_base_present = TRUE;
|
||||
cucon->cc_addr_base_offset_present = TRUE;
|
||||
}
|
||||
} else {
|
||||
local_attrlist_dealloc(dbg,atcount,alist);
|
||||
@ -1551,7 +1549,10 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
|
||||
it refers to .debug_ranges.
|
||||
Note that this base applies when
|
||||
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;
|
||||
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 ){
|
||||
int battr = 0;
|
||||
|
||||
/* Prefer DW_AT_low_pc */
|
||||
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) {
|
||||
/* Only on Apple do we let entry_pc
|
||||
be used as base address. */
|
||||
if (entry_pc_attrnum >= 0 &&
|
||||
cucon->cc_producer == CC_PROD_Apple) {
|
||||
int battr = 0;
|
||||
|
||||
/* 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).
|
||||
So we allow that as an extension,
|
||||
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];
|
||||
battr = _dwarf_setup_base_address(dbg,"DW_AT_entry_pc",
|
||||
attr,at_addr_base_attrnum, cucon,
|
||||
@ -1648,6 +1638,21 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
|
||||
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);
|
||||
alist = 0;
|
||||
atcount = 0;
|
||||
@ -1655,7 +1660,10 @@ find_cu_die_base_fields(Dwarf_Debug dbg,
|
||||
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
|
||||
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) {
|
||||
/* For finding base data from skeleton.
|
||||
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,
|
||||
cu_context,error);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
@ -2088,14 +2098,17 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg,
|
||||
}
|
||||
{
|
||||
Dwarf_Debug tieddbg = 0;
|
||||
int tres = 0;
|
||||
tieddbg = dbg->de_tied_data.td_tied_object;
|
||||
if (tieddbg) {
|
||||
int tres = DW_DLV_OK;
|
||||
tieddbg = dbg->de_secondary_dbg;
|
||||
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(
|
||||
dbg, cu_context,
|
||||
tieddbg, 0,
|
||||
cu_context,
|
||||
tieddbg,
|
||||
0 /* we do not want the context returned */,
|
||||
error);
|
||||
}
|
||||
} /* Else no merge */
|
||||
if (tres == DW_DLV_ERROR && error) {
|
||||
/* We'll assume any errors will be
|
||||
discovered later. Lets get our
|
||||
|
5
src/lib/libdwarf/dwarf_errmsg_list.h
vendored
5
src/lib/libdwarf/dwarf_errmsg_list.h
vendored
@ -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 "
|
||||
"a Mach-O universal binary has an impossible value"},
|
||||
{"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 */
|
||||
|
15
src/lib/libdwarf/dwarf_error.c
vendored
15
src/lib/libdwarf/dwarf_error.c
vendored
@ -110,6 +110,9 @@ _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error,
|
||||
{
|
||||
_dwarf_error_string(dbg,error,errval,0);
|
||||
}
|
||||
|
||||
/* Errors are all added to the de_primary_dbg, never to
|
||||
de_secondary_dbg. */
|
||||
void
|
||||
_dwarf_error_string(Dwarf_Debug dbg, Dwarf_Error * error,
|
||||
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,
|
||||
this will overwrite the earlier error. */
|
||||
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 =
|
||||
(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) {
|
||||
errptr = &_dwarf_failsafe_error;
|
||||
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) {
|
||||
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) {
|
||||
errptr = &_dwarf_failsafe_error;
|
||||
errptr->er_static_alloc = DE_STATIC;
|
||||
}
|
||||
errptr->er_errval = errval;
|
||||
dbg->de_errhand(errptr, dbg->de_errarg);
|
||||
dbg->de_errhand(errptr, dbg->de_errors_dbg->de_errarg);
|
||||
return;
|
||||
}
|
||||
fflush(stderr);
|
||||
|
26
src/lib/libdwarf/dwarf_fission_to_cu.c
vendored
26
src/lib/libdwarf/dwarf_fission_to_cu.c
vendored
@ -49,6 +49,27 @@
|
||||
#include "dwarf_loclists.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
|
||||
as the caller ensured that.
|
||||
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) {
|
||||
return res;
|
||||
}
|
||||
|
||||
cu_context->cc_rnglists_base =
|
||||
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_contr_size = size;
|
||||
/* FIXME cc_rnglists_header_length_present? */
|
||||
|
34
src/lib/libdwarf/dwarf_form.c
vendored
34
src/lib/libdwarf/dwarf_form.c
vendored
@ -750,13 +750,16 @@ dwarf_global_formref_b(Dwarf_Attribute attr,
|
||||
Dwarf_Error * error)
|
||||
{
|
||||
int res = 0;
|
||||
int context_level = 0;
|
||||
res = _dwarf_internal_global_formref_b( attr,
|
||||
0,
|
||||
context_level,
|
||||
ret_offset,
|
||||
offset_is_info,
|
||||
error);
|
||||
return res;
|
||||
}
|
||||
/* If context_level is 0, normal call
|
||||
But if non-zero will avoid creating CU Context. */
|
||||
int
|
||||
_dwarf_internal_global_formref_b(Dwarf_Attribute attr,
|
||||
int context_level,
|
||||
@ -987,7 +990,7 @@ _dwarf_internal_global_formref_b(Dwarf_Attribute attr,
|
||||
|
||||
dwarfstring_constructor(&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);
|
||||
fcres = dwarf_get_FORM_name (formcode,&name);
|
||||
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
|
||||
so lets be cautious. */
|
||||
#if 0 /* Attempted check for index uncertain, unwise. Ignore. */
|
||||
/* See de_secondary_dbg before using this */
|
||||
if (!dbg->de_tied_data.td_tied_object &&
|
||||
index > dbg->de_filesize) {
|
||||
_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_data4:
|
||||
case DW_FORM_data8:
|
||||
case DW_FORM_udata:
|
||||
case DW_FORM_flag:
|
||||
case DW_FORM_flag_present:
|
||||
case DW_FORM_loclistx:
|
||||
case DW_FORM_rnglistx:
|
||||
return TRUE;
|
||||
@ -1446,6 +1451,18 @@ _dwarf_formudata_internal(Dwarf_Debug dbg,
|
||||
*return_uval = ret_value;
|
||||
*bytes_read = 1;
|
||||
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
|
||||
the right number bits and generates host order.
|
||||
@ -2082,7 +2099,8 @@ dwarf_formstring(Dwarf_Attribute attr,
|
||||
if (res == DW_DLV_ERROR) {
|
||||
if (dwarf_errno(alterr) ==
|
||||
DW_DLE_NO_TIED_FILE_AVAILABLE) {
|
||||
dwarf_dealloc(dbg,alterr,DW_DLA_ERROR);
|
||||
|
||||
dwarf_dealloc_error(dbg,alterr);
|
||||
if ( attr->ar_attribute_form ==
|
||||
DW_FORM_GNU_strp_alt) {
|
||||
*return_str =
|
||||
@ -2168,17 +2186,17 @@ _dwarf_get_string_from_tied(Dwarf_Debug dbg,
|
||||
Dwarf_Error localerror = 0;
|
||||
|
||||
/* Attach errors to dbg, not tieddbg. */
|
||||
tieddbg = dbg->de_tied_data.td_tied_object;
|
||||
if (!tieddbg) {
|
||||
if (!DBG_HAS_SECONDARY(dbg)) {
|
||||
_dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
tieddbg = dbg->de_secondary_dbg;
|
||||
/* The 'offset' into .debug_str is set. */
|
||||
res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str,
|
||||
&localerror);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
Dwarf_Unsigned lerrno = dwarf_errno(localerror);
|
||||
dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR);
|
||||
dwarf_dealloc_error(tieddbg,localerror);
|
||||
_dwarf_error(dbg,error,lerrno);
|
||||
return res;
|
||||
}
|
||||
@ -2205,7 +2223,7 @@ _dwarf_get_string_from_tied(Dwarf_Debug dbg,
|
||||
&localerror);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
Dwarf_Unsigned lerrno = dwarf_errno(localerror);
|
||||
dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR);
|
||||
dwarf_dealloc_error(tieddbg,localerror);
|
||||
_dwarf_error(dbg,error,lerrno);
|
||||
return res;
|
||||
}
|
||||
|
123
src/lib/libdwarf/dwarf_generic_init.c
vendored
123
src/lib/libdwarf/dwarf_generic_init.c
vendored
@ -78,6 +78,54 @@ dwarf_init_path_dl(path true_path and globals, dbg1
|
||||
#include "dwarf_error.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
|
||||
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
|
||||
that has the .debug_addr section that
|
||||
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
|
||||
of de_tied_data.td_tied_object).
|
||||
Allows calling with NULL though we really just set
|
||||
primary_dbg->ge_primary to de_primary_dbg, thus cutting
|
||||
links between main and any previous tied-file setup.
|
||||
New September 2015.
|
||||
Logic revised Nov 2024. See dwarf_opaque.h
|
||||
*/
|
||||
int
|
||||
dwarf_set_tied_dbg(Dwarf_Debug dbg,
|
||||
Dwarf_Debug tieddbg,
|
||||
dwarf_set_tied_dbg(Dwarf_Debug primary_dbg,
|
||||
Dwarf_Debug secondary_dbg,
|
||||
Dwarf_Error*error)
|
||||
{
|
||||
CHECK_DBG(dbg,error,"dwarf_set_tied_dbg()");
|
||||
|
||||
dbg->de_tied_data.td_tied_object = tieddbg;
|
||||
if (tieddbg) {
|
||||
tieddbg->de_tied_data.td_is_tied_object = TRUE;
|
||||
CHECK_DBG(primary_dbg,error,"dwarf_set_tied_dbg()");
|
||||
if (secondary_dbg == primary_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(), 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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out,
|
||||
Dwarf_Error*error)
|
||||
dwarf_get_tied_dbg(Dwarf_Debug dw_dbg,
|
||||
Dwarf_Debug *dw_secondary_dbg_out,
|
||||
Dwarf_Error *dw_error)
|
||||
{
|
||||
CHECK_DBG(dbg,error,"dwarf_get_tied_dbg()");
|
||||
*tieddbg_out = dbg->de_tied_data.td_tied_object;
|
||||
CHECK_DBG(dw_dbg,dw_error,"dwarf_get_tied_dbg()");
|
||||
*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;
|
||||
}
|
||||
|
14
src/lib/libdwarf/dwarf_gnu_index.c
vendored
14
src/lib/libdwarf/dwarf_gnu_index.c
vendored
@ -276,10 +276,10 @@ scan_block_entries(Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned length = 0;
|
||||
unsigned int offsetsize = 0;
|
||||
unsigned int extensize = 0;
|
||||
unsigned int sumsize = 0;
|
||||
|
||||
if (curptr == endptr) {
|
||||
*count_out = count;
|
||||
return DW_DLV_OK;
|
||||
break;
|
||||
}
|
||||
/* Not sure how the coders think about
|
||||
the initial value. But the last
|
||||
@ -296,10 +296,16 @@ scan_block_entries(Dwarf_Debug dbg,
|
||||
}
|
||||
|
||||
++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;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
*count_out = count;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
4
src/lib/libdwarf/dwarf_harmless.c
vendored
4
src/lib/libdwarf/dwarf_harmless.c
vendored
@ -217,12 +217,12 @@ _dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size)
|
||||
unsigned i = 0;
|
||||
memset(dhp,0,sizeof(*dhp));
|
||||
dhp->dh_maxcount = size +1;
|
||||
dhp->dh_errors = (char **)calloc(dhp->dh_maxcount, sizeof(char *));
|
||||
dhp->dh_errors = (char **)calloc(dhp->dh_maxcount,
|
||||
sizeof(char *));
|
||||
if (!dhp->dh_errors) {
|
||||
dhp->dh_maxcount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < dhp->dh_maxcount; ++i) {
|
||||
char *newstr =
|
||||
(char *)calloc(1, DW_HARMLESS_ERROR_MSG_STRING_SIZE);
|
||||
|
10
src/lib/libdwarf/dwarf_init_finish.c
vendored
10
src/lib/libdwarf/dwarf_init_finish.c
vendored
@ -1035,6 +1035,8 @@ dwarf_object_init_b(Dwarf_Obj_Access_Interface_a* obj,
|
||||
size. */
|
||||
dbg = _dwarf_get_debug(filesize);
|
||||
if (IS_INVALID_DBG(dbg)) {
|
||||
dwarf_finish(dbg);
|
||||
dbg = 0;
|
||||
DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
|
||||
}
|
||||
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_same_value_number = DW_FRAME_SAME_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_filesize = filesize;
|
||||
@ -1099,7 +1107,7 @@ dwarf_object_init_b(Dwarf_Obj_Access_Interface_a* obj,
|
||||
/* *error safe */
|
||||
dwarfstring_append(&msg,dwarf_errmsg(*error));
|
||||
/* deallocate the soon-stale error pointer. */
|
||||
dwarf_dealloc(dbg,*error,DW_DLA_ERROR);
|
||||
dwarf_dealloc_error(dbg,*error);
|
||||
/* *error safe */
|
||||
*error = 0;
|
||||
}
|
||||
|
16
src/lib/libdwarf/dwarf_line.c
vendored
16
src/lib/libdwarf/dwarf_line.c
vendored
@ -844,9 +844,9 @@ _dwarf_internal_srclines(Dwarf_Die die,
|
||||
}
|
||||
section_start = dbg->de_debug_line.dss_data;
|
||||
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;
|
||||
uintptr_t line_ptr_as_uint = (uintptr_t)line_ptr;
|
||||
int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
|
||||
&fission_offset,&fission_size,error);
|
||||
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
|
||||
is undefined behavior with some compilers. */
|
||||
line_ptr_as_uint += fission_offset;
|
||||
line_ptr = (Dwarf_Small *)line_ptr_as_uint;
|
||||
if (fission_offset) {
|
||||
line_ptr += fission_offset;
|
||||
}
|
||||
if (line_ptr > section_end) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
section_start = dbg->de_debug_line.dss_data;
|
||||
section_end = section_start +dbg->de_debug_line.dss_size;
|
||||
orig_line_ptr = section_start + line_offset + fission_offset;
|
||||
|
@ -2704,11 +2704,14 @@ read_line_table_program(Dwarf_Debug dbg,
|
||||
/* This is an extended op code we do not know about,
|
||||
other than we know now many bytes it is
|
||||
and the op code and the bytes of operand. */
|
||||
Dwarf_Unsigned remaining_bytes = instr_length -1;
|
||||
Dwarf_Unsigned remaining_bytes = 0;
|
||||
/* ptrdiff_t is generated but not named */
|
||||
Dwarf_Unsigned space_left =
|
||||
(line_ptr <= line_ptr_end)?
|
||||
(line_ptr_end - line_ptr):0xfffffff;
|
||||
if (instr_length > 0) {
|
||||
remaining_bytes = instr_length -1;
|
||||
}
|
||||
|
||||
/* By catching this here instead of PRINTING_DETAILS
|
||||
we avoid reading off of our data of interest*/
|
||||
|
112
src/lib/libdwarf/dwarf_loc.c
vendored
112
src/lib/libdwarf/dwarf_loc.c
vendored
@ -48,6 +48,9 @@
|
||||
#include "dwarf_loc.h"
|
||||
#include "dwarf_string.h"
|
||||
|
||||
#define DEBUG_LOCLIST 1
|
||||
#undef DEBUG_LOCLIST
|
||||
|
||||
static int _dwarf_read_loc_section_dwo(Dwarf_Debug dbg,
|
||||
Dwarf_Block_c * return_block,
|
||||
Dwarf_Addr * lowpc,
|
||||
@ -1136,7 +1139,7 @@ _dwarf_original_loclist_build(Dwarf_Debug dbg,
|
||||
}
|
||||
/* We need to calculate the cooked values for
|
||||
each locldesc entry, that will be done
|
||||
in dwarf_get_loclist_c(). */
|
||||
in dwarf_get_loclist_d(). */
|
||||
|
||||
llhead->ll_bytes_total = loclist_offset -
|
||||
starting_loclist_offset;
|
||||
@ -1267,6 +1270,7 @@ cook_original_loclist_contents(Dwarf_Debug dbg,
|
||||
baseaddress = llc->ld_rawhigh;
|
||||
break;
|
||||
}
|
||||
/* This is the only way baseaddress is used. */
|
||||
case DW_LLE_offset_pair: {
|
||||
llc->ld_lopc = llc->ld_rawlow + baseaddress;
|
||||
llc->ld_highpc = llc->ld_rawhigh + baseaddress;
|
||||
@ -1590,14 +1594,18 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
|
||||
Dwarf_Debug dbg = 0;
|
||||
Dwarf_Half form = 0;
|
||||
Dwarf_Loc_Head_c llhead = 0;
|
||||
Dwarf_CU_Context cucontext = 0;
|
||||
unsigned address_size = 0;
|
||||
Dwarf_Half cuversionstamp = 0;
|
||||
Dwarf_Bool is_cu = FALSE;
|
||||
Dwarf_Unsigned attrnum = 0;
|
||||
Dwarf_Bool is_dwo = 0;
|
||||
int setup_res = DW_DLV_ERROR;
|
||||
int lkind = 0;
|
||||
Dwarf_CU_Context ctx = 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) {
|
||||
_dwarf_error_string(dbg, error,DW_DLE_ATTR_NULL,
|
||||
@ -1607,18 +1615,74 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
|
||||
"dwarf_get_loclist_c()");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
dbg = attr->ar_dbg;
|
||||
CHECK_DBG(dbg,error,"dwarf_get_loclist_c()");
|
||||
|
||||
/* ***** BEGIN CODE ***** */
|
||||
setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error);
|
||||
setup_res = _dwarf_setup_loc(attr, &dbg,&ctx, &form, error);
|
||||
if (setup_res != DW_DLV_OK) {
|
||||
return setup_res;
|
||||
}
|
||||
|
||||
CHECK_DBG(dbg,error,"dwarf_get_loclist_c()");
|
||||
if (form == DW_FORM_loclistx) {
|
||||
is_loclistx = TRUE;
|
||||
}
|
||||
attrnum = attr->ar_attribute;
|
||||
cuversionstamp = cucontext->cc_version_stamp;
|
||||
address_size = cucontext->cc_address_size;
|
||||
is_dwo = cucontext->cc_is_dwo;
|
||||
cuversionstamp = ctx->cc_version_stamp;
|
||||
address_size = ctx->cc_address_size;
|
||||
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,
|
||||
form, is_dwo);
|
||||
if (lkind == DW_LKIND_unknown) {
|
||||
@ -1663,27 +1727,29 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
|
||||
llhead->ll_attrform = (Dwarf_Half)form;
|
||||
llhead->ll_dbg = dbg;
|
||||
llhead->ll_address_size = address_size;
|
||||
llhead->ll_offset_size = cucontext->cc_length_size;
|
||||
llhead->ll_context = cucontext;
|
||||
llhead->ll_offset_size = ctx->cc_length_size;
|
||||
llhead->ll_context = ctx;
|
||||
llhead->ll_magic = LOCLISTS_MAGIC;
|
||||
|
||||
llhead->ll_at_loclists_base_present =
|
||||
cucontext->cc_loclists_base_present;
|
||||
llhead->ll_at_loclists_base = cucontext->cc_loclists_base;
|
||||
llhead->ll_cu_base_address_present = cucontext->cc_low_pc_present;
|
||||
llhead->ll_cu_base_address = cucontext->cc_low_pc;
|
||||
llhead->ll_cu_addr_base = cucontext->cc_addr_base;
|
||||
llhead->ll_cu_addr_base_present =
|
||||
cucontext->cc_addr_base_present;
|
||||
ctx->cc_loclists_base_present;
|
||||
llhead->ll_at_loclists_base = ctx->cc_loclists_base;
|
||||
llhead->ll_cu_base_address_present =
|
||||
ctx->cc_base_address_present;
|
||||
llhead->ll_cu_base_address = ctx->cc_base_address;
|
||||
|
||||
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 ||
|
||||
lkind == DW_LKIND_GNU_exp_list) {
|
||||
int ores = 0;
|
||||
/* 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) {
|
||||
dwarf_dealloc_loc_head_c(llhead);
|
||||
return setup_res;
|
||||
return ores;
|
||||
}
|
||||
ores = _dwarf_original_loclist_build(dbg,
|
||||
llhead, attr, error);
|
||||
@ -1715,7 +1781,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr,
|
||||
int leres = 0;
|
||||
|
||||
leres = _dwarf_loclists_fill_in_lle_head(dbg,
|
||||
attr,llhead,error);
|
||||
attr,form,attr_val,llhead,error);
|
||||
if (leres != DW_DLV_OK) {
|
||||
dwarf_dealloc_loc_head_c(llhead);
|
||||
return leres;
|
||||
|
9
src/lib/libdwarf/dwarf_loc.h
vendored
9
src/lib/libdwarf/dwarf_loc.h
vendored
@ -208,14 +208,15 @@ struct Dwarf_Loc_Head_c_s {
|
||||
Dwarf_Bool ll_at_loclists_base_present;
|
||||
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_Unsigned ll_cu_base_address;
|
||||
|
||||
/* DW_AT_addr_base, so we can use .debug_addr
|
||||
if such is needed. */
|
||||
Dwarf_Bool ll_cu_addr_base_present;
|
||||
Dwarf_Unsigned ll_cu_addr_base;
|
||||
Dwarf_Bool ll_cu_addr_base_offset_present;
|
||||
Dwarf_Unsigned ll_cu_addr_base_offset;
|
||||
|
||||
Dwarf_Small * ll_llepointer;
|
||||
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,
|
||||
Dwarf_Attribute attr,
|
||||
Dwarf_Half theform,
|
||||
Dwarf_Unsigned attr_val,
|
||||
Dwarf_Loc_Head_c llhead,
|
||||
Dwarf_Error *error);
|
||||
|
||||
|
290
src/lib/libdwarf/dwarf_loclists.c
vendored
290
src/lib/libdwarf/dwarf_loclists.c
vendored
@ -324,7 +324,7 @@ read_single_lle_entry(Dwarf_Debug dbg,
|
||||
preserve a testing baseline:
|
||||
baselines/hongg2024-02-18-m.base
|
||||
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 ) {
|
||||
/* Corrupt data being read. */
|
||||
@ -334,7 +334,7 @@ read_single_lle_entry(Dwarf_Debug dbg,
|
||||
"of its allowed space");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (count > sectionsize) {
|
||||
if (count > section_size) {
|
||||
/* Corrupt data being read. */
|
||||
_dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR,
|
||||
"DW_DLE_LOCLISTS_ERROR: "
|
||||
@ -501,8 +501,8 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg,
|
||||
} /* else no offset table */
|
||||
|
||||
buildhere->lc_offsets_off_in_sect = offset+localoff;
|
||||
buildhere->lc_first_loclist_offset = offset+localoff+
|
||||
lists_len;
|
||||
buildhere->lc_first_loclist_offset =
|
||||
buildhere->lc_offsets_off_in_sect + lists_len;
|
||||
buildhere->lc_loclists_header = startdata;
|
||||
buildhere->lc_endaddr = startdata + buildhere->lc_length;
|
||||
buildhere->lc_past_last_loclist_offset =
|
||||
@ -719,6 +719,14 @@ dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg,
|
||||
READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned,
|
||||
offsetptr,
|
||||
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) {
|
||||
*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= head->ll_cu_base_address;
|
||||
|
||||
*loclists_debug_addr_base_present = head->ll_cu_addr_base_present;
|
||||
*loclists_debug_addr_base = head->ll_cu_addr_base;
|
||||
*loclists_debug_addr_base_present =
|
||||
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;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
@ -938,10 +947,14 @@ int dwarf_get_loclist_lle(Dwarf_Debug dbg,
|
||||
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
|
||||
_dwarf_which_loclists_context(Dwarf_Debug dbg,
|
||||
Dwarf_CU_Context ctx,
|
||||
Dwarf_Unsigned loclist_offset,
|
||||
Dwarf_Unsigned loclist_offset /* Not always set */,
|
||||
Dwarf_Unsigned *index,
|
||||
Dwarf_Error *error)
|
||||
{
|
||||
@ -951,18 +964,47 @@ _dwarf_which_loclists_context(Dwarf_Debug dbg,
|
||||
Dwarf_Loclists_Context rcx = 0;
|
||||
Dwarf_Unsigned rcxoff = 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;
|
||||
count = dbg->de_loclists_context_count;
|
||||
if (!array) {
|
||||
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];
|
||||
rcxoff = rcx->lc_header_offset;
|
||||
rcxend = rcxoff + rcx->lc_length;
|
||||
if (!ctx->cc_loclists_base_present) {
|
||||
/* We look at the location of each loclist context
|
||||
to find one with the offset the DIE gave us. */
|
||||
to find one with the offset we want */
|
||||
for ( i = 0 ; i < count; ++i) {
|
||||
rcx = array[i];
|
||||
rcxoff = rcx->lc_header_offset;
|
||||
@ -970,10 +1012,10 @@ _dwarf_which_loclists_context(Dwarf_Debug dbg,
|
||||
rcx->lc_length;
|
||||
rcxend = rcxoff +
|
||||
rcx->lc_length;
|
||||
if (loclist_offset < rcxoff){
|
||||
if (chosen_offset < rcxoff){
|
||||
continue;
|
||||
}
|
||||
if (loclist_offset < rcxend ){
|
||||
if (chosen_offset < rcxend ){
|
||||
*index = i;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
@ -985,63 +1027,14 @@ _dwarf_which_loclists_context(Dwarf_Debug dbg,
|
||||
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);
|
||||
" 0x%" DW_PR_XZEROS DW_PR_DUx ,chosen_offset);
|
||||
dwarfstring_append(&m,
|
||||
" Not found anywhere in .debug_loclists "
|
||||
" Not found anywhere in .debug_loclists[.dwo] "
|
||||
"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. */
|
||||
Dwarf_Unsigned lookfor = 0;;
|
||||
lookfor = ctx->cc_loclists_base;
|
||||
for ( i = 0 ; i < count; ++i) {
|
||||
dwarfstring m;
|
||||
|
||||
rcx = array[i];
|
||||
if (rcx->lc_offsets_off_in_sect == lookfor){
|
||||
*index = i;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (rcx->lc_offsets_off_in_sect < lookfor){
|
||||
continue;
|
||||
}
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_LOCLISTS_ERROR: loclists base of "
|
||||
" 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;
|
||||
}
|
||||
@ -1077,33 +1070,6 @@ alloc_rle_and_append_to_list(Dwarf_Debug dbg,
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
_dwarf_implicit_loclists_base(Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned indexval,
|
||||
Dwarf_Unsigned *ibase)
|
||||
{
|
||||
Dwarf_Loclists_Context rctx = 0;
|
||||
if (IS_INVALID_DBG(dbg)) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (!dbg->de_debug_loclists.dss_size) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (!dbg->de_loclists_context_count) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
/* This implicit base can only work if the 0-th
|
||||
Rnglists_Context is appropriate here. */
|
||||
rctx = dbg->de_loclists_context[0];
|
||||
if (indexval > rctx->lc_offset_entry_count) {
|
||||
/* We are not using base offset, we
|
||||
will not see a DW_FORM_loclistx */
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
*ibase = rctx->lc_offsets_off_in_sect;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
/* Read the group of loclists entries, and
|
||||
finally build an array of Dwarf_Locdesc_c
|
||||
records. Attach to rctx here.
|
||||
@ -1227,6 +1193,8 @@ build_array_of_lle(Dwarf_Debug dbg,
|
||||
int
|
||||
_dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
|
||||
Dwarf_Attribute attr,
|
||||
Dwarf_Half theform,
|
||||
Dwarf_Unsigned attr_val,
|
||||
Dwarf_Loc_Head_c llhead,
|
||||
Dwarf_Error *error)
|
||||
{
|
||||
@ -1243,13 +1211,13 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
|
||||
Dwarf_CU_Context ctx = 0;
|
||||
Dwarf_Unsigned offset_in_loclists = 0;
|
||||
Dwarf_Bool is_loclistx = FALSE;
|
||||
Dwarf_Half theform = llhead->ll_attrform;
|
||||
Dwarf_Bool loclists_base_present =
|
||||
llhead->ll_at_loclists_base_present;
|
||||
Dwarf_Unsigned loclists_base =
|
||||
llhead->ll_at_loclists_base;
|
||||
Dwarf_Unsigned attr_val = 0;
|
||||
Dwarf_Unsigned secsize = 0;
|
||||
|
||||
if (theform == DW_FORM_loclistx) {
|
||||
is_loclistx = TRUE;
|
||||
} else {
|
||||
offset_in_loclists = attr_val;
|
||||
}
|
||||
if (!attr) {
|
||||
_dwarf_error_string(NULL, error,DW_DLE_DBG_NULL,
|
||||
"DW_DLE_DBG_NULL "
|
||||
@ -1258,79 +1226,76 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
|
||||
"_dwarf_loclists_fill_in_lle_head()");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
secsize = dbg->de_debug_loclists.dss_size;
|
||||
ctx = attr->ar_cu_context;
|
||||
array = dbg->de_loclists_context;
|
||||
if (theform == DW_FORM_loclistx) {
|
||||
Dwarf_Bool offset_is_info = 0;
|
||||
is_loclistx = TRUE;
|
||||
res = dwarf_global_formref_b(attr,
|
||||
&attr_val, &offset_is_info, error);
|
||||
if (dbg != ctx->cc_dbg) {
|
||||
/* is_loclistx TRUE */
|
||||
/* Now find the correct secondary CU context via
|
||||
signature. */
|
||||
Dwarf_CU_Context lctx = 0;
|
||||
|
||||
if (ctx->cc_signature_present) {
|
||||
/* Looking in current dbg for the correct cu context */
|
||||
res = _dwarf_search_for_signature(dbg,
|
||||
ctx->cc_signature,
|
||||
&lctx,error);
|
||||
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;
|
||||
} else {
|
||||
ctx = lctx;
|
||||
}
|
||||
} else {
|
||||
if (theform == DW_FORM_sec_offset) {
|
||||
/* DW_FORM_sec_offset is not formudata , often
|
||||
seen in in DW5 DW_AT_location etc */
|
||||
res = dwarf_global_formref(attr, &attr_val,error);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_loclistx) {
|
||||
if (loclists_base_present) {
|
||||
offset_in_loclists = loclists_base;
|
||||
} else if (ctx->cc_is_dwo) {
|
||||
/* missing a DW_AT_loclists_base! */
|
||||
/* Generate a base and set as 'present'
|
||||
by looking at the location offset
|
||||
table that we are supposedly indexing into.
|
||||
finding what the table value is.
|
||||
An implicit loclists_base.
|
||||
Will not work with multiple loclists! */
|
||||
int ires = 0;
|
||||
Dwarf_Unsigned ibase = 0;
|
||||
ires = _dwarf_implicit_loclists_base(dbg,
|
||||
attr_val,&ibase);
|
||||
if (ires != DW_DLV_OK) {
|
||||
dwarfstring m;
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_LOCLISTS_ERROR: loclists table"
|
||||
" index of"
|
||||
" %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);
|
||||
/* 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;
|
||||
}
|
||||
ctx->cc_loclists_base_present = TRUE;
|
||||
ctx->cc_loclists_base = ibase;
|
||||
offset_in_loclists = ibase;
|
||||
}
|
||||
/* A */
|
||||
if (ctx->cc_loclists_base_present) {
|
||||
offset_in_loclists = ctx->cc_loclists_base;
|
||||
} else {
|
||||
offset_in_loclists = attr_val;
|
||||
}
|
||||
|
||||
if (offset_in_loclists >= secsize) {
|
||||
_dwarf_error_string(dbg,error, DW_DLE_LLE_ERROR,
|
||||
"DW_DLE_LLE_ERROR: a .debug_loclists offset "
|
||||
"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) {
|
||||
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];
|
||||
table_base = rctx->lc_offsets_array;
|
||||
entrycount = rctx->lc_offset_entry_count;
|
||||
offsetsize = rctx->lc_offset_size;
|
||||
enddata = rctx->lc_endaddr;
|
||||
|
||||
if (is_loclistx) {
|
||||
if (attr_val >= entrycount) {
|
||||
if (is_loclistx && attr_val >= entrycount) {
|
||||
dwarfstring m;
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
@ -1346,7 +1311,6 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
}
|
||||
llhead->ll_localcontext = rctx;
|
||||
llhead->ll_index = loclists_contextnum;
|
||||
llhead->ll_cuversion = rctx->lc_version;
|
||||
@ -1354,21 +1318,49 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg,
|
||||
llhead->ll_address_size = rctx->lc_address_size;
|
||||
llhead->ll_segment_selector_size =
|
||||
rctx->lc_segment_selector_size;
|
||||
|
||||
/* D */
|
||||
if (is_loclistx) {
|
||||
Dwarf_Unsigned table_entryval = 0;
|
||||
Dwarf_Unsigned globaloff = 0;
|
||||
|
||||
table_entry = attr_val*offsetsize + table_base;
|
||||
/* No malloc here yet so no leak if the macro returns
|
||||
DW_DLV_ERROR */
|
||||
READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned,
|
||||
table_entry,offsetsize,error,enddata);
|
||||
lle_global_offset = rctx->lc_offsets_off_in_sect +
|
||||
table_entryval;
|
||||
if (table_entryval >= rctx->lc_length) {
|
||||
_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 {
|
||||
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_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_llepointer = lle_global_offset +
|
||||
|
6
src/lib/libdwarf/dwarf_machoread.c
vendored
6
src/lib/libdwarf/dwarf_machoread.c
vendored
@ -119,14 +119,20 @@ static struct macho_sect_names_s {
|
||||
{ "__debug_aranges", ".debug_aranges" },
|
||||
{ "__debug_frame", ".debug_frame" },
|
||||
{ "__debug_info", ".debug_info" },
|
||||
{ "__debug_addr", ".debug_addr" },
|
||||
{ "__debug_line", ".debug_line" },
|
||||
{ "__debug_rnglists", ".debug_rnglists" },
|
||||
{ "__debug_loclists", ".debug_loclists" },
|
||||
{ "__debug_macinfo", ".debug_macinfo" },
|
||||
{ "__debug_loc", ".debug_loc" },
|
||||
{ "__debug_pubnames", ".debug_pubnames" },
|
||||
{ "__debug_pubtypes", ".debug_pubtypes" },
|
||||
{ "__debug_str", ".debug_str" },
|
||||
{ "__debug_str_offs", ".debug_str_offsets" },
|
||||
{ "__debug_line_str", ".debug_line_str" },
|
||||
{ "__debug_ranges", ".debug_ranges" },
|
||||
{ "__debug_macro", ".debug_macro" },
|
||||
{ "__debug_names", ".debug_names" },
|
||||
{ "__debug_gdb_scri", ".debug_gdb_scripts" }
|
||||
};
|
||||
|
||||
|
5
src/lib/libdwarf/dwarf_macro.c
vendored
5
src/lib/libdwarf/dwarf_macro.c
vendored
@ -331,7 +331,10 @@ dwarf_get_macro_details(Dwarf_Debug dbg,
|
||||
break;
|
||||
|
||||
case DW_MACINFO_end_file:
|
||||
if (--depth == 0) {
|
||||
if (depth) {
|
||||
--depth;
|
||||
}
|
||||
if (!depth) {
|
||||
/* done = 1; no, do not stop here,
|
||||
at least one gcc had
|
||||
the wrong depth settings in the
|
||||
|
2
src/lib/libdwarf/dwarf_macro5.c
vendored
2
src/lib/libdwarf/dwarf_macro5.c
vendored
@ -653,7 +653,7 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context,
|
||||
*macro_string =
|
||||
(char *)"<Error: DW_FORM_str_sup-got-error>";
|
||||
}
|
||||
dwarf_dealloc(dbg,lerr,DW_DLA_ERROR);
|
||||
dwarf_dealloc_error(dbg,lerr);
|
||||
} else {
|
||||
*macro_string = "<DW_FORM_str_sup-no-entry>";
|
||||
}
|
||||
|
2
src/lib/libdwarf/dwarf_names.c
vendored
2
src/lib/libdwarf/dwarf_names.c
vendored
@ -1,5 +1,5 @@
|
||||
/* Generated routines, do not edit. */
|
||||
/* Generated for source version 0.9.3 */
|
||||
/* Generated for source version 0.11.1 */
|
||||
|
||||
/* BEGIN FILE */
|
||||
|
||||
|
90
src/lib/libdwarf/dwarf_opaque.h
vendored
90
src/lib/libdwarf/dwarf_opaque.h
vendored
@ -1,6 +1,6 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
@ -70,6 +70,31 @@
|
||||
.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;
|
||||
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_Apple 2 /* Apple clang */
|
||||
|
||||
/*
|
||||
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
|
||||
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_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_dwo_name_present;
|
||||
@ -243,6 +278,9 @@ struct Dwarf_CU_Context_s {
|
||||
cc_cu_die_global_sec_offset is meaningful. */
|
||||
Dwarf_Bool cc_cu_die_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
|
||||
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
|
||||
mentioned as the base address. */
|
||||
Dwarf_Unsigned cc_low_pc;
|
||||
|
||||
/* 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 */
|
||||
Dwarf_Bool cc_line_base_present; /*DW5 */
|
||||
@ -542,19 +585,13 @@ struct Dwarf_Tied_Data_s {
|
||||
Pointer to the tied_to Dwarf_Debug*/
|
||||
Dwarf_Debug td_tied_object;
|
||||
|
||||
/* TRUE if this tied object is tied to.
|
||||
It's extra work to look for a DW_AT_dwo_id.
|
||||
Set when tied dbg (on the base) was created.
|
||||
This helps us do it only when it may be productive. */
|
||||
Dwarf_Bool td_is_tied_object;
|
||||
|
||||
/* Used for Type Unit signatures.
|
||||
Type Units are in .debug_types in DW4
|
||||
but in .debug_info in DW5.
|
||||
Some .debug_info point to them symbolically
|
||||
via DW_AT_signature attributes.
|
||||
If non-zero is a dwarf_tsearch 'tree'.
|
||||
Only non-zero if td_is_tied_object is set and
|
||||
Only non-zero if
|
||||
we had a reason to build the search tree..
|
||||
Type Units have a Dwarf_Sig8 signature
|
||||
in the header, and such is recorded here.
|
||||
@ -563,7 +600,7 @@ struct Dwarf_Tied_Data_s {
|
||||
signatures in split-dwarf (dwo/dwp) sections.
|
||||
|
||||
The Key for each record is a Dwarf_Sig8 (8 bytes).
|
||||
The data for each is a pointer to a Dwarf_CU_context
|
||||
The data for each is a pointer to a Dwarf_CU_Context
|
||||
record in this dbg (cu_context in
|
||||
one of tied dbg's de_cu_context_list). */
|
||||
void *td_tied_search;
|
||||
@ -599,6 +636,15 @@ struct Dwarf_Debug_s {
|
||||
structure and contents. */
|
||||
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_Ptr de_errarg;
|
||||
|
||||
@ -958,8 +1004,7 @@ int _dwarf_search_for_signature(Dwarf_Debug dbg,
|
||||
Dwarf_CU_Context *context_out,
|
||||
Dwarf_Error *error);
|
||||
|
||||
int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg,
|
||||
Dwarf_CU_Context context,
|
||||
int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_CU_Context context,
|
||||
Dwarf_Debug tieddbg,
|
||||
Dwarf_CU_Context *tiedcontext_out,
|
||||
Dwarf_Error *error);
|
||||
@ -1155,9 +1200,22 @@ _dwarf_internal_global_formref_b(Dwarf_Attribute attr,
|
||||
Dwarf_Bool * offset_is_info,
|
||||
Dwarf_Error * error);
|
||||
|
||||
int _dwarf_skip_leb128(char * /*leb*/,
|
||||
Dwarf_Unsigned * /*leblen*/,
|
||||
char * /*endptr*/);
|
||||
int
|
||||
_dwarf_has_SECT_fission(Dwarf_CU_Context ctx,
|
||||
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);
|
||||
void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig, int lineno);
|
||||
|
6
src/lib/libdwarf/dwarf_peread.c
vendored
6
src/lib/libdwarf/dwarf_peread.c
vendored
@ -566,7 +566,8 @@ _dwarf_pe_load_dwarf_section_headers(
|
||||
if (sec_outp->VirtualSize >
|
||||
((Dwarf_Unsigned)2000*
|
||||
(Dwarf_Unsigned)1000*
|
||||
(Dwarf_Unsigned)1000)) {
|
||||
(Dwarf_Unsigned)1000) &&
|
||||
(sec_outp->VirtualSize > pep->pe_filesize)) {
|
||||
/* Likely unreasonable.
|
||||
the hard limit written this way
|
||||
simply for clarity.
|
||||
@ -574,7 +575,8 @@ _dwarf_pe_load_dwarf_section_headers(
|
||||
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (sec_outp->VirtualSize > limit) {
|
||||
if (sec_outp->VirtualSize > limit &&
|
||||
0 == pep->pe_is_64bit ) {
|
||||
/* Likely totally unreasonable. Bad. */
|
||||
*errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL;
|
||||
return DW_DLV_ERROR;
|
||||
|
162
src/lib/libdwarf/dwarf_query.c
vendored
162
src/lib/libdwarf/dwarf_query.c
vendored
@ -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 2012 SN Systems Ltd. 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
|
||||
section is unreasonably sized or we are
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -839,6 +845,7 @@ dwarf_die_text(Dwarf_Die die,
|
||||
res = dwarf_attr(die,attrnum,&attr,&lerr);
|
||||
dbg = die->di_cu_context->cc_dbg;
|
||||
if (res == DW_DLV_ERROR) {
|
||||
dwarf_dealloc_error(dbg,lerr);
|
||||
return 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.
|
||||
This looks for DW_AT_addr_base and if present
|
||||
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.
|
||||
*/
|
||||
static int
|
||||
@ -986,12 +993,12 @@ _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
|
||||
Dwarf_Byte_Ptr sectionend = 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);
|
||||
if (res != DW_DLV_OK) {
|
||||
/* Ignore the inner error, report something meaningful */
|
||||
if (res == DW_DLV_ERROR && error) {
|
||||
dwarf_dealloc(dbg,*error, DW_DLA_ERROR);
|
||||
dwarf_dealloc_error(dbg,*error);
|
||||
*error = 0;
|
||||
}
|
||||
_dwarf_error(dbg,error,
|
||||
@ -1046,6 +1053,10 @@ _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg,
|
||||
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
|
||||
_dwarf_look_in_local_and_tied_by_index(
|
||||
Dwarf_Debug dbg,
|
||||
@ -1063,11 +1074,12 @@ _dwarf_look_in_local_and_tied_by_index(
|
||||
error && dwarf_errno(*error) ==
|
||||
DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION
|
||||
&& dbg->de_tied_data.td_tied_object) {
|
||||
/* see also DBG_HAS_SECONDARY macro */
|
||||
int res3 = 0;
|
||||
|
||||
/* We do not want to leak error structs... */
|
||||
/* *error safe */
|
||||
dwarf_dealloc(dbg,*error,DW_DLA_ERROR);
|
||||
dwarf_dealloc_error(dbg,*error);
|
||||
*error = 0; /* *error safe */
|
||||
/* Any error is returned on dbg,
|
||||
not tieddbg. */
|
||||
@ -1107,6 +1119,8 @@ dwarf_debug_addr_index_to_addr(Dwarf_Die die,
|
||||
/* ASSERT:
|
||||
attr_form == DW_FORM_GNU_addr_index ||
|
||||
attr_form == DW_FORM_addrx
|
||||
We are looking for data in .debug_addr,
|
||||
which could be in base file or in tied-file..
|
||||
*/
|
||||
int
|
||||
_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) {
|
||||
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. */
|
||||
res2 = _dwarf_look_in_local_and_tied_by_index(
|
||||
dbg,context,index_to_addr,return_addr,error);
|
||||
@ -1151,8 +1148,10 @@ _dwarf_look_in_local_and_tied(Dwarf_Half attr_form,
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_lowpc(Dwarf_Die die,
|
||||
static int
|
||||
_dwarf_lowpc_internal(Dwarf_Die die,
|
||||
Dwarf_Half attrnum,
|
||||
const char *msg,
|
||||
Dwarf_Addr *return_addr,
|
||||
Dwarf_Error *error)
|
||||
{
|
||||
@ -1173,7 +1172,7 @@ dwarf_lowpc(Dwarf_Die die,
|
||||
dbg = context->cc_dbg;
|
||||
address_size = context->cc_address_size;
|
||||
offset_size = context->cc_length_size;
|
||||
res = _dwarf_get_value_ptr(die, DW_AT_low_pc,
|
||||
res = _dwarf_get_value_ptr(die, attrnum,
|
||||
&attr_form,&info_ptr,0,error);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
return res;
|
||||
@ -1182,11 +1181,12 @@ dwarf_lowpc(Dwarf_Die die,
|
||||
return res;
|
||||
}
|
||||
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);
|
||||
if (class != DW_FORM_CLASS_ADDRESS) {
|
||||
/* Not the correct form for DW_AT_low_pc */
|
||||
_dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS);
|
||||
/* Not a correct FORM for low_pc or entry_pc */
|
||||
_dwarf_error_string(dbg, error, DW_DLE_LOWPC_WRONG_CLASS,
|
||||
(char *)msg);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
@ -1209,6 +1209,30 @@ dwarf_lowpc(Dwarf_Die die,
|
||||
*return_addr = ret_addr;
|
||||
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
|
||||
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
|
||||
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
|
||||
_dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg,
|
||||
Dwarf_CU_Context context,
|
||||
_dwarf_merge_all_base_attrs_of_cu_die(Dwarf_CU_Context context,
|
||||
Dwarf_Debug tieddbg,
|
||||
Dwarf_CU_Context *tiedcontext_out,
|
||||
Dwarf_Error *error)
|
||||
@ -1267,31 +1295,53 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg,
|
||||
&tiedcontext,
|
||||
error);
|
||||
if ( res == DW_DLV_ERROR) {
|
||||
/* Associate the error with dbg, not tieddbg */
|
||||
_dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
|
||||
return res;
|
||||
}
|
||||
if ( res == DW_DLV_NO_ENTRY) {
|
||||
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 =
|
||||
tiedcontext->cc_low_pc_present;
|
||||
context-> cc_low_pc =
|
||||
tiedcontext->cc_low_pc;
|
||||
}
|
||||
if (!context->cc_addr_base_present) {
|
||||
context-> cc_addr_base_present =
|
||||
tiedcontext->cc_addr_base_present;
|
||||
context-> cc_addr_base=
|
||||
tiedcontext->cc_addr_base;
|
||||
|
||||
if (tiedcontext->cc_base_address_present) {
|
||||
context->cc_base_address_present =
|
||||
tiedcontext->cc_base_address_present;
|
||||
context-> cc_base_address =
|
||||
tiedcontext->cc_base_address;
|
||||
}
|
||||
if (context->cc_version_stamp == DW_CU_VERSION4 &&
|
||||
!context->cc_ranges_base_present) {
|
||||
if (tiedcontext->cc_addr_base_offset_present) {
|
||||
/* This is a base-offset, not an address. */
|
||||
context-> cc_addr_base_offset_present =
|
||||
tiedcontext->cc_addr_base_offset_present;
|
||||
context-> cc_addr_base_offset=
|
||||
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;;
|
||||
tiedcontext->cc_ranges_base;
|
||||
}
|
||||
}
|
||||
if (!context->cc_str_offsets_tab_present) {
|
||||
context-> cc_str_offsets_tab_present =
|
||||
@ -1458,7 +1508,7 @@ dwarf_highpc_b(Dwarf_Die die,
|
||||
|
||||
*/
|
||||
int
|
||||
_dwarf_get_addr_from_tied(Dwarf_Debug dbg,
|
||||
_dwarf_get_addr_from_tied(Dwarf_Debug primary_dbg,
|
||||
Dwarf_CU_Context context,
|
||||
Dwarf_Unsigned index,
|
||||
Dwarf_Addr *addr_out,
|
||||
@ -1471,25 +1521,21 @@ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned addrtabsize = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
tieddbg = dbg->de_tied_data.td_tied_object;
|
||||
if (!tieddbg) {
|
||||
_dwarf_error(dbg, error, DW_DLE_NO_TIED_ADDR_AVAILABLE);
|
||||
if (!DBG_HAS_SECONDARY(primary_dbg)) {
|
||||
_dwarf_error(primary_dbg, error,
|
||||
DW_DLE_NO_TIED_ADDR_AVAILABLE);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (!context->cc_addr_base_present) {
|
||||
/* Does not exist. */
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
tieddbg = primary_dbg->de_secondary_dbg;
|
||||
res = _dwarf_search_for_signature(tieddbg,
|
||||
context->cc_signature,
|
||||
&tiedcontext,
|
||||
error);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
/* Associate the error with dbg, not tieddbg */
|
||||
_dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
|
||||
return res;
|
||||
}
|
||||
if ( res == DW_DLV_NO_ENTRY) {
|
||||
@ -1500,7 +1546,8 @@ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
|
||||
if ( (index > tieddbg->de_filesize ||
|
||||
index > 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 "
|
||||
"Looking for an index from an addr FORM "
|
||||
"we find an impossibly large index value for the tied "
|
||||
@ -1513,8 +1560,6 @@ _dwarf_get_addr_from_tied(Dwarf_Debug dbg,
|
||||
&local_addr,
|
||||
error);
|
||||
if ( res == DW_DLV_ERROR) {
|
||||
/* Associate the error with dbg, not tidedbg */
|
||||
_dwarf_error_mv_s_to_t(tieddbg,error,dbg,error);
|
||||
return res;
|
||||
}
|
||||
if ( res == DW_DLV_NO_ENTRY) {
|
||||
@ -1814,6 +1859,7 @@ dw_get_special_offset(Dwarf_Half attrnum,
|
||||
}
|
||||
return DW_FORM_CLASS_LOCLISTPTR;
|
||||
}
|
||||
case DW_AT_GNU_locviews:
|
||||
case DW_AT_sibling:
|
||||
case DW_AT_byte_size :
|
||||
case DW_AT_bit_offset :
|
||||
@ -1843,6 +1889,8 @@ dw_get_special_offset(Dwarf_Half attrnum,
|
||||
case DW_AT_object_pointer:
|
||||
case DW_AT_signature:
|
||||
return DW_FORM_CLASS_REFERENCE;
|
||||
case DW_AT_GNU_entry_view:
|
||||
return DW_FORM_CLASS_CONSTANT;
|
||||
case DW_AT_MIPS_fde: /* SGI/IRIX extension */
|
||||
return DW_FORM_CLASS_FRAMEPTR;
|
||||
default: break;
|
||||
|
81
src/lib/libdwarf/dwarf_ranges.c
vendored
81
src/lib/libdwarf/dwarf_ranges.c
vendored
@ -46,6 +46,9 @@
|
||||
#include "dwarf_util.h"
|
||||
#include "dwarf_string.h"
|
||||
|
||||
#define DEBUG_RANGES 1
|
||||
#undef DEBUG_RANGES
|
||||
|
||||
struct ranges_entry {
|
||||
struct ranges_entry *next;
|
||||
Dwarf_Ranges cur;
|
||||
@ -129,7 +132,6 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg,
|
||||
int res = DW_DLV_ERROR;
|
||||
Dwarf_Unsigned ranges_base = 0;
|
||||
Dwarf_Debug localdbg = dbg;
|
||||
Dwarf_Error localerror = 0;
|
||||
|
||||
/* default for dwarf_get_ranges() */
|
||||
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()");
|
||||
address_size = localdbg->de_pointer_size; /* default */
|
||||
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
|
||||
had better match! It cannot be other than a match.
|
||||
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) {
|
||||
return res;
|
||||
}
|
||||
/* FIX. HAS_TIED or ? */
|
||||
if (res == DW_DLV_NO_ENTRY) {
|
||||
/* data is in a.out, not dwp */
|
||||
localdbg = dbg->de_tied_data.td_tied_object;
|
||||
if (!localdbg) {
|
||||
if (!DBG_HAS_SECONDARY(dbg)) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
localdbg = dbg->de_secondary_dbg;
|
||||
res = _dwarf_load_section(localdbg,
|
||||
&localdbg->de_debug_ranges, &localerror);
|
||||
&localdbg->de_debug_ranges, 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;
|
||||
}
|
||||
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 +
|
||||
localdbg->de_debug_ranges.dss_size;
|
||||
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;
|
||||
beginrangeptr = rangeptr;
|
||||
|
||||
@ -366,6 +365,12 @@ dwarf_dealloc_ranges(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf,
|
||||
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
|
||||
_dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
|
||||
Dwarf_Die dw_die,
|
||||
@ -376,11 +381,10 @@ _dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
|
||||
Dwarf_Error *dw_error)
|
||||
{
|
||||
Dwarf_Bool hasatranges = FALSE;
|
||||
Dwarf_Bool haslowpc = FALSE;
|
||||
Dwarf_Attribute attr = 0;
|
||||
Dwarf_Unsigned rangeoffset_local = 0;
|
||||
int res = 0;
|
||||
Dwarf_Unsigned local_lowpc = 0;
|
||||
Dwarf_CU_Context cucon = 0;
|
||||
|
||||
res = dwarf_hasattr(dw_die,DW_AT_ranges, &hasatranges,dw_error);
|
||||
if (res != DW_DLV_OK) {
|
||||
@ -397,7 +401,7 @@ _dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
|
||||
*dw_error = 0;
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
}
|
||||
res = dwarf_global_formref(attr,
|
||||
&rangeoffset_local, dw_error);
|
||||
if (res != DW_DLV_OK) {
|
||||
@ -408,32 +412,16 @@ _dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg,
|
||||
return res;
|
||||
}
|
||||
}
|
||||
/* rangeoffset_local was set . */
|
||||
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);
|
||||
attr = 0;
|
||||
*have_die_ranges_offset = TRUE;
|
||||
*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;
|
||||
}
|
||||
|
||||
@ -457,8 +445,6 @@ dwarf_get_ranges_baseaddress(Dwarf_Debug dw_dbg,
|
||||
Dwarf_CU_Context context = 0;
|
||||
Dwarf_Unsigned local_ranges_offset = 0;
|
||||
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_Unsigned die_ranges_offset = 0;
|
||||
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) {
|
||||
*dw_at_ranges_offset_present = local_ranges_offset_present;
|
||||
}
|
||||
if (have_die_base_addr) {
|
||||
local_base_addr_present = have_die_base_addr;
|
||||
local_base_addr = die_base_addr;
|
||||
} 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;
|
||||
if (context->cc_base_address_present) {
|
||||
*dw_baseaddress = context->cc_base_address;
|
||||
*dw_known_base = context->cc_base_address_present;
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
688
src/lib/libdwarf/dwarf_rnglists.c
vendored
688
src/lib/libdwarf/dwarf_rnglists.c
vendored
@ -51,12 +51,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "dwarf_string.h"
|
||||
#include "dwarf_rnglists.h"
|
||||
|
||||
#undef DEBUG_RNGLIST
|
||||
|
||||
#define SIZEOFT8 1
|
||||
#define SIZEOFT16 2
|
||||
#define SIZEOFT32 4
|
||||
#define SIZEOFT64 8
|
||||
|
||||
#if 0 /* dump_bytes */
|
||||
#ifdef DEBUG_RNGLIST /* dump_bytes */
|
||||
static void
|
||||
dump_bytes(const char *msg,Dwarf_Small * start, long len)
|
||||
{
|
||||
@ -67,6 +69,7 @@ dump_bytes(const char *msg,Dwarf_Small * start, long len)
|
||||
printf("%02x", *cur);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif /*0*/
|
||||
#if 0 /* dump_rh */
|
||||
@ -129,41 +132,6 @@ dump_rc(const char *msg,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The DWARF5 standard does not make it clear that
|
||||
there should be a rnglists_base even in a dwp object.
|
||||
Table F.1 implies such is not needed.
|
||||
gcc seems to leave it off in the dwp.
|
||||
ibase is an offset in the array of offsets in a rnglist,
|
||||
which only makes sense for DW_FORM_rnglistx and
|
||||
in that case there is no base.
|
||||
We are dealing with DW_FORM_rnglistx */
|
||||
static int
|
||||
_dwarf_implicit_rnglists_base(Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned indexval,
|
||||
Dwarf_Unsigned *ibase)
|
||||
{
|
||||
Dwarf_Rnglists_Context rctx = 0;
|
||||
if (IS_INVALID_DBG(dbg)) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (!dbg->de_debug_rnglists.dss_size) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (!dbg->de_rnglists_context_count) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
/* This implicit base can only work if the 0-th
|
||||
Rnglists_Context is appropriate here. */
|
||||
rctx = dbg->de_rnglists_context[0];
|
||||
if (indexval > rctx->rc_offset_entry_count) {
|
||||
/* We are not using base offset, we
|
||||
will not see a DW_FORM_rnglistx */
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
*ibase = rctx->rc_offsets_off_in_sect;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
free_rnglists_context(Dwarf_Rnglists_Context cx)
|
||||
{
|
||||
@ -283,7 +251,7 @@ read_single_rle_entry(Dwarf_Debug dbg,
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: "
|
||||
"The rangelists entry at .debug_rnglists"
|
||||
"The rangelists entry at .debug_rnglists[.dwo]"
|
||||
" offset 0x%x" ,dataoffset);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" has code 0x%x which is unknown",code);
|
||||
@ -301,8 +269,7 @@ read_single_rle_entry(Dwarf_Debug dbg,
|
||||
preserve a testing baseline:
|
||||
baselines/hongg2024-02-18-m.base
|
||||
otherwise we would test against sectionsize first.*/
|
||||
|
||||
Dwarf_Unsigned sectionsize = dbg->de_debug_rnglists.dss_size;
|
||||
Dwarf_Unsigned sectionsize = 0;
|
||||
|
||||
if (data > enddata || data < startdata ) {
|
||||
/* Corrupt data being read. */
|
||||
@ -312,6 +279,7 @@ read_single_rle_entry(Dwarf_Debug dbg,
|
||||
"of its allowed space");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
sectionsize = dbg->de_debug_rnglists.dss_size;
|
||||
if (count > sectionsize) {
|
||||
/* Corrupt data being read. */
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
@ -332,8 +300,9 @@ read_single_rle_entry(Dwarf_Debug dbg,
|
||||
|
||||
/* Reads the header. Determines the
|
||||
various offsets, including offset
|
||||
of the next header. Does no memory
|
||||
allocations here. */
|
||||
of the next header. ALlocates
|
||||
an array pointed to by rc_offset_value_array
|
||||
here. */
|
||||
int
|
||||
_dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
Dwarf_Bool build_offset_array,
|
||||
@ -341,7 +310,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned sectionlength,
|
||||
Dwarf_Small *data,
|
||||
Dwarf_Small *end_data,
|
||||
Dwarf_Unsigned offset,
|
||||
Dwarf_Unsigned starting_offset,
|
||||
Dwarf_Rnglists_Context buildhere,
|
||||
Dwarf_Unsigned *next_offset,
|
||||
Dwarf_Error *error)
|
||||
@ -355,7 +324,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
unsigned segment_selector_size= 0;
|
||||
Dwarf_Unsigned offset_entry_count = 0;
|
||||
Dwarf_Unsigned localoff = 0;
|
||||
Dwarf_Unsigned lists_len = 0;
|
||||
Dwarf_Unsigned lists_byte_len = 0;
|
||||
Dwarf_Unsigned secsize_dbg = 0;
|
||||
Dwarf_Unsigned sum_size = 0;
|
||||
|
||||
@ -369,7 +338,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
" section_length argument (%lu) mismatch vs.",
|
||||
sectionlength);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
".debug_rnglists"
|
||||
".debug_rnglists[.dwo]"
|
||||
" section length",secsize_dbg);
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
@ -381,17 +350,19 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
data,offset_size,exten_size,
|
||||
error,
|
||||
sectionlength,end_data);
|
||||
sum_size = arealen+offset_size+exten_size;
|
||||
localoff = offset_size+exten_size;
|
||||
/* local off is bytes including length field */
|
||||
sum_size = arealen+localoff;
|
||||
if (arealen > sectionlength ||
|
||||
sum_size < arealen ||
|
||||
sum_size > sectionlength) {
|
||||
dwarfstring m;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: A .debug_rnglists "
|
||||
"DW_DLE_RNGLISTS_ERROR: A .debug_rnglists[.dwo] "
|
||||
"area size of 0x%x ",arealen);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"at offset 0x%x ",offset);
|
||||
"at offset 0x%x ",starting_offset);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"is larger than the entire section size of "
|
||||
"0x%x. Corrupt DWARF.",sectionlength);
|
||||
@ -400,11 +371,10 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
localoff = offset_size+exten_size;
|
||||
buildhere->rc_length = arealen + localoff;
|
||||
buildhere->rc_length = sum_size;
|
||||
buildhere->rc_dbg = dbg;
|
||||
buildhere->rc_index = contextnum;
|
||||
buildhere->rc_header_offset = offset;
|
||||
buildhere->rc_header_offset = starting_offset;
|
||||
buildhere->rc_offset_size = offset_size;
|
||||
buildhere->rc_extension_size = exten_size;
|
||||
buildhere->rc_magic = RNGLISTS_MAGIC;
|
||||
@ -431,7 +401,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring m;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists "
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo] "
|
||||
"The address size "
|
||||
"of %u is not supported.",address_size);
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
@ -452,7 +422,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring m;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists"
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo]"
|
||||
" The segment selector size "
|
||||
"of %u is not supported.",address_size);
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
@ -460,13 +430,13 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if ((offset+localoff+SIZEOFT32) > secsize_dbg) {
|
||||
if ((starting_offset+localoff+SIZEOFT32) > secsize_dbg) {
|
||||
dwarfstring m;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists"
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo]"
|
||||
" Header runs off the end of the section "
|
||||
" with offset %u",offset+localoff+SIZEOFT32);
|
||||
" with offset %u",starting_offset+localoff+SIZEOFT32);
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
@ -482,7 +452,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring m;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists"
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo]"
|
||||
" offset entry size impossibly large "
|
||||
" with size 0x%x",
|
||||
offset_entry_count*offset_size);
|
||||
@ -493,7 +463,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
}
|
||||
if (offset_entry_count){
|
||||
buildhere->rc_offsets_array = data;
|
||||
lists_len += offset_size*offset_entry_count;
|
||||
lists_byte_len += offset_size*offset_entry_count;
|
||||
if (build_offset_array) {
|
||||
Dwarf_Unsigned tabentrynum = 0;
|
||||
|
||||
@ -524,11 +494,14 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
}
|
||||
} /* else no offset table */
|
||||
if (offset_entry_count >= secsize_dbg ||
|
||||
lists_len >= secsize_dbg) {
|
||||
lists_byte_len >= secsize_dbg) {
|
||||
dwarfstring m;
|
||||
|
||||
free(buildhere->rc_offset_value_array);
|
||||
buildhere->rc_offset_value_array = 0;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists"
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo]"
|
||||
" offset entry count"
|
||||
" of %u is clearly impossible. Corrupt data",
|
||||
offset_entry_count);
|
||||
@ -537,14 +510,18 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
data += lists_len;
|
||||
buildhere->rc_offsets_off_in_sect = offset+localoff;
|
||||
localoff += lists_len;
|
||||
data += lists_byte_len;
|
||||
buildhere->rc_offsets_off_in_sect = starting_offset+localoff;
|
||||
localoff += lists_byte_len;
|
||||
if (localoff > buildhere->rc_length) {
|
||||
dwarfstring m;
|
||||
|
||||
free(buildhere->rc_offset_value_array);
|
||||
buildhere->rc_offset_value_array = 0;
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists"
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo]"
|
||||
" length of rnglists header too large at"
|
||||
" of %u is clearly impossible. Corrupt data",
|
||||
localoff);
|
||||
@ -553,14 +530,17 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
buildhere->rc_first_rnglist_offset = offset+localoff;
|
||||
buildhere->rc_first_rnglist_offset = starting_offset+localoff;
|
||||
buildhere->rc_rnglists_header = startdata;
|
||||
buildhere->rc_endaddr = startdata +buildhere->rc_length;
|
||||
if (buildhere->rc_endaddr > end_data) {
|
||||
dwarfstring m;
|
||||
|
||||
free(buildhere->rc_offset_value_array);
|
||||
buildhere->rc_offset_value_array = 0;
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists"
|
||||
" DW_DLE_RNGLISTS_ERROR: .debug_rnglists[.dwo]"
|
||||
" length of rnglists header (%u) "
|
||||
"runs off end of section. Corrupt data",
|
||||
buildhere->rc_length);
|
||||
@ -571,6 +551,13 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg,
|
||||
}
|
||||
buildhere->rc_past_last_rnglist_offset =
|
||||
buildhere->rc_header_offset +buildhere->rc_length;
|
||||
if (buildhere->rc_past_last_rnglist_offset > secsize_dbg) {
|
||||
free(buildhere->rc_offset_value_array);
|
||||
buildhere->rc_offset_value_array = 0;
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
"Impossible end of rnglist");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
*next_offset = buildhere->rc_past_last_rnglist_offset;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
@ -595,9 +582,9 @@ internal_load_rnglists_contexts(Dwarf_Debug dbg,
|
||||
Dwarf_Chain head_chain = 0;
|
||||
Dwarf_Chain * plast = &head_chain;
|
||||
int res = 0;
|
||||
Dwarf_Unsigned i = 0;
|
||||
Dwarf_Unsigned chainlength = 0;
|
||||
Dwarf_Rnglists_Context *fullarray = 0;
|
||||
Dwarf_Unsigned i = 0;
|
||||
|
||||
for (i = 0 ; data < end_data ; ++i,data = startdata+nextoffset) {
|
||||
Dwarf_Rnglists_Context newcontext = 0;
|
||||
@ -696,6 +683,8 @@ int dwarf_load_rnglists(
|
||||
if (rnglists_count) {
|
||||
*rnglists_count = dbg->de_rnglists_context_count;
|
||||
}
|
||||
if (rnglists_count) {
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (!dbg->de_debug_rnglists.dss_size) {
|
||||
@ -761,6 +750,8 @@ dwarf_get_rnglist_offset_index_value(
|
||||
Dwarf_Small *offsetptr = 0;
|
||||
Dwarf_Unsigned targetoffset = 0;
|
||||
Dwarf_Unsigned localoffset = 0;
|
||||
Dwarf_Unsigned globaloffset = 0;
|
||||
Dwarf_Unsigned section_size = 0;
|
||||
|
||||
CHECK_DBG(dbg,error,"dwarf_get_rnglist_offset_index_value()");
|
||||
if (!dbg->de_rnglists_context) {
|
||||
@ -786,7 +777,13 @@ dwarf_get_rnglist_offset_index_value(
|
||||
}
|
||||
offset_len = con->rc_offset_size;
|
||||
localoffset = offsetentry_index*offset_len;
|
||||
offsetptr = con->rc_offsets_array + localoffset;
|
||||
if (localoffset >= con->rc_length) {
|
||||
_dwarf_error_string(dbg,error, DW_DLE_RLE_ERROR,
|
||||
"DW_DLE_RLE_ERROR: a .debug_rnglists[.dwo] "
|
||||
"section offset "
|
||||
"is greater than this rnglists table length");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if ((con->rc_offsets_off_in_sect +localoffset +
|
||||
offset_len) >
|
||||
con->rc_past_last_rnglist_offset) {
|
||||
@ -804,15 +801,24 @@ dwarf_get_rnglist_offset_index_value(
|
||||
return DW_DLV_ERROR;
|
||||
|
||||
}
|
||||
offsetptr = con->rc_offsets_array + localoffset;
|
||||
READ_UNALIGNED_CK(dbg,targetoffset,Dwarf_Unsigned,
|
||||
offsetptr,
|
||||
offset_len,error,con->rc_endaddr);
|
||||
globaloffset = con->rc_offsets_off_in_sect;
|
||||
section_size = dbg->de_debug_rnglists.dss_size;
|
||||
if (globaloffset >= section_size) {
|
||||
_dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR,
|
||||
"DW_DLE_RNGLISTS_ERROR: "
|
||||
"The offset of a rnglists entry is past "
|
||||
"its allowed space");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (offset_value_out) {
|
||||
*offset_value_out = targetoffset;
|
||||
}
|
||||
if (global_offset_value_out) {
|
||||
*global_offset_value_out = targetoffset +
|
||||
con->rc_offsets_off_in_sect;
|
||||
*global_offset_value_out = globaloffset;
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
@ -875,8 +881,9 @@ int dwarf_get_rnglist_head_basics(
|
||||
*rnglists_base_address_present = head->rh_cu_base_address_present;
|
||||
*rnglists_base_address= head->rh_cu_base_address;
|
||||
|
||||
*rnglists_debug_addr_base_present = head->rh_cu_addr_base_present;
|
||||
*rnglists_debug_addr_base = head->rh_cu_addr_base;
|
||||
*rnglists_debug_addr_base_present =
|
||||
head->rh_cu_addr_base_offset_present;
|
||||
*rnglists_debug_addr_base = head->rh_cu_addr_base_offset;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
@ -1049,30 +1056,68 @@ int dwarf_get_rnglist_rle(
|
||||
static int
|
||||
_dwarf_which_rnglists_context(Dwarf_Debug dbg,
|
||||
Dwarf_CU_Context ctx,
|
||||
Dwarf_Unsigned rnglist_offset,
|
||||
Dwarf_Unsigned rnglist_offset/* not always set */,
|
||||
Dwarf_Unsigned *index,
|
||||
Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_Unsigned count;
|
||||
Dwarf_Unsigned count = 0;
|
||||
Dwarf_Rnglists_Context *array;
|
||||
Dwarf_Rnglists_Context rcx = 0;
|
||||
Dwarf_Unsigned rcxoff = 0;
|
||||
Dwarf_Unsigned rcxend = 0;
|
||||
|
||||
Dwarf_Unsigned i = 0;
|
||||
Dwarf_Unsigned rnglists_base = 0;
|
||||
Dwarf_Bool rnglists_base_present = FALSE;
|
||||
int res = 0;
|
||||
Dwarf_Bool found_base = FALSE;
|
||||
Dwarf_Unsigned chosen_offset = 0;
|
||||
|
||||
array = dbg->de_rnglists_context;
|
||||
count = dbg->de_rnglists_context_count;
|
||||
/* Using the slow way, a simple linear search. */
|
||||
if (!ctx->cc_rnglists_base_present) {
|
||||
/* We look at the location of each rnglist context
|
||||
to find one with the offset the DIE gave us. */
|
||||
for ( i = 0 ; i < count; ++i) {
|
||||
Dwarf_Rnglists_Context rcx = array[i];
|
||||
Dwarf_Unsigned rcxoff = rcx->rc_header_offset;
|
||||
Dwarf_Unsigned rcxend = rcxoff +
|
||||
rcx->rc_length;
|
||||
|
||||
if (rnglist_offset < rcxoff){
|
||||
if (!array) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (count == 1) {
|
||||
*index = 0;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (ctx->cc_rnglists_base_present) {
|
||||
rnglists_base_present = ctx->cc_rnglists_base_present;
|
||||
rnglists_base = ctx->cc_rnglists_base;
|
||||
found_base = TRUE;
|
||||
chosen_offset = rnglists_base;
|
||||
}
|
||||
if (!found_base) {
|
||||
res = _dwarf_has_SECT_fission(ctx,
|
||||
DW_SECT_RNGLISTS,
|
||||
&rnglists_base_present,&rnglists_base);
|
||||
if (res == DW_DLV_OK) {
|
||||
found_base = TRUE;
|
||||
chosen_offset = rnglists_base;
|
||||
}
|
||||
}
|
||||
if (!found_base) {
|
||||
rnglists_base = rnglist_offset;
|
||||
chosen_offset = rnglist_offset;
|
||||
}
|
||||
|
||||
rcx = array[i];
|
||||
rcxoff = rcx->rc_header_offset;
|
||||
rcxend = rcxoff + rcx->rc_length;
|
||||
|
||||
/* We look at the location of each rnglist context
|
||||
to find one with the offset we want */
|
||||
for ( i = 0 ; i < count; ++i) {
|
||||
rcx = array[i];
|
||||
rcxoff = rcx->rc_header_offset;
|
||||
rcxend = rcxoff +
|
||||
rcx->rc_length;
|
||||
if (chosen_offset < rcxoff){
|
||||
continue;
|
||||
}
|
||||
if (rnglist_offset < rcxend ){
|
||||
if (chosen_offset < rcxend ){
|
||||
*index = i;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
@ -1084,67 +1129,17 @@ _dwarf_which_rnglists_context(Dwarf_Debug dbg,
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: rnglist ran off end "
|
||||
" finding target offset of"
|
||||
" 0x%" DW_PR_XZEROS DW_PR_DUx ,rnglist_offset);
|
||||
" 0x%" DW_PR_XZEROS DW_PR_DUx ,chosen_offset);
|
||||
dwarfstring_append(&m,
|
||||
" Not found anywhere in .debug_rnglists "
|
||||
" Not found anywhere in .debug_rnglists[.dwo] "
|
||||
"data. Corrupted data?");
|
||||
_dwarf_error_string(dbg,error,
|
||||
DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
}
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
} else {
|
||||
/* We have a DW_AT_rnglists_base (cc_rangelists_base),
|
||||
let's use it. */
|
||||
Dwarf_Unsigned lookfor = 0;;
|
||||
|
||||
lookfor = ctx->cc_rnglists_base;
|
||||
for ( i = 0 ; i < count; ++i) {
|
||||
dwarfstring m;
|
||||
|
||||
Dwarf_Rnglists_Context rcx = array[i];
|
||||
if (rcx->rc_offsets_off_in_sect == lookfor){
|
||||
*index = i;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (rcx->rc_offsets_off_in_sect < lookfor){
|
||||
continue;
|
||||
}
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: rnglists base of "
|
||||
" 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->rc_offsets_off_in_sect);
|
||||
_dwarf_error_string(dbg,error,
|
||||
DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
{
|
||||
dwarfstring m;
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: rnglist base of "
|
||||
" 0x%" DW_PR_XZEROS DW_PR_DUx ,lookfor);
|
||||
dwarfstring_append(&m,
|
||||
" was not found anywhere in .debug_rnglists "
|
||||
"data. Corrupted data?");
|
||||
_dwarf_error_string(dbg,error,
|
||||
DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
}
|
||||
/* ASSERT: This line cannot be reached. */
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head h)
|
||||
@ -1364,7 +1359,7 @@ build_array_of_rle(Dwarf_Debug dbg,
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" DW_DLE_RNGLISTS_ERROR: "
|
||||
" The .debug_rnglists "
|
||||
" The .debug_rnglists[.dwo] "
|
||||
" rangelist code 0x%x is unknown, "
|
||||
" DWARF5 is corrupted.",code);
|
||||
_dwarf_error_string(dbg, error,
|
||||
@ -1403,8 +1398,234 @@ build_array_of_rle(Dwarf_Debug dbg,
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
_dwarf_fill_in_rle_head(Dwarf_Debug dbg,
|
||||
Dwarf_Half theform,
|
||||
/* attr_val is either an offset
|
||||
(theform == DW_FORM_sec_offset)
|
||||
to a specific rangelist entry set or
|
||||
or a rnglistx index DW_FORM_rnglistx
|
||||
at that index is the local offset of
|
||||
a specific rangelist entry set. */
|
||||
Dwarf_Unsigned attr_val,
|
||||
/* ctx is the context from the PRIMARY
|
||||
dbg, not necessarily for *this* dbg */
|
||||
Dwarf_CU_Context ctx,
|
||||
Dwarf_Rnglists_Head *head_out,
|
||||
Dwarf_Unsigned *entries_count_out,
|
||||
Dwarf_Unsigned *global_offset_of_rle_set,
|
||||
Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_Bool is_rnglistx = FALSE;
|
||||
Dwarf_Unsigned entrycount = 0;
|
||||
Dwarf_Unsigned offset_in_rnglists = 0;
|
||||
Dwarf_Rnglists_Context *array = 0;
|
||||
Dwarf_Rnglists_Context rctx = 0;
|
||||
struct Dwarf_Rnglists_Head_s shead;
|
||||
Dwarf_Rnglists_Head lhead = 0;
|
||||
Dwarf_Unsigned rnglists_contextnum = 0;
|
||||
int res = 0;
|
||||
Dwarf_Small *table_base = 0;
|
||||
Dwarf_Small *table_entry = 0;
|
||||
Dwarf_Small *enddata = 0;
|
||||
Dwarf_Unsigned rle_global_offset = 0;
|
||||
unsigned offsetsize = 0;
|
||||
Dwarf_Unsigned secsize = 0;
|
||||
Dwarf_Debug localdbg = 0;
|
||||
|
||||
if (theform == DW_FORM_rnglistx) {
|
||||
is_rnglistx = TRUE;
|
||||
} else {
|
||||
offset_in_rnglists = attr_val;
|
||||
}
|
||||
/* ASSERT: the 3 pointers just set are non-null */
|
||||
/* the context cc_rnglists_base gives the offset
|
||||
of the array. of offsets (if cc_rnglists_base_present) */
|
||||
secsize = dbg->de_debug_rnglists.dss_size;
|
||||
if (dbg != ctx->cc_dbg) {
|
||||
/* is_rnglistx TRUE */
|
||||
/* Now find the correct secondary context via
|
||||
signature. */
|
||||
Dwarf_CU_Context lctx = 0;
|
||||
if (ctx->cc_signature_present) {
|
||||
/* Looking in current dbg for the correct cu context */
|
||||
res = _dwarf_search_for_signature(dbg,
|
||||
ctx->cc_signature,
|
||||
&lctx,error);
|
||||
if (res != DW_DLV_OK) {
|
||||
if (res == DW_DLV_NO_ENTRY) {
|
||||
} else {
|
||||
_dwarf_error_string(dbg,error, DW_DLE_RLE_ERROR,
|
||||
"DW_DLE_RLE_ERROR: a .debug_rnglists[.dwo] "
|
||||
"cu context cannot be found with the "
|
||||
"correct signature");
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
ctx = lctx;
|
||||
}
|
||||
} else {
|
||||
/* No signature. Hopeless, I think. */
|
||||
_dwarf_error_string(dbg,error, DW_DLE_RLE_ERROR,
|
||||
"DW_DLE_RLE_ERROR: a .debug_rnglists[.dwo] "
|
||||
"cu context cannot be found as there is "
|
||||
"no signature to use");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* A */
|
||||
if (ctx->cc_rnglists_base_present) {
|
||||
offset_in_rnglists = ctx->cc_rnglists_base;
|
||||
} else {
|
||||
offset_in_rnglists = attr_val;
|
||||
}
|
||||
if (offset_in_rnglists >= secsize) {
|
||||
_dwarf_error_string(dbg,error, DW_DLE_RLE_ERROR,
|
||||
"DW_DLE_RLE_ERROR: a .debug_rnglists[.dwo] offset "
|
||||
"is greater than the rnglists section size");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
/* B */
|
||||
localdbg = dbg;
|
||||
{
|
||||
/* This call works for updated DWARF5 not inheriting
|
||||
DW_AT_rnglists_base or generating such.
|
||||
It returns rangelists_context 0 if no
|
||||
base, which works for gcc/clang. */
|
||||
res = _dwarf_which_rnglists_context(localdbg,ctx,
|
||||
offset_in_rnglists,
|
||||
&rnglists_contextnum,error);
|
||||
if (res == DW_DLV_OK) {
|
||||
/* FALL THROUGH */
|
||||
} else if (res == DW_DLV_NO_ENTRY) {
|
||||
rnglists_contextnum = 0;
|
||||
/* FALL THROUGH */
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
/* C */
|
||||
array = localdbg->de_rnglists_context;
|
||||
rctx = array[rnglists_contextnum];
|
||||
table_base = rctx->rc_offsets_array;
|
||||
entrycount = rctx->rc_offset_entry_count;
|
||||
offsetsize = rctx->rc_offset_size;
|
||||
enddata = rctx->rc_endaddr;
|
||||
if (is_rnglistx && attr_val >= entrycount) {
|
||||
dwarfstring m;
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: rnglists table index of"
|
||||
" %u" ,attr_val);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" too large for table of %u "
|
||||
"entries.",entrycount);
|
||||
_dwarf_error_string(dbg,error,
|
||||
DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
memset(&shead,0,sizeof(shead));
|
||||
shead.rh_context = ctx;
|
||||
shead.rh_magic = RNGLISTS_MAGIC;
|
||||
shead.rh_localcontext = rctx;
|
||||
shead.rh_index = rnglists_contextnum;
|
||||
shead.rh_version = rctx->rc_version;
|
||||
shead.rh_offset_size = offsetsize;
|
||||
shead.rh_address_size = rctx->rc_address_size;
|
||||
shead.rh_segment_selector_size =
|
||||
rctx->rc_segment_selector_size;
|
||||
|
||||
/* DW_AT_rnglists_base from CU */
|
||||
shead.rh_at_rnglists_base_present =
|
||||
ctx->cc_rnglists_base_present;
|
||||
shead.rh_at_rnglists_base = ctx->cc_rnglists_base;
|
||||
|
||||
/* DW_AT_low_pc originally if present. From CU,
|
||||
possibly inherited into dwo from skeleton. */
|
||||
shead.rh_cu_base_address_present = ctx->cc_base_address_present;
|
||||
shead.rh_cu_base_address = ctx->cc_base_address;;
|
||||
|
||||
/* base address DW_AT_addr_base of our part of
|
||||
.debug_addr, from CU */
|
||||
shead.rh_cu_addr_base_offset = ctx->cc_addr_base_offset;
|
||||
shead.rh_cu_addr_base_offset_present =
|
||||
ctx->cc_addr_base_offset_present;
|
||||
|
||||
/* D */
|
||||
if (is_rnglistx) {
|
||||
Dwarf_Unsigned table_entryval = 0;
|
||||
|
||||
table_entry = attr_val*offsetsize + table_base;
|
||||
/* No malloc here yet so no leak if the macro returns
|
||||
DW_DLV_ERROR */
|
||||
READ_UNALIGNED_CK(localdbg,table_entryval, Dwarf_Unsigned,
|
||||
table_entry,offsetsize,error,enddata);
|
||||
if (table_entryval >= secsize) {
|
||||
_dwarf_error_string(dbg,error, DW_DLE_RLE_ERROR,
|
||||
"DW_DLE_RLE_ERROR: a .debug_rnglists[.dwo] "
|
||||
"table entry "
|
||||
"value is impossibly large");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if ((rctx->rc_offsets_off_in_sect +
|
||||
table_entryval) >= secsize) {
|
||||
_dwarf_error_string(dbg,error, DW_DLE_RLE_ERROR,
|
||||
"DW_DLE_RLE_ERROR: a .debug_rnglist[.dwo]s "
|
||||
"table entry "
|
||||
"value + section offset is impossibly large");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
rle_global_offset = rctx->rc_offsets_off_in_sect +
|
||||
table_entryval;
|
||||
} else {
|
||||
rle_global_offset = attr_val;
|
||||
}
|
||||
/* E */
|
||||
shead.rh_end_data_area = enddata;
|
||||
shead.rh_rlearea_offset = rle_global_offset;
|
||||
shead.rh_rlepointer = rle_global_offset +
|
||||
localdbg->de_debug_rnglists.dss_data;
|
||||
lhead = (Dwarf_Rnglists_Head)
|
||||
_dwarf_get_alloc(dbg,DW_DLA_RNGLISTS_HEAD,1);
|
||||
if (!lhead) {
|
||||
_dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
|
||||
"Allocating a Dwarf_Rnglists_Head struct fails"
|
||||
" in libdwarf function "
|
||||
"dwarf_rnglists_index_get_rle_head()");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
/* To read correctly from DWARF data we must
|
||||
use the data in the tied (SECONDARY) when
|
||||
applicable. This is a bit delicate. */
|
||||
shead.rh_dbg = localdbg;
|
||||
*lhead = shead;
|
||||
res = build_array_of_rle(localdbg,lhead,error);
|
||||
if (res != DW_DLV_OK) {
|
||||
dwarf_dealloc(localdbg,lhead,DW_DLA_RNGLISTS_HEAD);
|
||||
return res;
|
||||
}
|
||||
if (global_offset_of_rle_set) {
|
||||
*global_offset_of_rle_set = rle_global_offset;
|
||||
}
|
||||
/* Caller needs the head pointer else there will be leaks. */
|
||||
*head_out = lhead;
|
||||
if (entries_count_out) {
|
||||
*entries_count_out = lhead->rh_count;
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
/* Build a head with all the relevent Entries
|
||||
attached.
|
||||
If the context is not found in the main object,
|
||||
and there is a tied-file
|
||||
use the context signature (should be present)
|
||||
and look in the tied-file for a match and
|
||||
get the content there.
|
||||
*/
|
||||
int
|
||||
dwarf_rnglists_get_rle_head(
|
||||
@ -1423,19 +1644,7 @@ dwarf_rnglists_get_rle_head(
|
||||
Dwarf_Error *error)
|
||||
{
|
||||
int res = 0;
|
||||
Dwarf_Unsigned rnglists_contextnum = 0;
|
||||
Dwarf_Small *table_base = 0;
|
||||
Dwarf_Small *table_entry = 0;
|
||||
Dwarf_Small *enddata = 0;
|
||||
Dwarf_Rnglists_Context *array = 0;
|
||||
Dwarf_Rnglists_Context rctx = 0;
|
||||
Dwarf_Unsigned entrycount = 0;
|
||||
unsigned offsetsize = 0;
|
||||
Dwarf_Unsigned rle_global_offset = 0;
|
||||
Dwarf_Rnglists_Head lhead = 0;
|
||||
Dwarf_CU_Context ctx = 0;
|
||||
struct Dwarf_Rnglists_Head_s shead;
|
||||
Dwarf_Unsigned offset_in_rnglists = 0;
|
||||
Dwarf_Debug dbg = 0;
|
||||
Dwarf_Bool is_rnglistx = FALSE;
|
||||
|
||||
@ -1447,153 +1656,70 @@ dwarf_rnglists_get_rle_head(
|
||||
"dwarf_rnglists_get_rle_head()");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
memset(&shead,0,sizeof(shead));
|
||||
ctx = attr->ar_cu_context;
|
||||
dbg = ctx->cc_dbg;
|
||||
CHECK_DBG(dbg,error,
|
||||
"dwarf_rnglists_get_rle_head() via attribute");
|
||||
|
||||
array = dbg->de_rnglists_context;
|
||||
|
||||
if (theform == DW_FORM_rnglistx) {
|
||||
is_rnglistx = TRUE;
|
||||
}
|
||||
/* ASSERT: the 3 pointers just set are non-null */
|
||||
/* the context cc_rnglists_base gives the offset
|
||||
of the array. of offsets (if cc_rnglists_base_present) */
|
||||
offset_in_rnglists = attr_val;
|
||||
if (is_rnglistx) {
|
||||
if (ctx->cc_rnglists_base_present) {
|
||||
offset_in_rnglists = ctx->cc_rnglists_base;
|
||||
} else if (ctx->cc_is_dwo) {
|
||||
/* Generate a base and set as 'present'
|
||||
by looking at the location offset
|
||||
table that we are supposedly indexing into.
|
||||
finding what the table value is.
|
||||
An implicit rnglists_base.
|
||||
Will not work with multiple rnglists! */
|
||||
int ires = 0;
|
||||
Dwarf_Unsigned ibase = 0;
|
||||
ires = _dwarf_implicit_rnglists_base(dbg,
|
||||
attr_val,&ibase);
|
||||
if (ires != DW_DLV_OK) {
|
||||
dwarfstring m;
|
||||
CHECK_DBG(dbg,error,
|
||||
"dwarf_rnglists_get_rle_head() via attribute");
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: rnglists table"
|
||||
" index of"
|
||||
" %u" ,attr_val);
|
||||
dwarfstring_append(&m,
|
||||
" is unusable, there is no default "
|
||||
" rnglists base address ");
|
||||
_dwarf_error_string(dbg,error,
|
||||
DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
ctx->cc_rnglists_base_present = TRUE;
|
||||
ctx->cc_rnglists_base = ibase;
|
||||
offset_in_rnglists = ibase;
|
||||
if (is_rnglistx) {
|
||||
if (ctx->cc_rnglists_base_present ||
|
||||
dbg->de_rnglists_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_rnglists_get_rle_head() via attribute(sec)");
|
||||
}
|
||||
} else {
|
||||
offset_in_rnglists = attr_val;
|
||||
}
|
||||
res = _dwarf_which_rnglists_context(dbg,ctx,
|
||||
offset_in_rnglists,
|
||||
&rnglists_contextnum,error);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
rctx = array[rnglists_contextnum];
|
||||
table_base = rctx->rc_offsets_array;
|
||||
entrycount = rctx->rc_offset_entry_count;
|
||||
offsetsize = rctx->rc_offset_size;
|
||||
enddata = rctx->rc_endaddr;
|
||||
|
||||
if (is_rnglistx && attr_val >= entrycount) {
|
||||
dwarfstring m;
|
||||
|
||||
dwarfstring_constructor(&m);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
"DW_DLE_RNGLISTS_ERROR: rnglists table index of"
|
||||
" %u" ,attr_val);
|
||||
dwarfstring_append_printf_u(&m,
|
||||
" too large for table of %u "
|
||||
"entries.",entrycount);
|
||||
_dwarf_error_string(dbg,error,
|
||||
DW_DLE_RNGLISTS_ERROR,
|
||||
dwarfstring_string(&m));
|
||||
dwarfstring_destructor(&m);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
shead.rh_context = ctx;
|
||||
shead.rh_magic = RNGLISTS_MAGIC;
|
||||
shead.rh_localcontext = rctx;
|
||||
shead.rh_index = rnglists_contextnum;
|
||||
shead.rh_version = rctx->rc_version;
|
||||
shead.rh_offset_size = offsetsize;
|
||||
shead.rh_address_size = rctx->rc_address_size;
|
||||
shead.rh_segment_selector_size =
|
||||
rctx->rc_segment_selector_size;
|
||||
|
||||
/* DW_AT_rnglists_base from CU */
|
||||
shead.rh_at_rnglists_base_present =
|
||||
ctx->cc_rnglists_base_present;
|
||||
shead.rh_at_rnglists_base = ctx->cc_rnglists_base;
|
||||
|
||||
/* DW_AT_low_pc, if present. From CU */
|
||||
shead.rh_cu_base_address_present = ctx->cc_low_pc_present;
|
||||
shead.rh_cu_base_address = ctx->cc_low_pc;
|
||||
|
||||
/* base address DW_AT_addr_base of our part of
|
||||
.debug_addr, from CU */
|
||||
shead.rh_cu_addr_base = ctx->cc_addr_base;
|
||||
shead.rh_cu_addr_base_present = ctx->cc_addr_base_present;
|
||||
if (is_rnglistx) {
|
||||
Dwarf_Unsigned table_entryval = 0;
|
||||
|
||||
table_entry = attr_val*offsetsize + table_base;
|
||||
/* No malloc here yet so no leak if the macro returns
|
||||
DW_DLV_ERROR */
|
||||
READ_UNALIGNED_CK(dbg,table_entryval, Dwarf_Unsigned,
|
||||
table_entry,offsetsize,error,enddata);
|
||||
rle_global_offset = rctx->rc_offsets_off_in_sect +
|
||||
table_entryval;
|
||||
/* attr_val is .debug_rnglists section global offset
|
||||
of a range list*/
|
||||
if (!dbg->de_debug_rnglists.dss_size ||
|
||||
attr_val >= dbg->de_debug_rnglists.dss_size) {
|
||||
if (DBG_HAS_SECONDARY(dbg)) {
|
||||
dbg = dbg->de_secondary_dbg;
|
||||
CHECK_DBG(dbg,error,
|
||||
"dwarf_rnglists_get_rle_head() "
|
||||
"via attribute(secb)");
|
||||
} else {
|
||||
rle_global_offset = attr_val;
|
||||
/* There is an error to be
|
||||
generated later */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shead.rh_end_data_area = enddata;
|
||||
shead.rh_rlearea_offset = rle_global_offset;
|
||||
shead.rh_rlepointer = rle_global_offset +
|
||||
dbg->de_debug_rnglists.dss_data;
|
||||
lhead = (Dwarf_Rnglists_Head)
|
||||
_dwarf_get_alloc(dbg,DW_DLA_RNGLISTS_HEAD,1);
|
||||
if (!lhead) {
|
||||
_dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL,
|
||||
"Allocating a Dwarf_Rnglists_Head struct fails"
|
||||
" in libdwarf function "
|
||||
"dwarf_rnglists_index_get_rle_head()");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
shead.rh_dbg = dbg;
|
||||
*lhead = shead;
|
||||
res = build_array_of_rle(dbg,lhead,error);
|
||||
if (res != DW_DLV_OK) {
|
||||
dwarf_dealloc(dbg,lhead,DW_DLA_RNGLISTS_HEAD);
|
||||
res = _dwarf_load_section(dbg,
|
||||
&dbg->de_debug_rnglists,
|
||||
error);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
return res;
|
||||
}
|
||||
if (global_offset_of_rle_set) {
|
||||
*global_offset_of_rle_set = rle_global_offset;
|
||||
if (res == DW_DLV_OK && dbg->de_debug_rnglists.dss_size) {
|
||||
res = _dwarf_fill_in_rle_head(dbg, theform,
|
||||
/* attr_val is either an offset
|
||||
(theform == DW_FORM_sec_offset)
|
||||
to a specific rangelist entry set or
|
||||
or a rnglistx index DW_FORM_rnglistx
|
||||
at that index is the local offset of
|
||||
a specific rangelist entry set offset table. */
|
||||
attr_val,
|
||||
ctx,
|
||||
head_out,
|
||||
entries_count_out,
|
||||
global_offset_of_rle_set,
|
||||
error);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
return res;
|
||||
}
|
||||
/* Caller needs the head pointer else there will be leaks. */
|
||||
*head_out = lhead;
|
||||
if (entries_count_out) {
|
||||
*entries_count_out = lhead->rh_count;
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* As of 18 Aug 2020
|
||||
|
6
src/lib/libdwarf/dwarf_rnglists.h
vendored
6
src/lib/libdwarf/dwarf_rnglists.h
vendored
@ -112,7 +112,7 @@ struct Dwarf_Rnglists_Entry_s {
|
||||
Dwarf_Unsigned rle_raw1;
|
||||
Dwarf_Unsigned rle_raw2;
|
||||
/* 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_cooked2;
|
||||
Dwarf_Rnglists_Entry rle_next;
|
||||
@ -148,8 +148,8 @@ struct Dwarf_Rnglists_Head_s {
|
||||
|
||||
/* DW_AT_addr_base, so we can use .debug_addr
|
||||
if such is needed. */
|
||||
Dwarf_Bool rh_cu_addr_base_present;
|
||||
Dwarf_Unsigned rh_cu_addr_base;
|
||||
Dwarf_Bool rh_cu_addr_base_offset_present;
|
||||
Dwarf_Unsigned rh_cu_addr_base_offset;
|
||||
Dwarf_Small * rh_rlepointer;
|
||||
Dwarf_Unsigned rh_rlearea_offset;
|
||||
Dwarf_Small * rh_end_data_area;
|
||||
|
24
src/lib/libdwarf/dwarf_setup_sections.c
vendored
24
src/lib/libdwarf/dwarf_setup_sections.c
vendored
@ -105,6 +105,25 @@ add_debug_section_info(Dwarf_Debug dbg,
|
||||
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.
|
||||
PRECONDITION: secname and targname are non-null
|
||||
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
|
||||
a false positive. We had to drop stringop-overread
|
||||
references in compiler options, such turned off
|
||||
valuable warnings. */
|
||||
if (postzprefix &&
|
||||
valuable warnings. Oct 2024
|
||||
refined the test to notice empty string */
|
||||
if (both_strings_nonempty(postzprefix,targname,DPREFIXLEN) &&
|
||||
!strcmp(postzprefix,targname+DPREFIXLEN)) {
|
||||
/* zprefix version matches the object section
|
||||
name so the section is compressed and is
|
||||
|
19
src/lib/libdwarf/dwarf_tied.c
vendored
19
src/lib/libdwarf/dwarf_tied.c
vendored
@ -49,7 +49,7 @@
|
||||
#include "dwarf_tsearch.h"
|
||||
#include "dwarf_tied_decls.h"
|
||||
|
||||
#if 0 /*debug dumpsignature */
|
||||
#ifdef DEBUG_PRIMARY_DBG /*debug dumpsignature */
|
||||
void
|
||||
_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
|
||||
'normal' to 'dwo/dwp' (DWARF4) */
|
||||
int is_info = TRUE;
|
||||
Dwarf_CU_Context startingcontext = 0;
|
||||
Dwarf_Unsigned next_cu_offset = 0;
|
||||
|
||||
startingcontext = tieddbg->de_info_reading.de_cu_context;
|
||||
|
||||
if (startingcontext) {
|
||||
next_cu_offset =
|
||||
startingcontext->cc_debug_offset +
|
||||
startingcontext->cc_length +
|
||||
startingcontext->cc_length_size +
|
||||
startingcontext->cc_extension_size;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int sres = DW_DLV_OK;
|
||||
Dwarf_Half cu_type = 0;
|
||||
@ -177,6 +166,9 @@ _dwarf_loop_reading_debug_info_for_cu(
|
||||
&typeoffset,
|
||||
&next_cu_offset,
|
||||
&cu_type, error);
|
||||
if (sres == DW_DLV_ERROR) {
|
||||
return sres;
|
||||
}
|
||||
if (sres == DW_DLV_NO_ENTRY) {
|
||||
break;
|
||||
}
|
||||
@ -231,6 +223,9 @@ _dwarf_loop_reading_debug_info_for_cu(
|
||||
}
|
||||
|
||||
/* 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
|
||||
_dwarf_search_for_signature(Dwarf_Debug tieddbg,
|
||||
|
6
src/lib/libdwarf/dwarf_tsearchhash.c
vendored
6
src/lib/libdwarf/dwarf_tsearchhash.c
vendored
@ -223,7 +223,8 @@ printf("debugging: initial alloc prime to use %lu\n",prime_to_use);
|
||||
/* hashtab_ is an array of hs_entry,
|
||||
indexes 0 through tablesize_ -1. */
|
||||
base->hashfunc_ = hashfunc;
|
||||
base->hashtab_ = calloc(base->tablesize_, sizeof(struct ts_entry));
|
||||
base->hashtab_ = calloc(base->tablesize_,
|
||||
sizeof(struct ts_entry));
|
||||
if (!base->hashtab_) {
|
||||
free(base);
|
||||
return NULL;
|
||||
@ -368,7 +369,8 @@ resize_table(struct hs_base *head,
|
||||
return;
|
||||
}
|
||||
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_) {
|
||||
/* Oops, too large. Leave table size as is, though
|
||||
things will get slow as it overfills. */
|
||||
|
210
src/lib/libdwarf/dwarf_util.c
vendored
210
src/lib/libdwarf/dwarf_util.c
vendored
@ -70,6 +70,164 @@ dwarf_package_version(void)
|
||||
{
|
||||
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 */
|
||||
static void
|
||||
@ -125,7 +283,8 @@ static void dump_hash_table(char *msg,
|
||||
tab->tb_highest_used_entry);
|
||||
|
||||
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__);
|
||||
}
|
||||
printf(" ---end hash tab---\n");
|
||||
@ -1191,7 +1350,7 @@ _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
|
||||
return res;
|
||||
}
|
||||
/* 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. */
|
||||
res = dwarf_load_rnglists(dbg,0,error);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
@ -1363,53 +1522,6 @@ _dwarf_printf(Dwarf_Debug dbg,
|
||||
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
|
||||
inthissection(struct Dwarf_Section_s *sec,Dwarf_Small *ptr)
|
||||
{
|
||||
|
2
src/lib/libdwarf/dwarf_util.h
vendored
2
src/lib/libdwarf/dwarf_util.h
vendored
@ -487,8 +487,6 @@ int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die);
|
||||
int _dwarf_reference_outside_section(Dwarf_Die die,
|
||||
Dwarf_Small * startaddr,
|
||||
Dwarf_Small * pastend);
|
||||
void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs,
|
||||
Dwarf_Debug dbgt,Dwarf_Error *errt);
|
||||
|
||||
int _dwarf_internal_get_die_comp_dir(Dwarf_Die die,
|
||||
const char **compdir_out,
|
||||
|
43
src/lib/libdwarf/libdwarf.h
vendored
43
src/lib/libdwarf/libdwarf.h
vendored
@ -1,7 +1,7 @@
|
||||
/*
|
||||
Copyright (C) 2000-2010 Silicon Graphics, 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 2010-2012 SN Systems Ltd. All rights reserved.
|
||||
|
||||
@ -99,10 +99,10 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/* 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_MINOR 11
|
||||
#define DW_LIBDWARF_VERSION_MICRO 0
|
||||
#define DW_LIBDWARF_VERSION_MICRO 1
|
||||
|
||||
#define DW_PATHSOURCE_unspecified 0
|
||||
#define DW_PATHSOURCE_basic 1
|
||||
@ -338,8 +338,8 @@ typedef struct Dwarf_Block_s {
|
||||
Provides access to Dwarf_Locdesc_c, a single
|
||||
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
|
||||
provides access to any sort of location description
|
||||
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_UNIV_BIN_OFFSET_SIZE_ERROR 503
|
||||
#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 */
|
||||
#define DW_DLE_LAST 504
|
||||
#define DW_DLE_LAST 506
|
||||
#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.
|
||||
|
||||
Given a base Dwarf_Debug this returns
|
||||
the tied Dwarf_Debug.
|
||||
Given a main Dwarf_Debug this returns
|
||||
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
|
||||
you had the tied and base dbg when calling
|
||||
callers had the tied and base dbg when calling
|
||||
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,
|
||||
Dwarf_Debug * dw_tieddbg_out,
|
||||
|
Loading…
x
Reference in New Issue
Block a user