Bump to libdwarf 0.8.0

This commit is contained in:
Jeremy 2023-09-18 19:25:48 -04:00
parent 5fc39fbcea
commit 43a50c734c
No known key found for this signature in database
GPG Key ID: 19AA8270105E8EB4
17 changed files with 315 additions and 89 deletions

View File

@ -65,6 +65,9 @@ calls
#elif defined HAVE_UNISTD_H
#include <unistd.h> /* close() */
#endif /* _WIN32 */
#ifdef HAVE_FCNTL_H
#include <fcntl.h> /* open() O_RDONLY */
#endif /* HAVE_FCNTL_H */
#include "dwarf.h"
#include "libdwarf.h"
@ -84,6 +87,9 @@ calls
#ifndef O_BINARY
#define O_BINARY 0
#endif /* O_BINARY */
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif /* O_CLOEXEC */
#if 0
/* One example of calling this.
@ -181,7 +187,7 @@ dwarf_construct_elf_access_path(const char *path,
int res = 0;
dwarf_elf_object_access_internals_t *mymp = 0;
fd = open(path, O_RDONLY|O_BINARY);
fd = open(path, O_RDONLY|O_BINARY|O_CLOEXEC);
if (fd < 0) {
*errcode = DW_DLE_PATH_SIZE_TOO_SMALL;
return DW_DLV_ERROR;

View File

@ -1246,6 +1246,13 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
dfi->fi_expr.bl_len = block_len;
dfi->fi_expr.bl_data = instr_ptr;
}
if (block_len >= instr_area_length) {
SERSTRING(DW_DLE_DF_FRAME_DECODING_ERROR,
"DW_DLE_DF_FRAME_DECODING_ERROR: "
"DW_CFA_def_cfa_expression "
"block len overflows instructions "
"available range.");
}
instr_ptr += block_len;
if (instr_area_length < block_len ||
instr_ptr < base_instr_ptr) {
@ -2127,14 +2134,21 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
}
fde_ptr = prefix.cf_addr_after_prefix;
cie_id = prefix.cf_cie_id;
if (cie_id >= dbg->de_debug_frame.dss_size ) {
_dwarf_error_string(dbg, error, DW_DLE_NO_CIE_FOR_FDE,
"DW_DLE_NO_CIE_FOR_FDE: "
"dwarf_get_fde_for_die fails as the CIE id "
"offset is impossibly large");
return DW_DLV_ERROR;
}
/* Pass NULL, not section pointer, for 3rd argument.
de_debug_frame.dss_data has no eh_frame relevance. */
res = _dwarf_create_fde_from_after_start(dbg, &prefix,
fde_start_ptr,
dbg->de_debug_frame.dss_size,
fde_ptr,
fde_end_ptr,
/* use_gnu_cie_calc= */ 0,
/* Dwarf_Cie = */ 0,
address_size,
&new_fde, error);
@ -2151,7 +2165,25 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
/* Now read the cie corresponding to the fde,
_dwarf_read_cie_fde_prefix checks
cie_ptr for being within the section. */
if (cie_id >= dbg->de_debug_frame.dss_size ) {
_dwarf_error_string(dbg, error, DW_DLE_NO_CIE_FOR_FDE,
"DW_DLE_NO_CIE_FOR_FDE: "
"dwarf_get_fde_for_die fails as the CIE id "
"offset is impossibly large");
return DW_DLV_ERROR;
}
cie_ptr = new_fde->fd_section_ptr + cie_id;
if ((Dwarf_Unsigned)cie_ptr <
(Dwarf_Unsigned) new_fde->fd_section_ptr ||
(Dwarf_Unsigned)cie_ptr < cie_id) {
dwarf_dealloc(dbg,new_fde,DW_DLA_FDE);
new_fde = 0;
_dwarf_error_string(dbg, error, DW_DLE_NO_CIE_FOR_FDE,
"DW_DLE_NO_CIE_FOR_FDE: "
"dwarf_get_fde_for_die fails as the CIE id "
"offset is impossibly large");
return DW_DLV_ERROR;
}
res = _dwarf_read_cie_fde_prefix(dbg, cie_ptr,
dbg->de_debug_frame.dss_data,
dbg->de_debug_frame.dss_index,
@ -2193,7 +2225,9 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
} else {
dwarf_dealloc(dbg,new_fde,DW_DLA_FDE);
new_fde = 0;
_dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
_dwarf_error_string(dbg, error, DW_DLE_NO_CIE_FOR_FDE,
"DW_DLE_NO_CIE_FOR_FDE: "
"The CIE id is not a true cid id. Corrupt DWARF.");
return DW_DLV_ERROR;
}
*ret_fde = new_fde;
@ -2551,8 +2585,7 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
return DW_DLV_OK;
}
/* In this interface, table_column of DW_FRAME_CFA_COL
is not meaningful.
/* Table_column DW_FRAME_CFA_COL is not meaningful.
Use dwarf_get_fde_info_for_cfa_reg3_b() to get the CFA.
Call dwarf_set_frame_cfa_value() to set the correct column
after calling dwarf_init()
@ -2571,15 +2604,49 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
if the pointer is null).
Otherwise *has_more_rows and *subsequent_pc
are not set.
The offset returned is Unsigned, which was
always wrong. Cast to Dwarf_Signed to use it.
*/
int
dwarf_get_fde_info_for_reg3_b(Dwarf_Fde fde,
Dwarf_Half table_column,
Dwarf_Addr requested,
Dwarf_Small *value_type,
Dwarf_Unsigned *offset_relevant,
Dwarf_Unsigned *register_num,
Dwarf_Unsigned *offset,
Dwarf_Block *block,
Dwarf_Addr *row_pc_out,
Dwarf_Bool *has_more_rows,
Dwarf_Addr *subsequent_pc,
Dwarf_Error *error)
{
Dwarf_Signed soff = 0;
int res = 0;
res = dwarf_get_fde_info_for_reg3_c(
fde,table_column,requested,
value_type,offset_relevant,
register_num,&soff,
block,row_pc_out,has_more_rows,
subsequent_pc,error);
if (offset) {
*offset = (Dwarf_Unsigned)soff;
}
return res;
}
/* New September 2023.
The same as dwarf_get_fde_info_for_reg3_b() but here
*/
int
dwarf_get_fde_info_for_reg3_c(Dwarf_Fde fde,
Dwarf_Half table_column,
Dwarf_Addr pc_requested,
Dwarf_Small *value_type,
Dwarf_Unsigned *offset_relevant,
Dwarf_Unsigned *register_num,
Dwarf_Unsigned *offset,
Dwarf_Signed *offset,
Dwarf_Block *block,
Dwarf_Addr *row_pc_out,
Dwarf_Bool *has_more_rows,
@ -2676,6 +2743,37 @@ dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde fde,
Dwarf_Bool *has_more_rows,
Dwarf_Addr *subsequent_pc,
Dwarf_Error *error)
{
Dwarf_Signed soff = 0;
int res = 0;
res = dwarf_get_fde_info_for_cfa_reg3_c(fde,
pc_requested, value_type,offset_relevant,
register_num,&soff,block, row_pc_out,
has_more_rows,subsequent_pc,error);
if (offset) {
*offset = (Dwarf_Unsigned)soff;
}
return res;
}
/*
New September 2023. With the offset argument
a signed value. This is more correct, so
convert from dwarf_get_fde_info_for_cfa_reg3_b
when convenient.
*/
int
dwarf_get_fde_info_for_cfa_reg3_c(Dwarf_Fde fde,
Dwarf_Addr pc_requested,
Dwarf_Small *value_type,
Dwarf_Unsigned *offset_relevant,
Dwarf_Unsigned *register_num,
Dwarf_Signed *offset,
Dwarf_Block *block,
Dwarf_Addr *row_pc_out,
Dwarf_Bool *has_more_rows,
Dwarf_Addr *subsequent_pc,
Dwarf_Error *error)
{
struct Dwarf_Frame_s fde_table;
int res = DW_DLV_ERROR;

View File

@ -196,8 +196,6 @@ typedef struct Dwarf_Regtable3_s_i {
Dwarf_Regtable_Entry3_i *rt3_rules;
} Dwarf_Regtable3_i;
typedef struct Dwarf_Frame_s *Dwarf_Frame;
/*
@ -486,6 +484,7 @@ int _dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
int _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
struct cie_fde_prefix_s * prefix,
Dwarf_Small *section_pointer,
Dwarf_Unsigned section_length,
Dwarf_Small *frame_ptr,
Dwarf_Small *section_ptr_end,
int use_gnu_cie_calc,

View File

@ -301,25 +301,41 @@ print_prefix(struct cie_fde_prefix_s *prefix, int line)
ambiguous, but this calculation is correct.
*/
static Dwarf_Small *
get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
static int
get_cieptr_given_offset(Dwarf_Debug dbg,
Dwarf_Unsigned cie_id_value,
int use_gnu_cie_calc,
Dwarf_Small * section_ptr,
Dwarf_Small * cie_id_addr)
Dwarf_Unsigned section_length,
Dwarf_Small * cie_id_addr,
Dwarf_Small ** ret_cieptr,
Dwarf_Error *error)
{
Dwarf_Small *cieptr = 0;
if (cie_id_value >= section_length) {
_dwarf_error_string(dbg, error,
DW_DLE_DEBUG_FRAME_LENGTH_BAD,
"DW_DLE_DEBUG_FRAME_LENGTH_BAD: in eh_frame "
" cie_id value makes no sense. Corrupt DWARF");
return DW_DLV_ERROR;
}
if (use_gnu_cie_calc) {
/* cie_id value is offset, in section, of the
cie_id itself, to
use vm ptr of the value,
less the value, to get to the cie header. */
cieptr = cie_id_addr - cie_id_value;
if ((Dwarf_Unsigned)cie_id_addr <= cie_id_value) {
_dwarf_error_string(dbg, error,
DW_DLE_DEBUG_FRAME_LENGTH_BAD,
"DW_DLE_DEBUG_FRAME_LENGTH_BAD: in eh_frame "
" cie_id makes no sense. Corrupt DWARF");
return DW_DLV_ERROR;
}
*ret_cieptr = cie_id_addr - cie_id_value;
} else {
/* Traditional dwarf section offset is in cie_id */
cieptr = section_ptr + cie_id_value;
*ret_cieptr = section_ptr + cie_id_value;
}
return cieptr;
return DW_DLV_OK;
}
/* Internal function called from various places to create
@ -410,7 +426,9 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
if (frame_ptr >= section_ptr_end) {
_dwarf_dealloc_fde_cie_list_internal(head_fde_ptr,
head_cie_ptr);
#if 0
_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
#endif
_dwarf_error_string(dbg, error,
DW_DLE_DEBUG_FRAME_LENGTH_BAD,
"DW_DLE_DEBUG_FRAME_LENGTH_BAD: following "
@ -473,10 +491,15 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
Dwarf_Fde fde_ptr_to_use = 0;
Dwarf_Small *cieptr_val = 0;
cieptr_val = get_cieptr_given_offset(prefix.cf_cie_id,
resf = get_cieptr_given_offset(dbg,
prefix.cf_cie_id,
use_gnu_cie_calc,
section_ptr,
prefix.cf_cie_id_addr);
section_length,
prefix.cf_cie_id_addr,&cieptr_val,error);
if (resf != DW_DLV_OK) {
return resf;
}
resf = _dwarf_find_existing_cie_ptr(cieptr_val,
cur_cie_ptr,
&cie_ptr_to_use,
@ -516,6 +539,7 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
resf = _dwarf_create_fde_from_after_start(dbg,
&prefix,
section_ptr,
section_length,
frame_ptr,
section_ptr_end,
use_gnu_cie_calc,
@ -1057,6 +1081,7 @@ int
_dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
struct cie_fde_prefix_s *prefix,
Dwarf_Small *section_pointer,
Dwarf_Unsigned section_length,
Dwarf_Small *frame_ptr,
Dwarf_Small *section_ptr_end,
int use_gnu_cie_calc,
@ -1133,6 +1158,42 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
dbg,error,section_ptr_end);
fde_aug_data_len = adlen;
fde_aug_data = frame_ptr;
if (frame_ptr < section_ptr_end) {
Dwarf_Unsigned remaininglen = 0;
remaininglen = (Dwarf_Unsigned)
(section_ptr_end - frame_ptr);
if (remaininglen <= adlen) {
_dwarf_error_string(dbg, error,
DW_DLE_AUG_DATA_LENGTH_BAD,
"DW_DLE_AUG_DATA_LENGTH_BAD: The "
"augmentation length is too large for "
"the frame section, corrupt DWARF");
return DW_DLV_ERROR;
}
} else {
_dwarf_error_string(dbg, error,
DW_DLE_AUG_DATA_LENGTH_BAD,
"DW_DLE_AUG_DATA_LENGTH_BAD: The "
"frame pointer has stepped off the end "
"of the frame section on reading augmentation "
"length. Corrupt DWARF");
return DW_DLV_ERROR;
}
if ( adlen >= section_length) {
dwarfstring m;
dwarfstring_constructor(&m);
dwarfstring_append_printf_u(&m,
"DW_DLE_AUG_DATA_LENGTH_BAD: The "
"gcc .eh_frame augmentation data "
"length of %" DW_PR_DUu " is too long to"
" fit in the section.",adlen);
_dwarf_error_string(dbg, error,
DW_DLE_AUG_DATA_LENGTH_BAD,
dwarfstring_string(&m));
dwarfstring_destructor(&m);
return DW_DLV_ERROR;
}
frame_ptr += adlen;
if (adlen) {
if (frame_ptr < fde_aug_data ||
@ -1265,7 +1326,8 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
_dwarf_error_string(dbg, error,
DW_DLE_DF_FRAME_DECODING_ERROR,
"DW_DLE_DF_FRAME_DECODING_ERROR "
"frame pointer decreased.Impossible. arithmetic overflow");
"frame pointer decreased.Impossible. "
"arithmetic overflow");
return DW_DLV_ERROR;
}

View File

@ -93,6 +93,9 @@ dwarf_init_path_dl(path true_path and globals, dbg1
#ifndef O_BINARY
#define O_BINARY 0
#endif /* O_BINARY */
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif /* O_CLOEXEC */
/* This is the initialization set intended to
handle multiple object formats.
@ -107,7 +110,7 @@ open_a_file(const char * name)
/* Set to a file number that cannot be legal. */
int fd = -1;
fd = open(name, O_RDONLY | O_BINARY);
fd = open(name, O_RDONLY | O_BINARY|O_CLOEXEC);
return fd;
}

