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 #elif defined HAVE_UNISTD_H
#include <unistd.h> /* close() */ #include <unistd.h> /* close() */
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifdef HAVE_FCNTL_H
#include <fcntl.h> /* open() O_RDONLY */
#endif /* HAVE_FCNTL_H */
#include "dwarf.h" #include "dwarf.h"
#include "libdwarf.h" #include "libdwarf.h"
@ -84,6 +87,9 @@ calls
#ifndef O_BINARY #ifndef O_BINARY
#define O_BINARY 0 #define O_BINARY 0
#endif /* O_BINARY */ #endif /* O_BINARY */
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif /* O_CLOEXEC */
#if 0 #if 0
/* One example of calling this. /* One example of calling this.
@ -181,7 +187,7 @@ dwarf_construct_elf_access_path(const char *path,
int res = 0; int res = 0;
dwarf_elf_object_access_internals_t *mymp = 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) { if (fd < 0) {
*errcode = DW_DLE_PATH_SIZE_TOO_SMALL; *errcode = DW_DLE_PATH_SIZE_TOO_SMALL;
return DW_DLV_ERROR; 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_len = block_len;
dfi->fi_expr.bl_data = instr_ptr; 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; instr_ptr += block_len;
if (instr_area_length < block_len || if (instr_area_length < block_len ||
instr_ptr < base_instr_ptr) { instr_ptr < base_instr_ptr) {
@ -2127,14 +2134,21 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
} }
fde_ptr = prefix.cf_addr_after_prefix; fde_ptr = prefix.cf_addr_after_prefix;
cie_id = prefix.cf_cie_id; 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. /* Pass NULL, not section pointer, for 3rd argument.
de_debug_frame.dss_data has no eh_frame relevance. */ de_debug_frame.dss_data has no eh_frame relevance. */
res = _dwarf_create_fde_from_after_start(dbg, &prefix, res = _dwarf_create_fde_from_after_start(dbg, &prefix,
fde_start_ptr, fde_start_ptr,
dbg->de_debug_frame.dss_size,
fde_ptr, fde_ptr,
fde_end_ptr, fde_end_ptr,
/* use_gnu_cie_calc= */ 0, /* use_gnu_cie_calc= */ 0,
/* Dwarf_Cie = */ 0, /* Dwarf_Cie = */ 0,
address_size, address_size,
&new_fde, error); &new_fde, error);
@ -2151,7 +2165,25 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
/* Now read the cie corresponding to the fde, /* Now read the cie corresponding to the fde,
_dwarf_read_cie_fde_prefix checks _dwarf_read_cie_fde_prefix checks
cie_ptr for being within the section. */ 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; 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, res = _dwarf_read_cie_fde_prefix(dbg, cie_ptr,
dbg->de_debug_frame.dss_data, dbg->de_debug_frame.dss_data,
dbg->de_debug_frame.dss_index, dbg->de_debug_frame.dss_index,
@ -2193,7 +2225,9 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
} else { } else {
dwarf_dealloc(dbg,new_fde,DW_DLA_FDE); dwarf_dealloc(dbg,new_fde,DW_DLA_FDE);
new_fde = 0; 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; return DW_DLV_ERROR;
} }
*ret_fde = new_fde; *ret_fde = new_fde;
@ -2551,8 +2585,7 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
return DW_DLV_OK; return DW_DLV_OK;
} }
/* In this interface, table_column of DW_FRAME_CFA_COL /* Table_column DW_FRAME_CFA_COL is not meaningful.
is not meaningful.
Use dwarf_get_fde_info_for_cfa_reg3_b() to get the CFA. Use dwarf_get_fde_info_for_cfa_reg3_b() to get the CFA.
Call dwarf_set_frame_cfa_value() to set the correct column Call dwarf_set_frame_cfa_value() to set the correct column
after calling dwarf_init() after calling dwarf_init()
@ -2571,15 +2604,49 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
if the pointer is null). if the pointer is null).
Otherwise *has_more_rows and *subsequent_pc Otherwise *has_more_rows and *subsequent_pc
are not set. are not set.
The offset returned is Unsigned, which was
always wrong. Cast to Dwarf_Signed to use it.
*/ */
int int
dwarf_get_fde_info_for_reg3_b(Dwarf_Fde fde, 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_Half table_column,
Dwarf_Addr pc_requested, Dwarf_Addr pc_requested,
Dwarf_Small *value_type, Dwarf_Small *value_type,
Dwarf_Unsigned *offset_relevant, Dwarf_Unsigned *offset_relevant,
Dwarf_Unsigned *register_num, Dwarf_Unsigned *register_num,
Dwarf_Unsigned *offset, Dwarf_Signed *offset,
Dwarf_Block *block, Dwarf_Block *block,
Dwarf_Addr *row_pc_out, Dwarf_Addr *row_pc_out,
Dwarf_Bool *has_more_rows, 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_Bool *has_more_rows,
Dwarf_Addr *subsequent_pc, Dwarf_Addr *subsequent_pc,
Dwarf_Error *error) 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; struct Dwarf_Frame_s fde_table;
int res = DW_DLV_ERROR; int res = DW_DLV_ERROR;

