diff --git a/bundled/libdwarf/dwarf_elf_load_headers.c b/bundled/libdwarf/dwarf_elf_load_headers.c index 2eb4584..a193305 100644 --- a/bundled/libdwarf/dwarf_elf_load_headers.c +++ b/bundled/libdwarf/dwarf_elf_load_headers.c @@ -65,6 +65,9 @@ calls #elif defined HAVE_UNISTD_H #include /* close() */ #endif /* _WIN32 */ +#ifdef HAVE_FCNTL_H +#include /* 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; diff --git a/bundled/libdwarf/dwarf_frame.c b/bundled/libdwarf/dwarf_frame.c index 44e105c..0cf00cd 100644 --- a/bundled/libdwarf/dwarf_frame.c +++ b/bundled/libdwarf/dwarf_frame.c @@ -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; diff --git a/bundled/libdwarf/dwarf_frame.h b/bundled/libdwarf/dwarf_frame.h index 627fe20..070ddb6 100644 --- a/bundled/libdwarf/dwarf_frame.h +++ b/bundled/libdwarf/dwarf_frame.h @@ -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, diff --git a/bundled/libdwarf/dwarf_frame2.c b/bundled/libdwarf/dwarf_frame2.c index 8227406..97cc955 100644 --- a/bundled/libdwarf/dwarf_frame2.c +++ b/bundled/libdwarf/dwarf_frame2.c @@ -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, @@ -580,8 +604,8 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, if (!head_cie_ptr) { /* Should be impossible. */ _dwarf_error_string(dbg, error,DW_DLE_DEBUGFRAME_ERROR, - "DW_DLE_DEBUGFRAME_ERROR" - "Impossible no head_cie_ptr"); + "DW_DLE_DEBUGFRAME_ERROR" + "Impossible no head_cie_ptr"); return DW_DLV_ERROR; } 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, head_cie_ptr); _dwarf_error_string(dbg, error,DW_DLE_ALLOC_FAIL, - "DW_DLE_ALLOC_FAIL" + "DW_DLE_ALLOC_FAIL" "getting DW_DLA_LIST given fde_count"); 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); if (new_cie == NULL) { - _dwarf_error_string(dbg, error, + _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL " "attempting to allocate a Dwarf_Cie"); @@ -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 || @@ -1180,7 +1241,7 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg, length_of_augmented_fields = (Dwarf_Unsigned) lreg; 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 " "in irix exception table length of augmented " @@ -1202,8 +1263,8 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg, error,section_ptr_end); SIGN_EXTEND(offset_into_exception_tables, DWARF_32BIT_SIZE); - if (offset_into_exception_tables > 0) { - if ((Dwarf_Unsigned)offset_into_exception_tables >= + if (offset_into_exception_tables > 0) { + if ((Dwarf_Unsigned)offset_into_exception_tables >= dbg->de_filesize) { _dwarf_error_string(dbg,error, DW_DLE_DEBUG_FRAME_LENGTH_BAD, @@ -1262,10 +1323,11 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg, return DW_DLV_ERROR; } 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 " - "frame pointer decreased.Impossible. arithmetic overflow"); + "frame pointer decreased.Impossible. " + "arithmetic overflow"); return DW_DLV_ERROR; } diff --git a/bundled/libdwarf/dwarf_generic_init.c b/bundled/libdwarf/dwarf_generic_init.c index 92a8ff0..a692d9b 100644 --- a/bundled/libdwarf/dwarf_generic_init.c +++ b/bundled/libdwarf/dwarf_generic_init.c @@ -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; } diff --git a/bundled/libdwarf/dwarf_line.c b/bundled/libdwarf/dwarf_line.c index c1ddaa2..3d4f6d3 100644 --- a/bundled/libdwarf/dwarf_line.c +++ b/bundled/libdwarf/dwarf_line.c @@ -154,7 +154,7 @@ _dwarf_file_name_is_full_path(Dwarf_Small *fname) /* Used for a short time in the next two functions. 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. */ static char targbuf[300]; static char nbuf[300]; @@ -163,7 +163,7 @@ static int ret_simple_full_path(Dwarf_Debug dbg, char *file_name, char ** name_ptr_out, - Dwarf_Error *error) + Dwarf_Error *error) { char *tmp = 0; char * mstr = 0; @@ -217,14 +217,14 @@ _dwarf_dirno_string(Dwarf_Line_Context line_context, " only %u directories present>", line_context->lc_include_directories_count); return; - } + } { char *inc_dir_name = (char *)line_context->lc_include_directories[ dirno - include_dir_offset]; if (!inc_dir_name) { /* 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 */ inc_dir_name = "/ERROR"; @@ -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() @@ -276,13 +274,13 @@ create_fullest_file_path(Dwarf_Debug dbg, return DW_DLV_ERROR; } if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) { - int res = 0; + int res = 0; - res = ret_simple_full_path(dbg, - file_name, - name_ptr_out, - error); - return res; + res = ret_simple_full_path(dbg, + file_name, + name_ptr_out, + error); + return res; } { int need_dir = FALSE; @@ -350,12 +348,12 @@ create_fullest_file_path(Dwarf_Debug dbg, _dwarf_file_name_is_full_path( (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]) */ _dwarf_pathjoinl(&targ,&incdir); _dwarf_pathjoinl(&targ,&filename); } else { - /* Join two or all three strings, + /* Join two or all three strings, ignoring empty/irrelevant ones. */ /* Remember that 0xf006 is the version of the experimental line table */ diff --git a/bundled/libdwarf/dwarf_line_table_reader_common.h b/bundled/libdwarf/dwarf_line_table_reader_common.h index a0f61fc..1a9d539 100644 --- a/bundled/libdwarf/dwarf_line_table_reader_common.h +++ b/bundled/libdwarf/dwarf_line_table_reader_common.h @@ -235,7 +235,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, line_context->lc_section_offset = starting_line_ptr - dbg->de_debug_line.dss_data; /* 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 as that is normal for the last CUs line table. */ 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, "DW_DLE_LINE_OFFSET_BAD " "The line table actuals offset is too large " - "to be real."); + "to be real."); return DW_DLV_ERROR; } } diff --git a/bundled/libdwarf/dwarf_loclists.c b/bundled/libdwarf/dwarf_loclists.c index a084987..c6061cb 100644 --- a/bundled/libdwarf/dwarf_loclists.c +++ b/bundled/libdwarf/dwarf_loclists.c @@ -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; diff --git a/bundled/libdwarf/dwarf_machoread.c b/bundled/libdwarf/dwarf_machoread.c index 8fff3f1..1d17c37 100644 --- a/bundled/libdwarf/dwarf_machoread.c +++ b/bundled/libdwarf/dwarf_machoread.c @@ -945,7 +945,17 @@ _dwarf_macho_object_access_internals_init( _dwarf_destruct_macho_access(localdoas); 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) { int j = 1; int lim = sizeof(SectionNames)/sizeof(SectionNames[0]); diff --git a/bundled/libdwarf/dwarf_names.c b/bundled/libdwarf/dwarf_names.c index 06f65ee..99b4228 100644 --- a/bundled/libdwarf/dwarf_names.c +++ b/bundled/libdwarf/dwarf_names.c @@ -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 */ diff --git a/bundled/libdwarf/dwarf_object_detector.c b/bundled/libdwarf/dwarf_object_detector.c index e1215dd..a3d12b9 100644 --- a/bundled/libdwarf/dwarf_object_detector.c +++ b/bundled/libdwarf/dwarf_object_detector.c @@ -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) { diff --git a/bundled/libdwarf/dwarf_object_detector.h b/bundled/libdwarf/dwarf_object_detector.h index 8aaade1..85dfa47 100644 --- a/bundled/libdwarf/dwarf_object_detector.h +++ b/bundled/libdwarf/dwarf_object_detector.h @@ -76,7 +76,6 @@ extern "C" { *errcode when the function returns DW_DLV_ERROR) will hopefully suffice for most purposes. */ - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bundled/libdwarf/dwarf_rnglists.c b/bundled/libdwarf/dwarf_rnglists.c index 1f89a7d..c0056a5 100644 --- a/bundled/libdwarf/dwarf_rnglists.c +++ b/bundled/libdwarf/dwarf_rnglists.c @@ -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; diff --git a/bundled/libdwarf/dwarf_safe_arithmetic.h b/bundled/libdwarf/dwarf_safe_arithmetic.h index c661dd8..7fc604d 100644 --- a/bundled/libdwarf/dwarf_safe_arithmetic.h +++ b/bundled/libdwarf/dwarf_safe_arithmetic.h @@ -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, diff --git a/bundled/libdwarf/dwarf_tied.c b/bundled/libdwarf/dwarf_tied.c index 909cf4a..1eeb8d1 100644 --- a/bundled/libdwarf/dwarf_tied.c +++ b/bundled/libdwarf/dwarf_tied.c @@ -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; diff --git a/bundled/libdwarf/dwarf_util.c b/bundled/libdwarf/dwarf_util.c index 4defb5a..99113ef 100644 --- a/bundled/libdwarf/dwarf_util.c +++ b/bundled/libdwarf/dwarf_util.c @@ -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); diff --git a/bundled/libdwarf/libdwarf.h b/bundled/libdwarf/libdwarf.h index 36d2e3d..7a85d28 100644 --- a/bundled/libdwarf/libdwarf.h +++ b/bundled/libdwarf/libdwarf.h @@ -60,9 +60,9 @@ # elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) # if defined(PIC) || defined(__PIC__) # define DW_API __global -# endif /* __PIC__ */ +# endif /* __PIC__ */ # elif (defined(__GNUC__) && __GNUC__ >= 4) || \ - defined(__INTEL_COMPILER) + defined(__INTEL_COMPILER) # if defined(PIC) || defined(__PIC__) # define DW_API __attribute__ ((visibility("default"))) # endif /* PIC */ @@ -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,