View File

@ -234,8 +234,6 @@ _dwarf_dirno_string(Dwarf_Line_Context line_context,
return;
}
/* With this routine we ensure the file full path
is calculated identically for
dwarf_srcfiles() and _dwarf_filename()

View File

@ -1014,10 +1014,9 @@ build_array_of_lle(Dwarf_Debug dbg,
unsigned int address_size = rctx->ll_address_size;
Dwarf_Unsigned bytescounttotal= 0;
int done = FALSE;
Dwarf_Unsigned locdesc_index = 0;
Dwarf_Unsigned i = 0;
for ( ; !done ;++locdesc_index ) {
for ( ; !done ; ) {
unsigned entrylen = 0;
unsigned code = 0;
Dwarf_Unsigned val1 = 0;

View File

@ -945,7 +945,17 @@ _dwarf_macho_object_access_internals_init(
_dwarf_destruct_macho_access(localdoas);
return res;
}
if (intfc->mo_dwarf_sections) {
sp = intfc->mo_dwarf_sections+1;
} else {
/* There are no dwarf sections,
count better be zero. */
if (intfc->mo_dwarf_sectioncount) {
_dwarf_destruct_macho_access(localdoas);
*errcode = DW_DLE_MACHO_CORRUPT_HEADER;
return DW_DLV_ERROR;
}
}
for (i = 1; i < intfc->mo_dwarf_sectioncount ; ++i,++sp) {
int j = 1;
int lim = sizeof(SectionNames)/sizeof(SectionNames[0]);

View File

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

View File

@ -65,6 +65,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif /* O_CLOEXEC */
/* TYP, SIZEOFT32 and ASNAR
mean we can use correctly-sized arrays of char for the
@ -572,7 +575,7 @@ dwarf_object_detector_path_dSYM(
*errcode = DW_DLE_PATH_SIZE_TOO_SMALL;
return DW_DLV_ERROR;
}
fd = open(outpath,O_RDONLY|O_BINARY);
fd = open(outpath,O_RDONLY|O_BINARY|O_CLOEXEC);
if (fd < 0) {
outpath[0] = 0;
return DW_DLV_NO_ENTRY;
@ -826,7 +829,7 @@ _dwarf_debuglink_finder_internal(
/* First, open the file to determine if it exists.
If not, loop again */
pfd = open(pa,O_RDONLY|O_BINARY);
pfd = open(pa,O_RDONLY|O_BINARY| O_CLOEXEC);
if (pfd < 0) {
/* This is the usual path. */
continue;
@ -921,11 +924,11 @@ dwarf_object_detector_path_b(
lpathsource = DW_PATHSOURCE_debuglink;
}
dwarfstring_destructor(&m);
fd = open(outpath,O_RDONLY|O_BINARY);
fd = open(outpath,O_RDONLY|O_BINARY|O_CLOEXEC);
/* fall through to get fsize etc */
} else {
lpathsource = DW_PATHSOURCE_basic;
fd = open(path,O_RDONLY|O_BINARY);
fd = open(path,O_RDONLY|O_BINARY|O_CLOEXEC);
}
if (fd < 0) {
if (pathsource) {

View File

@ -76,7 +76,6 @@ extern "C" {
*errcode when the function returns DW_DLV_ERROR)
will hopefully suffice for most purposes. */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -1412,10 +1412,7 @@ dwarf_rnglists_get_rle_head(
rle_global_offset = attr_val;
}
shead.rh_rlepointer = rctx->rc_offsets_array +
rctx->rc_offset_entry_count*offsetsize;
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;

View File

@ -29,7 +29,6 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Thanks to David Grayson/
codereview.stackexchange.com/questions/98791/
safe-multiplication-of-two-64-bit-signed-integers
@ -45,7 +44,8 @@ int _dwarf_uint64_mult(Dwarf_Unsigned x, Dwarf_Unsigned y,
#if 0
/* See:
https://stackoverflow.com/questions/3944505/detecting-signed-overflow-in-c-c
https://stackoverflow.com/questions/
3944505/detecting-signed-overflow-in-c-c
*/
int _dwarf_signed_add_check(Dwarf_Signed l, Dwarf_Signed r,
Dwarf_Signed *sum, Dwarf_Debug dbg,

View File

@ -131,7 +131,6 @@ _dwarf_loop_reading_debug_info_for_cu(
Dwarf_Debug tieddbg,
Dwarf_Error *error)
{
unsigned loop_count = 0;
/* We will not find tied signatures
for .debug_addr (or line tables) in .debug_types.
it seems. Those signatures point from
@ -150,7 +149,7 @@ _dwarf_loop_reading_debug_info_for_cu(
startingcontext->cc_extension_size;
}
for (;;++loop_count) {
for (;;) {
int sres = DW_DLV_OK;
Dwarf_Half cu_type = 0;
Dwarf_CU_Context latestcontext = 0;

View File

@ -1244,7 +1244,9 @@ _dwarf_free_abbrev_hash_table_contents(Dwarf_Hash_Table hash_table,
Dwarf_Abbrev_List nextabbrev = 0;
Dwarf_Abbrev_List abbrev =
hash_table->tb_entries[hashnum];
#ifdef TESTINGHASHTAB
unsigned listcount = 0;
#endif
if (!abbrev) {
continue;
@ -1266,7 +1268,9 @@ _dwarf_free_abbrev_hash_table_contents(Dwarf_Hash_Table hash_table,
/* dealloc single list entry */
free(abbrev);
abbrev = 0;
#ifdef TESTINGHASHTAB
++listcount;
#endif
}
#ifdef TESTINGHASHTAB
printf("debugging: hashnum %lu listcount %u\n",hashnum,listcount);

View File

@ -99,10 +99,10 @@ extern "C" {
*/
/* Semantic Version identity for this libdwarf.h */
#define DW_LIBDWARF_VERSION "0.7.1"
#define DW_LIBDWARF_VERSION "0.8.0"
#define DW_LIBDWARF_VERSION_MAJOR 0
#define DW_LIBDWARF_VERSION_MINOR 7
#define DW_LIBDWARF_VERSION_MICRO 1
#define DW_LIBDWARF_VERSION_MINOR 8
#define DW_LIBDWARF_VERSION_MICRO 0
#define DW_PATHSOURCE_unspecified 0
#define DW_PATHSOURCE_basic 1
@ -458,11 +458,11 @@ typedef struct Dwarf_Ranges_s {
possible case for dwarf2):
If dw_offset_relevant is non-zero, then
the value is stored at at the address
CFA+N where N is a signed offset.
CFA+N where N (dw_offset) is a signed offset,
(not unsigned) and must be cast to Dwarf_Signed
before use.
dw_regnum is the cfa register rule which means
one ignores dw_regnum and uses the CFA appropriately.
So dw_offset is a signed value, really,
and must be printed/evaluated as such.
Rule: Offset(N)
If dw_offset_relevant is zero, then the
value of the register
@ -470,7 +470,8 @@ typedef struct Dwarf_Ranges_s {
Rule: register(R)
If dw_value_type == DW_EXPR_VAL_OFFSET
the value of this register is CFA +N where
N is a signed offset.
N (dw_offset) is a signed offset (not unsigned)
and must be cast to Dwarf_Signed before use.
dw_regnum is the cfa register rule which means
one ignores dw_regnum and uses the CFA appropriately.
Rule: val_offset(N)
@ -494,15 +495,16 @@ typedef struct Dwarf_Ranges_s {
Note that this definition can only deal correctly
with register numbers that fit in a 16 bit
unsigned value. And it is difficult to alter
unsigned value. Changing this would be an incompatible
change to several functions in the libdwarf API.
*/
typedef struct Dwarf_Regtable_Entry3_s {
Dwarf_Small dw_offset_relevant;
Dwarf_Small dw_value_type;
Dwarf_Half dw_regnum;
Dwarf_Unsigned dw_offset;
Dwarf_Unsigned dw_args_size; /* Not dealt with. */
Dwarf_Unsigned dw_offset; /* Should be Dwarf_Signed */
Dwarf_Unsigned dw_args_size; /* Always zero. */
Dwarf_Block dw_block;
} Dwarf_Regtable_Entry3;
@ -2583,7 +2585,7 @@ DW_API int dwarf_attrlist(Dwarf_Die dw_die,
Dwarf_Signed * dw_attrcount,
Dwarf_Error* dw_error);
/*! @brief Sets TRUE of a Dwarf_Attribute has the indicated FORM
/*! @brief Sets TRUE if a Dwarf_Attribute has the indicated FORM
@param dw_attr
The Dwarf_Attribute of interest.
@param dw_form
@ -5301,7 +5303,7 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde,
/*! @brief Return details about a particular pc and register.
It is inefficient to iterate across all table_columns (registers)
using this function (dwarf_get_fde_info_for_reg3_b()).
using this function (dwarf_get_fde_info_for_reg3_c()).
Instead call dwarf_get_fde_info_for_all_regs3()
and index into the table it fills in.
@ -5312,6 +5314,11 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde,
on runtime frame data which cannot be calculated
without a stack frame including registers (etc).
dwarf_get_fde_info_for_reg3_c() is new in Septmber 2023
to correct the incorrect type of the dw_offset
argument in dwarf_get_fde_info_for_reg3_b().
Both versions operate correctly.
@param dw_fde
Pass in the FDE of interest.
@param dw_table_column
@ -5328,11 +5335,8 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde,
@param dw_register
On success returns a register number.
@param dw_offset
On success returns a register offset value.
In principle these are signed, but historically
in libdwarf it is typed unsigned.
Cast the returned value to Dwarf_Signed to
get the correct meaning.
On success returns a signed register offset value when
dw_value_tyoe is DW_EXPR_OFFSET or DW_EXPER_VAL_OFFSET.
@param dw_block_content
On success returns a pointer to a block.
For example, for DW_EXPR_EXPRESSION the block
@ -5355,6 +5359,28 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde,
FDE passed in and there is a row for the pc
in the table.
*/
DW_API int dwarf_get_fde_info_for_reg3_c(Dwarf_Fde dw_fde,
Dwarf_Half dw_table_column,
Dwarf_Addr dw_pc_requested,
Dwarf_Small * dw_value_type,
Dwarf_Unsigned * dw_offset_relevant,
Dwarf_Unsigned * dw_register,
Dwarf_Signed * dw_offset,
Dwarf_Block * dw_block_content,
Dwarf_Addr * dw_row_pc_out,
Dwarf_Bool * dw_has_more_rows,
Dwarf_Addr * dw_subsequent_pc,
Dwarf_Error * dw_error);
/*! @brief Return details about a particular pc and register.
Identical to dwarf_get_fde_info_for_reg3_c() except that
this returns dw_offset as a Dwarf_Unsigned, which
was never appropriate, and required you to
cast that value to Dwarf_Signed to use it properly..
Please switch to using dwarf_get_fde_info_for_reg3_c()
*/
DW_API int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde dw_fde,
Dwarf_Half dw_table_column,
Dwarf_Addr dw_pc_requested,
@ -5370,23 +5396,46 @@ DW_API int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde dw_fde,
/*! @brief Get the value of the CFA for a particular pc value
@see dwarf_get_fde_info_for_reg3_b
This has essentially the same return values but
@see dwarf_get_fde_info_for_reg3_c
has essentially the same return values as
dwarf_get_fde_info_for_reg3_c but
it refers to the CFA (which is not part of the register
table)
In principle the value returned throuth
dw_offset is signed, but historically
in libdwarf it is typed unsigned.
Cast the returned dw_offset value to Dwarf_Signed to
get the correct meaning.
table) so function has no table column argument.
New in September 2023, release 0.8.0.
dwarf_get_fde_info_for_cfa_reg3_c() returns dw_offset
as a signed type.
dwarf_get_fde_info_for_cfa_reg3_b() returns dw_offset
as an unsigned type, requiring the caller to cast
to Dwarf_Signed before using the value.
Both versions exist and operate properly.
If dw_value_type == DW_EXPR_EXPRESSION or
DW_EXPR_VALUE_EXPRESSION dw_offset
is not set and the caller must
evaluate the expression, which usually depends
on runtime frame data which cannot be calculated
without a stack frame including registers (etc).
without a stack frame including register values (etc).
*/
DW_API int dwarf_get_fde_info_for_cfa_reg3_c(Dwarf_Fde dw_fde,
Dwarf_Addr dw_pc_requested,
Dwarf_Small * dw_value_type,
Dwarf_Unsigned* dw_offset_relevant,
Dwarf_Unsigned* dw_register,
Dwarf_Signed * dw_offset,
Dwarf_Block * dw_block,
Dwarf_Addr * dw_row_pc_out,
Dwarf_Bool * dw_has_more_rows,
Dwarf_Addr * dw_subsequent_pc,
Dwarf_Error * dw_error);
/*! @brief Get the value of the CFA for a particular pc value(obsolete)
@see dwarf_get_fde_info_for_cfa_reg3_c
This is the earlier version that returns a dw_offset
of Dwarf_Unsigned, requiring you to cast to Dwarf_Signed
to work with the value.
*/
DW_API int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde dw_fde,
Dwarf_Addr dw_pc_requested,