From 97fd68c6026c0237943106d6bc3e83f3661d39e8 Mon Sep 17 00:00:00 2001 From: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sun, 18 Aug 2024 14:08:35 -0500 Subject: [PATCH] Bump to v0.11.0 --- CMakeLists.txt | 2 +- pull.sh | 3 +- src/lib/libdwarf/dwarf_arange.c | 8 +- src/lib/libdwarf/dwarf_base_types.h | 8 +- src/lib/libdwarf/dwarf_debugaddr.c | 2 +- src/lib/libdwarf/dwarf_die_deliv.c | 83 ++++--- src/lib/libdwarf/dwarf_fission_to_cu.c | 28 ++- src/lib/libdwarf/dwarf_frame.c | 56 ++--- src/lib/libdwarf/dwarf_generic_init.c | 6 +- src/lib/libdwarf/dwarf_global.c | 2 +- src/lib/libdwarf/dwarf_gnu_index.c | 4 +- src/lib/libdwarf/dwarf_harmless.c | 6 +- src/lib/libdwarf/dwarf_init_finish.c | 6 +- src/lib/libdwarf/dwarf_line.c | 37 +-- .../libdwarf/dwarf_line_table_reader_common.h | 40 ++-- src/lib/libdwarf/dwarf_loc.c | 6 +- src/lib/libdwarf/dwarf_loc.h | 1 + src/lib/libdwarf/dwarf_loclists.c | 53 +++-- src/lib/libdwarf/dwarf_loclists.h | 9 +- src/lib/libdwarf/dwarf_machoread.c | 49 ++-- src/lib/libdwarf/dwarf_opaque.h | 10 +- src/lib/libdwarf/dwarf_print_lines.c | 14 +- src/lib/libdwarf/dwarf_query.c | 19 +- src/lib/libdwarf/dwarf_ranges.c | 220 ++++++++++++++++-- src/lib/libdwarf/dwarf_rnglists.c | 94 +++++--- src/lib/libdwarf/dwarf_rnglists.h | 12 +- src/lib/libdwarf/dwarf_setup_sections.c | 3 +- src/lib/libdwarf/dwarf_tied.c | 2 +- src/lib/libdwarf/dwarf_tsearchhash.c | 7 +- src/lib/libdwarf/libdwarf.h | 90 ++++++- 30 files changed, 631 insertions(+), 249 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c53fda5..28f33ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.5) -project(libdwarf VERSION 0.10.1 +project(libdwarf VERSION 0.11.0 DESCRIPTION "Library to access DWARF debugging information" HOMEPAGE_URL "https://github.com/davea42/libdwarf-code.git" LANGUAGES C CXX) diff --git a/pull.sh b/pull.sh index dcb86e6..afbf685 100644 --- a/pull.sh +++ b/pull.sh @@ -9,7 +9,8 @@ cd libdwarf-code #git checkout "8b0bd09d8c77d45a68cb1bb00a54186a92b683d9" # v0.9.0 #git checkout "8cdcc531f310d1c5ae61da469d8056bdd36b77e7" # v0.9.1 + cmake fixes # git checkout "5e43a5ab73cb00c8a46660b361366a8c9c3c93c9" # v0.9.2 -git checkout "45ef8e2763f65c31b27cc38bed197b84dc1441d4" # v0.10.2 +# git checkout "45ef8e2763f65c31b27cc38bed197b84dc1441d4" # v0.10.2 +git checkout "285d9d34f3e9f56cc1c487d0055f6dc54a9c54a1" # v0.11.0 cd .. echo "Copying files" mkdir -p src/lib diff --git a/src/lib/libdwarf/dwarf_arange.c b/src/lib/libdwarf/dwarf_arange.c index be44ed0..b3bd35a 100644 --- a/src/lib/libdwarf/dwarf_arange.c +++ b/src/lib/libdwarf/dwarf_arange.c @@ -629,7 +629,7 @@ dwarf_get_cu_die_offset(Dwarf_Arange arange, } } cres = _dwarf_length_of_cu_header(dbg, offset, - true, &headerlen,error); + TRUE, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } @@ -671,11 +671,11 @@ dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, /* This function takes a Dwarf_Arange, and returns - true if it is not NULL. It also stores the start + TRUE if it is not NULL. It also stores the start address of the range in *start, the length of the range in *length, and the offset of the first die in the compilation-unit in *cu_die_offset. It - returns false on error. + returns FALSE on error. If cu_die_offset returned ensures .debug_info loaded so the cu_die_offset is meaningful. @@ -723,7 +723,7 @@ dwarf_get_arange_info_b(Dwarf_Arange arange, } } cres = _dwarf_length_of_cu_header(dbg, offset, - true, &headerlen,error); + TRUE, &headerlen,error); if (cres != DW_DLV_OK) { return cres; } diff --git a/src/lib/libdwarf/dwarf_base_types.h b/src/lib/libdwarf/dwarf_base_types.h index 89a38eb..adbcce2 100644 --- a/src/lib/libdwarf/dwarf_base_types.h +++ b/src/lib/libdwarf/dwarf_base_types.h @@ -31,8 +31,12 @@ Portions Copyright (C) 2008-2023 David Anderson. All Rights Reserved. #ifndef DWARF_BASE_TYPES_H #define DWARF_BASE_TYPES_H -#define true 1 -#define false 0 +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif /* .debug_addr new in DWARF5 */ #define DW_ADDR_VERSION5 5 diff --git a/src/lib/libdwarf/dwarf_debugaddr.c b/src/lib/libdwarf/dwarf_debugaddr.c index 8433cf4..8b4e87c 100644 --- a/src/lib/libdwarf/dwarf_debugaddr.c +++ b/src/lib/libdwarf/dwarf_debugaddr.c @@ -137,7 +137,7 @@ dwarf_debug_addr_table(Dwarf_Debug dbg, address_size = (Dwarf_Small)dbg->de_debug_addr_address_size; offset_size = dbg->de_debug_addr_offset_size; tab.da_address_size = address_size; - tab.da_length_size = offset_size; + tab.da_length_size = (Dwarf_Small)offset_size; tab.da_length = section_size; tab.da_version = dbg->de_debug_addr_version; end_data = section_start + section_size; diff --git a/src/lib/libdwarf/dwarf_die_deliv.c b/src/lib/libdwarf/dwarf_die_deliv.c index 9755b4f..b568014 100644 --- a/src/lib/libdwarf/dwarf_die_deliv.c +++ b/src/lib/libdwarf/dwarf_die_deliv.c @@ -59,7 +59,7 @@ #define MINIMUM_ADDRESS_SIZE 2 #define MAXIMUM_ADDRESS_SIZE 8 -#if 0 +#if 0 /* dump rnglists context */ #include "dwarf_rnglists.h" /* for debugging declaration */ static void dumprnglists_context(Dwarf_Rnglists_Context *rnglists, @@ -1245,7 +1245,7 @@ _dwarf_set_children_flag(Dwarf_CU_Context cucon, cucon->cc_cu_die_has_children = TRUE; chres = dwarf_die_abbrev_children_flag(cudie,&flag); /* If chres is not DW_DLV_OK the assumption - of children remains true. */ + of children remains TRUE. */ if (chres == DW_DLV_OK) { cucon->cc_cu_die_has_children = flag; } @@ -1440,7 +1440,29 @@ find_cu_die_base_fields(Dwarf_Debug dbg, entry_pc_attrnum = i; break; } + case DW_AT_ranges: { + Dwarf_Unsigned at_ranges_offset = 0; + 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, + &is_info, + error); + if (res == DW_DLV_OK) { + cucon->cc_at_ranges_offset = at_ranges_offset; + cucon->cc_at_ranges_offset_present = TRUE; + } else { + local_attrlist_dealloc(dbg,atcount,alist); + return res; + } + break; + } /* The offset is of the first offset in .debug_str_offsets that is the string table offset array for this CU. */ @@ -1475,6 +1497,7 @@ find_cu_die_base_fields(Dwarf_Debug dbg, error); if (udres == DW_DLV_OK) { cucon->cc_loclists_base_present = TRUE; + cucon->cc_loclists_base_via_at = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ @@ -1518,12 +1541,18 @@ find_cu_die_base_fields(Dwarf_Debug dbg, http://llvm.1065342.n5.nabble.com/ DebugInfo-DW-AT-GNU-ranges-base-in- non-fission-td64194.html - But we accept it anyway. */ - /* offset in .debug_rnglists of the offsets table + But we accept it anyway. + In dw4 GNU fission extension + it is used and matters. + + offset in .debug_rnglists of the offsets table applicable to this CU. + Or for DW4 GNU .debug_ranges split dwarf + it refers to .debug_ranges. Note that this base applies when referencing from the dwp, but NOT when referencing from the a.out */ + int udres = 0; Dwarf_Bool is_info = cucon->cc_is_info; @@ -1552,6 +1581,7 @@ find_cu_die_base_fields(Dwarf_Debug dbg, error); if (udres == DW_DLV_OK) { cucon->cc_rnglists_base_present = TRUE; + cucon->cc_rnglists_base_via_at = TRUE; } else { local_attrlist_dealloc(dbg,atcount,alist); /* Something is badly wrong. */ @@ -1705,10 +1735,9 @@ finish_up_cu_context_from_cudie(Dwarf_Debug dbg, assign_correct_unit_type(cu_context); } if (cu_context->cc_signature_present) { - /* Initially just for DW_SECT_STR_OFFSETS, - finds the section offset of the - contribution which is not the same - as the table offset. */ + /* For finding base data from skeleton. + For the few fields inherited + (per the DWARF5 standard. */ res = _dwarf_find_all_offsets_via_fission(dbg, cu_context,error); if (res == DW_DLV_ERROR) { @@ -1726,6 +1755,7 @@ finish_up_cu_context_from_cudie(Dwarf_Debug dbg, Invariant: cc_debug_offset in strictly ascending order in the list. + Never returns DW_DLV_NO_ENTRY */ static int insert_into_cu_context_list(Dwarf_Debug_InfoTypes dis, @@ -1845,9 +1875,13 @@ _dwarf_create_a_new_cu_context_record_on_list( local_dealloc_cu_context(dbg,cu_context); return res; } - /* Add the new cu_context to a list of contexts */ + /* Add the new cu_context to a list of contexts + Never returns DW_DLV_NO_ENTRY */ icres = insert_into_cu_context_list(dis,cu_context); if (icres == DW_DLV_ERROR) { + /* Correcting ossfuzz70721 DW202407-010 */ + dwarf_dealloc_die(*cudie_return); + *cudie_return = 0; local_dealloc_cu_context(dbg,cu_context); _dwarf_error_string(dbg,error,DW_DLE_DIE_NO_CU_CONTEXT, "DW_DLE_DIE_NO_CU_CONTEXT" @@ -2004,9 +2038,6 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, dbg,dis,is_info,section_size,new_offset, &cu_context,&local_cudie,error); if (res != DW_DLV_OK) { - if (local_cudie) { - dwarf_dealloc_die(local_cudie); - } return res; } } @@ -2318,13 +2349,13 @@ dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off *offset) /* This function does two slightly different things depending on the input flag want_AT_sibling. If - this flag is true, it checks if the input die has + this flag is TRUE, it checks if the input die has a DW_AT_sibling attribute. If it does it returns a pointer to the start of the sibling die in the .debug_info section. Otherwise it behaves the - same as the want_AT_sibling false case. + same as the want_AT_sibling FALSE case. - If the want_AT_sibling flag is false, it returns + If the want_AT_sibling flag is FALSE, it returns a pointer to the immediately adjacent die in the .debug_info section. @@ -2335,11 +2366,11 @@ dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off *offset) to the start of the .debug_info portion for the current cu, and is used to add to the offset for DW_AT_sibling attributes. Finally, has_die_child - is a pointer to a Dwarf_Bool that is set true if - the present die has children, false otherwise. - However, in case want_AT_child is true and the die + is a pointer to a Dwarf_Bool that is set TRUE if + the present die has children, FALSE otherwise. + However, in case want_AT_child is TRUE and the die has a DW_AT_sibling attribute *has_die_child is set - false to indicate that the children are being skipped. + FALSE to indicate that the children are being skipped. die_info_end points to the last byte+1 of the cu. */ static int @@ -2497,7 +2528,7 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, } /* Reset *has_die_child to indicate children skipped. */ - *has_die_child = false; + *has_die_child = FALSE; /* A value beyond die_info_end indicates an error. Exactly at die_info_end means 1-past-cu-end @@ -2640,7 +2671,7 @@ is_cu_tag(int t) is used to track the depth of children and sibling terminations encountered. Child_depth is incremented when a die has the Has-Child flag set unless the child happens to be a NULL die. - Child_depth is decremented when a die has Has-Child false, + Child_depth is decremented when a die has Has-Child FALSE, and the adjacent die is NULL. Algorithm returns when child_depth is 0. @@ -2669,7 +2700,7 @@ dwarf_siblingof_b(Dwarf_Debug dbg, } else { /* This is the pre-0.9.0 way, and is assuming that the 'dis' has the correct cu context. - Which might not be true if a caller + Which might not be TRUE if a caller used dwarf_next_cu_header_d() twice in a row before calling dwarf_siblingof_b(). Use dwarf_next_cu_header_e() instead of @@ -2783,7 +2814,7 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, } } else { /* Find sibling die. */ - Dwarf_Bool has_child = false; + Dwarf_Bool has_child = FALSE; Dwarf_Signed child_depth = 0; /* We cannot have a legal die unless debug_info @@ -2809,7 +2840,7 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, res2 = _dwarf_next_die_info_ptr(die_info_ptr, context, die_info_end, - cu_info_start, true, &has_child, + cu_info_start, TRUE, &has_child, &die_info_ptr2, error); if (res2 != DW_DLV_OK) { @@ -2884,7 +2915,7 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, if (die_info_ptr < die_info_end) { if ((*die_info_ptr) == 0 && has_child) { die_info_ptr++; - has_child = false; + has_child = FALSE; } } @@ -3080,7 +3111,7 @@ dwarf_child(Dwarf_Die die, res = _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context, die_info_end, - NULL, false, + NULL, FALSE, &has_die_child, &die_info_ptr2, error); diff --git a/src/lib/libdwarf/dwarf_fission_to_cu.c b/src/lib/libdwarf/dwarf_fission_to_cu.c index 3aaacc1..8e8e564 100644 --- a/src/lib/libdwarf/dwarf_fission_to_cu.c +++ b/src/lib/libdwarf/dwarf_fission_to_cu.c @@ -29,6 +29,7 @@ #include /* memset() */ #include /* free() */ +#include /* debugging printf */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" @@ -49,7 +50,8 @@ #include "dwarf_rnglists.h" /* ASSERT: dbg,cu_context, and fsd are non-NULL - as the caller ensured that. */ + as the caller ensured that. + With no DW_AT_loclists_base this computes one. */ const struct Dwarf_Loclists_Context_s localcontxt_zero; static int load_xu_loclists_into_cucontext(Dwarf_Debug dbg, @@ -83,7 +85,7 @@ load_xu_loclists_into_cucontext(Dwarf_Debug dbg, /* Something is badly wrong. Ignore it here. */ return DW_DLV_NO_ENTRY; } - res = _dwarf_internal_read_loclists_header(dbg, + res = _dwarf_internal_read_loclists_header(dbg, FALSE, 0,soff_size, dbg->de_debug_loclists.dss_data, dbg->de_debug_loclists.dss_data +soff_size, @@ -223,7 +225,9 @@ load_xu_debug_macro_into_cucontext(Dwarf_Debug dbg, } /* ASSERT: dbg,cu_context, and fsd are non-NULL - as the caller ensured that. */ + as the caller ensured that. + With no DW_AT_rnglists_base present this + computes the value. */ const struct Dwarf_Rnglists_Context_s builddata_zero; static int load_xu_rnglists_into_cucontext(Dwarf_Debug dbg, @@ -257,7 +261,7 @@ load_xu_rnglists_into_cucontext(Dwarf_Debug dbg, return DW_DLV_NO_ENTRY; } memset(buildhere,0,sizeof(builddata)); - res = _dwarf_internal_read_rnglists_header(dbg, + res = _dwarf_internal_read_rnglists_header(dbg, TRUE, 0,soff_size, dbg->de_debug_rnglists.dss_data, dbg->de_debug_rnglists.dss_data+soff_size, @@ -290,7 +294,10 @@ static const char *keylist[2] = { _dwarf_merge_all_base_attrs_of_cu_die() if there is a tied (executable) object known. (not all base attrs are merged from tied. Certainly not - .debug_rnglists or .debug_loclists. + .debug_rnglists or .debug_loclists, but here we + load correct table information + for the CU being read as a replacement + if a CU has no base attr for rnglists and/or loclists) Called by dwarf_die_deliv.c */ @@ -341,11 +348,17 @@ _dwarf_find_all_offsets_via_fission(Dwarf_Debug dbg, case DW_SECT_ABBREV: case DW_SECT_LINE: */ + case DW_SECT_LOCLISTS: res = load_xu_loclists_into_cucontext(dbg, cu_context, fsd,sec_index,error); break; + case DW_SECT_RNGLISTS: + res = load_xu_rnglists_into_cucontext(dbg, + cu_context, + fsd,sec_index,error); + break; case DW_SECT_STR_OFFSETS: res = load_xu_str_offsets_into_cucontext(dbg, cu_context, @@ -356,11 +369,6 @@ _dwarf_find_all_offsets_via_fission(Dwarf_Debug dbg, cu_context, fsd,sec_index,error); break; - case DW_SECT_RNGLISTS: - res = load_xu_rnglists_into_cucontext(dbg, - cu_context, - fsd,sec_index,error); - break; default: res = DW_DLV_OK; break; diff --git a/src/lib/libdwarf/dwarf_frame.c b/src/lib/libdwarf/dwarf_frame.c index ae34aed..76b8323 100644 --- a/src/lib/libdwarf/dwarf_frame.c +++ b/src/lib/libdwarf/dwarf_frame.c @@ -233,8 +233,8 @@ dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg, If successful, returns DW_DLV_OK And sets returned_count thru the pointer - if make_instr is true. - If make_instr is false returned_count + if make_instr is TRUE. + If make_instr is FALSE returned_count should NOT be used by the caller (returned_count is set to 0 thru the pointer by this routine...) If unsuccessful, returns DW_DLV_ERROR @@ -243,16 +243,16 @@ dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg, It does not do a whole lot of input validation being a private function. Please make sure inputs are valid. - (1) If make_instr is true, it makes a list of pointers to + (1) If make_instr is TRUE, it makes a list of pointers to Dwarf_Frame_Op structures containing the frame instructions executed. A pointer to this list is returned in ret_frame_instr. - Make_instr is true only when a list of frame instructions is to be + Make_instr is TRUE only when a list of frame instructions is to be returned. In this case since we are not interested in the contents of the table, the input Cie can be NULL. This is the only case where the input Cie can be NULL. - (2) If search_pc is true, frame instructions are executed till + (2) If search_pc is TRUE, frame instructions are executed till either a location is reached that is greater than the search_pc_val provided, or all instructions are executed. At this point the @@ -263,14 +263,14 @@ dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg, defined by a Cie. In this case, the Dwarf_Cie pointer cie, is NULL. For an FDE, however, cie points to the associated Cie. - (4) If search_pc is true and (has_more_rows and subsequent_pc + (4) If search_pc is TRUE and (has_more_rows and subsequent_pc are non-null) then: - has_more_rows is set true if there are instruction + has_more_rows is set TRUE if there are instruction bytes following the detection of search_over. If all the instruction bytes have been seen - then *has_more_rows is set false. + then *has_more_rows is set FALSE. - If *has_more_rows is true then *subsequent_pc + If *has_more_rows is TRUE then *subsequent_pc is set to the pc value that is the following row in the table. @@ -395,9 +395,9 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, struct Dwarf_Reg_Rule_s cfa_reg; /* This is used to end executing frame instructions. */ - /* Becomes true when search_pc is true and current_loc */ + /* Becomes TRUE when search_pc is TRUE and current_loc */ /* is greater than search_pc_val. */ - Dwarf_Bool search_over = false; + Dwarf_Bool search_over = FALSE; Dwarf_Addr possible_subsequent_pc = 0; @@ -411,7 +411,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Frame stack_table = NULL; Dwarf_Frame top_stack = NULL; - /* These are used only when make_instr is true. Curr_instr is a + /* These are used only when make_instr is TRUE. Curr_instr is a pointer to the current frame instruction executed. Curr_instr_ptr, head_instr_list, and curr_instr_list are used to form a chain of Dwarf_Frame_Op structs. @@ -441,7 +441,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, using an alignment factor is encountered when this flag is set, an error is returned because the Cie did not have a valid augmentation. */ - Dwarf_Bool need_augmentation = false; + Dwarf_Bool need_augmentation = FALSE; Dwarf_Unsigned instr_area_length = 0; Dwarf_Unsigned i = 0; @@ -1792,14 +1792,14 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, so we are not done with rows. */ if ((instr_ptr == final_instr_ptr) && !search_over) { if (has_more_rows) { - *has_more_rows = false; + *has_more_rows = FALSE; } if (subsequent_pc) { *subsequent_pc = 0; } } else { if (has_more_rows) { - *has_more_rows = true; + *has_more_rows = TRUE; } if (subsequent_pc) { *subsequent_pc = possible_subsequent_pc; @@ -1968,7 +1968,7 @@ dwarf_get_cie_index( definition of the cie_id in an fde is the distance back from the address of the value to the cie. - Or 0 if this is a true cie. + Or 0 if this is a TRUE cie. Non standard dwarf, designed this way to be convenient at run time for an allocated (mapped into memory as part of the running image) section. @@ -2409,8 +2409,8 @@ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, dbg->de_frame_rule_initial_value); _dwarf_init_reg_rules_ru(&cie->ci_initial_table->fr_cfa_rule, 0,1,dbg->de_frame_rule_initial_value); - res = _dwarf_exec_frame_instr( /* make_instr= */ false, - /* search_pc */ false, + res = _dwarf_exec_frame_instr( /* make_instr= */ FALSE, + /* search_pc */ FALSE, /* search_pc_val */ 0, /* location */ 0, instrstart, @@ -2435,8 +2435,8 @@ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } - res = _dwarf_exec_frame_instr( /* make_instr= */ false, - /* search_pc */ true, + res = _dwarf_exec_frame_instr( /* make_instr= */ FALSE, + /* search_pc */ TRUE, /* search_pc_val */ pc_requested, fde->fd_initial_location, fde->fd_fde_instr_start, @@ -2671,7 +2671,7 @@ dwarf_get_fde_info_for_reg3_c(Dwarf_Fde fde, fde->fd_fde_pc_requested != pc_requested) { if (fde->fd_have_fde_tab) { _dwarf_free_fde_table(fde_table); - fde->fd_have_fde_tab = false; + fde->fd_have_fde_tab = FALSE; } table_real_data_size = dbg->de_frame_reg_rules_entry_count; res = _dwarf_initialize_fde_table(dbg, fde_table, @@ -2681,7 +2681,7 @@ dwarf_get_fde_info_for_reg3_c(Dwarf_Fde fde, } if (table_column >= table_real_data_size) { _dwarf_free_fde_table(fde_table); - fde->fd_have_fde_tab = false; + fde->fd_have_fde_tab = FALSE; _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return DW_DLV_ERROR; } @@ -2695,7 +2695,7 @@ dwarf_get_fde_info_for_reg3_c(Dwarf_Fde fde, error); if (res != DW_DLV_OK) { _dwarf_free_fde_table(fde_table); - fde->fd_have_fde_tab = false; + fde->fd_have_fde_tab = FALSE; return res; } } @@ -2717,7 +2717,7 @@ dwarf_get_fde_info_for_reg3_c(Dwarf_Fde fde, so we insist on it being present, we don't test it. */ *value_type = fde_table->fr_reg[table_column].ru_value_type; *offset_relevant = (fde_table->fr_reg[table_column].ru_is_offset); - fde->fd_have_fde_tab = true; + fde->fd_have_fde_tab = TRUE; fde->fd_fde_pc_requested = pc_requested; return DW_DLV_OK; @@ -2977,8 +2977,8 @@ dwarf_expand_frame_instructions(Dwarf_Cie cie, _dwarf_error(dbg, error,DW_DLE_FDE_INSTR_PTR_ERROR); return DW_DLV_ERROR; } - res = _dwarf_exec_frame_instr( /* make_instr= */ true, - /* search_pc */ false, + res = _dwarf_exec_frame_instr( /* make_instr= */ TRUE, + /* search_pc */ FALSE, /* search_pc_val */ 0, /* location */ 0, instr_start, @@ -3369,7 +3369,7 @@ init_reg_rules_alloc(Dwarf_Debug dbg,struct Dwarf_Frame_s *f, { f->fr_reg_count = count; f->fr_reg = (struct Dwarf_Reg_Rule_s *) - calloc(sizeof(struct Dwarf_Reg_Rule_s), (size_t)count); + calloc((size_t)count, sizeof(struct Dwarf_Reg_Rule_s)); if (f->fr_reg == 0) { if (error) { _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL); @@ -3440,7 +3440,7 @@ _dwarf_fde_destructor(void *f) } if (fde->fd_have_fde_tab) { _dwarf_free_fde_table(&fde->fd_fde_table); - fde->fd_have_fde_tab = false; + fde->fd_have_fde_tab = FALSE; } } void diff --git a/src/lib/libdwarf/dwarf_generic_init.c b/src/lib/libdwarf/dwarf_generic_init.c index 14d07f6..3ff8778 100644 --- a/src/lib/libdwarf/dwarf_generic_init.c +++ b/src/lib/libdwarf/dwarf_generic_init.c @@ -327,7 +327,7 @@ dwarf_init_path_dl_a(const char *path, } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); - dbg->de_ftype = ftype; + dbg->de_ftype = (Dwarf_Small)ftype; *ret_dbg = dbg; return res; } @@ -344,7 +344,7 @@ dwarf_init_path_dl_a(const char *path, } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); - dbg->de_ftype = ftype; + dbg->de_ftype = (Dwarf_Small)ftype; *ret_dbg = dbg; return res; } @@ -359,7 +359,7 @@ dwarf_init_path_dl_a(const char *path, } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); - dbg->de_ftype = ftype; + dbg->de_ftype = (Dwarf_Small)ftype; *ret_dbg = dbg; return res; } diff --git a/src/lib/libdwarf/dwarf_global.c b/src/lib/libdwarf/dwarf_global.c index 70fd82f..2481c60 100644 --- a/src/lib/libdwarf/dwarf_global.c +++ b/src/lib/libdwarf/dwarf_global.c @@ -1514,7 +1514,7 @@ dwarf_global_name_offsets(Dwarf_Global global, return DW_DLV_ERROR; } #endif /* 0 */ - cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,true, + cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,TRUE, &headerlen,error); if (cres != DW_DLV_OK) { return cres; diff --git a/src/lib/libdwarf/dwarf_gnu_index.c b/src/lib/libdwarf/dwarf_gnu_index.c index ff1129a..7a069e4 100644 --- a/src/lib/libdwarf/dwarf_gnu_index.c +++ b/src/lib/libdwarf/dwarf_gnu_index.c @@ -465,7 +465,7 @@ fill_in_blocks(Dwarf_Gnu_Index_Head head, see dwarf_util.h */ gib->ib_index = i; gib->ib_head = head; - gib->ib_offset_size = offsetsize; + gib->ib_offset_size = (Dwarf_Half)offsetsize; gib->ib_block_length = length; gib->ib_block_length_offset = dataoffset; dataoffset += offsetsize + extensize; @@ -780,7 +780,7 @@ dwarf_get_gnu_index_block_entry(Dwarf_Gnu_Index_Head head, /* DW_GNUIKIND_ */ unsigned v = be->ge_flag_byte & 0x70; v = v>>4; - *typeofentry = v; + *typeofentry = (unsigned char)v; } return DW_DLV_OK; } diff --git a/src/lib/libdwarf/dwarf_harmless.c b/src/lib/libdwarf/dwarf_harmless.c index 678924f..f97a817 100644 --- a/src/lib/libdwarf/dwarf_harmless.c +++ b/src/lib/libdwarf/dwarf_harmless.c @@ -217,8 +217,7 @@ _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(sizeof(char *), - dhp->dh_maxcount); + dhp->dh_errors = (char **)calloc(dhp->dh_maxcount, sizeof(char *)); if (!dhp->dh_errors) { dhp->dh_maxcount = 0; return; @@ -226,8 +225,7 @@ _dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size) for (i = 0; i < dhp->dh_maxcount; ++i) { char *newstr = - (char *)calloc(1, - DW_HARMLESS_ERROR_MSG_STRING_SIZE); + (char *)calloc(1, DW_HARMLESS_ERROR_MSG_STRING_SIZE); dhp->dh_errors[i] = newstr; #if 0 /* Commentary about avoiding leak */ /* BAD IDEA. just use the NULL pointer, diff --git a/src/lib/libdwarf/dwarf_init_finish.c b/src/lib/libdwarf/dwarf_init_finish.c index be66bf0..fa8caf8 100644 --- a/src/lib/libdwarf/dwarf_init_finish.c +++ b/src/lib/libdwarf/dwarf_init_finish.c @@ -107,7 +107,7 @@ int dwarf_set_reloc_application(int apply) { int oldval = _dwarf_apply_relocs; - _dwarf_apply_relocs = apply; + _dwarf_apply_relocs = (Dwarf_Small)apply; return oldval; } @@ -116,7 +116,7 @@ dwarf_set_stringcheck(int newval) { int oldval = _dwarf_assume_string_in_bounds; - _dwarf_assume_string_in_bounds = newval; + _dwarf_assume_string_in_bounds = (Dwarf_Small)newval; return oldval; } @@ -178,7 +178,7 @@ add_relx_data_to_secdata( struct Dwarf_Section_s *secdata, secdata->dss_reloc_addr = doas->as_addr; secdata->dss_reloc_symtab = doas->as_link; secdata->dss_reloc_link = doas->as_link; - secdata->dss_is_rela = is_rela; + secdata->dss_is_rela = (char)is_rela; } #if 0 /* dump_bytes */ diff --git a/src/lib/libdwarf/dwarf_line.c b/src/lib/libdwarf/dwarf_line.c index f8cf38b..a372c97 100644 --- a/src/lib/libdwarf/dwarf_line.c +++ b/src/lib/libdwarf/dwarf_line.c @@ -60,11 +60,11 @@ static struct Dwarf_Line_Registers_s /* Dwarf_Unsigned lr_file */ 1, /* Dwarf_Unsigned lr_line */ 1, /* Dwarf_Unsigned lr_column */ 0, - /* Dwarf_Bool lr_is_stmt */ false, - /* Dwarf_Bool lr_basic_block */ false, - /* Dwarf_Bool lr_end_sequence */ false, - /* Dwarf_Bool lr_prologue_end */ false, - /* Dwarf_Bool lr_epilogue_begin */ false, + /* Dwarf_Bool lr_is_stmt */ FALSE, + /* Dwarf_Bool lr_basic_block */ FALSE, + /* Dwarf_Bool lr_end_sequence */ FALSE, + /* Dwarf_Bool lr_prologue_end */ FALSE, + /* Dwarf_Bool lr_epilogue_begin */ FALSE, /* Dwarf_Small lr_isa */ 0, /* Dwarf_Unsigned lr_op_index */ 0, /* Dwarf_Unsigned lr_discriminator */ 0, @@ -607,7 +607,7 @@ dwarf_srcfiles(Dwarf_Die die, _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } - line_context->lc_new_style_access = false; + line_context->lc_new_style_access = FALSE; /* We are in dwarf_srcfiles() */ { Dwarf_Small *line_ptr_out = 0; @@ -825,7 +825,7 @@ _dwarf_internal_srclines(Dwarf_Die die, return DW_DLV_NO_ENTRY; } - address_size = _dwarf_get_address_size(dbg, die); + address_size = (Dwarf_Half)_dwarf_get_address_size(dbg, die); resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); if (resattr != DW_DLV_OK) { @@ -895,7 +895,8 @@ _dwarf_internal_srclines(Dwarf_Die die, _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } - line_context->lc_new_style_access = is_new_interface; + line_context->lc_new_style_access = + (unsigned char)is_new_interface; line_context->lc_compilation_directory = comp_dir; /* We are in dwarf_internal_srclines() */ { @@ -939,8 +940,8 @@ _dwarf_internal_srclines(Dwarf_Die die, /* ASSERT: lc_table_count == 1 or lc_table_count == 0 */ int err_count_out = 0; /* Normal style (single level) line table. */ - Dwarf_Bool is_actuals_table = false; - Dwarf_Bool local_is_single_table = true; + Dwarf_Bool is_actuals_table = FALSE; + Dwarf_Bool local_is_single_table = TRUE; res = read_line_table_program(dbg, line_ptr, line_ptr_end, orig_line_ptr, section_start, @@ -980,11 +981,11 @@ _dwarf_internal_srclines(Dwarf_Die die, *linecount_actuals = 0; } } else { - Dwarf_Bool is_actuals_table = false; - Dwarf_Bool local2_is_single_table = false; + Dwarf_Bool is_actuals_table = FALSE; + Dwarf_Bool local2_is_single_table = FALSE; int err_count_out = 0; - line_context->lc_is_single_table = false; + line_context->lc_is_single_table = FALSE; /* Two-level line table. First read the logicals table. */ res = read_line_table_program(dbg, @@ -1021,7 +1022,7 @@ _dwarf_internal_srclines(Dwarf_Die die, } if (is_new_interface) { /* ASSERT: linebuf_actuals == NULL */ - is_actuals_table = true; + is_actuals_table = TRUE; /* The call requested an actuals table and one is present. So now read that one. */ res = read_line_table_program(dbg, @@ -1193,7 +1194,7 @@ dwarf_srclines_b(Dwarf_Die die, Dwarf_Line *linebuf = 0; Dwarf_Line *linebuf_actuals = 0; Dwarf_Signed linecount = 0; - Dwarf_Bool is_new_interface = true; + Dwarf_Bool is_new_interface = TRUE; int res = 0; Dwarf_Unsigned tcount = 0; @@ -1206,11 +1207,11 @@ dwarf_srclines_b(Dwarf_Die die, &linecount, &linebuf_actuals, &linecount_actuals, - /* addrlist= */ false, - /* linelist= */ true, + /* addrlist= */ FALSE, + /* linelist= */ TRUE, error); if (res == DW_DLV_OK) { - (*line_context)->lc_new_style_access = true; + (*line_context)->lc_new_style_access = TRUE; } if (linecount_actuals) { tcount++; diff --git a/src/lib/libdwarf/dwarf_line_table_reader_common.h b/src/lib/libdwarf/dwarf_line_table_reader_common.h index 3cba430..b843859 100644 --- a/src/lib/libdwarf/dwarf_line_table_reader_common.h +++ b/src/lib/libdwarf/dwarf_line_table_reader_common.h @@ -229,8 +229,8 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, err, section_length,section_end); line_ptr_end = line_ptr + total_length; line_context->lc_line_ptr_end = line_ptr_end; - line_context->lc_length_field_length = local_length_size + - local_extension_size; + line_context->lc_length_field_length = + (Dwarf_Half)(local_length_size + local_extension_size); line_context->lc_section_offset = starting_line_ptr - dbg->de_debug_line.dss_data; /* ASSERT: line_context->lc_length_field_length == line_ptr @@ -382,7 +382,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, unsigned tab_count = sizeof(dwarf_standard_opcode_operand_count); - int operand_ck_fail = true; + int operand_ck_fail = TRUE; if (line_context->lc_std_op_count > tab_count) { _dwarf_print_header_issue(dbg, "Too many standard operands in linetable header: ", @@ -450,7 +450,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, 0,0,0, err_count_out); } } - operand_ck_fail = false; + operand_ck_fail = FALSE; } } if (operand_ck_fail) { @@ -1363,7 +1363,7 @@ read_line_table_program(Dwarf_Debug dbg, Dwarf_Small *section_start, Dwarf_Line_Context line_context, Dwarf_Half address_size, - Dwarf_Bool doaddrs, /* Only true if SGI IRIX rqs calling. */ + Dwarf_Bool doaddrs, /* Only TRUE if SGI IRIX rqs calling. */ Dwarf_Bool dolines, Dwarf_Bool is_single_table, Dwarf_Bool is_actuals_table, @@ -1409,7 +1409,7 @@ read_line_table_program(Dwarf_Debug dbg, Dwarf_Line *block_line = 0; /* Mark a line record as being DW_LNS_set_address */ - Dwarf_Bool is_addr_set = false; + Dwarf_Bool is_addr_set = FALSE; (void)orig_line_ptr; (void)err_count_out; @@ -1585,7 +1585,7 @@ read_line_table_program(Dwarf_Debug dbg, /* Mark a line record as being DW_LNS_set_address */ curr_line->li_l_data.li_is_addr_set = is_addr_set; - is_addr_set = false; + is_addr_set = FALSE; curr_line->li_address = regs.lr_address; curr_line->li_l_data.li_file = (Dwarf_Signed) regs.lr_file; @@ -1632,9 +1632,9 @@ read_line_table_program(Dwarf_Debug dbg, curr_line = 0; } - regs.lr_basic_block = false; - regs.lr_prologue_end = false; - regs.lr_epilogue_begin = false; + regs.lr_basic_block = FALSE; + regs.lr_prologue_end = FALSE; + regs.lr_epilogue_begin = FALSE; regs.lr_discriminator = 0; #ifdef PRINTING_DETAILS #endif /* PRINTING_DETAILS */ @@ -1665,7 +1665,7 @@ read_line_table_program(Dwarf_Debug dbg, /* Mark a line record as DW_LNS_set_address */ curr_line->li_l_data.li_is_addr_set = is_addr_set; - is_addr_set = false; + is_addr_set = FALSE; curr_line->li_address = regs.lr_address; curr_line->li_l_data.li_file = @@ -1712,9 +1712,9 @@ read_line_table_program(Dwarf_Debug dbg, curr_line = 0; } - regs.lr_basic_block = false; - regs.lr_prologue_end = false; - regs.lr_epilogue_begin = false; + regs.lr_basic_block = FALSE; + regs.lr_prologue_end = FALSE; + regs.lr_epilogue_begin = FALSE; regs.lr_discriminator = 0; } break; @@ -1903,7 +1903,7 @@ read_line_table_program(Dwarf_Debug dbg, } break; case DW_LNS_set_basic_block:{ - regs.lr_basic_block = true; + regs.lr_basic_block = TRUE; #ifdef PRINTING_DETAILS _dwarf_printf(dbg, "DW_LNS_set_basic_block\n"); @@ -2018,12 +2018,12 @@ read_line_table_program(Dwarf_Debug dbg, /* New in DWARF3 */ case DW_LNS_set_prologue_end:{ - regs.lr_prologue_end = true; + regs.lr_prologue_end = TRUE; } break; /* New in DWARF3 */ case DW_LNS_set_epilogue_begin:{ - regs.lr_epilogue_begin = true; + regs.lr_epilogue_begin = TRUE; #ifdef PRINTING_DETAILS _dwarf_printf(dbg, "DW_LNS_set_prologue_end set true.\n"); @@ -2395,7 +2395,7 @@ read_line_table_program(Dwarf_Debug dbg, switch (ext_opcode) { case DW_LNE_end_sequence:{ - regs.lr_end_sequence = true; + regs.lr_end_sequence = TRUE; if (dolines) { curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); @@ -2481,7 +2481,7 @@ read_line_table_program(Dwarf_Debug dbg, } /* Mark a line record as being DW_LNS_set_address */ - is_addr_set = true; + is_addr_set = TRUE; #ifdef PRINTING_DETAILS { dwarfstring sadd; @@ -2508,7 +2508,7 @@ read_line_table_program(Dwarf_Debug dbg, DW_LNS_set_address */ curr_line->li_l_data.li_is_addr_set = is_addr_set; - is_addr_set = false; + is_addr_set = FALSE; curr_line->li_address = regs.lr_address; #ifdef __sgi /* SGI IRIX ONLY */ /* ptrdiff_t is generated but not named */ diff --git a/src/lib/libdwarf/dwarf_loc.c b/src/lib/libdwarf/dwarf_loc.c index cdf3eef..eaa299f 100644 --- a/src/lib/libdwarf/dwarf_loc.c +++ b/src/lib/libdwarf/dwarf_loc.c @@ -1054,13 +1054,13 @@ _dwarf_original_loclist_build(Dwarf_Debug dbg, if (lkind == DW_LKIND_GNU_exp_list) { count_res = _dwarf_get_loclist_lle_count_dwo(dbg, loclist_offset, - address_size, - lkind, + (Dwarf_Half)address_size, + (Dwarf_Half)lkind, &loclist_count, error); } else { count_res = _dwarf_get_loclist_lle_count(dbg, - loclist_offset, address_size, + loclist_offset, (Dwarf_Half)address_size, &loclist_count, error); } diff --git a/src/lib/libdwarf/dwarf_loc.h b/src/lib/libdwarf/dwarf_loc.h index b167a51..e0915f6 100644 --- a/src/lib/libdwarf/dwarf_loc.h +++ b/src/lib/libdwarf/dwarf_loc.h @@ -238,6 +238,7 @@ int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error*error); int _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, + Dwarf_Bool temporary, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, diff --git a/src/lib/libdwarf/dwarf_loclists.c b/src/lib/libdwarf/dwarf_loclists.c index df37da5..3b2cf47 100644 --- a/src/lib/libdwarf/dwarf_loclists.c +++ b/src/lib/libdwarf/dwarf_loclists.c @@ -360,6 +360,7 @@ read_single_lle_entry(Dwarf_Debug dbg, allocations here. */ int _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, + Dwarf_Bool build_offset_array, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, @@ -379,7 +380,6 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned localoff = 0; Dwarf_Unsigned lists_len = 0; - Dwarf_Unsigned tabentrynum = 0; READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, data,offset_size,exten_size, @@ -469,29 +469,34 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, localoff = data - startdata; if (offset_entry_count) { buildhere->lc_offsets_array = data; - buildhere->lc_offset_value_array = (Dwarf_Unsigned *) - calloc(offset_entry_count, sizeof(Dwarf_Unsigned)); - if (!buildhere->lc_offset_value_array) { - _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL, - "dbg,DW_DLE_ALLOC_CAIL: " - " The debug_loclists offset table " - "cannot be allocated."); - return DW_DLV_ERROR; - } - for (tabentrynum = 0 ; tabentrynum < offset_entry_count; - data += SIZEOFT32,++tabentrynum ) { - Dwarf_Unsigned entry = 0; - int res = 0; + lists_len += offset_size*offset_entry_count; + if (build_offset_array) { + Dwarf_Unsigned tabentrynum = 0; - res = _dwarf_read_unaligned_ck_wrapper(dbg, - &entry,data,SIZEOFT32,end_data,error); - if (res != DW_DLV_OK) { - free(buildhere->lc_offset_value_array); - buildhere->lc_offset_value_array = 0; - return res; + buildhere->lc_offset_value_array = (Dwarf_Unsigned *) + calloc(offset_entry_count, sizeof(Dwarf_Unsigned)); + if (!buildhere->lc_offset_value_array) { + _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL, + "dbg,DW_DLE_ALLOC_CAIL: " + " The debug_loclists offset table " + "cannot be allocated."); + return DW_DLV_ERROR; + } + for (tabentrynum = 0 ; tabentrynum < offset_entry_count; + data += offset_size,++tabentrynum ) { + Dwarf_Unsigned entry = 0; + int res = 0; + + res = _dwarf_read_unaligned_ck_wrapper(dbg, + &entry,data,offset_size,end_data,error); + if (res != DW_DLV_OK) { + free(buildhere->lc_offset_value_array); + buildhere->lc_offset_value_array = 0; + return res; + } + buildhere->lc_offset_value_array[tabentrynum] = + entry; } - buildhere->lc_offset_value_array[tabentrynum] = entry; - lists_len += SIZEOFT32; } } /* else no offset table */ @@ -544,7 +549,7 @@ internal_load_loclists_contexts(Dwarf_Debug dbg, return DW_DLV_ERROR; } memset(newcontext,0,sizeof(*newcontext)); - res = _dwarf_internal_read_loclists_header(dbg, + res = _dwarf_internal_read_loclists_header(dbg, TRUE, chainlength, section_size, data,end_data,offset, @@ -1376,7 +1381,7 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, return DW_DLV_OK; } -#if 0 /* candiate??? for public api. No, not usable. */ +#if 0 /* candidate for public api?. No, not usable. */ int dwarf_get_loclists_entry_fields( Dwarf_Loc_Head_c head, diff --git a/src/lib/libdwarf/dwarf_loclists.h b/src/lib/libdwarf/dwarf_loclists.h index 96f60d3..7882bce 100644 --- a/src/lib/libdwarf/dwarf_loclists.h +++ b/src/lib/libdwarf/dwarf_loclists.h @@ -1,7 +1,7 @@ /* Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Rese rved. Portions Copyright (C) 2015-2023 David Anderson. All Rights Rese rved. - + This program is free software; you can redistribute it and/or modify it under the terms of version 2.1 of the GNU Lesser General Public License as published by the Free @@ -28,7 +28,8 @@ Floor, Boston MA 02110-1301, USA. /* Dwarf_Loclists_Context_s contains the data from the .debug_loclists - section headers (if that section exists). Dwarf 2,3,4 .debug_loc + section headers (if that section exists). + Dwarf 2,3,4 .debug_loc has no such data. The array (one of these per header in .debug_loclists) is recorded in Dwarf_Debug. These are filled in at startup at the same time .debug_info @@ -58,9 +59,9 @@ struct Dwarf_Loclists_Context_s { Dwarf_Small lc_segment_selector_size; Dwarf_Half lc_version; /* 5 */ Dwarf_Unsigned lc_offset_entry_count; - /* lc_offset_entry_count values. Each local offset to + /* lc_offset_entry_count values. Each local offset to a locdesc set. We need this as a way to know - which lle entry offsets are relevant from a loclistx. + which lle entry offsets are relevant from a loclistx. as nothing else reveals these special LLE entries. */ Dwarf_Unsigned *lc_offset_value_array; diff --git a/src/lib/libdwarf/dwarf_machoread.c b/src/lib/libdwarf/dwarf_machoread.c index fada0c6..55cc3da 100644 --- a/src/lib/libdwarf/dwarf_machoread.c +++ b/src/lib/libdwarf/dwarf_machoread.c @@ -83,13 +83,31 @@ dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; + int ct = 0; printf("%s (0x%lx) ",msg,(unsigned long)start); for (; cur < end; cur++) { printf("%02x", *cur); + ct++; + if (ct %4 == 0) { + printf(" "); + } } printf("\n"); } #endif /*0*/ +#if 0 /* print_arch_item debugging */ +static void +print_arch_item(unsigned int i, + struct Dwarf_Universal_Arch_s* arch) +{ + printf(" Universal Binary Index %u\n",i); + printf(" cpu 0x%x\n",(unsigned)arch->au_cputype); + printf(" cpusubt 0x%x\n",(unsigned)arch->au_cpusubtype); + printf(" offset 0x%x\n",(unsigned)arch->au_offset); + printf(" size 0x%x\n",(unsigned)arch->au_size); + printf(" align 0x%x\n",(unsigned)arch->au_align); +} +#endif /* MACH-O and dwarf section names */ static struct macho_sect_names_s { @@ -521,8 +539,8 @@ _dwarf_macho_load_segment_commands( } mfp->mo_segment_commands = (struct generic_macho_segment_command *) - calloc(sizeof(struct generic_macho_segment_command), - (size_t)mfp->mo_segment_count); + calloc((size_t)mfp->mo_segment_count, + sizeof(struct generic_macho_segment_command)); if (!mfp->mo_segment_commands) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; @@ -567,8 +585,8 @@ _dwarf_macho_load_dwarf_section_details32( struct generic_macho_section *secs = 0; secs = (struct generic_macho_section *)calloc( - sizeof(struct generic_macho_section), - (size_t)secalloc); + (size_t)secalloc, + sizeof(struct generic_macho_section)); if (!secs) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_OK; @@ -648,8 +666,8 @@ _dwarf_macho_load_dwarf_section_details64( struct generic_macho_section *secs = 0; secs = (struct generic_macho_section *)calloc( - sizeof(struct generic_macho_section), - (size_t)secalloc); + (size_t)secalloc, + sizeof(struct generic_macho_section)); if (!secs) { *errcode = DW_DLE_ALLOC_FAIL; return DW_DLV_ERROR; @@ -900,6 +918,7 @@ _dwarf_macho_setup(int fd, return res; } +/* Initialize the methods needed to read Macho object files. */ static Dwarf_Obj_Access_Methods_a const macho_methods = { macho_get_section_info, macho_get_byte_order, @@ -1148,6 +1167,9 @@ magic_copy(unsigned char *d, unsigned len) return v; } +/* fa points to fat arch in object-file format + duhd points to space to fill in (in au_rches) data + for each macho object in the fat object. */ static int fill_in_uni_arch_32( struct fat_arch * fa, @@ -1299,6 +1321,7 @@ _dwarf_object_detector_universal_head_fd( } if (locoffsetsize == 32) { struct fat_arch * fa = 0; + fa = (struct fat_arch *)calloc(duhd.au_count, sizeof(struct fat_arch)); if (!fa) { @@ -1384,20 +1407,6 @@ _dwarf_object_detector_universal_head_fd( return DW_DLV_OK; } -#if 0 /* print_arch_item debugging */ -static void -print_arch_item(unsigned int i, - struct Dwarf_Universal_Arch_s* arch) -{ - printf(" Universal Binary Index " LONGESTUFMT "\n",i); - printf(" cpu " LONGESTXFMT "\n",arch->au_cputype); - printf(" cpusubt " LONGESTXFMT "\n",arch->au_cpusubtype); - printf(" offset " LONGESTXFMT "\n",arch->au_offset); - printf(" size " LONGESTXFMT "\n",arch->au_size); - printf(" align " LONGESTXFMT "\n",arch->au_align); -} -#endif - int _dwarf_object_detector_universal_instance( Dwarf_Universal_Head dw_head, diff --git a/src/lib/libdwarf/dwarf_opaque.h b/src/lib/libdwarf/dwarf_opaque.h index d99a4d3..52a469b 100644 --- a/src/lib/libdwarf/dwarf_opaque.h +++ b/src/lib/libdwarf/dwarf_opaque.h @@ -242,6 +242,7 @@ struct Dwarf_CU_Context_s { /* cc_cu_die_offset_present is non-zero if cc_cu_die_global_sec_offset is meaningful. */ Dwarf_Bool cc_cu_die_offset_present; + Dwarf_Bool cc_at_ranges_offset_present; /* If present, is base address of CU. In DWARF2 nothing says what attribute is the base address. @@ -263,10 +264,13 @@ struct Dwarf_CU_Context_s { Dwarf_Unsigned cc_line_base; /*DW5 */ Dwarf_Unsigned cc_line_base_contr_size; /*DW5 */ - /* From DW_AT_loclists_base or DW_SECT_LOCLISTS */ + /* From DW_AT_loclists_base or + computed from DW_SECT_LOCLISTS */ Dwarf_Unsigned cc_loclists_base; Dwarf_Unsigned cc_loclists_base_contr_size; Dwarf_Bool cc_loclists_base_present; + /* via_at means there was a DW_AT_loclists_base */ + Dwarf_Bool cc_loclists_base_via_at; Dwarf_Bool cc_loclists_header_length_present; /* ======= str_offsets table data =======*/ @@ -306,6 +310,8 @@ struct Dwarf_CU_Context_s { Dwarf_Bool cc_macro_base_present; Dwarf_Bool cc_macro_header_length_present; + /* For quick access to .debug_ranges from a CU DIE. */ + Dwarf_Unsigned cc_at_ranges_offset; /* DW_SECT_RNGLISTS */ /* DW_AT_GNU_ranges_base was a GNU extension that appeared but was unused. See dwarf_die_deliv.c for details. */ @@ -316,6 +322,8 @@ struct Dwarf_CU_Context_s { Dwarf_Unsigned cc_rnglists_base; /*DW5 */ Dwarf_Unsigned cc_rnglists_base_contr_size; /*DW5 */ Dwarf_Bool cc_rnglists_base_present; /* DW5 */ + /* via_at means there was a DW_AT_rnglists_base */ + Dwarf_Bool cc_rnglists_base_via_at; Dwarf_Bool cc_rnglists_header_length_present; char * cc_dwo_name; diff --git a/src/lib/libdwarf/dwarf_print_lines.c b/src/lib/libdwarf/dwarf_print_lines.c index a986bc9..1d76c9d 100644 --- a/src/lib/libdwarf/dwarf_print_lines.c +++ b/src/lib/libdwarf/dwarf_print_lines.c @@ -915,14 +915,14 @@ print_actuals_and_locals(Dwarf_Debug dbg, dwarfstring_reset(&m8); { - Dwarf_Bool doaddrs = false; - Dwarf_Bool dolines = true; + Dwarf_Bool doaddrs = FALSE; + Dwarf_Bool dolines = TRUE; if (!line_ptr_actuals) { /* Normal single level line table. */ - Dwarf_Bool is_single_table = true; - Dwarf_Bool is_actuals_table = false; + Dwarf_Bool is_single_table = TRUE; + Dwarf_Bool is_actuals_table = FALSE; print_line_header(dbg, is_single_table, is_actuals_table); res = read_line_table_program(dbg, line_ptr, line_ptr_end, orig_line_ptr, @@ -939,8 +939,8 @@ print_actuals_and_locals(Dwarf_Debug dbg, return res; } } else { - Dwarf_Bool is_single_table = false; - Dwarf_Bool is_actuals_table = false; + Dwarf_Bool is_single_table = FALSE; + Dwarf_Bool is_actuals_table = FALSE; if (line_context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) { dwarf_srclines_dealloc_b(line_context); @@ -964,7 +964,7 @@ print_actuals_and_locals(Dwarf_Debug dbg, return res; } if (line_context->lc_actuals_table_offset > 0) { - is_actuals_table = true; + is_actuals_table = TRUE; /* Read Actuals */ print_line_header(dbg, is_single_table, diff --git a/src/lib/libdwarf/dwarf_query.c b/src/lib/libdwarf/dwarf_query.c index 1076e9d..98dfa4f 100644 --- a/src/lib/libdwarf/dwarf_query.c +++ b/src/lib/libdwarf/dwarf_query.c @@ -858,6 +858,7 @@ dwarf_diename(Dwarf_Die die, return dwarf_die_text(die,DW_AT_name,ret_name,error); } +/* Never returns DW_DLV_NO_ENTRY */ int dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, @@ -876,10 +877,10 @@ dwarf_hasattr(Dwarf_Die die, return res; } if (res == DW_DLV_NO_ENTRY) { - *return_bool = false; - return DW_DLV_OK; + *return_bool = FALSE; + } else { + *return_bool = TRUE; } - *return_bool = (true); return DW_DLV_OK; } @@ -1243,6 +1244,8 @@ dwarf_dietype_offset(Dwarf_Die die, return res; } +/* Only a few values are inherited from the tied + file. Not rnglists or loclists base offsets. */ int _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, Dwarf_CU_Context context, @@ -1283,6 +1286,13 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, context-> cc_addr_base= tiedcontext->cc_addr_base; } + if (context->cc_version_stamp == DW_CU_VERSION4 && + !context->cc_ranges_base_present) { + context->cc_ranges_base_present = + tiedcontext->cc_ranges_base_present; + context->cc_ranges_base = + tiedcontext->cc_ranges_base;; + } if (!context->cc_str_offsets_tab_present) { context-> cc_str_offsets_tab_present = tiedcontext->cc_str_offsets_tab_present; @@ -2070,7 +2080,8 @@ _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context) is_info is always non-zero except if the section of the CU is DWARF4 .debug_types. */ -int dwarf_cu_header_basics(Dwarf_Die die, +int +dwarf_cu_header_basics(Dwarf_Die die, Dwarf_Half *version, Dwarf_Bool *is_info, Dwarf_Bool *is_dwo, diff --git a/src/lib/libdwarf/dwarf_ranges.c b/src/lib/libdwarf/dwarf_ranges.c index d186de6..1f18c7e 100644 --- a/src/lib/libdwarf/dwarf_ranges.c +++ b/src/lib/libdwarf/dwarf_ranges.c @@ -30,6 +30,7 @@ #include #include /* calloc() free() */ +#include /* printf debugging */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" @@ -109,7 +110,7 @@ read_unaligned_addr_check(Dwarf_Debug dbg, int dwarf_get_ranges_b(Dwarf_Debug dbg, Dwarf_Off rangesoffset, Dwarf_Die die, - Dwarf_Off *actual_offset, + Dwarf_Off *actual_offset /* in .debug_ranges */, Dwarf_Ranges ** rangesbuf, Dwarf_Signed * listlen, Dwarf_Unsigned * bytecount, @@ -127,20 +128,22 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg, Dwarf_Half address_size = 0; int res = DW_DLV_ERROR; Dwarf_Unsigned ranges_base = 0; - Dwarf_Debug localdbg = dbg; - Dwarf_Error localerror = 0; - Dwarf_Half die_version = 3; /* default for dwarf_get_ranges() */ + Dwarf_Debug localdbg = dbg; + Dwarf_Error localerror = 0; + + /* default for dwarf_get_ranges() */ + Dwarf_Half die_version = 3; + Dwarf_Half offset_size= 4; Dwarf_CU_Context cucontext = 0; - Dwarf_Bool rangeslocal = TRUE; - (void)offset_size; CHECK_DBG(dbg,error,"dwarf_get_ranges_b()"); address_size = localdbg->de_pointer_size; /* default */ if (die) { - /* 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. + /* printing by raw offset from DW_AT_ranges attribute. + 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. Add err code if error. Version comes from the cu context, not the DIE itself. */ res = dwarf_get_version_of_die(die,&die_version, @@ -160,10 +163,22 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg, http://llvm.1065342.n5.nabble.com/DebugInfo\ -DW-AT-GNU-ranges-base-in-non-fission-\ td64194.html + HOWEVER: in dw4 GNU fission extension + it is used and matters. */ - /* ranges_base was merged from tied context. */ - ranges_base = cucontext->cc_ranges_base; + /* ranges_base was merged from tied context. + Otherwise it is zero. But not if + the current die is the skeleton */ + if (cucontext->cc_unit_type != DW_UT_skeleton) { + ranges_base = cucontext->cc_ranges_base; + } + rangesoffset += ranges_base; address_size = cucontext->cc_address_size; + } else { + /* Printing by raw offset + The caller will use the bytecount to + increment to the next part of .debug_ranges + and will call again with the next offset */ } localdbg = dbg; @@ -187,7 +202,6 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg, if (res == DW_DLV_NO_ENTRY) { return res; } - rangeslocal = FALSE; } /* Be safe in case adding rangesoffset and rangebase @@ -212,8 +226,7 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg, dwarfstring_destructor(&m); return DW_DLV_ERROR; } - if (!rangeslocal && ((rangesoffset +ranges_base) >= - localdbg->de_debug_ranges.dss_size)) { + if (rangesoffset >= localdbg->de_debug_ranges.dss_size) { dwarfstring m; dwarfstring_constructor(&m); @@ -235,11 +248,12 @@ 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. */ - rangesoffset += ranges_base; } +#endif rangeptr += rangesoffset; beginrangeptr = rangeptr; @@ -264,7 +278,7 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg, dwarfstring_destructor(&m); return DW_DLV_ERROR; } - re = calloc(sizeof(struct ranges_entry),1); + re = calloc(1, sizeof(struct ranges_entry)); if (!re) { free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); @@ -351,3 +365,177 @@ dwarf_dealloc_ranges(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf, (void)rangecount; dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES); } + +static int +_dwarf_determine_die_range_offset(Dwarf_Debug dw_dbg, + Dwarf_Die dw_die, + Dwarf_Bool *have_die_ranges_offset, + Dwarf_Unsigned *die_ranges_offset, + Dwarf_Bool *have_die_base_addr, + Dwarf_Unsigned *die_base_addr, + 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; + + res = dwarf_hasattr(dw_die,DW_AT_ranges, &hasatranges,dw_error); + if (res != DW_DLV_OK) { + return res; + } + if (!hasatranges) { + /* Give up, this die not directly relevant. */ + return res; + } + res = dwarf_attr(dw_die,DW_AT_ranges,&attr,dw_error); + if (res != DW_DLV_OK) { + if (res == DW_DLV_ERROR) { + dwarf_dealloc_error(dw_dbg,*dw_error); + *dw_error = 0; + } + return res; + } else { + res = dwarf_global_formref(attr, + &rangeoffset_local, dw_error); + if (res != DW_DLV_OK) { + if (res == DW_DLV_ERROR) { + dwarf_dealloc_attribute(attr); + dwarf_dealloc_error(dw_dbg,*dw_error); + *dw_error = 0; + return res; + } + } + /* rangeoffset_local was set . */ + } + 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; +} + +/* Must not ever return DW_DLV_NO_ENTRY. + Uses cu_context sometimes, so the base address + is from the CU_DIE of the CU that + dw_die is a child of. + We attempt to cover what compilers actually do + in the GNU dwarf4 extensions, but rules are not + fully documented and it is difficult to be + sure what is fully correct. */ +int +dwarf_get_ranges_baseaddress(Dwarf_Debug dw_dbg, + Dwarf_Die dw_die, + Dwarf_Bool *dw_known_base, + Dwarf_Unsigned *dw_baseaddress, + Dwarf_Bool *dw_at_ranges_offset_present, + Dwarf_Unsigned *dw_at_ranges_offset, + Dwarf_Error *dw_error) +{ + 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; + Dwarf_Unsigned die_base_addr = 0; + int res = 0; + + CHECK_DBG(dw_dbg,dw_error,"dwarf_get_ranges_baseaddress()"); + if (!dw_die) { + if (dw_known_base) { + *dw_known_base = FALSE; + *dw_at_ranges_offset_present = FALSE; + } + if (dw_baseaddress) { + *dw_baseaddress = 0; + *dw_at_ranges_offset = 0; + } + return DW_DLV_OK; + } + /* If the DIE passed in has a DW_AT_ranges attribute + we will use that DIE ranges offset. + Otherwise we use the DW_AT_ranges from the + CU DIE (if any) + If the DIE passed in has a DW_AT_low_pc + attribute we will use that as the ranges + base address, otherwise we use the + cu context base adddress (if present) ... + which may be incorrect... ? */ + res = _dwarf_determine_die_range_offset(dw_dbg, + dw_die,&have_die_ranges_offset,&die_ranges_offset, + &have_die_base_addr,&die_base_addr,dw_error); + if (res != DW_DLV_OK ) { + if (res == DW_DLV_ERROR) { + /* Suppressing knowledge of any error */ + dwarf_dealloc_error(dw_dbg,*dw_error); + *dw_error = 0; + } + } + + context = dw_die->di_cu_context; + if (!context) { + _dwarf_error_string(dw_dbg, dw_error, + DW_DLE_DIE_NO_CU_CONTEXT, + "DW_DLE_DIE_NO_CU_CONTEXT: in a call to " + "dwarf_get_ranges_baseaddress"); + return DW_DLV_ERROR; + } + if (have_die_ranges_offset) { + local_ranges_offset_present = have_die_ranges_offset; + local_ranges_offset = die_ranges_offset; + } else { + local_ranges_offset_present = + context->cc_at_ranges_offset_present; + local_ranges_offset = + context->cc_at_ranges_offset; + } + if (dw_at_ranges_offset) { + *dw_at_ranges_offset = local_ranges_offset; + } + 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; + } + return DW_DLV_OK; +} diff --git a/src/lib/libdwarf/dwarf_rnglists.c b/src/lib/libdwarf/dwarf_rnglists.c index 2256a17..e579004 100644 --- a/src/lib/libdwarf/dwarf_rnglists.c +++ b/src/lib/libdwarf/dwarf_rnglists.c @@ -97,7 +97,7 @@ dump_rh(const char *msg, printf(" Rnglists Context: %p",(void *)head->rh_localcontext); } #endif -#if 0 +#if 0 /* debug print struct */ static void dump_rc(const char *msg, int line, @@ -164,6 +164,17 @@ _dwarf_implicit_rnglists_base(Dwarf_Debug dbg, return DW_DLV_OK; } +static void +free_rnglists_context(Dwarf_Rnglists_Context cx) +{ + if (cx) { + free(cx->rc_offset_value_array); + cx->rc_offset_value_array = 0; + cx->rc_magic = 0; + free(cx); + } +} + /* Used in case of error reading the rnglists headers (not referring to Dwarf_Rnglists_Head here), to clean up. */ @@ -173,14 +184,16 @@ free_rnglists_chain(Dwarf_Debug dbg, Dwarf_Chain head) Dwarf_Chain cur = head; Dwarf_Chain next = 0; - if (!head) { + if (!head || IS_INVALID_DBG(dbg)) { return; } for ( ;cur; cur = next) { next = cur->ch_next; if (cur->ch_item) { /* ch_item is Dwarf_Rnglists_Context */ - free(cur->ch_item); + Dwarf_Rnglists_Context cx = + (Dwarf_Rnglists_Context)cur->ch_item; + free_rnglists_context(cx); cur->ch_item = 0; dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); } @@ -323,6 +336,7 @@ read_single_rle_entry(Dwarf_Debug dbg, allocations here. */ int _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, + Dwarf_Bool build_offset_array, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, Dwarf_Small *data, @@ -343,6 +357,7 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, Dwarf_Unsigned localoff = 0; Dwarf_Unsigned lists_len = 0; Dwarf_Unsigned secsize_dbg = 0; + Dwarf_Unsigned sum_size = 0; secsize_dbg = dbg->de_debug_rnglists.dss_size; /* Sanity checks */ @@ -361,25 +376,15 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, dwarfstring_destructor(&m); return DW_DLV_ERROR; } - if (sectionlength > secsize_dbg) { - dwarfstring m; - dwarfstring_constructor(&m); - dwarfstring_append(&m, - "DW_DLE_RNGLISTS_ERROR: " - " section_length argument mismatch vs. .debug_rnglists" - " section length including header."); - _dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; - } buildhere->rc_startaddr = data; READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, data,offset_size,exten_size, error, sectionlength,end_data); + sum_size = arealen+offset_size+exten_size; if (arealen > sectionlength || - (arealen+offset_size+exten_size) > sectionlength) { + sum_size < arealen || + sum_size > sectionlength) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, @@ -395,7 +400,6 @@ _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_dbg = dbg; @@ -474,10 +478,51 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, buildhere->rc_offset_entry_count = offset_entry_count; data += SIZEOFT32; localoff+= SIZEOFT32; + if (offset_entry_count > (arealen/offset_size)) { + dwarfstring m; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + " DW_DLE_RNGLISTS_ERROR: .debug_rnglists" + " offset entry size impossibly large " + " with size 0x%x", + offset_entry_count*offset_size); + _dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } if (offset_entry_count ){ buildhere->rc_offsets_array = data; - } - lists_len = offset_size *offset_entry_count; + lists_len += offset_size*offset_entry_count; + if (build_offset_array) { + Dwarf_Unsigned tabentrynum = 0; + + buildhere->rc_offset_value_array = (Dwarf_Unsigned *) + calloc(offset_entry_count, sizeof(Dwarf_Unsigned)); + if (!buildhere->rc_offset_value_array) { + _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL, + "dbg,DW_DLE_ALLOC_CAIL: " + " The debug_rnglists offset table " + "cannot be allocated."); + return DW_DLV_ERROR; + } + for (tabentrynum = 0 ; tabentrynum < offset_entry_count; + data += offset_size,++tabentrynum ) { + Dwarf_Unsigned entry = 0; + int res = 0; + + res = _dwarf_read_unaligned_ck_wrapper(dbg, + &entry,data,offset_size,end_data,error); + if (res != DW_DLV_OK) { + free(buildhere->rc_offset_value_array); + buildhere->rc_offset_value_array = 0; + return res; + } + buildhere->rc_offset_value_array[tabentrynum] = + entry; + } + } + } /* else no offset table */ if (offset_entry_count >= secsize_dbg || lists_len >= secsize_dbg) { dwarfstring m; @@ -569,13 +614,13 @@ internal_load_rnglists_contexts(Dwarf_Debug dbg, } memset(newcontext,0,sizeof(*newcontext)); newcontext->rc_magic = RNGLISTS_MAGIC; - res = _dwarf_internal_read_rnglists_header(dbg, + res = _dwarf_internal_read_rnglists_header(dbg, TRUE, chainlength, section_size, data,end_data,offset, newcontext,&nextoffset,error); if (res == DW_DLV_ERROR) { - free(newcontext); + free_rnglists_context(newcontext); newcontext = 0; free_rnglists_chain(dbg,head_chain); return res; @@ -587,7 +632,7 @@ internal_load_rnglists_contexts(Dwarf_Debug dbg, _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: allocating Rnglists_Context" " chain entry"); - free(newcontext); + free_rnglists_context(newcontext); newcontext = 0; free_rnglists_chain(dbg,head_chain); return DW_DLV_ERROR; @@ -693,10 +738,7 @@ _dwarf_dealloc_rnglists_context(Dwarf_Debug dbg) rngcon = dbg->de_rnglists_context; for ( ; i < dbg->de_rnglists_context_count; ++i) { Dwarf_Rnglists_Context con = rngcon[i]; - con->rc_offsets_array = 0; - con->rc_magic = 0; - con->rc_offset_entry_count = 0; - free(con); + free_rnglists_context(con); rngcon[i] = 0; } free(dbg->de_rnglists_context); diff --git a/src/lib/libdwarf/dwarf_rnglists.h b/src/lib/libdwarf/dwarf_rnglists.h index 10db0a8..d2a1ec1 100644 --- a/src/lib/libdwarf/dwarf_rnglists.h +++ b/src/lib/libdwarf/dwarf_rnglists.h @@ -71,6 +71,11 @@ struct Dwarf_Rnglists_Context_s { index values in the array are offsets into area starting with rc_first_rnglist_offset */ Dwarf_Unsigned rc_offset_entry_count; + /* rc_offset_entry_count values. Each local offset to + a locdesc set. We need this as a way to know + which lle entry offsets are relevant from a loclistx. + as nothing else reveals these special LLE entries. */ + Dwarf_Unsigned *rc_offset_value_array; /* offset in the section of the offset entries */ Dwarf_Unsigned rc_offsets_off_in_sect; @@ -151,14 +156,15 @@ struct Dwarf_Rnglists_Head_s { }; int _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, + Dwarf_Bool build_offsets_array, Dwarf_Unsigned contextnum, Dwarf_Unsigned sectionlength, - Dwarf_Small *data, - Dwarf_Small *end_data, + Dwarf_Small *data, + Dwarf_Small *end_data, Dwarf_Unsigned offset, Dwarf_Rnglists_Context buildhere, Dwarf_Unsigned *next_offset, - Dwarf_Error *error); + Dwarf_Error *error); void _dwarf_rnglists_head_destructor(void *m); diff --git a/src/lib/libdwarf/dwarf_setup_sections.c b/src/lib/libdwarf/dwarf_setup_sections.c index f2065de..0015af6 100644 --- a/src/lib/libdwarf/dwarf_setup_sections.c +++ b/src/lib/libdwarf/dwarf_setup_sections.c @@ -87,7 +87,8 @@ add_debug_section_info(Dwarf_Debug dbg, secdata->dss_name = name; /* Actual name from object file. */ secdata->dss_standard_name = standard_section_name; secdata->dss_number = obj_sec_num; - secdata->dss_zdebug_requires_decompress = havezdebug; + secdata->dss_zdebug_requires_decompress = + (Dwarf_Small)havezdebug; /* We don't yet know about SHF_COMPRESSED */ debug_section->ds_duperr = duperr; debug_section->ds_emptyerr = emptyerr; diff --git a/src/lib/libdwarf/dwarf_tied.c b/src/lib/libdwarf/dwarf_tied.c index 6286fec..ad96aaf 100644 --- a/src/lib/libdwarf/dwarf_tied.c +++ b/src/lib/libdwarf/dwarf_tied.c @@ -49,7 +49,7 @@ #include "dwarf_tsearch.h" #include "dwarf_tied_decls.h" -#if 0 +#if 0 /*debug dumpsignature */ void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) { diff --git a/src/lib/libdwarf/dwarf_tsearchhash.c b/src/lib/libdwarf/dwarf_tsearchhash.c index 89476ae..0119173 100644 --- a/src/lib/libdwarf/dwarf_tsearchhash.c +++ b/src/lib/libdwarf/dwarf_tsearchhash.c @@ -190,7 +190,7 @@ dwarf_initialize_search_hash( void **treeptr, /* initialized already. */ return base ; } - base = calloc(sizeof(struct hs_base),1); + base = calloc(1, sizeof(struct hs_base)); if (!base) { /* Out of memory. */ return NULL ; @@ -223,7 +223,7 @@ 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(sizeof(struct ts_entry),base->tablesize_); + base->hashtab_ = calloc(base->tablesize_, sizeof(struct ts_entry)); if (!base->hashtab_) { free(base); return NULL; @@ -368,8 +368,7 @@ resize_table(struct hs_base *head, return; } newhead.tablesize_entry_index_ = new_entry_index; - newhead.hashtab_ = calloc(sizeof(struct ts_entry), - newhead.tablesize_); + 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. */ diff --git a/src/lib/libdwarf/libdwarf.h b/src/lib/libdwarf/libdwarf.h index 0a9d8ae..e925100 100644 --- a/src/lib/libdwarf/libdwarf.h +++ b/src/lib/libdwarf/libdwarf.h @@ -99,10 +99,10 @@ extern "C" { */ /* Semantic Version identity for this libdwarf.h */ -#define DW_LIBDWARF_VERSION "0.10.1" +#define DW_LIBDWARF_VERSION "0.11.0" #define DW_LIBDWARF_VERSION_MAJOR 0 -#define DW_LIBDWARF_VERSION_MINOR 10 -#define DW_LIBDWARF_VERSION_MICRO 1 +#define DW_LIBDWARF_VERSION_MINOR 11 +#define DW_LIBDWARF_VERSION_MICRO 0 #define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_basic 1 @@ -211,12 +211,22 @@ typedef void* Dwarf_Ptr; /* host machine pointer */ /*! @defgroup enums Enumerators with various purposes @{ @enum Dwarf_Ranges_Entry_Type - The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY) - or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or - both are zero (DW_RANGES_END). - For DWARF5 each table starts with a header - followed by range list entries defined - as here. + The dwr_addr1/addr2 data is either pair of offsets + of a base pc address (DW_RANGES_ENTRY) + or a base pc address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or + both are zero(end of list, DW_RANGES_END) + or both non-zero but identical + (means an empty range, DW_RANGES_ENTRY). + These are for use with DWARF 2,3,4. + + DW_RANGES_ADDRESS_SELECTION should have been spelled + DW_RANGES_BASE_ADDRESS. but it is not worth changing + as it is widely used. + + The DW_RANGES_ENTRY values are raw pc offset data recorded + in the section, not addresses. + @see examplev + Dwarf_Ranges* apply to DWARF2,3, and 4. Not to DWARF5 (the data is different and in a new DWARF5 section). @@ -448,6 +458,13 @@ typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; Details of of non-contiguous address ranges of DIEs for DWARF2, DWARF3, and DWARF4. Sufficient for older dwarf. + + dwr_addr1 and dwr_addr2 in the struct are + offsets from a base address in the CU involved. + To calculate actual range pc addresses see + the example: + + @see examplev */ typedef struct Dwarf_Ranges_s { Dwarf_Addr dwr_addr1; @@ -2533,7 +2550,7 @@ DW_API int dwarf_validate_die_sibling(Dwarf_Die dw_sibling, DW_AT_name for example. @param dw_returned_bool On success is set TRUE if dw_die has - dw_attrnum. + dw_attrnum and FALSE otherwise. @param dw_error The usual error detail return pointer. @return @@ -4235,9 +4252,12 @@ DW_API struct Dwarf_Printf_Callback_Info_s Pass in the DIE whose DW_AT_ranges brought us to ranges. @param dw_return_realoffset The actual offset in the section actually read. - In a tieddbg this + In a tieddbg dwp DWARF4 extension object + the base offset is added to dw_rangesoffset and returned here. @param dw_rangesbuf A pointer to an array of structs is returned here. + The struct contents are the raw values in the + section. @param dw_rangecount The count of structs in the array is returned here. @param dw_bytecount @@ -4270,6 +4290,54 @@ DW_API int dwarf_get_ranges_b(Dwarf_Debug dw_dbg, DW_API void dwarf_dealloc_ranges(Dwarf_Debug dw_dbg, Dwarf_Ranges * dw_rangesbuf, Dwarf_Signed dw_rangecount); + +/*! @brief Find ranges base address + + The function allows callers to calculate + actual address from .debug_ranges data + in a simple and efficient way. + + @param dw_dbg + The Dwarf_Debug of interest. + @param dw_die + Pass in any non-null valid Dwarf_Die + to find the applicable .debug_ranges + base address. The dw_die need not + be a CU-DIE. + A null dw_die is allowed. + @param dw_known_base + if dw_die is non-null and there is a known + base address for the CU DIE that + (a DW_at_low_pc in the CU DIE) + dw_known_base will be set TRUE, + Otherwise the value FALSE will be returned through + dw_known_base. + @param dw_baseaddress + if dw_known_base is retured as TRUE then + dw_baseaddress will be set with the correct pc value. + Otherwise zero will be set through dw_baseaddress. + @param dw_at_ranges_offset_present + Set to 1 (TRUE) if the dw_die has the attribute + DW_AT_ranges, otherwise set to zero (FALSE). + @param dw_at_ranges_offset + Set to the value of dw_die DW_AT_ranges attribute + of dw_die if and only iff + dw_at_ranges_offset_present was set to 1. + @param dw_error + The usual error detail return pointer. + @return + Returns DW_DLV_OK or DW_DLV_ERROR. + Never returns DW_DLV_NO_ENTRY. + +*/ +DW_API int dwarf_get_ranges_baseaddress(Dwarf_Debug dw_dbg, + Dwarf_Die dw_die, + Dwarf_Bool *dw_known_base, + Dwarf_Unsigned *dw_baseaddress, + Dwarf_Bool *dw_at_ranges_offset_present, + Dwarf_Unsigned *dw_at_ranges_offset, + Dwarf_Error *dw_error); + /*! @} */ /*! @defgroup rnglists Rnglists: code addresses in DWARF5