View File

@ -196,8 +196,6 @@ typedef struct Dwarf_Regtable3_s_i {
Dwarf_Regtable_Entry3_i *rt3_rules; Dwarf_Regtable_Entry3_i *rt3_rules;
} Dwarf_Regtable3_i; } Dwarf_Regtable3_i;
typedef struct Dwarf_Frame_s *Dwarf_Frame; 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, int _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
struct cie_fde_prefix_s * prefix, struct cie_fde_prefix_s * prefix,
Dwarf_Small *section_pointer, Dwarf_Small *section_pointer,
Dwarf_Unsigned section_length,
Dwarf_Small *frame_ptr, Dwarf_Small *frame_ptr,
Dwarf_Small *section_ptr_end, Dwarf_Small *section_ptr_end,
int use_gnu_cie_calc, 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. ambiguous, but this calculation is correct.
*/ */
static Dwarf_Small * static int
get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, get_cieptr_given_offset(Dwarf_Debug dbg,
Dwarf_Unsigned cie_id_value,
int use_gnu_cie_calc, int use_gnu_cie_calc,
Dwarf_Small * section_ptr, 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) { if (use_gnu_cie_calc) {
/* cie_id value is offset, in section, of the /* cie_id value is offset, in section, of the
cie_id itself, to cie_id itself, to
use vm ptr of the value, use vm ptr of the value,
less the value, to get to the cie header. */ 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 { } else {
/* Traditional dwarf section offset is in cie_id */ /* 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 /* 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) { if (frame_ptr >= section_ptr_end) {
_dwarf_dealloc_fde_cie_list_internal(head_fde_ptr, _dwarf_dealloc_fde_cie_list_internal(head_fde_ptr,
head_cie_ptr); head_cie_ptr);
#if 0
_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
#endif
_dwarf_error_string(dbg, error, _dwarf_error_string(dbg, error,
DW_DLE_DEBUG_FRAME_LENGTH_BAD, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
"DW_DLE_DEBUG_FRAME_LENGTH_BAD: following " "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_Fde fde_ptr_to_use = 0;
Dwarf_Small *cieptr_val = 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, use_gnu_cie_calc,
section_ptr, 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, resf = _dwarf_find_existing_cie_ptr(cieptr_val,
cur_cie_ptr, cur_cie_ptr,
&cie_ptr_to_use, &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, resf = _dwarf_create_fde_from_after_start(dbg,
&prefix, &prefix,
section_ptr, section_ptr,
section_length,
frame_ptr, frame_ptr,
section_ptr_end, section_ptr_end,
use_gnu_cie_calc, use_gnu_cie_calc,
@ -580,8 +604,8 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
if (!head_cie_ptr) { if (!head_cie_ptr) {
/* Should be impossible. */ /* Should be impossible. */
_dwarf_error_string(dbg, error,DW_DLE_DEBUGFRAME_ERROR, _dwarf_error_string(dbg, error,DW_DLE_DEBUGFRAME_ERROR,
"DW_DLE_DEBUGFRAME_ERROR" "DW_DLE_DEBUGFRAME_ERROR"
"Impossible no head_cie_ptr"); "Impossible no head_cie_ptr");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
cur_cie_ptr = head_cie_ptr; cur_cie_ptr = head_cie_ptr;
@ -600,7 +624,7 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
_dwarf_dealloc_fde_cie_list_internal(head_fde_ptr, _dwarf_dealloc_fde_cie_list_internal(head_fde_ptr,
head_cie_ptr); head_cie_ptr);
_dwarf_error_string(dbg, error,DW_DLE_ALLOC_FAIL, _dwarf_error_string(dbg, error,DW_DLE_ALLOC_FAIL,
"DW_DLE_ALLOC_FAIL" "DW_DLE_ALLOC_FAIL"
"getting DW_DLA_LIST given fde_count"); "getting DW_DLA_LIST given fde_count");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
@ -987,7 +1011,7 @@ _dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
if (new_cie == NULL) { if (new_cie == NULL) {
_dwarf_error_string(dbg, error, _dwarf_error_string(dbg, error,
DW_DLE_ALLOC_FAIL, DW_DLE_ALLOC_FAIL,
"DW_DLE_ALLOC_FAIL " "DW_DLE_ALLOC_FAIL "
"attempting to allocate a Dwarf_Cie"); "attempting to allocate a Dwarf_Cie");
@ -1057,6 +1081,7 @@ int
_dwarf_create_fde_from_after_start(Dwarf_Debug dbg, _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
struct cie_fde_prefix_s *prefix, struct cie_fde_prefix_s *prefix,
Dwarf_Small *section_pointer, Dwarf_Small *section_pointer,
Dwarf_Unsigned section_length,
Dwarf_Small *frame_ptr, Dwarf_Small *frame_ptr,
Dwarf_Small *section_ptr_end, Dwarf_Small *section_ptr_end,
int use_gnu_cie_calc, int use_gnu_cie_calc,
@ -1133,6 +1158,42 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
dbg,error,section_ptr_end); dbg,error,section_ptr_end);
fde_aug_data_len = adlen; fde_aug_data_len = adlen;
fde_aug_data = frame_ptr; 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; frame_ptr += adlen;
if (adlen) { if (adlen) {
if (frame_ptr < fde_aug_data || if (frame_ptr < fde_aug_data ||
@ -1180,7 +1241,7 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
length_of_augmented_fields = (Dwarf_Unsigned) lreg; length_of_augmented_fields = (Dwarf_Unsigned) lreg;
if (length_of_augmented_fields >= dbg->de_filesize) { if (length_of_augmented_fields >= dbg->de_filesize) {
_dwarf_error_string(dbg, error, _dwarf_error_string(dbg, error,
DW_DLE_DEBUG_FRAME_LENGTH_BAD, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
"DW_DLE_DEBUG_FRAME_LENGTH_BAD " "DW_DLE_DEBUG_FRAME_LENGTH_BAD "
"in irix exception table length of augmented " "in irix exception table length of augmented "
@ -1202,8 +1263,8 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
error,section_ptr_end); error,section_ptr_end);
SIGN_EXTEND(offset_into_exception_tables, SIGN_EXTEND(offset_into_exception_tables,
DWARF_32BIT_SIZE); DWARF_32BIT_SIZE);
if (offset_into_exception_tables > 0) { if (offset_into_exception_tables > 0) {
if ((Dwarf_Unsigned)offset_into_exception_tables >= if ((Dwarf_Unsigned)offset_into_exception_tables >=
dbg->de_filesize) { dbg->de_filesize) {
_dwarf_error_string(dbg,error, _dwarf_error_string(dbg,error,
DW_DLE_DEBUG_FRAME_LENGTH_BAD, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
@ -1262,10 +1323,11 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
if ( frame_ptr < initloc) { if ( frame_ptr < initloc) {
_dwarf_error_string(dbg, error, _dwarf_error_string(dbg, error,
DW_DLE_DF_FRAME_DECODING_ERROR, DW_DLE_DF_FRAME_DECODING_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; return DW_DLV_ERROR;
} }

View File

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

View File

@ -154,7 +154,7 @@ _dwarf_file_name_is_full_path(Dwarf_Small *fname)
/* Used for a short time in the next two functions. /* Used for a short time in the next two functions.
Not saved. If multithreading ever allowed this Not saved. If multithreading ever allowed this
will have to change to be function local will have to change to be function local
non-static buffers. */ non-static buffers. */
static char targbuf[300]; static char targbuf[300];
static char nbuf[300]; static char nbuf[300];
@ -163,7 +163,7 @@ static int
ret_simple_full_path(Dwarf_Debug dbg, ret_simple_full_path(Dwarf_Debug dbg,
char *file_name, char *file_name,
char ** name_ptr_out, char ** name_ptr_out,
Dwarf_Error *error) Dwarf_Error *error)
{ {
char *tmp = 0; char *tmp = 0;
char * mstr = 0; char * mstr = 0;
@ -217,14 +217,14 @@ _dwarf_dirno_string(Dwarf_Line_Context line_context,
" only %u directories present>", " only %u directories present>",
line_context->lc_include_directories_count); line_context->lc_include_directories_count);
return; return;
} }
{ {
char *inc_dir_name = char *inc_dir_name =
(char *)line_context->lc_include_directories[ (char *)line_context->lc_include_directories[
dirno - include_dir_offset]; dirno - include_dir_offset];
if (!inc_dir_name) { if (!inc_dir_name) {
/* This should never ever happen except in case /* This should never ever happen except in case
of a corrupted object file. of a corrupted object file.
Make the text look like a full-path */ Make the text look like a full-path */
inc_dir_name = inc_dir_name =
"/ERROR<erroneous NULL include dir pointer>"; "/ERROR<erroneous NULL include dir pointer>";
@ -234,8 +234,6 @@ _dwarf_dirno_string(Dwarf_Line_Context line_context,
return; return;
} }
/* With this routine we ensure the file full path /* With this routine we ensure the file full path
is calculated identically for is calculated identically for
dwarf_srcfiles() and _dwarf_filename() dwarf_srcfiles() and _dwarf_filename()
@ -276,13 +274,13 @@ create_fullest_file_path(Dwarf_Debug dbg,
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) { if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) {
int res = 0; int res = 0;
res = ret_simple_full_path(dbg, res = ret_simple_full_path(dbg,
file_name, file_name,
name_ptr_out, name_ptr_out,
error); error);
return res; return res;
} }
{ {
int need_dir = FALSE; int need_dir = FALSE;
@ -350,12 +348,12 @@ create_fullest_file_path(Dwarf_Debug dbg,
_dwarf_file_name_is_full_path( _dwarf_file_name_is_full_path(
(Dwarf_Small*)dwarfstring_string(&incdir))) { (Dwarf_Small*)dwarfstring_string(&incdir))) {
/* incdir is full path,Ignore DW_AT_comp_dir /* incdir is full path,Ignore DW_AT_comp_dir
and (for DWARF5 include_dir[0]) */ and (for DWARF5 include_dir[0]) */
_dwarf_pathjoinl(&targ,&incdir); _dwarf_pathjoinl(&targ,&incdir);
_dwarf_pathjoinl(&targ,&filename); _dwarf_pathjoinl(&targ,&filename);
} else { } else {
/* Join two or all three strings, /* Join two or all three strings,
ignoring empty/irrelevant ones. */ ignoring empty/irrelevant ones. */
/* Remember that 0xf006 is the version of /* Remember that 0xf006 is the version of
the experimental line table */ the experimental line table */

View File

@ -235,7 +235,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg,
line_context->lc_section_offset = starting_line_ptr - line_context->lc_section_offset = starting_line_ptr -
dbg->de_debug_line.dss_data; dbg->de_debug_line.dss_data;
/* ASSERT: line_context->lc_length_field_length == line_ptr /* ASSERT: line_context->lc_length_field_length == line_ptr
-line_context->lc_line_ptr_start; -line_context->lc_line_ptr_start;
The following test allows the == case too The following test allows the == case too
as that is normal for the last CUs line table. */ as that is normal for the last CUs line table. */
if (line_ptr_end > section_end) { if (line_ptr_end > section_end) {
@ -678,7 +678,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg,
_dwarf_error_string(dbg, err, DW_DLE_LINE_OFFSET_BAD, _dwarf_error_string(dbg, err, DW_DLE_LINE_OFFSET_BAD,
"DW_DLE_LINE_OFFSET_BAD " "DW_DLE_LINE_OFFSET_BAD "
"The line table actuals offset is too large " "The line table actuals offset is too large "
"to be real."); "to be real.");
return DW_DLV_ERROR; return DW_DLV_ERROR;
} }
} }

View File

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

View File

@ -945,7 +945,17 @@ _dwarf_macho_object_access_internals_init(
_dwarf_destruct_macho_access(localdoas); _dwarf_destruct_macho_access(localdoas);
return res; return res;
} }
sp = intfc->mo_dwarf_sections+1; 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) { for (i = 1; i < intfc->mo_dwarf_sectioncount ; ++i,++sp) {
int j = 1; int j = 1;
int lim = sizeof(SectionNames)/sizeof(SectionNames[0]); int lim = sizeof(SectionNames)/sizeof(SectionNames[0]);

View File

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

View File

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

View File

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

View File

@ -1412,10 +1412,7 @@ dwarf_rnglists_get_rle_head(
rle_global_offset = attr_val; 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_end_data_area = enddata;
shead.rh_rlearea_offset = rle_global_offset; shead.rh_rlearea_offset = rle_global_offset;
shead.rh_rlepointer = rle_global_offset + shead.rh_rlepointer = rle_global_offset +
dbg->de_debug_rnglists.dss_data; 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. EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/* Thanks to David Grayson/ /* Thanks to David Grayson/
codereview.stackexchange.com/questions/98791/ codereview.stackexchange.com/questions/98791/
safe-multiplication-of-two-64-bit-signed-integers safe-multiplication-of-two-64-bit-signed-integers
@ -45,7 +44,8 @@ int _dwarf_uint64_mult(Dwarf_Unsigned x, Dwarf_Unsigned y,
#if 0 #if 0
/* See: /* 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, int _dwarf_signed_add_check(Dwarf_Signed l, Dwarf_Signed r,
Dwarf_Signed *sum, Dwarf_Debug dbg, Dwarf_Signed *sum, Dwarf_Debug dbg,

View File

@ -131,7 +131,6 @@ _dwarf_loop_reading_debug_info_for_cu(
Dwarf_Debug tieddbg, Dwarf_Debug tieddbg,
Dwarf_Error *error) Dwarf_Error *error)
{ {
unsigned loop_count = 0;
/* We will not find tied signatures /* We will not find tied signatures
for .debug_addr (or line tables) in .debug_types. for .debug_addr (or line tables) in .debug_types.
it seems. Those signatures point from it seems. Those signatures point from
@ -150,7 +149,7 @@ _dwarf_loop_reading_debug_info_for_cu(
startingcontext->cc_extension_size; startingcontext->cc_extension_size;
} }
for (;;++loop_count) { for (;;) {
int sres = DW_DLV_OK; int sres = DW_DLV_OK;
Dwarf_Half cu_type = 0; Dwarf_Half cu_type = 0;
Dwarf_CU_Context latestcontext = 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 nextabbrev = 0;
Dwarf_Abbrev_List abbrev = Dwarf_Abbrev_List abbrev =
hash_table->tb_entries[hashnum]; hash_table->tb_entries[hashnum];
#ifdef TESTINGHASHTAB
unsigned listcount = 0; unsigned listcount = 0;
#endif
if (!abbrev) { if (!abbrev) {
continue; continue;
@ -1266,7 +1268,9 @@ _dwarf_free_abbrev_hash_table_contents(Dwarf_Hash_Table hash_table,
/* dealloc single list entry */ /* dealloc single list entry */
free(abbrev); free(abbrev);
abbrev = 0; abbrev = 0;
#ifdef TESTINGHASHTAB
++listcount; ++listcount;
#endif
} }
#ifdef TESTINGHASHTAB #ifdef TESTINGHASHTAB
printf("debugging: hashnum %lu listcount %u\n",hashnum,listcount); printf("debugging: hashnum %lu listcount %u\n",hashnum,listcount);

View File

@ -60,9 +60,9 @@
# elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) # elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
# if defined(PIC) || defined(__PIC__) # if defined(PIC) || defined(__PIC__)
# define DW_API __global # define DW_API __global
# endif /* __PIC__ */ # endif /* __PIC__ */
# elif (defined(__GNUC__) && __GNUC__ >= 4) || \ # elif (defined(__GNUC__) && __GNUC__ >= 4) || \
defined(__INTEL_COMPILER) defined(__INTEL_COMPILER)
# if defined(PIC) || defined(__PIC__) # if defined(PIC) || defined(__PIC__)
# define DW_API __attribute__ ((visibility("default"))) # define DW_API __attribute__ ((visibility("default")))
# endif /* PIC */ # endif /* PIC */
@ -99,10 +99,10 @@ extern "C" {
*/ */
/* Semantic Version identity for this libdwarf.h */ /* Semantic Version identity for this libdwarf.h */
#define DW_LIBDWARF_VERSION "0.7.1" #define DW_LIBDWARF_VERSION "0.8.0"
#define DW_LIBDWARF_VERSION_MAJOR 0 #define DW_LIBDWARF_VERSION_MAJOR 0
#define DW_LIBDWARF_VERSION_MINOR 7 #define DW_LIBDWARF_VERSION_MINOR 8
#define DW_LIBDWARF_VERSION_MICRO 1 #define DW_LIBDWARF_VERSION_MICRO 0
#define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_unspecified 0
#define DW_PATHSOURCE_basic 1 #define DW_PATHSOURCE_basic 1
@ -458,11 +458,11 @@ typedef struct Dwarf_Ranges_s {
possible case for dwarf2): possible case for dwarf2):
If dw_offset_relevant is non-zero, then If dw_offset_relevant is non-zero, then
the value is stored at at the address 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 dw_regnum is the cfa register rule which means
one ignores dw_regnum and uses the CFA appropriately. 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) Rule: Offset(N)
If dw_offset_relevant is zero, then the If dw_offset_relevant is zero, then the
value of the register value of the register
@ -470,7 +470,8 @@ typedef struct Dwarf_Ranges_s {
Rule: register(R) Rule: register(R)
If dw_value_type == DW_EXPR_VAL_OFFSET If dw_value_type == DW_EXPR_VAL_OFFSET
the value of this register is CFA +N where 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 dw_regnum is the cfa register rule which means
one ignores dw_regnum and uses the CFA appropriately. one ignores dw_regnum and uses the CFA appropriately.
Rule: val_offset(N) Rule: val_offset(N)
@ -494,15 +495,16 @@ typedef struct Dwarf_Ranges_s {
Note that this definition can only deal correctly Note that this definition can only deal correctly
with register numbers that fit in a 16 bit 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 { typedef struct Dwarf_Regtable_Entry3_s {
Dwarf_Small dw_offset_relevant; Dwarf_Small dw_offset_relevant;
Dwarf_Small dw_value_type; Dwarf_Small dw_value_type;
Dwarf_Half dw_regnum; Dwarf_Half dw_regnum;
Dwarf_Unsigned dw_offset; Dwarf_Unsigned dw_offset; /* Should be Dwarf_Signed */
Dwarf_Unsigned dw_args_size; /* Not dealt with. */ Dwarf_Unsigned dw_args_size; /* Always zero. */
Dwarf_Block dw_block; Dwarf_Block dw_block;
} Dwarf_Regtable_Entry3; } Dwarf_Regtable_Entry3;
@ -2583,7 +2585,7 @@ DW_API int dwarf_attrlist(Dwarf_Die dw_die,
Dwarf_Signed * dw_attrcount, Dwarf_Signed * dw_attrcount,
Dwarf_Error* dw_error); 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 @param dw_attr
The Dwarf_Attribute of interest. The Dwarf_Attribute of interest.
@param dw_form @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. /*! @brief Return details about a particular pc and register.
It is inefficient to iterate across all table_columns (registers) 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() Instead call dwarf_get_fde_info_for_all_regs3()
and index into the table it fills in. 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 on runtime frame data which cannot be calculated
without a stack frame including registers (etc). 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 @param dw_fde
Pass in the FDE of interest. Pass in the FDE of interest.
@param dw_table_column @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 @param dw_register
On success returns a register number. On success returns a register number.
@param dw_offset @param dw_offset
On success returns a register offset value. On success returns a signed register offset value when
In principle these are signed, but historically dw_value_tyoe is DW_EXPR_OFFSET or DW_EXPER_VAL_OFFSET.
in libdwarf it is typed unsigned.
Cast the returned value to Dwarf_Signed to
get the correct meaning.
@param dw_block_content @param dw_block_content
On success returns a pointer to a block. On success returns a pointer to a block.
For example, for DW_EXPR_EXPRESSION the 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 FDE passed in and there is a row for the pc
in the table. 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, DW_API int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde dw_fde,
Dwarf_Half dw_table_column, Dwarf_Half dw_table_column,
Dwarf_Addr dw_pc_requested, 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 /*! @brief Get the value of the CFA for a particular pc value
@see dwarf_get_fde_info_for_reg3_b @see dwarf_get_fde_info_for_reg3_c
has essentially the same return values as
This has essentially the same return values but dwarf_get_fde_info_for_reg3_c but
it refers to the CFA (which is not part of the register it refers to the CFA (which is not part of the register
table) table) so function has no table column argument.
In principle the value returned throuth
dw_offset is signed, but historically New in September 2023, release 0.8.0.
in libdwarf it is typed unsigned. dwarf_get_fde_info_for_cfa_reg3_c() returns dw_offset
Cast the returned dw_offset value to Dwarf_Signed to as a signed type.
get the correct meaning. 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 If dw_value_type == DW_EXPR_EXPRESSION or
DW_EXPR_VALUE_EXPRESSION dw_offset DW_EXPR_VALUE_EXPRESSION dw_offset
is not set and the caller must is not set and the caller must
evaluate the expression, which usually depends evaluate the expression, which usually depends
on runtime frame data which cannot be calculated 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, DW_API int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde dw_fde,
Dwarf_Addr dw_pc_requested, Dwarf_Addr dw_pc_requested,