diff --git a/thirdparty/dwarf/CMakeLists.txt b/thirdparty/dwarf/CMakeLists.txt index b9e15816..1fc076dc 100644 --- a/thirdparty/dwarf/CMakeLists.txt +++ b/thirdparty/dwarf/CMakeLists.txt @@ -2,31 +2,29 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-pointer-to-int-cast -Wno-int-to-pointe add_library (dwarf STATIC dwarf_abbrev.c - dwarf_addr_finder.c dwarf_alloc.c dwarf_arange.c dwarf_die_deliv.c + dwarf_dsc.c + dwarf_dnames.c dwarf_error.c dwarf_form.c dwarf_frame.c dwarf_frame2.c - dwarf_frame3.c dwarf_funcs.c dwarf_global.c + dwarf_groups.c dwarf_harmless.c dwarf_init_finish.c dwarf_leb.c dwarf_line.c - dwarf_line2.c dwarf_loc.c - #dwarf_loc2.c dwarf_macro.c dwarf_macro5.c dwarf_print_lines.c dwarf_pubtypes.c dwarf_query.c dwarf_ranges.c - dwarf_sort_line.c dwarf_string.c dwarf_stubs.c dwarf_tied.c diff --git a/thirdparty/dwarf/ChangeLog b/thirdparty/dwarf/ChangeLog index 98760782..60a171d5 100644 --- a/thirdparty/dwarf/ChangeLog +++ b/thirdparty/dwarf/ChangeLog @@ -1,522 +1,588 @@ -2016-06-13 David Anderson - * dwarf_alloc.c: Dwarf_Fde_s now has a destructor. - * dwarf_frame.c,dwarf_frame.h: Now dwarf_get_fde_info_for_reg3 memoizes - frame data making one pattern of use (from dwarfdump) - much much faster. -2016-06-13 David Anderson - * dwarf_frame.c: Revised some local assignments so - we are sure the same value used as intended. - Added some {} on if for consistency with libdwarf use. - * gennames.c: Update version string. -2016-06-12 David Anderson - * libdwarf/gennames.c: Update version string. -2016-06-12 David Anderson - * dwarf_frame.c: Adding dwarf_get_fde_info_for_cfa_reg3_b() - which lets dwarfdump print frame data a bit more quickly. - It is unclear whether other applications will find this - new interface to be of value. - * dwarf_frame.h,dwarf_frame3.c: Internal interfaces changed slightly - to allow the new function to work. - * libdwarf.h.in: Added dwarf_get_fde_info_for_cfa_reg3_b() - declaration. - * libdwarf2.1.mm: Documents dwarf_get_fde_info_for_cfa_reg3_b(). - Rev.2.50 - * libdwarf2.1.pdf: Regenerated. -2016-06-08 David Anderson - * dwarf_init_finish.c, dwarf_line_table_reader_common.c: Remove - trailing whitespace. Fix one indent. -2016-06-08 David Anderson - * gennames.c: Update version string. -2016-06-07 David Anderson - * Makefile.in: Use $(SONAME) rather than libdwarf.so.1 whereever - possible. -2016-06-01 David Anderson - * Makefile.in: Tweaks for debian build compatibility. - * gennames.c: Use DW_VERSION_DATE_STR instead of __DATE__ __TIME__ -2016-05-23 David Anderson - * dwarf_errmsg_list.c, libdwarf.h.in: Added - DW_DLE_COMPRESSED_EMPTY_SECTION. - * dwarf_init_finish.c: If load_section gets - DW_DLV_NO_ENTRY just return that. - If requres-decompress but has no data call it - a corrupt Elf section (given what sections - libdwarf is interested in). - * dwarf_line_table_reader_common.c: Only - deal with line table format entries if the - count is > 0. -2016-05-23 David Anderson - * Makefile.in: add SONAME libdwarf.so.1 to dynamic section when - building shared libdwarf.so - We have not made an incompatible interface change since - May 19, 2014 (and that was to the producer code not to - what DWARF readers use). -2016-05-22 David Anderson - * libdwarf.h.in, dwarf_errmsg_list.c: Adding - DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH error code. - Fixed unsigned/signed comparison warning in the table test code. - * dwarf_line.c: If we find a null pointer from include directores - we substitute "" for the - reader. - * dwarf_line_table_reader_common.c: Detect a corrupted DWARF5 - directory count vs directory format count problem and return - an error. -2016-05-20 David Anderson - * dwarf_macro5.c: Was failing to initialize - mc_cu_context leading to coredump. - If dwarf_srcfiles() returned zero as the count - of source files an erroneous calloc() would result in an - objection from valgrind: an erroneous calloc of zero bytes - of srcfiles pointers would never be freed. -2016-05-19 David Anderson - * Makefile.in: HOST_CFLAGS now references CFLAGS - at the request of the Debian project. - * configure.in: Now defaults to -fPIC always - (though in a nonshared build one could reasonably - turn it off with --disable-fpic) - Adds several messages reporting configure actions. - * configure: Regenerated. -2016-05-18 David Anderson - * dwarf_form.c: Directly check expression length against - section length in case expression length very very large. - * dwarf_query.c: _dwarf_calculate_info_section_*() routines - made clearer and the *_start_ptr() instance also now returns - the length (via a pointer arg). - * dwarf_xu_index.c: Check data read from the section so - a wildly large columns count or slots count will be caught - and an error returned. -2016-05-16 David Anderson - * dwarf_elf_access.c: Check more thoroughly for corrupt - relocation records and return an error if such found. - * dwarf_macro5.c: Remove trailing whitespace. -2016-05-10 David Anderson - * dwarf_arange.c,dwarf_die_deliv.c: All read operations check for overrun. - * dwarf_errmsg_list.c: DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE, - DW_DLE_LOCEXPR_OFF_SECTION_END, and DW_DLE_POINTER_SECTION_UNKNOWN - added to error values. - * dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_global.c,dwarf_line.c, - dwarf_line_table_reader_common.c,dwarf_loc.c,dwarf_loc2.c, - dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, - dwarf_ranges.c,dwarf_util.c, dwarf_xu_index.c: All read - operations check for overrun. - * dwarf_opaque.h: Put the 4 SGI-only section data - items next to each other to make it clear they - are such. - * dwarf_util.h: Added some checks to READ_AREA_LENGTH_CK - * libdwarf.h.in: Defined the new error names. -2016-05-07-b David Anderson - * libdwarf2.1.mm,libdwarf2p.1.mm: Fixed spelling errors. - * libdwarf2.1.pdf,libdwarf2p.1.pdf: Regenerated. -2016-05-07 David Anderson - * libdwarf.h.in, dwarf_errmsg_list.c: New error codes for - stopping due to corrupted frame data. - * dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c,dwarf_line.c: - Notice frame area overrun and generate error. -2016-05-06 David Anderson - * dwarf_errmsg_list.c: Added DW_DLE_ZLIB_SECTION_SHORT. - * dwarf_form.c: Now checking for section overrun. - * dwarf_init_finish.c: Now checking zlib reading - for section overrun. - * dwarf_macro5.c: Now checking for section overrun and - also fixing double delete caused by having - _dwarf_get_alloc() space pointing at other _dwarf_get_alloc() - space. Because in case of error the order of free - of such is unpredictable! - * dwarf_macro5.h: Added comment on mc_srcfiles member. - * libdwarf.h.in: Added DW_DLE_ZLIB_SECTION_SHORT. -2016-05-05 David Anderson - * dwarf_form.c: Add a test so that a really large form_block length - will not be considered safe (due to unsigned arithmetic - overflow). - Fixed the new check-code reading string offsets section - so the endpoint in the check is that section, not debug_info. - * dwarf_query.c: New function _dwarf_calculate_info_section_start_ptr() - helps in some checking. - * dwarf_util.h: Add a test so arithmetic overflow will not show - a bogus value as being ok. - * libdwarf.h.in,dwarf_errmsg_list.c: Add error code - DW_DLE_FORM_BLOCK_LENGTH_ERROR so we have a specific - error for this case. - * dwarf_line.c: %lld switched to "%" DW_PR_DSd - * dwarf_opaque.h: Added function declaration for - _dwarf_calculate_info_section_start_ptr(). -2016-05-04 David Anderson - * dwarf_macro5.c(construct_at_path_from_parts): Move 3 lines - of code up to test for NULL pointer. So we do not - dereference the pointer. -2016-05-03 David Anderson - * dwarf_die_deliv.c: Add checks for overrun of end of section - due to corrupted DWARF. - * dwarf_arange.c,dwarf_util.c: first use of READ_UNALIGNED_CK. - * dwarf_errmsg_list.c, libdwarf.h.in: DW_DLE_READ_LITTLEENDIAN_ERROR - and DW_DLE_READ_BIGENDIAN_ERROR are errors possible - in READ_UNALIGNED_CK. DW_DLE_LINE_OFFSET_WRONG_FORM gives - a more meaningful description of a particular corruption - problem (not a new test, just a new error name). - * dwarf_elf_access.c: Add a check on relocations to ensure - we do not write off the end of the section. - * dwarf_query.c: Using local variables for shorter lines. - * dwarf_util.h: Implement READ_UNALIGNED_CK macros. - * dwarf_leb.c: Improve a couple comments. - * dwarf_line.c: Now use DW_DLE_LINE_OFFSET_WRONG_FORM. - Add operandmismatch() to get better debug information - in case of corrupted dwarf. Revise the code for - clarity. - * dwarf_macro5.c: Duplicate free() could result if - dwarf_finish() was used to clean up from a dwarf macro - context. Two functions are really static so - the function type set properly now. -2016-04-30 David Anderson - * dwarf_frame.c, dwarf_line_table_reader_common.c, - dwarf_loc2.c: switch to using DECODE_LEB*_CK. - * dwarf_frame.c: Delete unused local variables. - Use DECODE_LEB*_CK for better error checking. - * dwarf_frame2.c, dwarf_frame.h: Internal functions get new - arguments to support DECODE_LEB*_CK. - * dwarf_arange.c: Using UNUSEDARG to suppress warning. - * dwarf_line_table_reader_common.c: Use DECODE_LEB*_CK - for better error checking. - * dwarf_loc2.c: Use DECODE_LEB*_CK - for better error checking. -2016-04-30 David Anderson - * dwarf_die_deliv.c: Deleted unused local variable. - * dwarf_form.c,dwarf_macro.c, dwarf_macro5.c: Now uses - DCODE_LEB128*_CK nearly everywhere - for better checking for corrupted data. - * dwarf_opaque.h:New argument to _dwarf_get_addr_index_itself() - for better data checks.. - * dwarf_query.c: Uses revised _dwarf_get_addr_index_itself() - interface. - * dwarf_util.c: Fixed formatting errors. -2016-04-29 David Anderson - * dwarf_line_table_reader_common.c, dwarf_macro.c, - dwarf_macro5.c, dwarf_util.c, dwarf_util.h: - Now use DECODE_LEB128_*CK macros simplifying - the code while catching errors/corruption in DWARF - data. -2016-04-28 David Anderson - * dwarf_die_deliv.c: Now _dwarf_next_die_info_ptr() has - a section length argument. - * dwarf_query.c, dwarf_util.c: Now uses the checked version - of leb reading. - * dwarf_util.h: Now _dwarf_get_size_of_val() has - section_end_ptr argument for checking leb values - do not overrun end of section. -2016-04-27 David Anderson - * dwarf_frame2.c: Now notices a frame-length field - which is too large to be meaningful and returns - an error.. -2016-04-27 David Anderson - * Makefile.in: Now dwarf_error.o dependency on - dwarf_errmsg_list.c is explicit. - * dwarf_errmsg_list.c: New error strings. - * libdwarf.h.in: New error values for when running off - end of section and line range and address size where - zero leads to trouble.. - * dwarf_abbrev.c,dwarf_die_deliv.c, dwarf_frame.c, - dwarf_frame.h, dwarf_frame2.c,dwarf_frame3.c,dwarf_leb.c, - dwarf_line.c, dwarf_line.h, dwarf_line_table_reader_common.c, - dwarf_query.c,dwarf_util.c,dwarf_util.h: - Add checks for running off end of section. -2016-04-26 David Anderson - * Makefile.in: The new errmsg_check dependency - line was a bit wrong. libdwarf.h should not have $(srcdir) -2016-04-25 David Anderson - * dwarf_errmsg_list.c: When -DTESTING ensure all the - error messages have a value in () so we can check - that value. -2016-04-25 David Anderson - * dwarf_tied.c: A C11-ism crept in. Fixed. - Added 'static' to local function declaration. - Removed unused local variable. - * dwarf_errmsg_list.c: Now checks that the number in () - matches the index (and still checks that the array size - is the declared size) when compiled -DTESTING. -2016-04-25 David Anderson - * dwarf_errmsg_list.c: Fixed indent mistakes. - * dwarf_leb.c: Fixed places were leb128_length - was assumed non-null (dwarf_form.c passes NULL!). -2016-04-25 David Anderson - * Makefile.in: Added testing of the _dwarf_errmsgs array. - * dwarf_error.c: Moved _dwarf_errmsgs out of dwarf_error.c into - dwarf_errmsg_list.c - * dwarf_errmsg_list.c: Now has error strings and test code. -2016-04-25 David Anderson - * dwarf_error.c: The error description - "DW_DLE_GDB_INDEX_INDEX_ERROR(264)" was missing the - comma so following errors were reporting the wrong string. -2016-04-21 Carlos Alberto Enciso - * Use the _WIN32 macro to identify a WINDOWS specific code. -2016-03-14 David Anderson - * dwarf_util.c: Changed 'byte' to 'byte pair' - in a comment. Where we read abbreviation AT/FORM lists. -2016-03-14 David Anderson - * dwarf_error.c(_dwarf_errno): Now prints to stdout and - does abort(1) when it has to give up. Instead of - using stderr and abort(). - It is not a good idea for applications to fail to provide - error handling, so no one should notice this change. - * libdwarf2.1.mm: Documents behavior in case there is no error - handling provided by our caller. - * libdwarf2.1.pdf: Regenerated. Rev 2.48. -2016-03-14 David Anderson - * libdwarf2.1.mm: Documents Dwarf_Handler error handler function. - * libdwarf2.1.pdf: Regenerated. Rev 2.47. -2016-03-13 David Anderson - * dwarf_query.c: Use dwarf_formstring to read string - attributes as it handles all the string types already. - Now dwarf_diename() and dwarf_die_text() call dwarf_formstring() - so DW_FORM_strp_sup and DW_FORM_GNU_strp_alt are - properly handled(along with all the other string FORMs). - * dwarf_form.c: Handle an error in dwarf_formstring() - (for tied files, or the lack thereof) - differently so it all works properly even if the incoming - error argument is null. -2016-03-12 David Anderson - * dwarf_abbrev.c: Uses renamed fields abbrev internal struct. - Removes some gratuitous (). Adds clarifying {} - * dwarf_abbrev.h: renames Dwarf_Abbrev_s struct fields - from ab_tag to dab_tag, etc. - Adds global section offset to the fields. - * dwarf_die_deliv.c: Uses renamed Abbrev_List fields. - Adds dwarf_die_abbrev_global_offset() function so - clients can properly identify where an abbrev entry is - in .debug_abbrev. - * dwarf_die_deliv.h: renames Dwarf_Abbrev_List - struct fields from ab_tag to abl_tag etc. - Adds abl_goffset, abl_count. - * dwarf_query.c,dwarf_util.c: Uses renamed Dwarf_Abbrev_List - fields. - * libdwarf.h.in: Adds function dwarf_die_abbrev_global_offset(). - * libdwarf2.1.mm: Documents dwarf_die_abbrev_global_offset(). - * libdwarf2.1.pdf: Regenerated. Rev 2.46. -2016-03-11 David Anderson - * dwarf_die_deliv.c: Fixed issues with handling NULL - Dwarf_Error* and with mistakes treating DW_DLV_NO_ENTRY - as if it were DW_DLV_ERROR. - * dwarf_form.c: Only do dwarf_errno(*error) when error is non-null. - * dwarf_macro5.c, dwarf_query.c, dwarf_ranges.c: Avoid the - possibility of - doing dwarf_errno(*error) when error is null. - * dwarf_util.c(_dwarf_error_mv_s_to_t): Added code to - ensure that nothing crash-worthy happens - even if a future internal caller calls it with one or more NULL - arguments. - * libdwarf2.1.mm: Added a few words about Error Handling in general - to clarify earlier wording (earlier wording was not as explicit - as it should have been). - * libdwarf2.1.pdf: Regenerated. Version 2.45 - * dwarf_sort_line.c: Though no longer built or used, added - an initializer to a local variable for correctness. - * dwarf_addr_finder.c: Though no longer compiled or used (is IRIX only), - cleaned up local variable declarations that were not - up to the current standard usage in libdwarf. -2016-03-11 David Anderson - * Makefile.in: Added a comment about pr and pdf-building. -2016-03-09 David Anderson - * libdwarf2.1.mm: Slightly altered the dwarf_offsets_list() documentation. - * libdwarf2.1.pdf: Rev 2.44. Regenerated. -2016-03-09 David Anderson - * dwarf_form.c: Correct and amplify a comment. -2016-03-01 David Anderson - * libdwarf2.1.mm: Documented dwarf_dietype() and - dwarf_offset_list(). - * libdwarf2.1.pdf: Regenerated. Rev 2.43 - * checkexamples.c: Added example for dwarf_offset_list(). -2016-02-19 Carlos Alberto Enciso - * dwarf_alloc.h, dwarf_alloc.c, dwarf_base_types.h, dwarf_opaque.h: - New allocator type (DW_DLA_CHAIN_2), to allow a list of addressed - types (address, offset). - There was Memory corruption due to incorrect usage of - memory allocator type. - * dwarf_query.c: Use the new allocator type. -2016-02-14 David Anderson - * libdwarf2.1.mm: dwarf_exprloc -> dwarf_formexprloc. - The spelling error was introduced in version 2.41. - * libdwarf2.1.pdf: Regenerated. Version 2.42 -2016-02-13 David Anderson - * libdwarf2.1.mm: Added dwarf_lineoff_b() documentation. - Fixed a typo in dwarf_formexprloc() documentation. - * libdwarf2.1.pdf: Regenerated. Version 2.41 - * Makefile.in: Add HOSTCFLAGS HOSTLDFLAGS HOSTCC to make - it easier to cross-compile. Remove common.c, common.h - (a few lines of code moved to gennames.c). - * README: document use of HOSTCC - * common.c,common.h: Delete. A few lines of code moved to gennames.c. - * configure.in: for AC_TRY_RUN add [],[] for else and for - cross-compile cases. - * configure: Regenerated. - * dwarf_die_deliv.c, dwarf_frame2.c, dwarf_line.c, - dwarf_macro5.c, dwarf_print_lines.c, dwarf_ranges.c: - Renamed to avoid shadowing variables with same name. - For clarity. - * gennames.c: Incorporates a few lines from common.c - so common.c, common.h can be deleted. -2016-02-10 David Anderson - * README: Improved a comment about Dwarf_Obj_Access_Methods. - * dwarf_elf_access.c: New function _dwarf_get_elf_flags_func() - extracts the sh_flags field from Elf sections. In an odd way - so we preserve binary and source compatibility.+ - * dwarf_error.c,libdwarf.h.in: New error DW_DLE_ELF_FLAGS_NOT_AVAILABLE. - * dwarf_init_finish.c: Use new (global) function pointer - _dwarf_get_elf_flags_func_ptr - to access extra Elf data without breaking compatibility. - Add additional way (SHF_COMPRESSED) to detect zlib - compression and expand the compressed data. -2016-02-08 David Anderson - * dwarf_alloc.c: Drop VALTYPE, use DW_TSHASHTYPE instead. - Use DW_TSHASHTYPE in the hash functions. - * dwarf_tied.c: Use DW_TSHASHTYPE in the hash function. - * dwarf_tsearchhash.c: Add back the UNUSEDARG to avoid - unused argument warnings. -2016-02-07 David Anderson - * dwarf_init_finish.c: Fix indents. remove a trailing space. - * dwarf_tsearch.h,dwarf_tsearchhash.c: Now DW_TSHASHTYPE (if not defined - otherwise) defines the type returned by the hash function - used in tsearchhash. - * pro_alloc.c: Removed trailing whitespace. -2016-02-07 David Anderson - * README: Mention - https://github.com/jrfonseca/drmingw/tree/master/src/mgwhelp - * dwarf_init_finish.c: If SHT_RELA not defined define it as 4 - in hopes that will not cause trouble for mingw. For Elf - objects 4 is the correct value and is defined in elf.h -2016-02-06 David Anderson - * dwarf_elf_access.c,dwarf_original_elf_init.c,dwarf_tsearchhash.c, - libdwarfdefs.h: Remove trailing whitespace. -2016-02-06 David Anderson - * configure.in: defines HAVE_UNUSED_ATTRIBUTE - if the gcc '__attribute__ ((unused))' compiles ok. - * config.h.in, configure: Regenerated. - * libdwarfdefs.h: Test HAVE_UNUSED_ATTRIBUTE and define - UNUSEDARG appropriately. - * dwarf_alloc.c,dwarf_elf_access.c,dwarf_form.c,dwarf_frame2.c, - dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, - dwarf_line_table_reader_common.c,dwarf_macro5.c, - dwarf_original_elf_init.c,dwarf_print_lines.c,dwarf_ranges.c, - dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, - pro_alloc.c,pro_frame.c,pro_init.c,pro_reloc.c, - pro_reloc_stream.c,pro_section.c: Use UNUSEDARG to suppress - meaningless unused-parameter warnings from gcc. -2016-02-06 David Anderson - * dwarf_tsearchhash.c: The original default - hash table size (a prime number) was very small. Now its - closer to 100. -2016-02-06 David Anderson - * dwarf_frame.h: Added fde_fd_eh_table_value. - Added fde->fd_gnu_eh_aug_present so presence/absence - is unambiguous. - * dwarf_frame.c: Added code to set fd_eh_table_value when - appropriate, though there is no interface for dwarfdump to - get the value yet. - * dwarf_frame2.c: Update the new fields appropriately. - Corrected some comments about the eh_frame cie_id field. -2016-02-05 David Anderson - * dwarf_frame2.c: Comments in get_cieptr_given_offset() - were slightly incorrect and one calculation was pointlessly - full of casts. Fixed commentary about the CIE_pointer - (CIE id or FDE id) field in a frame header. - * dwarf_loc2.c: Fixed compiler warning on signed/unsigned - comparison by changing local variable int->Dwarf_Unsigned.. - * pro_init.c: Removed extraneous semicolon to avoid - warning for C90. -2016-01-26 David Anderson - * dwarf_abbrev.c: Remove useless blank line. - * dwarf_macro5.c: Add check for macro_import offset correctness. -2016-01-21 David Anderson - * libdwarf.h.in: Typo, */* fixed to be * /* - * configure.in: Added new gcc compiler options to --enable-wall. - * configure: regenerated. - * dwarf_die_deliv.c dwarf_frame.c,dwarf_frame2.c,dwarf_gdbindex.c, - dwarf_gdbindex.h,dwarf_line.c,dwarf_line.h, - dwarf_line_table_reader_common.c,dwarf_macro5.c,dwarf_query.c, - dwarf_tsearchhash.c: Eliminated use of int/Dwarf_Signed - in favor of unsigned types where - signed served no purpose. Added ommitted return DW_DLV_NO_ERROR - in dwarf_frame2.c. Other than 'unused parameter' fixed - the warnings from gcc. - No interfaces changed though. To keep binary compatibility. -2016-01-20 David Anderson - * dwarf_query.c: New function dwarf_die_text() is a general way - to get strings from various attributes in a DIE. - * libdwarf.h.in: Add prototype for dwarf_die_text(). - * libdwarf2.1.mm: Document dwarf_die_text(). - * libdwarf2.1.pdf: Regenerated. Version 2.40. - -2016-01-19 David Anderson - * Makefile.in: Remove dwarf_stubs.o. - * configure.in: Add various gcc opts to --enable-wall - to get appropriate coverage. - * configure: regenerated. - * dwarf_macro5.c: File-local functions now declared static. - * dwarf_query.c: File-local functions now declared static. - * dwarf_stubs.c: No longer this function. It never had a prototype - declaration and never had more than return DW_DLV_ERROR as - an implementation. - * dwarf_util.c: Remove trailing whitespace. - * dwarf_original_elf_init.c(dwarf_set_tied_dbg): Added - check for null dbg. - * dwgetopt.c: Add include of dwgetopt.h. #if 0 a testing-only function. - All functions prototyped, no (). - * libdwarf.h.in: Comment out argument names for safety. - Added dwarf_get_tied_dbg(), dwarf_dietype_offset(), - dwarf_pubtype_type_die_offset() declarations. - Sorted the dwarf_get_TAG_name() etc function names. - * pro_alloc.c: Documented and commented a useless function, - dwarf_p_dealloc(). . - * pro_alloc.h: Prototyped both the useful and useless - global-to-libdwarf producer - functions _dwarf_p_dealloc and dwarf_p_dealloc. - * libdwarf2.1.mm: Documented dwarf_get_tied_dbg(), - dwarf_fde_section_offset(), and dwarf_cie_section_offset() - * libdwarf2.1.pdf: Regenerated. Rev 2.39 -2016-01-19 David Anderson - * dwarf_form.c,dwarf_macro5.c: Ensure declarations - before executable statements - * dwarf_loc.c: Cast pointer to Dwarf_Small* so pointer arithmetic - works (standard conformance). - Ensure declarations before executable statements - * dwarf_macro5.c: Ensure declarations before executable statements. - * dwarf_query.c: Ensure declarations before executable statements. - Add dwarf_dietype_offset() convenience function. - * dwarf_util.c: Use a local name that does not conflict - with standards. use mydw_errno, not errno. - * dwarf_frame2.c(dwarf_read_cie_fde_prefix): Add tests - to ensure we do not access past end of a section. -2016-01-19 David Anderson - * dwarf_form.c, dwarf_frame2.c,: Fix indentation and trailing whitespace. -2016-01-19 David Anderson - * dwarf_line.c, dwarf_line_table_reader_common.c, - dwarf_loc.c, dwarf_macro5.c, dwarf_query.c, pro_die.c: - Remove silly second ; from ;; where appropriate. -2016-01-19 David Anderson - * libdwarf.h.in, dwarf_error.c: New error numbers. - DW_DLE_LINE_STRP_OFFSET_BAD, DW_DLE_STRING_FORM_IMPROPER. - * dwarf_form.c: Added suport for DW_FORM_line_strp into - dwarf_form_string(). -2016-01-17 David Anderson - * dwarf_frame2.c: Added additional checks for - bad frame section. Looking for premature end of frame data. -2016-01-16 David Anderson - * libdwarf2.1.mm: Documented DWARF5 macro operations. - Version 2.38 - * libdwarf2.1.pdf: Regenerated. - * libdwarf2p.1.pdf: Regenerated following a trivial - clarification on cie production made a couple days ago. -2016-01-15 David Anderson - * pro_frame.h, pro_frame.c: The code adding a CIE for output - (dwarf_add_frame_cie()) - was simply assuming that the augmentation string passed in was - in stable storage. Now it uses strdup() to guarantee there - no surprises. -2016-01-14 David Anderson - * dwarf_query.c(dwarf_die_offsets): 'res ==' corrected to 'res ='. -2016-01-12 David Anderson - * dwarf_macro5.c: Fixed DW_MACRO_define/undef - calls of _dwarf_check_string_valid(). - Arranged to get the macro unit offset out - when creating context. - * libdwarf.h.in: Fixed declaration of dwarf_get_macro_context() - to get the macro unit offset out of it - so it can work properly in all contexts. - - +2019-05-29 David Anderson + * libdwarf_version.h: Updated version string. + * dwarf_names.c,dwarf_names.h,dwarf_names_enum.h, + dwarf_names_new.h: regenerated. +2019-05-26 David Anderson + * dwarf_alloc.c,dwarf_frame.c: Reformat comment lines + to shorten them. + Include inttypes.h for tsearch.h. + * elf_load_headers.c: Remove trailing whitespace. + * dwarf_groups.c,dwarf_loc.c,dwarf_tied.c: Reformat + comment lines to shorten them. + Remove small erroneous comment. + * dwarf_machoread.c: Shorten too-long lines. + * dwarf_tied_test.c: Reformat + comment lines to shorten them. Remove trailing whitespace. + * dwarf_tsearch.h: Make idempotent include with + ifndef DWARF_TSEARCH_H . Delete a blank line. + * dwarf_tsearchhash.c: Add and use DW_PR_DUx and + DW_PR_DUu and uintptr_t, refining casts to avoid + compiler warnings. + * pro_alloc.c,pro_die.c: Reformat comment lines + to shorten them. + Remove small erroneous comment. + * pro_expr.c,pro_init.c: Reformat comment lines + to shortent them. + Remove small erroneous comment. +2019-05-24 David Anderson + * Makefile.am: Delete mention of config.h.in.cmake. + * Makefile.in: Regenerate. + * dwarf_tied_test.c: Delete the comment on uintptr_t + on the intypes.h line. + * libdwarf.h.in: Refine commentary a little. + * generated_libdwarf.h.in: Regenerated. +2019-05-20 David Anderson + * CMakeLists.txt: No longer generates a local-build-dir + config.h + * config.h.in.cmake: Deleted. +2019-05-20 David Anderson + * CMakeLists.txt: Reflects revised cmake option names. + Adds compiler warning options when -DWALL selected. + * config.h.in.cmake: Reflects the set of defines + needed now, such as cmakedefine DWARF_WITH_LIBELF. + * dwarf_elf_access.c: Removes some messy HAVE_LIBELF_H + etc to dwarf_elf_defines.h so the test/define + is reusable + * dwarf_elf_defines.h: Now has the messy HAVE_LIBELF_H + etc tests. + * dwarf_elf_load_headers.c: Removes unwanted include of elf.h + * dwarf_elfread.c: Add Windows-related ifdef. + A couple if () reformatted slightly. a few casts + added to ensure compiler warnings eliminated. + * dwarf_frame2.c: Using Dwarf_Unsigned a bit more + so the output can use DW_PR_DUx for the printf. + * dwarf_incl.h: Small comment change for readability. + * dwarf_machoread.c: Add Windows-related ifdef/define/include. + Minor if() revision for consistency. Some casts + added to avoid compiler warnings and communicate intent. + * dwarf_object_detector.c: Added Windows specific ifdef/include + and accomodation of HAVE_CUSTOM_LIBELF. + * dwarf_object_read_common.c: Added Windows specific + ifdef/include and a slight reformatting of argument + lists. + * dwarf_peread.c: Added Windows specific ifdef/include. + Added casts to avoid compiler warnings. + * dwarf_query.c: Reformat some if() for consistency. + * gennames.c: Added Windows specific ifdef/include. + * libdwarf.h.in: Deleted excessive blank lines. + Added DW_FTYPE_CUSTOM_ELF 5. + * pro_encode_nm.c: Added casts to avoid certain compiler + warnings. + * pro_incl.h: Made a comment more consistent with + other uses of that comment. +2019-05-14 David Anderson + * dwarf_pe_descr.h: Several // C++ comments + present, now all such comments deleted. +2019-05-13 David Anderson + * pro_section.c,pro_frame.c: A bug in a macro shows up only + on big-endian systems (causes a compiler warning). + This fixes it. +2019-05-07 David Anderson + * configure.cmake: Moved into CMakeLists.txt. + * Makefile.am: Deleted reference to configure.cmake. + * CMakeLists.txt: no longer needs configure.cmake +2019-05-05 David Anderson + * dwarf_names.c,dwarf_names.h,dwarf_names_enum.h, + dwarf_names_new.h: Updated with latest version + string (in a comment). + * libdwarf_version.h: New version string. +2019-05-04 David Anderson + * dwarf_elf_load_headers.c: A corrupt Elf .shstring + section (lacking trailing NUL) is now detected. + * dwarf_elfread.h: Removed an unused struct + and an unused struct field. +2019-05-02 David Anderson + * dwarf_leb.c,dwarf_tied.c,dwarf_tied_decls.h, + dwarf_tied_test.c: Removing trailing whitespace + and final blank lines. + * dwarf_object_detector.c,dwarf_pe_descr.h,dwarf_peread.c: + Adding _dw to the names of more Windows things to avoid + compilation conflicts with Windows names. +2019-05-01 David Anderson + * configure.cmake: Removed some more lines. + Mainly leaving options declarations (which + will be moved later). + * dwarf_incl.h: Fixed a typo in a comment. +2019-05-01 David Anderson + * configure.cmake: Removed some lines, placing them in + base directory configure.cmake. +2019-04-30 David Anderson + * CMakeLists.txt: Added the new files. Revised the + testing area the tests can be run and pass. +2019-04-30 David Anderson + * libdwarf2.1.mm: Increased font size for better + legibility in the pdf on a computer monitor + Using the .S mm control. Rev 2.73. + The smaller size was readable on paper, but + not very readable on a screen. + * libdwarf2p.1.mm: Larger font size here too. Rev 1.45. + * libdwarf2.1.pdf,libdwarf2p.1.pdf: Regenerated + * pdfbld.sh: Fixed the -p option. +2019-04-30 David Anderson + * Makefile.am: Altered the lists of headers/source + to account for the new 'make check' details. + * dwarf_leb.c,dwarf_tied.c: Removed testing-related + source. Moved to the respective _test.c + * dwarf_leb_test.c,dwarf_tied_decls.h,dwarf_tied_test.c: + New files so we isolate test code without ifdefs. + * runtests.sh: Now reflects the new test sourcefiles. +2019-04-29 David Anderson + * dwarf_names.c,dwarf_names.h,dwarf_names_enum.h, + dwarf_names_new.h: Regenerated. + Version date update. +2019-04-28 David Anderson + * config.h.in.cmake, configure.cmake: Deleted all reference to + INT32 and INT64 as no longer needed. +2019-04-26 David Anderson + * CMakeLists.txt,config.h.in.cmake,configure.cmake: + Revised to work with the updated use of cmake. +2019-04-25 David Anderson + * dwarf_pe_descr.h, dwarf_peread.c: All the Windows PE + structs have been renamed, adding a trailing _dw, + to make them distinct from the standard Windows + names. +2019-04-25 David Anderson + * dwarf_elfread.c, dwarf_object_read_common.c: Removed + trailing whitespace. +2019-04-25 David Anderson + * dwarf_peread.c: Change the way an strncpy + is handled to avoid a compiler warning + as well as create hopefully clearer code. +2019-04-25 David Anderson + * dwarf_elf_load_headers.c,dwarf_elfread.c, + dwarf_object_read_common.c: Added missing + Windows-specific includes. + * libdwarf_version.h: Updated version date string. +2019-04-24 David Anderson + * dwarf_die_deliv.c(_dwarf_next_cu_internal): + Allow a null as the next_cu_offset pointer + passed in. + * dwarf_elf_load_headers.c: Correct the check + for a dwarf-related section. Correct + the error code returned in several places. + * dwarf_elfread.c:a Correct the error code + returned and one return value. + * dwarf_errmsg_list.h: Add specific errors relating + to nolibelf elf reading. + * dwarf_generaic_init.c: Remove trailing whitespace. + * dwarf_query.c(dwarf_highpc_b): Allow a couple + of pointer args to be null in case clients + are uninterested in returning values. + * libdwarf.h.in: Added DW_DLE_ELF_SECTION_ERROR, + DW_DLE_ELF_STRING_SECTION_ERROR. + * libdwarf2.1.mm: Version 2.72. Documented that + dwarf_next_cu_header_d() and dwarf_hipc_b() + allow specific arguments to be null. + * libdwarf2.1.pdf: Regenerated +2019-04-22 David Anderson + * dwarf_generic_init.c, dwarf_machoread.c, + dwarf_object_detector.c, + dwarf_object_read_common.c,dwarf_peread.c: Add test + for _MSC_VER for Windows MSVC. +2019-04-22 David Anderson + * dwarf_frame.c: Add ifdef/include of stdint.h + and inttypes.h and add casts using uintptr_t + so we avoid some compiler warnings. + * dwarf_groups.c,dwarf_tied.c, + pro_alloc.c,pro_die.c,pro_init.c: Add ifdef/include + of stdint.h + and inttypes.h as the updated dwarf_tsearch.h + requires uintptr_t. + * dwarf_loc.c,pro_expr.c: Add ifdef/include of stdint.h + and inttypes.h so we can use uintptr_t + in casts and avoid compiler warnings. + * dwarf_tsearchhash.c: Add ifdef/include of stdint.h + and inttypes.h for dwarf_tsearch.h so we can use uintptr_t + in casts and avoid compiler warnings. +2019-04-21 David Anderson + * dwarf_pe_descr.h: Added a comment specifying + a MS web page describing + how the section data length and content is + calculated and handled. + * dwarf_peread.c(pe_get_section_info): The understanding + of the length of section data was overly simplistic. + Now with all the bytes filled in properly in this function. +2019-04-21 David Anderson + * dwarf_peread.c: Now getting pe section + data returns a meaningful section virtual address. +2019-04-19 David Anderson + * CMakeLists.txt: Add new files to the files to build. + * Makefile.am: add the new .h and .c files. + * dwarf_die_deliv.c(reloc_incomplete): Reformat + the long 'if' to make it easier to read. + * dwarf_elf_access.c: Remove the full list of + relocations header files as no longer needed, + include dwarf_elf_defines.h instead. + Remove the + is_??bit_abs_reloc() predicate functions. Move + to dwarf_elf_rel_detector. (renamed the functions). + * dwarf_errmsg_list.h: Added + DW_DLE_SECTION_SIZE_ERROR, + DW_DLE_INTERNAL_NULL_POINTER, + DW_DLE_SECTION_STRING_OFFSET_BAD, + DW_DLE_SECTION_INDEX_BAD, DW_DLE_INTEGER_TOO_SMALL, + DW_DLE_ELF_SECTION_LINK_ERROR,DW_DLE_ELF_SECTION_GROUP_ERROR, + DW_DLE_ELF_SECTION_COUNT_MISMATCH, + DW_DLE_ELF_STRING_SECTION_MISSING,DW_DLE_SEEK_OFF_END, + DW_DLE_READ_OFF_END for use by the nolibelf + elf reader. + * dwarf_generic_init.c: Now separates + archive access (using libelf) from non-archive (using + no libelf). + * dwarf_init_finish.c: Revamp commentary about + _dwarf_load_section. + * dwarf_machoread.c: Renamed mo_byteorder to mo_endian + for consistency. Added filesize to seek/read + (RRMOA macro)for better checking of offset/size. + * dwarf_machoread.h: Renamed mo_byteorder to mo_endian. + * dwarf_object_detector.c: Added filesize to seek/read + (_dwarf_object_read_random()) + for better checking of offset/size. + * dwarf_object_read_common.c: Added additional checks + of seek/read to ensure offset correctness. + Seek itself allows seeking past end, which we + do not want. + * dwarf_object_read_common.h: Added filesize to + _dwarf_object_read_random argument list. + * dwarf_opaque.h: Removed trailing whitespace. + Added _dwarf_elf_nlsetup() declaration for non-libelf. + * dwarf_original_elf_init.c: Added ifdef so calls + do not get warnings when only non-libelf. + * dwarf_peread.c: Renamed pe_byteorder to pe_endian + forconsistency. Added filesize arg to + _dwarf_object_read_random calls. + * dwarf_peread.h: Renamed pe_byteorder to pe_endian + for consistency. + * dwarf_reading.h: Now RRMOA macro adds filesize + argument. + * libdwarf.h.in: Added error codes DW_DLE_SECTION_SIZE_ERROR, + DW_DLE_INTERNAL_NULL_POINTER,DW_DLE_SECTION_STRING_OFFSET_BAD, + DW_DLE_SECTION_INDEX_BAD,DW_DLE_INTEGER_TOO_SMALL, + DW_DLE_ELF_SECTION_LINK_ERROR,DW_DLE_ELF_SECTION_GROUP_ERROR, + DW_DLE_ELF_SECTION_COUNT_MISMATCH, + DW_DLE_ELF_STRING_SECTION_MISSING,DW_DLE_SEEK_OFF_END, + DW_DLE_READ_OFF_END + * memcpy_swap.h: Returned the function declarations + to be a single long line each. + * dwarf_elf_rel_detector.h, dwarf_elf_rel_detector.c: + Refactored relocation tests determing whether + the relocation was 32bit or 64bit. + * dwarf_elf_reloc_386.h, + dwarf_elf_reloc_aarch64.h,dwarf_elf_reloc_arm.h, + dwarf_elf_reloc_mips.h,dwarf_elf_reloc_ppc64.h, + dwarf_elf_reloc_ppc.h,dwarf_elf_reloc_sparc.h, + dwarf_elf_reloc_x86_64.h: Complete lists + of relocation types. + These are no longer needed by libdwarf, but + for now remain here. They were once needed + for builds lacking a sufficiently complete + elf.h. + * dwarf_elfstructs.h: struct declarations for + the standard Elf structs, but using character + arrays, not integers. Assures we always have the + correct lengths independent of integer sizes. + * dwarf_elf_defines.h: A basic set of Elf defines + so the producer code has all it needs. + Used by the Elf readers (libelf and nolibelf). + * dwarf_elfread.h: The internally-used set of + structures that hold nolibelf Elf data. + The fields are sized to hold 64bit and used for + both 32bit and 64bit elf. Some extra fields exist + so aspects that differ by 32/64 are recorded + by 32/64 specific code so + * dwarf_elf_load_headers.c: Actually reads 32 and 64 + Elf and inserts the values into the structures + declared in dwarf_elfread.h. + * dwarf_elfread.c: This does the nolibelf setup + and calls dwarf_elf_load_headers.c interfaces + to help with setup. +2019-03-08 David Anderson + * pro_section.c: Remove trailing whitespace. +2019-03-07 David Anderson + * pro_section.c(_dwarf_pro_generate_debuginfo): Now when + there are zero bytes to copy we do not call memcpy, + as in that case the source pointer will be NULL. +2019-03-06 David Anderson + * dwarf_form.c,dwarf_global.c: Removed trailing whitespace. + * pro_init.c: Removed trailing whitespace and fixed indents. + * pro_forms.c(dwarf_add_AT_any_value_uleb_a): Accidentally + leftout dbg = ownerdie->di_dbg, resulting in a memory + leak. + * pro_frame.c(dwarf_new_fde_a): Accidentally left out + setting fde_dbg, resulting in a memory leak. +2019-03-04 David Anderson + * dwarf.h: Adding go-specifig type attributes + DW_AT_go_kind,DW_AT_go_key,DW_AT_go_elem, + DW_AT_go_embedded_field,DW_AT_go_runtime_type. + Added error code DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR. + * dwarf_errmsg_list.h: + Added error code DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR. + * dwarf_global.c: Updates new fields in the hidden struct + with pubnames(etc) context data and makes it possible + to see the CU headers there, even if there are no + actual variables listed for a CU (a fake record + returned in that case). The change in output + records (the fake records) only appear if + the caller has requested such by a call to + xxxxx + Implements dwarf_get_globals_header() so a caller + like dwarfdump can print such section headers. + Implements dwarf_return_empty_pubnames() + which just sets a flag so a caller + like dwarfdump can request such empty sections + return a useful fake entry. + * dwarf_global.h: Adds fields like pu_length, pu_version + so pubnames(etc) sections can have their cu header + data returned. + * dwarf_line.c: Adds explicit calls to dwarf_dealloc + in error cases to avoid leaving the allocated memory + hanging around until dwarf_finish(). + * dwarf_names.c,dwarf_names.h, dwarf_names_enum.h, + dwarf_names_new.h: Regenerated to create the new attributes + for the Go language. + * dwarf_opaque.h: Adds flag de_return_empty_pubnames to + Dwarf_Debug_s struct so libdwarf can know when fake + records for CUs with no entries are wanted by + callers. + * libdwarf.h.in: Added error code DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR. + Declares dwarf_return_empty_pubnames() and + dwarf_get_globals_header() so callers (like dwarfdump) + can see and access all pubnames(etc)section CU headers. + * libdwarf2.1.mm: Version 2.71. Documents the new functions. + Revises the contest structure a little so all the pubnames-like + sections are documented as a related group of functions. + * libdwarf2.1.pdf: Regenerated. Version 2.71. + * libdwarf_version.h: New date string. +2019-02-26 David Anderson + * dwarf.h: Added go language specific attributes. + * dwarf_line.c(dwarf_srcfiles): Dealloc stmt_list_attr + as soon as we lose interest in it instead of waiting + for dwarf_finish() to be called. +2019-02-24 David Anderson + * libdwarf_version.h: Updated date string. + * dwarf_names.c,dwarf_names.h, dwarf_names_enum.h, + dwarf_names_new.h: Regenerated with latest date string. +2019-02-18 David Anderson + * configure.cmake: Now always defines DWARF_WITH_LIBELF + so builds work as always. + * dwarf_elf_access.c,dwarf_generic_init.c, + dwarf_original_elf_init.c, + pro_incl.h,pro_init.c,pro_reloc_stream.c: Now these use + DWARF_WITH_LIBELF tests to build properly when + libelf is to be used. +2019-02-18 David Anderson + * pro_incl.h: Added comments on tests of HAVE_ELF_H + and the LIBELF_H macros and the #include of + the Elf/libelf headers. +2019-02-18 David Anderson + * pro_reloc_stream.h: Was testing ifdef HAVE_ELF_H, which + is unnecessary as it does not use any elf.h types. +2019-02-12 David Anderson + * dwarf_form.c: Implement dwarf_uncompress_integer_block_a() + with the proper return type (int). Use this instead + of the old dwarf_uncompress_integer_block(). + * libdwarf.h.in: Declare dwarf_uncompress_integer_block_a() + and dwarf_uncompress_integer_block_a(). + * pro_forms.c: Implment the two new functions. +2019-02-10 David Anderson + * dwarf_errmsg_list.h,libdwarf.h.in: Adding + DW_DLE_NO_STREAM_RELOC_SUPPORT error code. + * pro_alloc.c,pro_arange.c,pro_die.c,pro_dnames.c, + pro_error.c,pro_expr.c,pro_finish.c,pro_forms.c, + pro_frame.c,pro_funcs.c,pro_init.c,pro_line.c, + pro_macinfo.c,pro_pubnames.c,pro_reloc.c, + pro_reloc_symbolic.c,pro_section.c,pro_types.c, + pro_vars.c,pro_weaks.c: + Removed the ifdef HAVE_ELF_H in most places + as we can really build everything without elf.h + except pro_reloc_stream.c (which retains + the big ifdef HAVE_ELF_H on the whole file). + Now only a couple files have ifdef HAVE_ELF_H + * pro_reloc_stream.h: Hiding the function decls + with ifdef HAVE_ELF_H +2019-02-10 David Anderson + * dwarf_errmsg_list.h,dwarf_generic_init.c: + Removed trailing whitespace on one line. + * dwarf_incl.h: Removed blank line + and a duplicated include statement. +2019-02-10 David Anderson + * pro_alloc.c,pro_arange.c,pro_die.c,pro_dnames.c, + pro_error.c,pro_expr.c,pro_finish.c,pro_forms.c, + pro_frame.c,pro_funcs.c,pro_incl.h,pro_init.c, + pro_line.c,pro_macinfo.c,pro_pubnames.c,pro_reloc.c, + pro_reloc_stream.c,pro_reloc_symbolic.c,pro_section.c, + pro_types.c,pro_vars.c,pro_weaks.c: Now pro_incl.h + is almost entirely just #defines and each .c + brings in just the headers it really wants. +2019-02-10 David Anderson + * dwarf_names.c,dwarf_names.h,dwarf_names_enum.h, + dwarf_names_new.h: Datestring update. + * libdwarf_version.h: Updated date string +2019-02-07 David Anderson + * dwarf_elf_access.c, pro_alloc.c, pro_arange,c,pro_die.c, + pro_dnames.c,pro_error.c,pro_xpr.c,pro_finish.c, + pro_forms.c,pro_frame.c, pro_funcs.c,pro_init.c, + pro_line.c,pro_macinfo.c,pro_pubnames.c,pro_reloc.c, + pro_reloc_stream.c, pro_reloc_symbolic.c,pro_section.c, + pro_types.c,pro_vars.c,pro_weaks.c: + Ifdef (entire file after include config.h) + HAVE_ELF_H so libdwarf compiles without HAVE_ELF_H + * pro_encode_nm.c: Get rid nested includes, include just + what is needed. + * dwarf_generic_init.c: Moved dwarf_set_tied_dbg() here + and ifdef HAVE_ELF_H so + libdwarf compiles without HAVE_ELF_H + * dwarf_original_elf_init.c: ifdef HAVE_ELF_H so + we can emit an error if no Elf: DW_DLE_NO_ELF_SUPPORT. + * dwarf_errmsg_list.h: Add new error DW_DLE_PRODUCER_CODE_NOT_AVAILABLE + to display if an attempt is made to open an elf object + when libdwarf built without HAVE_ELF_H. And add + DW_DLE_NO_ELF_SUPPORT. + * libdwarf.h.in: Add DW_DLE_PRODUCER_CODE_NOT_AVAILABLE and + DW_DLE_NO_ELF_SUPPORT. +2019-01-31 David Anderson + * dwarf_alloc.c, dwarf_die_deliv.c,dwarf_dnames.c, dwarf_dsc.c, + dwarf_elf_access.c,dwarf_frame.c,dwarf_frame2.c, + dwarf_gdbindex.c,dwarf_generic_init.c,dwarf_init_finish.c, + dwarf_line.c,dwarf_loc.c,dwarf_loc2.h,dwarf_machoread.c, + dwarf_macro.c,dwarf_macro5.c,dwarf_opaque.h,dwarf_peread.c, + dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c,pro_alloc.c, + pro_arange.c,pro_expr.c,pro_line.c,pro_macinfo.c, + pro_section.c,pro_types.c: Fixed 56 bugs found + by llvm's scan-build tool. +2019-01-27 David Anderson + * dwarf_form.c,dwarf_gdbindex.c,dwarf_object_read_common.c, + pro_forms.c,pro_section.c: Remove trailing whitespace. +2019-01-27 David Anderson + * dwarf_object_read_common.c,dwarf_object_read_common.h: + Now uses the ISO (1990) datatypes off_t and size_t and + ssize_t for lseek, read. +2019-01-20 David Anderson + * dwarf_base_types.h: Remove Dwarf_ufixed and + Dwarf_sfixed and all __int32_t and __uint32_t use. + __uint64_t Dwarf_ufixed64 and __int64_t Dwarf_sfixed64 + have also been removed. + * dwarf_elf_access.c: Remove use of those types here too. + * dwarf_form.c: Remove references to those types here + too. + * dwarf_gdbindex.c, dwarf_gdbindex.h: Replace + gdbindex_offset_type headerval[6] + by char gfs[4][6] (replacing dependence on the int32 + sorts of types. + * dwarf_macho_loader.h: Clarified that the uint32_t sorts + of things are just comments. + * libdwarf.h.in: Fixed a too-long comment line. + * libdwarfdefs.h: Removed all the *UINT32* and + *uint64* use. + * pro_forms.c,pro_opaque, pro_section.c: + Removed all the Dwarf_sfixed and ufixed + stuff here too. +2019-01-14 David Anderson + * dwarf_frame.c: Add support for DW_CFA_MIPS_advance_loc8 + (though pointless, really) so we can test all the code + paths of advance_loc production. + * dwarf_frame2.c: Minor formatting cleanup. + * dwarf_line_table_reader_common.h: Now tests for + negative line numbers in the table and returns an error + with the new error code DW_DLE_LINE_TABLE_LINENO_ERROR + (which indicates a corrupted line table). + * dwarf_names.c, dwarf_names.h, dwarf_names_enum.h, + dwarf_names_new.h: Regenerated. Just an update of + the sourcedate comment. + * dwarf_opaque.h: Delete a trailing whitespace character. + * libdwarf.h.in: Add error DW_DLE_LINE_TABLE_LINENO_ERROR. + * pro_expr.c: Remove trailing whitespace. + * pro_frame.c( dwarf_add_fde_inst_a): A new simpler + more portable implementation of the DW_CFA_advance_loc + code. + * pro_opaque.h: Delete blank last line. +2019-01-12 David Anderson + * dwarf_abbrev.c,dwarf_abbrev.h,dwarf_base_types.h, + dwarf_die_deliv.c, dwarf_dsc.c,dwarf_error.c, + dwarf_error.h,dwarf_form.c,dwarf_frame.c, + dwarf_frame.h,dwarf_frame2.c,dwarf_global.h, + dwarf_leb.c,dwarf_line.c,dwarf_line.h, + dwarf_line_table_reader_common.h,dwarf_loc.c, + dwarf_loc2.h,dwarf_macro5.c,dwarf_macro5.h,dwarf_opaque.h, + dwarf_print_lines.c,dwarf_query.c,dwarf_util.c,dwarf_util.h, + pro_arange.c,pro_error.c,pro_error.h,pro_expr.c, + pro_forms.c,pro_frame.c,pro_frame.h,pro_line.h, + pro_opaque.h,pro_reloc_stream.c,pro_section.c, + pro_types.c: Removed all instances of use of + Dwarf_Word, Dwarf_Sword, __int32_t (and other such). + In nearly all cases the use was gratuitous. In a few + cases some very old code was problematic (dwarf_frame2.c) + and is fixed. +2019-01-10 David Anderson + * libdwarf_version.h: New date string. +2019-01-09 David Anderson + * dwarf_original_elf_init.c: One of the calls to + dwarf_object_init_b() was checking the result code + then doing a statment that will crash the caller unless + the result code was DW_DLV_OK. +2019-01-05 David Anderson + * dwarf_generic_init.c: Removed trailing whitespace. +2019-01-04 David Anderson + * dwarf_generic_init.c: After closing de_fd, + set de_owns_fd FALSE as an extra guard. +2019-01-04 David Anderson + * dwarf_object_detector.c: Ensure the configure + can set O_BINARY if necessary so open() will use it. +2019-01-04 David Anderson + * dwarf_elf_access.c,dwarf_generic_init.c,dwarf_machoread.c, + dwarf_opaque.h,dwarf_peread.c: Simplified and unified + the requirement that dwarf_finish() close the fd + that dwarf_init_path() opened. +2019-01-04 David Anderson + * configure.ac: Version 20190104 + * dwarf_elf_access.c: Now records that libdwarf owns + its fd in the elf case and arranges to close it + when the Dwarf_Debug is being closed. + This is the case of dwarf_init_path(). + Hopefully will address Coverity CID 190599. + * dwarf_object_detector.c: Now that struct stat + is not in use delete the sys/types.h and sys/stat.h + includes as they are no longer needed. + * dwarf_generic_init(dwarf_init_path): When libdwarf + owns the fd, call _dwarf_elf_record_owned_fd() + to record that information. + In the default case (not a known object type) + we also now close the fd. + * dwarf_opaque.h: Add prototype for + _dwarf_elf_record_owned_fd, a new internal function + so the fd can be closed by libdwarf only when + libdwarf owns it. + * libdwarf_version.h: New date string. +2019-01-03 David Anderson + * dwarf_object_detector.c: Had a pointless call to stat() + which was noticed by Coverity CID 190601 + as a possible race condition. Deleted the call. + * dwarf_generic_init(dwarf_init_path): + Serious bugs introduced yesterday. + Coverity CID 190600. + the fd is remembered in the Dwarf_Debug + being created and will eventually be closed + when the Dwarf_Debug is closed. +2019-01-02 David Anderson + * dwarf_die_deliv.c(dwarf_get_real_section_name): + Uninitialized local char array + could lead to unpredictable behavior, so now initialized + with a NUL first byte so the array is a legal string. + Coverity CID CID 190598. + * ChangeLog: Renamed ChangeLog2018. New ChangeLog created. + * Makefile.am: Added ChangeLog2018 to files in dist. + * gennames.c(GenerateOneSet): Fixing Coverity CID 190603 + by removing an unused (unusable) value. + * dwarf_machoread.c.The include order + is now libdwarfdefs.h then dwarf_base_types.h + * dwarf_peread.c: The include order + is now libdwarfdefs.h then dwarf_base_types.h + Was leaking memory re-malloc into local var + localdoas. Coverity CID 190602. + * dwarf_generic_init.c(dwarf_init_path): + We clarify the use of fd and in case + of failure ensure we close the fd if + it is open (fd >= 0). + * dwarf_object_detector.c(dwarf_object_detector_path): + Mistaken 'fix' + * libdwarf_version.h: Updated version string. diff --git a/thirdparty/dwarf/ChangeLog2016 b/thirdparty/dwarf/ChangeLog2016 new file mode 100644 index 00000000..50cab3c4 --- /dev/null +++ b/thirdparty/dwarf/ChangeLog2016 @@ -0,0 +1,917 @@ +2016-12-25 David Anderson + * dwarf.h: DWARF5 changed DW_FORM_ref_sup to DW_FORM_ref_sup4 + and added DW_FORM_ref_sup8. +2016-12-20 David Anderson + * libdwarfdefs.h: Removed definition of SHF_COMPRESSED. + There was no reason to define it early in a local header file. + * dwarf_init_finish.c: Added definition of SHF_COMPRESSED. + Making it a late definition avoids a conflict with Centos-7.3. +2016-12-06 David Anderson + * dwarf.h: Comments mention certain values unused in + DWARF2 and later as being from DWARF1. +2016-11-24 David Anderson + * libdwarf/gennames.c: Update version string. +2016-11-24 David Anderson + * Makefile.in: Clean *~ +2016-11-16 David Anderson + * dwarf_die_deliv.c(dwarf_child): Added a check for 'at end of DIEs', + removed pointless parens in returns, and added {} to make an if() + follow normal form. + * dwarf_query.c: Removed pointless parens in return. + * dwarf_util.c(_dwarf_get_size_of_val): Changed return 0 + to return DW_DLV_OK so it reads as is supposed to. + For DW_FORM_block1 check a pointer for validity before + dereferencing. In _dwarf_check_string_valid() added + comments clarifying the intent of the function. +2016-11-11 David Anderson + * dwarf_init_finish.c: Remove a few bytes of trailing whitespace. + * dwarf_leb.c(_dwarf_decode_s_leb128_chk): Now we avoid + using code with undefined behavior. And add new test cases + in the #ifdef TESTING code that shows the problem is fixed. +2016-11-04 David Anderson + * libdwarf.h.in: Removed trailing whitespace, three places. + Added DW_DLE_ZLIB_UNCOMPRESS_ERROR. + * dwarf_arange.c(dwarf_get_aranges_list): Add checks for the sanity + of aranges headers and values to catch corrupted dwarf.. + * dwarf_errmsg_list.c: Add DW_DLE_ZLIB_UNCOMPRESS_ERROR to + identify impossible zlib compression. + * dwarf_form.c:(dwarf_formblock): Check for overrun of + a section-end. Return witw DW_DLE_FORM_BLOCK_LENGTH_ERROR as + the error when such corrupt dwarf is encountered. + * dwarf_init_finish.c(do_decompress_zlib): Check for corrupted + zlib compression information and set DW_DLE_ZLIB_UNCOMPRESS_ERROR + when a corrupted expanded-length is found. + * dwarf_macro5.c(_dwarf_skim_forms): For DW_FORM_STRING call + _dwarf_check_string_valid() to ensure a string does not + run off the end of a malloc block. + * dwarf_util.c(_dwarf_check_string_valid): Remove and add + a blank line to get the usual way functions begin with + declarations, a blank line, then code. No change in logic. +2016-11-01 David Anderson + * dwarf.h: Adding Ada GNAT gcc attributes DW_AT_GNU_numerator, + DW_AT_GNU_denominator, DW_AT_GNU_bias. +2016-10-21 David Anderson + * gennames.c: Update version string. +2016-10-15 David Anderson + * libdwarf.h.in: Added DWARF5 values + to enum Dwarf_Form_Class. + * dwarf_query.c(dwarf_get_form_class): Added DWARF5 support. +2016-10-11 David Anderson + * pro_forms.c, pro_section.c: Restoring DW_AT_MIPS_linkage_name + and DW_AT_MIPS_abstract_name (lost by accident in July 2007) + and adding DW_AT_linkage_name (DWARF5, but usable in + earlier DWARF versions if you wish to use it). +2016-10-07 David Anderson + * libdwarf2p.1.mm: Improved the documentation of + dwarf_pro_set_default_string_form(). + * libdwarf2p.1.pdf: Version 1.46. Regenerated. + * pro_die.c: Now the code allows modification + of the start of real strings in .debug_str easily. + Was a bit brittle before, allowed offset of 1 to work + but not zero. + * pro_opaque.h: Add dse_has_table_offset member to + eliminate brittleness in the logic for .debug_str. + * pro_init.c: Use dse_has_table_offset member to + eliminate brittleness in the logic for .debug_str. +2016-10-04 David Anderson + * dwarf_elf_access.c: Remove trailing whitespace. + * dwarf_form.c: Fix an indent. + * dwarf_init_finish.c: Comment the #if 0 so it is clear + these are for debugging only. + * dwarf_leb.c: Remove trailing whitespace. + * dwarf_line.c: Remove unused #if 0/#endif code. + * dwarf_macro5.c: Remove some obsolete #if 0 code. + Comment the remaining #if 0 so it is clear + these are for debugging only. + Remove trailing whitespace. + * dwarf_util.h: Delete obsolete #if 0 macro. + * dwgetopt.c: Comment the #if 0 so it is clear + these are for debugging only. + * pro_frame.h: Delete never-used #if 0 macro. +2016-10-04 David Anderson + * dwarf_util.c(_dwarf_check_string_valid): + removed accidental test code. +2016-10-04 David Anderson + * dwarf_leb.c: The 'make tests' test code had some + warnings, which are now fixed. + * libdwarf.h.in: Adding error codes. + * dwarf_util.c(_dwarf_check_string_valid): Uses passed-in error + code in case pointer out of bounds. + _dwarf_get_size_of_val now calls _dwarf_check_string_valid() + on a DW_FORM_string. + * dwarf_util.h: _dwarf_check_string_valid() interface changed. + * dwarf_errmsg_list.c: Adding error codes. + * dwarf_form.c, dwarf_frame2.c, dwarf_global.c, + dwarf_line.c, dwarf_line_table_reader_common.c, + dwarf_macro.c, dwarf_macro5.c, dwarf_string.c: + Using the new _dwarf_check_string_valid interface and + new error codes. + * dwarf_elf_access.c: Added commentary about a libelf call + and possible outcomes. +2016-10-03 David Anderson + * Makefile.in: Now run tests at build time to ensure DW_DLE macros correct. + * dwarf_errmsg_list.c: Add new error code and add test code to verify + DW_DLE_ macros specified correctly. + * dwarf_sort_line.c: While this file is not used, for consistency + it uses the checking macros so deleting the non-checking ones + would not look odd. + * dwarf_util.c: Add a check for running off end of abbreviation data + at a spot that was missed till now. + * dwarf_util.h: Delete unused non-checking DECODE_LEB128_UWORD and + DECODE_LEB128_SWORD and SKIP_LEB128_WORD macros. + * libdwarf.h.in: Add DW_DLE_ABBREV_OFF_END and correct + the numbering (again). Now critical parts + are checked at build time. +2016-09-30 David Anderson + * dwarf_leb.c: One comparison was accidentally + signed vs unsigned. Now both unsigned. +2016-09-30 David Anderson + * Makefile.in: Ensure test executable removed by make clean. +2016-09-30 David Anderson + * dwarf_leb.c: Fix decode and encode leb to avoid + runtime warning from left-shift signed value, + we got into undefined behavior. + Add test code used by 'make tests'. + * Makefile.in: Add leb testing to 'make tests' + * configure.in: Add additional -fsanitize tests. + * configure: Regenerated. +2016-09-28 David Anderson + * dwarf_opaque.h: New interface for + _dwarf_extract_string_offset_via_str_offsets(). + Remove duplicate declaration of the function. + * dwarf_form.c(_dwarf_extract_string_offset_via_str_offsets): + Had a test for end of section + on what was sometimes the wrong section. + Now section end passed in and correct. + Depending on circumstances such + as where elf data was in memory, the + result was a single regression test would + get a DW_DLE_LEB_IMPROPER + error ... or not get it. + * dwarf_macro5.c: A test for DW_DLV_OK was testing the + wrong local variable. +2016-09-28 David Anderson + * dwarf_errmsg_list.c: Added error codes for + duplicated DWARF5 .debug_loclists and .debug_rnglists + sections. + * dwarf_init_finish.c: Adds incomplete support for + DWARF5 .debug_names.c, .debug_loclists, and .debug_rnglists + Adds dwarf_get_section_max_offsets_d() to return all the possible + DWARF section sizes across all DWARF2..5 + * dwarf_line_table_reader_common.c: DW_LNCT renamed as + DW_LNCT_GNU as the DWARF5 standard has some differences + from the experimental version (no named)DW_LNCT_GNU. + * dwarf_loc2.c: Renames DW_LLE to DW_LLEX as these are + the non-standard experimental version (not the same + as the DWARF5 standard). + * dwarf_opaque.h: Updated version number comments. + Added new section support data in Dwarf_Debug_s. + * dwarf_ranges.c(dwarf_get_ranges_a): deleted unused local variable. + * libdwarf.h.in: New error codes. Declaration for + dwarf_get_section_max_offsets_d() added. + Now has all the DWARF5 dwarf_get_*_name() function declarations too. + * dwarf_error.h: Deleted two unwanted blank lines. +2016-09-28 David Anderson + * gennames.c: Now the comparison function to qsort + guarantees a stable sort by also referencing the + original array location (a new data item + in the struct). Needed for consistent + output. +2016-09-28 David Anderson + * dwarf_alloc.c: Special function + _dwarf_special_no_dbg_error_malloc() was failing + to return a value. Serious bug. Now it returns + a value. +2016-09-27 David Anderson + * dwarf.h: The previous experimental DW_LLE_ + non-standard names are renamed as DW_LLEX_ + temporarily. Do not use the LLEX names. +2016-09-27 David Anderson + * dwarf.h: Added commentary about DW_children_yes[no] which + are non-standard. Use DW_CHILDREN_yes[no] instead. +2016-09-27 David Anderson + * dwarf.h: Update with the probably-final DWARF5 + tags, attributes, etc. +2016-09-26 David Anderson + * dwarf_query.c: Removed four lines of code associated with + DWARF5 DW_MACRO_define_strx that + should not have existed. + There are as yet no testcases using strx, though + one fuzzed testcase (liu/NULLdereference0519.elf) + made it appear such was in use. +2016-09-25 David Anderson + * dwarf_opaque.h: Accidentally had a function pointer + definition _dwarf_get_elf_flags_func_ptr but now has a + typedef of _dwarf_get_elf_flags_func_ptr_type instead. + * dwarf_init_finish.c: Add definition of _dwarf_get_elf_flags_func. +2016-09-23 David Anderson + * gennames.c: gennames -t generated incorrect tables. + gcc -fsanitize=address noticed out of bounds references + in the generated code. The code has been wrong for quite a while. + It's likely no one was using the table form, gennames -s + is generally better to use anyway. + * pro_frame.c: Was using strdup() and now uses _dwarf_p_get_alloc() + and strcpy() so we do not leak a string. +2016-09-22 David Anderson + * dwarf_abbrev.c: Was calling _dwarf_error() with NULL dbg + when a real dbg was available. fixed. + * dwarf_alloc.c: Was testing for the static DW_DLA_ERROR + too late in dwarf_dealloc(). So the address sanitizer reported the + erroneous address calculation that resulted. + * dwarf_error.c,dwarf_error.h: Now DE_STANDARD,DE_STATIC,DE_MALLOC + let dwarf_dealloc free up Dwarf_Error resources properly. +2016-09-22 David Anderson + * dwarf_ranges.c: dwarf_get_ranges_a() was allocating at the wrong + place and not freeing all it should. +2016-09-21 David Anderson + * dwarf_errmsg_list.c,libdwarf.h.in: Added DW_DLE_LINE_TABLE_BAD. + * dwarf_line_table_reader_common.c: Added tests to prevent running + off end of line table. Second commit is fix 3 line indent error. +2016-09-21 David Anderson + * configure.in: Support --enable-sanitize + * configure: Regenerated. + * dwarf_alloc.c: Rearrange DW_DLA_STRING check to avoid + calculating and using an address that may not exist. + And check earlier for a NULL dbg. + * dwarf_die_deliv.c: Add offset and length checks to catch + corrupt dwarf. + * dwarf_errmsg_list.c: Add DW_DLE_LOCLIST_OFFSET_BAD error code. + * dwarf_form.c: Delete three completely blank lines for + consistency in formatting.. + * dwarf_loc.c: Add offset and length checks to catch + corrupt dwarf. Correct the initialization of loc_section_end + in _dwarf_read_loc_section(). + * dwarf_ranges.c: Add free() in two places to avoid + memory leak. + * dwarf_util.c: Add length error checks for DW_FORM_block* . + Correct initialization of end_abbrev_ptr in + _dwarf_get_abbrev_for_code(). + * libdwarf.h.in: Add DW_DLE_LOCLIST_OFFSET_BAD. +2016-09-17 David Anderson + * libdwarf.h.in: Added error code DW_DLE_SIBLING_LIST_IMPROPER. + * dwarf_errmsg_list.c: Added DW_DLE_SIBLING_LIST_IMPROPER. + * dwarf_die_deliv.c: Vulnerability DW201609-001. + Added a check to catch invalid DWARF instead of + reading a byte inappropriately (that might not even + be addressable). + The error code generated is DW_DLE_SIBLING_LIST_IMPROPER. +2016-09-15 David Anderson + * configure.in: Add check for unistd.h . + * configure: Regenerated. + * gennames.c: Add HAVE_UNISTD_H check for the include + of unistd.h. +2016-09-15 David Anderson + * dwarf_elf_access.c: Depends on libelf.h, so if libelf.h + is missing (as shown in the generated config.h) + the compile stops with an error. +2016-09-15 David Anderson + * libdwarf.h.in: New interface functions + dwarf_producer_finish_a() and + dwarf_add_die_to_debug_a() + declared, providing libdwarf-standard + int return value. + * libdwarf2p.1.mm: Document dwarf_producer_finish_a() + and dwarf_add_die_to_debug_a(). + * libdwarf2p.1.pdf: Regenerated. Rev 1.45. + * pro_init.c: Remove use of C99 type uint32_t + and use DW_TSHASHTYPE instead. + * pro_finish.c: Implement dwarf_producer_finish_a(). + * pro_die.c: Implement dwarf_add_die_to_debug_a(). +2016-09-14 David Anderson + * dwarf_dsc.h: Removed accidental typedef redeclaration + of Dwarf_Dsc_Head: it is already in libdwarf.h and + FreeBSD compiler complained. + * pro_section.c: Removed trailing whitespace from three lines. + Fixed indentation on one line. +2016-09-13 David Anderson + * pro_section.c: new interface dwarf_get_section_bytes_a(). + * libdwarf.h.in: Declaration for dwarf_get_section_bytes_a() added. + * libdwarf2p.1.mm: Document dwarf_get_section_bytes_a(). + * libdwarf2p.1.pdf: Regenerated. Rev 1.44. +2016-09-12 David Anderson + * libdwarf.h.in: Declaring dwarf_new_die_a() + and dwarf_die_link_a(). + Renamed yesterday's new function dwarf_transform_to_disk_form_b() to + dwarf_transform_to_disk_form_a() for consistency + with the new dwarf_new_die_a(). + * pro_die.c: Implementing dwarf_new_die_a() + and dwarf_die_link_a() with easier to use + error handling than dwarf_new_die() + and dwarf_die_link(). + * libdwarf2p.1.mm: Document the new and renamed *_a() functions. + * libdwarf2p.1.pdf: Regenerated. Rev 1.43. +2016-09-11 David Anderson + * dwarf_errmsg_list.c: Adding DW_DLE_LEB_OUT_ERROR. + * libdwarf.h.in: Adding DW_DLE_LEB_OUT_ERROR + and dwarf_transform_to_disk_form_b(), first steps + to making type-safe producer functions. + * libdwarf2p.1.mm: Document dwarf_transform_to_disk_form_b(). + * libdwarf2p.1.pdf: Rev 1.42. + * pro_arange.c: Altered internal interface to _dwarf_transform_arange_to_disk(). + * pro_die.c: Altered internal error return to use DW_DLV_ERROR. + * pro_macinfo.c,pro_macinfo.h: Altered internal interface to + _dwarf_pro_transform_macro_info_to_disk(). + * pro_section.c: Implemented dwarf_transform_to_disk_form_b() and + changed internals to use DW_DLV_OK/DW_DLV_ERROR. + Many places where errors were ignored now have checks for error. + * pro_section.h: Added GET_CHUNK_ERR to return DW_DLV_ERROR + on error. Altered internal function _dwarf_transform_arange_to_disk() + and _dwarf_transform_simplename_to_disk() + to the newer interface. + * pro_types.h: Internal declaration of _dwarf_transform_simplename_to_disk() + now uses the new interface. +2016-09-11 David Anderson + * dwarf_dsc.c: Set the internal flag so we do not redo the + leb decoding over and over. +2016-09-08 David Anderson + * Makefile.in: Add dwarf_dsc.c to the build to access + DW_AT_discr_list attributes. + * dwarf.h: Added comment that DW_AT_discr_list is DWARF2. + * dwarf_alloc.c, dwarf_alloc.h: Added DW_DLA_DSC_HEAD support. + * dwarf_dsc.c: Implement the new discriminant list + functions. + * dwarf_dsc.h: Internal discriminant types. + * libdwarf.h.in: A new opaque type and new functions + dwarf_discr_list etc. + * dwarf_errmsg_list.c: New error code for + discriminants: DW_DLE_DISCR_ARRAY_ERROR. + * checkexample.c: Added a new example. for dwarf_descr_list(). +2016-09-01 David Anderson + * libdwarf2.1.mm: Improved the wording for dwarf_diename() + and dwarf_die_text(). + * libdwarf2.1.pdf: Regenerated as Version 2.51. +2016-08-28 David Anderson + * libdwarf.h.in: Added dwarf_pro_get_string_stats() for producer + library users to know how libdwarf handled DW_AT_name etc. + * pro_die.c: Corrected the tsearch-related compare/hash functions + to work correctly. + * pro_finish.c: Implements dwarf_pro_get_string_stats(). + * pro_init.c: Hash function for tsearch implemented correctly now. + * pro_opaque.h: Changed the hash data structure so it can work + correctly. Added the statistics struct to the Dwarf_P_Debug + structure. + * libdwarf2p.1.mm: Documents dwarf_pro_get_string_stats(). + * libdwarf2p.1.pdf: Revision 1.41. Regenerated. +2016-08-27 David Anderson + * pro_section.c, pro_reloc_stream.c: In a couple of places names were + shadowing other names. Fixed. No change in functionality. +2016-08-25 David Anderson + * libdwarf.h.in: Added new error code relating to DW_FORM_strp + relocations. + * dwarf_errmsg_list.c: Added DW_DLE_DEBUGSTR_UNEXPECTED_REL string. + * pro_die.c: Added a comment related to DW_FORM_strp. + * pro_opaque.h: Added/modified commentary. + * pro_section.c: Now sets the correct section symbol for + relocations for strings in .debug_str. + * pro_reloc.c: Added commentary, deleted blank lines. + * pro_reloc_stream.c: Moved declarations to inner + contexts where possible. Refined looping for clarity. +2016-08-23 David Anderson + * libdwarf2p.1.mm: Document dwarf_pro_set_default_string_form. + * libdwarf2p.1.pdf: Regenerated. Rev 1.40. +2016-08-23 David Anderson + * dwarf_alloc.c,dwarf_frame.c: Remove trailing whitespace. + * dwarf_errmsg_list.c: Has four new error codes to deal + with emitting .debug_str from the producer. + * gennames.c: Added 'static' to a static function to + avoid compiler warnings. + * libdwarf.h.in: Four new error codes. + A new producer function: dwarf_pro_set_default_string_form() which + causes debug_info strings to be emitted in .debug_str where + that seems like it might save space. + * pro_alloc.c: A new debug_str producer string + hashtab free helper function to clean up the .debug_str + hash table.. + * pro_die.c: Now calls a single function to emit strings and + can emit in either .debug_info or .debug_str. + * pro_die.h: Declares _dwarf_pro_set_string_attr() now. + * pro_forms.c: Some local variables are always initialized now + at declaration point. Now uses common code to set up strings. + * pro_init.c: Initializes debug_str hash table for strings + And sets up the section properly. Defines the hashfunc. + * pro_opaque.h: Fixes some spacing awkwardness. Adds + .debug_str hash data and eliminates unused data. + * pro_section.c: Now emits .debug_str when such is + wanted. +2016-06-13 David Anderson + * dwarf_alloc.c: Dwarf_Fde_s now has a destructor. + * dwarf_frame.c,dwarf_frame.h: Now dwarf_get_fde_info_for_reg3 memoizes + frame data making one pattern of use (from dwarfdump) + much much faster. +2016-06-13 David Anderson + * dwarf_frame.c: Revised some local assignments so + we are sure the same value used as intended. + Added some {} on if for consistency with libdwarf use. + * gennames.c: Update version string. +2016-06-12 David Anderson + * libdwarf/gennames.c: Update version string. +2016-06-12 David Anderson + * dwarf_frame.c: Adding dwarf_get_fde_info_for_cfa_reg3_b() + which lets dwarfdump print frame data a bit more quickly. + It is unclear whether other applications will find this + new interface to be of value. + * dwarf_frame.h,dwarf_frame3.c: Internal interfaces changed slightly + to allow the new function to work. + * libdwarf.h.in: Added dwarf_get_fde_info_for_cfa_reg3_b() + declaration. + * libdwarf2.1.mm: Documents dwarf_get_fde_info_for_cfa_reg3_b(). + Rev.2.50 + * libdwarf2.1.pdf: Regenerated. +2016-06-08 David Anderson + * dwarf_init_finish.c, dwarf_line_table_reader_common.c: Remove + trailing whitespace. Fix one indent. +2016-06-08 David Anderson + * gennames.c: Update version string. +2016-06-07 David Anderson + * Makefile.in: Use $(SONAME) rather than libdwarf.so.1 whereever + possible. +2016-06-01 David Anderson + * Makefile.in: Tweaks for debian build compatibility. + * gennames.c: Use DW_VERSION_DATE_STR instead of __DATE__ __TIME__ +2016-05-23 David Anderson + * dwarf_errmsg_list.c, libdwarf.h.in: Added + DW_DLE_COMPRESSED_EMPTY_SECTION. + * dwarf_init_finish.c: If load_section gets + DW_DLV_NO_ENTRY just return that. + If requres-decompress but has no data call it + a corrupt Elf section (given what sections + libdwarf is interested in). + * dwarf_line_table_reader_common.c: Only + deal with line table format entries if the + count is > 0. +2016-05-23 David Anderson + * Makefile.in: add SONAME libdwarf.so.1 to dynamic section when + building shared libdwarf.so + We have not made an incompatible interface change since + May 19, 2014 (and that was to the producer code not to + what DWARF readers use). +2016-05-22 David Anderson + * libdwarf.h.in, dwarf_errmsg_list.c: Adding + DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH error code. + Fixed unsigned/signed comparison warning in the table test code. + * dwarf_line.c: If we find a null pointer from include directores + we substitute "" for the + reader. + * dwarf_line_table_reader_common.c: Detect a corrupted DWARF5 + directory count vs directory format count problem and return + an error. +2016-05-20 David Anderson + * dwarf_macro5.c: Was failing to initialize + mc_cu_context leading to coredump. + If dwarf_srcfiles() returned zero as the count + of source files an erroneous calloc() would result in an + objection from valgrind: an erroneous calloc of zero bytes + of srcfiles pointers would never be freed. +2016-05-19 David Anderson + * Makefile.in: HOST_CFLAGS now references CFLAGS + at the request of the Debian project. + * configure.in: Now defaults to -fPIC always + (though in a nonshared build one could reasonably + turn it off with --disable-fpic) + Adds several messages reporting configure actions. + * configure: Regenerated. +2016-05-18 David Anderson + * dwarf_form.c: Directly check expression length against + section length in case expression length very very large. + * dwarf_query.c: _dwarf_calculate_info_section_*() routines + made clearer and the *_start_ptr() instance also now returns + the length (via a pointer arg). + * dwarf_xu_index.c: Check data read from the section so + a wildly large columns count or slots count will be caught + and an error returned. +2016-05-16 David Anderson + * dwarf_elf_access.c: Check more thoroughly for corrupt + relocation records and return an error if such found. + * dwarf_macro5.c: Remove trailing whitespace. +2016-05-10 David Anderson + * dwarf_arange.c,dwarf_die_deliv.c: All read operations check for overrun. + * dwarf_errmsg_list.c: DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE, + DW_DLE_LOCEXPR_OFF_SECTION_END, and DW_DLE_POINTER_SECTION_UNKNOWN + added to error values. + * dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_global.c,dwarf_line.c, + dwarf_line_table_reader_common.c,dwarf_loc.c,dwarf_loc2.c, + dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, + dwarf_ranges.c,dwarf_util.c, dwarf_xu_index.c: All read + operations check for overrun. + * dwarf_opaque.h: Put the 4 SGI-only section data + items next to each other to make it clear they + are such. + * dwarf_util.h: Added some checks to READ_AREA_LENGTH_CK + * libdwarf.h.in: Defined the new error names. +2016-05-07-b David Anderson + * libdwarf2.1.mm,libdwarf2p.1.mm: Fixed spelling errors. + * libdwarf2.1.pdf,libdwarf2p.1.pdf: Regenerated. +2016-05-07 David Anderson + * libdwarf.h.in, dwarf_errmsg_list.c: New error codes for + stopping due to corrupted frame data. + * dwarf_frame.c,dwarf_frame.h,dwarf_frame2.c,dwarf_line.c: + Notice frame area overrun and generate error. +2016-05-06 David Anderson + * dwarf_errmsg_list.c: Added DW_DLE_ZLIB_SECTION_SHORT. + * dwarf_form.c: Now checking for section overrun. + * dwarf_init_finish.c: Now checking zlib reading + for section overrun. + * dwarf_macro5.c: Now checking for section overrun and + also fixing double delete caused by having + _dwarf_get_alloc() space pointing at other _dwarf_get_alloc() + space. Because in case of error the order of free + of such is unpredictable! + * dwarf_macro5.h: Added comment on mc_srcfiles member. + * libdwarf.h.in: Added DW_DLE_ZLIB_SECTION_SHORT. +2016-05-05 David Anderson + * dwarf_form.c: Add a test so that a really large form_block length + will not be considered safe (due to unsigned arithmetic + overflow). + Fixed the new check-code reading string offsets section + so the endpoint in the check is that section, not debug_info. + * dwarf_query.c: New function _dwarf_calculate_info_section_start_ptr() + helps in some checking. + * dwarf_util.h: Add a test so arithmetic overflow will not show + a bogus value as being ok. + * libdwarf.h.in,dwarf_errmsg_list.c: Add error code + DW_DLE_FORM_BLOCK_LENGTH_ERROR so we have a specific + error for this case. + * dwarf_line.c: %lld switched to "%" DW_PR_DSd + * dwarf_opaque.h: Added function declaration for + _dwarf_calculate_info_section_start_ptr(). +2016-05-04 David Anderson + * dwarf_macro5.c(construct_at_path_from_parts): Move 3 lines + of code up to test for NULL pointer. So we do not + dereference the pointer. +2016-05-03 David Anderson + * dwarf_die_deliv.c: Add checks for overrun of end of section + due to corrupted DWARF. + * dwarf_arange.c,dwarf_util.c: first use of READ_UNALIGNED_CK. + * dwarf_errmsg_list.c, libdwarf.h.in: DW_DLE_READ_LITTLEENDIAN_ERROR + and DW_DLE_READ_BIGENDIAN_ERROR are errors possible + in READ_UNALIGNED_CK. DW_DLE_LINE_OFFSET_WRONG_FORM gives + a more meaningful description of a particular corruption + problem (not a new test, just a new error name). + * dwarf_elf_access.c: Add a check on relocations to ensure + we do not write off the end of the section. + * dwarf_query.c: Using local variables for shorter lines. + * dwarf_util.h: Implement READ_UNALIGNED_CK macros. + * dwarf_leb.c: Improve a couple comments. + * dwarf_line.c: Now use DW_DLE_LINE_OFFSET_WRONG_FORM. + Add operandmismatch() to get better debug information + in case of corrupted dwarf. Revise the code for + clarity. + * dwarf_macro5.c: Duplicate free() could result if + dwarf_finish() was used to clean up from a dwarf macro + context. Two functions are really static so + the function type set properly now. +2016-04-30 David Anderson + * dwarf_frame.c, dwarf_line_table_reader_common.c, + dwarf_loc2.c: switch to using DECODE_LEB*_CK. + * dwarf_frame.c: Delete unused local variables. + Use DECODE_LEB*_CK for better error checking. + * dwarf_frame2.c, dwarf_frame.h: Internal functions get new + arguments to support DECODE_LEB*_CK. + * dwarf_arange.c: Using UNUSEDARG to suppress warning. + * dwarf_line_table_reader_common.c: Use DECODE_LEB*_CK + for better error checking. + * dwarf_loc2.c: Use DECODE_LEB*_CK + for better error checking. +2016-04-30 David Anderson + * dwarf_die_deliv.c: Deleted unused local variable. + * dwarf_form.c,dwarf_macro.c, dwarf_macro5.c: Now uses + DCODE_LEB128*_CK nearly everywhere + for better checking for corrupted data. + * dwarf_opaque.h:New argument to _dwarf_get_addr_index_itself() + for better data checks.. + * dwarf_query.c: Uses revised _dwarf_get_addr_index_itself() + interface. + * dwarf_util.c: Fixed formatting errors. +2016-04-29 David Anderson + * dwarf_line_table_reader_common.c, dwarf_macro.c, + dwarf_macro5.c, dwarf_util.c, dwarf_util.h: + Now use DECODE_LEB128_*CK macros simplifying + the code while catching errors/corruption in DWARF + data. +2016-04-28 David Anderson + * dwarf_die_deliv.c: Now _dwarf_next_die_info_ptr() has + a section length argument. + * dwarf_query.c, dwarf_util.c: Now uses the checked version + of leb reading. + * dwarf_util.h: Now _dwarf_get_size_of_val() has + section_end_ptr argument for checking leb values + do not overrun end of section. +2016-04-27 David Anderson + * dwarf_frame2.c: Now notices a frame-length field + which is too large to be meaningful and returns + an error.. +2016-04-27 David Anderson + * Makefile.in: Now dwarf_error.o dependency on + dwarf_errmsg_list.c is explicit. + * dwarf_errmsg_list.c: New error strings. + * libdwarf.h.in: New error values for when running off + end of section and line range and address size where + zero leads to trouble.. + * dwarf_abbrev.c,dwarf_die_deliv.c, dwarf_frame.c, + dwarf_frame.h, dwarf_frame2.c,dwarf_frame3.c,dwarf_leb.c, + dwarf_line.c, dwarf_line.h, dwarf_line_table_reader_common.c, + dwarf_query.c,dwarf_util.c,dwarf_util.h: + Add checks for running off end of section. +2016-04-26 David Anderson + * Makefile.in: The new errmsg_check dependency + line was a bit wrong. libdwarf.h should not have $(srcdir) +2016-04-25 David Anderson + * dwarf_errmsg_list.c: When -DTESTING ensure all the + error messages have a value in () so we can check + that value. +2016-04-25 David Anderson + * dwarf_tied.c: A C11-ism crept in. Fixed. + Added 'static' to local function declaration. + Removed unused local variable. + * dwarf_errmsg_list.c: Now checks that the number in () + matches the index (and still checks that the array size + is the declared size) when compiled -DTESTING. +2016-04-25 David Anderson + * dwarf_errmsg_list.c: Fixed indent mistakes. + * dwarf_leb.c: Fixed places were leb128_length + was assumed non-null (dwarf_form.c passes NULL!). +2016-04-25 David Anderson + * Makefile.in: Added testing of the _dwarf_errmsgs array. + * dwarf_error.c: Moved _dwarf_errmsgs out of dwarf_error.c into + dwarf_errmsg_list.c + * dwarf_errmsg_list.c: Now has error strings and test code. +2016-04-25 David Anderson + * dwarf_error.c: The error description + "DW_DLE_GDB_INDEX_INDEX_ERROR(264)" was missing the + comma so following errors were reporting the wrong string. +2016-04-21 Carlos Alberto Enciso + * Use the _WIN32 macro to identify a WINDOWS specific code. +2016-03-14 David Anderson + * dwarf_util.c: Changed 'byte' to 'byte pair' + in a comment. Where we read abbreviation AT/FORM lists. +2016-03-14 David Anderson + * dwarf_error.c(_dwarf_errno): Now prints to stdout and + does abort(1) when it has to give up. Instead of + using stderr and abort(). + It is not a good idea for applications to fail to provide + error handling, so no one should notice this change. + * libdwarf2.1.mm: Documents behavior in case there is no error + handling provided by our caller. + * libdwarf2.1.pdf: Regenerated. Rev 2.48. +2016-03-14 David Anderson + * libdwarf2.1.mm: Documents Dwarf_Handler error handler function. + * libdwarf2.1.pdf: Regenerated. Rev 2.47. +2016-03-13 David Anderson + * dwarf_query.c: Use dwarf_formstring to read string + attributes as it handles all the string types already. + Now dwarf_diename() and dwarf_die_text() call dwarf_formstring() + so DW_FORM_strp_sup and DW_FORM_GNU_strp_alt are + properly handled(along with all the other string FORMs). + * dwarf_form.c: Handle an error in dwarf_formstring() + (for tied files, or the lack thereof) + differently so it all works properly even if the incoming + error argument is null. +2016-03-12 David Anderson + * dwarf_abbrev.c: Uses renamed fields abbrev internal struct. + Removes some gratuitous (). Adds clarifying {} + * dwarf_abbrev.h: renames Dwarf_Abbrev_s struct fields + from ab_tag to dab_tag, etc. + Adds global section offset to the fields. + * dwarf_die_deliv.c: Uses renamed Abbrev_List fields. + Adds dwarf_die_abbrev_global_offset() function so + clients can properly identify where an abbrev entry is + in .debug_abbrev. + * dwarf_die_deliv.h: renames Dwarf_Abbrev_List + struct fields from ab_tag to abl_tag etc. + Adds abl_goffset, abl_count. + * dwarf_query.c,dwarf_util.c: Uses renamed Dwarf_Abbrev_List + fields. + * libdwarf.h.in: Adds function dwarf_die_abbrev_global_offset(). + * libdwarf2.1.mm: Documents dwarf_die_abbrev_global_offset(). + * libdwarf2.1.pdf: Regenerated. Rev 2.46. +2016-03-11 David Anderson + * dwarf_die_deliv.c: Fixed issues with handling NULL + Dwarf_Error* and with mistakes treating DW_DLV_NO_ENTRY + as if it were DW_DLV_ERROR. + * dwarf_form.c: Only do dwarf_errno(*error) when error is non-null. + * dwarf_macro5.c, dwarf_query.c, dwarf_ranges.c: Avoid the + possibility of + doing dwarf_errno(*error) when error is null. + * dwarf_util.c(_dwarf_error_mv_s_to_t): Added code to + ensure that nothing crash-worthy happens + even if a future internal caller calls it with one or more NULL + arguments. + * libdwarf2.1.mm: Added a few words about Error Handling in general + to clarify earlier wording (earlier wording was not as explicit + as it should have been). + * libdwarf2.1.pdf: Regenerated. Version 2.45 + * dwarf_sort_line.c: Though no longer built or used, added + an initializer to a local variable for correctness. + * dwarf_addr_finder.c: Though no longer compiled or used (is IRIX only), + cleaned up local variable declarations that were not + up to the current standard usage in libdwarf. +2016-03-11 David Anderson + * Makefile.in: Added a comment about pr and pdf-building. +2016-03-09 David Anderson + * libdwarf2.1.mm: Slightly altered the dwarf_offsets_list() documentation. + * libdwarf2.1.pdf: Rev 2.44. Regenerated. +2016-03-09 David Anderson + * dwarf_form.c: Correct and amplify a comment. +2016-03-01 David Anderson + * libdwarf2.1.mm: Documented dwarf_dietype() and + dwarf_offset_list(). + * libdwarf2.1.pdf: Regenerated. Rev 2.43 + * checkexamples.c: Added example for dwarf_offset_list(). +2016-02-19 Carlos Alberto Enciso + * dwarf_alloc.h, dwarf_alloc.c, dwarf_base_types.h, dwarf_opaque.h: + New allocator type (DW_DLA_CHAIN_2), to allow a list of addressed + types (address, offset). + There was Memory corruption due to incorrect usage of + memory allocator type. + * dwarf_query.c: Use the new allocator type. +2016-02-14 David Anderson + * libdwarf2.1.mm: dwarf_exprloc -> dwarf_formexprloc. + The spelling error was introduced in version 2.41. + * libdwarf2.1.pdf: Regenerated. Version 2.42 +2016-02-13 David Anderson + * libdwarf2.1.mm: Added dwarf_lineoff_b() documentation. + Fixed a typo in dwarf_formexprloc() documentation. + * libdwarf2.1.pdf: Regenerated. Version 2.41 + * Makefile.in: Add HOSTCFLAGS HOSTLDFLAGS HOSTCC to make + it easier to cross-compile. Remove common.c, common.h + (a few lines of code moved to gennames.c). + * README: document use of HOSTCC + * common.c,common.h: Delete. A few lines of code moved to gennames.c. + * configure.in: for AC_TRY_RUN add [],[] for else and for + cross-compile cases. + * configure: Regenerated. + * dwarf_die_deliv.c, dwarf_frame2.c, dwarf_line.c, + dwarf_macro5.c, dwarf_print_lines.c, dwarf_ranges.c: + Renamed to avoid shadowing variables with same name. + For clarity. + * gennames.c: Incorporates a few lines from common.c + so common.c, common.h can be deleted. +2016-02-10 David Anderson + * README: Improved a comment about Dwarf_Obj_Access_Methods. + * dwarf_elf_access.c: New function _dwarf_get_elf_flags_func() + extracts the sh_flags field from Elf sections. In an odd way + so we preserve binary and source compatibility.+ + * dwarf_error.c,libdwarf.h.in: New error DW_DLE_ELF_FLAGS_NOT_AVAILABLE. + * dwarf_init_finish.c: Use new (global) function pointer + _dwarf_get_elf_flags_func_ptr + to access extra Elf data without breaking compatibility. + Add additional way (SHF_COMPRESSED) to detect zlib + compression and expand the compressed data. +2016-02-08 David Anderson + * dwarf_alloc.c: Drop VALTYPE, use DW_TSHASHTYPE instead. + Use DW_TSHASHTYPE in the hash functions. + * dwarf_tied.c: Use DW_TSHASHTYPE in the hash function. + * dwarf_tsearchhash.c: Add back the UNUSEDARG to avoid + unused argument warnings. +2016-02-07 David Anderson + * dwarf_init_finish.c: Fix indents. remove a trailing space. + * dwarf_tsearch.h,dwarf_tsearchhash.c: Now DW_TSHASHTYPE (if not defined + otherwise) defines the type returned by the hash function + used in tsearchhash. + * pro_alloc.c: Removed trailing whitespace. +2016-02-07 David Anderson + * README: Mention + https://github.com/jrfonseca/drmingw/tree/master/src/mgwhelp + * dwarf_init_finish.c: If SHT_RELA not defined define it as 4 + in hopes that will not cause trouble for mingw. For Elf + objects 4 is the correct value and is defined in elf.h +2016-02-06 David Anderson + * dwarf_elf_access.c,dwarf_original_elf_init.c,dwarf_tsearchhash.c, + libdwarfdefs.h: Remove trailing whitespace. +2016-02-06 David Anderson + * configure.in: defines HAVE_UNUSED_ATTRIBUTE + if the gcc '__attribute__ ((unused))' compiles ok. + * config.h.in, configure: Regenerated. + * libdwarfdefs.h: Test HAVE_UNUSED_ATTRIBUTE and define + UNUSEDARG appropriately. + * dwarf_alloc.c,dwarf_elf_access.c,dwarf_form.c,dwarf_frame2.c, + dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, + dwarf_line_table_reader_common.c,dwarf_macro5.c, + dwarf_original_elf_init.c,dwarf_print_lines.c,dwarf_ranges.c, + dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, + pro_alloc.c,pro_frame.c,pro_init.c,pro_reloc.c, + pro_reloc_stream.c,pro_section.c: Use UNUSEDARG to suppress + meaningless unused-parameter warnings from gcc. +2016-02-06 David Anderson + * dwarf_tsearchhash.c: The original default + hash table size (a prime number) was very small. Now its + closer to 100. +2016-02-06 David Anderson + * dwarf_frame.h: Added fde_fd_eh_table_value. + Added fde->fd_gnu_eh_aug_present so presence/absence + is unambiguous. + * dwarf_frame.c: Added code to set fd_eh_table_value when + appropriate, though there is no interface for dwarfdump to + get the value yet. + * dwarf_frame2.c: Update the new fields appropriately. + Corrected some comments about the eh_frame cie_id field. +2016-02-05 David Anderson + * dwarf_frame2.c: Comments in get_cieptr_given_offset() + were slightly incorrect and one calculation was pointlessly + full of casts. Fixed commentary about the CIE_pointer + (CIE id or FDE id) field in a frame header. + * dwarf_loc2.c: Fixed compiler warning on signed/unsigned + comparison by changing local variable int->Dwarf_Unsigned.. + * pro_init.c: Removed extraneous semicolon to avoid + warning for C90. +2016-01-26 David Anderson + * dwarf_abbrev.c: Remove useless blank line. + * dwarf_macro5.c: Add check for macro_import offset correctness. +2016-01-21 David Anderson + * libdwarf.h.in: Typo, */* fixed to be * /* + * configure.in: Added new gcc compiler options to --enable-wall. + * configure: regenerated. + * dwarf_die_deliv.c dwarf_frame.c,dwarf_frame2.c,dwarf_gdbindex.c, + dwarf_gdbindex.h,dwarf_line.c,dwarf_line.h, + dwarf_line_table_reader_common.c,dwarf_macro5.c,dwarf_query.c, + dwarf_tsearchhash.c: Eliminated use of int/Dwarf_Signed + in favor of unsigned types where + signed served no purpose. Added ommitted return DW_DLV_NO_ERROR + in dwarf_frame2.c. Other than 'unused parameter' fixed + the warnings from gcc. + No interfaces changed though. To keep binary compatibility. +2016-01-20 David Anderson + * dwarf_query.c: New function dwarf_die_text() is a general way + to get strings from various attributes in a DIE. + * libdwarf.h.in: Add prototype for dwarf_die_text(). + * libdwarf2.1.mm: Document dwarf_die_text(). + * libdwarf2.1.pdf: Regenerated. Version 2.40. + +2016-01-19 David Anderson + * Makefile.in: Remove dwarf_stubs.o. + * configure.in: Add various gcc opts to --enable-wall + to get appropriate coverage. + * configure: regenerated. + * dwarf_macro5.c: File-local functions now declared static. + * dwarf_query.c: File-local functions now declared static. + * dwarf_stubs.c: No longer this function. It never had a prototype + declaration and never had more than return DW_DLV_ERROR as + an implementation. + * dwarf_util.c: Remove trailing whitespace. + * dwarf_original_elf_init.c(dwarf_set_tied_dbg): Added + check for null dbg. + * dwgetopt.c: Add include of dwgetopt.h. #if 0 a testing-only function. + All functions prototyped, no (). + * libdwarf.h.in: Comment out argument names for safety. + Added dwarf_get_tied_dbg(), dwarf_dietype_offset(), + dwarf_pubtype_type_die_offset() declarations. + Sorted the dwarf_get_TAG_name() etc function names. + * pro_alloc.c: Documented and commented a useless function, + dwarf_p_dealloc(). . + * pro_alloc.h: Prototyped both the useful and useless + global-to-libdwarf producer + functions _dwarf_p_dealloc and dwarf_p_dealloc. + * libdwarf2.1.mm: Documented dwarf_get_tied_dbg(), + dwarf_fde_section_offset(), and dwarf_cie_section_offset() + * libdwarf2.1.pdf: Regenerated. Rev 2.39 +2016-01-19 David Anderson + * dwarf_form.c,dwarf_macro5.c: Ensure declarations + before executable statements + * dwarf_loc.c: Cast pointer to Dwarf_Small* so pointer arithmetic + works (standard conformance). + Ensure declarations before executable statements + * dwarf_macro5.c: Ensure declarations before executable statements. + * dwarf_query.c: Ensure declarations before executable statements. + Add dwarf_dietype_offset() convenience function. + * dwarf_util.c: Use a local name that does not conflict + with standards. use mydw_errno, not errno. + * dwarf_frame2.c(dwarf_read_cie_fde_prefix): Add tests + to ensure we do not access past end of a section. +2016-01-19 David Anderson + * dwarf_form.c, dwarf_frame2.c,: Fix indentation and trailing whitespace. +2016-01-19 David Anderson + * dwarf_line.c, dwarf_line_table_reader_common.c, + dwarf_loc.c, dwarf_macro5.c, dwarf_query.c, pro_die.c: + Remove silly second ; from ;; where appropriate. +2016-01-19 David Anderson + * libdwarf.h.in, dwarf_error.c: New error numbers. + DW_DLE_LINE_STRP_OFFSET_BAD, DW_DLE_STRING_FORM_IMPROPER. + * dwarf_form.c: Added suport for DW_FORM_line_strp into + dwarf_form_string(). +2016-01-17 David Anderson + * dwarf_frame2.c: Added additional checks for + bad frame section. Looking for premature end of frame data. +2016-01-16 David Anderson + * libdwarf2.1.mm: Documented DWARF5 macro operations. + Version 2.38 + * libdwarf2.1.pdf: Regenerated. + * libdwarf2p.1.pdf: Regenerated following a trivial + clarification on cie production made a couple days ago. +2016-01-15 David Anderson + * pro_frame.h, pro_frame.c: The code adding a CIE for output + (dwarf_add_frame_cie()) + was simply assuming that the augmentation string passed in was + in stable storage. Now it uses strdup() to guarantee there + no surprises. +2016-01-14 David Anderson + * dwarf_query.c(dwarf_die_offsets): 'res ==' corrected to 'res ='. +2016-01-12 David Anderson + * dwarf_macro5.c: Fixed DW_MACRO_define/undef + calls of _dwarf_check_string_valid(). + Arranged to get the macro unit offset out + when creating context. + * libdwarf.h.in: Fixed declaration of dwarf_get_macro_context() + to get the macro unit offset out of it + so it can work properly in all contexts. + + diff --git a/thirdparty/dwarf/ChangeLog2017 b/thirdparty/dwarf/ChangeLog2017 new file mode 100644 index 00000000..87319c42 --- /dev/null +++ b/thirdparty/dwarf/ChangeLog2017 @@ -0,0 +1,388 @@ + +2017-12-01 David Anderson + * gennames.c: Update version string. +2017-12-01 David Anderson + * dwarf_frame2.c: dwarf_get_fde_augmentation_data() could + return data that would result in segfaulting in a caller. + Now the length is checked and if in error + then DW_DLE_AUG_DATA_LENGTH_BAD is set as the error. +2017-11-08 David Anderson + * dwarf_die_deliv.c(_dwarf_die_next_info_ptr): Dereferencing + a pointer not fully checked could lead to segv in libdwarf. + * dwarf_frame.c(_dwarf_get_return_address_reg): Dereferencing + a pointer not fully checked could lead to segv in libdwarf. + * dwarf_frame2.c(dwarf_create_cie_from_after_start): Dereferencing + a pointer not fully checked could lead to segv in libdwarf. + * dwarf_line_table_reader_common.c(_dwarf_read_line_table_header): + DW201711-002 fix. Dereferencing + pointers not fully checked could lead to segv in libdwarf. + * dwarf_query.c(_dwarf_die_attr_unsigned_constant): Dereferencing + a pointer not fully checked could lead to segv in libdwarf. +2017-11-01 David Anderson + * dwarf_frame.c(_dwarf_exec_frame_instr): + An invalid frame section with + a DW_CFA_advance_loc1 could result in dereferencing + an invalid pointer. Now fixed. +2017-10-29 David Anderson + * dwarf.h: There was a typo in DW_FORM_strx4. +2017-10-20 David Anderson + * dwarf_form.c: New function: dwarf_formdata16() reads + DW_FORM_data16. + * dwarf_query.c,dwarf_util.c: Added support for DW_FORM_data16. + * libdwarf.h.in: Declarations for new functions dwarf_add_AT_data16() + and dwarf_formdata16() and new datatype Dwarf_Form_Data16 (since there + is no numerical type we can use at present). +2017-10-15 David Anderson + * dwgetopt.c: Removing unused local variable 'found'. +2017-10-15 David Anderson + * dwgetopt.c,dwgetopt.h: Now handles simple long argument + names cases. +2017-10-05 David Anderson + * gennames.c: Update version string. +2017-10-13 David Anderson + * dwarf.h,libdwarf/dwarf_loc.c: Corrected spelling to + match its use in DWARF5: DW_SECT_LOC -> DW_SECT_LOCLISTS +2017-10-05 David Anderson + * tag_attr.list,dwarf.h,dwarf_die_deliv.c, dwarf_opaque.h, + dwarf_query.c,libdwarf.h.in: Changed DW_AT_ranges_base + spelling to DW_AT_rnglists_base to match the final + DWARF5 standard. +2017-09-26 David Anderson + * gennames.c: Update version string. + * dwarf_abbrev.c: See DW201709-001. A carefully + constructed invalid abbrev section could result + in a caller getting an invalid memory reference. + So an addtional 'if' statement catches the error now. +2017-08-22 David Anderson + * gennames.c: Update version string. +2017-08-21 David Anderson + * Makefile.in: Now 'make test', not 'make tests'. + So consistent test name with dwarfdump. + * configure.cmake: Improving the handling of libelf + (mainly for Windows) and simplifying this file. + * dwarf_init_finish.c: Fixed indentation errors. + * gennames.c: Update version string. +2017-07-27 David Anderson + * dwarf_init_finish.c(_dwarf_setup): Removed some dead code and + that simplified the the logic. Comments fixed + as some in this area were not correct (stale comments). +2017-07-24 David Anderson + * configure.in, configure.cmake, config.h.in: Renamed + LOCATION_OF_LIBELFHEADER to HAVE_LOCATION_OF_LIBELFHEADER + for consistency with config.h.in generally. + * configure: Regenerated +2017-07-24 David Anderson + * configure.in, configure.cmake, config.h.in: Consistent use of + LOCATION_OF_LIBELFHEADER so Windows can build libdwarf with + configure or cmake. + * configure: Regenerated +2017-07-08 David Anderson + * gennames.c: Update version string. +2017-07-06 David Anderson + * dwarf_query.c(_dwarf_get_value_ptr): Did an add that could + overflow and segv given certain fuzzing and a certain + run time data layout. Fixed so the bad data is detected now + and libdwarf returns an error code. A place + in _dwarf_extract_address_from_debug_addr() + that an overflow might possibly occur fixed too. +2017-06-29 David Anderson + * dwarf_elf_access.c: Added R_SPARC_TLS_DTPOFF32 + for the EM_SPARC32PLUS. +2017-06-03 David Anderson + * dwarf_form.c,dwarf_frame2.c: Now use + _dwarf_decode_s_leb128_chk(), the checked form. + * dwarf_leb.c: Deleted _dwarf_decode_u_leb128() and + _dwarf_decode_s_leb128(), they are no longer used. + * dwarf_reloc_386.h: Removed some trailing whitespace. + * dwarf_util.h: Removed READ_UNALIGNED macro. Removed + declarations of the deleted two functions + _dwarf_decode_u_leb128() and _dwarf_decode_s_leb128() +2017-05-30 David Anderson + * dwarf_die_deliv.c: Added commentary about the DW_AT_dwo_id + found only in experimental DWARF4. + * libdwarf.h.in: Added commentary about Dwarf_Sig8 struct. +2017-05-28 David Anderson + * gennames.c: Update version string. +2017-05-25 David Anderson + * gennames.c: Update version string. + * dwarf_reloc_386.h: Added so dwarfdump can print + i386 relocations sensibly. + * dwarf_elf_access.c: For WIN32 added dwarf_reloc_386.h include. +2017-05-18 David Anderson + * dwarf_elf_access.c: Added R_X86_64_PC32 to + the list of relocations we can expect to see. +2017-05-18 David Anderson + * dwarf_opaque.h: Now names _dwarf_destroy_group_map so the + group map destructor can be called when cleaning up a Dwarf_Debug. + * dwarf_alloc.c: Call _dwarf_destroy_group_map(). + * dwarf_groups.c: Implemented _dwarf_destroy_group_map() + to clean up the map. +2017-05-18 David Anderson + * dwarf_init_finish.c: One argument was unused in + is_a_special_section_semi_dwarf() so removed + that argument. Function is local (static) so safe + to change it. Avoids a compiler warning. +2017-05-18 David Anderson + * libdwarf2.1.mm: Filling in documentation of the new sections. + Rev 2.58. There is more on this to do. + * libdwarf2.1.pdf: Regenerated. + * dwarf_groups.c: Inserted a space so things lined up, one place. +2017-05-18 David Anderson + * libdwarf2.1.mm: Documenting new functions + including .debug_names access and group operations. + Rev 2.57. There is more on this to do. + * libdwarf2.1.pdf: Regenerated. +2017-05-18 David Anderson + * libdwarf2.1.mm: Documenting new functions + including .debug_names access and group operations. + Rev 2.56. +2017-05-14 David Anderson + * libdwarf2.1.mm: Added a comment about a special + case of dwarf_get_section_count(). Rev 2.55 now. + * CMakeLists.txt, Makefile.in: Add dwarf_groups.c(.o), + a new source file. + * dwarf_elf_access.c: Added trailing _doas to a local variable so + related uses easily found with grep. Added some sections to + the relocatables sections list. + * dwarf_errmsg_list.c: Added six new error codes related to groups. + * dwarf_groups.c: New file to deal with both split-dwarf and + comdat groups. Added section name to the struct for improved reporting from + dwarfdump. Much easier to understand groups this way. + Added array of dwo section names so those group 2 names get the + right group (and obviously get it right). + * dwarf_init_finish.c: most of the new code for groups is in this + file. Now accomodates non-dwarf + SHT_GROUP sections by figuring out they should + be ignored. Fixed some indentation issues. + Added critical commentary to make it easier to follow the + handling of groups. + * dwarf_die_deliv.c: Named a local for a call so the call would + not have an unadorned 0. + * dwarf_opaque.h: New fields for comdat groups. A new small + struct, Dwarf_Group_Data_s has the data so it's all in + one place. + * dwarf_query.c: Trailing blank lines deleted. + Added a few lines of #if 0 code, for debugging. + * libdwarf.h.in: New error codes and new functions for section + groups. +2017-04-29 David Anderson + * pro_arange.c,pro_init.c, pro_opaque.h, pro_section.c, pro_types.c: + Renamed de_reloc_name function pointer as + de_relocate_by_name_symbol. + Most relocation points use a single section-name elf symbol as + the relocation reference. + Renamed de_reloc_pair function pointer as + de_relocate_pair_by_symbol. + dump_bytes() debug code is now #if 0. Deleted set but not used + local variable in _dwarf_pro_generate_debuginfo(). +2017-04-21 David Anderson + * pro_section.c: Improved commentary on the abbrev section + offset and on the backpatch of overall CU length once CU + generated. +2017-04-20 David Anderson + * dwarf_die_deliv.c: declaration of local separated from definition + for easier insertion of debug stuff. Nothing substantive done. + * dwarf_errmsg_list.c,libdwarf.h.in: Added + DW_DLE_UNIT_TYPE_NOT_HANDLED. + * dwarf_util.c: Fixed setup of debug_info header field reader. + output code. +2017-04-20 David Anderson + * pro_section.c: A harmless(!) comment-within-comment + removed. +2017-04-20 David Anderson + * gennames.c: Update version string. +2017-04-20 David Anderson + * configure.in: Added additional gcc -W to --enable-wall. + * configure: Regenerated. + * dwarf_errmsg_list.c: Added new error codes in + new DWARF5 support. + * dwarf_line_table_reader_common.c: Improved comments and + added specific code for DWARF5 (just clarity here, + no real change). + * dwarf_opaque.h: Removed unused declaration of cc_at_comp_dir. + * dwarf_print_lines.c: Update copyright year. + * libdwarf.h.in: Added new DW_DLE codes. + * pro_alloc.c: Added tdestroy for the de_debug_line_str_hashtab + to support a .debug_line_str section. + * pro_arange.c: Renamed local variables for greater clarity + and fixed an improper length write to be offset_size. + * pro_die.c: Generalized _dwarf_insert_or_find_in_debug_str() + so it can apply to the debug_str or debug_line_str sections. + * pro_finish.c: We have new statistics arrangement + to aid in getting statistics on debug_str and + debug_line_str independently. + So a little change needed to get things to compile. + * pro_frame.c: Now sets cie_version properly for all + DWARF versions. + * pro_frame.h: cie_version field changed to proper size (Dwarf_Half). + * pro_init.c: Support for .debug_line_str strings added. + Corrected ancient serious botch in setting up 64bit output. + Tweaked the version setup a little (no real change). + Moved _dwarf_init_default_line_header_vals() call to + where it actually works right for getting version number. + * pro_line.c: Unified handling of include directories + and files so that we can reuse code readily. + Eliminating one internal struct declaration. + * pro_line.h: Added new fields for DWARF5 data. + Deleted struct Dwarf_P_Inc_Dir_s. + * pro_opaque.h: Rearranged section codes and strings + and added in DWARF5 sections. + Added fields to Dwarf_P_Line_Inits_s for DWARF5 support. + Revised struct Dwarf_P_Stats_s and Dwarf_P_Debug_s + for DWARF5 support. + * pro_section.c: Added DWARF5 sections to tables and + began the addition to generation of these sections. + Refactored debug_line header output for clarity, + DWARF5 support, and to avoid code duplication. +2017-04-19 David Anderson + * dwarf_opaque.h: Deleted the unused field cc_at_comp_dir. +2017-04-17 David Anderson + * pro_init.c(common_init): Handling of 64bit offsets + was coded wrong, the length field would be emitted + incorrectly (confusing standard 64bit offset dwarf + with non-standard IRIX 64bit offset dwarf). +2017-04-17 David Anderson + * gennames.c: Update version string. + * dwarf_dnames.c: Fixed indentation of a few lines. + * dwarf_frame2.c: Deleted the argument fde_eh_encoding_out + from the local function get_gcc_eh_augmentation() as + is not needed and got an annoying compiler warning. + * dwarf_print_lines.c: Removed trailing whitespace. +2017-04-16 David Anderson + * CMakeLists.txt: Added in the new files dwarf_dnames.c, .h +2017-04-16 David Anderson + * README: A common build problem and the fix are mentioned. + * configure.in: Added more checking messages and results so + easier diagnose problems. + * config.h.in,configure: Regenerated with GNU Autoconf 2.69 +2017-04-15 David Anderson + * dwarf_print_lines.c: Added a comment , a reminder + that _dwarf_print_line_context_record() was never + implemented. + * libdwarf.h.in: Deleted mistaken declarations + dwarf_srcfiles_b(), dwarf_get_macro(), + and dwarf_get_all_defined_macros(). + No such functions were ever defined. +2017-04-12 David Anderson + * gennames.c: Update version string. +2017-04-12 David Anderson + * dwarf_alloc.c: Renamed function as _dwarf_debugnames_destructor(). + * dwarf_dnames.c: Implemented a suite of new functions to allow + reading .debug_names. dwarf_debugnames_header() is + the entry point to get .debug_names information. + * dwarf_dnames.h: new structs and fields to complete + getting access to .debug_names section data. + * dwarf_form.c: Refactored so dwarf_dnames.c has + access to getting form data. + * dwarf_opaque.h: Declare new internal .debug_names + access functions. + * libdwarf.h.in: Declare new .debug_names functions + and new error codes. + * pro_section.c: Partial outline for generation of DWARF5 + .debug_names added. +2017-04-02 David Anderson + * dwarf.h: Corrected comment about DW_IDX_type_unit. + * dwarf_alloc.c, dwarf_alloc.h: Added support for .debug_names + and Dwarf_Dnames_Head. + * dwarf_dnames.c,dwarf_dnames.h: Skeleton implemenatation + of .debug_denames section reader. + * dwarf_errmsg_list.c: Added new *DEBUG_NAMES* error codes. + * libdwarf.h.in: New *DEBUG_NAMES* and new Dwarf_Dnames_Head type. + * pro_opaque.h: Now defines DEBUG_NAMES + * pro_section.c: Now defines _dwarf_pro_generate_debug_names, + and _dwarf_pro_generate_debug_names. + A skeleton implementation. +2017-04-02 David Anderson + * checkexamples.c: Slight change in a comment. + * libdwarf.h.in: Added commentary. + * libdwarf2.1.mm: Document dwarf_init_b(), dwarf_elf_init_b() + and dwarf_object_init_b(). + * libdwarf2.1.pdf: Regenerate. Version 2.54 +2017-04-02 David Anderson + * gennames.c: Update version string. +2017-04-02 David Anderson + * dwarf_init_finish.c(determine_target_group): Correct the default + group number code so the if() tests work properly. +2017-03-30 David Anderson + * gennames.c: Update version string. +2017-03-30 David Anderson + * dwarf_arange.c: Now uses DW_DLE_ADDRESS_SIZE_ZERO + to be more precise about the error found in the object. + * dwarf_die_deliv.c: Adding DWARF5 cu header reading. + Adding support to more fully support split dwarf. + Fixed some potential leaks (in case of erroneous DWARF). + New functions that add functionality where needed + to deal with reading split dwarf DWARF5. + * dwarf_errmsg_list.c: Clarified DW_DLE_ADDRESS_SIZE_ERROR + string and added DW_DLE_IMPROPER_DWO_ID DW_DLE_GROUPNUMBER_ERROR + and DW_DLE_ADDRESS_SIZE_ZERO. + * dwarf_form.c,dwarf_loc.c: Fixed trailing whitespace. + * dwarf_init_finish.c: Added support so split dwarf + can be read properly. + New function dwarf_object_init_b() is part of that support. + * dwarf_opaque.c: Added de_groupnumber. Clarified + some fields with commentary. + * dwarf_original_elf_init.c: New functions + dwarf_init_b() dwarf_elf_init_b() for groupnumber + support. + * dwarf_query.c: Removed trailing whitespace. + * dwarf_xu_index.c: Moved static declaration so it + is useful in more places in this source. + * libdwarf.h.in: Added DW_GROUPNUMBER_ANY, DW_GROUPNUMBER_BASE, + DW_GROUPNUMBER_DWO as part of giving better + split dwarf support. + Declared the new global functions mentioned just above. +2017-03-23 David Anderson + * dwarf_query.c(dwarf_dietype_offset): dwarf_dietype_offset() + leaked a Dwarf_Attribute. The one line fix + removes the leak. +2017-03-23 David Anderson + * gennames.c: Update version string. +2017-03-21 David Anderson + * dwarf_form.c: Vulnerability DW201703-006 + and DW201703-001 fixed. + Some types of form were not checked as being in bounds. + * dwarf_leb.c: Vulnerability DW201703-002 fixed. + A check for out of bounds was done after the + relevant dereference. Fixed. + * dwarf_loc.c: Vulnerability DW201703-005 fixed. + _dwarf_read_loc_expr_op() was failing to check for + a bounds violation. + * dwarf_query.c: Vulnerability DW201703-006. + A call to _dwarf_reference_outside_section() + did not pass a sufficiently careful argument list, + so a bounds violation was missed. + +2017-03-21 David Anderson + * checkexamples.c: Updated dwarf_discr_list example + with a cast to match function declaration. + * libdwarf2.1.mm: Updated dwarf_discr_list example + with a cast to match function declaration. + * libdwarf2.1.pdf: Regenerated. Version 2.53 + +2017-03-04 David Anderson + * dwarf_loc2.c(_dwarf_get_locdesc_c): Renamed to _dwarf_get_locdesc_op_c + and corrected the handling so offsets properly dealt with + and so a final empty operator is synthesized properly into an + end operator like DWARF5. +2017-01-30 David Anderson + * dwarf_die_deliv.c(_dwarf_make_CU_Context): Recent change + in dwarf.h for DWARF5 package files required a small change + here. + * dwarf_xu_index.c(dwarf_get_xu_section_names): Recent change + in dwarf.h for DWARF5 package files required a small change + here and in dwp_secnames[]. + * dwarf.h: Now matches final DWARF5. +2017-01-23 David Anderson + * config.h.in.cmake,configure,configure.cmake,configure.in, + CMakeLists.txt,Makefile.in: + Add checks for sys/elf_386.h sys/elf_amd64.h sys/elf_SPARC.h so + relocations noticed for Solaris. + Better diagostic about not-building archive or shared library. + * configure: Regenerated + * dwarf_elf_access.c: Ifdef added for sys/elf_386.h,sys/elf_amd64.h, + sys/elf_SPARC.h so Solaris relocations are found. + * Makefile.in +2017-01-02 David Anderson + * dwarf.h: DWARF5 added new DW_UT codes compared + to earlier DWARF5 drafts. diff --git a/thirdparty/dwarf/ChangeLog2018 b/thirdparty/dwarf/ChangeLog2018 new file mode 100644 index 00000000..a134837a --- /dev/null +++ b/thirdparty/dwarf/ChangeLog2018 @@ -0,0 +1,905 @@ +2018-12-21 David Anderson + * pdfbld.sh: Now more flexible for creating one or + both pdfs. + * libdwarf2.1.pdf: Regenerated rev 2.70 per + yesterday's .mm changes. +2018-12-20 David Anderson + * dwarf_elf_access.c,memcpy_swap.h,pro_alloc.h,pro_dnames.h: + Removing trailing whitespace, trailing blank lines. +2018-12-20 David Anderson + * dwarf_dnames.c,pro_dnames.h,pro_die.h: Remove some + uses of Dwarf_ufixed. + * pro_section.c: Remove some uses of Dwarf_ufixed + and instead of 2,4,8 use DWARF_HALF_SIZE, + DWARF_23BIT_SIZE or DWARF_64BIT_SIZE as appropriate. +2018-12-20 David Anderson + * Makefile.am: Adding new header memcpy_swap.h + to the headers list. + * dwarf_gdbindex.c,dwarf_init_finish.c,dwarf_machoread.c, + dwarf_object_detector.c, dwarf_peread.c: + Include memcpy_swap.h. + Use the new _dwarf_memcpy_noswap_bytes instead + of memcpy directly. + * pro_init.c: Include memcpy_swap.h. + Use the new _dwarf_memcpy_noswap_bytes instead + of memcpy directly. Delete local declaration + now memcpy_swap.h used here. + * dwarf_machoread.h,dwarf_peread.h: + mo_copy_word declaration adjustment + to match the new _dwarf_memcpy_noswap_bytes + * dwarf_incl.h: Put before "dwarf.h" and + "libdwarf.h" includes (and don't use <> on dwarf.h + or libdwarf.h as they may only be locally defined) + * dwarf_opaque.h: void return on de_copy_word now. + Delete ugly redeclaration of _dwarf_memcpy_swap_bytes. + * dwarf_util.c: Implement dwarf_get_endian_copy_function + so dwarfdump can swap bytes where it needs to (as in + printing frame instruction bytes). + And implement _dwarf_memcpy_noswap_bytes with + a void return. _dwarf_memcpy_swap_bytes now + also with void return. + * libdwarf.h.in: Declare the new function + dwarf_get_endian_copy_function(). + * pro_alloc.h: Add idempotency and ifdef __cplusplus. + * pro_incl.h: Delete pointless blank lines in the macro + definition area. + * pro_opaque.h: delete include. + No longer needed as de_copy_word no longer uses + size_t. +2018-12-19 David Anderson + * dwarf_elf_access.c(dwarf_get_elf): Now uses the new + format per-object-type to quickly figure out if there is + an Elf * open. +2018-12-19 David Anderson + * dwarf_errmsg_list.h: Added DW_DLE_IMAGE_FILE_UNKNOWN_TYPE. + * dwarf_error.c: Added dwarf_errmsg_by_number() + so one can get more complete messages when all we have + is an error number. + * dwarf_object_detector.c: For PE objects the correct + machine id for 64bit is 0x8664, not 0x8886. + * libdwarf.h.in: Added dwarf_errmsg_by_number() + and DW_DLE_IMAGE_FILE_UNKNOWN_TYPE. + Fixed a couple trailing white-space instances. + * pro_section.c: Removed the blank last line of the file. +2018-12-07 David Anderson + * pro_die.c pro_finish.c pro_forms.c pro_line.c: + Some lines were too long and one test for error + (from the last set of changes) + was written in a usable but non-standard way so + that's now done in the standard way. +2018-12-05 David Anderson + * dwarf_query.c: Removed useless blank lines. + * libdwarf.h.in: Many new producer functions so + the better return values of DW_DLV_OK/DW_DLV_ERROR + are available for every producer call. + The older functions are present and continue to work. + + * libdwarf2p.1.mm: Document the old (a couple + got left out earlier) and new producer + functions. + * libdwarf2p.1.pdf: Regenerated. Version 1.48. + * pro_arange.c, pro_die.c, pro_expr.c, pro_forms.c, + pro_frame.c,pro_funcs.c,pro_line.c,pro_opaque.h, + pro_pubnames.c,pro_reloc.c,pro_section.c,pro_types.c, + pro_vars.c,pro_weaks.c: New functions provided + so caller code is easier to read. The new + interfaces are more type-safe than before. +2018-11-29 David Anderson + * dwarf_abbrev.c: Now deals with DW_FORM_implicit_const + properly. + * dwarf_arange.c: Remove trailing whitespace. + * dwarf_die_deliv.c: Now deals with DW_FORM_implicit_const + properly. + * dwarf_machoread.c,dwarf_object_detector.c, + dwarf_peread.c: Remove + trailing whitespace and fix indentation. + * dwarf_opaque.h: Add ar_implicit_const to + Dwarf_Attribute_s to deal with the implicit const + FORM. + * dwarf_query.c: Now deals with DW_FORM_implicit_const + properly. + * dwarf_util.c: Remove trailing whitespace and + fix indentation. Now deals with DW_FORM_implicit_const + properly. + * libdwarf.h.in: Declare new function + dwarf_add_AT_implicit_const(). + * libdwarf_version.h: Updated version string. + * pro_die.h: Add abb_implicits to + Dwarf_P_Abbrev_s deal with the implicit const FORM. + * pro_forms.c: Implement dwarf_add_AT_implicit_const(). + * pro_opaque.h: Add Dwarf_Signed dsa_implicitvalue + to Dwarf_Sort_Abbrev_s for implicit value(s). + * pro_section.c: Now deals with DW_FORM_implicit_const + properly. + * pro_section.h: Now SECTION_TYPE defaults to 1 + as the suggested section type, + which is SHT_PROGBITS in Elf. See the comments + there. Used to depend on a #ifdef and sometimes + was defined SHT_MIPS_DWARF. + * libdwarf2p.1.mm: Document the new implicit + const function. + * libdwarf2p.1.pdf: Regenerate. Version 1.47. +2018-11-28 David Anderson + * CMakeLists.txt: The previous change failed to + deal with the new pe .h files properly. Fixed. + And, the SOURCES and HEADERS lists are now + on shorter lines so they fit in 70 characters. +2018-11-26 David Anderson + * Makefile.am: Added new files + * dwarf_pe_descr.h,dwarf_peread.c,dwarf_peread.h: + New files implementing reading DWARF from PE + object files. + * dwarf_arange.c: Notice some zero length + things in .debug_aranges and ignore them. + Only ever seen in a PE dll with DWARF . + Odd. Needs further checking. + * dwarf_die_deliv.c: Here too, check for zero length + CU and just move along. Same dll. + Odd. Needs further checking. + * dwarf_generic_init.c: Call the pe setup code. + * dwarf_init_finish.c: Delete useless blank line. + * dwarf_machoread.c: Add checks to catch + corrupted object files. + * dwarf_opaque.h: Add _dwarf_pe_setup(). + * dwarf_util.h: Some macro lines were too long. + Shortened so they are easier to read/verify. + * libdwarf_version.h: Updated version string. + * CMakeLists.txt: Added new pe files. +2018-11-24 David Anderson + * dwarf_object_detector.c: The same ASNAR bug + fixed here now. + * libdwarf_version.h: Updated date string. +2018-11-22 David Anderson + * dwarf_machoread.c: A bug in the ASNAR macro + for big-endian hosts lead to coredump reading + mach-o objects (of any endianness) on such hosts. +2018-11-20 David Anderson + * Makefile.am: The setup for cross-builds + was incomplete for errmsg_check. Fixed. + * dwarf_base_types.h: Removed a + nested include of libdwarfdefs.h. + * dwarf_incl.h: Moved the include of libdwarfdefs.h + to here. + * dwarf_errmsg_list.h: Added new (as yet + unused) error messages. + * dwarf_machoread.c: Added overview commentary. + * dwarf_test_errmsg_list.c: Improved error messages + in a few cases so errors detected are more + self-explanatory. + * libdwarf.h.in: Added new (as yet unused) error + message defines. +2018-11-06 David Anderson + * dwarf_machoread.c(_dwarf_macho_object_access_init): + Following a malloc the null + check referenced the wrong variable! +2018-11-05 David Anderson + * dwarf_machoread.c: Added a sanity check on mo_command_count + before adding it to anything. + Now malloc a Dwarf_Obj_Access_Interface_s so we + use a local function consistently. + We were freeing on an address of a local variable... + But only if a mach-o object was seriously corrupted. + * dwarf_object_detector.c: We now know we misinterpreted + a comment in the macho-loader header. DW_ENDIAN_SAME + (and _OPPOSITE) were inappropriate. + Endianness detection for PE and mach-o objects are fixed. + * libdwarf.h.in,dwarf_object_detector.h: Dropping + DW_ENDIAN_SAME and DW_ENDIAN_OPPOSITE as we + no longer use them. + * dwarf_macho_loader.h: Added commentary about + the MH_MAGIC etc values. + * libdwarf_version.h: Updated date string. +2018-11-01 David Anderson + * libdwarf_version.h: Updated date string. + * dwarf_machoread.c(dwarf_macho_load_dwarf_section_details64): + Had an off-by-one error (which was already corrected + in the *details32 function). If the last section + was DWARF related this bug caused a DWARF section to + appear unavailable. +2018-10-30 David Anderson + * libdwarf_version.h: Updated date string. +2018-10-24 David Anderson + * libdwarf2.1.mm: Added documentation on + new functions dwarf_object_detector_fd(), + dwarf_object_detector_path(), and dwarf_init_path(). + Fixed indentation many places (many still to fix). + * libdwarf2.1.pdf: Regenerated Reg 2.68. + * dwarf_macho_loader.h: Renamed from macho-loader.h + * Makefile.am: reflects name change. + * dwarf_machoread.c: Uses renamed macho structs. + * dwarf_machoread.h: Renames a couple macho structs. + Aligns fieldnames with the similar item in libdwarf.h. + * dwarf_object_detector.c: A build on 32bit machine + noticed a function-prototype inconsistency + in declaring dwarf_object_detector_path(). Fixed. + Now allows outpath, outlen + of the dwarf_object_detector_path() call to be zero, + suppressing macho dSYM subdirectory checks. +2018-10-23 David Anderson + * dw_elfstructs.h: Adding this for use with object readers. + * dwarf_init_finish.c: Fixed placement of blank line to + match standard source formatting. + * macho-loader.h: Now avoids direct use of integral + types. Uses macro to setup each member. + * dwarf_machoread.c: New macro ASNAR handles endianness + and uses the new struct member format in macho-loader.h + * dwarf_object_detector.c + * dwarf_reading.h: Simplified as a result of the new ASNAR + macro and the structs it helps with. + * libdwarf_version.h: New version string. +2018-10-20 David Anderson + * dwarf_machoread.c,dwarf_machoread.h: Moved macros from the .h + to the .c. + * dwarf_object_detector: Removed the need to know the correct + type of fields in object-defined headers. We know the lengths + and layouts and that suffices because we copy everything + anyway to deal with endianness. No more need to define t16 + or t32 as the 'right' type. +2018-10-19 David Anderson + * dwarf_version.h: Updated date string. + * dwarf_errmsg_list.h: New errors DW_DLE_ELF_CLASS_BAD(420), + DW_DLE_ELF_ENDIAN_BAD(421), DW_DLE_ELF_VERSION_BAD(422), + DW_DLE_FILE_TOO_SMALL(423),DW_DLE_PATH_SIZE_TOO_SMALL(424), + DW_DLE_BAD_TYPE_SIZE(425) for new checks for object + correctness. Of more than one object type. + * dwarf_generic_init.c: The new function + dwarf_init_path has a new type for the call to + dwarf_object_detector. + * dwarf_object_detector.c: Now works in the libdwarf context. + Contains checks for Elf, Mach-o and PE object files as well + as recognizing archives ( such as .a). + * dwarf_object_detector.h: Tweaked into final form. + * dwarf_opaque.h: Added de_filesize field as we usually + now know the file size for checking offsets. + * libdwarf.h.in: Added the DW_DLE named above. + declared dwarf_object_detector_path() and + dwarf_object_detector_fd() as public functions. + * pro_alloc.c: #ifdefd the include of malloc.h. +2018-10-17 David Anderson + * macho-loader.h: A header for reading mach-o dsym objects. + * dwarf_generic_init.c,dwarf_init_finish.c: Now modified to + support reading mach-o. + * dwarf_machoread.c,dwarf_machoread.h: Contains + the mach-o specific details. + * dwarf_object_read_common.c: New, has a + * dwarf_opaque.h + * dwarf_original_elf_init.c: now allows elf or mach-o objects + and calls the appropriate setup code. + * dwarf_reading.h: new common header for reading without libelf. + * pro_section.c: Fix trailing whitespace. +2018-10-15 David Anderson + * dwarf_version.h: Updated date string. + * dwarf_die_deliv.c: Now a sibling-offset error + returns an error of DW_DLE_SIBLING_OFFSET_WRONG. + Now the code avoids adding a corrupt value + to a pointer (thus properly detecting + DW_DLE_SIBLING_OFFSET_WRONG). + * libdwarf.h.in: Added DW_DLE_SIBLING_OFFSET_WRONG. + * dwarf_errmsg_list.h: Added DW_DLE_SIBLING_OFFSET_WRONG + to the errmsg strings list. +2018-10-14 David Anderson + * dwarf_version.h: Updated date string. + * pro_section.c: An extra 0-byte was being added + in generated DWARF + at the end of section as if the top level + was a sibling chain, and GNU readelf + noticed the wasted byte. No longer added. +2018-10-02 David Anderson + * dwarf_generic_init.c,dwarf_original_elf_init.c: + Fixed remaining indent issues. +2018-10-02 David Anderson + * Makefile.am: Tweaks for the object detector files. + * dwarf_errmsg_list.h,libdwarf.h.in: New error codes. + * dwarf_generic_init.c,dwarf_original_elf_init.c: + * Removed a function that just caused confusion, + it was doing two jobs. Now each job called where + needed. + * dwarf_object_detector.c,dwarf_object_detector.h: + tweeks for better error codes and trailing + spaces and indent issues. + * dwarf_opaque.h: Removed deleted function. +2018-10-02 David Anderson + * dwarf_object_detector.h,dwarf_object_detector.c: + To be used soon. +2018-09-29 David Anderson + * gennames.c: Fixed an indent issue in a comment. +2018-09-28 Carlos Alberto Enciso + * dwgetopt: Use size_t to remove conversion warning + on Windows platform. + * getnames.c: Generate '#ifdef __cplusplus/#endif' + include guards to + allow the inclusion of header files by C++ code. +2018-09-21 David Anderson + * CMakeLists.txt: Add dwarf_generic_init.c into + sources list. + * Makefile.am: Ensure all cmake files get into + releases. +2018-09-18 David Anderson + * dwarf_generic_init.c: Moved dwarf_finish() here + from dwarf_original_elf_init.c. + * dwarf_original_elf.c: Moved dwarf_finish() out of + this file. + * dwarf_init_finish.c: Corrected a comment. frmo->from +2018-09-18 David Anderson + * dwarf_generic_init.c: Moved dwarf_init() and dwarf_init_b() + to this new file. From dwarf_original_elf_init.c. + These functions will allow handling non-elf object DWARF + in the future. + * dwarf_original_elf_init.c: Functions moved to + dwarf_generic_init.c and _dwarf_elf_init_file_ownership + no longer static so + it can be called from dwarf_generic_init.c. + * Makefile.am: Add the new source file to the sources list. +2018-09-12 David Anderson + * dwarf_version.h: Updated date string. + * libdwarf.h.in: Corrected the use of + HAVE_NONSTANDARD_PRINTF_64_FORMAT. +2018-09-11 David Anderson + * libdwarf.h.in: Restored use of + HAVE_NONSTANDARD_PRINTF_64_FORMAT + for those needing that feature. +2018-09-02 David Anderson + * Makefile.am: Changed the way to build gennames + executable to the automake way, eliminating make warnings + when building. + * Makefile.in: regenerated. +2018-08-23 David Anderson + * CMakeLists.txt: Adjusted to fit new/changed file names. +2018-08-21 David Anderson + * Makefile.am: Now honors --enable-wall. + * dwarf_die_deliv.c,pro_section.c: Removed unused local variables. +2018-08-14 David Anderson + * libdwarf.h.in: DW_HARMLESS_ERROR_MSG_STRING_SIZE now + 300, c compiler noted 200 was too small for a + harmless-error sprintf string in dwarf_frame2.c (line 192). + * Makefile.am. Added CPPFLAGS_FOR_BUILD where it was + accidentally omitted. + * libdwarf_version.h: Updated the version date string. +2018-08-09 David Anderson + * Makefile.am: Added AM_TESTS_ENVIRONMENT enabling + make check from any build directory. + Also,add dwarf_test_errmsg_list.c to the files + in a release so make check can work + * runtests.sh: Handle the environment variable + AM_TESTS_ENVIRONMENT sets: DWTOPSRCDIR +2018-08-07 David Anderson + * libdwarf2.1.mm: Revised the argument list of + dwarf_get_real_section_name() to add compression + size information. + * libdwarf2.1.pdf: Regenerated version 2.67. + * dwarf_die_deliv.c: Added compression-size arguments + to call to + dwarf_get_real_section_name() and updated the string + additions to match. + * dwarf_init_finish.c: Update compression before/after + sizes in new fields dss_compressed_length + dss_uncompressed_length.. + * dwarf_opaque.h: Add the new dss_ fields. + * libdwarf.h.in: Revised prototype of + dwarf_get_real_section_name() +2018-08-06 David Anderson + * libdwarf2.1.mm: Revised the argument list of + dwarf_get_real_section_name() + so it works properly. + * libdwarf2.1.pdf: Regenerated version 2.66. + * dwarf_die_deliv.c: Added third argument to call to + dwarf_get_real_section_name() and updated the string + * dwarf_opaque.h: Added flag dss_ZLIB_compressed so we can report + compression more accurately. +2018-08-05 David Anderson + * dwarf_die_deliv.c: Was failing to report SHF_COMPRESSED in dwarfdump + do to mistake here (statement with no side effect!). +2018-08-05 David Anderson + * libdwarf_version.h: Updated version string. + * dwarf_errmsg_list.h: Support the new error code. + * dwarf_opaque.h: Fields to support dwarf_get_real_section_name(). + * dwarf_die_deliv.c: Implements dwarf_get_real_section_name(). + * dwarf_init_finish.c: Changes to support dwarf_get_real_section_name(). + * libdwarf.h.in: Declare dwarf_get_real_section_name(). Add + a new error code. + * libdwarf2.1.mm: Document dwarf_get_real_section_name(). + * libdwarf2.1.pdf: Regenerate. Version 2.65. +2018-08-04 David Anderson + * dwarf_util.h: Remove trailing whitespace. + * pro_dnames.h: Preliminary structs for writing .debug_names + * pro_section.c: Corrected a comment. Removed some debug + code. Fixed indent mistakes. + * pro_opaque.h: Fixed indent error. + * pro_init.c: Extracted Bernstein hash into its own function. + Fixed indent errors. +2018-08-02 David Anderson + * libdwarf_version.h: Updated version date. + * pro_section.c: #if 0 or comment out + some debug code. + * dwarf_util.c:Replaced accidental loss of 'do'. + * Makefile.am: Removed unused variables and references + to them. +2018-07-31 David Anderson + * Makefile.am: Move all but libdwarf*pdf out of the + /usr/local/share install set, keep them all in the + distribution set. +2018-07-31 David Anderson + * Makefile.am: add pro_dnames.h pro_dnames.c for + .debug_names support.. + * dwarf_errmsg_list.h: Add DW_DLE_DUP_ATTR_ON_DIE error + code. + * dwarf_frame2.c: Move qsort_compare up to top of + file to avoid a forward declaration. + * dwarf_init_finish.c: Additional comments. + * dwarf_util.c: Corrected comment. Moved local + variable declarations down to where needed. + * libdwarf.h.in: Declare new function + dwarf_force_debug_names() used for testing. + * pro_die.h: Add comment. + * pro_dnames.c: Remove junk whitespace. + * pro_forms.c(_dwarf_pro_add_at_to_die): + Add DW_AT_data_member_location, DW_AT_trampoline + to the allowed set. + * pro_opaque.h: Add de_dnames_sect to Dwarf_P_Debug_s. + * pro_section.c: Now sorts abbreviations by attribute + number. Refactors header generation to make + it easier to read the code. Refactors + _dwarf_pro_getabbrev() for clarity (using newly-sorted + abbreviation list). +2018-07-30 David Anderson + * pro_dnames.c, pro_dnames.h: New, these just placeholders + for the moment. To write out .debug_names. +2018-08-02 David Anderson + * Makefile.am: Removed unused variables and references + to them. + +2018-07-24 David Anderson + * libdwarf_version.h: Updated version string. + * dwarf_line_table_reader_common.h:Removed trailing whitespace + and fixed indentations. + * pro_line.c: Removed trailing whitespace. + * pro_reloc.c,pro_reloc.h: Defines + _dwarf_pro_pre_alloc_specific_reloc_slots(). + Deletes _dwarf_pro_pre_alloc_n_reloc_slots() + * pro_reloc_symbolic.c: Now uses + _dwarf_pro_pre_alloc_specific_reloc_slots() so + static analysis can understand what the code does. + Fixes Coverity CID 186978. + * pro_arange.c: Now uses + _dwarf_pro_pre_alloc_specific_reloc_slots + instead of + _dwarf_pro_pre_alloc_n_reloc_slots. +2018-07-24 David Anderson + * dwarf_init_finish.c(set_up_section): A simple + revision eliminates any copying and simplifies + the logic. And eliminates the use of safe_strcpy(). + * dwarf_util.h, dwarf_util.c: Remove safe_strcpy(). +2018-07-23 David Anderson + * Makefile.am: Make it impossible for Make to build the + libdwarf pdf files. We do not want users to be required + to have the pdf tools. + * pdfbld.sh: A script to build the libdwarf pdf files + when required (the .mm files rarely change). +2018-07-23 David Anderson + * libdwarf_version.h: Updated version string. + * pro_line.c: Added comments on the oddness + of some return values (signed vs unsigned and + error returns). + * dwarf_die_deliv.c: Removed a statement that + had no effect (A leftover of recent changes). + * gennames.c: Signed vs unsigned compare was accidental + in the code this generates. + Changed the local var to unsigned. +2018-07-22 David Anderson + * dwarf_init_finish.c: Now calls _dwarf_safe_strcpy() + so we are sure there is no string overrun. + * dwarf_util.c: Implements _dwarf_safe_strcpy(). + * dwarf_util.h: Declares _dwarf_safe_strcpy(). +2018-07-22 David Anderson + * pro_reloc_symbolic.c(_dwarf_symbolic_relocs_to_disk): + Coverity CID 186884. A much cleaner and more + readable fix. +2018-07-21 David Anderson + * libdwarf_version.h: Updated version string. + * dwarf_init_finish.c: Coverity CID 186884. + Revised the logic for clarity and added comments + too. + * libdwarf_version.h: Update version string. + * dwarf_dnames.c: Coverity CID 186887. + Encapsulating + DECODE_LEB128_UWORD_CK in a function + so we can catch an error + and free appropriate resources. + Fixed cases of error where DW_DLV_OK returned. + * dwarf_abbrev.c,dwarf_arange.c,dwarf_die_deliv.c, + dwarf_ranges.c,dwarf_tsearchhash.c: + Removed trailing whitespace. + * dwarf_xu_index.c: Coverity CID 186894. + We know the string length (2) so we just assign the + bytes directly avoiding any possibility of overrun. + * pro_reloc_symbolic.c(_dwarf_symbolic_relocs_to_disk): + Coverity CID 186978. + Was dereferencing a pointer after zeroing the + pointer, now fixed and the obfuscating single-call + function code moved to where used, deleted function. + * dwarf_macro.c: Coverity CID 186980. + Removed code testing for zero count as it is impossible + to get to that spot with count==0. + * pro_forms.c: The new return of error is now + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + to at least avoid a warning about this + necessary uglyness of pointer/integer confusion. + The dwarf reader (consumer) interfaces have none + of this. +2018-07-20 David Anderson + * dwarf_line_table_reader_common.h: Encapsulating + DECODE_LEB128_UWORD_CK in a function + so we can catch an error + and free appropriate resources. +2018-07-20 David Anderson + * dwarf_frame.c: Coverity CID 186901. + Removed duplicate check for dbg null. + * dwarf_macro5.c: Coverity CID 186890. + Was testing wrong status value. resattr -> lres +2018-07-20 David Anderson + * dwarf_arange.c(dwarf_get_aranges_list): Coverity CID 186976. + This function has a serious problem, it reads agranges + without knowing the CU version number so anything + with segment_selector != 0 could be read wrong. + Unless the compiler authors did in early versions + what DWARF4 called for in aranges: a segment selector + value. + * dwarf_elf_access.c(update_entry): Coverity CID 187700. + If we do not have + ELF64 symbol type available avoid letting us fall through + to dereference a null pointer. + * dwarf_print_lines.c(dwarf_print_lines): Coverity CID 186985. + Coverity CID 186973 + Remove if(){} as it is not needed. + * dwarf_macro.c(dwarf_get_macro_details): Coverity CID 186980. + Removed dead code for count==0 as count will be at least 1. + * pro_arange.c: Coverity CID 186974. + Delete redundant check for null. + * pro_section.c(dwarf_pro_getabbrev): Coverity CID 186983. + Avoid dereferencing forms/attrs if they are null. + * pro_forms.c(dwarf_add_AT_location_expr): Coverity CID 186984. + Was potentially reading more from input than could + possibly exist in the fixed-maximum-length input. + Coverity CID 186975. Make block_size Dwarf_Unsigned + to (possibly) avoid this warning. + * pro_expr.c(dwarf_add_expr_gen): Coverity CID 186987. + Add break; to the last case in the switch. + * pro_macinfo.c(dwarf_vendor_ext): Coverity CID 186988. + Coverity CIE 186981 + Deleting dead code. + * pro_types.c(_dwarf_transform_simplename_to_disk)): + Coverity CID 186977. Delete dead code. + * pro_init.c(common_init): Coverity CID 187001. Now we avoid + dereferencing a potentially NULL pointer abiname. + * pro_frame.c(dwarf_add_fde_inst): Coverity CID 186979. + Added missing check of 'res' variable. +2018-07-20 David Anderson + * libdwarf_version.h: Updated version string. + * pro_frame.c: Coverity CID 186989. Dereferenced tmpaug + before NULL check. Fixed. + * pro_section.c: Coverity CID 186990. copy-paste error + changed val_len to val_len2. + * dwarf_abbrev.c: Coverity CID 186982. dwarf_get_abbrev_count() + could leak Dwarf_Error. No longer can. + * dwarf_print_lines.c: Coverity CID 186973. Remove useless code. + * dwarf_ranges.c: Coverity CID 186909. Ensure null not + dereferenced. + * dwarf_dnames.c: Coverity CID 186899. If needed !firstdab, + not firstdab. Also, free local allocations on error. + * dwarf_dsc.c: Coverity CID 186898. Null check on wrong variable. + * dwarf_tsearchhash.c: Coverity CID 186893. Leak on error fixed. + * dwarf_query.c: Coverity CID 186892. Testing res, now res3. + * dwarf_macro5.c: Coverity CID 186891. Dead code moved to + correct place. + Coverity CID 186906. Only increment curopsonly if non-null. + * dwarf_dnames.c: Coverity CID 186889. Fixed leak on error. + * dwarf_die_deliv.c: Coverity CID 186888. Fixed: Removed + assignment overridden later. + Coverity CID 186904: deref before: null check, dataptr,dis. + * dwarf_frame2.c: Coverity CID 186885. Fixed: loop inappropriate. + Coverity CID 186908. Fixed test res->resf. + * dwarf_line_table_reader_common.h: Coverity CID 186886. + Fixed leak. +2018-07-16 David Anderson + * dwarf_incl.h: Refine ifdef of HAVE_STDAFX_H. + * dwarf_tsearch.h: Correcting web references in comments. + * pro_incl.h: Refine ifdef of HAVE_STDAFX_H. +2018-07-16 David Anderson + * Makefile.am: New, used by autotools to create configure. + * configure.ac, Makefile.in, config.h.in: Deleted. +2018-07-09 David Anderson + * dwarf_dnames.c: free(tmp) -> free(dab) +2018-06-19 David Anderson + * configure.ac, config.h.in: Removed + HAVE_NONSTANDARD_PRINTF_64_FORMAT. + * configure: Regenerated. +2018-06-19 David Anderson + * pro_util.h: Deleted unused sizeof_sbyte macro, + simplified sizeof_ubyte to 1. +2018-06-19 David Anderson + * dwarf_base_types.h,dwarf_die_deliv.c,dwarf_dnames.c, + dwarf_form.c,dwarf_frame.c,dwarf_frame2.c,dwarf_init_finish.c, + dwarf_loc2.h,dwarf_macro5.c,dwarf_query.c,dwarf_str_offsets.c, + dwarf_util.c,pro_opaque.h: Now defining using + DWARF_32BIT_SIZE DWARF_64BIT_SIZE DWARF_HALF_SIZE + instead of using sizeof(Dwarf_Unsigned) or sizeof(Dwarf_Half). + Making it clearer we're reading the size the standard + says the items are. +2018-06-14 David Anderson + * libdwarf.h.in: Simplified definitions of Dwarf_Unsigned etc + and DW_PR*. +2018-06-12 David Anderson + * dwarf_arange.c dwarf_base_types.h dwarf_die_deliv.c, + dwarf_dnames.c,dwarf_form.c,dwarf_frame.c,dwarf_global.c, + dwarf_line_table_reader_common.h,dwarf_loc.c,dwarf_macro5.c, + dwarf_opaque.h,dwarf_str_offsets.c,dwarf_util.c,libdwarfdefs.h, + pro_arange.c,pro_section.c,pro_types.c,pro_util.h: + Now, if Dwarf_Half is not defined 16 bits it is likely + that everything will still work right. + We don't use sizeof(Dwarf_Half) now. +2018-06-12 David Anderson + * libdwarf.h.in: Removed Dwarf_Frame_Op3 + struct declaration. It was never used + and was a bad idea. A functional interface + is a likely replacement. +2018-05-30 David Anderson + * Fix botch in revised Makefile.in. +2018-05-30 David Anderson + * Makefile.in: Add gennames dependency on libdwarf_version.h + * libdwarf_version.h: Create to hold the + DW_VERSION_DATE_STR string. +2018-05-26 David Anderson + * gennames.c: + Update version string + * dwarf_arange.c: Instead of load_section(dbg,.debug_info, + and then *_abbrevr, call the combined _info and _abbrev + function _dwarf_load_debug_info() as is done everywhere else. +2018-05-24 David Anderson + * dwarf_aranges.c: Calling dwarf_get_aranges() + without loading .debug_info and .debug_abbrev + resulted in an error when checking for the + sanity of an offset into .debug_info: + DW_DLE_ARANGE_OFFSET_BAD. + Now libdwarf ensures the needed sections are loaded + because the 'section length' of compressed + sections is only correct after such are loaded. +2018-05-17 David Anderson + * config.h.in: Added #undef HAVE_VSNPRINTF HAVE_SNPRINTF + * configure: regenerated. + * configure.ac: Added AC_CHECK_FUNCS(snprintf) + AC_CHECK_FUNCS(vsnprintf) + * dwarf_alloc.c(_dwarf_free_all_of_one_debug): Added fclose + of dbg->de_printf_callback_null_device_handle. + * dwarf_opaque.h: Added de_printf_callback_null_device_handle + Dwarf_Debug member. + * dwarf_arange.c,dwarf_die_deliv.c,dwarf_frame2.c, + gennames.c: Use static buffers, not on-stack char + array targets for sprintf/snprintf. + Testing HAVE_SNPRINTF(HAVE_VSNPRINTF) and use c99 function + if present, else c90 + * dwarf_util.c: Putting null_device_handle in Dwarf_Debug + struct Use static buffers, not on-stack char array targets for + sprintf/snprintf. + Testing HAVE_SNPRINTF(HAVE_VSNPRINTF) and use c99 function + if present, else c90. +2018-05-16 David Anderson + * dwarf_leb.c, dwarf_util.c: Removed use of C99 + like vsnprintf. Now using C90. +2018-05-15 David Anderson + * dwarf_incl.h: Inserted include here. + stddef.h defines really basic useful C90 things like NULL. + * dwarf_opaque.h: Remove nested include stddef.h. +2018-05-15 David Anderson + * dwarf_incl.h: Removed dwarf_alloc.h include + * dwarf_abbrev.c,dwarf_alloc.c,dwarf_arange.c,dwarf_die_deliv.c, + dwarf_dnames.c,dwarf_dsc.c,dwarf_error.c,dwarf_form.c dwarf_frame.c, + dwarf_frame2.c,dwarf_gdbindex.c,dwarf_global.c,dwarf_incl.h, + dwarf_init_finish.c,dwarf_line.c,dwarf_loc.c,dwarf_macro.c, + dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c,dwarf_ranges.c, + dwarf_str_offsets.c,dwarf_util.c,dwarf_xu_index.c: + Added explicit include dwarf_alloc.h. +2018-05-15 David Anderson + * Makefile.in: dwarf_frame3.c now gone from build. + It should be removed. Nothing in it is used. + * dwarf_incl.h: Removed dwarf_error.h include + * dwarf_*: put includes in local normal order + and added include dwarf_error.h as needed + (in many files). +2018-05-15 David Anderson + * dwarf_incl.h: Removed dwarf_util.h include + * dwarf_abbrev.c,dwarf_alloc.c,dwarf_arange.c,dwarf_die_deliv.c, + dwarf_dnames.c,dwarf_form.c,dwarf_frame.c,dwarf_frame2.c, + dwarf_gdbindex.c,dwarf_global.c,dwarf_init_finish.c,dwarf_line.c, + dwarf_loc.c,dwarf_macro5.c,dwarf_print_lines.c,dwarf_query.c, + dwarf_ranges.c,dwarf_str_offsets.c,dwarf_util.c,dwarf_xu_index.c, + dwarf_string.c,dwarf_macro.c: Added include dwarf_util.h. +2018-05-15 David Anderson + * dwarf_die_deliv.c,dwarf_dsc.c,dwarf_error.c, + dwarf_init_finish.c,dwarf_original_elf_init.c, + pro_error.c,pro_line.c: Removed the unnecessary + inclusion of elf.h. + * dwarf_incl.h: Removed the unnecessary + inclusion of elf.h, limits.h, and dwarf_xu_index.h. +2018-05-15 David Anderson + * dwarf_abbrev.c,dwarf_alloc.c,dwarf_die_deliv.c, + dwarf_dsc.c,dwarf_dsc.h,dwarf_elf_access.c,dwarf_error.h, + dwarf_gdbindex.h,dwarf_global.h,dwarf_groups.c, + dwarf_harmless.c,dwarf_harmless.h,dwarf_leb.c,dwarf_loc.h, + dwarf_loc2.h,dwarf_opaque.h,dwarf_print_lines.c, + dwarf_ranges.c,dwarf_string.c,dwarf_tsearch.h, + dwarf_tsearchhash.c,dwarf_util.c,dwarf_xu_index.c, + dwarf_xu_index.h,pro_alloc.c,pro_die.h,pro_finish.c, + pro_util.h: Removed trailing blank lines. + Updated copyright year. +2018-05-15 David Anderson + * dwarf_loc2.c, dwarf_line_table_reader_common.c, + dwarf_errmsg_list.c: Renamed to end in .h, not .c, + as these are all targets of #include. + * dwarf_test_errmsg_list.c: New file with the test code + extracted from dwarf_errmsg_list.c and #including + the new dwarf_errmsg_list.h + * Makefile.in: Renamings .c to .h and the errmsg checking + builds the new dwarf_test_errmsg_list.c + The -DTESTING in building dwarf_test_errmsg_list.c + is no longer necessary. + * dwarf_error.c, dwarf_line.c,dwarf_print_lines.c: + Reflect the .c->h renamings +2018-05-14 David Anderson + * libdwarf.h.in: Removed trailing whitespace. +2018-05-14 David Anderson + * libdwarf2.1.mm: Documented dwarf_get_fde_info_for_reg3_b(). + Refined some comments about frame data. + * libdwarf2.1.pdf: Regenerated. Version 2.64 +2018-05-14 David Anderson + * gennames.c: Updated version string. +2018-05-14 David Anderson + * dwarf_frame2.c: Do a thorough check of every non-zero + augmentation data length in a way that will catch + integer overflows. + * dwarf_str_offsets.c: Fixed a botch in the original + dwarf_dealloc in dwarf_close_str_offsets_table_access(). +2018-05-14 David Anderson + * dwarf_frame.c: Implemented dwarf_get_fde_info_for_reg3_b(). + * libdwarf.h.in: Fixed arg list for dwarf_get_fde_info_for_reg3_b. +2018-05-14 David Anderson + * libdwarf.h.in: Declare new frame function, + next commit will have the code in dwarf_frame.c. +2018-05-01 Carlos Alberto Enciso + * gennames.c: Reversed the order of calling process_args() + vs print_args(). There is no visible difference for + linux/unix, and is just to match the convention + now used in dwarfdump for the ordering. +2018-04-22 David Anderson + * gennames.c: Updated version string. + * libdwarf.h.in: Removed trailing comma from enumeration list. +2018-04-19 David Anderson + * dwgetopt.c: Changed to match correction in dwarfdump version. +2018-04-17 David Anderson + * dwgetopt.c: Changed to match correction in dwarfdump version. +2018-04-16 David Anderson + * dwarf_str_offsets.c: Removed debug call to dump_bytes() + * gennames.c: Updated version string. +2018-04-14 David Anderson + * CMakeLists.txt: Added new source/header files to cmake. +2018-04-14 David Anderson + * libdwarf2.1.mm: Complete doc on the new .debug_str_offsets + interfaces. + * Regenerated. Rev 2.63. +2018-04-13 David Anderson + * gennames.c: Updated version string. + * Makefile.in: Added dwarf_str_offsets.o to target list. + * checkexamples.c: Added example code for the .debug_str_offsets + section interfaces. + * dwarf_alloc.h: Update ALLOC_AREA_INDEX_TABLE_MAX for new + allocatable. + * dwarf_alloc.c:Add #include and array entry for DW_DLA_STR_OFFSETS + * libdwarf.h.in: + * dwarf_errmsg_list.c: Added new .debug_str_offsets section + reader error codes. + * dwarf_str_offsets.h: New. Hidden struct for .debug_str_offsets + interfaces. + * dwarf_str_offsets.c: New for .debug_str_offsets. + * libdwarf2.1.mm: Incomplete doc on the new interfaces. +2018-03-29 David Anderson + * configure.ac: Now uses AC_COMPILE_IFELSE + instead of AC_TRY_COMPILE. Substantial changes + along those lines. + * config.h.in, configure: Regenerated. +2018-03-28 David Anderson + * configure.ac: Replaces configure.in and + uses AC_COMPILE_IFELSE instead of the + deprecated AC_TRY_COMPILE. + * configure: Regenerated. + * config.h.in: Regenerated +2018-03-27 David Anderson + * configure.in: Cross compiling tested, working. + * configure: regenerated. +2018-03-25 David Anderson + * configure.in: Support for cross compiling + * configure: regenerated. + * Makefile.in: Support for cross compiling +2018-03-25 David Anderson + * Makefile.in: Add comments about what is built for build + system (as opposed to host or target). +2018-03-24 David Anderson + * checkexamples.c: This is just example code for + libdwarf2.1.mm, not part of libdwarf. Now + checked by cc for errors and organized in the + same order the examples appear in the .mm. + * dwarf_errmsg_list.c: Added error code + DW_DLE_LINE_HEADER_CORRUPT. + * dwarf_line.c(_dwarf_set_line_table_regs_default_values): + Add line-table header version number argument so the + function works for DWARF5 (and earlier as well). + Now uses dwarf_srclines_files_indexes() several places, + simplifying the code. + * dwarf_line.h: Adds new fields to Dwarf_Line_Context_s + so that dwarf_srclines_files_indexes() logic is + simple. + * dwarf_line_table_reader_common.c: Passes version number + to _dwarf_set_line_table_regs_default_values() so it + works right for DWARF5 (and for earlier DWARF). + * libdwarf.h.in: Added DW_DLE_LINE_HEADER_CORRUPT to + error list. Added function dwarf_srclines_files_indexes(). + * libdwarf2.1.mm: Rev 2.61. Document the new function + dwarf_srclines_files_indexes() + and update all examples for formatting and correct C. + * libdwarf2.1.pdf: Regenerated, Rev 2.61. +2018-03-22 David Anderson + * dwarf_line.c, dwarf_print_lines.c: Index file + numbers for all versions of DWARF (DWARF5 + indexes starting at 0). +2018-03-21 David Anderson + * gennames.c: Updated version string. +2018-03-21 David Anderson + * dwarf_elf_access.c: Allow for relocations on .debug_str_offsets. + * dwarf_errmsg_list.c: Clarified meaning of + DW_DLE_DIE_ABBREV_LIST_NULL, added new errors + DW_DLE_STR_OFFSETS_BASE_WRONG_FORM, + DW_DLE_DATA16_OUTSIDE_SECTION, + DW_DLE_LNCT_MD5_WRONG_FORM + * dwarf_form.c: Added support for DWARF5 new FORMs. + * dwarf_line.c: Added dwarf_srclines_files_data_b() + so clients needing DWARF5 line table support can + get the DW_LNCT_MD5 value if it is present. + * dwarf_line.h: Added support for the DWARF5 + MD5 data. + * dwarf_line_table_reader_common.c: Added + DW_LNCT_MD5 support. + * dwarf_opaque.h: Added _dwarf_extract_data16 so we do not + have code duplication reading this data. + * dwarf_print_lines.c: If MD5 present, we now print it. + * dwarf_query.c: Correct handling of form for + DW_AT_str_offsets_base. + * dwarf_util.c: Add support for DWARF5 FORMs. + * libdwarf.h.in: Define the values of the new + DW_DLE codes mentioned above. + Declare new function dwarf_srclines_files_data_b() + * libdwarf2.1.mm: Document new function. Rev 2.61. + * libdwarf2.1.pdf: Generated Rev 2.61 +2018-01-05 David Anderson + * dwarf_macro5.c(_dwarf_get_macro_ops_count_internal): + A test duplicated the preceding loop condition so + the body of the test was dead code. Removed the + dead code. +2018-01-29 David Anderson + * dwarf_arange.c: Improve and comment checks for + stepping off the end of arange data. + * dwarf_die_deliv.c: Make an error code + returned a bit more specific. + DW_DLA_DIE_BAD becomes DW_DLE_ABBREV_MISSING. + * dwarf_errmsg_list.c: Added new error codes + DW_DLE_ABBREV_MISSING DW_DLE_NO_TAG_FOR_DIE + DW_DLE_LOWPC_WRONG_CLASS DW_DLE_HIGHPC_WRONG_FORM. + * dwarf_form.c: Used DW_DLE_NO_TAG_FOR_DIE instead of + DW_DLA_DIE_BAD to make an error return more specific. + * dwarf_frame2.c: Add new checks for corrupted dwarf + frame data. + * dwarf_query.c: Added error check and changed + DW_DLE_DIE_BAD to DW_DLE_ABBREV_MISSING in one place. + Other DWARF corruption checks and error refinements added. + * libdwarf.h.in: Added the defines for the new DW_DLE + codes. +2018-01-29 David Anderson + * gennames.c: Update version string. + diff --git a/thirdparty/dwarf/NEWS b/thirdparty/dwarf/NEWS index c7560a4b..898ee040 100644 --- a/thirdparty/dwarf/NEWS +++ b/thirdparty/dwarf/NEWS @@ -1,3 +1,74 @@ +January 15, 2019 + All references to C data types spelled *int16* *int32* or + *int64* have been removed. Dwarf_Unsigned is used instead. + This simplifies builds in certain environments. +December 05, 2018 + Many new producer functions provided. Now no matter + what producer task is to be done there is a version + that returns DW_DLV_OK/DW_DLV_ERROR and no ugly + casting of return values is needed to check for success/failure. + All the old interfaces continue to work. + One can switch from + Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die die, + char* name, + Dwarf_Error* error); + (requires a cast to check return code DW_DLV_BADADDR) + to + int dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie, + char* current_working_directory, + Dwarf_P_Attribute * outattr, + Dwarf_Error* error); + (no cast,type safe) + for example. + The libdwarf2p.1.mm document table-of-contents + lists only the latest functions, but all the documentation + of all the earlier versions remain in the document as + subsections. +October 24, 2018 + Now supports reading MacOS dSYM object files. +May 17, 2017 + Now supports some COMDAT groups as well as split-dwarf. + Some new functions added so consumer code can know + what the sections and groups contain. + Some compilers emit groups findable only with relocation + data: libdwarf does not understand those groups. +April 02, 2017 + The consumer code now reads DWARF5 split-dwarf sections. + The functions dwarf_init_b() and dwarf_elf_init_b() + and dwarf_object_init_b() have a groupnumber argument + added. For non-split-dwarf objects the original + dwarf_init() and dwarf_elf_init() and + dwarf_object_init() functions continue to work properly. +September 11, 2016 + The producer code is getting a new batch of functions. + + For each existing producer call returning + a value other than DW_DLV_OK/DW_DLV_ERROR/DW_DLV_NO_ENTRY + a new function returning one of those three codes with + a pointer argument added to return the actual desired + value (that used to be the 'return'). + The existing calls require the caller to do ugly casting + to determine whether the call did its work or got an error. + The new calls have type-safe interfaces that separate + the desired result from the error-indication. + So producer calls look more like consumer calls. + + The existing historical producer interfaces will remain + unchanged and will continue to be supported. The + existing interfaces will simply call the new interfaces + so there is no code duplication: Old and new use the same + implementation. + + Source and binary compatibility is retained, but + users of the producer code can, when they wish, + partially or fully convert to the new interfaces. + + This work will be ongoing and gradual, not 'all at once'. + +August 27, 2016 + Now the producer is capable of producing .debug_str strings. + Strings are never duplicated in .debug_str. + See dwarf_pro_set_default_string_form() in libdwarf2p.1.pdf May 23, 2016 When building a shared-library the soname is set in the dynamic section "libdwarf.so.1". diff --git a/thirdparty/dwarf/README b/thirdparty/dwarf/README index dd5682af..981f440f 100644 --- a/thirdparty/dwarf/README +++ b/thirdparty/dwarf/README @@ -8,6 +8,16 @@ To build both, type ./configure --enable-shared make +April 16, 2017: Some people have had build problems, getting +errors like: +"dwarf_elf_access.c:238:21: warning: assignment makes +pointer from integer without a cast [enabled by default] + if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {" +That suggests that the libelf headers needed are missing. +On Ubuntu the command 'sudo apt-get install libelf-dev' +should solve this problem. + + January 30, 2013: libdwarf.h is no longer in the distribution, but libdwarf.h.in is identical to libdwarf.h. 'configure' copies libdwarf.h.in to libdwarf.h and whether libelf.h defines diff --git a/thirdparty/dwarf/checkexamples.c b/thirdparty/dwarf/checkexamples.c new file mode 100644 index 00000000..817c7edd --- /dev/null +++ b/thirdparty/dwarf/checkexamples.c @@ -0,0 +1,1621 @@ +/* The following are in libdwarf2.1.mm + to verify there are no silly typographical errors + in that document. + + These should not be built routinely nor + should it ever be executed. + + The code here is what user code should be, + hence the code typed here is + PUBLIC DOMAIN. + This file is not part of libdwarf, though + it appears in the same directory as libdwarf. + + compile with +cc -c -Wall -O0 -Wpointer-arith -Wdeclaration-after-statement \ +-Wextra -Wcomment -Wformat -Wpedantic -Wuninitialized \ +-Wno-long-long -Wshadow -Wbad-function-cast \ +-Wmissing-parameter-type -Wnested-externs checkexamples.c + + and expect to see lots of warnings, most of which + are nothing of interest. +*/ + + +#include "dwarf.h" +#include "libdwarf.h" +#include "stdlib.h" /* for free() */ +#include "string.h" /* for memcmp() */ + +#define FALSE 0 +#define TRUE 1 + +void example1(Dwarf_Die somedie) +{ + Dwarf_Debug dbg = 0; + Dwarf_Signed atcount; + Dwarf_Attribute *atlist; + Dwarf_Error error = 0; + Dwarf_Signed i = 0; + int errv; + + errv = dwarf_attrlist(somedie, &atlist,&atcount, &error); + if (errv == DW_DLV_OK) { + for (i = 0; i < atcount; ++i) { + /* use atlist[i] */ + dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); + } + dwarf_dealloc(dbg, atlist, DW_DLA_LIST); + } +} + +void example2(Dwarf_Debug dbg, Dwarf_Debug tieddbg) +{ + Dwarf_Error error = 0; + int res = 0; + + /* Do the dwarf_init_b() or dwarf_elf_init_b() + calls to set + dbg, tieddbg at this point. Then: */ + res = dwarf_set_tied_dbg(dbg,tieddbg,&error); + if (res != DW_DLV_OK) { + /* Something went wrong*/ + } +} + +void example3(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + int res = 0; + res = dwarf_set_tied_dbg(dbg,NULL,&error); + if (res != DW_DLV_OK) { + /* Something went wrong*/ + } +} + + +void examplesecgroup(Dwarf_Debug dbg) +{ + int res = 0; + Dwarf_Unsigned section_count = 0; + Dwarf_Unsigned group_count; + Dwarf_Unsigned selected_group = 0; + Dwarf_Unsigned group_map_entry_count = 0; + Dwarf_Unsigned *sec_nums = 0; + Dwarf_Unsigned *group_nums = 0; + const char ** sec_names = 0; + Dwarf_Error error = 0; + Dwarf_Unsigned i = 0; + + + res = dwarf_sec_group_sizes(dbg,§ion_count, + &group_count,&selected_group, &group_map_entry_count, + &error); + if(res != DW_DLV_OK) { + /* Something is badly wrong*/ + return; + } + /* In an object without split-dwarf sections + or COMDAT sections we now have + selected_group == 1. */ + sec_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); + if(!sec_nums) { + /* FAIL. out of memory */ + return; + } + group_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned)); + if(!group_nums) { + free(group_nums); + /* FAIL. out of memory */ + return; + } + sec_names = calloc(group_map_entry_count,sizeof(char*)); + if(!sec_names) { + free(group_nums); + free(sec_nums); + /* FAIL. out of memory */ + return; + } + + res = dwarf_sec_group_map(dbg,group_map_entry_count, + group_nums,sec_nums,sec_names,&error); + if(res != DW_DLV_OK) { + /* FAIL. Something badly wrong. */ + } + for( i = 0; i < group_map_entry_count; ++i) { + /* Now do something with + group_nums[i],sec_nums[i],sec_names[i] */ + } + free(group_nums); + free(sec_nums); + /* The strings are in Elf data. + Do not free() the strings themselves.*/ + free(sec_names); +} +void example4(Dwarf_Debug dbg,Dwarf_Die in_die,Dwarf_Bool is_info) +{ + Dwarf_Die return_sib = 0; + Dwarf_Error error = 0; + int res = 0; + + /* in_die might be NULL or a valid Dwarf_Die */ + res = dwarf_siblingof_b(dbg,in_die,is_info,&return_sib, &error); + if (res == DW_DLV_OK) { + /* Use return_sib here. */ + dwarf_dealloc(dbg, return_sib, DW_DLA_DIE); + /* return_sib is no longer usable for anything, we + ensure we do not use it accidentally with: */ + return_sib = 0; + } +} + + +void example5(Dwarf_Debug dbg,Dwarf_Die in_die) +{ + Dwarf_Die return_kid = 0; + Dwarf_Error error = 0; + int res = 0; + + res = dwarf_child(in_die,&return_kid, &error); + if (res == DW_DLV_OK) { + /* Use return_kid here. */ + dwarf_dealloc(dbg, return_kid, DW_DLA_DIE); + /* return_die is no longer usable for anything, we + ensure we do not use it accidentally with: */ + return_kid = 0; + } +} + +void example6(Dwarf_Debug dbg,Dwarf_Off die_offset,Dwarf_Bool is_info) +{ + Dwarf_Error error = 0; + Dwarf_Die return_die = 0; + int res = 0; + + res = dwarf_offdie_b(dbg,die_offset,is_info,&return_die, &error); + if (res == DW_DLV_OK) { + /* Use return_die here. */ + dwarf_dealloc(dbg, return_die, DW_DLA_DIE); + /* return_die is no longer usable for anything, we + ensure we do not use it accidentally with: */ + return_die = 0; + } else { + /* res could be NO ENTRY or ERROR, so no + dealloc necessary. */ + } +} + +void example7(Dwarf_Debug dbg, Dwarf_Die in_die,Dwarf_Bool is_info) +{ + int res = 0; + Dwarf_Off cudieoff = 0; + Dwarf_Die cudie = 0; + Dwarf_Error error = 0; + + res = dwarf_CU_dieoffset_given_die(in_die,&cudieoff,&error); + if(res != DW_DLV_OK) { + /* FAIL */ + return; + } + res = dwarf_offdie_b(dbg,cudieoff,is_info,&cudie,&error); + if(res != DW_DLV_OK) { + /* FAIL */ + return; + } + /* do something with cu_die */ + dwarf_dealloc(dbg,cudie, DW_DLA_DIE); +} + + +void example8(Dwarf_Debug dbg, Dwarf_Die somedie) +{ + Dwarf_Signed atcount = 0; + Dwarf_Attribute *atlist = 0; + Dwarf_Error error = 0; + int errv = 0; + + errv = dwarf_attrlist(somedie, &atlist,&atcount, &error); + if (errv == DW_DLV_OK) { + Dwarf_Signed i = 0; + + for (i = 0; i < atcount; ++i) { + /* use atlist[i] */ + dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR); + } + dwarf_dealloc(dbg, atlist, DW_DLA_LIST); + } +} + +void exampleoffset_list(Dwarf_Debug dbg, Dwarf_Off dieoffset, + Dwarf_Bool is_info) +{ + Dwarf_Unsigned offcnt = 0; + Dwarf_Off *offbuf = 0; + Dwarf_Error error = 0; + int errv = 0; + + errv = dwarf_offset_list(dbg,dieoffset, is_info, + &offbuf,&offcnt, &error); + if (errv == DW_DLV_OK) { + Dwarf_Unsigned i = 0; + + for (i = 0; i < offcnt; ++i) { + /* use offbuf[i] */ + } + dwarf_dealloc(dbg, offbuf, DW_DLA_LIST); + } +} + + +void example_discr_list(Dwarf_Debug dbg, + Dwarf_Die die, + Dwarf_Attribute attr, + Dwarf_Half attrnum, + Dwarf_Bool isunsigned, + Dwarf_Half theform, + Dwarf_Error *err) +{ + /* The example here assumes that + attribute attr is a DW_AT_discr_list. + isunsigned should be set from the signedness + of the parent of 'die' per DWARF rules for + DW_AT_discr_list. */ + enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN; + Dwarf_Half version = 0; + Dwarf_Half offset_size = 0; + int wres = 0; + + wres = dwarf_get_version_of_die(die,&version,&offset_size); + if (wres != DW_DLV_OK) { + /* FAIL */ + return; + } + fc = dwarf_get_form_class(version,attrnum,offset_size,theform); + if (fc == DW_FORM_CLASS_BLOCK) { + int fres = 0; + Dwarf_Block *tempb = 0; + fres = dwarf_formblock(attr, &tempb, err); + if (fres == DW_DLV_OK) { + Dwarf_Dsc_Head h = 0; + Dwarf_Unsigned u = 0; + Dwarf_Unsigned arraycount = 0; + int sres = 0; + + sres = dwarf_discr_list(dbg, + (Dwarf_Small *)tempb->bl_data, + tempb->bl_len, + &h,&arraycount,err); + if (sres == DW_DLV_NO_ENTRY) { + /* Nothing here. */ + dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); + return; + } + if (sres == DW_DLV_ERROR) { + /* FAIL . */ + dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); + return; + } + for(u = 0; u < arraycount; u++) { + int u2res = 0; + Dwarf_Half dtype = 0; + Dwarf_Signed dlow = 0; + Dwarf_Signed dhigh = 0; + Dwarf_Unsigned ulow = 0; + Dwarf_Unsigned uhigh = 0; + + if (isunsigned) { + u2res = dwarf_discr_entry_u(h,u, + &dtype,&ulow,&uhigh,err); + } else { + u2res = dwarf_discr_entry_s(h,u, + &dtype,&dlow,&dhigh,err); + } + if( u2res == DW_DLV_ERROR) { + /* Something wrong */ + dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); + dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); + return; + } + if( u2res == DW_DLV_NO_ENTRY) { + /* Impossible. u < arraycount. */ + dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); + dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); + return; + } + /* Do something with dtype, and whichever + of ulow, uhigh,dlow,dhigh got set. + Probably save the values somewhere. + Simple casting of dlow to ulow (or vice versa) + will not get the right value due to the nature + of LEB values. Similarly for uhigh, dhigh. + One must use the right call. */ + } + dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); + dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK); + } + } +} + +void example_loclistc(Dwarf_Debug dbg,Dwarf_Attribute someattr) +{ + Dwarf_Unsigned lcount = 0; + Dwarf_Loc_Head_c loclist_head = 0; + Dwarf_Error error = 0; + int lres = 0; + + lres = dwarf_get_loclist_c(someattr,&loclist_head,&lcount,&error); + if (lres == DW_DLV_OK) { + Dwarf_Unsigned i = 0; + + /* Before any return remember to call + dwarf_loc_head_c_dealloc(loclist_head); */ + for (i = 0; i < lcount; ++i) { + Dwarf_Small loclist_source = 0; + Dwarf_Small lle_value = 0; /* DWARF5 */ + Dwarf_Addr lopc = 0; + Dwarf_Addr hipc = 0; + Dwarf_Unsigned ulocentry_count = 0; + Dwarf_Locdesc_c locentry = 0; + + /* section_offset is the section offset of the expression, not + the location description prefix. */ + Dwarf_Unsigned section_offset = 0; + + /* locdesc_offset is the section offset of the + location description prefix. */ + Dwarf_Unsigned locdesc_offset = 0; + + lres = dwarf_get_locdesc_entry_c(loclist_head, + i, + &lle_value,&lopc,&hipc, + &ulocentry_count, + &locentry, + &loclist_source, + §ion_offset, + &locdesc_offset, + &error); + if (lres == DW_DLV_OK) { + /* Here, use loclist_source and + lle_value to determine what + sort of loclist it is and what to do with + the values. locentry_count will only be + more than zero if there is a set of location + operators. + One must use lle_value to determine how + to interpret lopc,hipc as sometimes they + are a target address and sometimes an + index into .debug_addr or even a length. */ + Dwarf_Unsigned j = 0; + int opres = 0; + Dwarf_Small op = 0; + + for (j = 0; i < ulocentry_count; ++i) { + Dwarf_Unsigned opd1 = 0; + Dwarf_Unsigned opd2 = 0; + Dwarf_Unsigned opd3 = 0; + Dwarf_Unsigned offsetforbranch = 0; + + opres = dwarf_get_location_op_value_c(locentry, + j,&op,&opd1, &opd2,&opd3,&offsetforbranch, + &error); + if (opres == DW_DLV_OK) { + /* Do something with the operators. */ + } else { + /*Something is wrong. */ + } + } + } else { + /* Something is wrong. Do something. */ + } + } + /* In case of error or any other situation where one + is giving up one can call dwarf_loc_head_c_dealloc() + to free all the memory associated with loclist_head. */ + dwarf_loc_head_c_dealloc(loclist_head); + loclist_head = 0; + } +} + +void example_locexprc(Dwarf_Debug dbg,Dwarf_Ptr expr_bytes, + Dwarf_Unsigned expr_len, + Dwarf_Half addr_size, + Dwarf_Half offset_size, + Dwarf_Half version) +{ + Dwarf_Loc_Head_c head = 0; + Dwarf_Locdesc_c locentry = 0; + int res2 = 0; + Dwarf_Unsigned lopc = 0; + Dwarf_Unsigned hipc = 0; + Dwarf_Unsigned ulistlen = 0; + Dwarf_Unsigned ulocentry_count = 0; + Dwarf_Unsigned section_offset = 0; + Dwarf_Unsigned locdesc_offset = 0; + Dwarf_Small lle_value = 0; + Dwarf_Small loclist_source = 0; + Dwarf_Unsigned i = 0; + Dwarf_Error error = 0; + + res2 = dwarf_loclist_from_expr_c(dbg, + expr_bytes,expr_len, + addr_size, + offset_size, + version, + &head, + &ulistlen, + &error); + if(res2 == DW_DLV_NO_ENTRY) { + return; + } + if(res2 == DW_DLV_ERROR) { + return; + } + /* These are a location expression, not loclist. + So we just need the 0th entry. */ + res2 = dwarf_get_locdesc_entry_c(head, + 0, /* Data from 0th LocDesc */ + &lle_value, + &lopc, &hipc, + &ulocentry_count, + &locentry, + &loclist_source, + §ion_offset, + &locdesc_offset, + &error); + if (res2 == DW_DLV_ERROR) { + dwarf_loc_head_c_dealloc(head); + return; + } else if (res2 == DW_DLV_NO_ENTRY) { + dwarf_loc_head_c_dealloc(head); + return; + } + /* ASSERT: ulistlen == 1 */ + for (i = 0; i < ulocentry_count;++i) { + Dwarf_Small op = 0; + Dwarf_Unsigned opd1 = 0; + Dwarf_Unsigned opd2 = 0; + Dwarf_Unsigned opd3 = 0; + Dwarf_Unsigned offsetforbranch = 0; + + res2 = dwarf_get_location_op_value_c(locentry, + i, &op,&opd1,&opd2,&opd3,&offsetforbranch, + &error); + /* Do something with the expression operator and operands */ + if (res2 != DW_DLV_OK) { + dwarf_loc_head_c_dealloc(head); + return; + } + } + dwarf_loc_head_c_dealloc(head); +} + +void example9(Dwarf_Debug dbg,Dwarf_Attribute someattr) +{ + Dwarf_Signed lcount = 0; + Dwarf_Locdesc **llbuf = 0; + Dwarf_Error error = 0; + int lres = 0; + + lres = dwarf_loclist_n(someattr, &llbuf,&lcount,&error); + if (lres == DW_DLV_OK) { + Dwarf_Signed i = 0; + for (i = 0; i < lcount; ++i) { + /* Use llbuf[i]. Both Dwarf_Locdesc and the + array of Dwarf_Loc it points to are + defined in libdwarf.h: they are + not opaque structs. */ + dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg,llbuf[i], DW_DLA_LOCDESC); + } + dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); + } +} + + +void examplea(Dwarf_Debug dbg,Dwarf_Attribute someattr) +{ + Dwarf_Signed lcount = 0; + Dwarf_Locdesc *llbuf = 0; + Dwarf_Error error = 0; + int lres = 0; + + lres = dwarf_loclist(someattr, &llbuf,&lcount,&error); + if (lres == DW_DLV_OK) { + /* lcount is always 1, (and has always been 1) */ + /* Use llbuf here. */ + + dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); + } +} + +void exampleb(Dwarf_Debug dbg,Dwarf_Ptr data, Dwarf_Unsigned len) +{ + Dwarf_Signed lcount = 0; + Dwarf_Locdesc *llbuf = 0; + Dwarf_Error error = 0; + int lres = 0; + + lres = dwarf_loclist_from_expr(dbg,data,len, &llbuf,&lcount, + &error); + if (lres == DW_DLV_OK) { + /* lcount is always 1 */ + /* Use llbuf here.*/ + + dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); + } +} + + +void examplec(Dwarf_Die cu_die) +{ + /* EXAMPLE: DWARF5 style access. */ + Dwarf_Line *linebuf = 0; + Dwarf_Signed linecount = 0; + Dwarf_Line *linebuf_actuals = 0; + Dwarf_Signed linecount_actuals = 0; + Dwarf_Line_Context line_context = 0; + Dwarf_Signed linecount_total = 0; + Dwarf_Small table_count = 0; + Dwarf_Unsigned lineversion = 0; + Dwarf_Error err = 0; + int sres = 0; + /* ... */ + /* we use 'return' here to signify we can do nothing more + at this point in the code. */ + sres = dwarf_srclines_b(cu_die,&lineversion, + &table_count,&line_context,&err); + if (sres != DW_DLV_OK) { + /* Handle the DW_DLV_NO_ENTRY or DW_DLV_ERROR + No memory was allocated so there nothing + to dealloc. */ + return; + } + if (table_count == 0) { + /* A line table with no actual lines. */ + /*...do something, see dwarf_srclines_files_count() + etc below. */ + + dwarf_srclines_dealloc_b(line_context); + /* All the memory is released, the line_context + and linebuf zeroed now + as a reminder they are stale. */ + linebuf = 0; + line_context = 0; + } else if (table_count == 1) { + Dwarf_Signed i = 0; + Dwarf_Signed baseindex = 0; + Dwarf_Signed file_count = 0; + Dwarf_Signed endindex = 0; + /* Standard dwarf 2,3,4, or 5 line table */ + /* Do something. */ + + /* First let us index through all the files listed + in the line table header. */ + sres = dwarf_srclines_files_indexes(line_context, + &baseindex,&file_count,&endindex,&err); + if (sres != DW_DLV_OK) { + /* Something badly wrong! */ + return; + } + /* Works for DWARF2,3,4 (one-based index) + and DWARF5 (zero-based index) */ + for (i = baseindex; i < endindex; i++) { + Dwarf_Unsigned dirindex = 0; + Dwarf_Unsigned modtime = 0; + Dwarf_Unsigned flength = 0; + Dwarf_Form_Data16 *md5data = 0; + int vres = 0; + const char *name = 0; + + vres = dwarf_srclines_files_data_b(line_context,i, + &name,&dirindex, &modtime,&flength, + &md5data,&err); + if (vres != DW_DLV_OK) { + /* something very wrong. */ + return; + } + /* do something */ + } + + + /* For this case where we have a line table we will likely + wish to get the line details: */ + sres = dwarf_srclines_from_linecontext(line_context, + &linebuf,&linecount, + &err); + if (sres != DW_DLV_OK) { + /* Error. Clean up the context information. */ + dwarf_srclines_dealloc_b(line_context); + return; + } + /* The lines are normal line table lines. */ + for (i = 0; i < linecount; ++i) { + /* use linebuf[i] */ + } + dwarf_srclines_dealloc_b(line_context); + /* All the memory is released, the line_context + and linebuf zeroed now as a reminder they are stale */ + linebuf = 0; + line_context = 0; + linecount = 0; + } else { + Dwarf_Signed i = 0; + /* ASSERT: table_count == 2, + Experimental two-level line table. Version 0xf006 + We do not define the meaning of this non-standard + set of tables here. */ + + /* For 'something C' (two-level line tables) + one codes something like this + Note that we do not define the meaning or use of two-level line + tables as these are experimental, not standard DWARF. */ + sres = dwarf_srclines_two_level_from_linecontext(line_context, + &linebuf,&linecount, + &linebuf_actuals,&linecount_actuals, + &err); + if (sres == DW_DLV_OK) { + for (i = 0; i < linecount; ++i) { + /* use linebuf[i], these are the 'logicals' entries. */ + } + for (i = 0; i < linecount_actuals; ++i) { + /* use linebuf_actuals[i], these are the actuals entries */ + } + dwarf_srclines_dealloc_b(line_context); + line_context = 0; + linebuf = 0; + linecount = 0; + linebuf_actuals = 0; + linecount_actuals = 0; + } else if (sres == DW_DLV_NO_ENTRY) { + /* This should be impossible, but do something. */ + /* Then Free the line_context */ + dwarf_srclines_dealloc_b(line_context); + line_context = 0; + linebuf = 0; + linecount = 0; + linebuf_actuals = 0; + linecount_actuals = 0; + } else { + /* ERROR, show the error or something. + Free the line_context. */ + dwarf_srclines_dealloc_b(line_context); + line_context = 0; + linebuf = 0; + linecount = 0; + linebuf_actuals = 0; + linecount_actuals = 0; + } + } +} + +void exampled(Dwarf_Debug dbg,Dwarf_Die somedie) +{ + Dwarf_Signed count = 0; + Dwarf_Line *linebuf = 0; + Dwarf_Signed i = 0; + Dwarf_Error error = 0; + int sres = 0; + + sres = dwarf_srclines(somedie, &linebuf,&count, &error); + if (sres == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use linebuf[i] */ + } + dwarf_srclines_dealloc(dbg, linebuf, count); + } +} + +void examplee(Dwarf_Debug dbg,Dwarf_Die somedie) +{ + Dwarf_Signed count = 0; + char **srcfiles = 0; + Dwarf_Signed i = 0; + Dwarf_Error error = 0; + int res = 0; + + res = dwarf_srcfiles(somedie, &srcfiles,&count,&error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use srcfiles[i] */ + dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); + } + dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); + } +} + +void examplef(Dwarf_Debug dbg) +{ + Dwarf_Signed count = 0; + Dwarf_Global *globs = 0; + Dwarf_Signed i = 0; + Dwarf_Error error = 0; + int res = 0; + + res = dwarf_get_globals(dbg, &globs,&count, &error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use globs[i] */ + } + dwarf_globals_dealloc(dbg, globs, count); + } +} + + + +void exampleg(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Type *types = 0; + Dwarf_Signed i = 0; + int res = 0; + + res = dwarf_get_pubtypes(dbg, &types,&count, &error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use types[i] */ + } + dwarf_types_dealloc(dbg, types, count); + } +} + +void exampleh(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Weak *weaks = 0; + Dwarf_Signed i = 0; + int res = 0; + + res = dwarf_get_weaks(dbg, &weaks, &count, &error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use weaks[i] */ + } + dwarf_weaks_dealloc(dbg, weaks, count); + } +} + +void examplei(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Weak *weaks = 0; + Dwarf_Signed i = 0; + int res = 0; + + /* Obsolete, see exampleh instead */ + res = dwarf_get_weaks(dbg, &weaks, &count, &error); + if (res == DW_DLV_OK) { + /* OBSOLETE: do not use dealloc for this. + See above */ + for (i = 0; i < count; ++i) { + /* use weaks[i] */ + dwarf_dealloc(dbg, weaks[i], DW_DLA_WEAK); + } + dwarf_dealloc(dbg, weaks, DW_DLA_LIST); + } +} + +void examplej(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Func *funcs = 0; + Dwarf_Signed i = 0; + int fres = 0; + + fres = dwarf_get_funcs(dbg, &funcs, &count, &error); + if (fres == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use funcs[i] */ + } + dwarf_funcs_dealloc(dbg, funcs, count); + } +} + +void examplek(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Func *funcs = 0; + Dwarf_Signed count = 0; + Dwarf_Signed i = 0; + int fres = 0; + + fres = dwarf_get_funcs(dbg, &funcs,&count, &error); + if (fres == DW_DLV_OK) { + /* OBSOLETE: see dwarf_funcs_dealloc() above */ + for (i = 0; i < count; ++i) { + /* use funcs[i] */ + dwarf_dealloc(dbg, funcs[i], DW_DLA_FUNC); + } + dwarf_dealloc(dbg, funcs, DW_DLA_LIST); + } +} + +void examplel(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Type *types = 0; + Dwarf_Signed i = 0; + int res = 0; + + res = dwarf_get_types(dbg, &types,&count, &error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use types[i] */ + } + dwarf_types_dealloc(dbg, types, count); + } +} + +void examplem(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Type *types = 0; + Dwarf_Signed i = 0; + int res = 0; + + /* OBSOLETE: see dwarf_types_dealloc() above */ + res = dwarf_get_types(dbg, &types,&count, &error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use types[i] */ + dwarf_dealloc(dbg, types[i], DW_DLA_TYPENAME); + } + dwarf_dealloc(dbg, types, DW_DLA_LIST); + } +} + +void examplen(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Var *vars = 0; + Dwarf_Signed i = 0; + int res = 0; + res = dwarf_get_vars(dbg, &vars,&count,&error); + if (res == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use vars[i] */ + } + dwarf_vars_dealloc(dbg, vars, count); + } +} + + +void exampleo(Dwarf_Debug dbg) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Var *vars = 0; + Dwarf_Signed i = 0; + int res = 0; + res = dwarf_get_vars(dbg, &vars,&count,&error); + if (res == DW_DLV_OK) { + /* DO NOT USE: see dwarf_vars_dealloc() above */ + for (i = 0; i < count; ++i) { + /* use vars[i] */ + dwarf_dealloc(dbg, vars[i], DW_DLA_VAR); + } + dwarf_dealloc(dbg, vars, DW_DLA_LIST); + } +} + +void exampledebugnames(Dwarf_Debug dbg) +{ + /* FIXME need extended example of debugnames use. */ +} + + + +/* This builds an list or some other data structure + (not defined) to give an import somewhere to list + the import offset and then later to enquire + if the list has unexamined offsets. + A candidate set of hypothetical functions that + callers would write: + +has_unchecked_import_in_list() +get_next_import_from_list() +mark_this_offset_as_examined(macro_unit_offset); +add_offset_to_list(offset); + +*/ +void examplep5(Dwarf_Debug dbg, Dwarf_Die cu_die) +{ + int lres = 0; + Dwarf_Unsigned version = 0; + Dwarf_Macro_Context macro_context = 0; + Dwarf_Unsigned macro_unit_offset = 0; + Dwarf_Unsigned number_of_ops = 0; + Dwarf_Unsigned ops_total_byte_len = 0; + Dwarf_Bool is_primary = TRUE; + unsigned k = 0; + Dwarf_Error err = 0; + + for(;;) { + if (is_primary) { + lres = dwarf_get_macro_context(cu_die, + &version,¯o_context, + ¯o_unit_offset, + &number_of_ops, + &ops_total_byte_len, + &err); + is_primary = FALSE; + } else { + if (has_unchecked_import_in_list()) { + macro_unit_offset = get_next_import_from_list(); + } else { + /* We are done */ + break; + } + lres = dwarf_get_macro_context_by_offset(cu_die, + macro_unit_offset, + &version, + ¯o_context, + &number_of_ops, + &ops_total_byte_len, + &err); + mark_this_offset_as_examined(macro_unit_offset); + } + + if (lres == DW_DLV_ERROR) { + /* Something is wrong. */ + return; + } + if (lres == DW_DLV_NO_ENTRY) { + /* We are done. */ + break; + } + /* lres == DW_DLV_OK) */ + for (k = 0; k < number_of_ops; ++k) { + Dwarf_Unsigned section_offset = 0; + Dwarf_Half macro_operator = 0; + Dwarf_Half forms_count = 0; + const Dwarf_Small *formcode_array = 0; + Dwarf_Unsigned line_number = 0; + Dwarf_Unsigned index = 0; + Dwarf_Unsigned offset =0; + const char * macro_string =0; + int lres2 = 0; + + lres2 = dwarf_get_macro_op(macro_context, + k, §ion_offset,¯o_operator, + &forms_count, &formcode_array,&err); + if (lres2 != DW_DLV_OK) { + /* Some error. Deal with it */ + dwarf_dealloc_macro_context(macro_context); + return; + } + switch(macro_operator) { + case 0: + /* Nothing to do. */ + break; + case DW_MACRO_end_file: + /* Do something */ + break; + case DW_MACRO_define: + case DW_MACRO_undef: + case DW_MACRO_define_strp: + case DW_MACRO_undef_strp: + case DW_MACRO_define_strx: + case DW_MACRO_undef_strx: + case DW_MACRO_define_sup: + case DW_MACRO_undef_sup: { + lres2 = dwarf_get_macro_defundef(macro_context, + k, + &line_number, + &index, + &offset, + &forms_count, + ¯o_string, + &err); + if (lres2 != DW_DLV_OK) { + /* Some error. Deal with it */ + dwarf_dealloc_macro_context(macro_context); + return; + } + /* do something */ + } + break; + case DW_MACRO_start_file: { + lres2 = dwarf_get_macro_startend_file(macro_context, + k,&line_number, + &index, + ¯o_string,&err); + if (lres2 != DW_DLV_OK) { + /* Some error. Deal with it */ + dwarf_dealloc_macro_context(macro_context); + return; + } + /* do something */ + } + break; + case DW_MACRO_import: { + lres2 = dwarf_get_macro_import(macro_context, + k,&offset,&err); + if (lres2 != DW_DLV_OK) { + /* Some error. Deal with it */ + dwarf_dealloc_macro_context(macro_context); + return; + } + add_offset_to_list(offset); + } + break; + case DW_MACRO_import_sup: { + lres2 = dwarf_get_macro_import(macro_context, + k,&offset,&err); + if (lres2 != DW_DLV_OK) { + /* Some error. Deal with it */ + dwarf_dealloc_macro_context(macro_context); + return; + } + /* do something */ + } + break; + } + } + dwarf_dealloc_macro_context(macro_context); + macro_context = 0; + } +} + +void examplep2(Dwarf_Debug dbg, Dwarf_Off cur_off) +{ + Dwarf_Error error = 0; + Dwarf_Signed count = 0; + Dwarf_Macro_Details *maclist = 0; + Dwarf_Signed i = 0; + Dwarf_Unsigned max = 500000; /* sanity limit */ + int errv = 0; + + /* Given an offset from a compilation unit, + start at that offset (from DW_AT_macroinfo) + and get its macro details. */ + errv = dwarf_get_macro_details(dbg, cur_off,max, + &count,&maclist,&error); + if (errv == DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use maclist[i] */ + } + dwarf_dealloc(dbg, maclist, DW_DLA_STRING); + } + /* Loop through all the compilation units macro info from zero. + This is not guaranteed to work because DWARF does not + guarantee every byte in the section is meaningful: + there can be garbage between the macro info + for CUs. But this loop will sometimes work. + */ + cur_off = 0; + while((errv = dwarf_get_macro_details(dbg, cur_off,max, + &count,&maclist,&error))== DW_DLV_OK) { + for (i = 0; i < count; ++i) { + /* use maclist[i] */ + } + cur_off = maclist[count-1].dmd_offset + 1; + dwarf_dealloc(dbg, maclist, DW_DLA_STRING); + } +} + +void exampleq(Dwarf_Debug dbg) +{ + Dwarf_Cie *cie_data = 0; + Dwarf_Signed cie_count = 0; + Dwarf_Fde *fde_data = 0; + Dwarf_Signed fde_count = 0; + Dwarf_Error error = 0; + int fres = 0; + + fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, + &fde_data,&fde_count,&error); + if (fres == DW_DLV_OK) { + dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, + fde_data,fde_count); + } +} + +/* OBSOLETE EXAMPLE */ +void exampleqb(Dwarf_Debug dbg) +{ + Dwarf_Cie *cie_data = 0; + Dwarf_Signed cie_count = 0; + Dwarf_Fde *fde_data = 0; + Dwarf_Signed fde_count = 0; + Dwarf_Error error = 0; + Dwarf_Signed i = 0; + int fres = 0; + + fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, + &fde_data,&fde_count,&error); + if (fres == DW_DLV_OK) { + for (i = 0; i < cie_count; ++i) { + /* use cie[i] */ + dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); + } + for (i = 0; i < fde_count; ++i) { + /* use fde[i] */ + dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); + } + dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); + dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); + } +} + + +void exampler(Dwarf_Debug dbg,Dwarf_Addr mypcval) +{ + /* Given a pc value + for a function find the FDE and CIE data for + the function. + Example shows basic access to FDE/CIE plus + one way to access details given a PC value. + dwarf_get_fde_n() allows accessing all FDE/CIE + data so one could build up an application-specific + table of information if that is more useful. */ + Dwarf_Cie *cie_data = 0; + Dwarf_Signed cie_count = 0; + Dwarf_Fde *fde_data = 0; + Dwarf_Signed fde_count = 0; + Dwarf_Error error = 0; + int fres = 0; + + fres = dwarf_get_fde_list_eh(dbg,&cie_data,&cie_count, + &fde_data,&fde_count,&error); + if (fres == DW_DLV_OK) { + Dwarf_Fde myfde = 0; + Dwarf_Addr low_pc = 0; + Dwarf_Addr high_pc = 0; + fres = dwarf_get_fde_at_pc(fde_data,mypcval, + &myfde,&low_pc,&high_pc, + &error); + if (fres == DW_DLV_OK) { + Dwarf_Cie mycie = 0; + fres = dwarf_get_cie_of_fde(myfde,&mycie,&error); + if (fres == DW_DLV_OK) { + /* Now we can access a range of information + about the fde and cie applicable. */ + } + } + dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count, + fde_data,fde_count); + } + /* ERROR or NO ENTRY. Do something */ +} + +void examples(Dwarf_Debug dbg,Dwarf_Cie cie, + Dwarf_Ptr instruction,Dwarf_Unsigned len) +{ + Dwarf_Signed count = 0; + Dwarf_Frame_Op *frameops = 0; + Dwarf_Error error = 0; + int res = 0; + + res = dwarf_expand_frame_instructions(cie,instruction,len, + &frameops,&count, &error); + if (res == DW_DLV_OK) { + Dwarf_Signed i = 0; + + for (i = 0; i < count; ++i) { + /* use frameops[i] */ + } + dwarf_dealloc(dbg, frameops, DW_DLA_FRAME_BLOCK); + } +} + +void examplet(Dwarf_Debug dbg,Dwarf_Unsigned offset) +{ + /* Looping through the dwarf_loc section finding loclists: + an example. */ + int res; + Dwarf_Unsigned next_entry = 0; + Dwarf_Addr hipc_off = 0; + Dwarf_Addr lowpc_off = 0; + Dwarf_Ptr data = 0; + Dwarf_Unsigned entry_len = 0; + Dwarf_Error err = 0; + + for(;;) { + res = dwarf_get_loclist_entry(dbg,offset,&hipc_off, + &lowpc_off, &data, &entry_len,&next_entry,&err); + if (res == DW_DLV_OK) { + /* A valid entry. */ + offset = next_entry; + continue; + } else if (res ==DW_DLV_NO_ENTRY) { + /* Done! */ + break; + } else { + /* Error! */ + break; + } + } +} + +/* We'll do in one function and not worry about + memory leakage to keep the example short. + dwarf_finish() will deallocate if we do not + do so here. */ +void examplestroffsets(Dwarf_Debug dbg) +{ + int res = 0; + Dwarf_Str_Offsets_Table sot = 0; + Dwarf_Unsigned wasted_byte_count = 0; + Dwarf_Unsigned table_count = 0; + Dwarf_Error error = 0; + + res = dwarf_open_str_offsets_table_access(dbg, &sot,&error); + if(res == DW_DLV_NO_ENTRY) { + /* No such table */ + return; + } + if(res == DW_DLV_ERROR) { + /* Something is very wrong. Print the error? */ + return; + } + for(;;) { + Dwarf_Unsigned unit_length =0; + Dwarf_Unsigned unit_length_offset =0; + Dwarf_Unsigned table_start_offset =0; + Dwarf_Half entry_size = 0; + Dwarf_Half version =0; + Dwarf_Half padding =0; + Dwarf_Unsigned table_value_count =0; + Dwarf_Unsigned i = 0; + Dwarf_Unsigned table_entry_value = 0; + + res = dwarf_next_str_offsets_table(sot, + &unit_length, &unit_length_offset, + &table_start_offset, + &entry_size,&version,&padding, + &table_value_count,&error); + if (res == DW_DLV_NO_ENTRY) { + /* We have dealt with all tables */ + break; + } + if (res == DW_DLV_ERROR) { + /* Something badly wrong. Do something. */ + return; + } + /* One could call dwarf_str_offsets_statistics to + get the wasted bytes so far, but we do not do that + in this example. */ + /* Possibly print the various table-related values + returned just above. */ + for (i=0; i < table_value_count; ++i) { + res = dwarf_str_offsets_value_by_index(sot,i, + &table_entry_value,&error); + if (res != DW_DLV_OK) { + /* Something is badly wrong. Do something. */ + return; + } + /* Do something with the table_entry_value + at this index. Maybe just print it. + It is an offset in .debug_str. */ + } + } + res = dwarf_str_offsets_statistics(sot,&wasted_byte_count, + &table_count,&error); + if (res == DW_DLV_OK) { + /* The wasted byte count is set. Print it or something. + One hopes zero bytes are wasted. + Print the table count if one is interested. */ + } + res = dwarf_close_str_offsets_table_access(sot,&error); + /* There is little point in checking the return value + as little can be done about any error. */ + sot = 0; +} + +void exampleu(Dwarf_Debug dbg) +{ + Dwarf_Signed count = 0; + Dwarf_Arange *arang = 0; + int res = 0; + Dwarf_Error error = 0; + + res = dwarf_get_aranges(dbg, &arang,&count, &error); + if (res == DW_DLV_OK) { + Dwarf_Signed i = 0; + + for (i = 0; i < count; ++i) { + /* use arang[i] */ + dwarf_dealloc(dbg, arang[i], DW_DLA_ARANGE); + } + dwarf_dealloc(dbg, arang, DW_DLA_LIST); + } +} +void examplev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Die die) +{ + Dwarf_Signed count = 0; + Dwarf_Ranges *ranges = 0; + Dwarf_Unsigned bytes = 0; + Dwarf_Error error = 0; + int res = 0; + res = dwarf_get_ranges_a(dbg,offset,die, + &ranges,&count,&bytes,&error); + if (res == DW_DLV_OK) { + Dwarf_Signed i; + for( i = 0; i < count; ++i ) { + Dwarf_Ranges *cur = ranges+i; + /* Use cur. */ + } + dwarf_ranges_dealloc(dbg,ranges,count); + } +} +void examplew(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Die die) +{ + Dwarf_Gdbindex gindexptr = 0; + Dwarf_Unsigned version = 0; + Dwarf_Unsigned cu_list_offset = 0; + Dwarf_Unsigned types_cu_list_offset = 0; + Dwarf_Unsigned address_area_offset = 0; + Dwarf_Unsigned symbol_table_offset = 0; + Dwarf_Unsigned constant_pool_offset = 0; + Dwarf_Unsigned section_size = 0; + Dwarf_Unsigned reserved = 0; + Dwarf_Error error = 0; + const char * section_name = 0; + int res = 0; + res = dwarf_gdbindex_header(dbg,&gindexptr, + &version,&cu_list_offset, &types_cu_list_offset, + &address_area_offset,&symbol_table_offset, + &constant_pool_offset, §ion_size, + &reserved,§ion_name,&error); + if (res == DW_DLV_NO_ENTRY) { + return; + } else if (res == DW_DLV_ERROR) { + return; + } + { + /* do something with the data */ + Dwarf_Unsigned length = 0; + Dwarf_Unsigned typeslength = 0; + Dwarf_Unsigned i = 0; + res = dwarf_gdbindex_culist_array(gindexptr, + &length,&error); + /* Example actions. */ + if (res == DW_DLV_OK) { + for(i = 0; i < length; ++i) { + Dwarf_Unsigned cuoffset = 0; + Dwarf_Unsigned culength = 0; + res = dwarf_gdbindex_culist_entry(gindexptr, + i,&cuoffset,&culength,&error); + if (res == DW_DLV_OK) { + /* Do something with cuoffset, culength */ + } + } + } + res = dwarf_gdbindex_types_culist_array(gindexptr, + &typeslength,&error); + if (res == DW_DLV_OK) { + for(i = 0; i < typeslength; ++i) { + Dwarf_Unsigned cuoffset = 0; + Dwarf_Unsigned tuoffset = 0; + Dwarf_Unsigned culength = 0; + Dwarf_Unsigned type_signature = 0; + res = dwarf_gdbindex_types_culist_entry(gindexptr, + i,&cuoffset,&tuoffset,&type_signature,&error); + if (res == DW_DLV_OK) { + /* Do something with cuoffset etc. */ + } + } + } + dwarf_gdbindex_free(gindexptr); + } +} +void examplewgdbindex(Dwarf_Gdbindex gdbindex) +{ + Dwarf_Unsigned list_len = 0; + Dwarf_Unsigned i = 0; + int res = 0; + Dwarf_Error err = 0; + + res = dwarf_gdbindex_addressarea(gdbindex, &list_len,&err); + if (res != DW_DLV_OK) { + /* Something wrong, ignore the addressarea */ + } + /* Iterate through the address area. */ + for( i = 0; i < list_len; i++) { + Dwarf_Unsigned lowpc = 0; + Dwarf_Unsigned highpc = 0; + Dwarf_Unsigned cu_index = 0; + res = dwarf_gdbindex_addressarea_entry(gdbindex,i, + &lowpc,&highpc, + &cu_index, + &err); + if (res != DW_DLV_OK) { + /* Something wrong, ignore the addressarea */ + return; + } + /* We have a valid address area entry, do something + with it. */ + } +} +void examplex(Dwarf_Gdbindex gdbindex) +{ + Dwarf_Unsigned symtab_list_length = 0; + Dwarf_Unsigned i = 0; + Dwarf_Error err = 0; + int res = 0; + + res = dwarf_gdbindex_symboltable_array(gdbindex, + &symtab_list_length,&err); + if (res != DW_DLV_OK) { + return; + } + for( i = 0; i < symtab_list_length; i++) { + Dwarf_Unsigned symnameoffset = 0; + Dwarf_Unsigned cuvecoffset = 0; + Dwarf_Unsigned cuvec_len = 0; + Dwarf_Unsigned ii = 0; + const char *name = 0; + res = dwarf_gdbindex_symboltable_entry(gdbindex,i, + &symnameoffset,&cuvecoffset, + &err); + if (res != DW_DLV_OK) { + return; + } + res = dwarf_gdbindex_string_by_offset(gdbindex, + symnameoffset,&name,&err); + if(res != DW_DLV_OK) { + return; + } + res = dwarf_gdbindex_cuvector_length(gdbindex, + cuvecoffset,&cuvec_len,&err); + if( res != DW_DLV_OK) { + return; + } + for(ii = 0; ii < cuvec_len; ++ii ) { + Dwarf_Unsigned attributes = 0; + Dwarf_Unsigned cu_index = 0; + Dwarf_Unsigned reserved1 = 0; + Dwarf_Unsigned symbol_kind = 0; + Dwarf_Unsigned is_static = 0; + + res = dwarf_gdbindex_cuvector_inner_attributes( + gdbindex,cuvecoffset,ii, + &attributes,&err); + if( res != DW_DLV_OK) { + return; + } + /* 'attributes' is a value with various internal + fields so we expand the fields. */ + res = dwarf_gdbindex_cuvector_instance_expand_value(gdbindex, + attributes, &cu_index,&reserved1,&symbol_kind, &is_static, + &err); + if( res != DW_DLV_OK) { + return; + } + /* Do something with the attributes. */ + } + } +} + +void exampley(Dwarf_Debug dbg, const char *type) +{ + /* type is "tu" or "cu" */ + int res = 0; + Dwarf_Xu_Index_Header xuhdr = 0; + Dwarf_Unsigned version_number = 0; + Dwarf_Unsigned offsets_count = 0; /*L */ + Dwarf_Unsigned units_count = 0; /* M */ + Dwarf_Unsigned hash_slots_count = 0; /* N */ + Dwarf_Error err = 0; + const char * ret_type = 0; + const char * section_name = 0; + + res = dwarf_get_xu_index_header(dbg, + type, + &xuhdr, + &version_number, + &offsets_count, + &units_count, + &hash_slots_count, + §ion_name, + &err); + if (res == DW_DLV_NO_ENTRY) { + /* No such section. */ + return; + } + if (res == DW_DLV_ERROR) { + /* Something wrong. */ + return; + } + /* Do something with the xuhdr here . */ + dwarf_xu_header_free(xuhdr); +} + +void examplez( Dwarf_Xu_Index_Header xuhdr, + Dwarf_Unsigned hash_slots_count) +{ + /* hash_slots_count returned by + dwarf_get_xu_index_header(), see above. */ + static Dwarf_Sig8 zerohashval; + + Dwarf_Error err = 0; + Dwarf_Unsigned h = 0; + + for( h = 0; h < hash_slots_count; h++) { + Dwarf_Sig8 hashval; + Dwarf_Unsigned index = 0; + Dwarf_Unsigned col = 0; + int res = 0; + + res = dwarf_get_xu_hash_entry(xuhdr,h, + &hashval,&index,&err); + if (res == DW_DLV_ERROR) { + /* Oops. hash_slots_count wrong. */ + return; + } else if (res == DW_DLV_NO_ENTRY) { + /* Impossible */ + return; + } else if (!memcmp(&hashval,&zerohashval, + sizeof(Dwarf_Sig8)) + && index == 0 ) { + /* An unused hash slot */ + continue; + } + /* Here, hashval and index (a row index into + offsets and lengths) are valid. */ + } +} + +void exampleza(Dwarf_Xu_Index_Header xuhdr, + Dwarf_Unsigned offsets_count, Dwarf_Unsigned index ) +{ + Dwarf_Error err = 0; + Dwarf_Unsigned col = 0; + /* We use 'offsets_count' returned by + a dwarf_get_xu_index_header() call. + We use 'index' returned by a + dwarf_get_xu_hash_entry() call. */ + for (col = 0; col < offsets_count; col++) { + Dwarf_Unsigned off = 0; + Dwarf_Unsigned len = 0; + const char * name = 0; + Dwarf_Unsigned num = 0; + int res = 0; + + res = dwarf_get_xu_section_names(xuhdr, + col,&num,&name,&err); + if (res != DW_DLV_OK) { + break; + } + res = dwarf_get_xu_section_offset(xuhdr, + index,col,&off,&len,&err); + if (res != DW_DLV_OK) { + break; + } + /* Here we have the DW_SECT_ name and number + and the base offset and length of the + section data applicable to the hash + that got us here. + Use the values.*/ + } +} + +void examplezb(void) +{ + const char * out = 0; + int res = 0; + + /* The following is wrong, do not do it! */ + res = dwarf_get_ACCESS_name(DW_TAG_entry_point,&out); + /* Nothing one does here with 'res' or 'out' + is meaningful. */ + + /* The following is meaningful.*/ + res = dwarf_get_TAG_name(DW_TAG_entry_point,&out); + if( res == DW_DLV_OK) { + /* Here 'out' is a pointer one can use which + points to the string "DW_TAG_entry_point". */ + } else { + /* Here 'out' has not been touched, it is + uninitialized. Do not use it. */ + } +} diff --git a/thirdparty/dwarf/dw_elfstructs.h b/thirdparty/dwarf/dw_elfstructs.h new file mode 100644 index 00000000..a032f238 --- /dev/null +++ b/thirdparty/dwarf/dw_elfstructs.h @@ -0,0 +1,203 @@ +/* +Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Typed in from the SystemV Application Binary Interface + but using char arrays instead of variables as + for reading we don't need the struct members to be + variables. This simplifies configure. + + https://www.uclibc.org/docs/elf-64-gen.pdf used as source + of Elf64 fields. + + It is expected code including this will have included + an official (for various definitions needed) + before including this. + + The structs were all officially defined so files + could be mapped in. Fields are arranged so + there will not be gaps and we need not deal with + alignment-gaps. +*/ + +#ifndef EI_NIDENT +#define EI_NIDENT 16 +#endif + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; + TYP(e_type,2); + TYP(e_machine,2); + TYP(e_version,4); + TYP(e_entry,4); + TYP(e_phoff,4); + TYP(e_shoff,4); + TYP(e_flags,4); + TYP(e_ehsize,2); + TYP(e_phentsize,2); + TYP(e_phnum,2); + TYP(e_shentsize,2); + TYP(e_shnum,2); + TYP(e_shstrndx,2); +} dw_elf32_ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; + TYP(e_type,2); + TYP(e_machine,2); + TYP(e_version,4); + TYP(e_entry,8); + TYP(e_phoff,8); + TYP(e_shoff,8); + TYP(e_flags,4); + TYP(e_ehsize,2); + TYP(e_phentsize,2); + TYP(e_phnum,2); + TYP(e_shentsize,2); + TYP(e_shnum,2); + TYP(e_shstrndx,2); +} dw_elf64_ehdr; + +typedef struct +{ + TYP(p_type,4); + TYP(p_offset,4); + TYP(p_vaddr,4); + TYP(p_paddr,4); + TYP(p_filesz,4); + TYP(p_memsz,4); + TYP(p_flags,4); + TYP(p_align,4); +} dw_elf32_phdr; + +typedef struct +{ + TYP(p_type,4); + TYP(p_flags,4); + TYP(p_offset,8); + TYP(p_vaddr,8); + TYP(p_paddr,8); + TYP(p_filesz,8); + TYP(p_memsz,8); + TYP(p_align,8); +} dw_elf64_phdr; + +typedef struct +{ + TYP(sh_name,4); + TYP(sh_type,4); + TYP(sh_flags,4); + TYP(sh_addr,4); + TYP(sh_offset,4); + TYP(sh_size,4); + TYP(sh_link,4); + TYP(sh_info,4); + TYP(sh_addralign,4); + TYP(sh_entsize,4); +}dw_elf32_shdr; + +typedef struct +{ + TYP(sh_name,4); + TYP(sh_type,4); + TYP(sh_flags,8); + TYP(sh_addr,8); + TYP(sh_offset,8); + TYP(sh_size,8); + TYP(sh_link,4); + TYP(sh_info,4); + TYP(sh_addralign,8); + TYP(sh_entsize,8); +}dw_elf64_shdr; + +typedef struct +{ + TYP(r_offset,4); + TYP(r_info,4); +} dw_elf32_rel; + +typedef struct +{ + TYP(r_offset,8); + TYP(r_info,8); +} dw_elf64_rel; + +typedef struct +{ + TYP(r_offset,4); + TYP(r_info,4); + TYP(r_addend,4); /* signed */ +} dw_elf32_rela; + +typedef struct +{ + TYP(r_offset,8); + TYP(r_info,8); + TYP(r_addend,8); /* signed */ +} dw_elf64_rela; + + +typedef struct { + TYP(st_name,4); + TYP(st_value,4); + TYP(st_size,4); + unsigned char st_info[1]; + unsigned char st_other[1]; + TYP(st_shndx,2); +} dw_elf32_sym; + +typedef struct { + TYP(st_name,4); + unsigned char st_info[1]; + unsigned char st_other[1]; + TYP(st_shndx,2); + TYP(st_value,8); + TYP(st_size,8); +} dw_elf64_sym; + + +typedef struct +{ + TYP(d_tag,4); /* signed */ + TYP(d_val,4); /* Union in original */ +} dw_elf32_dyn; + +typedef struct +{ + TYP(d_tag,8); /* signed */ + TYP(d_val,8); /* Union in original */ +} dw_elf64_dyn; diff --git a/thirdparty/dwarf/dwarf.h b/thirdparty/dwarf/dwarf.h index a0152c73..bd4eea99 100644 --- a/thirdparty/dwarf/dwarf.h +++ b/thirdparty/dwarf/dwarf.h @@ -1,7 +1,7 @@ /* - Copyright (C) 2000,2001,2003,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. + Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2007-2015 David Anderson. All rights reserved. + Portions Copyright 2007-2017 David Anderson. All rights reserved. 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 @@ -51,6 +51,9 @@ extern "C" { Vendors should use a vendor string in names and whereever possible avoid duplicating values used by other vendor extensions + + The DWARF1 comments indicate values unused in + DWARF2 and later but used or reserved in DWARF1. */ @@ -59,15 +62,21 @@ extern "C" { #define DW_TAG_entry_point 0x03 #define DW_TAG_enumeration_type 0x04 #define DW_TAG_formal_parameter 0x05 +/* TAG_global_subroutine 0x06 DWARF1 only */ +/* TAG_global_variable 0x07 DWARF1 only */ #define DW_TAG_imported_declaration 0x08 +/* reserved by DWARF1 0x09 DWARF1 only */ #define DW_TAG_label 0x0a #define DW_TAG_lexical_block 0x0b +/* TAG_local_variable 0x0c DWARF1 only. */ #define DW_TAG_member 0x0d +/* reserved by DWARF1 0x0e DWARF1 only */ #define DW_TAG_pointer_type 0x0f #define DW_TAG_reference_type 0x10 #define DW_TAG_compile_unit 0x11 #define DW_TAG_string_type 0x12 #define DW_TAG_structure_type 0x13 +/* TAG_subroutine 0x14 DWARF1 only */ #define DW_TAG_subroutine_type 0x15 #define DW_TAG_typedef 0x16 #define DW_TAG_union_type 0x17 @@ -129,6 +138,8 @@ extern "C" { #define DW_TAG_atomic_type 0x47 /* DWARF5 */ #define DW_TAG_call_site 0x48 /* DWARF5 */ #define DW_TAG_call_site_parameter 0x49 /* DWARF5 */ +#define DW_TAG_skeleton_unit 0x4a /* DWARF5 */ +#define DW_TAG_immutable_type 0x4b /* DWARF5 */ #define DW_TAG_lo_user 0x4080 #define DW_TAG_MIPS_loop 0x4081 @@ -188,10 +199,15 @@ extern "C" { #define DW_TAG_hi_user 0xffff +/* The following two are non-standard. Use DW_CHILDREN_yes + and DW_CHILDREN_no instead. These could + probably be deleted, but someone might be using them, + so they remain. */ #define DW_children_no 0 #define DW_children_yes 1 #define DW_FORM_addr 0x01 +/* FORM_REF 0x02 DWARF1 only */ #define DW_FORM_block2 0x03 #define DW_FORM_block4 0x04 #define DW_FORM_data2 0x05 @@ -217,11 +233,24 @@ extern "C" { #define DW_FORM_flag_present 0x19 /* DWARF4 */ #define DW_FORM_strx 0x1a /* DWARF5 */ #define DW_FORM_addrx 0x1b /* DWARF5 */ -#define DW_FORM_ref_sup 0x1c /* DWARF5 */ +#define DW_FORM_ref_sup4 0x1c /* DWARF5 */ #define DW_FORM_strp_sup 0x1d /* DWARF5 */ #define DW_FORM_data16 0x1e /* DWARF5 */ #define DW_FORM_line_strp 0x1f /* DWARF5 */ #define DW_FORM_ref_sig8 0x20 /* DWARF4 */ +#define DW_FORM_implicit_const 0x21 /* DWARF5 */ +#define DW_FORM_loclistx 0x22 /* DWARF5 */ +#define DW_FORM_rnglistx 0x23 /* DWARF5 */ +#define DW_FORM_ref_sup8 0x24 /* DWARF5 */ +#define DW_FORM_strx1 0x25 /* DWARF5 */ +#define DW_FORM_strx2 0x26 /* DWARF5 */ +#define DW_FORM_strx3 0x27 /* DWARF5 */ +#define DW_FORM_strx4 0x28 /* DWARF5 */ +#define DW_FORM_addrx1 0x29 /* DWARF5 */ +#define DW_FORM_addrx2 0x2a /* DWARF5 */ +#define DW_FORM_addrx3 0x2b /* DWARF5 */ +#define DW_FORM_addrx4 0x2c /* DWARF5 */ + #define DW_FORM_GNU_addr_index 0x1f01 /* GNU extension in debug_info.dwo.*/ #define DW_FORM_GNU_str_index 0x1f02 /* GNU extension, somewhat like DW_FORM_strp */ #define DW_FORM_GNU_ref_alt 0x1f20 /* GNU extension. Offset in .debug_info. */ @@ -230,11 +259,17 @@ extern "C" { #define DW_AT_sibling 0x01 #define DW_AT_location 0x02 #define DW_AT_name 0x03 +/* reserved DWARF1 0x04, DWARF1 only */ +/* AT_fund_type 0x05, DWARF1 only */ +/* AT_mod_fund_type 0x06, DWARF1 only */ +/* AT_user_def_type 0x07, DWARF1 only */ +/* AT_mod_u_d_type 0x08, DWARF1 only */ #define DW_AT_ordering 0x09 #define DW_AT_subscr_data 0x0a #define DW_AT_byte_size 0x0b #define DW_AT_bit_offset 0x0c #define DW_AT_bit_size 0x0d +/* reserved DWARF1 0x0d, DWARF1 only */ #define DW_AT_element_list 0x0f #define DW_AT_stmt_list 0x10 #define DW_AT_low_pc 0x11 @@ -251,16 +286,25 @@ extern "C" { #define DW_AT_const_value 0x1c #define DW_AT_containing_type 0x1d #define DW_AT_default_value 0x1e +/* reserved 0x1f */ #define DW_AT_inline 0x20 #define DW_AT_is_optional 0x21 #define DW_AT_lower_bound 0x22 +/* reserved 0x23 */ +/* reserved 0x24 */ #define DW_AT_producer 0x25 +/* reserved 0x26 */ #define DW_AT_prototyped 0x27 +/* reserved 0x28 */ +/* reserved 0x29 */ #define DW_AT_return_addr 0x2a +/* reserved 0x2b */ #define DW_AT_start_scope 0x2c +/* reserved 0x2d */ #define DW_AT_bit_stride 0x2e /* DWARF3 name */ #define DW_AT_stride_size 0x2e /* DWARF2 name */ #define DW_AT_upper_bound 0x2f +/* AT_virtual 0x30, DWARF1 only */ #define DW_AT_abstract_origin 0x31 #define DW_AT_accessibility 0x32 #define DW_AT_address_class 0x33 @@ -273,13 +317,13 @@ extern "C" { #define DW_AT_decl_file 0x3a #define DW_AT_decl_line 0x3b #define DW_AT_declaration 0x3c -#define DW_AT_discr_list 0x3d +#define DW_AT_discr_list 0x3d /* DWARF2 */ #define DW_AT_encoding 0x3e #define DW_AT_external 0x3f #define DW_AT_frame_base 0x40 #define DW_AT_friend 0x41 #define DW_AT_identifier_case 0x42 -#define DW_AT_macro_info 0x43 /* DWARF2-DWARF4, not DWARF5 */ +#define DW_AT_macro_info 0x43 /* DWARF{234} not DWARF5 */ #define DW_AT_namelist_item 0x44 #define DW_AT_priority 0x45 #define DW_AT_segment 0x46 @@ -329,8 +373,11 @@ extern "C" { #define DW_AT_rank 0x71 /* DWARF5 */ #define DW_AT_str_offsets_base 0x72 /* DWARF5 */ #define DW_AT_addr_base 0x73 /* DWARF5 */ -#define DW_AT_ranges_base 0x74 /* DWARF5 */ -#define DW_AT_dwo_id 0x75 /* DWARF5 */ + /* Use DW_AT_rnglists_base, DW_AT_ranges_base is obsolete as */ + /* it was only used in some DWARF5 drafts, not the final DWARF5. */ +#define DW_AT_rnglists_base 0x74 /* DWARF5 */ + /* DW_AT_dwo_id, an experiment in some DWARF4+. Not DWARF5! */ +#define DW_AT_dwo_id 0x75 /* DWARF4!*/ #define DW_AT_dwo_name 0x76 /* DWARF5 */ #define DW_AT_reference 0x77 /* DWARF5 */ #define DW_AT_rvalue_reference 0x78 /* DWARF5 */ @@ -351,6 +398,9 @@ extern "C" { #define DW_AT_noreturn 0x87 /* DWARF5 */ #define DW_AT_alignment 0x88 /* DWARF5 */ #define DW_AT_export_symbols 0x89 /* DWARF5 */ +#define DW_AT_deleted 0x8a /* DWARF5 */ +#define DW_AT_defaulted 0x8b /* DWARF5 */ +#define DW_AT_loclists_base 0x8c /* DWARF5 */ /* In extensions, we attempt to include the vendor extension in the name even when the vendor leaves it out. */ @@ -453,6 +503,10 @@ extern "C" { /* To distinguish distinct basic blocks in a single source line. */ #define DW_AT_GNU_discriminator 0x2136 /* GNU */ +/* Ada GNAT gcc attributes. constant integer forms. */ +#define DW_AT_GNU_numerator 0x2303 /* GNU */ +#define DW_AT_GNU_denominator 0x2304 /* GNU */ +#define DW_AT_GNU_bias 0x2305 /* GNU */ @@ -512,6 +566,13 @@ extern "C" { #define DW_AT_use_GNAT_descriptive_type 0x2301 /* GNAT */ #define DW_AT_GNAT_descriptive_type 0x2302 /* GNAT */ +/* Go-specific type attributes */ +#define DW_AT_go_kind 0x2900 +#define DW_AT_go_key 0x2901 +#define DW_AT_go_elem 0x2902 +#define DW_AT_go_embedded_field 0x2903 /* Attribute for DW_TAG_member of a struct type. Nonzero value indicates the struct field is an embedded field. */ +#define DW_AT_go_runtime_type 0x2904 + /* UPC extension */ #define DW_AT_upc_threads_scaled 0x3210 /* UPC */ @@ -539,6 +600,7 @@ extern "C" { #define DW_AT_hi_user 0x3fff +/* OP values 0x01,0x02,0x04,0x05,0x07 are DWARF1 only */ #define DW_OP_addr 0x03 #define DW_OP_deref 0x06 #define DW_OP_const1u 0x08 @@ -789,31 +851,58 @@ extern "C" { #define DW_ATE_hi_user 0xff +/* DWARF5 Defaulted Member Encodings. */ #define DW_DEFAULTED_no 0x0 /* DWARF5 */ #define DW_DEFAULTED_in_class 0x1 /* DWARF5 */ #define DW_DEFAULTED_out_of_class 0x2 /* DWARF5 */ #define DW_IDX_compile_unit 0x1 /* DWARF5 */ -#define DW_IDX_type_unit 0x2 /* DWARF4 only */ +#define DW_IDX_type_unit 0x2 /* DWARF5 */ #define DW_IDX_die_offset 0x3 /* DWARF5 */ #define DW_IDX_parent 0x4 /* DWARF5 */ #define DW_IDX_type_hash 0x5 /* DWARF5 */ #define DW_IDX_lo_user 0x2000 /* DWARF5 */ #define DW_IDX_hi_user 0x0fff /* DWARF5 */ +/* These with not-quite-the-same-names were used in DWARF4 + and never official and should not be used by anyone. */ +#define DW_LLEX_end_of_list_entry 0x0 /* DWARF4 experimental */ +#define DW_LLEX_base_address_selection_entry 0x01 /* DWARF4 experimental */ +#define DW_LLEX_start_end_entry 0x02 /* DWARF4 experimental */ +#define DW_LLEX_start_length_entry 0x03 /* DWARF4 experimental */ +#define DW_LLEX_offset_pair_entry 0x04 /* DWARF4 experimental */ /* DWARF5 Location List Entries in Split Objects */ -#define DW_LLE_end_of_list_entry 0x0 /* DWARF5 */ -#define DW_LLE_base_address_selection_entry 0x01 /* DWARF5 */ -#define DW_LLE_start_end_entry 0x02 /* DWARF5 */ -#define DW_LLE_start_length_entry 0x03 /* DWARF5 */ -#define DW_LLE_offset_pair_entry 0x04 /* DWARF5 */ +#define DW_LLE_end_of_list 0x0 /* DWARF5 */ +#define DW_LLE_base_addressx 0x01 /* DWARF5 */ +#define DW_LLE_startx_endx 0x02 /* DWARF5 */ +#define DW_LLE_startx_length 0x03 /* DWARF5 */ +#define DW_LLE_offset_pair 0x04 /* DWARF5 */ +#define DW_LLE_default_location 0x05 /* DWARF5 */ +#define DW_LLE_base_address 0x06 /* DWARF5 */ +#define DW_LLE_start_end 0x07 /* DWARF5 */ +#define DW_LLE_start_length 0x08 /* DWARF5 */ + +/* DWARF5 Range List Entries */ +#define DW_RLE_end_of_list 0x00 /* DWARF5 */ +#define DW_RLE_base_addressx 0x01 /* DWARF5 */ +#define DW_RLE_startx_endx 0x02 /* DWARF5 */ +#define DW_RLE_startx_length 0x03 /* DWARF5 */ +#define DW_RLE_offset_pair 0x04 /* DWARF5 */ +#define DW_RLE_base_address 0x05 /* DWARF5 */ +#define DW_RLE_start_end 0x06 /* DWARF5 */ +#define DW_RLE_start_length 0x07 /* DWARF5 */ /* DWARF5 Unit header unit type encodings */ #define DW_UT_compile 0x01 /* DWARF5 */ #define DW_UT_type 0x02 /* DWARF5 */ #define DW_UT_partial 0x03 /* DWARF5 */ +#define DW_UT_skeleton 0x04 /* DWARF5 */ +#define DW_UT_split_compile 0x05 /* DWARF5 */ +#define DW_UT_split_type 0x06 /* DWARF5 */ +#define DW_UT_lo_user 0x80 /* DWARF5 */ +#define DW_UT_hi_user 0xff /* DWARF5 */ /* DWARF5 DebugFission object section id values @@ -826,10 +915,10 @@ extern "C" { #define DW_SECT_TYPES 2 /* .debug_types.dwo pre-DWARF5 */ #define DW_SECT_ABBREV 3 /* .debug_abbrev.dwo DWARF5 */ #define DW_SECT_LINE 4 /* .debug_line.dwo DWARF5 */ -#define DW_SECT_LOC 5 /* .debug_loc.dwo DWARF5 */ +#define DW_SECT_LOCLISTS 5 /* .debug_loclists.dwo DWARF5 */ #define DW_SECT_STR_OFFSETS 6 /* .debug_str_offsets.dwo DWARF5 */ -#define DW_SECT_MACINFO 7 /* .debug_macinfo.dwo DWARF5 */ -#define DW_SECT_MACRO 8 /* .debug_macro.dwo DWARF5 */ +#define DW_SECT_MACRO 7 /* .debug_macro.dwo DWARF5 */ +#define DW_SECT_RNGLISTS 8 /* .debug_rnglists.dwo DWARF5 */ /* Decimal Sign codes. */ @@ -837,7 +926,6 @@ extern "C" { #define DW_DS_leading_overpunch 0x02 /* DWARF3f */ #define DW_DS_trailing_overpunch 0x03 /* DWARF3f */ #define DW_DS_leading_separate 0x04 /* DWARF3f */ - #define DW_DS_trailing_separate 0x05 /* DWARF3f */ /* Endian code name. */ @@ -916,6 +1004,8 @@ extern "C" { #define DW_LANG_C_plus_plus_14 0x0021 /* DWARF5 */ #define DW_LANG_Fortran03 0x0022 /* DWARF5 */ #define DW_LANG_Fortran08 0x0023 /* DWARF5 */ +#define DW_LANG_RenderScript 0x0024 /* DWARF5 */ +#define DW_LANG_BLISS 0x0025 /* DWARF5 */ #define DW_LANG_lo_user 0x8000 #define DW_LANG_Mips_Assembler 0x8001 /* MIPS */ #define DW_LANG_Upc 0x8765 /* UPC, use @@ -938,6 +1028,8 @@ extern "C" { #define DW_CC_normal 0x01 #define DW_CC_program 0x02 #define DW_CC_nocall 0x03 +#define DW_CC_pass_by_reference 0x04 /* DWARF5 */ +#define DW_CC_pass_by_value 0x05 /* DWARF5 */ #define DW_CC_lo_user 0x40 #define DW_CC_GNU_renesas_sh 0x40 /* GNU */ @@ -975,6 +1067,19 @@ extern "C" { #define DW_DSC_label 0x00 #define DW_DSC_range 0x01 +/* Line number header entry format encodings. DWARF5 */ +#define DW_LNCT_path 0x1 /* DWARF5 */ +#define DW_LNCT_directory_index 0x2 /* DWARF5 */ +#define DW_LNCT_timestamp 0x3 /* DWARF5 */ +#define DW_LNCT_size 0x4 /* DWARF5 */ +#define DW_LNCT_MD5 0x5 /* DWARF5 */ +/* Experimental two-level line tables. Non standard */ +#define DW_LNCT_GNU_subprogram_name 0x6 +#define DW_LNCT_GNU_decl_file 0x7 +#define DW_LNCT_GNU_decl_line 0x8 +#define DW_LNCT_lo_user 0x2000 /* DWARF5 */ +#define DW_LNCT_hi_user 0x3fff /* DWARF5 */ + /* Line number standard opcode name. */ #define DW_LNS_copy 0x01 #define DW_LNS_advance_pc 0x02 @@ -1005,9 +1110,8 @@ extern "C" { /* Line number extended opcode name. */ #define DW_LNE_end_sequence 0x01 #define DW_LNE_set_address 0x02 -#define DW_LNE_define_file 0x03 +#define DW_LNE_define_file 0x03 /* DWARF4 and earlier only */ #define DW_LNE_set_discriminator 0x04 /* DWARF4 */ -#define DW_LNE_define_file_MD5 0x05 /* DWARF5 */ /* HP extensions. */ #define DW_LNE_HP_negate_is_UV_update 0x11 /* 17 HP */ @@ -1025,18 +1129,8 @@ extern "C" { #define DW_LNE_lo_user 0x80 /* DWARF3 */ #define DW_LNE_hi_user 0xff /* DWARF3 */ -/* Type codes for line number program content descriptors (DWARF 5). */ -#define DW_LNCT_path 0x1 -#define DW_LNCT_directory_index 0x2 -#define DW_LNCT_timestamp 0x3 -#define DW_LNCT_size 0x4 -#define DW_LNCT_MD5 0x5 -/* Experimental two-level line tables. */ -#define DW_LNCT_subprogram_name 0x6 -#define DW_LNCT_decl_file 0x7 -#define DW_LNCT_decl_line 0x8 - /* These are known values for DW_LNS_set_isa. */ +/* These identifiers are not defined by any DWARFn standard. */ #define DW_ISA_UNKNOWN 0 /* The following two are ARM specific. */ #define DW_ISA_ARM_thumb 1 /* ARM ISA */ @@ -1120,6 +1214,7 @@ extern "C" { http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html The upper 4 bits indicate how the value is to be applied. The lower 4 bits indicate the format of the data. + These identifiers are not defined by any DWARFn standard. */ #define DW_EH_PE_absptr 0x00 /* GNU */ #define DW_EH_PE_uleb128 0x01 /* GNU */ @@ -1159,6 +1254,7 @@ extern "C" { Assumes reg 0 never appears as a register in DWARF information. Usable for MIPS, but never a good idea, really. */ +/* These identifiers are not defined by any DWARFn standard. */ #define DW_FRAME_CFA_COL 0 #define DW_FRAME_REG1 1 /* integer reg 1 */ diff --git a/thirdparty/dwarf/dwarf_abbrev.c b/thirdparty/dwarf/dwarf_abbrev.c index 94997631..3e9523f2 100644 --- a/thirdparty/dwarf/dwarf_abbrev.c +++ b/thirdparty/dwarf/dwarf_abbrev.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. + Portions Copyright (C) 2009-2018 David Anderson. All Rights Reserved. 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 @@ -26,9 +25,12 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" #include "dwarf_abbrev.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" /* This is used to print a .debug_abbrev section without knowing about the DIEs that use the abbrevs. @@ -111,7 +113,7 @@ dwarf_get_abbrev(Dwarf_Debug dbg, DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, dbg,error,abbrev_section_end); - ret_abbrev->dab_code = (Dwarf_Word) utmp; + ret_abbrev->dab_code = utmp; if (ret_abbrev->dab_code == 0) { *returned_abbrev = ret_abbrev; *abbr_count = 0; @@ -124,6 +126,10 @@ dwarf_get_abbrev(Dwarf_Debug dbg, DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, dbg,error,abbrev_section_end); ret_abbrev->dab_tag = utmp; + if (abbrev_ptr >= abbrev_section_end) { + _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return DW_DLV_ERROR; + } ret_abbrev->dab_has_child = *(abbrev_ptr++); ret_abbrev->dab_abbrev_ptr = abbrev_ptr; @@ -137,9 +143,15 @@ dwarf_get_abbrev(Dwarf_Debug dbg, dbg,error,abbrev_section_end); attr_form = (Dwarf_Half) utmp2; if (!_dwarf_valid_form_we_know(dbg,attr_form,attr)) { - _dwarf_error(NULL, error, DW_DLE_UNKNOWN_FORM); + _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return (DW_DLV_ERROR); } + if (attr_form == DW_FORM_implicit_const) { + UNUSEDARG Dwarf_Signed implicit_const = 0; + /* The value is here, not in a DIE. */ + DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, + dbg,error,abbrev_section_end); + } if (attr != 0) { labbr_count++; } @@ -254,6 +266,12 @@ dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp4,abbrev->dab_dbg, error,abbrev_end); attr_form = (Dwarf_Half) utmp4; + if (attr_form == DW_FORM_implicit_const) { + UNUSEDARG Dwarf_Signed implicit_const; + /* The value is here, not in a DIE. */ + DECODE_LEB128_SWORD_CK( abbrev_ptr, implicit_const, + abbrev->dab_dbg,error,abbrev_end); + } } if (abbrev_ptr >= abbrev_end) { @@ -281,7 +299,9 @@ dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, or .debug_types need to be initialized to anything specific. Any garbage bytes may cause trouble. Not all compilers/linkers leave unreferenced garbage bytes in .debug_abbrev, so this may - work for most objects. */ + work for most objects. + In case of error could return a bogus value, there is + no documented way to detect error. */ int dwarf_get_abbrev_count(Dwarf_Debug dbg) { @@ -291,7 +311,7 @@ dwarf_get_abbrev_count(Dwarf_Debug dbg) Dwarf_Unsigned attr_count = 0; Dwarf_Unsigned abbrev_count = 0; int abres = DW_DLV_OK; - Dwarf_Error err; + Dwarf_Error err = 0; while ((abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &attr_count, @@ -301,6 +321,9 @@ dwarf_get_abbrev_count(Dwarf_Debug dbg) offset += length; dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); } + if (err) { + dwarf_dealloc(dbg,err,DW_DLA_ERROR); + err = 0; + } return abbrev_count; } - diff --git a/thirdparty/dwarf/dwarf_abbrev.h b/thirdparty/dwarf/dwarf_abbrev.h index 5aaacdd1..d043fde4 100644 --- a/thirdparty/dwarf/dwarf_abbrev.h +++ b/thirdparty/dwarf/dwarf_abbrev.h @@ -35,10 +35,10 @@ struct Dwarf_Abbrev_s { /* No TAG should exceed DW_TAG_hi_user, 0xffff, but we do allow a larger value here. */ - Dwarf_Word dab_tag; + Dwarf_Unsigned dab_tag; /* Abbreviations are numbered (normally sequentially from 1 and so 16 bits is not enough! */ - Dwarf_Word dab_code; + Dwarf_Unsigned dab_code; Dwarf_Small dab_has_child; Dwarf_Byte_Ptr dab_abbrev_ptr; Dwarf_Debug dab_dbg; diff --git a/thirdparty/dwarf/dwarf_addr_finder.c b/thirdparty/dwarf/dwarf_addr_finder.c deleted file mode 100644 index eb5434af..00000000 --- a/thirdparty/dwarf/dwarf_addr_finder.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - - Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. - -*/ -/* This code used by SGI-IRIX rqs processing, not needed by - any other system or application. - The 'We need' and 'FIX' here are left in for historical - interest, the code is not really used in the public libdwarf - or applications. -*/ - -#include "config.h" -#include "libdwarfdefs.h" -#ifdef HAVE_ELF_H -#include -#endif -#include -#include -#include "dwarf_base_types.h" -#include "dwarf_alloc.h" -#include "dwarf_opaque.h" -#include "dwarf_arange.h" -#include "dwarf_line.h" -#include "dwarf_frame.h" -#include -#include "dwarf_error.h" - -typedef unsigned long long ull; - -static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, - int *errval); -static int handle_debug_info(Dwarf_Debug dbg, int *errval); -static int handle_debug_frame(Dwarf_Debug dbg, - Dwarf_addr_callback_func cb_func, int *errval); -static int handle_debug_aranges(Dwarf_Debug dbg, - Dwarf_addr_callback_func cb_func, int *errval); -static int handle_debug_line(Dwarf_Debug dbg, - Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval); -static int handle_debug_loc(void); - - -/* A static variable is not thread-safe, but this is only - used by SGI-internal software which is single-threaded - so the static variable is safe. -*/ -static Dwarf_addr_callback_func send_addr_note; - -/* A function which should probably not be used outside - of SGI. Intended to be used by executable and - shared-library post-processor software. -*/ -int -_dwarf_addr_finder(dwarf_elf_handle elf_file_ptr, - Dwarf_addr_callback_func cb_func, int *dwerr) -{ - - Dwarf_Error err = 0; - Dwarf_Debug dbg = 0; - int res = 0; - int errval = 0; - int sections_found = 0; - - res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0, - /* errarg */ 0, &dbg, &err); - if (res == DW_DLV_ERROR) { - int errv = (int) dwarf_errno(err); - return errv; - } - if (res == DW_DLV_NO_ENTRY) { - return res; - } - send_addr_note = cb_func; - res = handle_debug_info(dbg, &errval); - switch (res) { - case DW_DLV_OK: - ++sections_found; - break; - case DW_DLV_NO_ENTRY: - - break; - default: - case DW_DLV_ERROR: - dwarf_finish(dbg, &err); - *dwerr = errval; - return res; - } - - res = handle_debug_aranges(dbg, cb_func, &errval); - switch (res) { - case DW_DLV_OK: - ++sections_found; - break; - case DW_DLV_NO_ENTRY: - break; - default: - case DW_DLV_ERROR: - dwarf_finish(dbg, &err); - *dwerr = errval; - return res; - } - res = handle_debug_frame(dbg, cb_func, &errval); - switch (res) { - case DW_DLV_OK: - ++sections_found; - break; - case DW_DLV_NO_ENTRY: - break; - default: - case DW_DLV_ERROR: - dwarf_finish(dbg, &err); - *dwerr = errval; - return res; - } - - res = handle_debug_loc(); /* does nothing */ - switch (res) { - case DW_DLV_OK: - ++sections_found; - break; - case DW_DLV_NO_ENTRY: - break; - default: - case DW_DLV_ERROR: - /* IMPOSSIBLE : handle_debug_loc cannot return this */ - dwarf_finish(dbg, &err); - *dwerr = errval; - return res; - } - - - - *dwerr = 0; - res = dwarf_finish(dbg, &err); - if (res == DW_DLV_ERROR) { - *dwerr = (int) dwarf_errno(err); - return DW_DLV_ERROR; - } - if (sections_found == 0) { - return DW_DLV_NO_ENTRY; - } - return DW_DLV_OK; - -} - -/* Return DW_DLV_OK, ERROR, or NO_ENTRY. */ -static int -handle_debug_info(Dwarf_Debug dbg, int *errval) -{ - Dwarf_Unsigned nxtoff = 1; - Dwarf_Unsigned hdr_length = 0; - Dwarf_Half version_stamp = 0; - Dwarf_Unsigned abbrev_offset = 0; - Dwarf_Half addr_size = 0; - Dwarf_Error err = 0; - int terminate_now = 0; - int res = 0; - Dwarf_Die sibdie = 0; - int sibres = 0; - int nres = DW_DLV_OK; - - - for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, - &abbrev_offset, - &addr_size, &nxtoff, &err); - terminate_now == 0 && nres == DW_DLV_OK; - nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, - &abbrev_offset, - &addr_size, &nxtoff, &err)) { - - Dwarf_Die curdie = 0; - - /* Try to get the compilation unit die */ - sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err); - if (sibres == DW_DLV_OK) { - res = do_this_die_and_dealloc(dbg, sibdie, errval); - switch (res) { - case DW_DLV_OK: - break; - case DW_DLV_NO_ENTRY: - break; - default: - case DW_DLV_ERROR: - return DW_DLV_ERROR; - } - } else if (sibres == DW_DLV_ERROR) { - *errval = (int) dwarf_errno(err); - return DW_DLV_ERROR; - } else { - /* NO ENTRY! */ - /* impossible? */ - } - - } - if (nres == DW_DLV_ERROR) { - int localerr = (int) dwarf_errno(err); - - *errval = localerr; - return DW_DLV_ERROR; - } - return DW_DLV_OK; -} - -static const int - might_have_addr[] = { - DW_AT_high_pc, - DW_AT_low_pc, -}; -static const int might_have_locdesc[] = { - DW_AT_segment, - DW_AT_return_addr, - DW_AT_frame_base, - DW_AT_static_link, - DW_AT_data_member_location, - DW_AT_string_length, - DW_AT_location, - DW_AT_use_location, - DW_AT_vtable_elem_location, -}; - -/* Return DW_DLV_OK if handling this went ok. - For any FORM except DW_FORM_addr we do nothing - and return DW_DLV_OK. - For DW_FORM_ref_addr (the offset in .debug_info - of an address) we don't need to do anything - as the offsets in .debug_info do not change. -*/ -static int -handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum, - Dwarf_Error * perr) -{ - int res = DW_DLV_OK; - Dwarf_Off offset = 0; - Dwarf_Addr addr = 0; - Dwarf_Half form = 0; - int ares = 0; - - Dwarf_Attribute attr; - - ares = dwarf_attr(die, attrnum, &attr, perr); - if (ares == DW_DLV_OK) { - int formres = dwarf_whatform(attr, &form, perr); - - switch (formres) { - case DW_DLV_OK: - break; - case DW_DLV_ERROR: - case DW_DLV_NO_ENTRY: /* impossible. */ - return formres; - - } - - switch (form) { - case DW_FORM_addr: - res = dwarf_attr_offset(die, attr, &offset, perr); - if (res == DW_DLV_OK) { - ares = dwarf_formaddr(attr, &addr, perr); - if (ares == DW_DLV_OK) { - send_addr_note(DW_SECTION_INFO, offset, addr); - } else if (ares == DW_DLV_ERROR) { - return ares; - } - /* no entry: ok. */ - } else { - /* NO_ENTRY is impossible. */ - res = DW_DLV_ERROR; - } - break; - - default: - /* Surprising FORM. An error? */ - /* Do nothing */ - ; - } - dwarf_dealloc(dbg, attr, DW_DLA_ATTR); - } else { - res = ares; - } - return res; -} - -/* Return DW_DLV_OK if handling this went ok. */ -static int -handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum, - Dwarf_Error * perr) -{ - int retval = DW_DLV_OK; - Dwarf_Attribute attr = 0; - Dwarf_Locdesc *llbuf = 0; - Dwarf_Signed i = 0; - Dwarf_Off offset = 0; - Dwarf_Loc *locp = 0; - unsigned int entindx = 0; - int res = 0; - int ares = 0; - - - ares = dwarf_attr(die, attrnum, &attr, perr); - if (ares == DW_DLV_OK) { - Dwarf_Half form; - int fres = dwarf_whatform(attr, &form, perr); - - if (fres == DW_DLV_OK) { - switch (form) { - case DW_FORM_block1: - case DW_FORM_block2: - case DW_FORM_block4: - /* must be location description */ - res = dwarf_attr_offset(die, attr, &offset, perr); - llbuf = 0; - if (res == DW_DLV_OK) { - Dwarf_Signed count; - int lres = dwarf_loclist(attr, &llbuf, &count, perr); - if (lres != DW_DLV_OK) { - return lres; - } - if (count != 1) { - /* this cannot happen! */ - /* perr? */ - _dwarf_error(dbg, perr, - DW_DLE_LOCDESC_COUNT_WRONG); - retval = DW_DLV_ERROR; - return retval; - } - for (i = 0; i < count; ++i) { - unsigned int ents = llbuf[i].ld_cents; - - locp = llbuf[i].ld_s; - for (entindx = 0; entindx < ents; entindx++) { - Dwarf_Loc *llocp; - - llocp = locp + entindx; - if (llocp->lr_atom == DW_OP_addr) { - send_addr_note(DW_SECTION_INFO, offset + - llocp->lr_offset + 1 - /* The offset is the - offset of the atom, - ** and we know the - addr is 1 past it. */ - , llocp->lr_number); - } - } - } - - - if (count > 0) { - for (i = 0; i < count; ++i) { - dwarf_dealloc(dbg, llbuf[i].ld_s, - DW_DLA_LOC_BLOCK); - } - dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); - } - } else { - retval = res; - } - break; - - default: - /* must be a const offset in debug_loc */ - ; /* do nothing */ - } - dwarf_dealloc(dbg, attr, DW_DLA_ATTR); - } /* else error or no entry */ - retval = fres; - } else { - retval = ares; - } - return retval; -} - -/* Return DW_DLV_OK, or DW_DLV_ERROR - - Handle the addrs in a single die. */ -static int -process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval) -{ - Dwarf_Error err = 0; - Dwarf_Half i = 0; - Dwarf_Half newattrnum = 0; - int res = 0; - int tres = 0; - Dwarf_Half ltag = 0; - Dwarf_Off doff = 0; - - int doffres = dwarf_dieoffset(newdie, &doff, &err); - if (doffres != DW_DLV_OK) { - if (doffres == DW_DLV_ERROR) { - *errval = (int) dwarf_errno(err); - } - return doffres; - } - tres = dwarf_tag(newdie, <ag, &err); - if (tres != DW_DLV_OK) { - return tres; - } - if (DW_TAG_compile_unit == ltag) { - /* Because of the way the dwarf_line code works, we do lines - only per compile unit. This may turn out to be wrong if - we have lines left unconnected to a CU. of course such - lines will not, at present, be used by gnome. This is - not ideal as coded due to the dwarf_line.c issue. */ - int lres = handle_debug_line(dbg, newdie, send_addr_note, errval); - if (lres == DW_DLV_ERROR) { - return lres; - } - } - - for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) { - int resattr = 0; - Dwarf_Bool hasattr = 0; - - newattrnum = might_have_addr[i]; - err = 0; - resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err); - if (DW_DLV_OK == resattr) { - if (hasattr) { - res = handle_attr_addr(dbg, newdie, newattrnum, &err); - if (res != DW_DLV_OK) { - *errval = (int) dwarf_errno(err); - return DW_DLV_ERROR; - } - } - } else { - if (resattr == DW_DLV_ERROR) { - *errval = (int) dwarf_errno(err); - return resattr; - } - } - } - for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) { - int resattr = 0; - Dwarf_Bool hasattr = 0; - - newattrnum = might_have_locdesc[i]; - err = 0; - resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err); - if (DW_DLV_OK == resattr) { - if (hasattr) { - res = - handle_attr_locdesc(dbg, newdie, newattrnum, &err); - if (res != DW_DLV_OK) { - *errval = (int) dwarf_errno(err); - return DW_DLV_ERROR; - } - } - } else { - if (resattr == DW_DLV_ERROR) { - *errval = (int) dwarf_errno(err); - return resattr; - } - } - } - - return DW_DLV_OK; -} - -/* Handle siblings as a list, - Do children by recursing. - Effectively this is walking the tree preorder. - - This dealloc's any die passed to it, so the - caller should not do that dealloc. - It seems more logical to have the one causing - the alloc to do the dealloc, but that way this - routine became a mess. -*/ -static int -do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval) -{ - - Dwarf_Die prevdie = 0; - Dwarf_Die newdie = die; - Dwarf_Error err = 0; - int res = 0; - int sibres = DW_DLV_OK; - int tres = DW_DLV_OK; - Dwarf_Die sibdie = 0; - - while (sibres == DW_DLV_OK) { - Dwarf_Die ch_die; - - - res = process_this_die_attrs(dbg, newdie, errval); - switch (res) { - case DW_DLV_OK: - break; - case DW_DLV_NO_ENTRY: - break; - default: - case DW_DLV_ERROR: - if (prevdie) { - dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); - prevdie = 0; - } - return DW_DLV_ERROR; - } - - tres = dwarf_child(newdie, &ch_die, &err); - - if (tres == DW_DLV_OK) { - res = do_this_die_and_dealloc(dbg, ch_die, errval); - switch (res) { - case DW_DLV_OK: - break; - case DW_DLV_NO_ENTRY: - break; - default: - case DW_DLV_ERROR: - if (prevdie) { - dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); - prevdie = 0; - } - return DW_DLV_ERROR; - } - } else if (tres == DW_DLV_ERROR) { - /* An error! */ - *errval = (int) dwarf_errno(err); - if (prevdie) { - dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); - prevdie = 0; - } - dwarf_dealloc(dbg, err, DW_DLA_ERROR); - return DW_DLV_ERROR; - } /* else was NO ENTRY */ - prevdie = newdie; - sibdie = 0; - sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err); - if (prevdie) { - dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); - prevdie = 0; - } - newdie = sibdie; - - } - if (sibres == DW_DLV_NO_ENTRY) { - return DW_DLV_OK; - } - /* error. */ - *errval = (int) dwarf_errno(err); - if (prevdie) { - dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); - prevdie = 0; - } - dwarf_dealloc(dbg, err, DW_DLA_ERROR); - return DW_DLV_ERROR; - -} - - -static int -handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, - int *errval) -{ - int retval = DW_DLV_OK; - int res = 0; - Dwarf_Error err = 0; - Dwarf_Addr *addrlist = 0; - Dwarf_Off *offsetlist = 0; - Dwarf_Signed count = 0; - int i = 0; - - res = _dwarf_frame_address_offsets(dbg, &addrlist, - &offsetlist, &count, &err); - if (res == DW_DLV_OK) { - for (i = 0; i < count; i++) { - cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]); - } - dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); - dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); - } else if (res == DW_DLV_NO_ENTRY) { - retval = res; - } else { - *errval = (int) dwarf_errno(err); - retval = DW_DLV_ERROR; - } - return retval; - -} -static int -handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, - int *errval) -{ - int retval = DW_DLV_OK; - Dwarf_Error err = 0; - Dwarf_Addr *aranges = 0; - Dwarf_Signed count = 0; - int indx = 0; - Dwarf_Off *offsets = 0; - - retval = - _dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count, - &err); - if (retval == DW_DLV_OK) { - if (count == 0) { - retval = DW_DLV_NO_ENTRY; - } else { - for (indx = 0; indx < count; indx++) { - cb_func(DW_SECTION_ARANGES, offsets[indx], - aranges[indx]); - } - } - dwarf_dealloc(dbg, aranges, DW_DLA_ADDR); - dwarf_dealloc(dbg, offsets, DW_DLA_ADDR); - } else if (retval == DW_DLV_NO_ENTRY) { - ; /* do nothing */ - } else { - *errval = (int) dwarf_errno(err); - retval = DW_DLV_ERROR; - } - return retval; -} -static int -handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, - Dwarf_addr_callback_func cb_func, int *errval) -{ - int retval = DW_DLV_OK; - int res = 0; - Dwarf_Error err = 0; - Dwarf_Addr *addrlist = 0; - Dwarf_Off *offsetlist = 0; - Dwarf_Unsigned count = 0; - Dwarf_Unsigned i = 0; - - res = _dwarf_line_address_offsets(dbg, cu_die, &addrlist, - &offsetlist, &count, &err); - if (res == DW_DLV_OK) { - for (i = 0; i < count; i++) { - cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]); - - } - dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); - dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); - } else if (res == DW_DLV_NO_ENTRY) { - retval = res; - } else { - *errval = (int) dwarf_errno(err); - retval = DW_DLV_ERROR; - } - return retval; -} - -/* We need to add support for this. Currently we do not - generate this section. - FIX! -*/ -static int -handle_debug_loc(void) -{ - int retval = DW_DLV_NO_ENTRY; - - return retval; -} diff --git a/thirdparty/dwarf/dwarf_alloc.c b/thirdparty/dwarf/dwarf_alloc.c index 8d4ba879..8ba77079 100644 --- a/thirdparty/dwarf/dwarf_alloc.c +++ b/thirdparty/dwarf/dwarf_alloc.c @@ -1,41 +1,52 @@ /* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. - 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 Software Foundation. + 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 + Software Foundation. This program is distributed in the hope that it would be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ #undef DEBUG #include "config.h" -#include "dwarf_incl.h" #include #include #include +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ +#include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_alloc.h" /* These files are included to get the sizes of structs for malloc. */ +#include "dwarf_util.h" #include "dwarf_line.h" #include "dwarf_global.h" #include "dwarf_arange.h" @@ -52,6 +63,9 @@ #include "dwarf_gdbindex.h" #include "dwarf_xu_index.h" #include "dwarf_macro5.h" +#include "dwarf_dnames.h" +#include "dwarf_dsc.h" +#include "dwarf_str_offsets.h" #define TRUE 1 #define FALSE 0 @@ -150,7 +164,7 @@ struct ial_s alloc_instance_basics[ALLOC_AREA_INDEX_TABLE_MAX] = { /* 20 DW_DLA_CIE */ {sizeof(struct Dwarf_Cie_s),MULTIPLY_NO, 0, 0}, - {sizeof(struct Dwarf_Fde_s),MULTIPLY_NO, 0, + {sizeof(struct Dwarf_Fde_s),MULTIPLY_NO, 0, _dwarf_fde_destructor},/* 21 DW_DLA_FDE */ {sizeof(Dwarf_Loc),MULTIPLY_CT, 0, 0}, /* 22 DW_DLA_LOC_BLOCK */ {sizeof(Dwarf_Frame_Op),MULTIPLY_CT, 0, 0}, /* 23 DW_DLA_FRAME_BLOCK */ @@ -265,6 +279,14 @@ struct ial_s alloc_instance_basics[ALLOC_AREA_INDEX_TABLE_MAX] = { /* 61 DW_DLA_CHAIN_2 */ {sizeof(struct Dwarf_Chain_o),MULTIPLY_NO, 0, 0}, + /* 62 DW_DLA_DSC_HEAD 0x3e */ + {sizeof(struct Dwarf_Dsc_Head_s),MULTIPLY_NO, 0, + _dwarf_dsc_destructor}, + /* 63 DW_DLA_DNAMES_HEAD 0x3f */ + {sizeof(struct Dwarf_Dnames_Head_s),MULTIPLY_NO, 0, + _dwarf_debugnames_destructor}, + /* 64 DW_DLA_STR_OFFSETS 0x40 */ + {sizeof(struct Dwarf_Str_Offsets_Table_s),MULTIPLY_NO, 0,0}, }; /* We are simply using the incoming pointer as the key-pointer. @@ -273,7 +295,7 @@ struct ial_s alloc_instance_basics[ALLOC_AREA_INDEX_TABLE_MAX] = { static DW_TSHASHTYPE simple_value_hashfunc(const void *keyp) { - DW_TSHASHTYPE up = (DW_TSHASHTYPE)keyp; + DW_TSHASHTYPE up = (DW_TSHASHTYPE)(uintptr_t)keyp; return up; } /* We did alloc something but not a fixed-length thing. @@ -312,8 +334,8 @@ tdestroy_free_node(void *nodep) static int simple_compare_function(const void *l, const void *r) { - DW_TSHASHTYPE lp = (DW_TSHASHTYPE)l; - DW_TSHASHTYPE rp = (DW_TSHASHTYPE)r; + DW_TSHASHTYPE lp = (DW_TSHASHTYPE)(uintptr_t)l; + DW_TSHASHTYPE rp = (DW_TSHASHTYPE)(uintptr_t)r; if(lp < rp) { return -1; } @@ -472,27 +494,50 @@ dwarf_dealloc(Dwarf_Debug dbg, if (space == NULL) { return; } - type = alloc_type; - malloc_addr = (char *)space - DW_RESERVE; - r =(struct reserve_data_s *)malloc_addr; - if(dbg != r->rd_dbg) { - /* Something is badly wrong. Better to leak than - to crash. */ + if (dbg) { + /* If it's a string in debug_info etc doing + (char *)space - DW_RESERVE is totally bogus. */ + if (alloc_type == DW_DLA_STRING && + string_is_in_debug_section(dbg,space)) { + /* A string pointer may point into .debug_info or + .debug_string etc. + So must not be freed. And strings have no need of a + specialdestructor(). + Mostly a historical mistake here. */ + return; + } + /* Otherwise it might be allocated string so it is ok + do the (char *)space - DW_RESERVE */ + } else { + /* App error, or an app that failed to succeed in a + dwarf_init() call. */ return; } if (alloc_type == DW_DLA_ERROR) { Dwarf_Error ep = (Dwarf_Error)space; - if (ep->er_static_alloc) { + if (ep->er_static_alloc == DE_STATIC) { /* This is special, malloc arena - was exhausted and there is nothing to delete, really. + was exhausted or a NULL dbg + was used for the error because the real + dbg was unavailable. There is nothing to delete, really. Set er_errval to signal that the space was dealloc'd. */ - ep->er_errval = DW_DLE_FAILSAFE_ERRVAL; + _dwarf_failsafe_error.er_errval = DW_DLE_FAILSAFE_ERRVAL; return; } + if (ep->er_static_alloc == DE_MALLOC) { + /* This is special, we had no arena + so just malloc'd a Dwarf_Error_s. */ + free(space); + return; + } + /* Was normal alloc, use normal dealloc. */ } - if (dbg == NULL) { - /* App error, or an app that failed to succeed in a - dwarf_init() call. */ + type = alloc_type; + malloc_addr = (char *)space - DW_RESERVE; + r =(struct reserve_data_s *)malloc_addr; + if(dbg != r->rd_dbg) { + /* Something is badly wrong. Better to leak than + to crash. */ return; } if (type >= ALLOC_AREA_INDEX_TABLE_MAX) { @@ -501,14 +546,6 @@ dwarf_dealloc(Dwarf_Debug dbg, } - if (type == DW_DLA_STRING && string_is_in_debug_section(dbg,space)) { - /* A string pointer may point into .debug_info or .debug_string etc. - So must not be freed. And strings have no need of a - specialdestructor(). - Mostly a historical mistake here. */ - return; - } - if (alloc_instance_basics[type].specialdestructor) { alloc_instance_basics[type].specialdestructor(space); } @@ -622,7 +659,10 @@ _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) dwarf_xu_header_free(dbg->de_tu_hashindex_data); dbg->de_tu_hashindex_data = 0; } - + if( dbg->de_printf_callback_null_device_handle) { + fclose(dbg->de_printf_callback_null_device_handle); + dbg->de_printf_callback_null_device_handle = 0; + } freecontextlist(dbg,&dbg->de_info_reading); freecontextlist(dbg,&dbg->de_types_reading); @@ -660,6 +700,7 @@ _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) free(dbg->de_printf_callback.dp_buffer); } + _dwarf_destroy_group_map(dbg); dwarf_tdestroy(dbg->de_alloc_tree,tdestroy_free_node); dbg->de_alloc_tree = 0; if (dbg->de_tied_data.td_tied_search) { @@ -682,12 +723,15 @@ _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) struct Dwarf_Error_s * _dwarf_special_no_dbg_error_malloc(void) { + Dwarf_Error e = 0; /* The union unused things are to guarantee proper alignment */ - char *mem = malloc(sizeof(struct Dwarf_Error_s)); + Dwarf_Unsigned len = sizeof(struct Dwarf_Error_s); + char *mem = (char *)malloc(len); if (mem == 0) { return 0; } - memset(mem, 0, sizeof(struct Dwarf_Error_s)); - return (struct Dwarf_Error_s *) mem; + memset(mem, 0, len); + e = (Dwarf_Error)mem; + e->er_static_alloc = DE_MALLOC; + return e; } - diff --git a/thirdparty/dwarf/dwarf_alloc.h b/thirdparty/dwarf/dwarf_alloc.h index 7edc49c8..3eeab9dc 100644 --- a/thirdparty/dwarf/dwarf_alloc.h +++ b/thirdparty/dwarf/dwarf_alloc.h @@ -35,4 +35,4 @@ struct Dwarf_Error_s * _dwarf_special_no_dbg_error_malloc(void); /* ALLOC_AREA_INDEX_TABLE_MAX is the size of the struct ial_s index_into_allocated array in dwarf_alloc.c */ -#define ALLOC_AREA_INDEX_TABLE_MAX 62 +#define ALLOC_AREA_INDEX_TABLE_MAX 65 diff --git a/thirdparty/dwarf/dwarf_arange.c b/thirdparty/dwarf/dwarf_arange.c index fb9ff29c..d403d4b9 100644 --- a/thirdparty/dwarf/dwarf_arange.c +++ b/thirdparty/dwarf/dwarf_arange.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. @@ -28,8 +28,11 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_arange.h" #include "dwarf_global.h" /* for _dwarf_fixup_* */ @@ -99,6 +102,10 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, header_ptr = arange_ptr; + if (header_ptr >= arange_end_section) { + _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); + return DW_DLV_ERROR; + } /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned, arange_ptr, local_length_size, @@ -107,6 +114,11 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, arange_end_section); /* arange_ptr has been incremented appropriately past the length field by READ_AREA_LENGTH. */ + + if (area_length > dbg->de_debug_aranges.dss_size) { + _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); + return DW_DLV_ERROR; + } if ((area_length + local_length_size + local_extension_size) > dbg->de_debug_aranges.dss_size) { _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); @@ -114,11 +126,26 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, } end_this_arange = arange_ptr + area_length; + if (end_this_arange > arange_end_section) { + _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); + return DW_DLV_ERROR; + } + if (!area_length) { + /* We read 4 bytes of zero, so area-length zero. + Keep scanning. First seen Nov 27, 2018 + in GNU-cc in windows dll. */ + continue; + } READ_UNALIGNED_CK(dbg, version, Dwarf_Half, - arange_ptr, sizeof(Dwarf_Half), + arange_ptr, DWARF_HALF_SIZE, error,end_this_arange); - arange_ptr += sizeof(Dwarf_Half); + + arange_ptr += DWARF_HALF_SIZE; + if (arange_ptr >= end_this_arange) { + _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); + return DW_DLV_ERROR; + } if (version != DW_ARANGES_VERSION2) { _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return (DW_DLV_ERROR); @@ -128,6 +155,10 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, arange_ptr, local_length_size, error,end_this_arange); arange_ptr += local_length_size; + if (arange_ptr >= end_this_arange) { + _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); + return DW_DLV_ERROR; + } /* This applies to debug_info only, not to debug_types. */ if (info_offset >= dbg->de_debug_info.dss_size) { FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, @@ -144,14 +175,17 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, return DW_DLV_ERROR; } if (address_size == 0) { - _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR); + _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO); return DW_DLV_ERROR; } /* It is not an error if the sizes differ. Unusual, but not an error. */ arange_ptr = arange_ptr + sizeof(Dwarf_Small); - if (arange_ptr > end_this_arange) { + + /* The following deref means we better check the pointer for off-end. */ + if (arange_ptr >= end_this_arange) { _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); + return DW_DLV_ERROR; } /* Even DWARF2 had a segment_size field here, meaning @@ -163,8 +197,11 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, return (DW_DLV_ERROR); } arange_ptr = arange_ptr + sizeof(Dwarf_Small); + + /* Code below will check for == end_this_arange as appropriate. */ if (arange_ptr > end_this_arange) { _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); + return (DW_DLV_ERROR); } range_entry_size = 2*address_size + segment_size; @@ -174,18 +211,24 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, if (remainder != 0) { arange_ptr = arange_ptr + (2 * address_size) - remainder; } - if (arange_ptr > end_this_arange) { - _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); - } + do { Dwarf_Addr range_address = 0; Dwarf_Unsigned segment_selector = 0; Dwarf_Unsigned range_length = 0; /* For segmented address spaces, the first field to read is a segment selector (new in DWARF4). - Surprising since the segment_size was always there + The version number DID NOT CHANGE from 2, which + is quite surprising. + Also surprising since the segment_size + was always there in the table header! */ - if ((version >= 4) && (segment_size != 0)) { + /* We want to test cu_version here but + currently with no way to do that. + So we just hope no one using + segment_selectors, really. FIXME */ + if (segment_size) { + /* Only applies if cu_version >= 4. */ READ_UNALIGNED_CK(dbg, segment_selector, Dwarf_Unsigned, arange_ptr, segment_size, error,end_this_arange); @@ -254,7 +297,10 @@ dwarf_get_aranges_list(Dwarf_Debug dbg, char buf[200]; Dwarf_Unsigned pad_count = arange_ptr - end_this_arange; Dwarf_Unsigned offset = arange_ptr - arange_ptr_start; - snprintf(buf,sizeof(buf),"DW_DLE_ARANGE_LENGTH_BAD." + + /* Safe. Length strictly limited. */ + sprintf(buf, + "DW_DLE_ARANGE_LENGTH_BAD." " 0x%" DW_PR_XZEROS DW_PR_DUx " pad bytes at offset 0x%" DW_PR_XZEROS DW_PR_DUx " in .debug_aranges", @@ -314,6 +360,12 @@ dwarf_get_aranges(Dwarf_Debug dbg, if (res != DW_DLV_OK) { return res; } + /* aranges points in to info, so if info needs expanding + we have to load it. */ + res = _dwarf_load_debug_info(dbg, error); + if (res != DW_DLV_OK) { + return res; + } res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); if (res != DW_DLV_OK) { @@ -385,12 +437,16 @@ _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, if (res != DW_DLV_OK) { return res; } - + /* aranges points in to info, so if info needs expanding + we have to load it. */ + res = _dwarf_load_debug_info(dbg, error); + if (res != DW_DLV_OK) { + return res; + } res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); if (res != DW_DLV_OK) { return res; } - arange_addrs = (Dwarf_Addr *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); if (arange_addrs == NULL) { diff --git a/thirdparty/dwarf/dwarf_base_types.h b/thirdparty/dwarf/dwarf_base_types.h index 66f8af68..4bd28f05 100644 --- a/thirdparty/dwarf/dwarf_base_types.h +++ b/thirdparty/dwarf/dwarf_base_types.h @@ -25,10 +25,6 @@ */ - - -#include "libdwarfdefs.h" - #define true 1 #define false 0 @@ -120,33 +116,14 @@ Only used with malloc_check.c and that is basically obsolete. */ #define MAX_DW_DLA 0x3a -/*Dwarf_Word is unsigned word usable for index, count in memory */ -/*Dwarf_Sword is signed word usable for index, count in memory */ -/* They are 32 or 64 bits depending if 64 bit longs or not, which - fits the ILP32 and LP64 models - These work equally well with ILP64. */ - -typedef unsigned long Dwarf_Word; -typedef signed long Dwarf_Sword; - typedef signed char Dwarf_Sbyte; typedef unsigned char Dwarf_Ubyte; typedef signed short Dwarf_Shalf; typedef Dwarf_Small *Dwarf_Byte_Ptr; -/* These 2 are fixed sizes which must not vary with the - ILP32/LP64 model. Between these two, stay at 32 bit. */ -typedef __uint32_t Dwarf_ufixed; -typedef __int32_t Dwarf_sfixed; - -/* In various places the code mistakenly associates - forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned - This is not a very portable assumption. - The following should be used instead for 64 bit integers. -*/ -typedef __uint64_t Dwarf_ufixed64; -typedef __int64_t Dwarf_sfixed64; - +#define DWARF_HALF_SIZE 2 +#define DWARF_32BIT_SIZE 4 +#define DWARF_64BIT_SIZE 8 typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List; typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry; diff --git a/thirdparty/dwarf/dwarf_die_deliv.c b/thirdparty/dwarf/dwarf_die_deliv.c index 697746eb..efb97766 100644 --- a/thirdparty/dwarf/dwarf_die_deliv.c +++ b/thirdparty/dwarf/dwarf_die_deliv.c @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -26,16 +26,40 @@ */ #include "config.h" -#include "dwarf_incl.h" -#ifdef HAVE_ELF_H -#include -#endif #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_die_deliv.h" #define FALSE 0 #define TRUE 1 +/* These are sanity checks, not 'rules'. */ +#define MINIMUM_ADDRESS_SIZE 2 +#define MAXIMUM_ADDRESS_SIZE 8 + +/* DWARF5 DW_UT and DW_TAG*unit relationships. +DW_UT_compile + DW_TAG_compile_unit in .debug_info + +DW_UT_partial + DW_TAG_partial_unit in .debug_info + +DW_UT_skeleton + DW_TAG_compile_unit in .debug_info + +DW_UT_split_compile + DW_TAG_compile_unit in .debug_info.dwo + +DW_UT_type + DW_TAG_type_unit in .debug_info + +DW_UT_split_type No skeleton for split type. + DW_TAG_type_unit in .debug_info.dwo */ + + /* New October 2011. Enables client code to know if it is a debug_info or debug_types context. */ Dwarf_Bool @@ -44,6 +68,23 @@ dwarf_get_die_infotypes_flag(Dwarf_Die die) return die->di_is_info; } +#if 0 +static void +dump_bytes(char * msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + + printf("%s ",msg); + for (; cur < end; cur++) { + printf("%02x ", *cur); + } + printf("\n"); +} +#endif + + + /* For a given Dwarf_Debug dbg, this function checks if a CU that includes the given offset has been read @@ -146,7 +187,9 @@ dwarf_get_debugfission_for_die(Dwarf_Die die, return DW_DLV_NO_ENTRY; } - if (context->cc_unit_type == DW_UT_type ) { + /* Logic should work for DW4 and DW5. */ + if (context->cc_unit_type == DW_UT_type|| + context->cc_unit_type == DW_UT_split_type ) { if (!_dwarf_file_has_debug_fission_tu_index(dbg)) { return DW_DLV_NO_ENTRY; } @@ -163,6 +206,22 @@ dwarf_get_debugfission_for_die(Dwarf_Die die, return DW_DLV_OK; } +static Dwarf_Bool +is_unknown_UT_value(int ut) +{ + switch(ut) { + case DW_UT_compile: + case DW_UT_type: + case DW_UT_partial: + case DW_UT_skeleton: + case DW_UT_split_compile: + case DW_UT_split_type: + return FALSE; + } + return TRUE; +} + + /* ASSERT: whichone is a DW_SECT* macro value. */ Dwarf_Unsigned _dwarf_get_dwp_extra_offset(struct Dwarf_Debug_Fission_Per_CU_s* dwp, @@ -223,6 +282,76 @@ section_name_ends_with_dwo(const char *name) } + +/* New January 2017 */ +static int +_dwarf_read_cu_length_plus(Dwarf_Debug dbg, + Dwarf_Small *data, + Dwarf_Bool is_info, + UNUSEDARG unsigned group_number, + unsigned offset_size, /* 4 or 8 */ + /* end_data used for sanity checking */ + Dwarf_Small *end_data, + Dwarf_Half * version_out, + Dwarf_Half * ut_out, + Dwarf_Unsigned * bytes_read_out, + Dwarf_Unsigned *address_size_out, + Dwarf_Unsigned *abbrev_offset_out, + Dwarf_Error *error) +{ + Dwarf_Half version = 0; + Dwarf_Small *data_start = data; + Dwarf_Small *dataptr = data; + int unit_type = 0; + Dwarf_Ubyte addrsize = 0; + Dwarf_Unsigned abbrev_offset = 0; + + READ_UNALIGNED_CK(dbg, version, Dwarf_Half, + dataptr,DWARF_HALF_SIZE,error,end_data); + dataptr += DWARF_HALF_SIZE; + if (version == DW_CU_VERSION5) { + Dwarf_Ubyte unit_typeb = 0; + + READ_UNALIGNED_CK(dbg, unit_typeb, Dwarf_Ubyte, + dataptr, sizeof(unit_typeb),error,end_data); + dataptr += sizeof(unit_typeb); + unit_type = unit_typeb; + /* We do not need is_info flag in DWARF5 */ + if (is_unknown_UT_value(unit_type)) { + _dwarf_error(dbg, error, DW_DLE_CU_UT_TYPE_ERROR); + return DW_DLV_ERROR; + } + READ_UNALIGNED_CK(dbg, addrsize, unsigned char, + dataptr, sizeof(addrsize),error,end_data); + dataptr += sizeof(addrsize); + + READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, + dataptr, offset_size,error,end_data); + dataptr += offset_size; + + } else if (version ==2 || version ==3 || version ==4) { + /* DWARF2,3,4 */ + READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, + dataptr, offset_size,error,end_data); + dataptr += offset_size; + + READ_UNALIGNED_CK(dbg, addrsize, Dwarf_Ubyte, + dataptr, sizeof(addrsize),error,end_data); + dataptr += sizeof(Dwarf_Ubyte); + unit_type = is_info?DW_UT_compile:DW_UT_type; + } else { + _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + return DW_DLV_ERROR; + } + *ut_out = unit_type; + *version_out = version; + *bytes_read_out = (dataptr - data_start); + *address_size_out = addrsize; + *abbrev_offset_out = abbrev_offset; + return DW_DLV_OK; +} + + /* This function is used to create a CU Context for a compilation-unit that begins at offset in .debug_info. The CU Context is attached to the @@ -250,27 +379,29 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, Dwarf_CU_Context * context_out,Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; - Dwarf_Unsigned length = 0; - Dwarf_Signed abbrev_offset = 0; - Dwarf_Unsigned typeoffset = 0; - Dwarf_Sig8 signaturedata; - Dwarf_Unsigned types_extra_len = 0; - Dwarf_Unsigned max_cu_local_offset = 0; - Dwarf_Unsigned max_cu_global_offset = 0; - Dwarf_Byte_Ptr cu_ptr = 0; - Dwarf_Byte_Ptr section_end_ptr = 0; - int local_extension_size = 0; - int local_length_size = 0; - const char *secname = is_info?dbg->de_debug_info.dss_name: + Dwarf_Unsigned length = 0; + Dwarf_Unsigned abbrev_offset = 0; + Dwarf_Unsigned typeoffset = 0; + Dwarf_Sig8 signaturedata; + Dwarf_Unsigned types_extra_len = 0; + Dwarf_Unsigned max_cu_local_offset = 0; + Dwarf_Unsigned max_cu_global_offset = 0; + Dwarf_Byte_Ptr cu_ptr = 0; + Dwarf_Byte_Ptr section_end_ptr = 0; + int local_extension_size = 0; + int local_length_size = 0; + const char * secname = is_info?dbg->de_debug_info.dss_name: dbg->de_debug_types.dss_name; Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading; - Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size: + Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size: dbg->de_debug_types.dss_size; - int unit_type = 0; - int version = 0; - int is_type_tu = 0; - Dwarf_Small *dataptr = 0; + int is_type_tu = FALSE; + int unit_type = 0; + int version = 0; + Dwarf_Small * dataptr = 0; + int res = 0; + Dwarf_Unsigned address_size = 0; cu_context = (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1); @@ -284,10 +415,17 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, dataptr = is_info? dbg->de_debug_info.dss_data: dbg->de_debug_types.dss_data; if (!dataptr) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); + return DW_DLV_ERROR; + } + if (offset >= section_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } if ((offset+4) > section_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); return DW_DLV_ERROR; } @@ -301,78 +439,142 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned, cu_ptr, local_length_size, local_extension_size, error,section_size,section_end_ptr); + if (!length) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + return DW_DLV_NO_ENTRY; + } + cu_context->cc_length_size = local_length_size; cu_context->cc_extension_size = local_extension_size; cu_context->cc_length = length; max_cu_local_offset = length; + + /* This is a bare minimum, not the real max offset. + A preliminary sanity check. */ max_cu_global_offset = offset + length + local_extension_size + local_length_size; - - READ_UNALIGNED_CK(dbg, cu_context->cc_version_stamp, Dwarf_Half, - cu_ptr, sizeof(Dwarf_Half),error,section_end_ptr); - version = cu_context->cc_version_stamp; - cu_ptr += sizeof(Dwarf_Half); - if (version == DW_CU_VERSION5) { - unsigned char ub = 0; - READ_UNALIGNED_CK(dbg, ub, unsigned char, - cu_ptr, sizeof(ub),error,section_end_ptr); - cu_ptr += sizeof(ub); - unit_type = ub; - if (unit_type != DW_UT_compile && unit_type != DW_UT_partial - && unit_type != DW_UT_type) { - _dwarf_error(dbg, error, DW_DLE_CU_UT_TYPE_ERROR); - return DW_DLV_ERROR; - } - } else { - /* We don't know if it is or DW_UT_partial or not. */ - unit_type = is_info?DW_UT_compile:DW_UT_type; + if(length > section_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); + return DW_DLV_ERROR; + } + if(max_cu_global_offset > section_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); + return DW_DLV_ERROR; } - READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned, - cu_ptr, local_length_size,error,section_end_ptr); + { /* READ version and, if present, DW_UT value + and read abbrev_offset and address size. */ + Dwarf_Unsigned bytes_read = 0; + Dwarf_Half utvalue = 0; + Dwarf_Half vnum = 0; + + /* This deals with DW2,3,4 and 5 */ + res = _dwarf_read_cu_length_plus(dbg,cu_ptr,is_info, + dbg->de_groupnumber, + cu_context->cc_length_size, + section_end_ptr,&vnum,&utvalue, + &bytes_read,&address_size,&abbrev_offset,error); + if (res != DW_DLV_OK) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + return res; + } + version = vnum; + cu_ptr += bytes_read; + cu_context->cc_version_stamp = vnum; + cu_context->cc_unit_type = utvalue; + unit_type = utvalue; + cu_context->cc_address_size = address_size; + cu_context->cc_abbrev_offset = abbrev_offset; - cu_ptr += local_length_size; + /* We are ignoring this. Can get it from DWARF5. */ + cu_context->cc_segment_selector_size = 0; + } /* In a dwp context, this offset is incomplete. We need to add in the base from the .debug_cu_index or .debug_tu_index . Done below */ - cu_context->cc_abbrev_offset = abbrev_offset; - cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr; - /* The CU header has no selector size. See DW_AT_segment - and the DWARF5 line table header and the - DWARF5 .debug_aranges header. */ - cu_context->cc_segment_selector_size = 0; - ++cu_ptr; + /* There is some duplication of setting is_type_tu + and types_extra_len due to variations + across DWARF versions. */ + if (!is_info) { + /* DWARF4 */ + is_type_tu = TRUE; + } + if (version == DW_CU_VERSION5) { + /* DW5 introduces new header fields, depending on UT type. + See DW5 section 7.5.1.x */ + switch(unit_type) { + case DW_UT_split_type: + case DW_UT_type: { + types_extra_len = sizeof(Dwarf_Sig8) /* 8 */ + + local_length_size /*type_offset size*/; + is_type_tu = TRUE; + break; + } + case DW_UT_skeleton: + case DW_UT_split_compile: { + break; + } + case DW_UT_compile: /* No additional fields */ + case DW_UT_partial: /* No additional fields */ + break; + default: + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg,error,DW_DLE_CU_UT_TYPE_ERROR); + return DW_DLV_ERROR; + } + + } + if (is_type_tu) { + /* types CU headers have extra header bytes. + DWARF4 or DWARF5 */ + types_extra_len = sizeof(signaturedata) + local_length_size; + } if (cu_ptr > section_end_ptr) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR); } - + if (!address_size) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg,error,DW_DLE_ADDRESS_SIZE_ZERO); + return DW_DLV_ERROR; + } + if (address_size < MINIMUM_ADDRESS_SIZE || + address_size > MAXIMUM_ADDRESS_SIZE ) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR); + return DW_DLV_ERROR; + } if (cu_context->cc_address_size > sizeof(Dwarf_Addr)) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD); return DW_DLV_ERROR; } - is_type_tu = FALSE; - if (!is_info || - (version == DW_CU_VERSION5 && unit_type == DW_UT_type )) { - is_type_tu = TRUE; - } - if (is_type_tu) { - /* types CU headers have extra header bytes. */ - types_extra_len = sizeof(signaturedata) + local_length_size; - } - if ((length < (CU_VERSION_STAMP_SIZE + local_length_size + - CU_ADDRESS_SIZE_SIZE + types_extra_len)) || - (max_cu_global_offset > section_size)) { + + + /* Compare the space following the length field + to the bytes in the CU header. */ + if (length < + (CU_VERSION_STAMP_SIZE /* is 2 */ + + local_length_size /*for debug_abbrev offset */ + + CU_ADDRESS_SIZE_SIZE /* is 1 */ + + /* and finally size of the rest of the header: */ + types_extra_len)) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); return DW_DLV_ERROR; } + /* Now we can read the fields with some confidence, + we know the fields of the header are inside + the section. */ if (cu_context->cc_version_stamp != DW_CU_VERSION2 && cu_context->cc_version_stamp != DW_CU_VERSION3 @@ -382,14 +584,10 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); return DW_DLV_ERROR; } - if (is_type_tu) { - if (version != DW_CU_VERSION4 && - version != DW_CU_VERSION5) { - dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); - /* Error name misleading, version 5 has types too. */ - _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPES_ONLY_DWARF4); - return DW_DLV_ERROR; - } + cu_context->cc_unit_type = unit_type; + switch(unit_type) { + case DW_UT_split_type: + case DW_UT_type: { /* Now read the debug_types extra header fields of the signature (8 bytes) and the typeoffset. This can be in executable, ordinary object, @@ -401,15 +599,30 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, cu_ptr, local_length_size,error,section_end_ptr); cu_context->cc_type_signature = signaturedata; cu_context->cc_type_signature_offset = typeoffset; - { - if (typeoffset >= max_cu_local_offset) { - dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); - _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPEOFFSET_BAD); - return DW_DLV_ERROR; - } + if (typeoffset >= max_cu_local_offset) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPEOFFSET_BAD); + return DW_DLV_ERROR; + } + } + break; + case DW_UT_skeleton: + case DW_UT_split_compile: { + memcpy(&signaturedata,cu_ptr,sizeof(signaturedata)); + cu_context->cc_type_signature = signaturedata; + cu_context->cc_signature_present = TRUE; + + break; } + case DW_UT_compile: /* No additional fields */ + case DW_UT_partial: /* No additional fields */ + break; + default: + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + _dwarf_error(dbg,error,DW_DLE_CU_UT_TYPE_ERROR); + return DW_DLV_ERROR; } - cu_context->cc_unit_type = unit_type; + if (is_type_tu) { if (_dwarf_file_has_debug_fission_tu_index(dbg) ){ int resdf = 0; @@ -418,7 +631,10 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, "tu", &cu_context->cc_dwp_offsets, error); - if (resdf != DW_DLV_OK) { + if (resdf == DW_DLV_ERROR) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + return resdf; + } else if (resdf == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH); @@ -432,18 +648,29 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, offset, &cu_context->cc_dwp_offsets, error); - if (resdf != DW_DLV_OK) { + if (resdf == DW_DLV_ERROR) { + dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); + return resdf; + } else if (resdf == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); _dwarf_error(dbg, error, DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH); return DW_DLV_ERROR; } /* Eventually we will see the DW_AT_dwo_id - or DW_AT_GNU_dwo_id + or DW_AT_GNU_dwo_id if this is DWARF4 and we should check against this signature at that time. */ + if (!cu_context->cc_signature_present) { + cu_context->cc_type_signature = + cu_context->cc_dwp_offsets.pcu_hash; + cu_context->cc_signature_present = TRUE; + } + +#if 0 cu_context->cc_type_signature = cu_context->cc_dwp_offsets.pcu_hash; +#endif } } if (cu_context->cc_dwp_offsets.pcu_type) { @@ -472,6 +699,8 @@ _dwarf_make_CU_Context(Dwarf_Debug dbg, cu_context->cc_debug_offset = offset; + /* This is recording an overall section value for later + sanity checking. */ dis->de_last_offset = max_cu_global_offset; if (dis->de_cu_context_list == NULL) { @@ -497,15 +726,17 @@ reloc_incomplete(int res,Dwarf_Error err) return FALSE; } e = dwarf_errno(err); - if (e == DW_DLE_RELOC_MISMATCH_INDEX || + if (e == DW_DLE_RELOC_MISMATCH_INDEX || e == DW_DLE_RELOC_MISMATCH_RELOC_INDEX || e == DW_DLE_RELOC_MISMATCH_STRTAB_INDEX || e == DW_DLE_RELOC_SECTION_MISMATCH || - e == DW_DLE_RELOC_SECTION_MISSING_INDEX || - e == DW_DLE_RELOC_SECTION_LENGTH_ODD || - e == DW_DLE_RELOC_SECTION_PTR_NULL || - e == DW_DLE_RELOC_SECTION_MALLOC_FAIL || - e == DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD ) { + e == DW_DLE_RELOC_SECTION_MISSING_INDEX || + e == DW_DLE_RELOC_SECTION_LENGTH_ODD || + e == DW_DLE_RELOC_SECTION_PTR_NULL || + e == DW_DLE_RELOC_SECTION_MALLOC_FAIL || + e == DW_DLE_SEEK_OFF_END || + e == DW_DLE_RELOC_INVALID || + e == DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD ) { return TRUE; } return FALSE; @@ -614,7 +845,11 @@ dwarf_next_cu_header_d(Dwarf_Debug dbg, Dwarf_Half * header_cu_type, Dwarf_Error * error) { - int res = _dwarf_next_cu_header_internal(dbg, + /* Faking has_signature to do nothing. */ + Dwarf_Bool* has_signature = 0; + int res = 0; + + res = _dwarf_next_cu_header_internal(dbg, is_info, cu_header_length, version_stamp, @@ -623,7 +858,7 @@ dwarf_next_cu_header_d(Dwarf_Debug dbg, offset_size, extension_size, signature, - 0, + has_signature, typeoffset, next_cu_offset, header_cu_type, @@ -643,32 +878,41 @@ dwarf_next_cu_header_d(Dwarf_Debug dbg, static int find_context_base_fields(Dwarf_Debug dbg, Dwarf_Die cudie, - Dwarf_Sig8 *sig_return, - Dwarf_Bool *sig_present_return, + Dwarf_Sig8 * dwoid_return, + Dwarf_Bool * dwoid_present_return, Dwarf_Unsigned *str_offsets_base_return, - Dwarf_Bool *str_offsets_base_present_return, + Dwarf_Bool * str_offsets_base_present_return, Dwarf_Unsigned *addr_base_return, - Dwarf_Bool *addr_base_present_return, + Dwarf_Bool * addr_base_present_return, Dwarf_Unsigned *ranges_base_return, - Dwarf_Bool *ranges_base_present_return, - Dwarf_Error* error) + Dwarf_Bool * ranges_base_present_return, + Dwarf_Error* error) { Dwarf_Sig8 signature; - Dwarf_Bool sig_present = FALSE; - Dwarf_Off str_offsets_base = 0; - Dwarf_Off ranges_base = 0; - Dwarf_Off addr_base = 0; + Dwarf_Bool dwoid_sig_present = FALSE; + Dwarf_Off str_offsets_base = 0; + Dwarf_Off ranges_base = 0; + Dwarf_Off addr_base = 0; Dwarf_Bool str_offsets_base_present = FALSE; Dwarf_Bool addr_base_present = FALSE; Dwarf_Bool ranges_base_present = FALSE; - + Dwarf_Half version_stamp = 0; + Dwarf_CU_Context cu_context = 0; Dwarf_Attribute * alist = 0; Dwarf_Signed atcount = 0; - int alres = 0; + int alres = 0; + + cu_context = cudie->di_cu_context; + version_stamp = cu_context->cc_version_stamp; alres = dwarf_attrlist(cudie, &alist, &atcount,error); if(alres == DW_DLV_OK) { + /* DW_AT_dwo_id and DW_AT_GNU_dwo_id + are only found in some + experimental DWARF4. + DWARF5 changed CU header contents + to make this attribute unnecessary. */ Dwarf_Signed i = 0; for(i = 0; i < atcount; ++i) { Dwarf_Half attrnum; @@ -678,11 +922,21 @@ find_context_base_fields(Dwarf_Debug dbg, if (ares == DW_DLV_OK) { if (attrnum == DW_AT_dwo_id || attrnum == DW_AT_GNU_dwo_id ) { + /* This is for DWARF4 with an early + non-standard version + of split dwarf. Not DWARF5. */ int sres = 0; + if (version_stamp != DW_CU_VERSION4) { + /* Not supposed to happen. */ + _dwarf_error(dbg,error, + DW_DLE_IMPROPER_DWO_ID); + return DW_DLV_ERROR; + } + sres = dwarf_formsig8_const(attr, &signature,error); if(sres == DW_DLV_OK) { - sig_present = TRUE; + dwoid_sig_present = TRUE; } else { /* Something is badly wrong. */ dwarf_dealloc(dbg,attr,DW_DLA_ATTR); @@ -714,7 +968,7 @@ find_context_base_fields(Dwarf_Debug dbg, /* Something is badly wrong. */ return udres; } - } else if (attrnum == DW_AT_ranges_base + } else if (attrnum == DW_AT_rnglists_base || attrnum == DW_AT_GNU_ranges_base){ int udres = 0; udres = dwarf_global_formref(attr,&ranges_base, @@ -733,13 +987,13 @@ find_context_base_fields(Dwarf_Debug dbg, } dwarf_dealloc(dbg,alist,DW_DLA_LIST); } else { - /* Something is badly wrong. No attrlist. FIXME */ + /* Something is badly wrong. No attrlist. */ _dwarf_error(dbg,error, DW_DLE_DWP_MISSING_DWO_ID); return DW_DLV_ERROR; } - *sig_present_return = sig_present; - if (sig_present) { - *sig_return = signature; + *dwoid_present_return = dwoid_sig_present; + if (dwoid_sig_present) { + *dwoid_return = signature; } *str_offsets_base_present_return = str_offsets_base_present; if (str_offsets_base_present) { @@ -756,6 +1010,20 @@ find_context_base_fields(Dwarf_Debug dbg, return DW_DLV_OK; } +static Dwarf_Bool +_dwarf_may_have_base_fields(Dwarf_Debug dbg, + Dwarf_CU_Context cu_context) +{ + if (cu_context->cc_version_stamp < DW_CU_VERSION4) { + return FALSE; + } + if (dbg->de_tied_data.td_is_tied_object || + _dwarf_file_has_debug_fission_cu_index(dbg)) { + return TRUE; + } + return FALSE; +} + int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, @@ -771,7 +1039,9 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Unsigned *typeoffset, Dwarf_Unsigned * next_cu_offset, - /* header_type: DW_UT_compile, DW_UT_partial, DW_UT_type + /* header_type: DW_UT_compile, DW_UT_partial, DW_UT_type, + DW_UT_skeleton, DW_UT_split_compile, or + DW_UT_split_type returned through the pointer. A new item in DWARF5, synthesized for earlier DWARF CUs (& TUs). */ @@ -787,8 +1057,6 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Unsigned section_size = 0; int res = 0; - - /* ***** BEGIN CODE ***** */ if (dbg == NULL) { @@ -810,13 +1078,27 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, if (resd != DW_DLV_OK) { if (reloc_incomplete(resd,err2)) { /* We will assume all is ok, though it is not. - Relocation errors need not be fatal. */ - char msg_buf[200]; - snprintf(msg_buf,sizeof(msg_buf), - "Relocations did not complete successfully, but we are " - " ignoring error: %s",dwarf_errmsg(err2)); + Relocation errors need not be fatal. */ + char msg_buf[300]; + char *dwerrmsg = 0; + char *msgprefix = + "Relocations did not complete successfully, " + "but we are " " ignoring error: "; + size_t totallen = 0; + size_t prefixlen = 0; + + dwerrmsg = dwarf_errmsg(err2); + prefixlen = strlen(msgprefix); + totallen = prefixlen + strlen(dwerrmsg); + if( totallen >= sizeof(msg_buf)) { + /* Impossible unless something corrupted. + Provide a shorter dwerrmsg*/ + strcpy(msg_buf,"Error:corrupted dwarf message table!"); + } else { + strcpy(msg_buf,msgprefix); + strcpy(msg_buf+prefixlen,dwerrmsg); + } dwarf_insert_harmless_error(dbg,msg_buf); - resd = DW_DLV_OK; /* Fall thru to use the newly loaded section. even though it might not be adequately relocated. */ @@ -835,6 +1117,8 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, /* We are leaving new_offset zero. We are at the start of a section. */ } else { + /* We already have is_info cu_context. */ + new_offset = dis->de_cu_context->cc_debug_offset + dis->de_cu_context->cc_length + dis->de_cu_context->cc_length_size + @@ -893,23 +1177,24 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, *header_type = cu_context->cc_unit_type; } - if ( (dbg->de_tied_data.td_is_tied_object || - _dwarf_file_has_debug_fission_cu_index(dbg)) && - (cu_context->cc_unit_type == DW_UT_compile || - cu_context->cc_unit_type == DW_UT_partial)) { + if (_dwarf_may_have_base_fields(dbg,cu_context)) { /* ASSERT: !cu_context->cc_type_signature_present */ /* Look for DW_AT_dwo_id and if there is one pick up the hash - and the base array. - Also pick up cc_str_offset_base. */ + the dwo_id won't be present in DWARF5 since + it would be in the CU header instead. + Also pick up cc_str_offset_base and + any other base values. */ + Dwarf_Die cudie = 0; + int resdwo = 0; - int resdwo = dwarf_siblingof_b(dbg,NULL,is_info, + resdwo = dwarf_siblingof_b(dbg,NULL,is_info, &cudie, error); if (resdwo == DW_DLV_OK) { int dwo_idres = 0; Dwarf_Sig8 dwosignature; - Dwarf_Bool sig_present = FALSE; + Dwarf_Bool dwoid_present = FALSE; Dwarf_Unsigned str_offsets_base = 0; Dwarf_Unsigned addr_base = 0; Dwarf_Unsigned ranges_base = 0; @@ -917,16 +1202,18 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool addr_base_present = FALSE; Dwarf_Bool ranges_base_present = FALSE; dwo_idres = find_context_base_fields(dbg, - cudie,&dwosignature,&sig_present, + cudie,&dwosignature,&dwoid_present, &str_offsets_base,&str_offsets_base_present, &addr_base,&addr_base_present, &ranges_base,&ranges_base_present, error); if (dwo_idres == DW_DLV_OK) { - if(sig_present) { + if(dwoid_present && + !cu_context->cc_signature_present) { /* This can be in executable or ordinary .o - or .dwo or .dwp */ + or .dwo or .dwp, but only with non-standard + DWARF4 */ cu_context->cc_type_signature = dwosignature; cu_context->cc_signature_present = TRUE; } @@ -967,16 +1254,27 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, if (has_signature) { *has_signature = cu_context->cc_signature_present; } + /* Determine the offset of the next CU. */ new_offset = new_offset + cu_context->cc_length + cu_context->cc_length_size + cu_context->cc_extension_size; - *next_cu_offset = new_offset; - return (DW_DLV_OK); + /* Allowing null argument starting 22 April 2019. */ + if (next_cu_offset) { + *next_cu_offset = new_offset; + } + return DW_DLV_OK; } -/* Given hash signature, return the CU_die of the applicable CU. - The hash is assumed to be from 'somewhere', - such as from a skeleton DIE DW_AT_dwo_id ("cu" case) or - from a DW_FORM_ref_sig8 ("tu" case). +/* This involves data in a split dwarf or package file. + + Given hash signature, return the CU_die of the applicable CU. + The hash is assumed to be from 'somewhere'. + For DWARF 4: + From a skeleton DIE DW_AT_dwo_id ("cu" case) or + From a DW_FORM_ref_sig8 ("tu" case). + For DWARF5: + From (dwo_id) a skeleton CU header. + From a DW_FORM_ref_sig8 ("tu" case). + If "tu" request, the CU_die of of the type unit. @@ -1052,7 +1350,7 @@ dwarf_die_from_hash_signature(Dwarf_Debug dbg, } /* Found it */ if(is_type_unit) { - /* DW4 has debug_types, so look in .debug_types. + /* DW4 has debug_types, so look in .debug_types Else look in .debug_info. */ is_info2 = dbg->de_debug_types.dss_size?FALSE:TRUE; } else { @@ -1221,7 +1519,7 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, { Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; - Dwarf_Word abbrev_code = 0; + Dwarf_Unsigned abbrev_code = 0; Dwarf_Abbrev_List abbrev_list = 0; Dwarf_Half attr = 0; Dwarf_Half attr_form = 0; @@ -1233,7 +1531,7 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, info_ptr = die_info_ptr; DECODE_LEB128_UWORD_CK(info_ptr, utmp,dbg,error,die_info_end); - abbrev_code = (Dwarf_Word) utmp; + abbrev_code = (Dwarf_Unsigned) utmp; if (abbrev_code == 0) { /* Should never happen. Tested before we got here. */ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); @@ -1272,26 +1570,34 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, attr_form = (Dwarf_Half) utmp6; } + if (attr_form == DW_FORM_implicit_const) { + UNUSEDARG Dwarf_Signed cval = 0; + + DECODE_LEB128_SWORD_CK(abbrev_ptr, cval,dbg,error, + abbrev_end); + } if (want_AT_sibling && attr == DW_AT_sibling) { switch (attr_form) { case DW_FORM_ref1: - offset = *(Dwarf_Small *) info_ptr; + READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Small), + error,die_info_end); break; case DW_FORM_ref2: /* READ_UNALIGNED does not update info_ptr */ READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_Half), + info_ptr,DWARF_HALF_SIZE, error,die_info_end); break; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_ufixed), + info_ptr, DWARF_32BIT_SIZE, error,die_info_end); break; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_Unsigned), + info_ptr, DWARF_64BIT_SIZE, error,die_info_end); break; case DW_FORM_ref_udata: @@ -1323,10 +1629,14 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, at die_info_end means 1-past-cu-end and simply means we are at the end, do not return error. Higher level will detect that we are at the end. */ - if (cu_info_start + offset > die_info_end) { - /* Error case, bad DWARF. */ - _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END); - return DW_DLV_ERROR; + { /* Care required here. Offset can be garbage. */ + ptrdiff_t plen = die_info_end - cu_info_start; + ptrdiff_t signdoffset = (ptrdiff_t)offset; + if (signdoffset > plen || signdoffset < 0) { + /* Error case, bad DWARF. */ + _dwarf_error(dbg, error,DW_DLE_SIBLING_OFFSET_WRONG); + return DW_DLV_ERROR; + } } /* At or before end-of-cu */ *next_die_ptr_out = cu_info_start + offset; @@ -1334,9 +1644,11 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, } no_sibling_attr: - if (attr_form != 0) { + if (attr_form != 0 && attr_form != DW_FORM_implicit_const) { int res = 0; Dwarf_Unsigned sizeofval = 0; + ptrdiff_t sizeb = 0; + res = _dwarf_get_size_of_val(cu_context->cc_dbg, attr_form, cu_context->cc_version_stamp, @@ -1351,6 +1663,12 @@ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, } /* It is ok for info_ptr == die_info_end, as we will test later before using a too-large info_ptr */ + sizeb = (ptrdiff_t)sizeofval; + if (sizeb > (die_info_end - info_ptr) || + sizeb < 0) { + _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END); + return DW_DLV_ERROR; + } info_ptr += sizeofval; if (info_ptr > die_info_end) { /* More than one-past-end indicates a bug somewhere, @@ -1424,21 +1742,22 @@ dwarf_siblingof_b(Dwarf_Debug dbg, /* die_info_end points 1-past end of die (once set) */ Dwarf_Byte_Ptr die_info_end = 0; - Dwarf_Word abbrev_code = 0; + Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; int lres = 0; /* Since die may be NULL, we rely on the input argument. */ - Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading: - &dbg->de_types_reading; - Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data: - dbg->de_debug_types.dss_data; - - + Dwarf_Debug_InfoTypes dis = 0; + Dwarf_Small *dataptr = 0; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return (DW_DLV_ERROR); } + dis = is_info? &dbg->de_info_reading: + &dbg->de_types_reading; + dataptr = is_info? dbg->de_debug_info.dss_data: + dbg->de_debug_types.dss_data; + if (die == NULL) { /* Find root die of cu */ @@ -1467,6 +1786,7 @@ dwarf_siblingof_b(Dwarf_Debug dbg, } die_info_ptr = cu_info_start + headerlen; die_info_end = _dwarf_calculate_info_section_end_ptr(context); + /* Recording the CU die pointer so we can later access for special FORMs relating to .debug_str_offsets and .debug_addr */ @@ -1475,7 +1795,7 @@ dwarf_siblingof_b(Dwarf_Debug dbg, } else { /* Find sibling die. */ Dwarf_Bool has_child = false; - Dwarf_Sword child_depth = 0; + Dwarf_Signed child_depth = 0; Dwarf_CU_Context context=0; /* We cannot have a legal die unless debug_info was loaded, so @@ -1527,16 +1847,44 @@ dwarf_siblingof_b(Dwarf_Debug dbg, } } - /* die_info_ptr can be one-past-end. */ + /* die_info_ptr can be one-past-end. */ if ((die_info_ptr == die_info_end) || ((*die_info_ptr) == 0)) { - for (; child_depth > 0 && *die_info_ptr == 0; - child_depth--, die_info_ptr++) { + /* We are at the end of a sibling list. + get back to the next containing + sibling list (looking for a libling + list with more on it). + */ + for (;;) { + if (child_depth == 0) { + /* Meaning there is no outer list, + so stop. */ + break; + } + if (die_info_ptr == die_info_end) { + /* September 2016: do not deref + if we are past end. + If we are at end at this point + it means the sibling list + inside this CU is not properly + terminated. We run off the end. + An error.*/ + _dwarf_error(dbg, error,DW_DLE_SIBLING_LIST_IMPROPER); + return (DW_DLV_ERROR); + } + if (*die_info_ptr) { + /* We have a real sibling. */ + break; + } + /* Move out one DIE level. + Move past NUL byte marking end of + this sibling list. */ + child_depth--; + die_info_ptr++; } } else { child_depth = has_child ? child_depth + 1 : child_depth; } - } while (child_depth != 0); } @@ -1570,7 +1918,7 @@ dwarf_siblingof_b(Dwarf_Debug dbg, _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); return (DW_DLV_ERROR); } - abbrev_code = (Dwarf_Word) utmp; + abbrev_code = (Dwarf_Unsigned) utmp; if (abbrev_code == 0) { /* Zero means a null DIE */ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); @@ -1612,7 +1960,7 @@ dwarf_child(Dwarf_Die die, Dwarf_Die ret_die = 0; Dwarf_Bool has_die_child = 0; Dwarf_Debug dbg; - Dwarf_Word abbrev_code = 0; + Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned utmp = 0; Dwarf_Debug_InfoTypes dis = 0; int res = 0; @@ -1631,9 +1979,9 @@ dwarf_child(Dwarf_Die die, dis->de_last_di_ptr = die_info_ptr; /* NULL die has no child. */ - if ((*die_info_ptr) == 0) - return (DW_DLV_NO_ENTRY); - + if ((*die_info_ptr) == 0) { + return DW_DLV_NO_ENTRY; + } context = die->di_cu_context; die_info_end = _dwarf_calculate_info_section_end_ptr(context); @@ -1646,6 +1994,9 @@ dwarf_child(Dwarf_Die die, if(res != DW_DLV_OK) { return res; } + if (die_info_ptr == die_info_end) { + return DW_DLV_NO_ENTRY; + } die_info_ptr = die_info_ptr2; dis->de_last_di_ptr = die_info_ptr; @@ -1658,13 +2009,13 @@ dwarf_child(Dwarf_Die die, } ++dis->de_last_di_ptr; } - return (DW_DLV_NO_ENTRY); + return DW_DLV_NO_ENTRY; } ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); if (ret_die == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } ret_die->di_debug_ptr = die_info_ptr; ret_die->di_cu_context = die->di_cu_context; @@ -1672,7 +2023,7 @@ dwarf_child(Dwarf_Die die, DECODE_LEB128_UWORD_CK(die_info_ptr, utmp, dbg,error,die_info_end); - abbrev_code = (Dwarf_Word) utmp; + abbrev_code = (Dwarf_Unsigned) utmp; dis->de_last_di_ptr = die_info_ptr; @@ -1700,7 +2051,7 @@ dwarf_child(Dwarf_Die die, } if (lres == DW_DLV_NO_ENTRY) { dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + _dwarf_error(dbg, error, DW_DLE_ABBREV_MISSING); return DW_DLV_ERROR; } @@ -1862,6 +2213,77 @@ dwarf_die_abbrev_global_offset(Dwarf_Die die, } +/* New August 2018. + Because some real compressed sections + have .zdebug instead + of .debug as the leading characters. + actual_sec_name_out points to a static + string so so not free it. */ +int +dwarf_get_real_section_name(Dwarf_Debug dbg, + const char *std_section_name, + const char **actual_sec_name_out, + Dwarf_Small *marked_zcompressed, /* zdebug */ + Dwarf_Small *marked_zlib_compressed, /* ZLIB string */ + Dwarf_Small *marked_shf_compressed, /* SHF_COMPRESSED */ + Dwarf_Unsigned *compressed_length, + Dwarf_Unsigned *uncompressed_length, + Dwarf_Error *error) +{ + unsigned i = 0; + char tbuf[50]; + unsigned std_sec_name_len = strlen(std_section_name); + + tbuf[0] = 0; + /* std_section_name never has the .dwo on the end, + so allow for that and allow one (arbitrarily) more. */ + if ((std_sec_name_len + 5) < sizeof(tbuf)) { + strcpy(tbuf,std_section_name); + strcpy(tbuf+std_sec_name_len,".dwo"); + } + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + for (i=0; i < dbg->de_debug_sections_total_entries; i++) { + struct Dwarf_dbg_sect_s *sdata = &dbg->de_debug_sections[i]; + struct Dwarf_Section_s *section = sdata->ds_secdata; + const char *std = section->dss_standard_name; + + if (!strcmp(std,std_section_name) || + !strcmp(std,tbuf)) { + const char *used = section->dss_name; + *actual_sec_name_out = used; + if (sdata->ds_have_zdebug) { + *marked_zcompressed = TRUE; + } + if (section->dss_ZLIB_compressed) { + *marked_zlib_compressed = TRUE; + if (uncompressed_length) { + *uncompressed_length = + section->dss_uncompressed_length; + } + if (compressed_length) { + *compressed_length = + section->dss_compressed_length; + } + } + if (section->dss_shf_compressed) { + *marked_shf_compressed = TRUE; + if (uncompressed_length) { + *uncompressed_length = + section->dss_uncompressed_length; + } + if (compressed_length) { + *compressed_length = + section->dss_compressed_length; + } + } + return DW_DLV_OK; + } + } + return DW_DLV_NO_ENTRY; +} /* This is useful when printing DIE data. The string pointer returned must not be freed. With non-elf objects it is possible the @@ -1909,6 +2331,3 @@ dwarf_get_die_section_name_b(Dwarf_Die die, is_info = context->cc_is_info; return dwarf_get_die_section_name(dbg,is_info,sec_name,error); } - - - diff --git a/thirdparty/dwarf/dwarf_dnames.c b/thirdparty/dwarf/dwarf_dnames.c new file mode 100644 index 00000000..f209a14f --- /dev/null +++ b/thirdparty/dwarf/dwarf_dnames.c @@ -0,0 +1,1340 @@ +/* + Portions Copyright (C) 2017-2019 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + +/* This provides access to the DWARF5 .debug_names section. */ + +#include "config.h" +#include +#include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "dwarf_global.h" +#include "dwarf_dnames.h" + +#define FALSE 0 +#define TRUE 1 + +/* freedabs attempts to do some cleanup in the face + of an error. */ +static void +freedabs(struct Dwarf_D_Abbrev_s *dab) +{ + struct Dwarf_D_Abbrev_s *tmp = 0; + for(; dab; dab = tmp) { + tmp = dab->da_next; + free(dab); + } +} + +/* Encapsulates DECODE_LEB128_UWORD_CK + so the caller can free resources + in case of problems. */ +static int +read_uword_ab(Dwarf_Small **lp, + Dwarf_Unsigned *out_p, + Dwarf_Debug dbg, + Dwarf_Error *err, + Dwarf_Small *lpend) + +{ + Dwarf_Small *inptr = *lp; + Dwarf_Unsigned out = 0; + + /* The macro updates inptr */ + DECODE_LEB128_UWORD_CK(inptr, + out, dbg,err,lpend); + *lp = inptr; + *out_p = out; + return DW_DLV_OK; +} + + +static int +fill_in_abbrevs_table(struct Dwarf_Dnames_index_header_s * dn, + Dwarf_Error * error) +{ + Dwarf_Small *abdata = dn->din_abbreviations; + Dwarf_Unsigned ablen = dn->din_abbrev_table_size; + Dwarf_Small *tabend = abdata+ablen; + Dwarf_Small *abcur = 0; + Dwarf_Unsigned code = 0; + Dwarf_Unsigned tag = 0; + int foundabend = FALSE; + unsigned abcount = 0; + struct Dwarf_D_Abbrev_s *firstdab = 0; + struct Dwarf_D_Abbrev_s *lastdab = 0; + struct Dwarf_D_Abbrev_s *curdab = 0; + Dwarf_Debug dbg = dn->din_dbg; + + for (abcur = abdata; abcur < tabend; ) { + Dwarf_Unsigned idx = 0; + Dwarf_Unsigned form = 0; + Dwarf_Small *inner = 0; + unsigned idxcount = 0; + int res = 0; + + res = read_uword_ab(&abcur,&code,dbg,error,tabend); + if (res != DW_DLV_OK) { + freedabs(firstdab); + return res; + } + if (code == 0) { + foundabend = TRUE; + break; + } + + res = read_uword_ab(&abcur,&tag,dbg,error,tabend); + if (res != DW_DLV_OK) { + freedabs(firstdab); + return res; + } + inner = abcur; + curdab = (struct Dwarf_D_Abbrev_s *)calloc(1, + sizeof(struct Dwarf_D_Abbrev_s)); + if(!curdab) { + freedabs(firstdab); + firstdab = 0; + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + curdab->da_tag = tag; + curdab->da_abbrev_code = code; + abcount++; + for(;;) { + res = read_uword_ab(&inner,&idx,dbg,error,tabend); + if (res != DW_DLV_OK) { + free(curdab); + freedabs(firstdab); + firstdab = 0; + return res; + } + res = read_uword_ab(&inner,&form,dbg,error,tabend); + if (res != DW_DLV_OK) { + free(curdab); + freedabs(firstdab); + firstdab = 0; + return res; + } + if (!idx && !form) { + break; + } + if (idxcount >= ABB_PAIRS_MAX) { + free(curdab); + freedabs(firstdab); + firstdab = 0; + _dwarf_error(dbg, error, + DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW); + return DW_DLV_ERROR; + } + curdab->da_pairs[idxcount].ap_index = idx; + curdab->da_pairs[idxcount].ap_form = form; + idxcount++; + } + curdab->da_pairs_count = idxcount; + abcur = inner +1; + if (!firstdab) { + firstdab = curdab; + lastdab = curdab; + } else { + /* Add new on the end, last */ + lastdab->da_next = curdab; + } + } + if (!foundabend) { + freedabs(firstdab); + _dwarf_error(dbg, error, + DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION); + return DW_DLV_OK; + } + { + unsigned ct = 0; + struct Dwarf_D_Abbrev_s *tmpa = 0; + + dn->din_abbrev_list = (struct Dwarf_D_Abbrev_s *)calloc( + abcount,sizeof(struct Dwarf_D_Abbrev_s)); + if(!dn->din_abbrev_list) { + freedabs(firstdab); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + dn->din_abbrev_list_count = abcount; + tmpa = firstdab; + for(ct = 0; tmpa && ct < abcount; ++ct) { + struct Dwarf_D_Abbrev_s *tmpb =tmpa->da_next; + /* da_next no longer means anything */ + dn->din_abbrev_list[ct] = *tmpa; + dn->din_abbrev_list[ct].da_next = 0; + tmpa = tmpb; + } + freedabs(firstdab); + tmpa = 0; + firstdab = 0; + lastdab = 0; + /* Now the list has turned into an array. We can ignore + the list aspect. */ + } + return DW_DLV_OK; +} + +static int +get_inhdr_cur(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + struct Dwarf_Dnames_index_header_s **cur, + Dwarf_Error *error) +{ + Dwarf_Debug dbg = 0; + + if (!dn) { + _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_NULL_POINTER); + return DW_DLV_ERROR; + } + dbg = dn->dn_dbg; + if (index_number >= dn->dn_inhdr_count) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); + return DW_DLV_ERROR; + } + *cur = dn->dn_inhdr_first + index_number; + return DW_DLV_OK; +} + + +static int +read_uword_val(Dwarf_Debug dbg, + Dwarf_Small **ptr_in, + Dwarf_Small *endptr, + int errcode, + Dwarf_Unsigned *val_out, + Dwarf_Unsigned area_length, + Dwarf_Error *error) +{ + Dwarf_Unsigned val = 0; + Dwarf_Small *ptr = *ptr_in; + + READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, + ptr, DWARF_32BIT_SIZE, + error,endptr); + ptr += DWARF_32BIT_SIZE; + if (ptr >= endptr) { + _dwarf_error(dbg, error,errcode); + return DW_DLV_ERROR; + } + /* Some of the fields are not length fields, but + if non-zero the size will be longer than + the value, so we do the following + overall sanity check to avoid overflows. */ + if (val > area_length) { + _dwarf_error(dbg, error,errcode); + return DW_DLV_ERROR; + } + *val_out = val; + *ptr_in = ptr; + return DW_DLV_OK; +} + +/* We do not alter the dn data here. */ +static int +read_a_name_index(Dwarf_Dnames_Head dn, + Dwarf_Unsigned section_offset, + Dwarf_Small **curptr_in, + Dwarf_Small *end_section, + Dwarf_Unsigned remaining_section_size, + struct Dwarf_Dnames_index_header_s ** index_header_out, + Dwarf_Error *error) +{ + Dwarf_Unsigned area_length = 0; + int local_length_size; + int local_extension_size = 0; + Dwarf_Small *past_length = 0; + Dwarf_Small *end_dnames = 0; + Dwarf_Half version = 0; + Dwarf_Half padding = 0; + Dwarf_Unsigned comp_unit_count = 0; + Dwarf_Unsigned local_type_unit_count = 0; + Dwarf_Unsigned foreign_type_unit_count = 0; + Dwarf_Unsigned bucket_count = 0; + Dwarf_Unsigned name_count = 0; + Dwarf_Unsigned abbrev_table_size = 0; /* bytes */ + Dwarf_Unsigned augmentation_string_size = 0; /* bytes */ + int res = 0; + const char *str_utf8 = 0; + Dwarf_Small *curptr = *curptr_in; + struct Dwarf_Dnames_index_header_s *di_header = 0; + Dwarf_Debug dbg = dn->dn_dbg; + + READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned, + curptr, local_length_size, + local_extension_size,error, + remaining_section_size,end_section); + + /* curptr now points past the length field */ + past_length = curptr; + + /* Two stage length test so overflow is caught. */ + if (area_length > remaining_section_size) { + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + if ((area_length + local_length_size + local_extension_size) > + remaining_section_size) { + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + end_dnames = curptr + area_length; + + READ_UNALIGNED_CK(dbg, version, Dwarf_Half, + curptr, DWARF_HALF_SIZE, + error,end_dnames); + curptr += DWARF_HALF_SIZE; + if (curptr >= end_dnames) { + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + if (version != DWARF_DNAMES_VERSION5) { + _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + return (DW_DLV_ERROR); + } + READ_UNALIGNED_CK(dbg, padding, Dwarf_Half, + curptr, DWARF_HALF_SIZE, + error,end_dnames); + curptr += DWARF_HALF_SIZE; + if (curptr >= end_dnames) { + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + if (padding) { + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return (DW_DLV_ERROR); + } + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &comp_unit_count,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &local_type_unit_count,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &foreign_type_unit_count,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &bucket_count,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &name_count,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &abbrev_table_size,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + res = read_uword_val(dbg, &curptr, + end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR, + &augmentation_string_size,area_length,error); + if (res != DW_DLV_OK) { + return res; + } + + str_utf8 = (const char *) curptr; + + curptr+= augmentation_string_size; + if (curptr >= end_dnames) { + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + + di_header = (struct Dwarf_Dnames_index_header_s *) + calloc(1,sizeof(*di_header)); + if(!di_header) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + + di_header->din_dbg = dbg; + di_header->din_section_offset = section_offset; + di_header->din_indextable_data = past_length; + di_header->din_indextable_length = area_length; + di_header->din_version = version; + di_header->din_comp_unit_count = comp_unit_count; + di_header->din_local_type_unit_count = local_type_unit_count ; + di_header->din_foreign_type_unit_count = foreign_type_unit_count ; + di_header->din_bucket_count = bucket_count ; + di_header->din_name_count = name_count ; + di_header->din_abbrev_table_size = abbrev_table_size; + di_header->din_augmentation_string_size = augmentation_string_size; + di_header->din_augmentation_string = calloc(1, + augmentation_string_size +1); + strncpy(di_header->din_augmentation_string,str_utf8, + augmentation_string_size); + + { + /* This deals with a zero length string too. */ + Dwarf_Unsigned len = augmentation_string_size; + char *cp = 0; + char *cpend = 0; + Dwarf_Bool foundnull = FALSE; + + cp = di_header->din_augmentation_string; + cpend = cp + len; + for( ; cpdin_cu_list = curptr; + curptr += dbg->de_length_size * comp_unit_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + di_header->din_local_tu_list = curptr; + + curptr += dbg->de_length_size * local_type_unit_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + di_header->din_foreign_tu_list = curptr; + curptr += sizeof(Dwarf_Sig8) * foreign_type_unit_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + + di_header->din_buckets = curptr; + curptr += DWARF_32BIT_SIZE * bucket_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + + di_header->din_hash_table = curptr; + curptr += sizeof(Dwarf_Sig8) * name_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + + di_header->din_string_offsets = curptr; + curptr += DWARF_32BIT_SIZE * name_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + + di_header->din_entry_offsets = curptr; + curptr += DWARF_32BIT_SIZE * name_count; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + di_header->din_abbreviations = curptr; + curptr += abbrev_table_size; + if(curptr > end_dnames) { + free(di_header->din_augmentation_string); + free(di_header); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR); + return DW_DLV_ERROR; + } + + di_header->din_entry_pool = curptr; + di_header->din_offset_size = local_length_size; + + di_header->din_entry_pool_size = end_dnames - curptr; + + *curptr_in = curptr; + *index_header_out = di_header; + res = fill_in_abbrevs_table(di_header,error); + if (res != DW_DLV_OK) { + free(di_header->din_augmentation_string); + free(di_header); + return res; + } + return DW_DLV_OK; +} + +#define FAKE_LAST_USED 0xffffffff + +static void +free_inhdr_content(struct Dwarf_Dnames_index_header_s *f) +{ + free(f->din_augmentation_string); + free(f->din_abbrev_list); +} +static void +free_inhdr_list(struct Dwarf_Dnames_index_header_s *f) +{ + struct Dwarf_Dnames_index_header_s *tmp = 0; + + for( ; f ; f = tmp) { + tmp = f->din_next; + free_inhdr_content(f); + free(f); + } +} + +/* There may be one debug index for an entire object file, + for multiple CUs or there can be individual indexes + for some CUs. + see DWARF5 6.1.1.3 Per_CU versus Per-Module Indexes. */ +int +dwarf_debugnames_header(Dwarf_Debug dbg, + Dwarf_Dnames_Head * dn_out, + Dwarf_Unsigned * dn_count_out, + Dwarf_Error *error) +{ + Dwarf_Unsigned remaining = 0; + Dwarf_Dnames_Head dn_header = 0; + Dwarf_Unsigned section_size; + Dwarf_Small *start_section = 0; + Dwarf_Small *end_section = 0; + Dwarf_Small *curptr = 0; + struct Dwarf_Dnames_index_header_s *inhdr_last = 0; + struct Dwarf_Dnames_index_header_s *inhdr_first = 0; + unsigned inhdr_count = 0; + int res = 0; + + if(!dbg) { + _dwarf_error(dbg, error,DW_DLE_DBG_NULL); + return DW_DLV_ERROR; + } + + res = _dwarf_load_section(dbg, &dbg->de_debug_names, error); + if (res != DW_DLV_OK) { + return res; + } + + section_size = dbg->de_debug_names.dss_size; + if(!section_size){ + return DW_DLV_NO_ENTRY; + } + start_section = dbg->de_debug_names.dss_data; + curptr = start_section; + end_section = start_section + section_size; + remaining = section_size; + dn_header = (Dwarf_Dnames_Head)_dwarf_get_alloc(dbg, + DW_DLA_DNAMES_HEAD, 1); + if(!dn_header) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + dn_header->dn_section_data = start_section; + dn_header->dn_section_size = section_size; + dn_header->dn_section_end = start_section + section_size; + dn_header->dn_dbg = dbg; + for( ; curptr < end_section; ) { + struct Dwarf_Dnames_index_header_s * index_header = 0; + Dwarf_Small *curptr_start = curptr; + Dwarf_Unsigned usedspace = 0; + Dwarf_Unsigned section_offset = curptr - start_section; + + res = read_a_name_index(dn_header, + section_offset, + &curptr, + end_section, + remaining, + &index_header, + error); + if (res == DW_DLV_ERROR) { + free_inhdr_list(inhdr_first); + dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); + return res; + } + if (res == DW_DLV_NO_ENTRY) { + /* Impossible. A bug. Or possibly + a bunch of zero pad? */ + free_inhdr_list(inhdr_first); + dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); + break; + } + /* Add the new one to the list. */ + if(!inhdr_first) { + inhdr_count = 1; + inhdr_first = index_header; + inhdr_last = index_header; + } else { + struct Dwarf_Dnames_index_header_s *tmp = inhdr_last; + inhdr_last = index_header; + tmp->din_next = index_header; + inhdr_count++; + } + usedspace = curptr - curptr_start; + remaining -= - usedspace; + if (remaining < 5) { + /* No more in here, just padding. Check for zero + in padding. */ + if ((curptr +remaining) < end_section) { + free_inhdr_list(inhdr_first); + dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_OFF_END); + return DW_DLV_ERROR; + } + for ( ; curptr < end_section; ++curptr) { + if(*curptr) { + /* One could argue this is a harmless error, + but for now assume it is real corruption. */ + free_inhdr_list(inhdr_first); + dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD); + _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_PAD_NON_ZERO); + return DW_DLV_ERROR; + } + } + } + } + { + struct Dwarf_Dnames_index_header_s *cur = 0; + int n = 0; + + dn_header->dn_inhdr_first = + (struct Dwarf_Dnames_index_header_s *) + calloc(inhdr_count,sizeof(struct Dwarf_Dnames_index_header_s)); + for(n = 0,cur = inhdr_first; cur; ++n ) { + /* We are copying these structs so do not + free them at this time. */ + struct Dwarf_Dnames_index_header_s *tmp = cur->din_next; + dn_header->dn_inhdr_first[n] = *cur; + cur = tmp; + } + } + *dn_out = dn_header; + *dn_count_out = inhdr_count; + return DW_DLV_OK; +} + + +int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + + Dwarf_Unsigned * section_offset, + Dwarf_Unsigned * version, /* 5 */ + Dwarf_Unsigned * offset_size, /* 4 or 8 */ + + /* The counts are entry counts, not bye sizes. */ + Dwarf_Unsigned * comp_unit_count, + Dwarf_Unsigned * local_type_unit_count, + Dwarf_Unsigned * foreign_type_unit_count, + Dwarf_Unsigned * bucket_count, + Dwarf_Unsigned * name_count, + + /* The following are counted in bytes */ + Dwarf_Unsigned * indextable_overall_length, + Dwarf_Unsigned * abbrev_table_size, + Dwarf_Unsigned * entry_pool_size, + Dwarf_Unsigned * augmentation_string_size, + + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + int res = 0; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if(res != DW_DLV_OK) { + return res; + } + + if (section_offset) { + *section_offset = cur->din_section_offset; + } + if (version) { + *version = cur->din_version; + } + if (offset_size) { + *offset_size = cur->din_offset_size; + } + if (comp_unit_count) { + *comp_unit_count = cur->din_comp_unit_count; + } + if (local_type_unit_count) { + *local_type_unit_count = cur->din_local_type_unit_count; + } + if (foreign_type_unit_count) { + *foreign_type_unit_count = cur->din_foreign_type_unit_count; + } + if (bucket_count) { + *bucket_count = cur->din_bucket_count; + } + if (name_count) { + *name_count = cur->din_name_count; + } + if (abbrev_table_size) { + *abbrev_table_size = cur->din_abbrev_table_size; + } + if (entry_pool_size) { + *entry_pool_size = cur->din_entry_pool_size; + } + if (augmentation_string_size) { + *augmentation_string_size = cur->din_augmentation_string_size; + } + if (indextable_overall_length) { + *indextable_overall_length = cur->din_indextable_length; + } + return DW_DLV_OK; +} + +int +dwarf_debugnames_cu_entry(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned offset_number, + Dwarf_Unsigned * offset_count, + Dwarf_Unsigned * offset, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + Dwarf_Debug dbg = 0; + int res; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + + if (offset_number >= cur->din_comp_unit_count) { + if (offset_count) { + *offset_count = cur->din_comp_unit_count; + } + return DW_DLV_NO_ENTRY; + } + + + if (offset) { + Dwarf_Unsigned offsetval = 0; + Dwarf_Small *ptr = cur->din_cu_list + + offset_number *cur->din_offset_size; + Dwarf_Small *endptr = cur->din_local_tu_list; + + READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, + ptr, cur->din_offset_size, + error,endptr); + *offset = offsetval; + } + if (offset_count) { + *offset_count = cur->din_comp_unit_count; + } + return DW_DLV_OK; +} + +int +dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned offset_number, + Dwarf_Unsigned * offset_count, + Dwarf_Unsigned * offset, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + Dwarf_Debug dbg = 0; + int res; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + + if (offset_number >= cur->din_local_type_unit_count) { + if (offset_count) { + *offset_count = cur->din_local_type_unit_count; + } + return DW_DLV_NO_ENTRY; + } + + + if (offset) { + Dwarf_Unsigned offsetval = 0; + Dwarf_Small *ptr = cur->din_local_tu_list + + offset_number *cur->din_offset_size; + Dwarf_Small *endptr = cur->din_foreign_tu_list; + + READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, + ptr, cur->din_offset_size, + error,endptr); + *offset = offsetval; + } + if (offset_count) { + *offset_count = cur->din_local_type_unit_count; + } + return DW_DLV_OK; +} + + + +/* Here the sig_number ranges from + local_type_unit_count to + local_type_unit_count+foreign_type_unit_count-1 + because the foreign indices are a continuation + of the local tu indices. +*/ +int +dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned sig_number, + + /* these index starting at local_type_unit_count */ + Dwarf_Unsigned * sig_minimum, + Dwarf_Unsigned * sig_count, + Dwarf_Sig8 * signature, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + Dwarf_Debug dbg = 0; + int res; + unsigned legal_low = 0; + unsigned legal_high = 0; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + legal_low = cur->din_local_type_unit_count; + legal_high = legal_low + cur->din_foreign_type_unit_count; + if (sig_number < legal_low) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); + return DW_DLV_ERROR; + } + if (sig_number >= legal_high) { + if (sig_minimum) { + *sig_minimum = legal_low; + } + if (sig_count) { + *sig_count = cur->din_foreign_type_unit_count; + } + return DW_DLV_NO_ENTRY; + } + + if (signature) { + Dwarf_Small *ptr = cur->din_foreign_tu_list + + sig_number *cur->din_offset_size; + Dwarf_Small *endptr = cur->din_hash_table; + if((ptr +sizeof(Dwarf_Sig8)) > endptr) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); + return DW_DLV_ERROR; + } + memcpy(signature,ptr,sizeof(Dwarf_Sig8)); + } + if (sig_minimum) { + *sig_minimum = legal_low; + } + if (sig_count) { + *sig_count = cur->din_foreign_type_unit_count; + } + return DW_DLV_OK; +} + +/* The hash table is composed of the buckets table + and the hashes table. + If there is no buckets table (bucket_count == 0) + the hashes part still exists. */ +int dwarf_debugnames_bucket(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned bucket_number, + Dwarf_Unsigned * bucket_count, + Dwarf_Unsigned * index_of_name_entry, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + Dwarf_Debug dbg = 0; + int res; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + + if (bucket_number >= cur->din_bucket_count) { + if (bucket_count) { + *bucket_count = cur->din_bucket_count; + } + return DW_DLV_NO_ENTRY; + } + + if (index_of_name_entry) { + Dwarf_Unsigned offsetval = 0; + Dwarf_Small *ptr = cur->din_buckets + + bucket_number * DWARF_32BIT_SIZE; + Dwarf_Small *endptr = cur->din_hash_table; + + READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, + ptr, DWARF_32BIT_SIZE, + error,endptr); + *index_of_name_entry = offsetval; + } + if (bucket_count) { + *bucket_count = cur->din_bucket_count; + } + return DW_DLV_OK; +} + +/* Access to the .debug_names name table. */ +int +dwarf_debugnames_name(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned name_entry, + Dwarf_Unsigned * names_count, + Dwarf_Sig8 * signature, + Dwarf_Unsigned * offset_to_debug_str, + Dwarf_Unsigned * offset_in_entrypool, + Dwarf_Error * error) + +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + Dwarf_Debug dbg = 0; + int res; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + + if (name_entry >= cur->din_name_count) { + if (names_count) { + *names_count = cur->din_bucket_count; + } + return DW_DLV_NO_ENTRY; + } + + if (signature) { + Dwarf_Small *ptr = cur->din_hash_table + + name_entry *sizeof(Dwarf_Sig8); + Dwarf_Small *endptr = cur->din_string_offsets; + if ((ptr + sizeof(Dwarf_Sig8)) > endptr) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG); + return DW_DLV_ERROR; + } + memcpy(signature,ptr,sizeof(Dwarf_Sig8)); + } + + if (offset_to_debug_str) { + Dwarf_Unsigned offsetval = 0; + Dwarf_Small *ptr = cur->din_string_offsets + + name_entry * DWARF_32BIT_SIZE; + Dwarf_Small *endptr = cur->din_abbreviations; + + READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, + ptr, DWARF_32BIT_SIZE, + error,endptr); + *offset_to_debug_str = offsetval; + } + if (offset_in_entrypool) { + Dwarf_Unsigned offsetval = 0; + Dwarf_Small *ptr = cur->din_entry_offsets + + name_entry * DWARF_32BIT_SIZE; + Dwarf_Small *endptr = cur->din_abbreviations; + + READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned, + ptr, DWARF_32BIT_SIZE, + error,endptr); + *offset_in_entrypool = offsetval; + } + + if (names_count) { + *names_count = cur->din_name_count; + } + return DW_DLV_OK; +} + + + + + + +/* If abbrev_code returned is zero there is no tag returned + and we are at the end of the entry pool set for this name + entry. + abbrev code, tag + nameindexattr,form + ... + 0,0 + ... repeat like the above + 0 +*/ + +/* This provides a way to print the abbrev table by + indexing from 0. */ +int +dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned abbrev_entry, + Dwarf_Unsigned * abbrev_code, + Dwarf_Unsigned * tag, + + /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 + */ + Dwarf_Unsigned * number_of_abbrev, + + /* The number of attr/form pairs, not counting the trailing + 0,0 pair. */ + Dwarf_Unsigned * number_of_attr_form_entries, + Dwarf_Error *error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + struct Dwarf_D_Abbrev_s * abbrev = 0; + int res = 0; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + + if (abbrev_entry >= cur->din_abbrev_list_count) { + if (number_of_abbrev) { + *number_of_abbrev = cur->din_abbrev_list_count; + } + return DW_DLV_NO_ENTRY; + } + abbrev = cur->din_abbrev_list + abbrev_entry; + if(abbrev_code) { + *abbrev_code = abbrev->da_abbrev_code; + } + if(tag) { + *tag = abbrev->da_tag; + } + if(number_of_abbrev) { + *number_of_abbrev = cur->din_abbrev_list_count; + } + if(number_of_attr_form_entries) { + *number_of_attr_form_entries = abbrev->da_pairs_count; + } + return DW_DLV_OK; +} + +static int +_dwarf_internal_abbrev_by_code(struct Dwarf_Dnames_index_header_s *cur, + Dwarf_Unsigned abbrev_code, + Dwarf_Unsigned * tag, + Dwarf_Unsigned * index_of_abbrev, + Dwarf_Unsigned * number_of_attr_form_entries) +{ + unsigned n = 0; + struct Dwarf_D_Abbrev_s * abbrev = 0; + + abbrev = cur->din_abbrev_list; + for(n = 0; n < cur->din_abbrev_list_count; ++n,++abbrev) { + if (abbrev_code == abbrev->da_abbrev_code) { + if (tag) { + *tag = abbrev->da_tag; + } + if (index_of_abbrev) { + *index_of_abbrev = n; + } + if (number_of_attr_form_entries) { + *number_of_attr_form_entries = abbrev->da_pairs_count; + } + return DW_DLV_OK; + } + } + /* Something is wrong, not found! */ + return DW_DLV_NO_ENTRY; + +} + +/* Access the abbrev by abbrev code (instead of index). */ +int +dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned abbrev_code, + Dwarf_Unsigned * tag, + + /* The number of this code/tag as an array index. */ + Dwarf_Unsigned * index_of_abbrev, + + /* The number of attr/form pairs, not counting the trailing + 0,0 pair. */ + Dwarf_Unsigned * number_of_attr_form_entries, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + int res; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_internal_abbrev_by_code(cur, + abbrev_code, + tag, index_of_abbrev, + number_of_attr_form_entries); + return res; +} + + +int +dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned abbrev_entry_index, + Dwarf_Unsigned abbrev_form_index, + Dwarf_Unsigned * name_index_attr, + Dwarf_Unsigned * form, + Dwarf_Unsigned * number_of_attr_form_entries, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + struct Dwarf_D_Abbrev_s * abbrev = 0; + struct abbrev_pair_s *ap = 0; + int res; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + + if (abbrev_entry_index >= cur->din_abbrev_list_count) { + if (number_of_attr_form_entries) { + *number_of_attr_form_entries = cur->din_bucket_count; + } + return DW_DLV_NO_ENTRY; + } + abbrev = cur->din_abbrev_list + abbrev_entry_index; + if (abbrev_form_index >= abbrev->da_pairs_count) { + return DW_DLV_NO_ENTRY; + } + ap = abbrev->da_pairs + abbrev_entry_index; + if(name_index_attr) { + *name_index_attr = ap->ap_index; + } + if(form) { + *form = ap->ap_form; + } + if(number_of_attr_form_entries) { + *number_of_attr_form_entries = abbrev->da_pairs_count; + } + return DW_DLV_OK; +} + +/* This, combined with dwarf_debugnames_entrypool_values(), + lets one examine as much or as little of an entrypool + as one wants to by alternately calling these two + functions. */ + +int dwarf_debugnames_entrypool(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned offset_in_entrypool, + Dwarf_Unsigned * abbrev_code, + Dwarf_Unsigned * tag, + Dwarf_Unsigned * value_count, + Dwarf_Unsigned * index_of_abbrev, + Dwarf_Unsigned * offset_of_initial_value, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + Dwarf_Debug dbg = 0; + int res = 0; + Dwarf_Small *entrypool = 0; + Dwarf_Small *endentrypool = 0; + Dwarf_Unsigned abcode = 0; + Dwarf_Unsigned leblen = 0; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + + if (offset_in_entrypool >= cur->din_entry_pool_size) { + _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET); + return DW_DLV_ERROR; + } + endentrypool = cur->din_entry_pool +cur->din_entry_pool_size; + entrypool = cur->din_entry_pool + offset_in_entrypool; + + DECODE_LEB128_UWORD_LEN_CK(entrypool,abcode,leblen, + dbg,error,endentrypool); + + res = _dwarf_internal_abbrev_by_code(cur, + abcode, + tag, index_of_abbrev, + value_count); + if (res != DW_DLV_OK) { + /* Never DW_DLV_ERROR (so far) */ + return res; + } + *offset_of_initial_value = offset_in_entrypool + leblen; + *abbrev_code = abcode; + return DW_DLV_OK; +} + + +/* Caller, knowing array size needed, passes in arrays + it allocates of for idx, form, offset-size-values, + and signature values. Caller must examine idx-number + and form to decide, for each array element, whether + the offset or the signature contains the value. + So this returns all the values for the abbrev code. + And points via offset_of_next to the next abbrev code. + + While an array of structs would be easier for the caller + to allocate than parallel arrays, public structs have + turned out to be difficult to work with as interfaces + (as formats change over time). + */ +int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head dn, + Dwarf_Unsigned index_number, + Dwarf_Unsigned index_of_abbrev, + Dwarf_Unsigned offset_in_entrypool_of_values, + Dwarf_Unsigned * array_dw_idx_number, + Dwarf_Unsigned * array_form, + Dwarf_Unsigned * array_of_offsets, + Dwarf_Sig8 * array_of_signatures, + + /* offset of the next entrypool entry. */ + Dwarf_Unsigned * offset_of_next_entrypool, + Dwarf_Error * error) +{ + struct Dwarf_Dnames_index_header_s *cur = 0; + struct Dwarf_D_Abbrev_s * abbrev = 0; + Dwarf_Debug dbg = 0; + unsigned n = 0; + int res = 0; + Dwarf_Unsigned abcount = 0; + Dwarf_Unsigned pooloffset = offset_in_entrypool_of_values; + Dwarf_Small * endpool = 0; + Dwarf_Small * poolptr = 0; + + res = get_inhdr_cur(dn,index_number,&cur,error); + if (res != DW_DLV_OK) { + return res; + } + dbg = dn->dn_dbg; + endpool = cur->din_entry_pool + cur->din_entry_pool_size; + + if (index_of_abbrev >= cur->din_abbrev_list_count) { + _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION); + return DW_DLV_ERROR; + } + poolptr = cur->din_entry_pool + offset_in_entrypool_of_values; + abbrev = cur->din_abbrev_list + index_of_abbrev; + abcount = cur->din_abbrev_list_count; + for(n = 0; n < abcount ; ++n) { + struct abbrev_pair_s *abp = abbrev->da_pairs +n; + unsigned idxtype = abp->ap_index; + unsigned form = abp->ap_form; + array_dw_idx_number[n] = idxtype; + array_form[n] = form; + + if(form == DW_FORM_data8 && idxtype == DW_IDX_type_hash) { + if ((poolptr + sizeof(Dwarf_Sig8)) > endpool){ + _dwarf_error(dbg,error, + DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET); + return DW_DLV_ERROR; + } + memcpy(array_of_signatures+n, + poolptr,sizeof(Dwarf_Sig8)); + poolptr += sizeof(Dwarf_Sig8); + pooloffset += sizeof(Dwarf_Sig8); + continue; + } else if (_dwarf_allow_formudata(form)) { + Dwarf_Unsigned val = 0; + Dwarf_Unsigned bytesread = 0; + res = _dwarf_formudata_internal(dbg,form,poolptr, + endpool,&val,&bytesread,error); + if(res != DW_DLV_OK) { + return res; + } + poolptr += bytesread; + pooloffset += bytesread; + array_of_offsets[n] = val; + continue; + } + /* There is some mistake/omission in our code here or in + the data. */ + _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_UNHANDLED_FORM); + return DW_DLV_ERROR; + } + *offset_of_next_entrypool = pooloffset; + return DW_DLV_OK; +} + + + + +/* Frees any Dwarf_Dnames_Head_s data that is directly + mallocd. */ +void +_dwarf_debugnames_destructor(void *m) +{ + struct Dwarf_Dnames_Head_s *h = (struct Dwarf_Dnames_Head_s *)m; + + struct Dwarf_Dnames_index_header_s *cur = 0; + unsigned n = 0; + + cur = h->dn_inhdr_first; + for( ;n < h->dn_inhdr_count ; ++n,++cur) { + free_inhdr_content(cur); + } + free(h->dn_inhdr_first); + h->dn_inhdr_first = 0; + h->dn_inhdr_count = 0; +} diff --git a/thirdparty/dwarf/dwarf_dnames.h b/thirdparty/dwarf/dwarf_dnames.h new file mode 100644 index 00000000..e3a68dfd --- /dev/null +++ b/thirdparty/dwarf/dwarf_dnames.h @@ -0,0 +1,107 @@ +/* + Copyright (C) 2017-2017 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + +/* Only 5 abbrev DW_IDX defined, we + allow three user defined (arbitrarily) */ +#define ABB_PAIRS_MAX 8 + +struct abbrev_pair_s { + unsigned ap_index; + unsigned ap_form; +}; + +struct Dwarf_D_Abbrev_s { + struct Dwarf_D_Abbrev_s * da_next; + unsigned da_abbrev_code; + unsigned da_tag; + unsigned da_pairs_count; + struct abbrev_pair_s da_pairs[ABB_PAIRS_MAX]; +}; + + +#define DWARF_DNAMES_VERSION5 5 + +struct Dwarf_Dnames_index_header_s { + Dwarf_Debug din_dbg; + struct Dwarf_Dnames_index_header_s *din_next; + + /* The .debug_names section offset of 1st byte + of a header record. */ + Dwarf_Unsigned din_section_offset; + + /* For offset and pointer sanity calculations. */ + Dwarf_Small * din_indextable_data; + Dwarf_Unsigned din_indextable_length; + unsigned din_offset_size; + + Dwarf_Unsigned din_version; + Dwarf_Unsigned din_comp_unit_count; + Dwarf_Unsigned din_local_type_unit_count; + Dwarf_Unsigned din_foreign_type_unit_count; + Dwarf_Unsigned din_bucket_count; + Dwarf_Unsigned din_name_count; + Dwarf_Unsigned din_abbrev_table_size; /* bytes */ + Dwarf_Unsigned din_entry_pool_size; /* bytes */ + + Dwarf_Unsigned din_augmentation_string_size; + + /* Since we cannot assume the string is NUL + terminated we allocate a sufficient + string space and NUL terminate the string. + The DWARF5 standard does not specify + it as null-terminated. We copy it into + calloc area so not 'const' */ + char * din_augmentation_string; + + Dwarf_Small * din_cu_list; + Dwarf_Small * din_local_tu_list; + Dwarf_Small * din_foreign_tu_list; + Dwarf_Small * din_buckets; + Dwarf_Small * din_hash_table; + Dwarf_Small * din_string_offsets; + Dwarf_Small * din_entry_offsets; + Dwarf_Small * din_abbreviations; + Dwarf_Small * din_entry_pool; + + unsigned din_abbrev_list_count; + /* An array of size din_abbrev_list_count. */ + struct Dwarf_D_Abbrev_s * din_abbrev_list; + +}; + + +struct Dwarf_Dnames_Head_s { + Dwarf_Debug dn_dbg; + Dwarf_Small * dn_section_data; + Dwarf_Small * dn_section_end; + Dwarf_Unsigned dn_section_size; + unsigned dn_inhdr_count; + + /* Becomes an array of these structs, dn_inhdr_count + of them. */ + struct Dwarf_Dnames_index_header_s * dn_inhdr_first; +}; + +void _dwarf_debugnames_destructor(void *m); diff --git a/thirdparty/dwarf/dwarf_dsc.c b/thirdparty/dwarf/dwarf_dsc.c new file mode 100644 index 00000000..28ec5b38 --- /dev/null +++ b/thirdparty/dwarf/dwarf_dsc.c @@ -0,0 +1,321 @@ +/* + Copyright (C) 2016-2019 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + +#include "config.h" +#include +#ifdef HAVE_STDLIB_H +#include +#endif + +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "dwarf_dsc.h" + +#define FALSE 0 +#define TRUE 1 + +/* When called with ary and *arraycount 0 + this just counts the elements found. + Otherwise it records the values in ary and + recounts. The arraycount pointer must be + passed-in non-null always. */ +static int +get_dsc_leb_entries(Dwarf_Debug dbg, + Dwarf_Small * blockpointer, + Dwarf_Unsigned blocklen, + int dounsigned, + struct Dwarf_Dsc_Entry_s *ary, + size_t * arraycount, + Dwarf_Error * error) +{ + Dwarf_Small *p = blockpointer; + Dwarf_Small *endp = blockpointer + blocklen; + size_t larraycount = 0; + size_t iarraycount = *arraycount; + + if (!ary) { + if (iarraycount) { + /* Internal botch calling this static function. */ + _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + } else { + if (!iarraycount) { + /* Internal botch calling this static function. */ + _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + } + if (dounsigned) { + while (p < endp) { + Dwarf_Unsigned dsc = 0; + Dwarf_Unsigned low = 0; + Dwarf_Unsigned high = 0; + UNUSEDARG Dwarf_Unsigned leblen = 0; + + if (ary && (larraycount >= iarraycount)) { + _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + DECODE_LEB128_UWORD_LEN_CK(p,dsc, + leblen,dbg,error,endp); + if (!dsc) { + DECODE_LEB128_UWORD_LEN_CK(p,low, + leblen, dbg,error,endp); + } else { + DECODE_LEB128_UWORD_LEN_CK(p,low, + leblen, dbg,error,endp); + DECODE_LEB128_UWORD_LEN_CK(p,high, + leblen, dbg,error,endp); + } + if(ary) { + struct Dwarf_Dsc_Entry_s *arye = + ary+larraycount; + + /* type reads the same as uleb and leb because + it is only zero or one. */ + arye->dsc_type = dsc; + arye->dsc_low_u = low; + arye->dsc_high_u = high; + } + larraycount++; + } + } else { + while (p < endp) { + Dwarf_Signed dsc = 0; + Dwarf_Signed low = 0; + Dwarf_Signed high = 0; + UNUSEDARG Dwarf_Unsigned leblen = 0; + + if (ary && (larraycount >= iarraycount)) { + _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + DECODE_LEB128_SWORD_LEN_CK(p,dsc, + leblen,dbg,error,endp); + if (!dsc) { + DECODE_LEB128_SWORD_LEN_CK(p,low, + leblen,dbg,error,endp); + } else { + DECODE_LEB128_SWORD_LEN_CK(p,low, + leblen,dbg,error,endp); + DECODE_LEB128_SWORD_LEN_CK(p,high, + leblen,dbg,error,endp); + } + if(ary) { + struct Dwarf_Dsc_Entry_s *arye = + ary+larraycount; + + /* type reads the same as uleb and leb because + it is only zero or one. */ + arye->dsc_type = (Dwarf_Unsigned)dsc; + arye->dsc_low_s = low; + arye->dsc_high_s = high; + } + larraycount++; + } + } + if (ary) { + /* Just verify this recount matches original */ + if(iarraycount != larraycount) { + _dwarf_error(dbg, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + } else { + /* This matters for first call with + ary 0 and iarraycount 0 as we are generating the + count. */ + *arraycount = larraycount; + } + return DW_DLV_OK; +} + + +int dwarf_discr_list(Dwarf_Debug dbg, + Dwarf_Small * blockpointer, + Dwarf_Unsigned blocklen, + Dwarf_Dsc_Head * dsc_head_out, + Dwarf_Unsigned * dsc_array_length_out, + Dwarf_Error * error) +{ + Dwarf_Dsc_Head h = 0; + int res = 0; + size_t arraycount = 0; + struct Dwarf_Dsc_Entry_s *ary = 0; + Dwarf_Small * dscblockp = 0; + Dwarf_Unsigned dscblocklen = 0; + + if (!dbg){ + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ + return DW_DLV_ERROR; + } + if (blocklen == 0) { + return DW_DLV_NO_ENTRY; + } + dscblockp = (Dwarf_Small *)calloc(blocklen,sizeof(Dwarf_Small)); + if(!dscblockp) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + dscblocklen = blocklen; + memcpy(dscblockp,blockpointer,blocklen); + + res = get_dsc_leb_entries(dbg,dscblockp,dscblocklen, + /* TRUE or FALSE here is not important, the arraycount + returned to us will be identical either way. */ + FALSE, 0, &arraycount,error); + if (res != DW_DLV_OK) { + free(dscblockp); + return res; + } + + h = (Dwarf_Dsc_Head)_dwarf_get_alloc(dbg,DW_DLA_DSC_HEAD,1); + if(!h) { + free(dscblockp); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + + h->dsh_block = dscblockp; + h->dsh_block_len = dscblocklen; + h->dsh_debug = dbg; + /* Now the destructor for h will deal with block malloc space. */ + + ary = (struct Dwarf_Dsc_Entry_s *)calloc(arraycount, + sizeof(struct Dwarf_Dsc_Entry_s)); + if(!ary) { + dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + h->dsh_count = arraycount; + h->dsh_array = ary; + h->dsh_set_unsigned = 0; + h->dsh_set_signed = 0; + + *dsc_head_out = h; + *dsc_array_length_out = arraycount; + return DW_DLV_OK; +} + +/* NEW September 2016. Allows easy access to DW_AT_discr_list + entry. Callers must know which is the appropriate + one of the following two interfaces, though both + will work. */ +int dwarf_discr_entry_u(Dwarf_Dsc_Head dsh , + Dwarf_Unsigned entrynum, + Dwarf_Half * out_type, + Dwarf_Unsigned * out_discr_low, + Dwarf_Unsigned * out_discr_high, + UNUSEDARG Dwarf_Error * error) +{ + struct Dwarf_Dsc_Entry_s *dse = 0; + + if (entrynum >= dsh->dsh_count) { + return DW_DLV_NO_ENTRY; + } + if (!dsh->dsh_set_unsigned) { + int res =0; + int dounsigned = 1; + size_t count = dsh->dsh_count; + + res = get_dsc_leb_entries(dsh->dsh_debug, + dsh->dsh_block, + dsh->dsh_block_len, + dounsigned, + dsh->dsh_array, + &count, + error); + if (res != DW_DLV_OK) { + return res; + } + dsh->dsh_set_unsigned = TRUE; + } + if (!dsh->dsh_array) { + _dwarf_error(dsh->dsh_debug, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + dse = dsh->dsh_array + entrynum; + *out_type = dse->dsc_type; + *out_discr_low = dse->dsc_low_u; + *out_discr_high = dse->dsc_high_u; + return DW_DLV_OK; +} + +/* NEW September 2016. Allows easy access to DW_AT_discr_list + entry. */ +int dwarf_discr_entry_s(Dwarf_Dsc_Head dsh, + Dwarf_Unsigned entrynum, + Dwarf_Half * out_type, + Dwarf_Signed * out_discr_low, + Dwarf_Signed * out_discr_high, + UNUSEDARG Dwarf_Error * error) +{ + struct Dwarf_Dsc_Entry_s *dse = 0; + + if (entrynum >= dsh->dsh_count) { + return DW_DLV_NO_ENTRY; + } + if (!dsh->dsh_set_signed) { + int res =0; + int dounsigned = 0; + size_t count = dsh->dsh_count; + + res = get_dsc_leb_entries(dsh->dsh_debug, + dsh->dsh_block, + dsh->dsh_block_len, + dounsigned, + dsh->dsh_array, + &count, + error); + if (res != DW_DLV_OK) { + return res; + } + dsh->dsh_set_signed = TRUE; + } + if (!dsh->dsh_array) { + _dwarf_error(dsh->dsh_debug, error, DW_DLE_DISCR_ARRAY_ERROR); + return DW_DLV_ERROR; + } + dse = dsh->dsh_array + entrynum; + *out_type = dse->dsc_type; + *out_discr_low = dse->dsc_low_s; + *out_discr_high = dse->dsc_high_s; + return DW_DLV_OK; +} + +void +_dwarf_dsc_destructor(void *m) +{ + Dwarf_Dsc_Head h = (Dwarf_Dsc_Head) m; + + free(h->dsh_array); + h->dsh_array = 0; + free(h->dsh_block); + h->dsh_block = 0; + h->dsh_count = 0; +} diff --git a/thirdparty/dwarf/dwarf_dsc.h b/thirdparty/dwarf/dwarf_dsc.h new file mode 100644 index 00000000..1c80ebc5 --- /dev/null +++ b/thirdparty/dwarf/dwarf_dsc.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2016-2016 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. +*/ + +/* dsc_type: if 0, then dsc_low is a single discriminant value + and dsc_high is zero.. + If 1, then dsc_low, dsc_high are a discriminant range + + All the messy complexity here is so we can have both + a set of values read as uleb and as sleb. + We make our own copy of the block for the same reason. +*/ +struct Dwarf_Dsc_Entry_s { + /* Type is a 1 byte leb that reads the same as sleb or uleb + because its value can only be zero or one. */ + Dwarf_Half dsc_type; + Dwarf_Unsigned dsc_low_u; + Dwarf_Unsigned dsc_high_u; + Dwarf_Signed dsc_low_s; + Dwarf_Signed dsc_high_s; +}; +struct Dwarf_Dsc_Head_s { + Dwarf_Debug dsh_debug; + Dwarf_Unsigned dsh_count; + Dwarf_Small *dsh_block; + Dwarf_Unsigned dsh_block_len; + /* Following two are flags to tell us whether + lebs already read in a given signedness. */ + Dwarf_Bool dsh_set_unsigned; + Dwarf_Bool dsh_set_signed; + + struct Dwarf_Dsc_Entry_s *dsh_array; +}; + + +void _dwarf_dsc_destructor(void *m); diff --git a/thirdparty/dwarf/dwarf_elf_access.c b/thirdparty/dwarf/dwarf_elf_access.c index 64113c5a..6cad8154 100644 --- a/thirdparty/dwarf/dwarf_elf_access.c +++ b/thirdparty/dwarf/dwarf_elf_access.c @@ -2,168 +2,67 @@ Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved. - Portions Copyright 2009-2012 David Anderson. All rights reserved. + Portions Copyright 2009-2019 David Anderson. All rights reserved. Portions Copyright 2009-2010 Novell Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ +/* This file is ONLY used for libelf and with libelf + For */ + #include "config.h" +#ifdef DWARF_WITH_LIBELF #include "dwarf_incl.h" +#include "dwarf_error.h" #include "dwarf_elf_access.h" +#include "dwarf_elf_rel_detector.h" -/* Include Relocation definitions in the case of Windows */ -#ifdef _WIN32 -#include "dwarf_reloc_arm.h" -#include "dwarf_reloc_mips.h" -#include "dwarf_reloc_ppc.h" -#include "dwarf_reloc_ppc64.h" -#include "dwarf_reloc_x86_64.h" -#endif /* _WIN32 */ - -#ifdef HAVE_ELF_H -#include -#endif -#ifdef HAVE_LIBELF_H -#include -#else -#ifdef HAVE_LIBELF_LIBELF_H -#include -#endif -#endif +/* Include the ELF definitions depending on system headers if any. */ +#include "dwarf_elf_defines.h" #include #include #include +#ifdef HAVE_UNISTD_H +#include /* for close */ +#endif /* HAVE_UNISTD_H */ #include #include #define FALSE 0 #define TRUE 1 -#ifndef EM_MIPS -/* This is the standard elf value EM_MIPS. */ -#define EM_MIPS 8 -#endif - -#ifndef EM_K10M -#define EM_K10M 181 /* Intel K10M */ -#endif -#ifndef EM_L10M -#define EM_L10M 180 /* Intel L10M */ -#endif -#ifndef EM_AARCH64 -#define EM_AARCH64 183 /* Arm 64 */ -#endif -#ifndef R_AARCH64_ABS64 -#define R_AARCH64_ABS64 0x101 -#endif -#ifndef R_AARCH64_ABS32 -#define R_AARCH64_ABS32 0x102 -#endif -#ifndef R_MIPS_64 -#define R_MIPS_64 18 -#endif -#ifndef R_MIPS_TLS_TPREL64 -#define R_MIPS_TLS_TPREL64 48 -#endif - -#ifndef EM_IA_64 -#define EM_IA_64 50 -#endif -#ifndef R_IA64_SECREL32LSB -#define R_IA64_SECREL32LSB 0x65 -#endif -#ifndef R_IA64_DIR32MSB -#define R_IA64_DIR32MSB 0x24 -#endif -#ifndef R_IA64_DIR32LSB -#define R_IA64_DIR32LSB 0x25 -#endif -#ifndef R_IA64_DIR64MSB -#define R_IA64_DIR64MSB 0x26 -#endif -#ifndef R_IA64_DIR64LSB -#define R_IA64_DIR64LSB 0x27 -#endif -#ifndef R_IA64_SECREL64LSB -#define R_IA64_SECREL64LSB 0x67 -#endif -#ifndef R_IA64_SECREL64MSB -#define R_IA64_SECREL64MSB 0x66 -#endif -#ifndef R_IA64_DTPREL32LSB -#define R_IA64_DTPREL32LSB 0xb5 -#endif -#ifndef R_IA64_DTPREL32MSB -#define R_IA64_DTPREL32MSB 0xb4 -#endif -#ifndef R_IA64_DTPREL64LSB -#define R_IA64_DTPREL64LSB 0xb7 -#endif -#ifndef R_IA64_DTPREL64MSB -#define R_IA64_DTPREL64MSB 0xb6 -#endif - -#ifndef EM_S390 -#define EM_S390 22 -#endif -#ifndef R_390_TLS_LDO32 -#define R_390_TLS_LDO32 52 -#endif -#ifndef R_390_TLS_LDO64 -#define R_390_TLS_LDO64 53 -#endif - -#ifndef R_390_32 -#define R_390_32 4 -#endif -#ifndef R_390_64 -#define R_390_64 22 -#endif - -#ifndef EM_SH -#define EM_SH 42 -#endif -#ifndef R_SH_DIR32 -#define R_SH_DIR32 1 -#endif -#ifndef R_SH_TLS_DTPOFF32 -#define R_SH_TLS_DTPOFF32 150 -#endif - - - - - - - #ifdef HAVE_ELF64_GETEHDR extern Elf64_Ehdr *elf64_getehdr(Elf *); #endif #ifdef HAVE_ELF64_GETSHDR extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); #endif + #ifdef WORDS_BIGENDIAN #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ @@ -171,31 +70,31 @@ extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); ((char *)source) +srclength-len_out, \ len_out) ; \ } - - #else /* LITTLE ENDIAN */ - #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((char *)source) , \ len_out) ; \ } -#endif +#endif /* *-ENDIAN */ +/* ident[0] == 'E' for elf when using libelf. ident[1] = 1 */ typedef struct { - dwarf_elf_handle elf; + char ident[8]; + const char * path; int is_64bit; Dwarf_Small length_size; Dwarf_Small pointer_size; Dwarf_Unsigned section_count; Dwarf_Endianness endianness; Dwarf_Small machine; - int libdwarf_owns_elf; - Elf32_Ehdr *ehdr32; + char libdwarf_owns_elf; + dwarf_elf_handle elf; + Elf32_Ehdr *ehdr32; #ifdef HAVE_ELF64_GETEHDR Elf64_Ehdr *ehdr64; #endif @@ -208,11 +107,11 @@ typedef struct { } dwarf_elf_object_access_internals_t; struct Dwarf_Elf_Rela { - Dwarf_ufixed64 r_offset; - /*Dwarf_ufixed64 r_info; */ - Dwarf_ufixed64 r_type; - Dwarf_ufixed64 r_symidx; - Dwarf_ufixed64 r_addend; + Dwarf_Unsigned r_offset; + /*Dwarf_Unsigned r_info; */ + Dwarf_Unsigned r_type; + Dwarf_Unsigned r_symidx; + Dwarf_Unsigned r_addend; }; @@ -278,6 +177,8 @@ dwarf_elf_object_access_internals_init(void* obj_in, one calculation, and an approximate one at that. */ obj->length_size = obj->is_64bit ? 8 : 4; obj->pointer_size = obj->is_64bit ? 8 : 4; + obj->ident[0] = 'E'; + obj->ident[1] = 1; #ifdef _WIN32 if (obj->is_64bit && machine == EM_PPC64) { @@ -379,7 +280,7 @@ _dwarf_get_elf_flags_func( If writing a function vaguely like this for a non-elf object, be sure that when section-index is passed in as zero that - you set the fields in *ret_scn to reflect an empty section + you set the fields in *ret_scn_doas to reflect an empty section with an empty string as the section name. Adjust your section indexes of your non-elf-reading-code for all the necessary functions in Dwarf_Obj_Access_Methods_s @@ -394,7 +295,7 @@ int dwarf_elf_object_access_get_section_info( void* obj_in, Dwarf_Half section_index, - Dwarf_Obj_Access_Section* ret_scn, + Dwarf_Obj_Access_Section* ret_scn_doas, int* error) { dwarf_elf_object_access_internals_t*obj = @@ -423,15 +324,15 @@ dwarf_elf_object_access_get_section_info( /* Get also section 'sh_type' and sh_info' fields, so the caller can use it for additional tasks that require that info. */ - ret_scn->type = shdr64->sh_type; - ret_scn->size = shdr64->sh_size; - ret_scn->addr = shdr64->sh_addr; - ret_scn->link = shdr64->sh_link; - ret_scn->info = shdr64->sh_info; - ret_scn->entrysize = shdr64->sh_entsize; - ret_scn->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx, + ret_scn_doas->type = shdr64->sh_type; + ret_scn_doas->size = shdr64->sh_size; + ret_scn_doas->addr = shdr64->sh_addr; + ret_scn_doas->link = shdr64->sh_link; + ret_scn_doas->info = shdr64->sh_info; + ret_scn_doas->entrysize = shdr64->sh_entsize; + ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx, shdr64->sh_name); - if (ret_scn->name == NULL) { + if (ret_scn_doas->name == NULL) { *error = DW_DLE_ELF_STRPTR_ERROR; return DW_DLV_ERROR; } @@ -448,15 +349,15 @@ dwarf_elf_object_access_get_section_info( /* Get also the section type, so the caller can use it for additional tasks that require to know the section type. */ - ret_scn->type = shdr32->sh_type; - ret_scn->size = shdr32->sh_size; - ret_scn->addr = shdr32->sh_addr; - ret_scn->link = shdr32->sh_link; - ret_scn->info = shdr32->sh_info; - ret_scn->entrysize = shdr32->sh_entsize; - ret_scn->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx, + ret_scn_doas->type = shdr32->sh_type; + ret_scn_doas->size = shdr32->sh_size; + ret_scn_doas->addr = shdr32->sh_addr; + ret_scn_doas->link = shdr32->sh_link; + ret_scn_doas->info = shdr32->sh_info; + ret_scn_doas->entrysize = shdr32->sh_entsize; + ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx, shdr32->sh_name); - if (ret_scn->name == NULL) { + if (ret_scn_doas->name == NULL) { *error = DW_DLE_ELF_STRPTR_ERROR; return DW_DLV_ERROR; } @@ -509,6 +410,12 @@ find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec); MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec); /* dbg-> de_debug_tu_index,reloctablesec); */ /* dbg-> de_debug_cu_index,reloctablesec); */ /* dbg-> de_debug_gdbindex,reloctablesec); */ @@ -663,328 +570,6 @@ get_relocation_entries(Dwarf_Bool is_64bit, return(DW_DLV_OK); } -/* We have a EM_QUALCOMM_DSP6 relocatable object - test case in dwarf regression tests, atefail/ig_server. - Values for QUALCOMM were derived from this executable. - - The r = 0 in the function will get optimized away - when not needed. - -*/ - -#define EM_QUALCOMM_DSP6 0xa4 -#define QUALCOMM_REL32 6 - -static Dwarf_Bool -is_32bit_abs_reloc(unsigned int type, Dwarf_Half machine) -{ - Dwarf_Bool r = 0; - switch (machine) { -#if defined(EM_MIPS) && defined (R_MIPS_32) - case EM_MIPS: - r = (0 -#if defined (R_MIPS_32) - | (type == R_MIPS_32) -#endif -#if defined (R_MIPS_TLS_DTPREL32) - | (type == R_MIPS_TLS_DTPREL32) -#endif /* DTPREL32 */ - ); - break; -#endif /* MIPS case */ -#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32) - case EM_SPARC32PLUS: - r = (type == R_SPARC_UA32); - break; -#endif -#if defined(EM_SPARCV9) && defined (R_SPARC_UA32) - case EM_SPARCV9: - r = (type == R_SPARC_UA32); - break; -#endif -#if defined(EM_SPARC) && defined (R_SPARC_UA32) - case EM_SPARC: - r = (0 -#if defined(R_SPARC_UA32) - | (type == R_SPARC_UA32) -#endif -#if (R_SPARC_TLS_DTPOFF32) - | (type == R_SPARC_TLS_DTPOFF32) -#endif - ); - break; -#endif /* EM_SPARC */ -#if defined(EM_386) && defined (R_386_32) - case EM_386: - r = (0 -#if defined (R_386_32) - | (type == R_386_32) -#endif -#if defined (R_386_TLS_LDO_32) - | (type == R_386_TLS_LDO_32) -#endif -#if defined (R_386_TLS_DTPOFF32) - | (type == R_386_TLS_DTPOFF32) -#endif - ); - break; -#endif /* EM_386 */ - -#if defined (EM_SH) && defined (R_SH_DIR32) - case EM_SH: - r = (0 -#if defined (R_SH_DIR32) - | (type == R_SH_DIR32) -#endif -#if defined (R_SH_DTPOFF32) - | (type == R_SH_TLS_DTPOFF32) -#endif - ); - break; -#endif /* SH */ - -#if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB) - case EM_IA_64: /* 32bit? ! */ - r = (0 -#if defined (R_IA64_SECREL32LSB) - | (type == R_IA64_SECREL32LSB) -#endif -#if defined (R_IA64_DIR32LSB) - | (type == R_IA64_DIR32LSB) -#endif -#if defined (R_IA64_DTPREL32LSB) - | (type == R_IA64_DTPREL32LSB) -#endif - ); - break; -#endif /* EM_IA_64 */ - -#if defined(EM_ARM) && defined (R_ARM_ABS32) - case EM_ARM: - case EM_AARCH64: - r = (0 -#if defined (R_ARM_ABS32) - | ( type == R_ARM_ABS32) -#endif -#if defined (R_AARCH64_ABS32) - | ( type == R_AARCH64_ABS32) -#endif -#if defined (R_ARM_TLS_LDO32) - | ( type == R_ARM_TLS_LDO32) -#endif - ); - break; -#endif /* EM_ARM */ - -/* On FreeBSD R_PPC64_ADDR32 not defined - so we use the R_PPC_ names which - have the proper value. - Our headers have: - R_PPC64_ADDR64 38 - R_PPC_ADDR32 1 so we use this one - R_PPC64_ADDR32 R_PPC_ADDR32 - - R_PPC64_DTPREL32 110 which may be wrong/unavailable - R_PPC64_DTPREL64 78 - R_PPC_DTPREL32 78 - */ -#if defined(EM_PPC64) && defined (R_PPC_ADDR32) - case EM_PPC64: - r = (0 -#if defined(R_PPC_ADDR32) - | (type == R_PPC_ADDR32) -#endif -#if defined(R_PPC64_DTPREL32) - | (type == R_PPC64_DTPREL32) -#endif - ); - break; -#endif /* EM_PPC64 */ - - -#if defined(EM_PPC) && defined (R_PPC_ADDR32) - case EM_PPC: - r = (0 -#if defined (R_PPC_ADDR32) - | (type == R_PPC_ADDR32) -#endif -#if defined (R_PPC_DTPREL32) - | (type == R_PPC_DTPREL32) -#endif - ); - break; -#endif /* EM_PPC */ - -#if defined(EM_S390) && defined (R_390_32) - case EM_S390: - r = (0 -#if defined (R_390_32) - | (type == R_390_32) -#endif -#if defined (R_390_TLS_LDO32) - | (type == R_390_TLS_LDO32) -#endif - ); - break; -#endif /* EM_S390 */ - -#if defined(EM_X86_64) && defined (R_X86_64_32) -#if defined(EM_K10M) - case EM_K10M: -#endif -#if defined(EM_L10M) - case EM_L10M: -#endif - case EM_X86_64: - r = (0 -#if defined (R_X86_64_32) - | (type == R_X86_64_32) -#endif -#if defined (R_X86_64_DTPOFF32) - | (type == R_X86_64_DTPOFF32) -#endif - ); - break; -#endif /* EM_X86_64 */ - - case EM_QUALCOMM_DSP6: - r = (type == QUALCOMM_REL32); - break; - } - return r; -} - -static Dwarf_Bool -is_64bit_abs_reloc(unsigned int type, Dwarf_Half machine) -{ - Dwarf_Bool r = 0; - switch (machine) { -#if defined(EM_MIPS) && defined (R_MIPS_64) - case EM_MIPS: - r = (0 -#if defined (R_MIPS_64) - | (type == R_MIPS_64) -#endif -#if defined (R_MIPS_32) - | (type == R_MIPS_32) -#endif -#if defined(R_MIPS_TLS_DTPREL64) - | (type == R_MIPS_TLS_DTPREL64) -#endif - ); - break; -#endif /* EM_MIPS */ -#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64) - case EM_SPARC32PLUS: - r = (type == R_SPARC_UA64); - break; -#endif -#if defined(EM_SPARCV9) && defined (R_SPARC_UA64) - case EM_SPARCV9: - r = (0 -#if defined (R_SPARC_UA64) - | (type == R_SPARC_UA64) -#endif -#if defined (R_SPARC_TLS_DTPOFF64) - | (type == R_SPARC_TLS_DTPOFF64) -#endif - ); - break; -#endif -#if defined(EM_SPARC) && defined (R_SPARC_UA64) - case EM_SPARC: - r = (0 -#if defined(R_SPARC_UA64) - | (type == R_SPARC_UA64) -#endif -#if defined (R_SPARC_TLS_DTPOFF64) - | (type == R_SPARC_TLS_DTPOFF64) -#endif - ); - break; -#endif /* EM_SPARC */ - -#if defined(EM_IA_64) && defined (R_IA64_SECREL64LSB) - case EM_IA_64: /* 64bit */ - r = (0 -#if defined (R_IA64_SECREL64LSB) - | (type == R_IA64_SECREL64LSB) -#endif -#if defined (R_IA64_SECREL32LSB) - | (type == R_IA64_SECREL32LSB) -#endif -#if defined (R_IA64_DIR64LSB) - | (type == R_IA64_DIR64LSB) -#endif -#if defined (R_IA64_DTPREL64LSB) - | (type == R_IA64_DTPREL64LSB) -#endif -#if defined (R_IA64_REL32LSB) - | (type == R_IA64_REL32LSB) -#endif - ); - break; -#endif /* EM_IA_64 */ - -#if defined(EM_PPC64) && defined (R_PPC64_ADDR64) - case EM_PPC64: - r = (0 -#if defined(R_PPC64_ADDR64) - | (type == R_PPC64_ADDR64) -#endif -#if defined(R_PPC64_DTPREL64) - | (type == R_PPC64_DTPREL64) -#endif - ); - break; -#endif /* EM_PPC64 */ - -#if defined(EM_S390) && defined (R_390_64) - case EM_S390: - r = (0 -#if defined(R_390_64) - | (type == R_390_64) -#endif -#if defined(R_390_TLS_LDO64) - | (type == R_390_TLS_LDO64) -#endif - ); - break; -#endif /* EM_390 */ - -#if defined(EM_X86_64) && defined (R_X86_64_64) -#if defined(EM_K10M) - case EM_K10M: -#endif -#if defined(EM_L10M) - case EM_L10M: -#endif - case EM_X86_64: - r = (0 -#if defined (R_X86_64_64) - | (type == R_X86_64_64) -#endif -#if defined (R_X86_64_DTPOFF32) - | (type == R_X86_64_DTPOFF64) -#endif - ); - break; -#endif /* EM_X86_64 */ -#if defined(EM_AARCH64) && defined (R_AARCH64_ABS64) - case EM_AARCH64: - r = (0 -#if defined (R_AARCH64_ABS64) - | ( type == R_AARCH64_ABS64) -#endif - ); - break; -#endif /* EM_AARCH64 */ - - } - return r; -} - - /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. The caller may decide to ignore the errors or report them. */ static int @@ -1010,8 +595,8 @@ update_entry(Dwarf_Debug dbg, Elf32_Sym *sym = 0; #endif Elf32_Sym *sym32 = 0; - Dwarf_ufixed64 offset = 0; - Dwarf_sfixed64 addend = 0; + Dwarf_Unsigned offset = 0; + Dwarf_Signed addend = 0; Dwarf_Unsigned reloc_size = 0; Dwarf_Unsigned symtab_entry_count = 0; @@ -1039,6 +624,10 @@ update_entry(Dwarf_Debug dbg, if (is_64bit) { #ifdef HAVE_ELF64_SYM sym = &((Elf64_Sym*)symtab_section_data)[sym_idx]; +#else + /* We cannot handle this object without 64_SYMs. */ + *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; + return DW_DLV_ERROR; #endif } else { sym32 = &((Elf32_Sym*)symtab_section_data)[sym_idx]; @@ -1056,9 +645,9 @@ update_entry(Dwarf_Debug dbg, } /* Determine relocation size */ - if (is_32bit_abs_reloc(type, machine)) { + if (_dwarf_is_32bit_abs_reloc(type, machine)) { reloc_size = 4; - } else if (is_64bit_abs_reloc(type, machine)) { + } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { reloc_size = 8; } else { *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; @@ -1175,12 +764,12 @@ loop_through_relocations( space returned by the elf library */ mspace = malloc(relocatablesec->dss_size); if (!mspace) { + free(relas); *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL; return DW_DLV_ERROR; } memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size); relocatablesec->dss_data = mspace; - target_section = relocatablesec->dss_data; relocatablesec->dss_data_was_malloc = TRUE; } target_section = relocatablesec->dss_data; @@ -1278,7 +867,12 @@ dwarf_elf_object_relocate_a_section(void* obj_in, /* dwarf_elf_object_access_load_section() We are only asked to load sections that - libdwarf really needs. */ + libdwarf really needs. + It would be much better if a 'user data pointer' + were passed through these interfaces so one + part of libdwarf could pass through to this. + Or even just if a Dwarf_Debug were passed in. + Sigh. */ static int dwarf_elf_object_access_load_section(void* obj_in, Dwarf_Half section_index, @@ -1297,6 +891,8 @@ dwarf_elf_object_access_load_section(void* obj_in, scn = elf_getscn(obj->elf, section_index); if (scn == NULL) { + /* The section_index does not exist or + obj->elf is NULL. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } @@ -1309,6 +905,12 @@ dwarf_elf_object_access_load_section(void* obj_in, buffer. */ data = elf_getdata(scn, NULL); if (data == NULL) { + /* Most likely means that the Elf section header + is damaged/corrupt and the data is + impossible to read into + memory. The size specified in the + Elf section is too large to allocate memory + for so the data could not be loaded. */ *error = DW_DLE_MDE; return DW_DLV_ERROR; } @@ -1403,6 +1005,9 @@ dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj) dwarf_elf_object_access_internals_t *internals = (dwarf_elf_object_access_internals_t *)obj->object; if (internals->libdwarf_owns_elf){ + /* Happens with dwarf_init_path(), + dwarf_init(), or dwarf_init_b() + interfaces. */ elf_end(internals->elf); } } @@ -1413,7 +1018,9 @@ dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj) /* This function returns the Elf * pointer associated with a Dwarf_Debug. - This function only makes sense if ELF is implied. */ + This function only makes sense if ELF is implied + and there actually is an Elf * pointer available. +*/ int dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, Dwarf_Error * error) @@ -1425,19 +1032,25 @@ dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, } obj = dbg->de_obj_file; - if (obj) { - dwarf_elf_object_access_internals_t *internals = - (dwarf_elf_object_access_internals_t*)obj->object; + if (obj && obj->object) { + dwarf_elf_object_access_internals_t *internals = 0; + char typeletter = *(char *)(obj->object); + + if (typeletter != 'E') { + /* Not libelf Elf */ + return DW_DLV_NO_ENTRY; + } + internals = (dwarf_elf_object_access_internals_t*)obj->object; if (internals->elf == NULL) { _dwarf_error(dbg, error, DW_DLE_FNO); return (DW_DLV_ERROR); } *elf = internals->elf; return DW_DLV_OK; - } _dwarf_error(dbg, error, DW_DLE_FNO); return DW_DLV_ERROR; } - - +#else +int dwarf_elf_access_dummy_var_avoid_warn = 0; +#endif /* DWARF_WITH_LIBELF */ diff --git a/thirdparty/dwarf/dwarf_elf_defines.h b/thirdparty/dwarf/dwarf_elf_defines.h new file mode 100644 index 00000000..376241cf --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_defines.h @@ -0,0 +1,1112 @@ +/* Copyright (c) 2019, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef DWARF_ELF_DEFINES_H +#define DWARF_ELF_DEFINES_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Use the system headers if they are available. */ +#ifdef HAVE_ELF_H +#include +#endif /* HAVE_ELF_H */ + +/* Relocation definitions are in sys/elf_{mach}.h on Solaris. */ +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif /* HAVE_LIBELF_LIBELF_H */ +#endif /* HAVE_LIBELF_H */ + +/* Standard Elf section types. */ +#ifndef SHT_NULL +#define SHT_NULL 0 +#endif +#ifndef SHT_PROGBITS +#define SHT_PROGBITS 1 +#endif +#ifndef SHT_SYMTAB +#define SHT_SYMTAB 2 +#endif +#ifndef SHT_STRTAB +#define SHT_STRTAB 3 +#endif +#ifndef SHT_RELA +#define SHT_RELA 4 +#endif + +#ifndef DW_GROUPNUMBER_BASE +#define DW_GROUPNUMBER_BASE 1 +#endif +#ifndef DW_GROUPNUMBER_DWO +#define DW_GROUPNUMBER_DWO 2 +#endif + +#ifndef SHF_GROUP +#define SHF_GROUP (1 << 9) +#endif /* SHF_GROUP */ + +#ifndef STN_UNDEF +#define STN_UNDEF 0 +#endif /* STN_UNDEF */ + +#ifndef SHT_HASH +#define SHT_HASH 5 +#endif +#ifndef SHT_DYNAMIC +#define SHT_DYNAMIC 6 +#endif +#ifndef SHT_NOTE +#define SHT_NOTE 7 +#endif +#ifndef SHT_NOBITS +#define SHT_NOBITS 8 +#endif +#ifndef SHT_REL +#define SHT_REL 9 +#endif +#ifndef SHT_SHLIB +#define SHT_SHLIB 10 +#endif +#ifndef SHT_DYNSYM +#define SHT_DYNSYM 11 +#endif +#ifndef SHT_GROUP +#define SHT_GROUP 17 +#endif /* SHT_GROUP */ + +/* Symbol Types, Elf standard. */ +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 + +#ifndef PT_NULL +#define PT_NULL 0 +#endif +#ifndef PT_LOAD +#define PT_LOAD 1 +#endif +#ifndef PT_DYNAMIC +#define PT_DYNAMIC 2 +#endif +#ifndef PT_INTERP +#define PT_INTERP 3 +#endif +#ifndef PT_NOTE +#define PT_NOTE 4 +#endif +#ifndef PT_SHLIB +#define PT_SHLIB 5 +#endif +#ifndef PT_PHDR +#define PT_PHDR 6 +#endif +#ifndef PT_LOPROC +#define PT_LOPROC 0x70000000 +#endif +#ifndef PT_HIPROC +#define PT_HIPROC 0x7fffffff +#endif + +#ifndef PF_X +#define PF_X (1 << 0) +#endif +#ifndef PF_W +#define PF_W (1 << 1) +#endif +#ifndef PF_R +#define PF_R (1 << 2) +#endif +#ifndef PF_MASKOS +#define PF_MASKOS 0x0ff00000 +#endif +#ifndef PF_MASKPROC +#define PF_MASKPROC 0xf0000000 +#endif + + +#ifndef ET_NONE +#define ET_NONE 0 +#endif +#ifndef ET_REL +#define ET_REL 1 +#endif +#ifndef ET_EXEC +#define ET_EXEC 2 +#endif +#ifndef ET_DYN +#define ET_DYN 3 +#endif +#ifndef ET_CORE +#define ET_CORE 4 +#endif +#ifndef ET_NUM +#define ET_NUM 5 +#endif +#ifndef ET_LOOS +#define ET_LOOS 0xfe00 +#endif +#ifndef ET_HIOS +#define ET_HIOS 0xfeff +#endif +#ifndef ET_LOPROC +#define ET_LOPROC 0xff00 +#endif +#ifndef ET_HIPROC +#define ET_HIPROC 0xffff +#endif + + +#ifndef EM_NONE +#define EM_NONE 0 +#endif +#ifndef EM_M32 +#define EM_M32 1 +#endif +#ifndef EM_SPARC +#define EM_SPARC 2 +#endif +#ifndef EM_386 +#define EM_386 3 +#endif +#ifndef EM_68K +#define EM_68K 4 +#endif +#ifndef EM_88K +#define EM_88K 5 +#endif +#ifndef EM_IAMCU +#define EM_IAMCU 6 +#endif +#ifndef EM_860 +#define EM_860 7 +#endif +#ifndef EM_MIPS +#define EM_MIPS 8 +#endif +#ifndef EM_S370 +#define EM_S370 9 +#endif +#ifndef EM_MIPS_RS3_LE +#define EM_MIPS_RS3_LE 10 +#endif +#ifndef EM_PARISC +#define EM_PARISC 15 +#endif +#ifndef EM_VPP500 +#define EM_VPP500 17 +#endif +#ifndef EM_SPARC32PLUS +#define EM_SPARC32PLUS 18 +#endif +#ifndef EM_960 +#define EM_960 19 +#endif +#ifndef EM_PPC +#define EM_PPC 20 +#endif +#ifndef EM_PPC64 +#define EM_PPC64 21 +#endif +#ifndef EM_S390 +#define EM_S390 22 +#endif +#ifndef EM_SPU +#define EM_SPU 23 +#endif +#ifndef EM_V800 +#define EM_V800 36 +#endif +#ifndef EM_FR20 +#define EM_FR20 37 +#endif +#ifndef EM_RH32 +#define EM_RH32 38 +#endif +#ifndef EM_RCE +#define EM_RCE 39 +#endif +#ifndef EM_ARM +#define EM_ARM 40 +#endif +#ifndef EM_FAKE_ALPHA +#define EM_FAKE_ALPHA 41 +#endif +#ifndef EM_SH +#define EM_SH 42 +#endif +#ifndef EM_SPARCV9 +#define EM_SPARCV9 43 +#endif +#ifndef EM_TRICORE +#define EM_TRICORE 44 +#endif +#ifndef EM_ARC +#define EM_ARC 45 +#endif +#ifndef EM_H8_300 +#define EM_H8_300 46 +#endif +#ifndef EM_H8_300H +#define EM_H8_300H 47 +#endif +#ifndef EM_H8S +#define EM_H8S 48 +#endif +#ifndef EM_H8_500 +#define EM_H8_500 49 +#endif +#ifndef EM_IA_64 +#define EM_IA_64 50 +#endif +#ifndef EM_MIPS_X +#define EM_MIPS_X 51 +#endif +#ifndef EM_COLDFIRE +#define EM_COLDFIRE 52 +#endif +#ifndef EM_68HC12 +#define EM_68HC12 53 +#endif +#ifndef EM_MMA +#define EM_MMA 54 +#endif +#ifndef EM_PCP +#define EM_PCP 55 +#endif +#ifndef EM_NCPU +#define EM_NCPU 56 +#endif +#ifndef EM_NDR1 +#define EM_NDR1 57 +#endif +#ifndef EM_STARCORE +#define EM_STARCORE 58 +#endif +#ifndef EM_ME16 +#define EM_ME16 59 +#endif +#ifndef EM_ST100 +#define EM_ST100 60 +#endif +#ifndef EM_TINYJ +#define EM_TINYJ 61 +#endif +#ifndef EM_X86_64 +#define EM_X86_64 62 +#endif +#ifndef EM_PDSP +#define EM_PDSP 63 +#endif +#ifndef EM_PDP10 +#define EM_PDP10 64 +#endif +#ifndef EM_PDP11 +#define EM_PDP11 65 +#endif +#ifndef EM_FX66 +#define EM_FX66 66 +#endif +#ifndef EM_ST9PLUS +#define EM_ST9PLUS 67 +#endif +#ifndef EM_ST7 +#define EM_ST7 68 +#endif +#ifndef EM_68HC16 +#define EM_68HC16 69 +#endif +#ifndef EM_68HC11 +#define EM_68HC11 70 +#endif +#ifndef EM_68HC08 +#define EM_68HC08 71 +#endif +#ifndef EM_68HC05 +#define EM_68HC05 72 +#endif +#ifndef EM_SVX +#define EM_SVX 73 +#endif +#ifndef EM_ST19 +#define EM_ST19 74 +#endif +#ifndef EM_VAX +#define EM_VAX 75 +#endif +#ifndef EM_CRIS +#define EM_CRIS 76 +#endif +#ifndef EM_JAVELIN +#define EM_JAVELIN 77 +#endif +#ifndef EM_FIREPATH +#define EM_FIREPATH 78 +#endif +#ifndef EM_ZSP +#define EM_ZSP 79 +#endif +#ifndef EM_MMIX +#define EM_MMIX 80 +#endif +#ifndef EM_HUANY +#define EM_HUANY 81 +#endif +#ifndef EM_PRISM +#define EM_PRISM 82 +#endif +#ifndef EM_AVR +#define EM_AVR 83 +#endif +#ifndef EM_FR30 +#define EM_FR30 84 +#endif +#ifndef EM_D10V +#define EM_D10V 85 +#endif +#ifndef EM_D30V +#define EM_D30V 86 +#endif +#ifndef EM_V850 +#define EM_V850 87 +#endif +#ifndef EM_M32R +#define EM_M32R 88 +#endif +#ifndef EM_MN10300 +#define EM_MN10300 89 +#endif +#ifndef EM_MN10200 +#define EM_MN10200 90 +#endif +#ifndef EM_PJ +#define EM_PJ 91 +#endif +#ifndef EM_OPENRISC +#define EM_OPENRISC 92 +#endif +#ifndef EM_ARC_COMPACT +#define EM_ARC_COMPACT 93 +#endif +#ifndef EM_XTENSA +#define EM_XTENSA 94 +#endif +#ifndef EM_VIDEOCORE +#define EM_VIDEOCORE 95 +#endif +#ifndef EM_TMM_GPP +#define EM_TMM_GPP 96 +#endif +#ifndef EM_NS32K +#define EM_NS32K 97 +#endif +#ifndef EM_TPC +#define EM_TPC 98 +#endif +#ifndef EM_SNP1K +#define EM_SNP1K 99 +#endif +#ifndef EM_ST200 +#define EM_ST200 100 +#endif +#ifndef EM_IP2K +#define EM_IP2K 101 +#endif +#ifndef EM_MAX +#define EM_MAX 102 +#endif +#ifndef EM_CR +#define EM_CR 103 +#endif +#ifndef EM_F2MC16 +#define EM_F2MC16 104 +#endif +#ifndef EM_MSP430 +#define EM_MSP430 105 +#endif +#ifndef EM_BLACKFIN +#define EM_BLACKFIN 106 +#endif +#ifndef EM_SE_C33 +#define EM_SE_C33 107 +#endif +#ifndef EM_SEP +#define EM_SEP 108 +#endif +#ifndef EM_ARCA +#define EM_ARCA 109 +#endif +#ifndef EM_UNICORE +#define EM_UNICORE 110 +#endif +#ifndef EM_EXCESS +#define EM_EXCESS 111 +#endif +#ifndef EM_DXP +#define EM_DXP 112 +#endif +#ifndef EM_ALTERA_NIOS2 +#define EM_ALTERA_NIOS2 113 +#endif +#ifndef EM_CRX +#define EM_CRX 114 +#endif +#ifndef EM_XGATE +#define EM_XGATE 115 +#endif +#ifndef EM_C166 +#define EM_C166 116 +#endif +#ifndef EM_M16C +#define EM_M16C 117 +#endif +#ifndef EM_DSPIC30F +#define EM_DSPIC30F 118 +#endif +#ifndef EM_CE +#define EM_CE 119 +#endif +#ifndef EM_M32C +#define EM_M32C 120 +#endif +#ifndef EM_TSK3000 +#define EM_TSK3000 131 +#endif +#ifndef EM_RS08 +#define EM_RS08 132 +#endif +#ifndef EM_SHARC +#define EM_SHARC 133 +#endif +#ifndef EM_ECOG2 +#define EM_ECOG2 134 +#endif +#ifndef EM_SCORE7 +#define EM_SCORE7 135 +#endif +#ifndef EM_DSP24 +#define EM_DSP24 136 +#endif +#ifndef EM_VIDEOCORE3 +#define EM_VIDEOCORE3 137 +#endif +#ifndef EM_LATTICEMICO32 +#define EM_LATTICEMICO32 138 +#endif +#ifndef EM_SE_C17 +#define EM_SE_C17 139 +#endif +#ifndef EM_TI_C6000 +#define EM_TI_C6000 140 +#endif +#ifndef EM_TI_C2000 +#define EM_TI_C2000 141 +#endif +#ifndef EM_TI_C5500 +#define EM_TI_C5500 142 +#endif +#ifndef EM_TI_ARP32 +#define EM_TI_ARP32 143 +#endif +#ifndef EM_TI_PRU +#define EM_TI_PRU 144 +#endif +#ifndef EM_MMDSP_PLUS +#define EM_MMDSP_PLUS 160 +#endif +#ifndef EM_CYPRESS_M8C +#define EM_CYPRESS_M8C 161 +#endif +#ifndef EM_R32C +#define EM_R32C 162 +#endif +#ifndef EM_TRIMEDIA +#define EM_TRIMEDIA 163 +#endif +#ifndef EM_QDSP6 +#define EM_QDSP6 164 +#endif +#ifndef EM_QUALCOMM_DSP6 +#define EM_QUALCOMM_DSP6 164 +#endif +#ifndef EM_8051 +#define EM_8051 165 +#endif +#ifndef EM_STXP7X +#define EM_STXP7X 166 +#endif +#ifndef EM_NDS32 +#define EM_NDS32 167 +#endif +#ifndef EM_ECOG1X +#define EM_ECOG1X 168 +#endif +#ifndef EM_MAXQ30 +#define EM_MAXQ30 169 +#endif +#ifndef EM_XIMO16 +#define EM_XIMO16 170 +#endif +#ifndef EM_MANIK +#define EM_MANIK 171 +#endif +#ifndef EM_CRAYNV2 +#define EM_CRAYNV2 172 +#endif +#ifndef EM_RX +#define EM_RX 173 +#endif +#ifndef EM_METAG +#define EM_METAG 174 +#endif +#ifndef EM_MCST_ELBRUS +#define EM_MCST_ELBRUS 175 +#endif +#ifndef EM_ECOG16 +#define EM_ECOG16 176 +#endif +#ifndef EM_CR16 +#define EM_CR16 177 +#endif +#ifndef EM_ETPU +#define EM_ETPU 178 +#endif +#ifndef EM_SLE9X +#define EM_SLE9X 179 +#endif +#ifndef EM_L10M +#define EM_L10M 180 +#endif +#ifndef EM_K10M +#define EM_K10M 181 +#endif +#ifndef EM_AARCH64 +#define EM_AARCH64 183 +#endif +#ifndef EM_AVR32 +#define EM_AVR32 185 +#endif +#ifndef EM_STM8 +#define EM_STM8 186 +#endif +#ifndef EM_TILE64 +#define EM_TILE64 187 +#endif +#ifndef EM_TILEPRO +#define EM_TILEPRO 188 +#endif +#ifndef EM_MICROBLAZE +#define EM_MICROBLAZE 189 +#endif +#ifndef EM_CUDA +#define EM_CUDA 190 +#endif +#ifndef EM_TILEGX +#define EM_TILEGX 191 +#endif +#ifndef EM_CLOUDSHIELD +#define EM_CLOUDSHIELD 192 +#endif +#ifndef EM_COREA_1ST +#define EM_COREA_1ST 193 +#endif +#ifndef EM_COREA_2ND +#define EM_COREA_2ND 194 +#endif +#ifndef EM_ARC_COMPACT2 +#define EM_ARC_COMPACT2 195 +#endif +#ifndef EM_OPEN8 +#define EM_OPEN8 196 +#endif +#ifndef EM_RL78 +#define EM_RL78 197 +#endif +#ifndef EM_VIDEOCORE5 +#define EM_VIDEOCORE5 198 +#endif +#ifndef EM_78KOR +#define EM_78KOR 199 +#endif +#ifndef EM_56800EX +#define EM_56800EX 200 +#endif +#ifndef EM_BA1 +#define EM_BA1 201 +#endif +#ifndef EM_BA2 +#define EM_BA2 202 +#endif +#ifndef EM_XCORE +#define EM_XCORE 203 +#endif +#ifndef EM_MCHP_PIC +#define EM_MCHP_PIC 204 +#endif +#ifndef EM_KM32 +#define EM_KM32 210 +#endif +#ifndef EM_KMX32 +#define EM_KMX32 211 +#endif +#ifndef EM_EMX16 +#define EM_EMX16 212 +#endif +#ifndef EM_EMX8 +#define EM_EMX8 213 +#endif +#ifndef EM_KVARC +#define EM_KVARC 214 +#endif +#ifndef EM_CDP +#define EM_CDP 215 +#endif +#ifndef EM_COGE +#define EM_COGE 216 +#endif +#ifndef EM_COOL +#define EM_COOL 217 +#endif +#ifndef EM_NORC +#define EM_NORC 218 +#endif +#ifndef EM_CSR_KALIMBA +#define EM_CSR_KALIMBA 219 +#endif +#ifndef EM_Z80 +#define EM_Z80 220 +#endif +#ifndef EM_VISIUM +#define EM_VISIUM 221 +#endif +#ifndef EM_FT32 +#define EM_FT32 222 +#endif +#ifndef EM_MOXIE +#define EM_MOXIE 223 +#endif +#ifndef EM_AMDGPU +#define EM_AMDGPU 224 +#endif +#ifndef EM_RISCV +#define EM_RISCV 243 +#endif +#ifndef EM_BPF +#define EM_BPF 247 +#endif + +/* Standard Elf dynamic tags. */ +#ifndef DT_NULL +#define DT_NULL 0 +#endif +#ifndef DT_NEEDED +#define DT_NEEDED 1 +#endif +#ifndef DT_PLTRELSZ +#define DT_PLTRELSZ 2 +#endif +#ifndef DT_PLTGOT +#define DT_PLTGOT 3 +#endif +#ifndef DT_HASH +#define DT_HASH 4 +#endif +#ifndef DT_STRTAB +#define DT_STRTAB 5 +#endif +#ifndef DT_SYMTAB +#define DT_SYMTAB 6 +#endif +#ifndef DT_RELA +#define DT_RELA 7 +#endif +#ifndef DT_RELASZ +#define DT_RELASZ 8 +#endif +#ifndef DT_RELAENT +#define DT_RELAENT 9 +#endif +#ifndef DT_STRSZ +#define DT_STRSZ 10 +#endif + +#ifndef DT_SYMENT +#define DT_SYMENT 11 +#endif + +#ifndef DT_INIT +#define DT_INIT 12 +#endif + +#ifndef DT_FINI +#define DT_FINI 13 +#endif + +#ifndef DT_SONAME +#define DT_SONAME 14 +#endif + +#ifndef DT_RPATH +#define DT_RPATH 15 +#endif + +#ifndef DT_SYMBOLIC +#define DT_SYMBOLIC 16 +#endif + +#ifndef DT_REL +#define DT_REL 17 +#endif +#ifndef DT_RELSZ +#define DT_RELSZ 18 +#endif + +#ifndef DT_RELENT +#define DT_RELENT 19 +#endif + +#ifndef DT_PLTREL +#define DT_PLTREL 20 +#endif + +#ifndef DT_DEBUG +#define DT_DEBUG 21 +#endif + +#ifndef DT_TEXTREL +#define DT_TEXTREL 22 +#endif + +#ifndef DT_JMPREL +#define DT_JMPREL 23 +#endif + +#ifndef SHN_UNDEF +#define SHN_UNDEF 0 +#endif +#ifndef SHN_LORESERVE +#define SHN_LORESERVE 0xff00 +#endif +#ifndef SHN_LOPROC +#define SHN_LOPROC 0xff00 +#endif +#ifndef SHN_HIPROC +#define SHN_HIPROC 0xff1f +#endif +#ifndef SHN_ABS +#define SHN_ABS 0xfff1 +#endif +#ifndef SHN_COMMON +#define SHN_COMMON 0xfff2 +#endif +#ifndef SHN_HIRESERVE +#define SHN_HIRESERVE 0xffff +#endif + +#ifndef EV_CURRENT +#define EV_CURRENT 1 +#endif +#ifndef EV_NONE +#define EV_NONE 0 +#endif + +#ifndef EI_MAG0 +#define EI_MAG0 0 +#endif +#ifndef EI_MAG1 +#define EI_MAG1 1 +#endif +#ifndef EI_MAG2 +#define EI_MAG2 2 +#endif +#ifndef EI_MAG3 +#define EI_MAG3 3 +#endif +#ifndef EI_CLASS +#define EI_CLASS 4 +#endif +#ifndef EI_DATA +#define EI_DATA 5 +#endif +#ifndef EI_VERSION +#define EI_VERSION 6 +#endif +#ifndef EI_PAD +#define EI_PAD 7 +#endif +#ifndef EI_OSABI +#define EI_OSABI 7 +#endif +#ifndef EI_NIDENT +#define EI_NIDENT 16 +#endif +#ifndef EI_ABIVERSION +#define EI_ABIVERSION 8 +#endif + +#ifndef ELFMAG0 +#define ELFMAG0 0x7f +#endif +#ifndef ELFMAG1 +#define ELFMAG1 'E' +#endif +#ifndef ELFMAG2 +#define ELFMAG2 'L' +#endif +#ifndef ELFMAG3 +#define ELFMAG3 'F' +#endif +#ifndef ELFCLASSNONE +#define ELFCLASSNONE 0 +#endif +#ifndef ELFCLASS32 +#define ELFCLASS32 1 +#endif +#ifndef ELFCLASS64 +#define ELFCLASS64 2 +#endif +#ifndef ELFDATANONE +#define ELFDATANONE 0 +#endif +#ifndef ELFDATA2LSB +#define ELFDATA2LSB 1 +#endif +#ifndef ELFDATA2MSB +#define ELFDATA2MSB 2 +#endif + +#ifndef ELFOSABI_NONE +#define ELFOSABI_NONE 0 +#endif +#ifndef ELFOSABI_SYSV +#define ELFOSABI_SYSV 0 +#endif +#ifndef ELFOSABI_HPUX +#define ELFOSABI_HPUX 1 +#endif +#ifndef ELFOSABI_NETBSD +#define ELFOSABI_NETBSD 2 +#endif +#ifndef ELFOSABI_GNU +#define ELFOSABI_GNU 3 +#endif +#ifndef ELFOSABI_LINUX +#define ELFOSABI_LINUX ELFOSABI_GNU +#endif +#ifndef ELFOSABI_SOLARIS +#define ELFOSABI_SOLARIS 6 +#endif +#ifndef ELFOSABI_AIX +#define ELFOSABI_AIX 7 +#endif +#ifndef ELFOSABI_IRIX +#define ELFOSABI_IRIX 8 +#endif +#ifndef ELFOSABI_FREEBSD +#define ELFOSABI_FREEBSD 9 +#endif +#ifndef ELFOSABI_TRU64 +#define ELFOSABI_TRU64 10 +#endif +#ifndef ELFOSABI_MODESTO +#define ELFOSABI_MODESTO 11 +#endif +#ifndef ELFOSABI_OPENBSD +#define ELFOSABI_OPENBSD 12 +#endif +#ifndef ELFOSABI_ARM_AEABI +#define ELFOSABI_ARM_AEABI 64 +#endif +#ifndef ELFOSABI_ARM +#define ELFOSABI_ARM 97 +#endif +#ifndef ELFOSABI_STANDALONE +#define ELFOSABI_STANDALONE 255 +#endif + + +/* for the producer code. */ +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif +#ifndef R_QUALCOMM_REL32 +#define R_QUALCOMM_REL32 6 +#endif +/* For Freebsd: */ +#ifndef R_PPC64_ADDR32 +#define R_PPC64_ADDR32 1 +#endif +#ifndef R_PPC64_DTPREL32 +#define R_PPC64_DTPREL32 110 +#endif +#ifndef R_PPC64_DTPREL64 +#define R_PPC64_DTPREL64 78 +#endif +#ifndef R_PPC_DTPREL32 +#define R_PPC_DTPREL32 78 +#endif +/* The following two probably useless. */ +#ifndef R_X86_64_PC32_BND +#define R_X86_64_PC32_BND 39 +#endif +#ifndef R_X86_64_PLT32_BND +#define R_X86_64_PLT32_BND 40 +#endif + +#ifndef R_386_32 +#define R_386_32 1 +#endif /* R_386_32 */ +#ifndef R_386_TLS_DTPOFF32 +#define R_386_TLS_DTPOFF32 36 +#endif /* R_386_TLS_DTPOFF32 */ +#ifndef R_386_TLS_LDO_32 +#define R_386_TLS_LDO_32 32 +#endif /* R_386_TLS_LDO_32 */ +#ifndef R_390_32 +#define R_390_32 4 +#endif /* R_390_32 */ +#ifndef R_390_64 +#define R_390_64 22 +#endif /* R_390_64 */ +#ifndef R_390_TLS_LDO32 +#define R_390_TLS_LDO32 52 +#endif /* R_390_TLS_LDO32 */ +#ifndef R_390_TLS_LDO64 +#define R_390_TLS_LDO64 53 +#endif /* R_390_TLS_LDO64 */ +#ifndef R_AARCH64_ABS32 +#define R_AARCH64_ABS32 258 +#endif /* R_AARCH64_ABS32 */ +#ifndef R_AARCH64_ABS64 +#define R_AARCH64_ABS64 257 +#endif /* R_AARCH64_ABS64 */ +#ifndef R_ARM_ABS32 +#define R_ARM_ABS32 2 +#endif /* R_ARM_ABS32 */ +#ifndef R_ARM_TLS_LDO32 +#define R_ARM_TLS_LDO32 106 +#endif /* R_ARM_TLS_LDO32 */ +#ifndef R_IA64_DIR32LSB +#define R_IA64_DIR32LSB 0x25 +#endif /* R_IA64_DIR32LSB */ +#ifndef R_IA64_DIR64LSB +#define R_IA64_DIR64LSB 0x27 +#endif /* R_IA64_DIR64LSB */ +#ifndef R_IA64_DTPREL32LSB +#define R_IA64_DTPREL32LSB 0xb5 +#endif /* R_IA64_DTPREL32LSB */ +#ifndef R_IA64_DTPREL64LSB +#define R_IA64_DTPREL64LSB 0xb7 +#endif /* R_IA64_DTPREL64LSB */ +#ifndef R_IA64_REL32LSB +#define R_IA64_REL32LSB 0x6d +#endif /* R_IA64_REL32LSB */ +#ifndef R_IA64_SECREL32LSB +#define R_IA64_SECREL32LSB 0x65 +#endif /* R_IA64_SECREL32LSB */ +#ifndef R_IA64_SECREL64LSB +#define R_IA64_SECREL64LSB 0x67 +#endif /* R_IA64_SECREL64LSB */ +#ifndef R_MIPS_32 +#define R_MIPS_32 2 +#endif /* R_MIPS_32 */ +#ifndef R_MIPS_64 +#define R_MIPS_64 18 +#endif /* R_MIPS_64 */ +#ifndef R_MIPS_TLS_DTPREL32 +#define R_MIPS_TLS_DTPREL32 39 +#endif /* R_MIPS_TLS_DTPREL32 */ +#ifndef R_MIPS_TLS_DTPREL64 +#define R_MIPS_TLS_DTPREL64 41 +#endif /* R_MIPS_TLS_DTPREL64 */ +#ifndef R_PPC64_ADDR64 +#define R_PPC64_ADDR64 38 +#endif /* R_PPC64_ADDR64 */ +#ifndef R_PPC64_DTPREL32 +#define R_PPC64_DTPREL32 110 +#endif /* R_PPC64_DTPREL32 */ +#ifndef R_PPC64_DTPREL64 +#define R_PPC64_DTPREL64 78 +#endif /* R_PPC64_DTPREL64 */ +#ifndef R_PPC_ADDR32 +#define R_PPC_ADDR32 1 +#endif /* R_PPC_ADDR32 */ +#ifndef R_PPC_DTPREL32 +#define R_PPC_DTPREL32 78 +#endif /* R_PPC_DTPREL32 */ +#ifndef R_QUALCOMM_REL32 +#define R_QUALCOMM_REL32 6 +#endif /* R_QUALCOMM_REL32 */ +#ifndef R_SH_DIR32 +#define R_SH_DIR32 1 +#endif /* R_SH_DIR32 */ +#ifndef R_SH_TLS_DTPOFF32 +#define R_SH_TLS_DTPOFF32 150 +#endif /* R_SH_TLS_DTPOFF32 */ +#ifndef R_SPARC_TLS_DTPOFF32 +#define R_SPARC_TLS_DTPOFF32 76 +#endif /* R_SPARC_TLS_DTPOFF32 */ +#ifndef R_SPARC_TLS_DTPOFF64 +#define R_SPARC_TLS_DTPOFF64 77 +#endif /* R_SPARC_TLS_DTPOFF64 */ +#ifndef R_SPARC_UA32 +#define R_SPARC_UA32 23 +#endif /* R_SPARC_UA32 */ +#ifndef R_SPARC_UA64 +#define R_SPARC_UA64 54 +#endif /* R_SPARC_UA64 */ +#ifndef R_X86_64_32 +#define R_X86_64_32 10 +#endif /* R_X86_64_32 */ +#ifndef R_X86_64_64 +#define R_X86_64_64 1 +#endif /* R_X86_64_64 */ +#ifndef R_X86_64_DTPOFF32 +#define R_X86_64_DTPOFF32 21 +#endif /* R_X86_64_DTPOFF32 */ +#ifndef R_X86_64_DTPOFF64 +#define R_X86_64_DTPOFF64 17 +#endif /* R_X86_64_DTPOFF64 */ +#ifndef R_X86_64_PC32 +#define R_X86_64_PC32 2 +#endif /* R_X86_64_PC32 */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DWARF_ELF_DEFINES_H */ diff --git a/thirdparty/dwarf/dwarf_elf_load_headers.c b/thirdparty/dwarf/dwarf_elf_load_headers.c new file mode 100644 index 00000000..bca948e8 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_load_headers.c @@ -0,0 +1,2115 @@ +/* +Copyright 2018 David Anderson. All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This reads elf headers and creates generic-elf + structures containing the Elf headers. */ + + +#include "config.h" +#include +#include /* For memcpy etc */ +#include +#include +#include /* for open() */ +#include /* for open() */ +#include /* for open() */ +#ifdef HAVE_UNISTD_H +#include /* lseek read close */ +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#endif /* HAVE_UNISTD_H */ + +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) +#include "stdafx.h" +#endif /* HAVE_STDAFX_H */ + +#include "libdwarfdefs.h" +#include "dwarf.h" +#include "libdwarf.h" +#include "dwarf_base_types.h" +#include "dwarf_opaque.h" +#include "memcpy_swap.h" +#include "dwarf_elfstructs.h" +#include "dwarf_reading.h" +#include "dwarf_elf_defines.h" +#include "dwarf_elfread.h" +#include "dwarf_object_detector.h" +#include "dwarf_object_read_common.h" +#include "dwarf_util.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* O_BINARY */ + +#ifdef HAVE_UNUSED_ATTRIBUTE +#define UNUSEDARG __attribute__ ((unused)) +#else +#define UNUSEDARG +#endif +#define TRUE 1 +#define FALSE 0 + +#ifdef WORDS_BIGENDIAN +#define ASNAR(func,t,s) \ + do { \ + unsigned tbyte = sizeof(t) - sizeof(s); \ + t = 0; \ + func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ + } while (0) +#else /* LITTLE ENDIAN */ +#define ASNAR(func,t,s) \ + do { \ + t = 0; \ + func(&t,&s[0],sizeof(s)); \ + } while (0) +#endif /* end LITTLE- BIG-ENDIAN */ + +static int +_dwarf_load_elf_section_is_dwarf(const char *sname) +{ + if (!strncmp(sname,".rel",4)) { + return FALSE; + } + if (!strncmp(sname,".debug_",7)) { + return TRUE; + } + if (!strncmp(sname,".zdebug_",8)) { + return TRUE; + } + if (!strcmp(sname,".eh_frame")) { + return TRUE; + } + if (!strncmp(sname,".gdb_index",10)) { + return TRUE; + } + return FALSE; +} + + +static int +is_empty_section(Dwarf_Unsigned type) +{ + if (type == SHT_NOBITS) { + return TRUE; + } + if (type == SHT_NULL) { + return TRUE; + } + return FALSE; +} + +#if 0 +int +dwarf_construct_elf_access_path(const char *path, + dwarf_elf_object_access_internals_t **mp,int *errcode) +{ + int fd = -1; + int res = 0; + dwarf_elf_object_access_internals_t *mymp = 0; + + fd = open(path, O_RDONLY|O_BINARY); + if (fd < 0) { + *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; + return DW_DLV_ERROR; + } + res = dwarf_construct_elf_access(fd, + path,&mymp,errcode); + if (res != DW_DLV_OK) { + close(fd); + return res; + } + mymp->f_destruct_close_fd = TRUE; + *mp = mymp; + return res; +} +#endif /* 0 */ + +/* Here path is not essential. Pass in with "" if unknown. */ +int +dwarf_construct_elf_access(int fd, + const char *path, + dwarf_elf_object_access_internals_t **mp,int *errcode) +{ + unsigned ftype = 0; + unsigned endian = 0; + unsigned offsetsize = 0; + Dwarf_Unsigned filesize = 0; + dwarf_elf_object_access_internals_t *mfp = 0; + int res = 0; + + res = dwarf_object_detector_fd(fd, + &ftype,&endian,&offsetsize, &filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + + mfp = calloc(1,sizeof(dwarf_elf_object_access_internals_t)); + if (!mfp) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + /* For non-libelf Elf, call it 'F'. Libelf Elf uses 'E' */ + mfp->f_ident[0] = 'F'; + mfp->f_ident[1] = 1; + mfp->f_fd = fd; + mfp->f_destruct_close_fd = FALSE; + mfp->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); + mfp->f_filesize = filesize; + mfp->f_offsetsize = offsetsize; + mfp->f_pointersize = offsetsize; + mfp->f_endian = endian; + mfp->f_ftype = ftype; + mfp->f_path = strdup(path); + + *mp = mfp; + return DW_DLV_OK; +} + +/* Caller must zero the passed in pointer + after this returns to remind + the caller to avoid use of the pointer. */ +int +dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t* ep, + UNUSEDARG int *errcode) +{ + struct generic_shdr *shp = 0; + Dwarf_Unsigned shcount = 0; + Dwarf_Unsigned i = 0; + + free(ep->f_ehdr); + shp = ep->f_shdr; + shcount = ep->f_loc_shdr.g_count; + for(i = 0; i < shcount; ++i,++shp) { + free(shp->gh_rels); + shp->gh_rels = 0; + free(shp->gh_content); + shp->gh_content = 0; + free(shp->gh_sht_group_array); + shp->gh_sht_group_array = 0; + shp->gh_sht_group_array_count = 0; + } + free(ep->f_shdr); + free(ep->f_phdr); + free(ep->f_elf_shstrings_data); + free(ep->f_dynamic); + free(ep->f_symtab_sect_strings); + free(ep->f_dynsym_sect_strings); + free(ep->f_symtab); + free(ep->f_dynsym); + + /* if TRUE close f_fd on destruct.*/ + if (ep->f_destruct_close_fd) { + close(ep->f_fd); + } + ep->f_ident[0] = 'X'; + free(ep->f_path); + free(ep); + return DW_DLV_OK; +} + + + + +static int +generic_ehdr_from_32(dwarf_elf_object_access_internals_t *ep, + struct generic_ehdr *ehdr, dw_elf32_ehdr *e, + UNUSEDARG int *errcode) +{ + int i = 0; + + for (i = 0; i < EI_NIDENT; ++i) { + ehdr->ge_ident[i] = e->e_ident[i]; + } + ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type); + ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine); + ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version); + ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry); + ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff); + ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff); + ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags); + ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize); + ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize); + ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum); + ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize); + ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum); + ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx); + ep->f_machine = ehdr->ge_machine; + ep->f_ehdr = ehdr; + ep->f_loc_ehdr.g_name = "Elf File Header"; + ep->f_loc_ehdr.g_offset = 0; + ep->f_loc_ehdr.g_count = 1; + ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf32_ehdr); + ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf32_ehdr); + return DW_DLV_OK; +} + +static int +generic_ehdr_from_64(dwarf_elf_object_access_internals_t* ep, + struct generic_ehdr *ehdr, dw_elf64_ehdr *e, + UNUSEDARG int *errcode) +{ + int i = 0; + + for (i = 0; i < EI_NIDENT; ++i) { + ehdr->ge_ident[i] = e->e_ident[i]; + } + ASNAR(ep->f_copy_word,ehdr->ge_type,e->e_type); + ASNAR(ep->f_copy_word,ehdr->ge_machine,e->e_machine); + ASNAR(ep->f_copy_word,ehdr->ge_version,e->e_version); + ASNAR(ep->f_copy_word,ehdr->ge_entry,e->e_entry); + ASNAR(ep->f_copy_word,ehdr->ge_phoff,e->e_phoff); + ASNAR(ep->f_copy_word,ehdr->ge_shoff,e->e_shoff); + ASNAR(ep->f_copy_word,ehdr->ge_flags,e->e_flags); + ASNAR(ep->f_copy_word,ehdr->ge_ehsize,e->e_ehsize); + ASNAR(ep->f_copy_word,ehdr->ge_phentsize,e->e_phentsize); + ASNAR(ep->f_copy_word,ehdr->ge_phnum,e->e_phnum); + ASNAR(ep->f_copy_word,ehdr->ge_shentsize,e->e_shentsize); + ASNAR(ep->f_copy_word,ehdr->ge_shnum,e->e_shnum); + ASNAR(ep->f_copy_word,ehdr->ge_shstrndx,e->e_shstrndx); + ep->f_machine = ehdr->ge_machine; + ep->f_ehdr = ehdr; + ep->f_loc_ehdr.g_name = "Elf File Header"; + ep->f_loc_ehdr.g_offset = 0; + ep->f_loc_ehdr.g_count = 1; + ep->f_loc_ehdr.g_entrysize = sizeof(dw_elf64_ehdr); + ep->f_loc_ehdr.g_totalsize = sizeof(dw_elf64_ehdr); + return DW_DLV_OK; +} + + +#if 0 /* not used */ +static int +generic_phdr_from_phdr32(dwarf_elf_object_access_internals_t* ep, + struct generic_phdr **phdr_out, + Dwarf_Unsigned * count_out, + Dwarf_Unsigned offset, + Dwarf_Unsigned entsize, + Dwarf_Unsigned count, + int *errcode) +{ + dw_elf32_phdr *pph =0; + dw_elf32_phdr *orig_pph =0; + struct generic_phdr *gphdr =0; + struct generic_phdr *orig_gphdr =0; + Dwarf_Unsigned i = 0; + int res = 0; + + *count_out = 0; + pph = (dw_elf32_phdr *)calloc(count , entsize); + if(pph == 0) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr)); + if(gphdr == 0) { + free(pph); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + orig_pph = pph; + orig_gphdr = gphdr; + res = RRMOA(ep->f_fd,pph,offset,count*entsize, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(pph); + free(gphdr); + return res; + } + for( i = 0; i < count; + ++i, pph++,gphdr++) { + ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type); + ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset); + ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr); + ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr); + ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz); + ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz); + ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags); + ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align); + } + free(orig_pph); + *phdr_out = orig_gphdr; + *count_out = count; + ep->f_phdr = orig_gphdr; + ep->f_loc_phdr.g_name = "Program Header"; + ep->f_loc_phdr.g_offset = offset; + ep->f_loc_phdr.g_count = count; + ep->f_loc_phdr.g_entrysize = sizeof(dw_elf32_phdr); + ep->f_loc_phdr.g_totalsize = sizeof(dw_elf32_phdr)*count; + return DW_DLV_OK; +} + +static int +generic_phdr_from_phdr64(dwarf_elf_object_access_internals_t* ep, + struct generic_phdr **phdr_out, + Dwarf_Unsigned * count_out, + Dwarf_Unsigned offset, + Dwarf_Unsigned entsize, + Dwarf_Unsigned count, + int *errcode) +{ + dw_elf64_phdr *pph =0; + dw_elf64_phdr *orig_pph =0; + struct generic_phdr *gphdr =0; + struct generic_phdr *orig_gphdr =0; + int res = 0; + Dwarf_Unsigned i = 0; + + *count_out = 0; + pph = (dw_elf64_phdr *)calloc(count , entsize); + if(pph == 0) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + gphdr = (struct generic_phdr *)calloc(count,sizeof(*gphdr)); + if(gphdr == 0) { + free(pph); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + orig_pph = pph; + orig_gphdr = gphdr; + res = RRMOA(ep->f_fd,pph,offset,count*entsize, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(pph); + free(gphdr); + return res; + } + for( i = 0; i < count; + ++i, pph++,gphdr++) { + ASNAR(ep->f_copy_word,gphdr->gp_type,pph->p_type); + ASNAR(ep->f_copy_word,gphdr->gp_offset,pph->p_offset); + ASNAR(ep->f_copy_word,gphdr->gp_vaddr,pph->p_vaddr); + ASNAR(ep->f_copy_word,gphdr->gp_paddr,pph->p_paddr); + ASNAR(ep->f_copy_word,gphdr->gp_filesz,pph->p_filesz); + ASNAR(ep->f_copy_word,gphdr->gp_memsz,pph->p_memsz); + ASNAR(ep->f_copy_word,gphdr->gp_flags,pph->p_flags); + ASNAR(ep->f_copy_word,gphdr->gp_align,pph->p_align); + } + free(orig_pph); + *phdr_out = orig_gphdr; + *count_out = count; + ep->f_phdr = orig_gphdr; + ep->f_loc_phdr.g_name = "Program Header"; + ep->f_loc_phdr.g_offset = offset; + ep->f_loc_phdr.g_count = count; + ep->f_loc_phdr.g_entrysize = sizeof(dw_elf64_phdr); + ep->f_loc_phdr.g_totalsize = sizeof(dw_elf64_phdr)*count; + return DW_DLV_OK; +} +#endif /* not used */ + +static int +generic_shdr_from_shdr32(dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned * count_out, + Dwarf_Unsigned offset, + Dwarf_Unsigned entsize, + Dwarf_Unsigned count, + int *errcode) +{ + dw_elf32_shdr *psh =0; + dw_elf32_shdr *orig_psh =0; + struct generic_shdr *gshdr =0; + struct generic_shdr *orig_gshdr =0; + Dwarf_Unsigned i = 0; + int res = 0; + + *count_out = 0; + psh = (dw_elf32_shdr *)calloc(count , entsize); + if(!psh) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr)); + if(!gshdr) { + free(psh); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + orig_psh = psh; + orig_gshdr = gshdr; + res = RRMOA(ep->f_fd,psh,offset,count*entsize, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(psh); + free(gshdr); + return res; + } + for(i = 0; i < count; + ++i, psh++,gshdr++) { + gshdr->gh_secnum = i; + ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name); + ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type); + ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags); + ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr); + ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset); + ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size); + ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link); + ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info); + ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign); + ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize); + if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){ + gshdr->gh_reloc_target_secnum = gshdr->gh_info; + } + } + free(orig_psh); + *count_out = count; + ep->f_shdr = orig_gshdr; + ep->f_loc_shdr.g_name = "Section Header"; + ep->f_loc_shdr.g_count = count; + ep->f_loc_shdr.g_offset = offset; + ep->f_loc_shdr.g_entrysize = sizeof(dw_elf32_shdr); + ep->f_loc_shdr.g_totalsize = sizeof(dw_elf32_shdr)*count; + return DW_DLV_OK; +} + +static int +generic_shdr_from_shdr64(dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned * count_out, + Dwarf_Unsigned offset, + Dwarf_Unsigned entsize, + Dwarf_Unsigned count, + int *errcode) +{ + dw_elf64_shdr *psh =0; + dw_elf64_shdr *orig_psh =0; + struct generic_shdr *gshdr =0; + struct generic_shdr *orig_gshdr =0; + Dwarf_Unsigned i = 0; + int res = 0; + + *count_out = 0; + psh = (dw_elf64_shdr *)calloc(count , entsize); + if(!psh) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + gshdr = (struct generic_shdr *)calloc(count,sizeof(*gshdr)); + if(gshdr == 0) { + free(psh); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + orig_psh = psh; + orig_gshdr = gshdr; + res = RRMOA(ep->f_fd,psh,offset,count*entsize, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(psh); + free(gshdr); + return res; + } + for( i = 0; i < count; + ++i, psh++,gshdr++) { + gshdr->gh_secnum = i; + ASNAR(ep->f_copy_word,gshdr->gh_name,psh->sh_name); + ASNAR(ep->f_copy_word,gshdr->gh_type,psh->sh_type); + ASNAR(ep->f_copy_word,gshdr->gh_flags,psh->sh_flags); + ASNAR(ep->f_copy_word,gshdr->gh_addr,psh->sh_addr); + ASNAR(ep->f_copy_word,gshdr->gh_offset,psh->sh_offset); + ASNAR(ep->f_copy_word,gshdr->gh_size,psh->sh_size); + ASNAR(ep->f_copy_word,gshdr->gh_link,psh->sh_link); + ASNAR(ep->f_copy_word,gshdr->gh_info,psh->sh_info); + ASNAR(ep->f_copy_word,gshdr->gh_addralign,psh->sh_addralign); + ASNAR(ep->f_copy_word,gshdr->gh_entsize,psh->sh_entsize); + if (gshdr->gh_type == SHT_REL || gshdr->gh_type == SHT_RELA){ + gshdr->gh_reloc_target_secnum = gshdr->gh_info; + } + } + free(orig_psh); + *count_out = count; + ep->f_shdr = orig_gshdr; + ep->f_loc_shdr.g_name = "Section Header"; + ep->f_loc_shdr.g_count = count; + ep->f_loc_shdr.g_offset = offset; + ep->f_loc_shdr.g_entrysize = sizeof(dw_elf64_shdr); + ep->f_loc_shdr.g_totalsize = sizeof(dw_elf64_shdr)*count; + return DW_DLV_OK; +} + + + +static int +dwarf_generic_elf_load_symbols32( + dwarf_elf_object_access_internals_t *ep, + struct generic_symentry **gsym_out, + Dwarf_Unsigned offset,Dwarf_Unsigned size, + Dwarf_Unsigned *count_out,int *errcode) +{ + Dwarf_Unsigned ecount = 0; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned i = 0; + dw_elf32_sym *psym = 0; + dw_elf32_sym *orig_psym = 0; + struct generic_symentry * gsym = 0; + struct generic_symentry * orig_gsym = 0; + int res = 0; + + ecount = (long)(size/sizeof(dw_elf32_sym)); + size2 = ecount * sizeof(dw_elf32_sym); + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + psym = calloc(ecount,sizeof(dw_elf32_sym)); + if (!psym) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + gsym = calloc(ecount,sizeof(struct generic_symentry)); + if (!gsym) { + free(psym); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,psym,offset,size, + ep->f_filesize,errcode); + if(res!= DW_DLV_OK) { + free(psym); + free(gsym); + return res; + } + orig_psym = psym; + orig_gsym = gsym; + for ( i = 0; i < ecount; ++i,++psym,++gsym) { + Dwarf_Unsigned bind = 0; + Dwarf_Unsigned type = 0; + + ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name); + ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value); + ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size); + ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info); + ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other); + ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx); + bind = gsym->gs_info >> 4; + type = gsym->gs_info & 0xf; + gsym->gs_bind = bind; + gsym->gs_type = type; + } + *count_out = ecount; + *gsym_out = orig_gsym; + free(orig_psym); + return DW_DLV_OK; +} + + +static int +dwarf_generic_elf_load_symbols64( + dwarf_elf_object_access_internals_t *ep, + struct generic_symentry **gsym_out, + Dwarf_Unsigned offset,Dwarf_Unsigned size, + Dwarf_Unsigned *count_out,int *errcode) +{ + Dwarf_Unsigned ecount = 0; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned i = 0; + dw_elf64_sym *psym = 0; + dw_elf64_sym *orig_psym = 0; + struct generic_symentry * gsym = 0; + struct generic_symentry * orig_gsym = 0; + int res = 0; + + ecount = (long)(size/sizeof(dw_elf64_sym)); + size2 = ecount * sizeof(dw_elf64_sym); + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + psym = calloc(ecount,sizeof(dw_elf64_sym)); + if (!psym) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + gsym = calloc(ecount,sizeof(struct generic_symentry)); + if (!gsym) { + free(psym); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,psym,offset,size, + ep->f_filesize,errcode); + if(res!= DW_DLV_OK) { + free(psym); + free(gsym); + *errcode = DW_DLE_ALLOC_FAIL; + return res; + } + orig_psym = psym; + orig_gsym = gsym; + for ( i = 0; i < ecount; ++i,++psym,++gsym) { + Dwarf_Unsigned bind = 0; + Dwarf_Unsigned type = 0; + + ASNAR(ep->f_copy_word,gsym->gs_name,psym->st_name); + ASNAR(ep->f_copy_word,gsym->gs_value,psym->st_value); + ASNAR(ep->f_copy_word,gsym->gs_size,psym->st_size); + ASNAR(ep->f_copy_word,gsym->gs_info,psym->st_info); + ASNAR(ep->f_copy_word,gsym->gs_other,psym->st_other); + ASNAR(ep->f_copy_word,gsym->gs_shndx,psym->st_shndx); + bind = gsym->gs_info >> 4; + type = gsym->gs_info & 0xf; + gsym->gs_bind = bind; + gsym->gs_type = type; + } + *count_out = ecount; + *gsym_out = orig_gsym; + free(orig_psym); + return DW_DLV_OK; +} + +static int +dwarf_generic_elf_load_symbols( + dwarf_elf_object_access_internals_t *ep, + int secnum, + struct generic_shdr *psh, + struct generic_symentry **gsym_out, + Dwarf_Unsigned *count_out,int *errcode) +{ + int res = 0; + struct generic_symentry *gsym = 0; + Dwarf_Unsigned count = 0; + + if(!secnum) { + return DW_DLV_NO_ENTRY; + } + if (ep->f_offsetsize == 32) { + res = dwarf_generic_elf_load_symbols32(ep, + &gsym, + psh->gh_offset,psh->gh_size, + &count,errcode); + } else if (ep->f_offsetsize == 64) { + res = dwarf_generic_elf_load_symbols64(ep, + &gsym, + psh->gh_offset,psh->gh_size, + &count,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + if (res == DW_DLV_OK) { + *gsym_out = gsym; + *count_out = count; + } + return res; +} +#if 0 +int +dwarf_load_elf_dynsym_symbols( + dwarf_elf_object_access_internals_t *ep, int*errcode) +{ + int res = 0; + struct generic_symentry *gsym = 0; + Dwarf_Unsigned count = 0; + Dwarf_Unsigned secnum = ep->f_dynsym_sect_index; + struct generic_shdr * psh = 0; + + if(!secnum) { + return DW_DLV_NO_ENTRY; + } + psh = ep->f_shdr + secnum; + res = dwarf_generic_elf_load_symbols(ep, + secnum, + psh, + &gsym, + &count,errcode); + if (res == DW_DLV_OK) { + ep->f_dynsym = gsym; + ep->f_loc_dynsym.g_count = count; + } + return res; +} +#endif /* 0 */ + +int +_dwarf_load_elf_symtab_symbols( + dwarf_elf_object_access_internals_t *ep, int*errcode) +{ + int res = 0; + struct generic_symentry *gsym = 0; + Dwarf_Unsigned count = 0; + Dwarf_Unsigned secnum = ep->f_symtab_sect_index; + struct generic_shdr * psh = 0; + + if(!secnum) { + return DW_DLV_NO_ENTRY; + } + psh = ep->f_shdr + secnum; + res = dwarf_generic_elf_load_symbols(ep, + secnum, + psh, + &gsym, + &count,errcode); + if (res == DW_DLV_OK) { + ep->f_symtab = gsym; + ep->f_loc_symtab.g_count = count; + } + return res; +} + +static int +generic_rel_from_rela32( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh, + dw_elf32_rela *relp, + struct generic_rela *grel, + int *errcode) +{ + Dwarf_Unsigned ecount = 0; + Dwarf_Unsigned size = gsh->gh_size; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned i = 0; + + ecount = size/sizeof(dw_elf32_rela); + size2 = ecount * sizeof(dw_elf32_rela); + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + for ( i = 0; i < ecount; ++i,++relp,++grel) { + ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); + ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); + /* addend signed */ + ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend); + SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend)); + grel->gr_isrela = TRUE; + grel->gr_sym = grel->gr_info>>8; /* ELF32_R_SYM */ + grel->gr_type = grel->gr_info & 0xff; + } + return DW_DLV_OK; +} + +static int +generic_rel_from_rela64( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh, + dw_elf64_rela *relp, + struct generic_rela *grel, int *errcode) +{ + Dwarf_Unsigned ecount = 0; + Dwarf_Unsigned size = gsh->gh_size; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned i = 0; + int objlittleendian = (ep->f_endian == DW_OBJECT_LSB); + int ismips64 = (ep->f_machine == EM_MIPS); + int issparcv9 = (ep->f_machine == EM_SPARCV9); + + ecount = size/sizeof(dw_elf64_rela); + size2 = ecount * sizeof(dw_elf64_rela); + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + for ( i = 0; i < ecount; ++i,++relp,++grel) { + ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); + ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); + ASNAR(ep->f_copy_word,grel->gr_addend,relp->r_addend); + SIGN_EXTEND(grel->gr_addend,sizeof(relp->r_addend)); + if (ismips64 && objlittleendian ) { + char realsym[4]; + + memcpy(realsym,&relp->r_info,sizeof(realsym)); + ASNAR(ep->f_copy_word,grel->gr_sym,realsym); + grel->gr_type = relp->r_info[7]; + grel->gr_type2 = relp->r_info[6]; + grel->gr_type3 = relp->r_info[5]; + } else if (issparcv9) { + /* Always Big Endian? */ + char realsym[4]; + + memcpy(realsym,&relp->r_info,sizeof(realsym)); + ASNAR(ep->f_copy_word,grel->gr_sym,realsym); + grel->gr_type = relp->r_info[7]; + } else { + grel->gr_sym = grel->gr_info >> 32; + grel->gr_type = grel->gr_info & 0xffffffff; + } + grel->gr_isrela = TRUE; + } + return DW_DLV_OK; +} + +#if 0 +static int +generic_rel_from_rel32( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh, + dw_elf32_rel *relp, + struct generic_rela *grel,int *errcode) +{ + Dwarf_Unsigned ecount = 0; + Dwarf_Unsigned size = gsh->gh_size; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned i = 0; + + ecount = size/sizeof(dw_elf32_rel); + size2 = ecount * sizeof(dw_elf32_rel); + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + for ( i = 0; i < ecount; ++i,++relp,++grel) { + grel->gr_isrela = 0; + ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); + ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); + grel->gr_addend = 0; /* Unused for plain .rel */ + grel->gr_sym = grel->gr_info >>8; /* ELF32_R_SYM */ + grel->gr_isrela = FALSE; + grel->gr_type = grel->gr_info & 0xff; + } + return DW_DLV_OK; +} +#endif /* 0 */ + +#if 0 +static int +generic_rel_from_rel64( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh, + dw_elf64_rel *relp, + struct generic_rela *grel,int *errcode) +{ + Dwarf_Unsigned ecount = 0; + Dwarf_Unsigned size = gsh->gh_size; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned i = 0; + int objlittleendian = (ep->f_endian == DW_OBJECT_LSB); + int ismips64 = (ep->f_machine == EM_MIPS); + int issparcv9 = (ep->f_machine == EM_SPARCV9); + + ecount = size/sizeof(dw_elf64_rel); + size2 = ecount * sizeof(dw_elf64_rel); + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + for ( i = 0; i < ecount; ++i,++relp,++grel) { + grel->gr_isrela = 0; + ASNAR(ep->f_copy_word,grel->gr_offset,relp->r_offset); + ASNAR(ep->f_copy_word,grel->gr_info,relp->r_info); + grel->gr_addend = 0; /* Unused for plain .rel */ + if (ismips64 && objlittleendian ) { + char realsym[4]; + + memcpy(realsym,&relp->r_info,sizeof(realsym)); + ASNAR(ep->f_copy_word,grel->gr_sym,realsym); + grel->gr_type = relp->r_info[7]; + grel->gr_type2 = relp->r_info[6]; + grel->gr_type3 = relp->r_info[5]; + } else if (issparcv9) { + /* Always Big Endian? */ + char realsym[4]; + + memcpy(realsym,&relp->r_info,sizeof(realsym)); + ASNAR(ep->f_copy_word,grel->gr_sym,realsym); + grel->gr_type = relp->r_info[7]; + } else { + grel->gr_sym = grel->gr_info >>32; + grel->gr_type = grel->gr_info & 0xffffffff; + } + grel->gr_isrela = FALSE; + + } + return DW_DLV_OK; +} +#endif /* 0 */ + +#if 0 +int +dwarf_load_elf_dynstr( + dwarf_elf_object_access_internals_t *ep, int *errcode) +{ + struct generic_shdr *strpsh = 0; + int res = 0; + Dwarf_Unsigned strsectindex =0; + Dwarf_Unsigned strsectlength = 0; + + if (!ep->f_dynsym_sect_strings_sect_index) { + return DW_DLV_NO_ENTRY; + } + strsectindex = ep->f_dynsym_sect_strings_sect_index; + strsectlength = ep->f_dynsym_sect_strings_max; + strpsh = ep->f_shdr + strsectindex; + /* Alloc an extra byte as a guaranteed NUL byte + at the end of the strings in case the section + is corrupted and lacks a NUL at end. */ + ep->f_dynsym_sect_strings = calloc(1,strsectlength+1); + if(!ep->f_dynsym_sect_strings) { + ep->f_dynsym_sect_strings = 0; + ep->f_dynsym_sect_strings_max = 0; + ep->f_dynsym_sect_strings_sect_index = 0; + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,ep->f_dynsym_sect_strings, + strpsh->gh_offset, + strsectlength, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + ep->f_dynsym_sect_strings = 0; + ep->f_dynsym_sect_strings_max = 0; + ep->f_dynsym_sect_strings_sect_index = 0; + return res; + } + return DW_DLV_OK; +} +#endif /* 0 */ + +int +_dwarf_load_elf_symstr( + dwarf_elf_object_access_internals_t *ep, int *errcode) +{ + struct generic_shdr *strpsh = 0; + int res = 0; + Dwarf_Unsigned strsectindex =0; + Dwarf_Unsigned strsectlength = 0; + + if (!ep->f_symtab_sect_strings_sect_index) { + return DW_DLV_NO_ENTRY; + } + strsectindex = ep->f_symtab_sect_strings_sect_index; + strsectlength = ep->f_symtab_sect_strings_max; + strpsh = ep->f_shdr + strsectindex; + /* Alloc an extra byte as a guaranteed NUL byte + at the end of the strings in case the section + is corrupted and lacks a NUL at end. */ + ep->f_symtab_sect_strings = calloc(1,strsectlength+1); + if(!ep->f_symtab_sect_strings) { + ep->f_symtab_sect_strings = 0; + ep->f_symtab_sect_strings_max = 0; + ep->f_symtab_sect_strings_sect_index = 0; + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,ep->f_symtab_sect_strings, + strpsh->gh_offset, + strsectlength, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(ep->f_symtab_sect_strings); + ep->f_symtab_sect_strings = 0; + ep->f_symtab_sect_strings_max = 0; + ep->f_symtab_sect_strings_sect_index = 0; + return res; + } + return DW_DLV_OK; +} + + +static int +_dwarf_elf_load_sectstrings( + dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned stringsection, + int *errcode) +{ + int res = 0; + struct generic_shdr *psh = 0; + Dwarf_Unsigned secoffset = 0; + + ep->f_elf_shstrings_length = 0; + if (stringsection >= ep->f_ehdr->ge_shnum) { + *errcode = DW_DLE_SECTION_INDEX_BAD; + return DW_DLV_ERROR; + } + psh = ep->f_shdr + stringsection; + secoffset = psh->gh_offset; + if(is_empty_section(psh->gh_type)) { + *errcode = DW_DLE_ELF_STRING_SECTION_MISSING; + return DW_DLV_ERROR; + } + if(psh->gh_size > ep->f_elf_shstrings_max) { + free(ep->f_elf_shstrings_data); + ep->f_elf_shstrings_data = (char *)malloc(psh->gh_size); + ep->f_elf_shstrings_max = psh->gh_size; + if(!ep->f_elf_shstrings_data) { + ep->f_elf_shstrings_max = 0; + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + } + ep->f_elf_shstrings_length = psh->gh_size; + res = RRMOA(ep->f_fd,ep->f_elf_shstrings_data,secoffset, + psh->gh_size, + ep->f_filesize,errcode); + return res; +} + +static int +elf_load_sectheaders32( + dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned offset,Dwarf_Unsigned entsize, + Dwarf_Unsigned count,int *errcode) +{ + Dwarf_Unsigned generic_count = 0; + int res = 0; + + + if(count == 0) { + return DW_DLV_NO_ENTRY; + } + if(entsize < sizeof(dw_elf32_shdr)) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + if ((offset > ep->f_filesize)|| + (entsize > 200)|| + (count > ep->f_filesize) || + ((count *entsize +offset) > ep->f_filesize)) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + res = generic_shdr_from_shdr32(ep,&generic_count, + offset,entsize,count,errcode); + if (res != DW_DLV_OK) { + return res; + } + if (generic_count != count) { + *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH; + return DW_DLV_ERROR; + } + return DW_DLV_OK; +} + +static int +elf_load_sectheaders64( + dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned offset,Dwarf_Unsigned entsize, + Dwarf_Unsigned count,int*errcode) +{ + Dwarf_Unsigned generic_count = 0; + int res = 0; + + + if(count == 0) { + return DW_DLV_NO_ENTRY; + } + if(entsize < sizeof(dw_elf64_shdr)) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + if ((offset > ep->f_filesize)|| + (entsize > 200)|| + (count > ep->f_filesize) || + ((count *entsize +offset) > ep->f_filesize)) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + res = generic_shdr_from_shdr64(ep,&generic_count, + offset,entsize,count,errcode); + if (res != DW_DLV_OK) { + return res; + } + if (generic_count != count) { + *errcode = DW_DLE_ELF_SECTION_COUNT_MISMATCH; + return DW_DLV_ERROR; + } + return DW_DLV_OK; +} + + +static int +_dwarf_elf_load_rela_32( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh, + struct generic_rela ** grel_out, + Dwarf_Unsigned *count_out, int *errcode) +{ + Dwarf_Unsigned count = 0; + Dwarf_Unsigned size = 0; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned sizeg = 0; + Dwarf_Unsigned offset = 0; + int res = 0; + dw_elf32_rela *relp = 0; + Dwarf_Unsigned object_reclen = sizeof(dw_elf32_rela); + struct generic_rela *grel = 0; + + offset = gsh->gh_offset; + size = gsh->gh_size; + if(size == 0) { + return DW_DLV_NO_ENTRY; + } + if ((offset > ep->f_filesize)|| + (size > ep->f_filesize) || + ((size +offset) > ep->f_filesize)) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + + count = (long)(size/object_reclen); + size2 = count * object_reclen; + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + relp = (dw_elf32_rela *)malloc(size); + if(!relp) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,relp,offset,size, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(relp); + return res; + } + sizeg = count*sizeof(struct generic_rela); + grel = (struct generic_rela *)malloc(sizeg); + if (!grel) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = generic_rel_from_rela32(ep,gsh,relp,grel,errcode); + free(relp); + if (res == DW_DLV_OK) { + gsh->gh_relcount = count; + gsh->gh_rels = grel; + *count_out = count; + *grel_out = grel; + return res; + } + /* Some sort of issue */ + count_out = 0; + free(grel); + return res; +} + +#if 0 +static int +_dwarf_elf_load_rel_32( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh,struct generic_rela ** grel_out, + Dwarf_Unsigned *count_out,int *errcode) +{ + Dwarf_Unsigned count = 0; + Dwarf_Unsigned size = 0; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned sizeg = 0; + Dwarf_Unsigned offset = 0; + int res = 0; + dw_elf32_rel* relp = 0; + Dwarf_Unsigned object_reclen = sizeof(dw_elf32_rel); + struct generic_rela *grel = 0; + + offset = gsh->gh_offset; + size = gsh->gh_size; + if(size == 0) { + return DW_DLV_NO_ENTRY; + } + if ((offset > ep->f_filesize)|| + (size > ep->f_filesize) || + ((size +offset) > ep->f_filesize)) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + + count = size/object_reclen; + size2 = count * object_reclen; + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + relp = (dw_elf32_rel *)malloc(size); + if(!relp) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,relp,offset,size, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(relp); + return res; + } + sizeg = count *sizeof(struct generic_rela); + grel = (struct generic_rela *)malloc(sizeg); + if (!grel) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = generic_rel_from_rel32(ep,gsh,relp,grel,errcode); + free(relp); + if (res == DW_DLV_OK) { + *count_out = count; + *grel_out = grel; + return res; + } + /* Some sort of error */ + count_out = 0; + free (grel); + return res; +} +#endif /* 0 */ + +#if 0 +static int +_dwarf_elf_load_rel_64( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh,struct generic_rela ** grel_out, + Dwarf_Unsigned *count_out,int *errcode) +{ + Dwarf_Unsigned count = 0; + Dwarf_Unsigned size = 0; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned sizeg = 0; + Dwarf_Unsigned offset = 0; + int res = 0; + dw_elf64_rel* relp = 0; + Dwarf_Unsigned object_reclen = sizeof(dw_elf64_rel); + struct generic_rela *grel = 0; + + offset = gsh->gh_offset; + size = gsh->gh_size; + if(size == 0) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + if ((offset > ep->f_filesize)|| + (size > ep->f_filesize) || + ((size +offset) > ep->f_filesize)) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + + count = size/object_reclen; + size2 = count * object_reclen; + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + relp = (dw_elf64_rel *)malloc(size); + if(!relp) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,relp,offset,size, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(relp); + return res; + } + sizeg = count*sizeof(struct generic_rela); + grel = (struct generic_rela *)malloc(sizeg); + if (!grel) { + free(relp); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = generic_rel_from_rel64(ep,gsh,relp,grel,errcode); + free(relp); + if (res == DW_DLV_OK) { + *count_out = count; + *grel_out = grel; + return res; + } + /* Some sort of error */ + count_out = 0; + free (grel); + return res; +} +#endif /* 0 */ + + +static int +_dwarf_elf_load_rela_64( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr * gsh, + struct generic_rela ** grel_out, + Dwarf_Unsigned *count_out,int *errcode) +{ + Dwarf_Unsigned count = 0; + Dwarf_Unsigned size = 0; + Dwarf_Unsigned size2 = 0; + Dwarf_Unsigned sizeg = 0; + Dwarf_Unsigned offset = 0; + int res = 0; + dw_elf64_rela *relp = 0; + Dwarf_Unsigned object_reclen = sizeof(dw_elf64_rela); + struct generic_rela *grel = 0; + + offset = gsh->gh_offset; + size = gsh->gh_size; + if(size == 0) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + if ((offset > ep->f_filesize)|| + (size > ep->f_filesize) || + ((size +offset) > ep->f_filesize)) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + count = (long)(size/object_reclen); + size2 = count * object_reclen; + if(size != size2) { + *errcode = DW_DLE_SECTION_SIZE_ERROR; + return DW_DLV_ERROR; + } + /* Here want native rela size from the file */ + relp = (dw_elf64_rela *)malloc(size); + if(!relp) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,relp,offset,size, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(relp); + return res; + } + sizeg = count*sizeof(struct generic_rela); + /* Here want generic-record size from the file */ + grel = (struct generic_rela *)malloc(sizeg); + if (!grel) { + free(relp); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = generic_rel_from_rela64(ep,gsh,relp,grel,errcode); + free(relp); + if (res == DW_DLV_OK) { + *count_out = count; + *grel_out = grel; + return res; + } + /* Some sort of error */ + count_out = 0; + free (grel); + return res; +} + +/* Is this rela section related to dwarf at all? + set oksecnum zero if not. Else set targ secnum. + Never returns DW_DLV_NO_ENTRY. */ +static int +this_is_a_section_dwarf_related( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr *gshdr, + unsigned *oksecnum_out, + int *errcode) +{ + unsigned oksecnum = 0; + struct generic_shdr *gstarg = 0; + + if (gshdr->gh_type != SHT_RELA ) { + *oksecnum_out = 0; + return DW_DLV_OK; + } + oksecnum = gshdr->gh_reloc_target_secnum; + if (oksecnum >= ep->f_loc_shdr.g_count) { + *oksecnum_out = 0; + *errcode = DW_DLE_ELF_SECTION_ERROR; + return DW_DLV_ERROR; + } + gstarg = ep->f_shdr+oksecnum; + if (!gstarg->gh_is_dwarf) { + *oksecnum_out = 0; /* no reloc needed. */ + return DW_DLV_OK; + } + + *oksecnum_out = oksecnum; + return DW_DLV_OK; +} +/* Secnum here is the secnum of rela. Not + the target of the relocations. */ +int +_dwarf_load_elf_rela( + dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned secnum, + int *errcode) +{ + struct generic_shdr *gshdr = 0; + Dwarf_Unsigned seccount = 0; + unsigned offsetsize = 0; + struct generic_rela *grp = 0; + Dwarf_Unsigned count_read = 0; + int res = 0; + unsigned oksec = 0; + + if (!ep) { + *errcode = DW_DLE_INTERNAL_NULL_POINTER; + return DW_DLV_ERROR; + } + offsetsize = ep->f_offsetsize; + seccount = ep->f_loc_shdr.g_count; + if (secnum >= seccount) { + *errcode = DW_DLE_ELF_SECTION_ERROR; + return DW_DLV_ERROR; + } + gshdr = ep->f_shdr +secnum; + if (is_empty_section(gshdr->gh_type)) { + return DW_DLV_NO_ENTRY; + } + + res = this_is_a_section_dwarf_related(ep,gshdr,&oksec,errcode); + if (res == DW_DLV_ERROR) { + return res; + } + if (!oksec) { + return DW_DLV_OK; + } + /* We will actually read these relocations. + Others get ignored. */ + if (offsetsize == 32) { + res = _dwarf_elf_load_rela_32(ep, + gshdr,&grp,&count_read,errcode); + } else if (offsetsize == 64) { + res = _dwarf_elf_load_rela_64(ep, + gshdr,&grp,&count_read,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + if (res == DW_DLV_ERROR) { + return res; + } + if (res == DW_DLV_NO_ENTRY) { + return res; + } + gshdr->gh_rels = grp; + gshdr->gh_relcount = count_read; + return DW_DLV_OK; +} +#if 0 +int +_dwarf_load_elf_rel( + dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned secnum, int *errcode) +{ + struct generic_shdr *gshdr = 0; + Dwarf_Unsigned generic_count = 0; + unsigned offsetsize = 0; + struct generic_rela *grp = 0; + Dwarf_Unsigned count_read = 0; + int res = 0; + + if (!ep) { + *errcode = DW_DLE_INTERNAL_NULL_POINTER; + return DW_DLV_ERROR; + } + offsetsize = ep->f_offsetsize; + generic_count = ep->f_loc_shdr.g_count; + if (secnum >= generic_count) { + *errcode = DW_DLE_ELF_SECTION_ERROR; + return DW_DLV_ERROR; + } + gshdr = ep->f_shdr +secnum; + if (is_empty_section(gshdr->gh_type)) { + return DW_DLV_NO_ENTRY; + } + if (offsetsize == 32) { + res = _dwarf_elf_load_rel_32(ep, + gshdr,&grp,&count_read,errcode); + } else if (offsetsize == 64) { + res = _dwarf_elf_load_rel_64(ep, + gshdr,&grp,&count_read,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + if (res == DW_DLV_ERROR) { + return res; + } + if (res == DW_DLV_NO_ENTRY) { + return res; + } + gshdr->gh_rels = grp; + gshdr->gh_relcount = count_read; + return DW_DLV_OK; +} +#endif /* 0 */ + +static int +validate_section_name_string(Dwarf_Unsigned section_length, + Dwarf_Unsigned string_loc_index, + const char * strings_start, + int * errcode) +{ + const char *endpoint = strings_start + section_length; + const char *cur = 0; + + if (section_length <= string_loc_index) { + *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD; + return DW_DLV_ERROR; + } + cur = string_loc_index+strings_start; + for( ; cur < endpoint;++cur) { + if (!*cur) { + return DW_DLV_OK; + } + } + *errcode = DW_DLE_SECTION_STRING_OFFSET_BAD; + return DW_DLV_ERROR; +} + +static int +_dwarf_elf_load_sect_namestring( + dwarf_elf_object_access_internals_t *ep, + int *errcode) +{ + struct generic_shdr *gshdr = 0; + Dwarf_Unsigned generic_count = 0; + Dwarf_Unsigned i = 1; + const char *stringsecbase = 0; + + stringsecbase = ep->f_elf_shstrings_data; + gshdr = ep->f_shdr; + generic_count = ep->f_loc_shdr.g_count; + for(i = 0; i < generic_count; i++, ++gshdr) { + const char *namestr = + ""; + int res = 0; + + res = validate_section_name_string(ep->f_elf_shstrings_length, + gshdr->gh_name, stringsecbase, + errcode); + if (res != DW_DLV_OK) { + gshdr->gh_namestring = namestr; + return res; + } + gshdr->gh_namestring = stringsecbase + gshdr->gh_name; + } + return DW_DLV_OK; +} + + +static int +elf_load_elf_header32( + dwarf_elf_object_access_internals_t *ep,int *errcode) +{ + int res = 0; + dw_elf32_ehdr ehdr32; + struct generic_ehdr *ehdr = 0; + + res = RRMOA(ep->f_fd,&ehdr32,0,sizeof(ehdr32), + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + return res; + } + ehdr = (struct generic_ehdr *)calloc(1, + sizeof(struct generic_ehdr)); + if (!ehdr) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = generic_ehdr_from_32(ep,ehdr,&ehdr32,errcode); + return res; +} +static int +elf_load_elf_header64( + dwarf_elf_object_access_internals_t *ep,int *errcode) +{ + int res = 0; + dw_elf64_ehdr ehdr64; + struct generic_ehdr *ehdr = 0; + + res = RRMOA(ep->f_fd,&ehdr64,0,sizeof(ehdr64), + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + return res; + } + ehdr = (struct generic_ehdr *)calloc(1, + sizeof(struct generic_ehdr)); + if (!ehdr) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = generic_ehdr_from_64(ep,ehdr,&ehdr64,errcode); + return res; +} + +static int +validate_struct_sizes( +#ifdef HAVE_ELF_H + int*errcode +#else + UNUSEDARG int*errcode +#endif + ) +{ +#ifdef HAVE_ELF_H + /* This is a sanity check when we have an elf.h + to check against. */ + if (sizeof(Elf32_Ehdr) != sizeof(dw_elf32_ehdr)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf64_Ehdr) != sizeof(dw_elf64_ehdr)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf32_Shdr) != sizeof(dw_elf32_shdr)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf64_Shdr) != sizeof(dw_elf64_shdr)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf32_Phdr) != sizeof(dw_elf32_phdr)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf64_Phdr) != sizeof(dw_elf64_phdr)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf32_Rel) != sizeof(dw_elf32_rel)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf64_Rel) != sizeof(dw_elf64_rel)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf32_Rela) != sizeof(dw_elf32_rela)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf64_Rela) != sizeof(dw_elf64_rela)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf32_Sym) != sizeof(dw_elf32_sym)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } + if (sizeof(Elf64_Sym) != sizeof(dw_elf64_sym)) { + *errcode = DW_DLE_BAD_TYPE_SIZE; + return DW_DLV_ERROR; + } +#endif /* HAVE_ELF_H */ + return DW_DLV_OK; +} + +int +_dwarf_load_elf_header( + dwarf_elf_object_access_internals_t *ep,int*errcode) +{ + unsigned offsetsize = ep->f_offsetsize; + int res = 0; + + res = validate_struct_sizes(errcode); + if (res != DW_DLV_OK) { + return res; + } + + if (offsetsize == 32) { + res = elf_load_elf_header32(ep,errcode); + } else if (offsetsize == 64) { + if (sizeof(Dwarf_Unsigned) < 8) { + *errcode = DW_DLE_INTEGER_TOO_SMALL; + return DW_DLV_ERROR; + } + res = elf_load_elf_header64(ep,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + return res; +} + +static int +validate_links( + dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned knownsect, + Dwarf_Unsigned string_sect, + int *errcode) +{ + struct generic_shdr* pshk = 0; + + if (!knownsect) { + return DW_DLV_OK; + } + if (!string_sect) { + *errcode = DW_DLE_ELF_STRING_SECTION_ERROR; + return DW_DLV_ERROR; + } + pshk = ep->f_shdr + knownsect; + if (string_sect != pshk->gh_link) { + *errcode = DW_DLE_ELF_SECTION_LINK_ERROR; + return DW_DLV_ERROR; + } + return DW_DLV_OK; +} + + +static int +string_endswith(const char *n,const char *q) +{ + unsigned long len = strlen(n); + unsigned long qlen = strlen(q); + const char *startpt = 0; + + if ( len < qlen) { + return FALSE; + } + startpt = n + (len-qlen); + if (strcmp(startpt,q)) { + return FALSE; + } + return TRUE; +} + +/* We are allowing either SHT_GROUP or .group to indicate + a group section, but really one should have both + or neither! */ +static int +elf_sht_groupsec(Dwarf_Unsigned type, const char *sname) +{ + /* ARM compilers name SHT group "__ARM_grp" + not .group */ + if ((type == SHT_GROUP) || (!strcmp(sname,".group"))){ + return TRUE; + } + return FALSE; +} + +static int +elf_flagmatches(Dwarf_Unsigned flagsword,Dwarf_Unsigned flag) +{ + if ((flagsword&flag) == flag) { + return TRUE; + } + return FALSE; +} + +/* For SHT_GROUP sections. */ +static int +read_gs_section_group( + dwarf_elf_object_access_internals_t *ep, + struct generic_shdr* psh, + int *errcode) +{ + Dwarf_Unsigned i = 0; + int res = 0; + + if (!psh->gh_sht_group_array) { + Dwarf_Unsigned seclen = psh->gh_size; + char *data = 0; + char *dp = 0; + Dwarf_Unsigned* grouparray = 0; + char dblock[4]; + Dwarf_Unsigned va = 0; + Dwarf_Unsigned count = 0; + int foundone = 0; + + if (seclen < DWARF_32BIT_SIZE) { + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + return DW_DLV_ERROR; + } + data = malloc(seclen); + if (!data) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + dp = data; + count = seclen/psh->gh_entsize; + if (count > ep->f_loc_shdr.g_count) { + /* Impossible */ + free(data); + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + return DW_DLV_ERROR; + } + + if (psh->gh_entsize != DWARF_32BIT_SIZE) { + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + free(data); + return DW_DLV_ERROR; + } + res = RRMOA(ep->f_fd,data,psh->gh_offset,seclen, + ep->f_filesize,errcode); + if(res != DW_DLV_OK) { + free(data); + return res; + } + grouparray = malloc(count * sizeof(Dwarf_Unsigned)); + if (!grouparray) { + free(data); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + memcpy(dblock,dp,DWARF_32BIT_SIZE); + ASNAR(memcpy,va,dblock); + /* There is ambiguity on the endianness of this stuff. */ + if (va != 1 && va != 0x1000000) { + /* Could be corrupted elf object. */ + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + free(data); + free(grouparray); + return DW_DLV_ERROR; + } + grouparray[0] = 1; + dp = dp + DWARF_32BIT_SIZE; + for( i = 1; i < count; ++i,dp += DWARF_32BIT_SIZE) { + Dwarf_Unsigned gseca = 0; + Dwarf_Unsigned gsecb = 0; + struct generic_shdr* targpsh = 0; + + memcpy(dblock,dp,DWARF_32BIT_SIZE); + ASNAR(memcpy,gseca,dblock); + ASNAR(_dwarf_memcpy_swap_bytes,gsecb,dblock); + if (!gseca) { + free(data); + free(grouparray); + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + return DW_DLV_ERROR; + } + grouparray[i] = gseca; + if (gseca > ep->f_loc_shdr.g_count) { + /* Might be confused endianness by + the compiler generating the SHT_GROUP. + This is pretty horrible. */ + + if (gsecb > ep->f_loc_shdr.g_count) { + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + free(data); + free(grouparray); + return DW_DLV_ERROR; + } + /* Ok. Yes, ugly. */ + gseca = gsecb; + grouparray[i] = gseca; + } + targpsh = ep->f_shdr + gseca; + if (targpsh->gh_section_group_number) { + /* multi-assignment to groups. Oops. */ + free(data); + free(grouparray); + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + return DW_DLV_ERROR; + } + targpsh->gh_section_group_number = + ep->f_sg_next_group_number; + foundone = 1; + } + if (foundone) { + ++ep->f_sg_next_group_number; + ++ep->f_sht_group_type_section_count; + } + free(data); + psh->gh_sht_group_array = grouparray; + psh->gh_sht_group_array_count = count; + } + return DW_DLV_OK; +} +/* Does related things. + A) Counts the number of SHT_GROUP + and for each builds an array of the sections in the group + (which we expect are all DWARF-related) + and sets the group number in each mentioned section. + B) Counts the number of SHF_GROUP flags. + C) If gnu groups: + ensure all the DWARF sections marked with right group + based on A(we will mark unmarked as group 1, + DW_GROUPNUMBER_BASE). + D) If arm groups (SHT_GROUP zero, SHF_GROUP non-zero): + Check the relocations of all SHF_GROUP section + FIXME: algorithm needed. + + + If SHT_GROUP and SHF_GROUP this is GNU groups. + If no SHT_GROUP and have SHF_GROUP this is + arm cc groups and we must use relocation information + to identify the group members. + + It seems(?) impossible for an object to have both + dwo sections and (SHF_GROUP or SHT_GROUP), but + we do not rule that out here. */ +static int +_dwarf_elf_setup_all_section_groups( + dwarf_elf_object_access_internals_t *ep, + int *errcode) +{ + struct generic_shdr* psh = 0; + Dwarf_Unsigned i = 0; + Dwarf_Unsigned count = 0; + int res = 0; + + count = ep->f_loc_shdr.g_count; + psh = ep->f_shdr; + + /* Does step A and step B */ + for (i = 0; i < count; ++psh,++i) { + const char *name = psh->gh_namestring; + if (is_empty_section(psh->gh_type)) { + /* No data here. */ + continue; + } + if (!elf_sht_groupsec(psh->gh_type,name)) { + /* Step B */ + if (elf_flagmatches(psh->gh_flags,SHF_GROUP)) { + ep->f_shf_group_flag_section_count++; + } + continue; + } + /* Looks like a section group. Do Step A. */ + res =read_gs_section_group(ep,psh,errcode); + if (res != DW_DLV_OK) { + return res; + } + } + /* Any sections not marked above or here are in + grep DW_GROUPNUMBER_BASE (1). + Section C. */ + psh = ep->f_shdr; + for (i = 0; i < count; ++psh,++i) { + const char *name = psh->gh_namestring; + + if (is_empty_section(psh->gh_type)) { + /* No data here. */ + continue; + } + if (elf_sht_groupsec(psh->gh_type,name)) { + continue; + } + /* Not a section group */ + if(string_endswith(name,".dwo")) { + if (psh->gh_section_group_number) { + /* multi-assignment to groups. Oops. */ + *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; + return DW_DLV_ERROR; + } + psh->gh_is_dwarf = TRUE; + psh->gh_section_group_number = DW_GROUPNUMBER_DWO; + ep->f_dwo_group_section_count++; + } else if (_dwarf_load_elf_section_is_dwarf(name)) { + if(!psh->gh_section_group_number) { + psh->gh_section_group_number = DW_GROUPNUMBER_BASE; + } + psh->gh_is_dwarf = TRUE; + } else { + /* Do nothing. */ + } + } + if (ep->f_sht_group_type_section_count) { + /* Not ARM. Done. */ + } + if (!ep->f_shf_group_flag_section_count) { + /* Nothing more to do. */ + return DW_DLV_OK; + } + return DW_DLV_OK; +} + +static int +_dwarf_elf_find_sym_sections( + dwarf_elf_object_access_internals_t *ep, + int *errcode) +{ + struct generic_shdr* psh = 0; + Dwarf_Unsigned i = 0; + Dwarf_Unsigned count = 0; + int res = 0; + + count = ep->f_loc_shdr.g_count; + psh = ep->f_shdr; + for (i = 0; i < count; ++psh,++i) { + const char *name = psh->gh_namestring; + if (is_empty_section(psh->gh_type)) { + /* No data here. */ + continue; + } + if (!strcmp(name,".dynsym")) { + ep->f_dynsym_sect_index = i; + ep->f_loc_dynsym.g_offset = psh->gh_offset; + } else if (!strcmp(name,".dynstr")) { + ep->f_dynsym_sect_strings_sect_index = i; + ep->f_dynsym_sect_strings_max = psh->gh_size; + } else if (!strcmp(name,".symtab")) { + ep->f_symtab_sect_index = i; + ep->f_loc_symtab.g_offset = psh->gh_offset; + } else if (!strcmp(name,".strtab")) { + ep->f_symtab_sect_strings_sect_index = i; + ep->f_symtab_sect_strings_max = psh->gh_size; + } else if (!strcmp(name,".dynamic")) { + ep->f_dynamic_sect_index = i; + ep->f_loc_dynamic.g_offset = psh->gh_offset; + } + } + +#if 0 + res = validate_links(ep,ep->f_dynsym_sect_index, + ep->f_dynsym_sect_strings_sect_index,errcode); + if (res!= DW_DLV_OK) { + return res; + } +#endif /* 0 */ + res = validate_links(ep,ep->f_symtab_sect_index, + ep->f_symtab_sect_strings_sect_index,errcode); + if (res!= DW_DLV_OK) { + return res; + } + return DW_DLV_OK; +} + + +int +_dwarf_load_elf_sectheaders( + dwarf_elf_object_access_internals_t *ep,int*errcode) +{ + int res = 0; + + if (ep->f_offsetsize == 32) { + res = elf_load_sectheaders32(ep,ep->f_ehdr->ge_shoff, + ep->f_ehdr->ge_shentsize, + ep->f_ehdr->ge_shnum,errcode); + } else if (ep->f_offsetsize == 64) { + res = elf_load_sectheaders64(ep,ep->f_ehdr->ge_shoff, + ep->f_ehdr->ge_shentsize, + ep->f_ehdr->ge_shnum,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_elf_load_sectstrings(ep, + ep->f_ehdr->ge_shstrndx,errcode); + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_elf_load_sect_namestring(ep,errcode); + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_elf_find_sym_sections(ep,errcode); + if (res != DW_DLV_OK) { + return res; + } + res = _dwarf_elf_setup_all_section_groups(ep,errcode); + return res; +} diff --git a/thirdparty/dwarf/dwarf_elf_rel_detector.c b/thirdparty/dwarf/dwarf_elf_rel_detector.c new file mode 100644 index 00000000..057dd809 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_rel_detector.c @@ -0,0 +1,357 @@ +/* +Copyright (c) 2019, David Anderson +All rights reserved. +cc +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" +#include +#include "dwarf_elf_defines.h" +#include "dwarf_elf_rel_detector.h" + +unsigned +_dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine) +{ + unsigned r = 0; + + switch (machine) { +#if defined(EM_MIPS) && defined (R_MIPS_32) + case EM_MIPS: + r = (0 +#if defined (R_MIPS_32) + | (type == R_MIPS_32) +#endif +#if defined (R_MIPS_TLS_DTPREL32) + | (type == R_MIPS_TLS_DTPREL32) +#endif /* DTPREL32 */ + ); + break; +#endif /* MIPS case */ +#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32) + case EM_SPARC32PLUS: + r = (0 +#if defined(R_SPARC_UA32) + | (type == R_SPARC_UA32) +#endif +#if defined(R_SPARC_TLS_DTPOFF32) + | (type == R_SPARC_TLS_DTPOFF32) +#endif + ); + break; +#endif +#if defined(EM_SPARCV9) && defined (R_SPARC_UA32) + case EM_SPARCV9: + r = (type == R_SPARC_UA32); + break; +#endif +#if defined(EM_SPARC) && defined (R_SPARC_UA32) + case EM_SPARC: + r = (0 +#if defined(R_SPARC_UA32) + | (type == R_SPARC_UA32) +#endif +#if (R_SPARC_TLS_DTPOFF32) + | (type == R_SPARC_TLS_DTPOFF32) +#endif + ); + break; +#endif /* EM_SPARC */ +#if defined(EM_386) && defined (R_386_32) + case EM_386: + r = (0 +#if defined (R_386_32) + | (type == R_386_32) +#endif +#if defined (R_386_TLS_LDO_32) + | (type == R_386_TLS_LDO_32) +#endif +#if defined (R_386_TLS_DTPOFF32) + | (type == R_386_TLS_DTPOFF32) +#endif + ); + break; +#endif /* EM_386 */ + +#if defined (EM_SH) && defined (R_SH_DIR32) + case EM_SH: + r = (0 +#if defined (R_SH_DIR32) + | (type == R_SH_DIR32) +#endif +#if defined (R_SH_DTPOFF32) + | (type == R_SH_TLS_DTPOFF32) +#endif + ); + break; +#endif /* SH */ + +#if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB) + case EM_IA_64: /* 32bit? ! */ + r = (0 +#if defined (R_IA64_SECREL32LSB) + | (type == R_IA64_SECREL32LSB) +#endif +#if defined (R_IA64_DIR32LSB) + | (type == R_IA64_DIR32LSB) +#endif +#if defined (R_IA64_DTPREL32LSB) + | (type == R_IA64_DTPREL32LSB) +#endif + ); + break; +#endif /* EM_IA_64 */ + +#if defined(EM_ARM) && defined (R_ARM_ABS32) + case EM_ARM: + case EM_AARCH64: + r = (0 +#if defined (R_ARM_ABS32) + | ( type == R_ARM_ABS32) +#endif +#if defined (R_AARCH64_ABS32) + | ( type == R_AARCH64_ABS32) +#endif +#if defined (R_ARM_TLS_LDO32) + | ( type == R_ARM_TLS_LDO32) +#endif + ); + break; +#endif /* EM_ARM */ + +/* On FreeBSD xR_PPC64_ADDR32 not defined + so we use the xR_PPC_ names which + have the proper value. + Our headers have: + xR_PPC64_ADDR64 38 + xR_PPC_ADDR32 1 so we use this one + xR_PPC64_ADDR32 R_PPC_ADDR32 + + xR_PPC64_DTPREL32 110 which may be wrong/unavailable + xR_PPC64_DTPREL64 78 + xR_PPC_DTPREL32 78 + */ +#if defined(EM_PPC64) && defined (R_PPC_ADDR32) + case EM_PPC64: + r = (0 +#if defined(R_PPC_ADDR32) + | (type == R_PPC_ADDR32) +#endif +#if defined(R_PPC64_DTPREL32) + | (type == R_PPC64_DTPREL32) +#endif + ); + break; +#endif /* EM_PPC64 */ + + +#if defined(EM_PPC) && defined (R_PPC_ADDR32) + case EM_PPC: + r = (0 +#if defined (R_PPC_ADDR32) + | (type == R_PPC_ADDR32) +#endif +#if defined (R_PPC_DTPREL32) + | (type == R_PPC_DTPREL32) +#endif + ); + break; +#endif /* EM_PPC */ + +#if defined(EM_S390) && defined (R_390_32) + case EM_S390: + r = (0 +#if defined (R_390_32) + | (type == R_390_32) +#endif +#if defined (R_390_TLS_LDO32) + | (type == R_390_TLS_LDO32) +#endif + ); + break; +#endif /* EM_S390 */ + +#if defined(EM_X86_64) && ( defined(R_X86_64_32) || defined(R_X86_64_PC32) || defined(R_X86_64_DTPOFF32) ) +#if defined(EM_K10M) + case EM_K10M: +#endif +#if defined(EM_L10M) + case EM_L10M: +#endif + case EM_X86_64: + r = (0 +#if defined (R_X86_64_PC32) + | (type == R_X86_64_PC32) +#endif +#if defined (R_X86_64_32) + | (type == R_X86_64_32) +#endif +#if defined (R_X86_64_DTPOFF32) + | (type == R_X86_64_DTPOFF32) +#endif + ); + break; +#endif /* EM_X86_64 */ + + case EM_QUALCOMM_DSP6: + r = (type == R_QUALCOMM_REL32); + break; + } + return r; +} + +unsigned +_dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine) +{ + unsigned r = 0; + + switch (machine) { +#if defined(EM_MIPS) && defined (R_MIPS_64) + case EM_MIPS: + r = (0 +#if defined (R_MIPS_64) + | (type == R_MIPS_64) +#endif +#if defined (R_MIPS_32) + | (type == R_MIPS_32) +#endif +#if defined(R_MIPS_TLS_DTPREL64) + | (type == R_MIPS_TLS_DTPREL64) +#endif + ); + break; +#endif /* EM_MIPS */ +#if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64) + case EM_SPARC32PLUS: + r = (type == R_SPARC_UA64); + break; +#endif +#if defined(EM_SPARCV9) && defined (R_SPARC_UA64) + case EM_SPARCV9: + r = (0 +#if defined (R_SPARC_UA64) + | (type == R_SPARC_UA64) +#endif +#if defined (R_SPARC_TLS_DTPOFF64) + | (type == R_SPARC_TLS_DTPOFF64) +#endif + ); + break; +#endif +#if defined(EM_SPARC) && defined (R_SPARC_UA64) + case EM_SPARC: + r = (0 +#if defined(R_SPARC_UA64) + | (type == R_SPARC_UA64) +#endif +#if defined (R_SPARC_TLS_DTPOFF64) + | (type == R_SPARC_TLS_DTPOFF64) +#endif + ); + break; +#endif /* EM_SPARC */ + +#if defined(EM_IA_64) && defined (R_IA64_SECREL64LSB) + case EM_IA_64: /* 64bit */ + r = (0 +#if defined (R_IA64_SECREL64LSB) + | (type == R_IA64_SECREL64LSB) +#endif +#if defined (R_IA64_SECREL32LSB) + | (type == R_IA64_SECREL32LSB) +#endif +#if defined (R_IA64_DIR64LSB) + | (type == R_IA64_DIR64LSB) +#endif +#if defined (R_IA64_DTPREL64LSB) + | (type == R_IA64_DTPREL64LSB) +#endif +#if defined (R_IA64_REL32LSB) + | (type == R_IA64_REL32LSB) +#endif + ); + break; +#endif /* EM_IA_64 */ + +#if defined(EM_PPC64) && defined (R_PPC64_ADDR64) + case EM_PPC64: + r = (0 +#if defined(R_PPC64_ADDR64) + | (type == R_PPC64_ADDR64) +#endif +#if defined(R_PPC64_DTPREL64) + | (type == R_PPC64_DTPREL64) +#endif + ); + break; +#endif /* EM_PPC64 */ + +#if defined(EM_S390) && defined (R_390_64) + case EM_S390: + r = (0 +#if defined(R_390_64) + | (type == R_390_64) +#endif +#if defined(R_390_TLS_LDO64) + | (type == R_390_TLS_LDO64) +#endif + ); + break; +#endif /* EM_390 */ + +#if defined(EM_X86_64) && defined (R_X86_64_64) +#if defined(EM_K10M) + case EM_K10M: +#endif +#if defined(EM_L10M) + case EM_L10M: +#endif + case EM_X86_64: + r = (0 +#if defined (R_X86_64_64) + | (type == R_X86_64_64) +#endif +#if defined (R_X86_64_DTPOFF32) + | (type == R_X86_64_DTPOFF64) +#endif + ); + break; +#endif /* EM_X86_64 */ +#if defined(EM_AARCH64) && defined (R_AARCH64_ABS64) + case EM_AARCH64: + r = (0 +#if defined (R_AARCH64_ABS64) + | ( type == R_AARCH64_ABS64) +#endif + ); + break; +#endif /* EM_AARCH64 */ + + } + return r; +} diff --git a/thirdparty/dwarf/dwarf_elf_rel_detector.h b/thirdparty/dwarf/dwarf_elf_rel_detector.h new file mode 100644 index 00000000..653c1b6c --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_rel_detector.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2019, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef DWARF_ELF_REL_DETECTOR_H +#define DWARF_ELF_REL_DETECTOR_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +unsigned _dwarf_is_32bit_abs_reloc(unsigned int type, unsigned machine); +unsigned _dwarf_is_64bit_abs_reloc(unsigned int type, unsigned machine); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DWARF_ELF_REL_DETECTOR_H */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_386.h b/thirdparty/dwarf/dwarf_elf_reloc_386.h new file mode 100644 index 00000000..a9020ef2 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_386.h @@ -0,0 +1,123 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_386(unsigned long); +#ifndef R_386_NONE +#define R_386_NONE 0 +#endif /* R_386_NONE */ +#ifndef R_386_32 +#define R_386_32 1 +#endif /* R_386_32 */ +#ifndef R_386_PC32 +#define R_386_PC32 2 +#endif /* R_386_PC32 */ +#ifndef R_386_GOT32 +#define R_386_GOT32 3 +#endif /* R_386_GOT32 */ +#ifndef R_386_PLT32 +#define R_386_PLT32 4 +#endif /* R_386_PLT32 */ +#ifndef R_386_COPY +#define R_386_COPY 5 +#endif /* R_386_COPY */ +#ifndef R_386_GLOB_DAT +#define R_386_GLOB_DAT 6 +#endif /* R_386_GLOB_DAT */ +#ifndef R_386_JMP_SLOT +#define R_386_JMP_SLOT 7 +#endif /* R_386_JMP_SLOT */ +#ifndef R_386_RELATIVE +#define R_386_RELATIVE 8 +#endif /* R_386_RELATIVE */ +#ifndef R_386_GOTOFF +#define R_386_GOTOFF 9 +#endif /* R_386_GOTOFF */ +#ifndef R_386_GOTPC +#define R_386_GOTPC 10 +#endif /* R_386_GOTPC */ +#ifndef R_386_32PLT +#define R_386_32PLT 11 +#endif /* R_386_32PLT */ +#ifndef R_386_TLS_TPOFF +#define R_386_TLS_TPOFF 14 +#endif /* R_386_TLS_TPOFF */ +#ifndef R_386_TLS_IE +#define R_386_TLS_IE 15 +#endif /* R_386_TLS_IE */ +#ifndef R_386_TLS_GOTIE +#define R_386_TLS_GOTIE 16 +#endif /* R_386_TLS_GOTIE */ +#ifndef R_386_TLS_LE +#define R_386_TLS_LE 17 +#endif /* R_386_TLS_LE */ +#ifndef R_386_TLS_LDM +#define R_386_TLS_LDM 19 +#endif /* R_386_TLS_LDM */ +#ifndef R_386_16 +#define R_386_16 20 +#endif /* R_386_16 */ +#ifndef R_386_PC16 +#define R_386_PC16 21 +#endif /* R_386_PC16 */ +#ifndef R_386_8 +#define R_386_8 22 +#endif /* R_386_8 */ +#ifndef R_386_PC8 +#define R_386_PC8 23 +#endif /* R_386_PC8 */ +#ifndef R_386_TLS_GD_32 +#define R_386_TLS_GD_32 24 +#endif /* R_386_TLS_GD_32 */ +#ifndef R_386_TLS_GD_PUSH +#define R_386_TLS_GD_PUSH 25 +#endif /* R_386_TLS_GD_PUSH */ +#ifndef R_386_TLS_GD_CALL +#define R_386_TLS_GD_CALL 26 +#endif /* R_386_TLS_GD_CALL */ +#ifndef R_386_TLS_GD_POP +#define R_386_TLS_GD_POP 27 +#endif /* R_386_TLS_GD_POP */ +#ifndef R_386_TLS_LDM_32 +#define R_386_TLS_LDM_32 28 +#endif /* R_386_TLS_LDM_32 */ +#ifndef R_386_TLS_LDM_PUSH +#define R_386_TLS_LDM_PUSH 29 +#endif /* R_386_TLS_LDM_PUSH */ +#ifndef R_386_TLS_LDM_CALL +#define R_386_TLS_LDM_CALL 30 +#endif /* R_386_TLS_LDM_CALL */ +#ifndef R_386_TLS_LDM_POP +#define R_386_TLS_LDM_POP 31 +#endif /* R_386_TLS_LDM_POP */ +#ifndef R_386_TLS_LDO_32 +#define R_386_TLS_LDO_32 32 +#endif /* R_386_TLS_LDO_32 */ +#ifndef R_386_TLS_IE_32 +#define R_386_TLS_IE_32 33 +#endif /* R_386_TLS_IE_32 */ +#ifndef R_386_TLS_LE_32 +#define R_386_TLS_LE_32 34 +#endif /* R_386_TLS_LE_32 */ +#ifndef R_386_TLS_DTPMOD32 +#define R_386_TLS_DTPMOD32 35 +#endif /* R_386_TLS_DTPMOD32 */ +#ifndef R_386_TLS_DTPOFF32 +#define R_386_TLS_DTPOFF32 36 +#endif /* R_386_TLS_DTPOFF32 */ +#ifndef R_386_TLS_TPOFF32 +#define R_386_TLS_TPOFF32 37 +#endif /* R_386_TLS_TPOFF32 */ +#ifndef R_386_SIZE32 +#define R_386_SIZE32 38 +#endif /* R_386_SIZE32 */ +#ifndef R_386_TLS_GOTDESC +#define R_386_TLS_GOTDESC 39 +#endif /* R_386_TLS_GOTDESC */ +#ifndef R_386_TLS_DESC_CALL +#define R_386_TLS_DESC_CALL 40 +#endif /* R_386_TLS_DESC_CALL */ +#ifndef R_386_TLS_DESC +#define R_386_TLS_DESC 41 +#endif /* R_386_TLS_DESC */ +#ifndef R_386_IRELATIVE +#define R_386_IRELATIVE 42 +#endif /* R_386_IRELATIVE */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_aarch64.h b/thirdparty/dwarf/dwarf_elf_reloc_aarch64.h new file mode 100644 index 00000000..159aff12 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_aarch64.h @@ -0,0 +1,402 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_aarch64(unsigned long); +#ifndef R_AARCH64_NONE +#define R_AARCH64_NONE 0 +#endif /* R_AARCH64_NONE */ +#ifndef R_AARCH64_P32_ABS32 +#define R_AARCH64_P32_ABS32 1 +#endif /* R_AARCH64_P32_ABS32 */ +#ifndef R_AARCH64_P32_COPY +#define R_AARCH64_P32_COPY 180 +#endif /* R_AARCH64_P32_COPY */ +#ifndef R_AARCH64_P32_GLOB_DAT +#define R_AARCH64_P32_GLOB_DAT 181 +#endif /* R_AARCH64_P32_GLOB_DAT */ +#ifndef R_AARCH64_P32_JUMP_SLOT +#define R_AARCH64_P32_JUMP_SLOT 182 +#endif /* R_AARCH64_P32_JUMP_SLOT */ +#ifndef R_AARCH64_P32_RELATIVE +#define R_AARCH64_P32_RELATIVE 183 +#endif /* R_AARCH64_P32_RELATIVE */ +#ifndef R_AARCH64_P32_TLS_DTPMOD +#define R_AARCH64_P32_TLS_DTPMOD 184 +#endif /* R_AARCH64_P32_TLS_DTPMOD */ +#ifndef R_AARCH64_P32_TLS_DTPREL +#define R_AARCH64_P32_TLS_DTPREL 185 +#endif /* R_AARCH64_P32_TLS_DTPREL */ +#ifndef R_AARCH64_P32_TLS_TPREL +#define R_AARCH64_P32_TLS_TPREL 186 +#endif /* R_AARCH64_P32_TLS_TPREL */ +#ifndef R_AARCH64_P32_TLSDESC +#define R_AARCH64_P32_TLSDESC 187 +#endif /* R_AARCH64_P32_TLSDESC */ +#ifndef R_AARCH64_P32_IRELATIVE +#define R_AARCH64_P32_IRELATIVE 188 +#endif /* R_AARCH64_P32_IRELATIVE */ +#ifndef R_AARCH64_ABS64 +#define R_AARCH64_ABS64 257 +#endif /* R_AARCH64_ABS64 */ +#ifndef R_AARCH64_ABS32 +#define R_AARCH64_ABS32 258 +#endif /* R_AARCH64_ABS32 */ +#ifndef R_AARCH64_ABS16 +#define R_AARCH64_ABS16 259 +#endif /* R_AARCH64_ABS16 */ +#ifndef R_AARCH64_PREL64 +#define R_AARCH64_PREL64 260 +#endif /* R_AARCH64_PREL64 */ +#ifndef R_AARCH64_PREL32 +#define R_AARCH64_PREL32 261 +#endif /* R_AARCH64_PREL32 */ +#ifndef R_AARCH64_PREL16 +#define R_AARCH64_PREL16 262 +#endif /* R_AARCH64_PREL16 */ +#ifndef R_AARCH64_MOVW_UABS_G0 +#define R_AARCH64_MOVW_UABS_G0 263 +#endif /* R_AARCH64_MOVW_UABS_G0 */ +#ifndef R_AARCH64_MOVW_UABS_G0_NC +#define R_AARCH64_MOVW_UABS_G0_NC 264 +#endif /* R_AARCH64_MOVW_UABS_G0_NC */ +#ifndef R_AARCH64_MOVW_UABS_G1 +#define R_AARCH64_MOVW_UABS_G1 265 +#endif /* R_AARCH64_MOVW_UABS_G1 */ +#ifndef R_AARCH64_MOVW_UABS_G1_NC +#define R_AARCH64_MOVW_UABS_G1_NC 266 +#endif /* R_AARCH64_MOVW_UABS_G1_NC */ +#ifndef R_AARCH64_MOVW_UABS_G2 +#define R_AARCH64_MOVW_UABS_G2 267 +#endif /* R_AARCH64_MOVW_UABS_G2 */ +#ifndef R_AARCH64_MOVW_UABS_G2_NC +#define R_AARCH64_MOVW_UABS_G2_NC 268 +#endif /* R_AARCH64_MOVW_UABS_G2_NC */ +#ifndef R_AARCH64_MOVW_UABS_G3 +#define R_AARCH64_MOVW_UABS_G3 269 +#endif /* R_AARCH64_MOVW_UABS_G3 */ +#ifndef R_AARCH64_MOVW_SABS_G0 +#define R_AARCH64_MOVW_SABS_G0 270 +#endif /* R_AARCH64_MOVW_SABS_G0 */ +#ifndef R_AARCH64_MOVW_SABS_G1 +#define R_AARCH64_MOVW_SABS_G1 271 +#endif /* R_AARCH64_MOVW_SABS_G1 */ +#ifndef R_AARCH64_MOVW_SABS_G2 +#define R_AARCH64_MOVW_SABS_G2 272 +#endif /* R_AARCH64_MOVW_SABS_G2 */ +#ifndef R_AARCH64_LD_PREL_LO19 +#define R_AARCH64_LD_PREL_LO19 273 +#endif /* R_AARCH64_LD_PREL_LO19 */ +#ifndef R_AARCH64_ADR_PREL_LO21 +#define R_AARCH64_ADR_PREL_LO21 274 +#endif /* R_AARCH64_ADR_PREL_LO21 */ +#ifndef R_AARCH64_ADR_PREL_PG_HI21 +#define R_AARCH64_ADR_PREL_PG_HI21 275 +#endif /* R_AARCH64_ADR_PREL_PG_HI21 */ +#ifndef R_AARCH64_ADR_PREL_PG_HI21_NC +#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 +#endif /* R_AARCH64_ADR_PREL_PG_HI21_NC */ +#ifndef R_AARCH64_ADD_ABS_LO12_NC +#define R_AARCH64_ADD_ABS_LO12_NC 277 +#endif /* R_AARCH64_ADD_ABS_LO12_NC */ +#ifndef R_AARCH64_LDST8_ABS_LO12_NC +#define R_AARCH64_LDST8_ABS_LO12_NC 278 +#endif /* R_AARCH64_LDST8_ABS_LO12_NC */ +#ifndef R_AARCH64_TSTBR14 +#define R_AARCH64_TSTBR14 279 +#endif /* R_AARCH64_TSTBR14 */ +#ifndef R_AARCH64_CONDBR19 +#define R_AARCH64_CONDBR19 280 +#endif /* R_AARCH64_CONDBR19 */ +#ifndef R_AARCH64_JUMP26 +#define R_AARCH64_JUMP26 282 +#endif /* R_AARCH64_JUMP26 */ +#ifndef R_AARCH64_CALL26 +#define R_AARCH64_CALL26 283 +#endif /* R_AARCH64_CALL26 */ +#ifndef R_AARCH64_LDST16_ABS_LO12_NC +#define R_AARCH64_LDST16_ABS_LO12_NC 284 +#endif /* R_AARCH64_LDST16_ABS_LO12_NC */ +#ifndef R_AARCH64_LDST32_ABS_LO12_NC +#define R_AARCH64_LDST32_ABS_LO12_NC 285 +#endif /* R_AARCH64_LDST32_ABS_LO12_NC */ +#ifndef R_AARCH64_LDST64_ABS_LO12_NC +#define R_AARCH64_LDST64_ABS_LO12_NC 286 +#endif /* R_AARCH64_LDST64_ABS_LO12_NC */ +#ifndef R_AARCH64_MOVW_PREL_G0 +#define R_AARCH64_MOVW_PREL_G0 287 +#endif /* R_AARCH64_MOVW_PREL_G0 */ +#ifndef R_AARCH64_MOVW_PREL_G0_NC +#define R_AARCH64_MOVW_PREL_G0_NC 288 +#endif /* R_AARCH64_MOVW_PREL_G0_NC */ +#ifndef R_AARCH64_MOVW_PREL_G1 +#define R_AARCH64_MOVW_PREL_G1 289 +#endif /* R_AARCH64_MOVW_PREL_G1 */ +#ifndef R_AARCH64_MOVW_PREL_G1_NC +#define R_AARCH64_MOVW_PREL_G1_NC 290 +#endif /* R_AARCH64_MOVW_PREL_G1_NC */ +#ifndef R_AARCH64_MOVW_PREL_G2 +#define R_AARCH64_MOVW_PREL_G2 291 +#endif /* R_AARCH64_MOVW_PREL_G2 */ +#ifndef R_AARCH64_MOVW_PREL_G2_NC +#define R_AARCH64_MOVW_PREL_G2_NC 292 +#endif /* R_AARCH64_MOVW_PREL_G2_NC */ +#ifndef R_AARCH64_MOVW_PREL_G3 +#define R_AARCH64_MOVW_PREL_G3 293 +#endif /* R_AARCH64_MOVW_PREL_G3 */ +#ifndef R_AARCH64_LDST128_ABS_LO12_NC +#define R_AARCH64_LDST128_ABS_LO12_NC 299 +#endif /* R_AARCH64_LDST128_ABS_LO12_NC */ +#ifndef R_AARCH64_MOVW_GOTOFF_G0 +#define R_AARCH64_MOVW_GOTOFF_G0 300 +#endif /* R_AARCH64_MOVW_GOTOFF_G0 */ +#ifndef R_AARCH64_MOVW_GOTOFF_G0_NC +#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 +#endif /* R_AARCH64_MOVW_GOTOFF_G0_NC */ +#ifndef R_AARCH64_MOVW_GOTOFF_G1 +#define R_AARCH64_MOVW_GOTOFF_G1 302 +#endif /* R_AARCH64_MOVW_GOTOFF_G1 */ +#ifndef R_AARCH64_MOVW_GOTOFF_G1_NC +#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 +#endif /* R_AARCH64_MOVW_GOTOFF_G1_NC */ +#ifndef R_AARCH64_MOVW_GOTOFF_G2 +#define R_AARCH64_MOVW_GOTOFF_G2 304 +#endif /* R_AARCH64_MOVW_GOTOFF_G2 */ +#ifndef R_AARCH64_MOVW_GOTOFF_G2_NC +#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 +#endif /* R_AARCH64_MOVW_GOTOFF_G2_NC */ +#ifndef R_AARCH64_MOVW_GOTOFF_G3 +#define R_AARCH64_MOVW_GOTOFF_G3 306 +#endif /* R_AARCH64_MOVW_GOTOFF_G3 */ +#ifndef R_AARCH64_GOTREL64 +#define R_AARCH64_GOTREL64 307 +#endif /* R_AARCH64_GOTREL64 */ +#ifndef R_AARCH64_GOTREL32 +#define R_AARCH64_GOTREL32 308 +#endif /* R_AARCH64_GOTREL32 */ +#ifndef R_AARCH64_GOT_LD_PREL19 +#define R_AARCH64_GOT_LD_PREL19 309 +#endif /* R_AARCH64_GOT_LD_PREL19 */ +#ifndef R_AARCH64_LD64_GOTOFF_LO15 +#define R_AARCH64_LD64_GOTOFF_LO15 310 +#endif /* R_AARCH64_LD64_GOTOFF_LO15 */ +#ifndef R_AARCH64_ADR_GOT_PAGE +#define R_AARCH64_ADR_GOT_PAGE 311 +#endif /* R_AARCH64_ADR_GOT_PAGE */ +#ifndef R_AARCH64_LD64_GOT_LO12_NC +#define R_AARCH64_LD64_GOT_LO12_NC 312 +#endif /* R_AARCH64_LD64_GOT_LO12_NC */ +#ifndef R_AARCH64_LD64_GOTPAGE_LO15 +#define R_AARCH64_LD64_GOTPAGE_LO15 313 +#endif /* R_AARCH64_LD64_GOTPAGE_LO15 */ +#ifndef R_AARCH64_TLSGD_ADR_PREL21 +#define R_AARCH64_TLSGD_ADR_PREL21 512 +#endif /* R_AARCH64_TLSGD_ADR_PREL21 */ +#ifndef R_AARCH64_TLSGD_ADR_PAGE21 +#define R_AARCH64_TLSGD_ADR_PAGE21 513 +#endif /* R_AARCH64_TLSGD_ADR_PAGE21 */ +#ifndef R_AARCH64_TLSGD_ADD_LO12_NC +#define R_AARCH64_TLSGD_ADD_LO12_NC 514 +#endif /* R_AARCH64_TLSGD_ADD_LO12_NC */ +#ifndef R_AARCH64_TLSGD_MOVW_G1 +#define R_AARCH64_TLSGD_MOVW_G1 515 +#endif /* R_AARCH64_TLSGD_MOVW_G1 */ +#ifndef R_AARCH64_TLSGD_MOVW_G0_NC +#define R_AARCH64_TLSGD_MOVW_G0_NC 516 +#endif /* R_AARCH64_TLSGD_MOVW_G0_NC */ +#ifndef R_AARCH64_TLSLD_ADR_PREL21 +#define R_AARCH64_TLSLD_ADR_PREL21 517 +#endif /* R_AARCH64_TLSLD_ADR_PREL21 */ +#ifndef R_AARCH64_TLSLD_ADR_PAGE21 +#define R_AARCH64_TLSLD_ADR_PAGE21 518 +#endif /* R_AARCH64_TLSLD_ADR_PAGE21 */ +#ifndef R_AARCH64_TLSLD_ADD_LO12_NC +#define R_AARCH64_TLSLD_ADD_LO12_NC 519 +#endif /* R_AARCH64_TLSLD_ADD_LO12_NC */ +#ifndef R_AARCH64_TLSLD_MOVW_G1 +#define R_AARCH64_TLSLD_MOVW_G1 520 +#endif /* R_AARCH64_TLSLD_MOVW_G1 */ +#ifndef R_AARCH64_TLSLD_MOVW_G0_NC +#define R_AARCH64_TLSLD_MOVW_G0_NC 521 +#endif /* R_AARCH64_TLSLD_MOVW_G0_NC */ +#ifndef R_AARCH64_TLSLD_LD_PREL19 +#define R_AARCH64_TLSLD_LD_PREL19 522 +#endif /* R_AARCH64_TLSLD_LD_PREL19 */ +#ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G2 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 +#endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G2 */ +#ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G1 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 +#endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G1 */ +#ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC +#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 +#endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC */ +#ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G0 +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 +#endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G0 */ +#ifndef R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC +#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 +#endif /* R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC */ +#ifndef R_AARCH64_TLSLD_ADD_DTPREL_HI12 +#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 +#endif /* R_AARCH64_TLSLD_ADD_DTPREL_HI12 */ +#ifndef R_AARCH64_TLSLD_ADD_DTPREL_LO12 +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 +#endif /* R_AARCH64_TLSLD_ADD_DTPREL_LO12 */ +#ifndef R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC +#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 +#endif /* R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLD_LDST8_DTPREL_LO12 +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 +#endif /* R_AARCH64_TLSLD_LDST8_DTPREL_LO12 */ +#ifndef R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC +#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 +#endif /* R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLD_LDST16_DTPREL_LO12 +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 +#endif /* R_AARCH64_TLSLD_LDST16_DTPREL_LO12 */ +#ifndef R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC +#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 +#endif /* R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLD_LDST32_DTPREL_LO12 +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 +#endif /* R_AARCH64_TLSLD_LDST32_DTPREL_LO12 */ +#ifndef R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC +#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 +#endif /* R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLD_LDST64_DTPREL_LO12 +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 +#endif /* R_AARCH64_TLSLD_LDST64_DTPREL_LO12 */ +#ifndef R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC +#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 +#endif /* R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC */ +#ifndef R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 +#endif /* R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 */ +#ifndef R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC +#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 +#endif /* R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC */ +#ifndef R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 +#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 +#endif /* R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 */ +#ifndef R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC +#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 +#endif /* R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC */ +#ifndef R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 +#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 +#endif /* R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 */ +#ifndef R_AARCH64_TLSLE_MOVW_TPREL_G2 +#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 +#endif /* R_AARCH64_TLSLE_MOVW_TPREL_G2 */ +#ifndef R_AARCH64_TLSLE_MOVW_TPREL_G1 +#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 +#endif /* R_AARCH64_TLSLE_MOVW_TPREL_G1 */ +#ifndef R_AARCH64_TLSLE_MOVW_TPREL_G1_NC +#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 +#endif /* R_AARCH64_TLSLE_MOVW_TPREL_G1_NC */ +#ifndef R_AARCH64_TLSLE_MOVW_TPREL_G0 +#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 +#endif /* R_AARCH64_TLSLE_MOVW_TPREL_G0 */ +#ifndef R_AARCH64_TLSLE_MOVW_TPREL_G0_NC +#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 +#endif /* R_AARCH64_TLSLE_MOVW_TPREL_G0_NC */ +#ifndef R_AARCH64_TLSLE_ADD_TPREL_HI12 +#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 +#endif /* R_AARCH64_TLSLE_ADD_TPREL_HI12 */ +#ifndef R_AARCH64_TLSLE_ADD_TPREL_LO12 +#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 +#endif /* R_AARCH64_TLSLE_ADD_TPREL_LO12 */ +#ifndef R_AARCH64_TLSLE_ADD_TPREL_LO12_NC +#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 +#endif /* R_AARCH64_TLSLE_ADD_TPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLE_LDST8_TPREL_LO12 +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 +#endif /* R_AARCH64_TLSLE_LDST8_TPREL_LO12 */ +#ifndef R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC +#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 +#endif /* R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLE_LDST16_TPREL_LO12 +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 +#endif /* R_AARCH64_TLSLE_LDST16_TPREL_LO12 */ +#ifndef R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC +#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 +#endif /* R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLE_LDST32_TPREL_LO12 +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 +#endif /* R_AARCH64_TLSLE_LDST32_TPREL_LO12 */ +#ifndef R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC +#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 +#endif /* R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLE_LDST64_TPREL_LO12 +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 +#endif /* R_AARCH64_TLSLE_LDST64_TPREL_LO12 */ +#ifndef R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC +#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 +#endif /* R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC */ +#ifndef R_AARCH64_TLSDESC_LD_PREL19 +#define R_AARCH64_TLSDESC_LD_PREL19 560 +#endif /* R_AARCH64_TLSDESC_LD_PREL19 */ +#ifndef R_AARCH64_TLSDESC_ADR_PREL21 +#define R_AARCH64_TLSDESC_ADR_PREL21 561 +#endif /* R_AARCH64_TLSDESC_ADR_PREL21 */ +#ifndef R_AARCH64_TLSDESC_ADR_PAGE21 +#define R_AARCH64_TLSDESC_ADR_PAGE21 562 +#endif /* R_AARCH64_TLSDESC_ADR_PAGE21 */ +#ifndef R_AARCH64_TLSDESC_LD64_LO12 +#define R_AARCH64_TLSDESC_LD64_LO12 563 +#endif /* R_AARCH64_TLSDESC_LD64_LO12 */ +#ifndef R_AARCH64_TLSDESC_ADD_LO12 +#define R_AARCH64_TLSDESC_ADD_LO12 564 +#endif /* R_AARCH64_TLSDESC_ADD_LO12 */ +#ifndef R_AARCH64_TLSDESC_OFF_G1 +#define R_AARCH64_TLSDESC_OFF_G1 565 +#endif /* R_AARCH64_TLSDESC_OFF_G1 */ +#ifndef R_AARCH64_TLSDESC_OFF_G0_NC +#define R_AARCH64_TLSDESC_OFF_G0_NC 566 +#endif /* R_AARCH64_TLSDESC_OFF_G0_NC */ +#ifndef R_AARCH64_TLSDESC_LDR +#define R_AARCH64_TLSDESC_LDR 567 +#endif /* R_AARCH64_TLSDESC_LDR */ +#ifndef R_AARCH64_TLSDESC_ADD +#define R_AARCH64_TLSDESC_ADD 568 +#endif /* R_AARCH64_TLSDESC_ADD */ +#ifndef R_AARCH64_TLSDESC_CALL +#define R_AARCH64_TLSDESC_CALL 569 +#endif /* R_AARCH64_TLSDESC_CALL */ +#ifndef R_AARCH64_TLSLE_LDST128_TPREL_LO12 +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 +#endif /* R_AARCH64_TLSLE_LDST128_TPREL_LO12 */ +#ifndef R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC +#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 +#endif /* R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC */ +#ifndef R_AARCH64_TLSLD_LDST128_DTPREL_LO12 +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 +#endif /* R_AARCH64_TLSLD_LDST128_DTPREL_LO12 */ +#ifndef R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC +#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 +#endif /* R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC */ +#ifndef R_AARCH64_COPY +#define R_AARCH64_COPY 1024 +#endif /* R_AARCH64_COPY */ +#ifndef R_AARCH64_GLOB_DAT +#define R_AARCH64_GLOB_DAT 1025 +#endif /* R_AARCH64_GLOB_DAT */ +#ifndef R_AARCH64_JUMP_SLOT +#define R_AARCH64_JUMP_SLOT 1026 +#endif /* R_AARCH64_JUMP_SLOT */ +#ifndef R_AARCH64_RELATIVE +#define R_AARCH64_RELATIVE 1027 +#endif /* R_AARCH64_RELATIVE */ +#ifndef R_AARCH64_TLS_DTPMOD +#define R_AARCH64_TLS_DTPMOD 1028 +#endif /* R_AARCH64_TLS_DTPMOD */ +#ifndef R_AARCH64_TLS_DTPREL +#define R_AARCH64_TLS_DTPREL 1029 +#endif /* R_AARCH64_TLS_DTPREL */ +#ifndef R_AARCH64_TLS_TPREL +#define R_AARCH64_TLS_TPREL 1030 +#endif /* R_AARCH64_TLS_TPREL */ +#ifndef R_AARCH64_TLSDESC +#define R_AARCH64_TLSDESC 1031 +#endif /* R_AARCH64_TLSDESC */ +#ifndef R_AARCH64_IRELATIVE +#define R_AARCH64_IRELATIVE 1032 +#endif /* R_AARCH64_IRELATIVE */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_arm.h b/thirdparty/dwarf/dwarf_elf_reloc_arm.h new file mode 100644 index 00000000..2271d285 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_arm.h @@ -0,0 +1,378 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_arm(unsigned long); +#ifndef R_ARM_NONE +#define R_ARM_NONE 0 +#endif /* R_ARM_NONE */ +#ifndef R_ARM_PC24 +#define R_ARM_PC24 1 +#endif /* R_ARM_PC24 */ +#ifndef R_ARM_ABS32 +#define R_ARM_ABS32 2 +#endif /* R_ARM_ABS32 */ +#ifndef R_ARM_REL32 +#define R_ARM_REL32 3 +#endif /* R_ARM_REL32 */ +#ifndef R_ARM_LDR_PC_G0 +#define R_ARM_LDR_PC_G0 4 +#endif /* R_ARM_LDR_PC_G0 */ +#ifndef R_ARM_ABS16 +#define R_ARM_ABS16 5 +#endif /* R_ARM_ABS16 */ +#ifndef R_ARM_ABS12 +#define R_ARM_ABS12 6 +#endif /* R_ARM_ABS12 */ +#ifndef R_ARM_THM_ABS5 +#define R_ARM_THM_ABS5 7 +#endif /* R_ARM_THM_ABS5 */ +#ifndef R_ARM_ABS8 +#define R_ARM_ABS8 8 +#endif /* R_ARM_ABS8 */ +#ifndef R_ARM_SBREL32 +#define R_ARM_SBREL32 9 +#endif /* R_ARM_SBREL32 */ +#ifndef R_ARM_THM_CALL +#define R_ARM_THM_CALL 10 +#endif /* R_ARM_THM_CALL */ +#ifndef R_ARM_THM_PC8 +#define R_ARM_THM_PC8 11 +#endif /* R_ARM_THM_PC8 */ +#ifndef R_ARM_BREL_ADJ +#define R_ARM_BREL_ADJ 12 +#endif /* R_ARM_BREL_ADJ */ +#ifndef R_ARM_TLS_DESC +#define R_ARM_TLS_DESC 13 +#endif /* R_ARM_TLS_DESC */ +#ifndef R_ARM_THM_SWI8 +#define R_ARM_THM_SWI8 14 +#endif /* R_ARM_THM_SWI8 */ +#ifndef R_ARM_XPC25 +#define R_ARM_XPC25 15 +#endif /* R_ARM_XPC25 */ +#ifndef R_ARM_THM_XPC22 +#define R_ARM_THM_XPC22 16 +#endif /* R_ARM_THM_XPC22 */ +#ifndef R_ARM_TLS_DTPMOD32 +#define R_ARM_TLS_DTPMOD32 17 +#endif /* R_ARM_TLS_DTPMOD32 */ +#ifndef R_ARM_TLS_DTPOFF32 +#define R_ARM_TLS_DTPOFF32 18 +#endif /* R_ARM_TLS_DTPOFF32 */ +#ifndef R_ARM_TLS_TPOFF32 +#define R_ARM_TLS_TPOFF32 19 +#endif /* R_ARM_TLS_TPOFF32 */ +#ifndef R_ARM_COPY +#define R_ARM_COPY 20 +#endif /* R_ARM_COPY */ +#ifndef R_ARM_GLOB_DAT +#define R_ARM_GLOB_DAT 21 +#endif /* R_ARM_GLOB_DAT */ +#ifndef R_ARM_JUMP_SLOT +#define R_ARM_JUMP_SLOT 22 +#endif /* R_ARM_JUMP_SLOT */ +#ifndef R_ARM_RELATIVE +#define R_ARM_RELATIVE 23 +#endif /* R_ARM_RELATIVE */ +#ifndef R_ARM_GOTOFF32 +#define R_ARM_GOTOFF32 24 +#endif /* R_ARM_GOTOFF32 */ +#ifndef R_ARM_BASE_PREL +#define R_ARM_BASE_PREL 25 +#endif /* R_ARM_BASE_PREL */ +#ifndef R_ARM_GOT_BREL +#define R_ARM_GOT_BREL 26 +#endif /* R_ARM_GOT_BREL */ +#ifndef R_ARM_PLT32 +#define R_ARM_PLT32 27 +#endif /* R_ARM_PLT32 */ +#ifndef R_ARM_CALL +#define R_ARM_CALL 28 +#endif /* R_ARM_CALL */ +#ifndef R_ARM_JUMP24 +#define R_ARM_JUMP24 29 +#endif /* R_ARM_JUMP24 */ +#ifndef R_ARM_THM_JUMP24 +#define R_ARM_THM_JUMP24 30 +#endif /* R_ARM_THM_JUMP24 */ +#ifndef R_ARM_BASE_ABS +#define R_ARM_BASE_ABS 31 +#endif /* R_ARM_BASE_ABS */ +#ifndef R_ARM_ALU_PCREL_7_0 +#define R_ARM_ALU_PCREL_7_0 32 +#endif /* R_ARM_ALU_PCREL_7_0 */ +#ifndef R_ARM_ALU_PCREL_15_8 +#define R_ARM_ALU_PCREL_15_8 33 +#endif /* R_ARM_ALU_PCREL_15_8 */ +#ifndef R_ARM_ALU_PCREL_23_15 +#define R_ARM_ALU_PCREL_23_15 34 +#endif /* R_ARM_ALU_PCREL_23_15 */ +#ifndef R_ARM_LDR_SBREL_11_0_NC +#define R_ARM_LDR_SBREL_11_0_NC 35 +#endif /* R_ARM_LDR_SBREL_11_0_NC */ +#ifndef R_ARM_ALU_SBREL_19_12_NC +#define R_ARM_ALU_SBREL_19_12_NC 36 +#endif /* R_ARM_ALU_SBREL_19_12_NC */ +#ifndef R_ARM_ALU_SBREL_27_20_CK +#define R_ARM_ALU_SBREL_27_20_CK 37 +#endif /* R_ARM_ALU_SBREL_27_20_CK */ +#ifndef R_ARM_TARGET1 +#define R_ARM_TARGET1 38 +#endif /* R_ARM_TARGET1 */ +#ifndef R_ARM_SBREL31 +#define R_ARM_SBREL31 39 +#endif /* R_ARM_SBREL31 */ +#ifndef R_ARM_V4BX +#define R_ARM_V4BX 40 +#endif /* R_ARM_V4BX */ +#ifndef R_ARM_TARGET2 +#define R_ARM_TARGET2 41 +#endif /* R_ARM_TARGET2 */ +#ifndef R_ARM_PREL31 +#define R_ARM_PREL31 42 +#endif /* R_ARM_PREL31 */ +#ifndef R_ARM_MOVW_ABS_NC +#define R_ARM_MOVW_ABS_NC 43 +#endif /* R_ARM_MOVW_ABS_NC */ +#ifndef R_ARM_MOVT_ABS +#define R_ARM_MOVT_ABS 44 +#endif /* R_ARM_MOVT_ABS */ +#ifndef R_ARM_MOVW_PREL_NC +#define R_ARM_MOVW_PREL_NC 45 +#endif /* R_ARM_MOVW_PREL_NC */ +#ifndef R_ARM_MOVT_PREL +#define R_ARM_MOVT_PREL 46 +#endif /* R_ARM_MOVT_PREL */ +#ifndef R_ARM_THM_MOVW_ABS_NC +#define R_ARM_THM_MOVW_ABS_NC 47 +#endif /* R_ARM_THM_MOVW_ABS_NC */ +#ifndef R_ARM_THM_MOVT_ABS +#define R_ARM_THM_MOVT_ABS 48 +#endif /* R_ARM_THM_MOVT_ABS */ +#ifndef R_ARM_THM_MOVW_PREL_NC +#define R_ARM_THM_MOVW_PREL_NC 49 +#endif /* R_ARM_THM_MOVW_PREL_NC */ +#ifndef R_ARM_THM_MOVT_PREL +#define R_ARM_THM_MOVT_PREL 50 +#endif /* R_ARM_THM_MOVT_PREL */ +#ifndef R_ARM_THM_JUMP19 +#define R_ARM_THM_JUMP19 51 +#endif /* R_ARM_THM_JUMP19 */ +#ifndef R_ARM_THM_JUMP6 +#define R_ARM_THM_JUMP6 52 +#endif /* R_ARM_THM_JUMP6 */ +#ifndef R_ARM_THM_ALU_PREL_11_0 +#define R_ARM_THM_ALU_PREL_11_0 53 +#endif /* R_ARM_THM_ALU_PREL_11_0 */ +#ifndef R_ARM_THM_PC12 +#define R_ARM_THM_PC12 54 +#endif /* R_ARM_THM_PC12 */ +#ifndef R_ARM_ABS32_NOI +#define R_ARM_ABS32_NOI 55 +#endif /* R_ARM_ABS32_NOI */ +#ifndef R_ARM_REL32_NOI +#define R_ARM_REL32_NOI 56 +#endif /* R_ARM_REL32_NOI */ +#ifndef R_ARM_ALU_PC_G0_NC +#define R_ARM_ALU_PC_G0_NC 57 +#endif /* R_ARM_ALU_PC_G0_NC */ +#ifndef R_ARM_ALU_PC_G0 +#define R_ARM_ALU_PC_G0 58 +#endif /* R_ARM_ALU_PC_G0 */ +#ifndef R_ARM_ALU_PC_G1_NC +#define R_ARM_ALU_PC_G1_NC 59 +#endif /* R_ARM_ALU_PC_G1_NC */ +#ifndef R_ARM_ALU_PC_G1 +#define R_ARM_ALU_PC_G1 60 +#endif /* R_ARM_ALU_PC_G1 */ +#ifndef R_ARM_ALU_PC_G2 +#define R_ARM_ALU_PC_G2 61 +#endif /* R_ARM_ALU_PC_G2 */ +#ifndef R_ARM_LDR_PC_G1 +#define R_ARM_LDR_PC_G1 62 +#endif /* R_ARM_LDR_PC_G1 */ +#ifndef R_ARM_LDR_PC_G2 +#define R_ARM_LDR_PC_G2 63 +#endif /* R_ARM_LDR_PC_G2 */ +#ifndef R_ARM_LDRS_PC_G0 +#define R_ARM_LDRS_PC_G0 64 +#endif /* R_ARM_LDRS_PC_G0 */ +#ifndef R_ARM_LDRS_PC_G1 +#define R_ARM_LDRS_PC_G1 65 +#endif /* R_ARM_LDRS_PC_G1 */ +#ifndef R_ARM_LDRS_PC_G2 +#define R_ARM_LDRS_PC_G2 66 +#endif /* R_ARM_LDRS_PC_G2 */ +#ifndef R_ARM_LDC_PC_G0 +#define R_ARM_LDC_PC_G0 67 +#endif /* R_ARM_LDC_PC_G0 */ +#ifndef R_ARM_LDC_PC_G1 +#define R_ARM_LDC_PC_G1 68 +#endif /* R_ARM_LDC_PC_G1 */ +#ifndef R_ARM_LDC_PC_G2 +#define R_ARM_LDC_PC_G2 69 +#endif /* R_ARM_LDC_PC_G2 */ +#ifndef R_ARM_ALU_SB_G0_NC +#define R_ARM_ALU_SB_G0_NC 70 +#endif /* R_ARM_ALU_SB_G0_NC */ +#ifndef R_ARM_ALU_SB_G0 +#define R_ARM_ALU_SB_G0 71 +#endif /* R_ARM_ALU_SB_G0 */ +#ifndef R_ARM_ALU_SB_G1_NC +#define R_ARM_ALU_SB_G1_NC 72 +#endif /* R_ARM_ALU_SB_G1_NC */ +#ifndef R_ARM_ALU_SB_G1 +#define R_ARM_ALU_SB_G1 73 +#endif /* R_ARM_ALU_SB_G1 */ +#ifndef R_ARM_ALU_SB_G2 +#define R_ARM_ALU_SB_G2 74 +#endif /* R_ARM_ALU_SB_G2 */ +#ifndef R_ARM_LDR_SB_G0 +#define R_ARM_LDR_SB_G0 75 +#endif /* R_ARM_LDR_SB_G0 */ +#ifndef R_ARM_LDR_SB_G1 +#define R_ARM_LDR_SB_G1 76 +#endif /* R_ARM_LDR_SB_G1 */ +#ifndef R_ARM_LDR_SB_G2 +#define R_ARM_LDR_SB_G2 77 +#endif /* R_ARM_LDR_SB_G2 */ +#ifndef R_ARM_LDRS_SB_G0 +#define R_ARM_LDRS_SB_G0 78 +#endif /* R_ARM_LDRS_SB_G0 */ +#ifndef R_ARM_LDRS_SB_G1 +#define R_ARM_LDRS_SB_G1 79 +#endif /* R_ARM_LDRS_SB_G1 */ +#ifndef R_ARM_LDRS_SB_G2 +#define R_ARM_LDRS_SB_G2 80 +#endif /* R_ARM_LDRS_SB_G2 */ +#ifndef R_ARM_LDC_SB_G0 +#define R_ARM_LDC_SB_G0 81 +#endif /* R_ARM_LDC_SB_G0 */ +#ifndef R_ARM_LDC_SB_G1 +#define R_ARM_LDC_SB_G1 82 +#endif /* R_ARM_LDC_SB_G1 */ +#ifndef R_ARM_LDC_SB_G2 +#define R_ARM_LDC_SB_G2 83 +#endif /* R_ARM_LDC_SB_G2 */ +#ifndef R_ARM_MOVW_BREL_NC +#define R_ARM_MOVW_BREL_NC 84 +#endif /* R_ARM_MOVW_BREL_NC */ +#ifndef R_ARM_MOVT_BREL +#define R_ARM_MOVT_BREL 85 +#endif /* R_ARM_MOVT_BREL */ +#ifndef R_ARM_MOVW_BREL +#define R_ARM_MOVW_BREL 86 +#endif /* R_ARM_MOVW_BREL */ +#ifndef R_ARM_THM_MOVW_BREL_NC +#define R_ARM_THM_MOVW_BREL_NC 87 +#endif /* R_ARM_THM_MOVW_BREL_NC */ +#ifndef R_ARM_THM_MOVT_BREL +#define R_ARM_THM_MOVT_BREL 88 +#endif /* R_ARM_THM_MOVT_BREL */ +#ifndef R_ARM_THM_MOVW_BREL +#define R_ARM_THM_MOVW_BREL 89 +#endif /* R_ARM_THM_MOVW_BREL */ +#ifndef R_ARM_TLS_GOTDESC +#define R_ARM_TLS_GOTDESC 90 +#endif /* R_ARM_TLS_GOTDESC */ +#ifndef R_ARM_TLS_CALL +#define R_ARM_TLS_CALL 91 +#endif /* R_ARM_TLS_CALL */ +#ifndef R_ARM_TLS_DESCSEQ +#define R_ARM_TLS_DESCSEQ 92 +#endif /* R_ARM_TLS_DESCSEQ */ +#ifndef R_ARM_THM_TLS_CALL +#define R_ARM_THM_TLS_CALL 93 +#endif /* R_ARM_THM_TLS_CALL */ +#ifndef R_ARM_PLT32_ABS +#define R_ARM_PLT32_ABS 94 +#endif /* R_ARM_PLT32_ABS */ +#ifndef R_ARM_GOT_ABS +#define R_ARM_GOT_ABS 95 +#endif /* R_ARM_GOT_ABS */ +#ifndef R_ARM_GOT_PREL +#define R_ARM_GOT_PREL 96 +#endif /* R_ARM_GOT_PREL */ +#ifndef R_ARM_GOT_BREL12 +#define R_ARM_GOT_BREL12 97 +#endif /* R_ARM_GOT_BREL12 */ +#ifndef R_ARM_GOTOFF12 +#define R_ARM_GOTOFF12 98 +#endif /* R_ARM_GOTOFF12 */ +#ifndef R_ARM_GOTRELAX +#define R_ARM_GOTRELAX 99 +#endif /* R_ARM_GOTRELAX */ +#ifndef R_ARM_GNU_VTENTRY +#define R_ARM_GNU_VTENTRY 100 +#endif /* R_ARM_GNU_VTENTRY */ +#ifndef R_ARM_GNU_VTINHERIT +#define R_ARM_GNU_VTINHERIT 101 +#endif /* R_ARM_GNU_VTINHERIT */ +#ifndef R_ARM_THM_JUMP11 +#define R_ARM_THM_JUMP11 102 +#endif /* R_ARM_THM_JUMP11 */ +#ifndef R_ARM_THM_JUMP8 +#define R_ARM_THM_JUMP8 103 +#endif /* R_ARM_THM_JUMP8 */ +#ifndef R_ARM_TLS_GD32 +#define R_ARM_TLS_GD32 104 +#endif /* R_ARM_TLS_GD32 */ +#ifndef R_ARM_TLS_LDM32 +#define R_ARM_TLS_LDM32 105 +#endif /* R_ARM_TLS_LDM32 */ +#ifndef R_ARM_TLS_LDO32 +#define R_ARM_TLS_LDO32 106 +#endif /* R_ARM_TLS_LDO32 */ +#ifndef R_ARM_TLS_IE32 +#define R_ARM_TLS_IE32 107 +#endif /* R_ARM_TLS_IE32 */ +#ifndef R_ARM_TLS_LE32 +#define R_ARM_TLS_LE32 108 +#endif /* R_ARM_TLS_LE32 */ +#ifndef R_ARM_TLS_LDO12 +#define R_ARM_TLS_LDO12 109 +#endif /* R_ARM_TLS_LDO12 */ +#ifndef R_ARM_TLS_LE12 +#define R_ARM_TLS_LE12 110 +#endif /* R_ARM_TLS_LE12 */ +#ifndef R_ARM_TLS_IE12GP +#define R_ARM_TLS_IE12GP 111 +#endif /* R_ARM_TLS_IE12GP */ +#ifndef R_ARM_ME_TOO +#define R_ARM_ME_TOO 128 +#endif /* R_ARM_ME_TOO */ +#ifndef R_ARM_THM_TLS_DESCSEQ16 +#define R_ARM_THM_TLS_DESCSEQ16 129 +#endif /* R_ARM_THM_TLS_DESCSEQ16 */ +#ifndef R_ARM_THM_TLS_DESCSEQ32 +#define R_ARM_THM_TLS_DESCSEQ32 130 +#endif /* R_ARM_THM_TLS_DESCSEQ32 */ +#ifndef R_ARM_RXPC25 +#define R_ARM_RXPC25 249 +#endif /* R_ARM_RXPC25 */ +#ifndef R_ARM_RSBREL32 +#define R_ARM_RSBREL32 250 +#endif /* R_ARM_RSBREL32 */ +#ifndef R_ARM_THM_RPC22 +#define R_ARM_THM_RPC22 251 +#endif /* R_ARM_THM_RPC22 */ +#ifndef R_ARM_RREL32 +#define R_ARM_RREL32 252 +#endif /* R_ARM_RREL32 */ +#ifndef R_ARM_RABS32 +#define R_ARM_RABS32 253 +#endif /* R_ARM_RABS32 */ +#ifndef R_ARM_RPC24 +#define R_ARM_RPC24 254 +#endif /* R_ARM_RPC24 */ +#ifndef R_ARM_RBASE +#define R_ARM_RBASE 255 +#endif /* R_ARM_RBASE */ +#ifndef R_ARM_NUM +#define R_ARM_NUM 256 +#endif /* R_ARM_NUM */ +#ifndef R_AARCH64_ABS64 +#define R_AARCH64_ABS64 0x101 +#endif /* R_AARCH64_ABS64 */ +#ifndef R_AARCH64_ABS32 +#define R_AARCH64_ABS32 0x102 +#endif /* R_AARCH64_ABS32 */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_mips.h b/thirdparty/dwarf/dwarf_elf_reloc_mips.h new file mode 100644 index 00000000..06ecb584 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_mips.h @@ -0,0 +1,165 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_mips(unsigned long); +#ifndef R_MIPS_NONE +#define R_MIPS_NONE 0 +#endif /* R_MIPS_NONE */ +#ifndef R_MIPS_16 +#define R_MIPS_16 1 +#endif /* R_MIPS_16 */ +#ifndef R_MIPS_32 +#define R_MIPS_32 2 +#endif /* R_MIPS_32 */ +#ifndef R_MIPS_REL +#define R_MIPS_REL 3 +#endif /* R_MIPS_REL */ +#ifndef R_MIPS_26 +#define R_MIPS_26 4 +#endif /* R_MIPS_26 */ +#ifndef R_MIPS_HI16 +#define R_MIPS_HI16 5 +#endif /* R_MIPS_HI16 */ +#ifndef R_MIPS_LO16 +#define R_MIPS_LO16 6 +#endif /* R_MIPS_LO16 */ +#ifndef R_MIPS_GPREL +#define R_MIPS_GPREL 7 +#endif /* R_MIPS_GPREL */ +#ifndef R_MIPS_LITERAL +#define R_MIPS_LITERAL 8 +#endif /* R_MIPS_LITERAL */ +#ifndef R_MIPS_GOT +#define R_MIPS_GOT 9 +#endif /* R_MIPS_GOT */ +#ifndef R_MIPS_PC16 +#define R_MIPS_PC16 10 +#endif /* R_MIPS_PC16 */ +#ifndef R_MIPS_CALL +#define R_MIPS_CALL 11 +#endif /* R_MIPS_CALL */ +#ifndef R_MIPS_GPREL32 +#define R_MIPS_GPREL32 12 +#endif /* R_MIPS_GPREL32 */ +#ifndef R_MIPS_UNUSED1 +#define R_MIPS_UNUSED1 13 +#endif /* R_MIPS_UNUSED1 */ +#ifndef R_MIPS_UNUSED2 +#define R_MIPS_UNUSED2 14 +#endif /* R_MIPS_UNUSED2 */ +#ifndef R_MIPS_UNUSED3 +#define R_MIPS_UNUSED3 15 +#endif /* R_MIPS_UNUSED3 */ +#ifndef R_MIPS_SHIFT5 +#define R_MIPS_SHIFT5 16 +#endif /* R_MIPS_SHIFT5 */ +#ifndef R_MIPS_SHIFT6 +#define R_MIPS_SHIFT6 17 +#endif /* R_MIPS_SHIFT6 */ +#ifndef R_MIPS_64 +#define R_MIPS_64 18 +#endif /* R_MIPS_64 */ +#ifndef R_MIPS_GOT_DISP +#define R_MIPS_GOT_DISP 19 +#endif /* R_MIPS_GOT_DISP */ +#ifndef R_MIPS_GOT_PAGE +#define R_MIPS_GOT_PAGE 20 +#endif /* R_MIPS_GOT_PAGE */ +#ifndef R_MIPS_GOT_OFST +#define R_MIPS_GOT_OFST 21 +#endif /* R_MIPS_GOT_OFST */ +#ifndef R_MIPS_GOT_HI16 +#define R_MIPS_GOT_HI16 22 +#endif /* R_MIPS_GOT_HI16 */ +#ifndef R_MIPS_GOT_LO16 +#define R_MIPS_GOT_LO16 23 +#endif /* R_MIPS_GOT_LO16 */ +#ifndef R_MIPS_SUB +#define R_MIPS_SUB 24 +#endif /* R_MIPS_SUB */ +#ifndef R_MIPS_INSERT_A +#define R_MIPS_INSERT_A 25 +#endif /* R_MIPS_INSERT_A */ +#ifndef R_MIPS_INSERT_B +#define R_MIPS_INSERT_B 26 +#endif /* R_MIPS_INSERT_B */ +#ifndef R_MIPS_DELETE +#define R_MIPS_DELETE 27 +#endif /* R_MIPS_DELETE */ +#ifndef R_MIPS_HIGHER +#define R_MIPS_HIGHER 28 +#endif /* R_MIPS_HIGHER */ +#ifndef R_MIPS_HIGHEST +#define R_MIPS_HIGHEST 29 +#endif /* R_MIPS_HIGHEST */ +#ifndef R_MIPS_CALL_HI16 +#define R_MIPS_CALL_HI16 30 +#endif /* R_MIPS_CALL_HI16 */ +#ifndef R_MIPS_CALL_LO16 +#define R_MIPS_CALL_LO16 31 +#endif /* R_MIPS_CALL_LO16 */ +#ifndef R_MIPS_SCN_DISP +#define R_MIPS_SCN_DISP 32 +#endif /* R_MIPS_SCN_DISP */ +#ifndef R_MIPS_REL16 +#define R_MIPS_REL16 33 +#endif /* R_MIPS_REL16 */ +#ifndef R_MIPS_ADD_IMMEDIATE +#define R_MIPS_ADD_IMMEDIATE 34 +#endif /* R_MIPS_ADD_IMMEDIATE */ +#ifndef R_MIPS_PJUMP +#define R_MIPS_PJUMP 35 +#endif /* R_MIPS_PJUMP */ +#ifndef R_MIPS_RELGOT +#define R_MIPS_RELGOT 36 +#endif /* R_MIPS_RELGOT */ +#ifndef R_MIPS_JALR +#define R_MIPS_JALR 37 +#endif /* R_MIPS_JALR */ +#ifndef R_MIPS_TLS_DTPMOD32 +#define R_MIPS_TLS_DTPMOD32 38 +#endif /* R_MIPS_TLS_DTPMOD32 */ +#ifndef R_MIPS_TLS_DTPREL32 +#define R_MIPS_TLS_DTPREL32 39 +#endif /* R_MIPS_TLS_DTPREL32 */ +#ifndef R_MIPS_TLS_DTPMOD64 +#define R_MIPS_TLS_DTPMOD64 40 +#endif /* R_MIPS_TLS_DTPMOD64 */ +#ifndef R_MIPS_TLS_DTPREL64 +#define R_MIPS_TLS_DTPREL64 41 +#endif /* R_MIPS_TLS_DTPREL64 */ +#ifndef R_MIPS_TLS_GD +#define R_MIPS_TLS_GD 42 +#endif /* R_MIPS_TLS_GD */ +#ifndef R_MIPS_TLS_LDM +#define R_MIPS_TLS_LDM 43 +#endif /* R_MIPS_TLS_LDM */ +#ifndef R_MIPS_TLS_DTPREL_HI16 +#define R_MIPS_TLS_DTPREL_HI16 44 +#endif /* R_MIPS_TLS_DTPREL_HI16 */ +#ifndef R_MIPS_TLS_DTPREL_LO16 +#define R_MIPS_TLS_DTPREL_LO16 45 +#endif /* R_MIPS_TLS_DTPREL_LO16 */ +#ifndef R_MIPS_TLS_GOTTPREL +#define R_MIPS_TLS_GOTTPREL 46 +#endif /* R_MIPS_TLS_GOTTPREL */ +#ifndef R_MIPS_TLS_TPREL32 +#define R_MIPS_TLS_TPREL32 47 +#endif /* R_MIPS_TLS_TPREL32 */ +#ifndef R_MIPS_TLS_TPREL_HI16 +#define R_MIPS_TLS_TPREL_HI16 49 +#endif /* R_MIPS_TLS_TPREL_HI16 */ +#ifndef R_MIPS_TLS_TPREL_LO16 +#define R_MIPS_TLS_TPREL_LO16 50 +#endif /* R_MIPS_TLS_TPREL_LO16 */ +#ifndef R_MIPS_GLOB_DAT +#define R_MIPS_GLOB_DAT 51 +#endif /* R_MIPS_GLOB_DAT */ +#ifndef R_MIPS_COPY +#define R_MIPS_COPY 126 +#endif /* R_MIPS_COPY */ +#ifndef R_MIPS_JUMP_SLOT +#define R_MIPS_JUMP_SLOT 127 +#endif /* R_MIPS_JUMP_SLOT */ +#ifndef R_MIPS_NUM +#define R_MIPS_NUM 128 +#endif /* R_MIPS_NUM */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_ppc.h b/thirdparty/dwarf/dwarf_elf_reloc_ppc.h new file mode 100644 index 00000000..f290234f --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_ppc.h @@ -0,0 +1,375 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_ppc(unsigned long); +#ifndef R_PPC_NONE +#define R_PPC_NONE 0 +#endif /* R_PPC_NONE */ +#ifndef R_PPC_ADDR32 +#define R_PPC_ADDR32 1 +#endif /* R_PPC_ADDR32 */ +#ifndef R_PPC_ADDR24 +#define R_PPC_ADDR24 2 +#endif /* R_PPC_ADDR24 */ +#ifndef R_PPC_ADDR16 +#define R_PPC_ADDR16 3 +#endif /* R_PPC_ADDR16 */ +#ifndef R_PPC_ADDR16_LO +#define R_PPC_ADDR16_LO 4 +#endif /* R_PPC_ADDR16_LO */ +#ifndef R_PPC_ADDR16_HI +#define R_PPC_ADDR16_HI 5 +#endif /* R_PPC_ADDR16_HI */ +#ifndef R_PPC_ADDR16_HA +#define R_PPC_ADDR16_HA 6 +#endif /* R_PPC_ADDR16_HA */ +#ifndef R_PPC_ADDR14 +#define R_PPC_ADDR14 7 +#endif /* R_PPC_ADDR14 */ +#ifndef R_PPC_ADDR14_BRTAKEN +#define R_PPC_ADDR14_BRTAKEN 8 +#endif /* R_PPC_ADDR14_BRTAKEN */ +#ifndef R_PPC_ADDR14_BRNTAKEN +#define R_PPC_ADDR14_BRNTAKEN 9 +#endif /* R_PPC_ADDR14_BRNTAKEN */ +#ifndef R_PPC_REL24 +#define R_PPC_REL24 10 +#endif /* R_PPC_REL24 */ +#ifndef R_PPC_REL14 +#define R_PPC_REL14 11 +#endif /* R_PPC_REL14 */ +#ifndef R_PPC_REL14_BRTAKEN +#define R_PPC_REL14_BRTAKEN 12 +#endif /* R_PPC_REL14_BRTAKEN */ +#ifndef R_PPC_REL14_BRNTAKEN +#define R_PPC_REL14_BRNTAKEN 13 +#endif /* R_PPC_REL14_BRNTAKEN */ +#ifndef R_PPC_GOT16 +#define R_PPC_GOT16 14 +#endif /* R_PPC_GOT16 */ +#ifndef R_PPC_GOT16_LO +#define R_PPC_GOT16_LO 15 +#endif /* R_PPC_GOT16_LO */ +#ifndef R_PPC_GOT16_HI +#define R_PPC_GOT16_HI 16 +#endif /* R_PPC_GOT16_HI */ +#ifndef R_PPC_GOT16_HA +#define R_PPC_GOT16_HA 17 +#endif /* R_PPC_GOT16_HA */ +#ifndef R_PPC_PLTREL24 +#define R_PPC_PLTREL24 18 +#endif /* R_PPC_PLTREL24 */ +#ifndef R_PPC_COPY +#define R_PPC_COPY 19 +#endif /* R_PPC_COPY */ +#ifndef R_PPC_GLOB_DAT +#define R_PPC_GLOB_DAT 20 +#endif /* R_PPC_GLOB_DAT */ +#ifndef R_PPC_JMP_SLOT +#define R_PPC_JMP_SLOT 21 +#endif /* R_PPC_JMP_SLOT */ +#ifndef R_PPC_RELATIVE +#define R_PPC_RELATIVE 22 +#endif /* R_PPC_RELATIVE */ +#ifndef R_PPC_LOCAL24PC +#define R_PPC_LOCAL24PC 23 +#endif /* R_PPC_LOCAL24PC */ +#ifndef R_PPC_UADDR32 +#define R_PPC_UADDR32 24 +#endif /* R_PPC_UADDR32 */ +#ifndef R_PPC_UADDR16 +#define R_PPC_UADDR16 25 +#endif /* R_PPC_UADDR16 */ +#ifndef R_PPC_REL32 +#define R_PPC_REL32 26 +#endif /* R_PPC_REL32 */ +#ifndef R_PPC_PLT32 +#define R_PPC_PLT32 27 +#endif /* R_PPC_PLT32 */ +#ifndef R_PPC_PLTREL32 +#define R_PPC_PLTREL32 28 +#endif /* R_PPC_PLTREL32 */ +#ifndef R_PPC_PLT16_LO +#define R_PPC_PLT16_LO 29 +#endif /* R_PPC_PLT16_LO */ +#ifndef R_PPC_PLT16_HI +#define R_PPC_PLT16_HI 30 +#endif /* R_PPC_PLT16_HI */ +#ifndef R_PPC_PLT16_HA +#define R_PPC_PLT16_HA 31 +#endif /* R_PPC_PLT16_HA */ +#ifndef R_PPC_SDAREL16 +#define R_PPC_SDAREL16 32 +#endif /* R_PPC_SDAREL16 */ +#ifndef R_PPC_SECTOFF +#define R_PPC_SECTOFF 33 +#endif /* R_PPC_SECTOFF */ +#ifndef R_PPC_SECTOFF_LO +#define R_PPC_SECTOFF_LO 34 +#endif /* R_PPC_SECTOFF_LO */ +#ifndef R_PPC_SECTOFF_HI +#define R_PPC_SECTOFF_HI 35 +#endif /* R_PPC_SECTOFF_HI */ +#ifndef R_PPC_SECTOFF_HA +#define R_PPC_SECTOFF_HA 36 +#endif /* R_PPC_SECTOFF_HA */ +#ifndef R_PPC_37 +#define R_PPC_37 37 +#endif /* R_PPC_37 */ +#ifndef R_PPC_38 +#define R_PPC_38 38 +#endif /* R_PPC_38 */ +#ifndef R_PPC_39 +#define R_PPC_39 39 +#endif /* R_PPC_39 */ +#ifndef R_PPC_40 +#define R_PPC_40 40 +#endif /* R_PPC_40 */ +#ifndef R_PPC_41 +#define R_PPC_41 41 +#endif /* R_PPC_41 */ +#ifndef R_PPC_42 +#define R_PPC_42 42 +#endif /* R_PPC_42 */ +#ifndef R_PPC_43 +#define R_PPC_43 43 +#endif /* R_PPC_43 */ +#ifndef R_PPC_44 +#define R_PPC_44 44 +#endif /* R_PPC_44 */ +#ifndef R_PPC_45 +#define R_PPC_45 45 +#endif /* R_PPC_45 */ +#ifndef R_PPC_46 +#define R_PPC_46 46 +#endif /* R_PPC_46 */ +#ifndef R_PPC_47 +#define R_PPC_47 47 +#endif /* R_PPC_47 */ +#ifndef R_PPC_48 +#define R_PPC_48 48 +#endif /* R_PPC_48 */ +#ifndef R_PPC_49 +#define R_PPC_49 49 +#endif /* R_PPC_49 */ +#ifndef R_PPC_50 +#define R_PPC_50 50 +#endif /* R_PPC_50 */ +#ifndef R_PPC_51 +#define R_PPC_51 51 +#endif /* R_PPC_51 */ +#ifndef R_PPC_52 +#define R_PPC_52 52 +#endif /* R_PPC_52 */ +#ifndef R_PPC_53 +#define R_PPC_53 53 +#endif /* R_PPC_53 */ +#ifndef R_PPC_54 +#define R_PPC_54 54 +#endif /* R_PPC_54 */ +#ifndef R_PPC_55 +#define R_PPC_55 55 +#endif /* R_PPC_55 */ +#ifndef R_PPC_56 +#define R_PPC_56 56 +#endif /* R_PPC_56 */ +#ifndef R_PPC_57 +#define R_PPC_57 57 +#endif /* R_PPC_57 */ +#ifndef R_PPC_58 +#define R_PPC_58 58 +#endif /* R_PPC_58 */ +#ifndef R_PPC_59 +#define R_PPC_59 59 +#endif /* R_PPC_59 */ +#ifndef R_PPC_60 +#define R_PPC_60 60 +#endif /* R_PPC_60 */ +#ifndef R_PPC_61 +#define R_PPC_61 61 +#endif /* R_PPC_61 */ +#ifndef R_PPC_62 +#define R_PPC_62 62 +#endif /* R_PPC_62 */ +#ifndef R_PPC_63 +#define R_PPC_63 63 +#endif /* R_PPC_63 */ +#ifndef R_PPC_64 +#define R_PPC_64 64 +#endif /* R_PPC_64 */ +#ifndef R_PPC_65 +#define R_PPC_65 65 +#endif /* R_PPC_65 */ +#ifndef R_PPC_66 +#define R_PPC_66 66 +#endif /* R_PPC_66 */ +#ifndef R_PPC_TLS +#define R_PPC_TLS 67 +#endif /* R_PPC_TLS */ +#ifndef R_PPC_DTPMOD32 +#define R_PPC_DTPMOD32 68 +#endif /* R_PPC_DTPMOD32 */ +#ifndef R_PPC_TPREL16 +#define R_PPC_TPREL16 69 +#endif /* R_PPC_TPREL16 */ +#ifndef R_PPC_TPREL16_LO +#define R_PPC_TPREL16_LO 70 +#endif /* R_PPC_TPREL16_LO */ +#ifndef R_PPC_TPREL16_HI +#define R_PPC_TPREL16_HI 71 +#endif /* R_PPC_TPREL16_HI */ +#ifndef R_PPC_TPREL16_HA +#define R_PPC_TPREL16_HA 72 +#endif /* R_PPC_TPREL16_HA */ +#ifndef R_PPC_TPREL32 +#define R_PPC_TPREL32 73 +#endif /* R_PPC_TPREL32 */ +#ifndef R_PPC_DTPREL16 +#define R_PPC_DTPREL16 74 +#endif /* R_PPC_DTPREL16 */ +#ifndef R_PPC_DTPREL16_LO +#define R_PPC_DTPREL16_LO 75 +#endif /* R_PPC_DTPREL16_LO */ +#ifndef R_PPC_DTPREL16_HI +#define R_PPC_DTPREL16_HI 76 +#endif /* R_PPC_DTPREL16_HI */ +#ifndef R_PPC_DTPREL16_HA +#define R_PPC_DTPREL16_HA 77 +#endif /* R_PPC_DTPREL16_HA */ +#ifndef R_PPC_DTPREL32 +#define R_PPC_DTPREL32 78 +#endif /* R_PPC_DTPREL32 */ +#ifndef R_PPC_GOT_TLSGD16 +#define R_PPC_GOT_TLSGD16 79 +#endif /* R_PPC_GOT_TLSGD16 */ +#ifndef R_PPC_GOT_TLSGD16_LO +#define R_PPC_GOT_TLSGD16_LO 80 +#endif /* R_PPC_GOT_TLSGD16_LO */ +#ifndef R_PPC_GOT_TLSGD16_HI +#define R_PPC_GOT_TLSGD16_HI 81 +#endif /* R_PPC_GOT_TLSGD16_HI */ +#ifndef R_PPC_GOT_TLSGD16_HA +#define R_PPC_GOT_TLSGD16_HA 82 +#endif /* R_PPC_GOT_TLSGD16_HA */ +#ifndef R_PPC_GOT_TLSLD16 +#define R_PPC_GOT_TLSLD16 83 +#endif /* R_PPC_GOT_TLSLD16 */ +#ifndef R_PPC_GOT_TLSLD16_LO +#define R_PPC_GOT_TLSLD16_LO 84 +#endif /* R_PPC_GOT_TLSLD16_LO */ +#ifndef R_PPC_GOT_TLSLD16_HI +#define R_PPC_GOT_TLSLD16_HI 85 +#endif /* R_PPC_GOT_TLSLD16_HI */ +#ifndef R_PPC_GOT_TLSLD16_HA +#define R_PPC_GOT_TLSLD16_HA 86 +#endif /* R_PPC_GOT_TLSLD16_HA */ +#ifndef R_PPC_GOT_TPREL16 +#define R_PPC_GOT_TPREL16 87 +#endif /* R_PPC_GOT_TPREL16 */ +#ifndef R_PPC_GOT_TPREL16_LO +#define R_PPC_GOT_TPREL16_LO 88 +#endif /* R_PPC_GOT_TPREL16_LO */ +#ifndef R_PPC_GOT_TPREL16_HI +#define R_PPC_GOT_TPREL16_HI 89 +#endif /* R_PPC_GOT_TPREL16_HI */ +#ifndef R_PPC_GOT_TPREL16_HA +#define R_PPC_GOT_TPREL16_HA 90 +#endif /* R_PPC_GOT_TPREL16_HA */ +#ifndef R_PPC_GOT_DTPREL16 +#define R_PPC_GOT_DTPREL16 91 +#endif /* R_PPC_GOT_DTPREL16 */ +#ifndef R_PPC_GOT_DTPREL16_LO +#define R_PPC_GOT_DTPREL16_LO 92 +#endif /* R_PPC_GOT_DTPREL16_LO */ +#ifndef R_PPC_GOT_DTPREL16_HI +#define R_PPC_GOT_DTPREL16_HI 93 +#endif /* R_PPC_GOT_DTPREL16_HI */ +#ifndef R_PPC_GOT_DTPREL16_HA +#define R_PPC_GOT_DTPREL16_HA 94 +#endif /* R_PPC_GOT_DTPREL16_HA */ +#ifndef R_PPC_TLSGD +#define R_PPC_TLSGD 95 +#endif /* R_PPC_TLSGD */ +#ifndef R_PPC_TLSLD +#define R_PPC_TLSLD 96 +#endif /* R_PPC_TLSLD */ +#ifndef R_PPC_EMB_NADDR32 +#define R_PPC_EMB_NADDR32 101 +#endif /* R_PPC_EMB_NADDR32 */ +#ifndef R_PPC_EMB_NADDR16 +#define R_PPC_EMB_NADDR16 102 +#endif /* R_PPC_EMB_NADDR16 */ +#ifndef R_PPC_EMB_NADDR16_LO +#define R_PPC_EMB_NADDR16_LO 103 +#endif /* R_PPC_EMB_NADDR16_LO */ +#ifndef R_PPC_EMB_NADDR16_HI +#define R_PPC_EMB_NADDR16_HI 104 +#endif /* R_PPC_EMB_NADDR16_HI */ +#ifndef R_PPC_EMB_NADDR16_HA +#define R_PPC_EMB_NADDR16_HA 105 +#endif /* R_PPC_EMB_NADDR16_HA */ +#ifndef R_PPC_EMB_SDAI16 +#define R_PPC_EMB_SDAI16 106 +#endif /* R_PPC_EMB_SDAI16 */ +#ifndef R_PPC_EMB_SDA2I16 +#define R_PPC_EMB_SDA2I16 107 +#endif /* R_PPC_EMB_SDA2I16 */ +#ifndef R_PPC_EMB_SDA2REL +#define R_PPC_EMB_SDA2REL 108 +#endif /* R_PPC_EMB_SDA2REL */ +#ifndef R_PPC_EMB_SDA21 +#define R_PPC_EMB_SDA21 109 +#endif /* R_PPC_EMB_SDA21 */ +#ifndef R_PPC_EMB_MRKREF +#define R_PPC_EMB_MRKREF 110 +#endif /* R_PPC_EMB_MRKREF */ +#ifndef R_PPC_EMB_RELSEC16 +#define R_PPC_EMB_RELSEC16 111 +#endif /* R_PPC_EMB_RELSEC16 */ +#ifndef R_PPC_EMB_RELST_LO +#define R_PPC_EMB_RELST_LO 112 +#endif /* R_PPC_EMB_RELST_LO */ +#ifndef R_PPC_EMB_RELST_HI +#define R_PPC_EMB_RELST_HI 113 +#endif /* R_PPC_EMB_RELST_HI */ +#ifndef R_PPC_EMB_RELST_HA +#define R_PPC_EMB_RELST_HA 114 +#endif /* R_PPC_EMB_RELST_HA */ +#ifndef R_PPC_EMB_BIT_FLD +#define R_PPC_EMB_BIT_FLD 115 +#endif /* R_PPC_EMB_BIT_FLD */ +#ifndef R_PPC_EMB_RELSDA +#define R_PPC_EMB_RELSDA 116 +#endif /* R_PPC_EMB_RELSDA */ +#ifndef R_PPC_DIAB_SDA21_LO +#define R_PPC_DIAB_SDA21_LO 180 +#endif /* R_PPC_DIAB_SDA21_LO */ +#ifndef R_PPC_DIAB_SDA21_HI +#define R_PPC_DIAB_SDA21_HI 181 +#endif /* R_PPC_DIAB_SDA21_HI */ +#ifndef R_PPC_DIAB_SDA21_HA +#define R_PPC_DIAB_SDA21_HA 182 +#endif /* R_PPC_DIAB_SDA21_HA */ +#ifndef R_PPC_DIAB_RELSDA_LO +#define R_PPC_DIAB_RELSDA_LO 183 +#endif /* R_PPC_DIAB_RELSDA_LO */ +#ifndef R_PPC_DIAB_RELSDA_HI +#define R_PPC_DIAB_RELSDA_HI 184 +#endif /* R_PPC_DIAB_RELSDA_HI */ +#ifndef R_PPC_DIAB_RELSDA_HA +#define R_PPC_DIAB_RELSDA_HA 185 +#endif /* R_PPC_DIAB_RELSDA_HA */ +#ifndef R_PPC_IRELATIVE +#define R_PPC_IRELATIVE 248 +#endif /* R_PPC_IRELATIVE */ +#ifndef R_PPC_REL16 +#define R_PPC_REL16 249 +#endif /* R_PPC_REL16 */ +#ifndef R_PPC_REL16_LO +#define R_PPC_REL16_LO 250 +#endif /* R_PPC_REL16_LO */ +#ifndef R_PPC_REL16_HI +#define R_PPC_REL16_HI 251 +#endif /* R_PPC_REL16_HI */ +#ifndef R_PPC_REL16_HA +#define R_PPC_REL16_HA 252 +#endif /* R_PPC_REL16_HA */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_ppc64.h b/thirdparty/dwarf/dwarf_elf_reloc_ppc64.h new file mode 100644 index 00000000..26d91bf9 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_ppc64.h @@ -0,0 +1,258 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_ppc64(unsigned long); +#ifndef R_PPC64_ADDR30 +#define R_PPC64_ADDR30 37 +#endif /* R_PPC64_ADDR30 */ +#ifndef R_PPC64_ADDR64 +#define R_PPC64_ADDR64 38 +#endif /* R_PPC64_ADDR64 */ +#ifndef R_PPC64_ADDR16_HIGHER +#define R_PPC64_ADDR16_HIGHER 39 +#endif /* R_PPC64_ADDR16_HIGHER */ +#ifndef R_PPC64_ADDR16_HIGHERA +#define R_PPC64_ADDR16_HIGHERA 40 +#endif /* R_PPC64_ADDR16_HIGHERA */ +#ifndef R_PPC64_ADDR16_HIGHEST +#define R_PPC64_ADDR16_HIGHEST 41 +#endif /* R_PPC64_ADDR16_HIGHEST */ +#ifndef R_PPC64_ADDR16_HIGHESTA +#define R_PPC64_ADDR16_HIGHESTA 42 +#endif /* R_PPC64_ADDR16_HIGHESTA */ +#ifndef R_PPC64_UADDR64 +#define R_PPC64_UADDR64 43 +#endif /* R_PPC64_UADDR64 */ +#ifndef R_PPC64_REL64 +#define R_PPC64_REL64 44 +#endif /* R_PPC64_REL64 */ +#ifndef R_PPC64_PLT64 +#define R_PPC64_PLT64 45 +#endif /* R_PPC64_PLT64 */ +#ifndef R_PPC64_PLTREL64 +#define R_PPC64_PLTREL64 46 +#endif /* R_PPC64_PLTREL64 */ +#ifndef R_PPC64_TOC16 +#define R_PPC64_TOC16 47 +#endif /* R_PPC64_TOC16 */ +#ifndef R_PPC64_TOC16_LO +#define R_PPC64_TOC16_LO 48 +#endif /* R_PPC64_TOC16_LO */ +#ifndef R_PPC64_TOC16_HI +#define R_PPC64_TOC16_HI 49 +#endif /* R_PPC64_TOC16_HI */ +#ifndef R_PPC64_TOC16_HA +#define R_PPC64_TOC16_HA 50 +#endif /* R_PPC64_TOC16_HA */ +#ifndef R_PPC64_TOC +#define R_PPC64_TOC 51 +#endif /* R_PPC64_TOC */ +#ifndef R_PPC64_PLTGOT16 +#define R_PPC64_PLTGOT16 52 +#endif /* R_PPC64_PLTGOT16 */ +#ifndef R_PPC64_PLTGOT16_LO +#define R_PPC64_PLTGOT16_LO 53 +#endif /* R_PPC64_PLTGOT16_LO */ +#ifndef R_PPC64_PLTGOT16_HI +#define R_PPC64_PLTGOT16_HI 54 +#endif /* R_PPC64_PLTGOT16_HI */ +#ifndef R_PPC64_PLTGOT16_HA +#define R_PPC64_PLTGOT16_HA 55 +#endif /* R_PPC64_PLTGOT16_HA */ +#ifndef R_PPC64_ADDR16_DS +#define R_PPC64_ADDR16_DS 56 +#endif /* R_PPC64_ADDR16_DS */ +#ifndef R_PPC64_ADDR16_LO_DS +#define R_PPC64_ADDR16_LO_DS 57 +#endif /* R_PPC64_ADDR16_LO_DS */ +#ifndef R_PPC64_GOT16_DS +#define R_PPC64_GOT16_DS 58 +#endif /* R_PPC64_GOT16_DS */ +#ifndef R_PPC64_GOT16_LO_DS +#define R_PPC64_GOT16_LO_DS 59 +#endif /* R_PPC64_GOT16_LO_DS */ +#ifndef R_PPC64_PLT16_LO_DS +#define R_PPC64_PLT16_LO_DS 60 +#endif /* R_PPC64_PLT16_LO_DS */ +#ifndef R_PPC64_SECTOFF_DS +#define R_PPC64_SECTOFF_DS 61 +#endif /* R_PPC64_SECTOFF_DS */ +#ifndef R_PPC64_SECTOFF_LO_DS +#define R_PPC64_SECTOFF_LO_DS 62 +#endif /* R_PPC64_SECTOFF_LO_DS */ +#ifndef R_PPC64_TOC16_DS +#define R_PPC64_TOC16_DS 63 +#endif /* R_PPC64_TOC16_DS */ +#ifndef R_PPC64_TOC16_LO_DS +#define R_PPC64_TOC16_LO_DS 64 +#endif /* R_PPC64_TOC16_LO_DS */ +#ifndef R_PPC64_PLTGOT16_DS +#define R_PPC64_PLTGOT16_DS 65 +#endif /* R_PPC64_PLTGOT16_DS */ +#ifndef R_PPC64_PLTGOT16_LO_DS +#define R_PPC64_PLTGOT16_LO_DS 66 +#endif /* R_PPC64_PLTGOT16_LO_DS */ +#ifndef R_PPC64_TLS +#define R_PPC64_TLS 67 +#endif /* R_PPC64_TLS */ +#ifndef R_PPC64_DTPMOD64 +#define R_PPC64_DTPMOD64 68 +#endif /* R_PPC64_DTPMOD64 */ +#ifndef R_PPC64_TPREL16 +#define R_PPC64_TPREL16 69 +#endif /* R_PPC64_TPREL16 */ +#ifndef R_PPC64_TPREL16_LO +#define R_PPC64_TPREL16_LO 70 +#endif /* R_PPC64_TPREL16_LO */ +#ifndef R_PPC64_TPREL16_HI +#define R_PPC64_TPREL16_HI 71 +#endif /* R_PPC64_TPREL16_HI */ +#ifndef R_PPC64_TPREL16_HA +#define R_PPC64_TPREL16_HA 72 +#endif /* R_PPC64_TPREL16_HA */ +#ifndef R_PPC64_TPREL64 +#define R_PPC64_TPREL64 73 +#endif /* R_PPC64_TPREL64 */ +#ifndef R_PPC64_DTPREL16 +#define R_PPC64_DTPREL16 74 +#endif /* R_PPC64_DTPREL16 */ +#ifndef R_PPC64_DTPREL16_LO +#define R_PPC64_DTPREL16_LO 75 +#endif /* R_PPC64_DTPREL16_LO */ +#ifndef R_PPC64_DTPREL16_HI +#define R_PPC64_DTPREL16_HI 76 +#endif /* R_PPC64_DTPREL16_HI */ +#ifndef R_PPC64_DTPREL16_HA +#define R_PPC64_DTPREL16_HA 77 +#endif /* R_PPC64_DTPREL16_HA */ +#ifndef R_PPC64_DTPREL64 +#define R_PPC64_DTPREL64 78 +#endif /* R_PPC64_DTPREL64 */ +#ifndef R_PPC64_GOT_TLSGD16 +#define R_PPC64_GOT_TLSGD16 79 +#endif /* R_PPC64_GOT_TLSGD16 */ +#ifndef R_PPC64_GOT_TLSGD16_LO +#define R_PPC64_GOT_TLSGD16_LO 80 +#endif /* R_PPC64_GOT_TLSGD16_LO */ +#ifndef R_PPC64_GOT_TLSGD16_HI +#define R_PPC64_GOT_TLSGD16_HI 81 +#endif /* R_PPC64_GOT_TLSGD16_HI */ +#ifndef R_PPC64_GOT_TLSGD16_HA +#define R_PPC64_GOT_TLSGD16_HA 82 +#endif /* R_PPC64_GOT_TLSGD16_HA */ +#ifndef R_PPC64_GOT_TLSLD16 +#define R_PPC64_GOT_TLSLD16 83 +#endif /* R_PPC64_GOT_TLSLD16 */ +#ifndef R_PPC64_GOT_TLSLD16_LO +#define R_PPC64_GOT_TLSLD16_LO 84 +#endif /* R_PPC64_GOT_TLSLD16_LO */ +#ifndef R_PPC64_GOT_TLSLD16_HI +#define R_PPC64_GOT_TLSLD16_HI 85 +#endif /* R_PPC64_GOT_TLSLD16_HI */ +#ifndef R_PPC64_GOT_TLSLD16_HA +#define R_PPC64_GOT_TLSLD16_HA 86 +#endif /* R_PPC64_GOT_TLSLD16_HA */ +#ifndef R_PPC64_GOT_TPREL16_DS +#define R_PPC64_GOT_TPREL16_DS 87 +#endif /* R_PPC64_GOT_TPREL16_DS */ +#ifndef R_PPC64_GOT_TPREL16_LO_DS +#define R_PPC64_GOT_TPREL16_LO_DS 88 +#endif /* R_PPC64_GOT_TPREL16_LO_DS */ +#ifndef R_PPC64_GOT_TPREL16_HI +#define R_PPC64_GOT_TPREL16_HI 89 +#endif /* R_PPC64_GOT_TPREL16_HI */ +#ifndef R_PPC64_GOT_TPREL16_HA +#define R_PPC64_GOT_TPREL16_HA 90 +#endif /* R_PPC64_GOT_TPREL16_HA */ +#ifndef R_PPC64_GOT_DTPREL16_DS +#define R_PPC64_GOT_DTPREL16_DS 91 +#endif /* R_PPC64_GOT_DTPREL16_DS */ +#ifndef R_PPC64_GOT_DTPREL16_LO_DS +#define R_PPC64_GOT_DTPREL16_LO_DS 92 +#endif /* R_PPC64_GOT_DTPREL16_LO_DS */ +#ifndef R_PPC64_GOT_DTPREL16_HI +#define R_PPC64_GOT_DTPREL16_HI 93 +#endif /* R_PPC64_GOT_DTPREL16_HI */ +#ifndef R_PPC64_GOT_DTPREL16_HA +#define R_PPC64_GOT_DTPREL16_HA 94 +#endif /* R_PPC64_GOT_DTPREL16_HA */ +#ifndef R_PPC64_TPREL16_DS +#define R_PPC64_TPREL16_DS 95 +#endif /* R_PPC64_TPREL16_DS */ +#ifndef R_PPC64_TPREL16_LO_DS +#define R_PPC64_TPREL16_LO_DS 96 +#endif /* R_PPC64_TPREL16_LO_DS */ +#ifndef R_PPC64_TPREL16_HIGHER +#define R_PPC64_TPREL16_HIGHER 97 +#endif /* R_PPC64_TPREL16_HIGHER */ +#ifndef R_PPC64_TPREL16_HIGHERA +#define R_PPC64_TPREL16_HIGHERA 98 +#endif /* R_PPC64_TPREL16_HIGHERA */ +#ifndef R_PPC64_TPREL16_HIGHEST +#define R_PPC64_TPREL16_HIGHEST 99 +#endif /* R_PPC64_TPREL16_HIGHEST */ +#ifndef R_PPC64_TPREL16_HIGHESTA +#define R_PPC64_TPREL16_HIGHESTA 100 +#endif /* R_PPC64_TPREL16_HIGHESTA */ +#ifndef R_PPC64_DTPREL16_DS +#define R_PPC64_DTPREL16_DS 101 +#endif /* R_PPC64_DTPREL16_DS */ +#ifndef R_PPC64_DTPREL16_LO_DS +#define R_PPC64_DTPREL16_LO_DS 102 +#endif /* R_PPC64_DTPREL16_LO_DS */ +#ifndef R_PPC64_DTPREL16_HIGHER +#define R_PPC64_DTPREL16_HIGHER 103 +#endif /* R_PPC64_DTPREL16_HIGHER */ +#ifndef R_PPC64_DTPREL16_HIGHERA +#define R_PPC64_DTPREL16_HIGHERA 104 +#endif /* R_PPC64_DTPREL16_HIGHERA */ +#ifndef R_PPC64_DTPREL16_HIGHEST +#define R_PPC64_DTPREL16_HIGHEST 105 +#endif /* R_PPC64_DTPREL16_HIGHEST */ +#ifndef R_PPC64_DTPREL16_HIGHESTA +#define R_PPC64_DTPREL16_HIGHESTA 106 +#endif /* R_PPC64_DTPREL16_HIGHESTA */ +#ifndef R_PPC64_TOC32 +#define R_PPC64_TOC32 107 +#endif /* R_PPC64_TOC32 */ +#ifndef R_PPC64_DTPMOD32 +#define R_PPC64_DTPMOD32 108 +#endif /* R_PPC64_DTPMOD32 */ +#ifndef R_PPC64_TPREL32 +#define R_PPC64_TPREL32 109 +#endif /* R_PPC64_TPREL32 */ +#ifndef R_PPC64_DTPREL32 +#define R_PPC64_DTPREL32 110 +#endif /* R_PPC64_DTPREL32 */ +#ifndef R_PPC64_ADDR16_HIGHA +#define R_PPC64_ADDR16_HIGHA 111 +#endif /* R_PPC64_ADDR16_HIGHA */ +#ifndef R_PPC64_TPREL16_HIGH +#define R_PPC64_TPREL16_HIGH 112 +#endif /* R_PPC64_TPREL16_HIGH */ +#ifndef R_PPC64_TPREL16_HIGHA +#define R_PPC64_TPREL16_HIGHA 113 +#endif /* R_PPC64_TPREL16_HIGHA */ +#ifndef R_PPC64_DTPREL16_HIGH +#define R_PPC64_DTPREL16_HIGH 114 +#endif /* R_PPC64_DTPREL16_HIGH */ +#ifndef R_PPC64_DTPREL16_HIGHA +#define R_PPC64_DTPREL16_HIGHA 115 +#endif /* R_PPC64_DTPREL16_HIGHA */ +#ifndef R_PPC64_JMP_IREL +#define R_PPC64_JMP_IREL 247 +#endif /* R_PPC64_JMP_IREL */ +#ifndef R_PPC64_IRELATIVE +#define R_PPC64_IRELATIVE 248 +#endif /* R_PPC64_IRELATIVE */ +#ifndef R_PPC64_REL16 +#define R_PPC64_REL16 249 +#endif /* R_PPC64_REL16 */ +#ifndef R_PPC64_REL16_LO +#define R_PPC64_REL16_LO 250 +#endif /* R_PPC64_REL16_LO */ +#ifndef R_PPC64_REL16_HI +#define R_PPC64_REL16_HI 251 +#endif /* R_PPC64_REL16_HI */ +#ifndef R_PPC64_REL16_HA +#define R_PPC64_REL16_HA 252 +#endif /* R_PPC64_REL16_HA */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_sparc.h b/thirdparty/dwarf/dwarf_elf_reloc_sparc.h new file mode 100644 index 00000000..ec6db7bd --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_sparc.h @@ -0,0 +1,285 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_sparc(unsigned long); +#ifndef R_SPARC_NONE +#define R_SPARC_NONE 0 +#endif /* R_SPARC_NONE */ +#ifndef R_SPARC_8 +#define R_SPARC_8 1 +#endif /* R_SPARC_8 */ +#ifndef R_SPARC_16 +#define R_SPARC_16 2 +#endif /* R_SPARC_16 */ +#ifndef R_SPARC_32 +#define R_SPARC_32 3 +#endif /* R_SPARC_32 */ +#ifndef R_SPARC_DISP8 +#define R_SPARC_DISP8 4 +#endif /* R_SPARC_DISP8 */ +#ifndef R_SPARC_DISP16 +#define R_SPARC_DISP16 5 +#endif /* R_SPARC_DISP16 */ +#ifndef R_SPARC_DISP32 +#define R_SPARC_DISP32 6 +#endif /* R_SPARC_DISP32 */ +#ifndef R_SPARC_WDISP30 +#define R_SPARC_WDISP30 7 +#endif /* R_SPARC_WDISP30 */ +#ifndef R_SPARC_WDISP22 +#define R_SPARC_WDISP22 8 +#endif /* R_SPARC_WDISP22 */ +#ifndef R_SPARC_HI22 +#define R_SPARC_HI22 9 +#endif /* R_SPARC_HI22 */ +#ifndef R_SPARC_22 +#define R_SPARC_22 10 +#endif /* R_SPARC_22 */ +#ifndef R_SPARC_13 +#define R_SPARC_13 11 +#endif /* R_SPARC_13 */ +#ifndef R_SPARC_LO10 +#define R_SPARC_LO10 12 +#endif /* R_SPARC_LO10 */ +#ifndef R_SPARC_GOT10 +#define R_SPARC_GOT10 13 +#endif /* R_SPARC_GOT10 */ +#ifndef R_SPARC_GOT13 +#define R_SPARC_GOT13 14 +#endif /* R_SPARC_GOT13 */ +#ifndef R_SPARC_GOT22 +#define R_SPARC_GOT22 15 +#endif /* R_SPARC_GOT22 */ +#ifndef R_SPARC_PC10 +#define R_SPARC_PC10 16 +#endif /* R_SPARC_PC10 */ +#ifndef R_SPARC_PC22 +#define R_SPARC_PC22 17 +#endif /* R_SPARC_PC22 */ +#ifndef R_SPARC_WPLT30 +#define R_SPARC_WPLT30 18 +#endif /* R_SPARC_WPLT30 */ +#ifndef R_SPARC_COPY +#define R_SPARC_COPY 19 +#endif /* R_SPARC_COPY */ +#ifndef R_SPARC_GLOB_DAT +#define R_SPARC_GLOB_DAT 20 +#endif /* R_SPARC_GLOB_DAT */ +#ifndef R_SPARC_JMP_SLOT +#define R_SPARC_JMP_SLOT 21 +#endif /* R_SPARC_JMP_SLOT */ +#ifndef R_SPARC_RELATIVE +#define R_SPARC_RELATIVE 22 +#endif /* R_SPARC_RELATIVE */ +#ifndef R_SPARC_UA32 +#define R_SPARC_UA32 23 +#endif /* R_SPARC_UA32 */ +#ifndef R_SPARC_PLT32 +#define R_SPARC_PLT32 24 +#endif /* R_SPARC_PLT32 */ +#ifndef R_SPARC_HIPLT22 +#define R_SPARC_HIPLT22 25 +#endif /* R_SPARC_HIPLT22 */ +#ifndef R_SPARC_LOPLT10 +#define R_SPARC_LOPLT10 26 +#endif /* R_SPARC_LOPLT10 */ +#ifndef R_SPARC_PCPLT32 +#define R_SPARC_PCPLT32 27 +#endif /* R_SPARC_PCPLT32 */ +#ifndef R_SPARC_PCPLT22 +#define R_SPARC_PCPLT22 28 +#endif /* R_SPARC_PCPLT22 */ +#ifndef R_SPARC_PCPLT10 +#define R_SPARC_PCPLT10 29 +#endif /* R_SPARC_PCPLT10 */ +#ifndef R_SPARC_10 +#define R_SPARC_10 30 +#endif /* R_SPARC_10 */ +#ifndef R_SPARC_11 +#define R_SPARC_11 31 +#endif /* R_SPARC_11 */ +#ifndef R_SPARC_64 +#define R_SPARC_64 32 +#endif /* R_SPARC_64 */ +#ifndef R_SPARC_OLO10 +#define R_SPARC_OLO10 33 +#endif /* R_SPARC_OLO10 */ +#ifndef R_SPARC_HH22 +#define R_SPARC_HH22 34 +#endif /* R_SPARC_HH22 */ +#ifndef R_SPARC_HM10 +#define R_SPARC_HM10 35 +#endif /* R_SPARC_HM10 */ +#ifndef R_SPARC_LM22 +#define R_SPARC_LM22 36 +#endif /* R_SPARC_LM22 */ +#ifndef R_SPARC_PC_HH22 +#define R_SPARC_PC_HH22 37 +#endif /* R_SPARC_PC_HH22 */ +#ifndef R_SPARC_PC_HM10 +#define R_SPARC_PC_HM10 38 +#endif /* R_SPARC_PC_HM10 */ +#ifndef R_SPARC_PC_LM22 +#define R_SPARC_PC_LM22 39 +#endif /* R_SPARC_PC_LM22 */ +#ifndef R_SPARC_WDISP16 +#define R_SPARC_WDISP16 40 +#endif /* R_SPARC_WDISP16 */ +#ifndef R_SPARC_WDISP19 +#define R_SPARC_WDISP19 41 +#endif /* R_SPARC_WDISP19 */ +#ifndef R_SPARC_GLOB_JMP +#define R_SPARC_GLOB_JMP 42 +#endif /* R_SPARC_GLOB_JMP */ +#ifndef R_SPARC_7 +#define R_SPARC_7 43 +#endif /* R_SPARC_7 */ +#ifndef R_SPARC_5 +#define R_SPARC_5 44 +#endif /* R_SPARC_5 */ +#ifndef R_SPARC_6 +#define R_SPARC_6 45 +#endif /* R_SPARC_6 */ +#ifndef R_SPARC_DISP64 +#define R_SPARC_DISP64 46 +#endif /* R_SPARC_DISP64 */ +#ifndef R_SPARC_PLT64 +#define R_SPARC_PLT64 47 +#endif /* R_SPARC_PLT64 */ +#ifndef R_SPARC_HIX22 +#define R_SPARC_HIX22 48 +#endif /* R_SPARC_HIX22 */ +#ifndef R_SPARC_LOX10 +#define R_SPARC_LOX10 49 +#endif /* R_SPARC_LOX10 */ +#ifndef R_SPARC_H44 +#define R_SPARC_H44 50 +#endif /* R_SPARC_H44 */ +#ifndef R_SPARC_M44 +#define R_SPARC_M44 51 +#endif /* R_SPARC_M44 */ +#ifndef R_SPARC_L44 +#define R_SPARC_L44 52 +#endif /* R_SPARC_L44 */ +#ifndef R_SPARC_REGISTER +#define R_SPARC_REGISTER 53 +#endif /* R_SPARC_REGISTER */ +#ifndef R_SPARC_UA64 +#define R_SPARC_UA64 54 +#endif /* R_SPARC_UA64 */ +#ifndef R_SPARC_UA16 +#define R_SPARC_UA16 55 +#endif /* R_SPARC_UA16 */ +#ifndef R_SPARC_TLS_GD_HI22 +#define R_SPARC_TLS_GD_HI22 56 +#endif /* R_SPARC_TLS_GD_HI22 */ +#ifndef R_SPARC_TLS_GD_LO10 +#define R_SPARC_TLS_GD_LO10 57 +#endif /* R_SPARC_TLS_GD_LO10 */ +#ifndef R_SPARC_TLS_GD_ADD +#define R_SPARC_TLS_GD_ADD 58 +#endif /* R_SPARC_TLS_GD_ADD */ +#ifndef R_SPARC_TLS_GD_CALL +#define R_SPARC_TLS_GD_CALL 59 +#endif /* R_SPARC_TLS_GD_CALL */ +#ifndef R_SPARC_TLS_LDM_HI22 +#define R_SPARC_TLS_LDM_HI22 60 +#endif /* R_SPARC_TLS_LDM_HI22 */ +#ifndef R_SPARC_TLS_LDM_LO10 +#define R_SPARC_TLS_LDM_LO10 61 +#endif /* R_SPARC_TLS_LDM_LO10 */ +#ifndef R_SPARC_TLS_LDM_ADD +#define R_SPARC_TLS_LDM_ADD 62 +#endif /* R_SPARC_TLS_LDM_ADD */ +#ifndef R_SPARC_TLS_LDM_CALL +#define R_SPARC_TLS_LDM_CALL 63 +#endif /* R_SPARC_TLS_LDM_CALL */ +#ifndef R_SPARC_TLS_LDO_HIX22 +#define R_SPARC_TLS_LDO_HIX22 64 +#endif /* R_SPARC_TLS_LDO_HIX22 */ +#ifndef R_SPARC_TLS_LDO_LOX10 +#define R_SPARC_TLS_LDO_LOX10 65 +#endif /* R_SPARC_TLS_LDO_LOX10 */ +#ifndef R_SPARC_TLS_LDO_ADD +#define R_SPARC_TLS_LDO_ADD 66 +#endif /* R_SPARC_TLS_LDO_ADD */ +#ifndef R_SPARC_TLS_IE_HI22 +#define R_SPARC_TLS_IE_HI22 67 +#endif /* R_SPARC_TLS_IE_HI22 */ +#ifndef R_SPARC_TLS_IE_LO10 +#define R_SPARC_TLS_IE_LO10 68 +#endif /* R_SPARC_TLS_IE_LO10 */ +#ifndef R_SPARC_TLS_IE_LD +#define R_SPARC_TLS_IE_LD 69 +#endif /* R_SPARC_TLS_IE_LD */ +#ifndef R_SPARC_TLS_IE_LDX +#define R_SPARC_TLS_IE_LDX 70 +#endif /* R_SPARC_TLS_IE_LDX */ +#ifndef R_SPARC_TLS_IE_ADD +#define R_SPARC_TLS_IE_ADD 71 +#endif /* R_SPARC_TLS_IE_ADD */ +#ifndef R_SPARC_TLS_LE_HIX22 +#define R_SPARC_TLS_LE_HIX22 72 +#endif /* R_SPARC_TLS_LE_HIX22 */ +#ifndef R_SPARC_TLS_LE_LOX10 +#define R_SPARC_TLS_LE_LOX10 73 +#endif /* R_SPARC_TLS_LE_LOX10 */ +#ifndef R_SPARC_TLS_DTPMOD32 +#define R_SPARC_TLS_DTPMOD32 74 +#endif /* R_SPARC_TLS_DTPMOD32 */ +#ifndef R_SPARC_TLS_DTPMOD64 +#define R_SPARC_TLS_DTPMOD64 75 +#endif /* R_SPARC_TLS_DTPMOD64 */ +#ifndef R_SPARC_TLS_DTPOFF32 +#define R_SPARC_TLS_DTPOFF32 76 +#endif /* R_SPARC_TLS_DTPOFF32 */ +#ifndef R_SPARC_TLS_DTPOFF64 +#define R_SPARC_TLS_DTPOFF64 77 +#endif /* R_SPARC_TLS_DTPOFF64 */ +#ifndef R_SPARC_TLS_TPOFF32 +#define R_SPARC_TLS_TPOFF32 78 +#endif /* R_SPARC_TLS_TPOFF32 */ +#ifndef R_SPARC_TLS_TPOFF64 +#define R_SPARC_TLS_TPOFF64 79 +#endif /* R_SPARC_TLS_TPOFF64 */ +#ifndef R_SPARC_GOTDATA_HIX22 +#define R_SPARC_GOTDATA_HIX22 80 +#endif /* R_SPARC_GOTDATA_HIX22 */ +#ifndef R_SPARC_GOTDATA_LOX10 +#define R_SPARC_GOTDATA_LOX10 81 +#endif /* R_SPARC_GOTDATA_LOX10 */ +#ifndef R_SPARC_GOTDATA_OP_HIX22 +#define R_SPARC_GOTDATA_OP_HIX22 82 +#endif /* R_SPARC_GOTDATA_OP_HIX22 */ +#ifndef R_SPARC_GOTDATA_OP_LOX10 +#define R_SPARC_GOTDATA_OP_LOX10 83 +#endif /* R_SPARC_GOTDATA_OP_LOX10 */ +#ifndef R_SPARC_GOTDATA_OP +#define R_SPARC_GOTDATA_OP 84 +#endif /* R_SPARC_GOTDATA_OP */ +#ifndef R_SPARC_H34 +#define R_SPARC_H34 85 +#endif /* R_SPARC_H34 */ +#ifndef R_SPARC_SIZE32 +#define R_SPARC_SIZE32 86 +#endif /* R_SPARC_SIZE32 */ +#ifndef R_SPARC_SIZE64 +#define R_SPARC_SIZE64 87 +#endif /* R_SPARC_SIZE64 */ +#ifndef R_SPARC_WDISP10 +#define R_SPARC_WDISP10 88 +#endif /* R_SPARC_WDISP10 */ +#ifndef R_SPARC_JMP_IREL +#define R_SPARC_JMP_IREL 248 +#endif /* R_SPARC_JMP_IREL */ +#ifndef R_SPARC_IRELATIVE +#define R_SPARC_IRELATIVE 249 +#endif /* R_SPARC_IRELATIVE */ +#ifndef R_SPARC_GNU_VTINHERIT +#define R_SPARC_GNU_VTINHERIT 250 +#endif /* R_SPARC_GNU_VTINHERIT */ +#ifndef R_SPARC_GNU_VTENTRY +#define R_SPARC_GNU_VTENTRY 251 +#endif /* R_SPARC_GNU_VTENTRY */ +#ifndef R_SPARC_REV32 +#define R_SPARC_REV32 252 +#endif /* R_SPARC_REV32 */ diff --git a/thirdparty/dwarf/dwarf_elf_reloc_x86_64.h b/thirdparty/dwarf/dwarf_elf_reloc_x86_64.h new file mode 100644 index 00000000..89414fd5 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elf_reloc_x86_64.h @@ -0,0 +1,126 @@ +/* Created by build_access.py */ +/* returns string of length 0 if invalid arg */ +const char * dwarf_get_elf_relocname_x86_64(unsigned long); +#ifndef R_X86_64_NONE +#define R_X86_64_NONE 0 +#endif /* R_X86_64_NONE */ +#ifndef R_X86_64_64 +#define R_X86_64_64 1 +#endif /* R_X86_64_64 */ +#ifndef R_X86_64_PC32 +#define R_X86_64_PC32 2 +#endif /* R_X86_64_PC32 */ +#ifndef R_X86_64_GOT32 +#define R_X86_64_GOT32 3 +#endif /* R_X86_64_GOT32 */ +#ifndef R_X86_64_PLT32 +#define R_X86_64_PLT32 4 +#endif /* R_X86_64_PLT32 */ +#ifndef R_X86_64_COPY +#define R_X86_64_COPY 5 +#endif /* R_X86_64_COPY */ +#ifndef R_X86_64_GLOB_DAT +#define R_X86_64_GLOB_DAT 6 +#endif /* R_X86_64_GLOB_DAT */ +#ifndef R_X86_64_JUMP_SLOT +#define R_X86_64_JUMP_SLOT 7 +#endif /* R_X86_64_JUMP_SLOT */ +#ifndef R_X86_64_RELATIVE +#define R_X86_64_RELATIVE 8 +#endif /* R_X86_64_RELATIVE */ +#ifndef R_X86_64_GOTPCREL +#define R_X86_64_GOTPCREL 9 +#endif /* R_X86_64_GOTPCREL */ +#ifndef R_X86_64_32 +#define R_X86_64_32 10 +#endif /* R_X86_64_32 */ +#ifndef R_X86_64_32S +#define R_X86_64_32S 11 +#endif /* R_X86_64_32S */ +#ifndef R_X86_64_16 +#define R_X86_64_16 12 +#endif /* R_X86_64_16 */ +#ifndef R_X86_64_PC16 +#define R_X86_64_PC16 13 +#endif /* R_X86_64_PC16 */ +#ifndef R_X86_64_8 +#define R_X86_64_8 14 +#endif /* R_X86_64_8 */ +#ifndef R_X86_64_PC8 +#define R_X86_64_PC8 15 +#endif /* R_X86_64_PC8 */ +#ifndef R_X86_64_DTPMOD64 +#define R_X86_64_DTPMOD64 16 +#endif /* R_X86_64_DTPMOD64 */ +#ifndef R_X86_64_DTPOFF64 +#define R_X86_64_DTPOFF64 17 +#endif /* R_X86_64_DTPOFF64 */ +#ifndef R_X86_64_TPOFF64 +#define R_X86_64_TPOFF64 18 +#endif /* R_X86_64_TPOFF64 */ +#ifndef R_X86_64_TLSGD +#define R_X86_64_TLSGD 19 +#endif /* R_X86_64_TLSGD */ +#ifndef R_X86_64_TLSLD +#define R_X86_64_TLSLD 20 +#endif /* R_X86_64_TLSLD */ +#ifndef R_X86_64_DTPOFF32 +#define R_X86_64_DTPOFF32 21 +#endif /* R_X86_64_DTPOFF32 */ +#ifndef R_X86_64_GOTTPOFF +#define R_X86_64_GOTTPOFF 22 +#endif /* R_X86_64_GOTTPOFF */ +#ifndef R_X86_64_TPOFF32 +#define R_X86_64_TPOFF32 23 +#endif /* R_X86_64_TPOFF32 */ +#ifndef R_X86_64_PC64 +#define R_X86_64_PC64 24 +#endif /* R_X86_64_PC64 */ +#ifndef R_X86_64_GOTOFF64 +#define R_X86_64_GOTOFF64 25 +#endif /* R_X86_64_GOTOFF64 */ +#ifndef R_X86_64_GOTPC32 +#define R_X86_64_GOTPC32 26 +#endif /* R_X86_64_GOTPC32 */ +#ifndef R_X86_64_GOT64 +#define R_X86_64_GOT64 27 +#endif /* R_X86_64_GOT64 */ +#ifndef R_X86_64_GOTPCREL64 +#define R_X86_64_GOTPCREL64 28 +#endif /* R_X86_64_GOTPCREL64 */ +#ifndef R_X86_64_GOTPC64 +#define R_X86_64_GOTPC64 29 +#endif /* R_X86_64_GOTPC64 */ +#ifndef R_X86_64_GOTPLT64 +#define R_X86_64_GOTPLT64 30 +#endif /* R_X86_64_GOTPLT64 */ +#ifndef R_X86_64_PLTOFF64 +#define R_X86_64_PLTOFF64 31 +#endif /* R_X86_64_PLTOFF64 */ +#ifndef R_X86_64_SIZE32 +#define R_X86_64_SIZE32 32 +#endif /* R_X86_64_SIZE32 */ +#ifndef R_X86_64_SIZE64 +#define R_X86_64_SIZE64 33 +#endif /* R_X86_64_SIZE64 */ +#ifndef R_X86_64_GOTPC32_TLSDESC +#define R_X86_64_GOTPC32_TLSDESC 34 +#endif /* R_X86_64_GOTPC32_TLSDESC */ +#ifndef R_X86_64_TLSDESC_CALL +#define R_X86_64_TLSDESC_CALL 35 +#endif /* R_X86_64_TLSDESC_CALL */ +#ifndef R_X86_64_TLSDESC +#define R_X86_64_TLSDESC 36 +#endif /* R_X86_64_TLSDESC */ +#ifndef R_X86_64_IRELATIVE +#define R_X86_64_IRELATIVE 37 +#endif /* R_X86_64_IRELATIVE */ +#ifndef R_X86_64_RELATIVE64 +#define R_X86_64_RELATIVE64 38 +#endif /* R_X86_64_RELATIVE64 */ +#ifndef R_X86_64_GOTPCRELX +#define R_X86_64_GOTPCRELX 41 +#endif /* R_X86_64_GOTPCRELX */ +#ifndef R_X86_64_REX_GOTPCRELX +#define R_X86_64_REX_GOTPCRELX 42 +#endif /* R_X86_64_REX_GOTPCRELX */ diff --git a/thirdparty/dwarf/dwarf_elfread.c b/thirdparty/dwarf/dwarf_elfread.c new file mode 100644 index 00000000..9cb1c4b5 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elfread.c @@ -0,0 +1,772 @@ +/* +Copyright (c) 2019, David Anderson +All rights reserved. +cc +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This file reads the parts of an Elf + file appropriate to reading DWARF debugging data. + Overview: + _dwarf_elf_nlsetup() Does all elf setup. + calls _dwarf_elf_access_init() + calls _dwarf_elf_object_access_internals_init() + Creates internals record 'M', + dwarf_elf_object_access_internals_t + Sets flags/data in internals record + Loads elf object data needed later. + Sets methods struct to access elf object. + calls _dwarf_object_init_b() Creates Dwarf_Debug, independent + of any elf code. + Sets internals record into dbg. + ---------------------- + _dwarf_destruct_elf_nlaccess(). This frees + the elf internals record created in + _dwarf_elf_object_access_internals_init() + in case of errors during setup or when + dwarf_finish() is called. Works safely for + partially or fully set-up elf internals record. + + Other than in _dwarf_elf_nlsetup() the elf code + knows nothing about Dwarf_Debug, and the rest of + libdwarf knows nothing about the content of the + object-type-specific (for Elf here) + internals record. +*/ + +#include "config.h" +#include +#ifdef HAVE_MALLOC_H +#include +#endif /* HAVE_MALLOC_H */ +#include +#include +#include +#include /* open() */ +#include /* open() */ +#include /* open() */ +#include +#ifdef HAVE_UNISTD_H +#include /* lseek read close */ +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#endif /* HAVE_UNISTD_H */ + +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) +#include "stdafx.h" +#endif /* HAVE_STDAFX_H */ + +#include "libdwarf.h" +#include "libdwarfdefs.h" +#include "dwarf_base_types.h" +#include "dwarf_opaque.h" +#include "dwarf_error.h" /* for _dwarf_error() declaration */ +#include "dwarf_reading.h" +#include "memcpy_swap.h" +#include "dwarf_object_read_common.h" +#include "dwarf_object_detector.h" +#include "dwarf_elfstructs.h" +#include "dwarf_elf_defines.h" +#include "dwarf_elf_rel_detector.h" +#include "dwarf_elfread.h" + + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif /* TYPE */ + + +#ifdef WORDS_BIGENDIAN +#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ + { \ + dbg->de_copy_word(dest, \ + ((char *)source) +srclength-len_out, \ + len_out) ; \ + } +#else /* LITTLE ENDIAN */ +#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ + { \ + dbg->de_copy_word( (dest) , \ + ((char *)source) , \ + len_out) ; \ + } +#endif /* end LITTLE- BIG-ENDIAN */ + +#ifdef WORDS_BIGENDIAN +#define ASNAR(func,t,s) \ + do { \ + unsigned tbyte = sizeof(t) - sizeof(s); \ + t = 0; \ + func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ + } while (0) +#else /* LITTLE ENDIAN */ +#define ASNAR(func,t,s) \ + do { \ + t = 0; \ + func(&t,&s[0],sizeof(s)); \ + } while (0) +#endif /* end LITTLE- BIG-ENDIAN */ + + +static int +_dwarf_elf_object_access_init( + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + Dwarf_Obj_Access_Interface **binary_interface, + int *localerrnum); + + +static Dwarf_Endianness elf_get_nolibelf_byte_order (void *obj) +{ + dwarf_elf_object_access_internals_t *elf = + (dwarf_elf_object_access_internals_t*)(obj); + return elf->f_endian; +} + + +static Dwarf_Small elf_get_nolibelf_length_size (void *obj) +{ + dwarf_elf_object_access_internals_t *elf = + (dwarf_elf_object_access_internals_t*)(obj); + return elf->f_offsetsize/8; +} + + +static Dwarf_Small elf_get_nolibelf_pointer_size (void *obj) +{ + dwarf_elf_object_access_internals_t *elf = + (dwarf_elf_object_access_internals_t*)(obj); + return elf->f_pointersize/8; +} + + +static Dwarf_Unsigned elf_get_nolibelf_section_count (void *obj) +{ + dwarf_elf_object_access_internals_t *elf = + (dwarf_elf_object_access_internals_t*)(obj); + return elf->f_loc_shdr.g_count; +} + +static int elf_get_nolibelf_section_info (void *obj, + Dwarf_Half section_index, + Dwarf_Obj_Access_Section *return_section, + UNUSEDARG int *error) +{ + dwarf_elf_object_access_internals_t *elf = + (dwarf_elf_object_access_internals_t*)(obj); + + + if (section_index < elf->f_loc_shdr.g_count) { + struct generic_shdr *sp = 0; + + sp = elf->f_shdr + section_index; + return_section->addr = sp->gh_addr; + return_section->type = sp->gh_type; + return_section->size = sp->gh_size; + return_section->name = sp->gh_namestring; + return_section->link = sp->gh_link; + return_section->info = sp->gh_info; + return_section->entrysize = sp->gh_entsize; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +static int +elf_load_nolibelf_section (void *obj, Dwarf_Half section_index, + Dwarf_Small **return_data, int *error) +{ + dwarf_elf_object_access_internals_t *elf = + (dwarf_elf_object_access_internals_t*)(obj); + + if (0 < section_index && + section_index < elf->f_loc_shdr.g_count) { + int res = 0; + + struct generic_shdr *sp = + elf->f_shdr + section_index; + if (sp->gh_content) { + *return_data = (Dwarf_Small *)sp->gh_content; + return DW_DLV_OK; + } + if (!sp->gh_size) { + return DW_DLV_NO_ENTRY; + } + if ((sp->gh_size + sp->gh_offset) > + elf->f_filesize) { + *error = DW_DLE_ELF_SECTION_ERROR; + return DW_DLV_ERROR; + } + + sp->gh_content = malloc((size_t)sp->gh_size); + if(!sp->gh_content) { + *error = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(elf->f_fd, + sp->gh_content, (off_t)sp->gh_offset, + (size_t)sp->gh_size, (off_t)elf->f_filesize, error); + if (res != DW_DLV_OK) { + free(sp->gh_content); + sp->gh_content = 0; + return res; + } + *return_data = (Dwarf_Small *)sp->gh_content; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +static int +_dwarf_get_elf_flags_func_nl( + void* obj_in, + Dwarf_Half section_index, + Dwarf_Unsigned *flags_out, + Dwarf_Unsigned *addralign_out, + int *error) +{ + dwarf_elf_object_access_internals_t *ep = 0; + struct generic_shdr *shp = 0; + + ep = (dwarf_elf_object_access_internals_t *)obj_in; + if (section_index == 0) { + /* Nothing to do. Empty section */ + return DW_DLV_OK; + } + if (section_index >= ep->f_loc_shdr.g_count) { + *error = DW_DLE_SECTION_INDEX_BAD; + return DW_DLV_ERROR; + } + shp = ep->f_shdr + section_index; + *flags_out = shp->gh_flags; + *addralign_out = shp->gh_addralign; + return DW_DLV_OK; +} + + +#define MATCH_REL_SEC(i_,s_,r_) \ +if (i_ == s_.dss_index) { \ + *r_ = &s_; \ + return DW_DLV_OK; \ +} + +static int +find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index, + struct Dwarf_Section_s **relocatablesec, int *error) +{ + MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec); + MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec); + /* dbg-> de_debug_tu_index,reloctablesec); */ + /* dbg-> de_debug_cu_index,reloctablesec); */ + /* dbg-> de_debug_gdbindex,reloctablesec); */ + /* dbg-> de_debug_str,syms); */ + /* de_elf_symtab,syms); */ + /* de_elf_strtab,syms); */ + *error = DW_DLE_RELOC_SECTION_MISMATCH; + return DW_DLV_ERROR; +} + + +/* Returns DW_DLV_OK if it works, else DW_DLV_ERROR. + The caller may decide to ignore the errors or report them. */ +static int +update_entry(Dwarf_Debug dbg, + dwarf_elf_object_access_internals_t*obj, + struct generic_rela *rela, + Dwarf_Small *target_section, + Dwarf_Unsigned target_section_size, + int *error) +{ + unsigned int type = 0; + unsigned int sym_idx = 0; + Dwarf_Unsigned offset = 0; + Dwarf_Signed addend = 0; + Dwarf_Unsigned reloc_size = 0; + Dwarf_Half machine = obj->f_machine; + struct generic_symentry *symp = 0; + + offset = rela->gr_offset; + addend = rela->gr_addend; + type = (unsigned int)rela->gr_type; + sym_idx = (unsigned int)rela->gr_sym; + if (sym_idx >= obj->f_loc_symtab.g_count) { + *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD; + return DW_DLV_ERROR; + } + symp = obj->f_symtab + sym_idx; + if (offset >= target_section_size) { + /* If offset really big, any add will overflow. + So lets stop early if offset is corrupt. */ + *error = DW_DLE_RELOC_INVALID; + return DW_DLV_ERROR; + } + + /* Determine relocation size */ + if (_dwarf_is_32bit_abs_reloc(type, machine)) { + reloc_size = 4; + } else if (_dwarf_is_64bit_abs_reloc(type, machine)) { + reloc_size = 8; + } else { + *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN; + return DW_DLV_ERROR; + } + if ( (offset + reloc_size) < offset) { + /* Another check for overflow. */ + *error = DW_DLE_RELOC_INVALID; + return DW_DLV_ERROR; + } + if ( (offset + reloc_size) > target_section_size) { + *error = DW_DLE_RELOC_INVALID; + return DW_DLV_ERROR; + } + { + /* Assuming we do not need to do a READ_UNALIGNED here + at target_section + offset and add its value to + outval. Some ABIs say no read (for example MIPS), + but if some do then which ones? */ + Dwarf_Unsigned outval = symp->gs_value + addend; + /* The 0th byte goes at offset. */ + WRITE_UNALIGNED(dbg, target_section + offset, + &outval, sizeof(outval), (unsigned long)reloc_size); + } + return DW_DLV_OK; +} + + + +/* Somewhat arbitrarily, we attempt to apply all the + relocations we can + and still notify the caller of at least one error if we found + any errors. */ + +static int +apply_rela_entries( + Dwarf_Debug dbg, + /* Section_index of the relocation section, .rela entries */ + Dwarf_Half r_section_index, + dwarf_elf_object_access_internals_t*obj, + /* relocatablesec is the .debug_info(etc) in Dwarf_Debug */ + struct Dwarf_Section_s * relocatablesec, + int *error) +{ + int return_res = DW_DLV_OK; + struct generic_shdr * rels_shp = 0; + Dwarf_Unsigned relcount; + Dwarf_Unsigned i = 0; + + if (r_section_index >= obj->f_loc_shdr.g_count) { + *error = DW_DLE_SECTION_INDEX_BAD; + return DW_DLV_ERROR; + } + rels_shp = obj->f_shdr + r_section_index; + relcount = rels_shp->gh_relcount; + if (!relcount) { + /* Nothing to do. */ + return DW_DLV_OK; + } + if (!rels_shp->gh_rels) { + /* something wrong. */ + *error = DW_DLE_RELOCS_ERROR; + return DW_DLV_ERROR; + } + for (i = 0; i < relcount; i++) { + int res = update_entry(dbg,obj, + rels_shp->gh_rels+i, + relocatablesec->dss_data, + relocatablesec->dss_size, + error); + if (res != DW_DLV_OK) { + /* We try to keep going, not stop. */ + return_res = res; + } + } + return return_res; +} + +/* Find the section data in dbg and find all the relevant + sections. Then do relocations. + + section_index is the index of a .debug_info (for example) + so we have to find the section(s) with relocations + targeting section_index. + Normally there is exactly one such, though. +*/ +static int +elf_relocations_nolibelf(void* obj_in, + Dwarf_Half section_index, + Dwarf_Debug dbg, + int* error) +{ + int res = DW_DLV_ERROR; + dwarf_elf_object_access_internals_t*obj = 0; + struct Dwarf_Section_s * relocatablesec = 0; + unsigned section_with_reloc_records = 0; + + if (section_index == 0) { + return DW_DLV_NO_ENTRY; + } + obj = (dwarf_elf_object_access_internals_t*)obj_in; + + /* The section to relocate must already be loaded into memory. + This just turns section_index into a pointer + to a de_debug_info or other section record in + Dwarf_Debug. */ + res = find_section_to_relocate(dbg, section_index, + &relocatablesec, error); + if (res != DW_DLV_OK) { + return res; + } + /* Now we know the Dwarf_Section_s section + we need to relocate. + So lets find the rela section(s) targeting this. + */ + + /* Sun and possibly others do not always set + sh_link in .debug_* sections. + So we cannot do full consistency checks. + FIXME: This approach assumes there is only one + relocation section applying to section section_index! */ + section_with_reloc_records = relocatablesec->dss_reloc_index; + if (!section_with_reloc_records) { + /* Something is wrong. */ + *error = DW_DLE_RELOC_SECTION_MISSING_INDEX; + return DW_DLV_ERROR; + } + /* The relocations, if they exist, have been loaded. */ + /* The symtab was already loaded. */ + if (!obj->f_symtab || !obj->f_symtab_sect_strings) { + *error = DW_DLE_DEBUG_SYMTAB_ERR; + return DW_DLV_ERROR; + } + if (obj->f_symtab_sect_index != relocatablesec->dss_reloc_link) { + /* Something is wrong. */ + *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX; + return DW_DLV_ERROR; + } + /* We have all the data we need in memory. */ + /* Now we apply the relocs in section_with_reloc_records to the + target, relocablesec */ + res = apply_rela_entries(dbg,section_with_reloc_records, + obj, relocatablesec,error); + return res; +} + +void +_dwarf_destruct_elf_nlaccess( + struct Dwarf_Obj_Access_Interface_s *aip) +{ + dwarf_elf_object_access_internals_t *ep = 0; + struct generic_shdr *shp = 0; + Dwarf_Unsigned shcount = 0; + Dwarf_Unsigned i = 0; + + ep = (dwarf_elf_object_access_internals_t *)aip->object; + free(ep->f_ehdr); + shp = ep->f_shdr; + shcount = ep->f_loc_shdr.g_count; + for(i = 0; i < shcount; ++i,++shp) { + free(shp->gh_rels); + shp->gh_rels = 0; + free(shp->gh_content); + shp->gh_content = 0; + free(shp->gh_sht_group_array); + shp->gh_sht_group_array = 0; + shp->gh_sht_group_array_count = 0; + } + free(ep->f_shdr); + ep->f_loc_shdr.g_count = 0; + free(ep->f_phdr); + free(ep->f_elf_shstrings_data); + free(ep->f_dynamic); + free(ep->f_symtab_sect_strings); + free(ep->f_dynsym_sect_strings); + free(ep->f_symtab); + free(ep->f_dynsym); + + /* if TRUE close f_fd on destruct.*/ + if (ep->f_destruct_close_fd) { + close(ep->f_fd); + } + ep->f_ident[0] = 'X'; + free(ep->f_path); + free(ep); + free(aip); +} + + +int +_dwarf_elf_nlsetup(int fd, + char *true_path, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error) +{ + Dwarf_Obj_Access_Interface *binary_interface = 0; + dwarf_elf_object_access_internals_t *intfc = 0; + int res = DW_DLV_OK; + int localerrnum = 0; + + res = _dwarf_elf_object_access_init( + fd, + ftype,endian,offsetsize,filesize,access, + &binary_interface, + &localerrnum); + if (res != DW_DLV_OK) { + if (res == DW_DLV_NO_ENTRY) { + return res; + } + _dwarf_error(NULL, error, localerrnum); + return DW_DLV_ERROR; + } + /* allocates and initializes Dwarf_Debug, + generic code */ + res = dwarf_object_init_b(binary_interface, errhand, errarg, + groupnumber, dbg, error); + if (res != DW_DLV_OK){ + _dwarf_destruct_elf_nlaccess(binary_interface); + return res; + } + intfc = binary_interface->object; + intfc->f_path = strdup(true_path); + return res; +} + +static Dwarf_Obj_Access_Methods const elf_nlmethods = { + elf_get_nolibelf_section_info, + elf_get_nolibelf_byte_order, + elf_get_nolibelf_length_size, + elf_get_nolibelf_pointer_size, + elf_get_nolibelf_section_count, + elf_load_nolibelf_section, + elf_relocations_nolibelf +}; + +/* On any error this frees internals argument. */ +static int +_dwarf_elf_object_access_internals_init( + dwarf_elf_object_access_internals_t * internals, + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + UNUSEDARG Dwarf_Unsigned access, + int *errcode) +{ + dwarf_elf_object_access_internals_t * intfc = internals; + Dwarf_Unsigned i = 0; + struct Dwarf_Obj_Access_Interface_s *localdoas; + int res = 0; + + /* Must malloc as _dwarf_destruct_elf_access() + forces that due to other uses. */ + localdoas = (struct Dwarf_Obj_Access_Interface_s *) + malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); + if (!localdoas) { + free(internals); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); + /* E is used with libelf. F with this elf reader. */ + intfc->f_ident[0] = 'F'; + intfc->f_ident[1] = '1'; + intfc->f_fd = fd; + intfc->f_is_64bit = ((offsetsize==64)?TRUE:FALSE); + intfc->f_offsetsize = offsetsize; + intfc->f_pointersize = offsetsize; + intfc->f_filesize = filesize; + intfc->f_ftype = ftype; + intfc->f_destruct_close_fd = FALSE; + +#ifdef WORDS_BIGENDIAN + if (endian == DW_ENDIAN_LITTLE ) { + intfc->f_copy_word = _dwarf_memcpy_swap_bytes; + intfc->f_endian = DW_OBJECT_LSB; + } else { + intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; + intfc->f_endian = DW_OBJECT_MSB; + } +#else /* LITTLE ENDIAN */ + if (endian == DW_ENDIAN_LITTLE ) { + intfc->f_copy_word = _dwarf_memcpy_noswap_bytes; + intfc->f_endian = DW_OBJECT_LSB; + } else { + intfc->f_copy_word = _dwarf_memcpy_swap_bytes; + intfc->f_endian = DW_OBJECT_MSB; + } +#endif /* LITTLE- BIG-ENDIAN */ + _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func_nl; + /* The following sets f_machine. */ + res = _dwarf_load_elf_header(intfc,errcode); + if (res != DW_DLV_OK) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_elf_nlaccess(localdoas); + localdoas = 0; + return res; + } + /* Not loading progheaders */ + res = _dwarf_load_elf_sectheaders(intfc,errcode); + if (res != DW_DLV_OK) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_elf_nlaccess(localdoas); + localdoas = 0; + return res; + } + /* We are not looking at symbol strings for now. */ + res = _dwarf_load_elf_symstr(intfc,errcode); + if (res == DW_DLV_ERROR) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_elf_nlaccess(localdoas); + localdoas = 0; + return res; + } + res = _dwarf_load_elf_symtab_symbols(intfc,errcode); + if (res == DW_DLV_ERROR) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_elf_nlaccess(localdoas); + localdoas = 0; + return res; + } + for ( i = 1; i < intfc->f_loc_shdr.g_count; ++i) { + struct generic_shdr *shp = 0; + Dwarf_Unsigned section_type = 0; + + shp = intfc->f_shdr +i; + section_type = shp->gh_type; + if (section_type == SHT_RELA) { + /* Possibly we should check if the target section + is one we care about before loading rela + FIXME */ + res = _dwarf_load_elf_rela(intfc,i,errcode); + if (res == DW_DLV_ERROR) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_elf_nlaccess(localdoas); + localdoas = 0; + return res; + } + } + } +#if 0 + /* Right now we don't need the .rel sections.Maybe later.*/ + res = _dwarf_load_elf_rel(intfc,i,errcode); + if (res != DW_DLV_OK) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_elf_nlaccess(localdoas); + localdoas = 0; + return res; + } +#endif + free(localdoas); + localdoas = 0; + return DW_DLV_OK; +} + + +static int +_dwarf_elf_object_access_init( + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + Dwarf_Obj_Access_Interface **binary_interface, + int *localerrnum) +{ + + int res = 0; + dwarf_elf_object_access_internals_t *internals = 0; + Dwarf_Obj_Access_Interface *intfc = 0; + + internals = malloc(sizeof(dwarf_elf_object_access_internals_t)); + if (!internals) { + *localerrnum = DW_DLE_ALLOC_FAIL; + /* Impossible case, we hope. Give up. */ + return DW_DLV_ERROR; + } + memset(internals,0,sizeof(*internals)); + res = _dwarf_elf_object_access_internals_init(internals, + fd, + ftype, endian, offsetsize, filesize, + access, + localerrnum); + if (res != DW_DLV_OK){ + return res; + } + + intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); + if (!intfc) { + /* Impossible case, we hope. Give up. */ + free(internals); + *localerrnum = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + /* Initialize the interface struct */ + intfc->object = internals; + intfc->methods = &elf_nlmethods; + *binary_interface = intfc; + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/dwarf_elfread.h b/thirdparty/dwarf/dwarf_elfread.h new file mode 100644 index 00000000..406c7ff4 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elfread.h @@ -0,0 +1,251 @@ +/* Copyright (c) 2013-2019, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef READELFOBJ_H +#define READELFOBJ_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Use this for rel too. */ +struct generic_rela { + int gr_isrela; /* 0 means rel, non-zero means rela */ + Dwarf_Unsigned gr_offset; + Dwarf_Unsigned gr_info; + Dwarf_Unsigned gr_sym; /* From info */ + Dwarf_Unsigned gr_type; /* From info */ + Dwarf_Signed gr_addend; + unsigned char gr_type2; /*MIPS64*/ + unsigned char gr_type3; /*MIPS64*/ +}; + +/* The following are generic to simplify handling + Elf32 and Elf64. Some fields added where + the two sizes have different extraction code. */ +struct generic_ehdr { + unsigned char ge_ident[EI_NIDENT]; + Dwarf_Unsigned ge_type; + Dwarf_Unsigned ge_machine; + Dwarf_Unsigned ge_version; + Dwarf_Unsigned ge_entry; + Dwarf_Unsigned ge_phoff; + Dwarf_Unsigned ge_shoff; + Dwarf_Unsigned ge_flags; + Dwarf_Unsigned ge_ehsize; + Dwarf_Unsigned ge_phentsize; + Dwarf_Unsigned ge_phnum; + Dwarf_Unsigned ge_shentsize; + Dwarf_Unsigned ge_shnum; + Dwarf_Unsigned ge_shstrndx; +}; +struct generic_phdr { + Dwarf_Unsigned gp_type; + Dwarf_Unsigned gp_flags; + Dwarf_Unsigned gp_offset; + Dwarf_Unsigned gp_vaddr; + Dwarf_Unsigned gp_paddr; + Dwarf_Unsigned gp_filesz; + Dwarf_Unsigned gp_memsz; + Dwarf_Unsigned gp_align; +}; +struct generic_shdr { + Dwarf_Unsigned gh_secnum; + Dwarf_Unsigned gh_name; + const char * gh_namestring; + Dwarf_Unsigned gh_type; + Dwarf_Unsigned gh_flags; + Dwarf_Unsigned gh_addr; + Dwarf_Unsigned gh_offset; + Dwarf_Unsigned gh_size; + Dwarf_Unsigned gh_link; + /* Section index (in an SHT_REL or SHT_RELA section) + of the target section from gh_link. Otherwise 0. */ + Dwarf_Unsigned gh_reloc_target_secnum; + Dwarf_Unsigned gh_info; + Dwarf_Unsigned gh_addralign; + Dwarf_Unsigned gh_entsize; + + /* Zero unless content read in. Malloc space + of size gh_size, in bytes. For dwarf + and strings mainly. free() this if not null*/ + char * gh_content; + + /* If a .rel or .rela section this will point + to generic relocation records if such + have been loaded. + free() this if not null. */ + Dwarf_Unsigned gh_relcount; + struct generic_rela * gh_rels; + + /* For SHT_GROUP based grouping, which + group is this section in. 0 unknown, + 1 DW_GROUP_NUMBER_BASE base DWARF, + 2 DW_GROUPNUMBER_DWO dwo sections, 3+ + are in an SHT_GROUP. GNU uses this. + set with group number (3+) from SHT_GROUP + and the flags should have SHF_GROUP set + if in SHT_GROUP. Must only be in one group? */ + Dwarf_Unsigned gh_section_group_number; + + /* Content of an SHT_GROUP section as an array + of integers. [0] is the version, which + can only be one(1) . */ + Dwarf_Unsigned * gh_sht_group_array; + /* Number of elements in the gh_sht_group_array. */ + Dwarf_Unsigned gh_sht_group_array_count; + + /* TRUE if .debug_info .eh_frame etc. */ + char gh_is_dwarf; +}; + +struct generic_dynentry { + Dwarf_Unsigned gd_tag; + /* gd_val stands in for d_ptr and d_val union, + the union adds nothing in practice since + we expect ptrsize <= ulongest. */ + Dwarf_Unsigned gd_val; + Dwarf_Unsigned gd_dyn_file_offset; +}; + +struct generic_symentry { + Dwarf_Unsigned gs_name; + Dwarf_Unsigned gs_value; + Dwarf_Unsigned gs_size; + Dwarf_Unsigned gs_info; + Dwarf_Unsigned gs_other; + Dwarf_Unsigned gs_shndx; + /* derived */ + Dwarf_Unsigned gs_bind; + Dwarf_Unsigned gs_type; +}; + +struct location { + const char *g_name; + Dwarf_Unsigned g_offset; + Dwarf_Unsigned g_count; + Dwarf_Unsigned g_entrysize; + Dwarf_Unsigned g_totalsize; +}; + +typedef struct elf_filedata_s { + /* f_ident[0] == 'E' means it is elf and + elf_filedata_s is the struct involved. + Other means error/corruption of some kind. + f_ident[1] is a version number. + Only version 1 is defined. */ + char f_ident[8]; + char * f_path; /* non-null if known. Must be freed */ + int f_fd; + int f_machine; /* EM_* */ + int f_destruct_close_fd; + int f_is_64bit; + unsigned f_endian; + Dwarf_Unsigned f_filesize; + /* Elf size, not DWARF. 32 or 64 */ + Dwarf_Small f_offsetsize; + Dwarf_Small f_pointersize; + int f_ftype; + + Dwarf_Unsigned f_max_secdata_offset; + Dwarf_Unsigned f_max_progdata_offset; + + void (*f_copy_word) (void *, const void *, unsigned long); + + struct location f_loc_ehdr; + struct generic_ehdr* f_ehdr; + + struct location f_loc_shdr; + struct generic_shdr* f_shdr; + + struct location f_loc_phdr; + struct generic_phdr* f_phdr; + + char *f_elf_shstrings_data; /* section name strings */ + /* length of currentsection. Might be zero..*/ + Dwarf_Unsigned f_elf_shstrings_length; + /* size of malloc-d space */ + Dwarf_Unsigned f_elf_shstrings_max; + + /* This is the .dynamic section */ + struct location f_loc_dynamic; + struct generic_dynentry * f_dynamic; + Dwarf_Unsigned f_dynamic_sect_index; + + /* .dynsym, .dynstr */ + struct location f_loc_dynsym; + struct generic_symentry* f_dynsym; + char *f_dynsym_sect_strings; + Dwarf_Unsigned f_dynsym_sect_strings_max; + Dwarf_Unsigned f_dynsym_sect_strings_sect_index; + Dwarf_Unsigned f_dynsym_sect_index; + + /* .symtab .strtab */ + struct location f_loc_symtab; + struct generic_symentry* f_symtab; + char * f_symtab_sect_strings; + Dwarf_Unsigned f_symtab_sect_strings_max; + Dwarf_Unsigned f_symtab_sect_strings_sect_index; + Dwarf_Unsigned f_symtab_sect_index; + + /* Starts at 3. 0,1,2 used specially. */ + Dwarf_Unsigned f_sg_next_group_number; + /* Both the following will be zero unless there + are explicit Elf groups. */ + Dwarf_Unsigned f_sht_group_type_section_count; + Dwarf_Unsigned f_shf_group_flag_section_count; + Dwarf_Unsigned f_dwo_group_section_count; +} dwarf_elf_object_access_internals_t; + +int dwarf_construct_elf_access(int fd, + const char *path, + dwarf_elf_object_access_internals_t **ep,int *errcode); +int dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t *ep,int *errcode); +int _dwarf_load_elf_header(dwarf_elf_object_access_internals_t *ep,int *errcode); +int _dwarf_load_elf_sectheaders(dwarf_elf_object_access_internals_t* ep,int *errcode); + +int _dwarf_load_elf_symtab_symbols(dwarf_elf_object_access_internals_t *ep,int *errcode); +int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode); + + +int _dwarf_load_elf_rela(dwarf_elf_object_access_internals_t *ep, + Dwarf_Unsigned secnum, int *errcode); + +#ifndef EI_NIDENT +#define EI_NIDENT 16 +#endif /* EI_NIDENT */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* READELFOBJ_H */ diff --git a/thirdparty/dwarf/dwarf_elfstructs.h b/thirdparty/dwarf/dwarf_elfstructs.h new file mode 100644 index 00000000..64545258 --- /dev/null +++ b/thirdparty/dwarf/dwarf_elfstructs.h @@ -0,0 +1,218 @@ +/* +Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Typed in from the SystemV Application Binary Interface + but using char arrays instead of variables as + for reading we don't need the struct members to be + variables. This simplifies configure. + + https://www.uclibc.org/docs/elf-64-gen.pdf used as source + of Elf64 fields. + + It is expected code including this will have included + an official (for various definitions needed) + before including this. But that is not strictly necessary + given other headers. + + The structs were all officially defined so files + could be mapped in. Fields are arranged so + there will not be gaps and we need not deal with + alignment-gaps. +*/ + +#ifndef DW_ELFSTRUCTS_H +#define DW_ELFSTRUCTS_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef EI_NIDENT +#define EI_NIDENT 16 +#endif + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; + TYP(e_type,2); + TYP(e_machine,2); + TYP(e_version,4); + TYP(e_entry,4); + TYP(e_phoff,4); + TYP(e_shoff,4); + TYP(e_flags,4); + TYP(e_ehsize,2); + TYP(e_phentsize,2); + TYP(e_phnum,2); + TYP(e_shentsize,2); + TYP(e_shnum,2); + TYP(e_shstrndx,2); +} dw_elf32_ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; + TYP(e_type,2); + TYP(e_machine,2); + TYP(e_version,4); + TYP(e_entry,8); + TYP(e_phoff,8); + TYP(e_shoff,8); + TYP(e_flags,4); + TYP(e_ehsize,2); + TYP(e_phentsize,2); + TYP(e_phnum,2); + TYP(e_shentsize,2); + TYP(e_shnum,2); + TYP(e_shstrndx,2); +} dw_elf64_ehdr; + +typedef struct +{ + TYP(p_type,4); + TYP(p_offset,4); + TYP(p_vaddr,4); + TYP(p_paddr,4); + TYP(p_filesz,4); + TYP(p_memsz,4); + TYP(p_flags,4); + TYP(p_align,4); +} dw_elf32_phdr; + +typedef struct +{ + TYP(p_type,4); + TYP(p_flags,4); + TYP(p_offset,8); + TYP(p_vaddr,8); + TYP(p_paddr,8); + TYP(p_filesz,8); + TYP(p_memsz,8); + TYP(p_align,8); +} dw_elf64_phdr; + +typedef struct +{ + TYP(sh_name,4); + TYP(sh_type,4); + TYP(sh_flags,4); + TYP(sh_addr,4); + TYP(sh_offset,4); + TYP(sh_size,4); + TYP(sh_link,4); + TYP(sh_info,4); + TYP(sh_addralign,4); + TYP(sh_entsize,4); +}dw_elf32_shdr; + +typedef struct +{ + TYP(sh_name,4); + TYP(sh_type,4); + TYP(sh_flags,8); + TYP(sh_addr,8); + TYP(sh_offset,8); + TYP(sh_size,8); + TYP(sh_link,4); + TYP(sh_info,4); + TYP(sh_addralign,8); + TYP(sh_entsize,8); +}dw_elf64_shdr; + +typedef struct +{ + TYP(r_offset,4); + TYP(r_info,4); +} dw_elf32_rel; + +typedef struct +{ + TYP(r_offset,8); + TYP(r_info,8); +} dw_elf64_rel; + +typedef struct +{ + TYP(r_offset,4); + TYP(r_info,4); + TYP(r_addend,4); /* signed */ +} dw_elf32_rela; + +typedef struct +{ + TYP(r_offset,8); + TYP(r_info,8); + TYP(r_addend,8); /* signed */ +} dw_elf64_rela; + + +typedef struct { + TYP(st_name,4); + TYP(st_value,4); + TYP(st_size,4); + unsigned char st_info[1]; + unsigned char st_other[1]; + TYP(st_shndx,2); +} dw_elf32_sym; + +typedef struct { + TYP(st_name,4); + unsigned char st_info[1]; + unsigned char st_other[1]; + TYP(st_shndx,2); + TYP(st_value,8); + TYP(st_size,8); +} dw_elf64_sym; + + +typedef struct +{ + TYP(d_tag,4); /* signed */ + TYP(d_val,4); /* Union in original */ +} dw_elf32_dyn; + +typedef struct +{ + TYP(d_tag,8); /* signed */ + TYP(d_val,8); /* Union in original */ +} dw_elf64_dyn; + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DW_ELFSTRUCTS_H */ diff --git a/thirdparty/dwarf/dwarf_errmsg_list.c b/thirdparty/dwarf/dwarf_errmsg_list.h similarity index 71% rename from thirdparty/dwarf/dwarf_errmsg_list.c rename to thirdparty/dwarf/dwarf_errmsg_list.h index a211bac4..3c26f20c 100644 --- a/thirdparty/dwarf/dwarf_errmsg_list.c +++ b/thirdparty/dwarf/dwarf_errmsg_list.h @@ -1,7 +1,6 @@ /* - Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2008-2016 David Anderson. All Rights Reserved. + Portions Copyright (C) 2008-2018 David Anderson. All Rights Reserved. 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 @@ -24,13 +23,9 @@ USA. */ +#ifndef DWARF_ERRMSG_LIST_H +#define DWARF_ERRMSG_LIST_H -#ifdef TESTING -#include "config.h" -#include "dwarf_incl.h" -#include -#include /* For exit() declaration etc. */ -#endif /* TESTING */ /* Array to hold string representation of errors. Any time a define is added to the list in libdwarf.h, a string should be @@ -54,7 +49,7 @@ const char *_dwarf_errmsgs[] = { "DW_DLE_IOF (7) I/O failure ", "DW_DLE_MAF (8) memory allocation failure ", "DW_DLE_IA (9) invalid argument ", - "DW_DLE_MDE (10) mangled debugging entry ", + "DW_DLE_MDE (10) mangled debugging entry:libelf detected error", "DW_DLE_MLE (11) mangled line number entry ", "DW_DLE_FNO (12) file not open ", "DW_DLE_FNR (13) file not a regular file ", @@ -119,7 +114,7 @@ const char *_dwarf_errmsgs[] = { "DW_DLE_CU_LENGTH_ERROR (47)", "DW_DLE_VERSION_STAMP_ERROR (48)", "DW_DLE_ABBREV_OFFSET_ERROR (49)", - "DW_DLE_ADDRESS_SIZE_ERROR (50) Either too large or zero", + "DW_DLE_ADDRESS_SIZE_ERROR (50) size too large", "DW_DLE_DEBUG_INFO_PTR_NULL (51)", "DW_DLE_DIE_NULL (52)", "DW_DLE_STRING_OFFSET_BAD (53)", @@ -222,7 +217,7 @@ const char *_dwarf_errmsgs[] = { "DW_DLE_ELF_GETIDENT_ERROR (148)", "DW_DLE_NO_AT_MIPS_FDE (149)", "DW_DLE_NO_CIE_FOR_FDE (150)", - "DW_DLE_DIE_ABBREV_LIST_NULL (151)", + "DW_DLE_DIE_ABBREV_LIST_NULL (151) No abbrev exists for the requested abbrev code" , "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE (152)", "DW_DLE_DEBUG_FUNCNAMES_NULL (153) .debug_funcnames section present but " "elf_getdata() failed or section is zero-length", @@ -258,11 +253,11 @@ const char *_dwarf_errmsgs[] = { "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)", "DW_DLE_MACINFO_MALLOC_FAIL (180)", "DW_DLE_DEBUGMACINFO_ERROR (181)", - "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182)", - "DW_DLE_DEBUG_MACRO_MAX_BAD (183)", - "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184)", - "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185)", - "DW_DLE_DEBUG_MACRO_INCONSISTENT (186)", + "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182) in .debug_macinfo", + "DW_DLE_DEBUG_MACRO_MAX_BAD (183) in .debug_macinfo", + "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184) in .debug_macinfo", + "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185) in .debug_macinfo", + "DW_DLE_DEBUG_MACRO_INCONSISTENT (186) in .debug_macinfo", "DW_DLE_DF_NO_CIE_AUGMENTATION(187)", "DW_DLE_DF_REG_NUM_TOO_HIGH(188)", "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)", @@ -424,104 +419,105 @@ const char *_dwarf_errmsgs[] = { "DW_DLE_ERRONEOUS_XU_INDEX_SECTION(345) XU means cu_ or tu_ index", "DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH(346) Inconsistent line table, corrupted.", "DW_DLE_COMPRESSED_EMPTY_SECTION(347) corrupt section data", + "DW_DLE_SIZE_WRAPAROUND(348) Impossible string length", + "DW_DLE_ILLOGICAL_TSEARCH(349) Impossible sitauation. Corrupted data?", + "DW_DLE_BAD_STRING_FORM(350) Not a currently allowed form", + "DW_DLE_DEBUGSTR_ERROR(351) problem generating .debug_str section", + "DW_DLE_DEBUGSTR_UNEXPECTED_REL(352) string relocation will be wrong.", + "DW_DLE_DISCR_ARRAY_ERROR(353) Internal error in dwarf_discr_list()", + "DW_DLE_LEB_OUT_ERROR(354) Insufficient buffer to turn integer to leb", + "DW_DLE_SIBLING_LIST_IMPROPER(355) Corrupt dwarf", + "DW_DLE_LOCLIST_OFFSET_BAD(356) Corrupt dwarf", + "DW_DLE_LINE_TABLE_BAD(357) Corrupt line table", + "DW_DLE_DEBUG_LOClISTS_DUPLICATE(358)", + "DW_DLE_DEBUG_RNGLISTS_DUPLICATE(359)", + "DW_DLE_ABBREV_OFF_END(360)", + "DW_DLE_FORM_STRING_BAD_STRING(361) string runs off end of data", + "DW_DLE_AUGMENTATION_STRING_OFF_END(362) augmenation runs off of its section", + "DW_DLE_STRING_OFF_END_PUBNAMES_LIKE(363) one of the global sections, string bad", + "DW_DLE_LINE_STRING_BAD(364) runs off end of line data", + "DW_DLE_DEFINE_FILE_STRING_BAD(365) runs off end of section", + "DW_DLE_MACRO_STRING_BAD(366) DWARF5 macro def/undef string runs off section data", + "DW_DLE_MACINFO_STRING_BAD(367) DWARF2..4 macro def/undef string runs off section data", + "DW_DLE_ZLIB_UNCOMPRESS_ERROR(368) Surely an invalid uncompress length", + "DW_DLE_IMPROPER_DWO_ID(369)", + "DW_DLE_GROUPNUMBER_ERROR(370) An error determining default target group number", + "DW_DLE_ADDRESS_SIZE_ZERO(371)", + "DW_DLE_DEBUG_NAMES_HEADER_ERROR(372)", + "DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR(373) corrupt dwarf", + "DW_DLE_DEBUG_NAMES_PAD_NON_ZERO(374) corrupt dwarf", + "DW_DLE_DEBUG_NAMES_OFF_END(375) corrupt dwarf", + "DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW(376) Surprising overrun of fixed size array", + "DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION(377)", + "DW_DLE_DEBUG_NAMES_NULL_POINTER(378) null argument", + "DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG(379) index outside valid range", + "DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET(380) offset outside entrypool", + "DW_DLE_DEBUG_NAMES_UNHANDLED_FORM(381) Might be corrupt dwarf or incomplete DWARF support", + "DW_DLE_LNCT_CODE_UNKNOWN(382)", + "DW_DLE_LNCT_FORM_CODE_NOT_HANDLED(383) Might be bad form or just not implemented", + "DW_DLE_LINE_HEADER_LENGTH_BOTCH(384) Internal libdwarf error", + "DW_DLE_STRING_HASHTAB_IDENTITY_ERROR(385) Internal libdwarf error", + "DW_DLE_UNIT_TYPE_NOT_HANDLED(386) Possibly incomplete dwarf5 support", + "DW_DLE_GROUP_MAP_ALLOC(387) Out of malloc space", + "DW_DLE_GROUP_MAP_DUPLICATE(388) Each section # should appear once", + "DW_DLE_GROUP_COUNT_ERROR(389) An inconsistency in map entry count", + "DW_DLE_GROUP_INTERNAL_ERROR(390) libdwarf data corruption", + "DW_DLE_GROUP_LOAD_ERROR(391) corrupt data?", + "DW_DLE_GROUP_LOAD_READ_ERROR(392)", + "DW_DLE_AUG_DATA_LENGTH_BAD(393) Data does not fit in section", + "DW_DLE_ABBREV_MISSING(394) Unable to find abbrev for DIE", + "DW_DLE_NO_TAG_FOR_DIE(395)", + "DW_DLE_LOWPC_WRONG_CLASS(396) found in dwarf_lowpc()", + "DW_DLE_HIGHPC_WRONG_FORM(397) found in dwarf_highpc()", + "DW_DLE_STR_OFFSETS_BASE_WRONG_FORM(398)", + "DW_DLE_DATA16_OUTSIDE_SECTION(399)", + "DW_DLE_LNCT_MD5_WRONG_FORM(400)", + "DW_DLE_LINE_HEADER_CORRUPT(401) possible data corruption", + "DW_DLE_STR_OFFSETS_NULLARGUMENT(402) improper call", + "DW_DLE_STR_OFFSETS_NULL_DBG(403) improper call", + "DW_DLE_STR_OFFSETS_NO_MAGIC(404) improper call", + "DW_DLE_STR_OFFSETS_ARRAY_SIZE(405) Not a multiple of entry size", + "DW_DLE_STR_OFFSETS_VERSION_WRONG(406) Must be 5 ", + "DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG(407) Requested outside bound", + "DW_DLE_STR_OFFSETS_EXTRA_BYTES(408) Unused non-zero bytes end section", + "DW_DLE_DUP_ATTR_ON_DIE(409) Compiler error, object improper DWARF", + "DW_DLE_SECTION_NAME_BIG(410) Caller provided insufficient room for section name", + "DW_DLE_FILE_UNAVAILABLE(411). Unable find/read object file", + "DW_DLE_FILE_WRONG_TYPE(412). Not an object type we recognize.", + "DW_DLE_SIBLING_OFFSET_WRONG(413). Corrupt dwarf.", + "DW_DLE_OPEN_FAIL(414) Unable to open, possibly a bad filename", + "DW_DLE_OFFSET_SIZE(415) Offset size is neither 32 nor 64", + "DW_DLE_MACH_O_SEGOFFSET_BAD(416) corrupt object", + "DW_DLE_FILE_OFFSET_BAD(417) corrupt object", + "DW_DLE_SEEK_ERROR(418). Seek failed, corrupt object", + "DW_DLE_READ_ERROR(419). Read failed, corrupt object", + "DW_DLE_ELF_CLASS_BAD(420) Corrupt object.", + "DW_DLE_ELF_ENDIAN_BAD(421) Corrupt object.", + "DW_DLE_ELF_VERSION_BAD(422) Corrupt object.", + "DW_DLE_FILE_TOO_SMALL(423) File is too small to be an object file.", + "DW_DLE_PATH_SIZE_TOO_SMALL(424) buffer passed to dwarf_object_detector_path is too small.", + "DW_DLE_BAD_TYPE_SIZE(425) At compile time the build configured itself improperly.", + "DW_DLE_PE_SIZE_SMALL(426) File too small to be valid PE object.", + "DW_DLE_PE_OFFSET_BAD(427) Calculated offset too large. Corrupt object.", + "DW_DLE_PE_STRING_TOO_LONG(428) Increase size for call.", + "DW_DLE_IMAGE_FILE_UNKNOWN_TYPE(429) a PE object has an unknown machine type, not 0x14c, 0x200 or 0x8664", + "DW_DLE_LINE_TABLE_LINENO_ERROR(430) Negative line number impossible. Corrupted line table.", + "DW_DLE_PRODUCER_CODE_NOT_AVAILABLE(431) Without elf.h the producer code is not available.", + "DW_DLE_NO_ELF_SUPPORT(432) libdwarf was compiled without Elf object support.", + "DW_DLE_NO_STREAM_RELOC_SUPPORT(433) no elf.h so cannot generate STREAM relocations", + "DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR(434) Flag value passed in not allowed.", + "DW_DLE_SECTION_SIZE_ERROR(435) Corrupt Elf. Section size not a multiple of section entry size", + "DW_DLE_INTERNAL_NULL_POINTER(436) Internal libdwarf call:null pointer", + "DW_DLE_SECTION_STRING_OFFSET_BAD(437) Corrupt Elf, an offset to section name is invalid", + "DW_DLE_SECTION_INDEX_BAD(438) Corrupt Elf, a section index is incorrect", + "DW_DLE_INTEGER_TOO_SMALL(439) Build does not allow reading Elf64", + "DW_DLE_ELF_SECTION_LINK_ERROR(440) Corrupt Elf, section links in error", + "DW_DLE_ELF_SECTION_GROUP_ERROR(441) Corrupt Elf, section group information problem", + "DW_DLE_ELF_SECTION_COUNT_MISMATCH(442) Corrupt Elf or libdwarf bug.", + "DW_DLE_ELF_STRING_SECTION_MISSING(443) Corrupt Elf, string section wrong type", + "DW_DLE_SEEK_OFF_END(444) Corrupt Elf. Seek past the end not allowed", + "DW_DLE_READ_OFF_END(445) Corrupt Elf. A read would read past end of object", + "DW_DLE_ELF_SECTION_ERROR(446) Section offset or size is too large. Corrupt elf object.", + "DW_DLE_ELF_STRING_SECTION_ERROR(447) String section missing. Corrupt Elf", }; - -#ifdef TESTING -#define FALSE 0 -#define TRUE 1 -/* This is just to help localize the error. */ -static void -printone(int i) -{ - int arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); - if ( i >= arraysize) { - printf("%d is outside the array! Missing something!\n",i); - } else { - printf("%d is: %s\n",i,_dwarf_errmsgs[i]); - } -} - -/* Arbitrary. A much smaller max length value would work. */ -#define MAX_NUM_LENGTH 12 - -/* return TRUE on error */ -static int -check_errnum_mismatches(unsigned i) -{ - unsigned nextstop = 0; - const char *sp = _dwarf_errmsgs[i]; - const char *cp = sp; - unsigned innit = FALSE; - unsigned prevchar = 0; - unsigned value = 0; - - for( ; *cp; cp++) { - unsigned c = 0; - c = 0xff & *cp; - if ( c >= '0' && c <= '9' && !innit - && prevchar != '(') { - /* Skip. number part of macro name. */ - prevchar = c; - continue; - } - if ( c >= '0' && c <= '9') { - value = value * 10; - value += (c - '0'); - nextstop++; - if (nextstop > MAX_NUM_LENGTH) { - break; - } - innit = TRUE; - } else { - if (innit) { - break; - } - prevchar= c; - } - } - if (innit) { - if (i != value) { - return TRUE; - } - return FALSE; - } - /* There is no number to check. Ignore it. */ - printf("mismatch value %d has no errnum to check %s\n",i,_dwarf_errmsgs[i]); - return TRUE; -} - -int -main() -{ - unsigned arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); - unsigned i = 0; - - if (arraysize != (DW_DLE_LAST + 1)) { - printf("Missing or extra entry in dwarf error strings array" - " %u expected DW_DLE_LAST+1 %d\n",arraysize, DW_DLE_LAST+1); - printone(1); - printone(100); - printone(200); - printone(250); - printone(260); - printone(262); - printone(263); - printone(264); - printone(265); - printone(273); - printone(274); - printone(275); - printone(300); - printone(328); - exit(1); - } - for ( i = 0; i <= DW_DLE_LAST; ++i) { - if(check_errnum_mismatches(i)) { - printf("mismatch value %d is: %s\n",i,_dwarf_errmsgs[i]); - exit(1); - } - } - /* OK. */ - exit(0); -} -#endif /* TESTING */ +#endif /* DWARF_ERRMSG_LIST_H */ diff --git a/thirdparty/dwarf/dwarf_error.c b/thirdparty/dwarf/dwarf_error.c index 29f319fe..d4c5e701 100644 --- a/thirdparty/dwarf/dwarf_error.c +++ b/thirdparty/dwarf/dwarf_error.c @@ -25,24 +25,21 @@ */ - - #include "config.h" -#include "dwarf_incl.h" -#ifdef HAVE_ELF_H -#include -#endif - #include #include #include #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" + /* Array to hold string representation of errors. Any time a define is added to the list in libdwarf.h, a string should be added to this Array */ -#include "dwarf_errmsg_list.c" +#include "dwarf_errmsg_list.h" /* This function performs error handling as described in the libdwarf consumer document section 3. Dbg is the Dwarf_debug @@ -63,7 +60,7 @@ a Dwarf_Error struct creation. */ void -_dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) +_dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Signed errval) { Dwarf_Error errptr; @@ -75,20 +72,23 @@ _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) if (dbg != NULL) { errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); - if (errptr == NULL) { + if (!errptr) { errptr = &_dwarf_failsafe_error; - errptr->er_static_alloc = 1; + errptr->er_static_alloc = DE_STATIC; + } else { + errptr->er_static_alloc = DE_STANDARD; } } else { /* We have no dbg to work with. dwarf_init failed. We hack up a special area. */ errptr = _dwarf_special_no_dbg_error_malloc(); - if (errptr == NULL) { + if (!errptr) { errptr = &_dwarf_failsafe_error; - errptr->er_static_alloc = 1; + errptr->er_static_alloc = DE_STATIC; + } else { + errptr->er_static_alloc = DE_MALLOC; } } - errptr->er_errval = errval; *error = errptr; return; @@ -98,7 +98,7 @@ _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); if (errptr == NULL) { errptr = &_dwarf_failsafe_error; - errptr->er_static_alloc = 1; + errptr->er_static_alloc = DE_STATIC; } errptr->er_errval = errval; dbg->de_errhand(errptr, dbg->de_errarg); @@ -116,27 +116,30 @@ _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) Dwarf_Unsigned dwarf_errno(Dwarf_Error error) { - if (error == NULL) { + if (!error) { return (0); } - return (error->er_errval); } +char* +dwarf_errmsg_by_number(Dwarf_Unsigned errornum ) +{ + if (errornum >= + (Dwarf_Signed)(sizeof(_dwarf_errmsgs) / sizeof(char *))) { + return "Dwarf_Error value out of range"; + } + return ((char *) _dwarf_errmsgs[errornum]); +} + /* */ char * dwarf_errmsg(Dwarf_Error error) { - if (error == NULL) { + if (!error) { return "Dwarf_Error is NULL"; } - - if (error->er_errval >= - (Dwarf_Signed)(sizeof(_dwarf_errmsgs) / sizeof(char *))) { - return "Dwarf_Error value out of range"; - } - - return ((char *) _dwarf_errmsgs[error->er_errval]); + return dwarf_errmsg_by_number(error->er_errval); } diff --git a/thirdparty/dwarf/dwarf_error.h b/thirdparty/dwarf/dwarf_error.h index a6b2e642..051513c5 100644 --- a/thirdparty/dwarf/dwarf_error.h +++ b/thirdparty/dwarf/dwarf_error.h @@ -28,10 +28,13 @@ void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, - Dwarf_Sword errval); + Dwarf_Signed errval); +#define DE_STANDARD 0 /* Normal alloc attached to dbg. */ +#define DE_STATIC 1 /* Using global static var */ +#define DE_MALLOC 2 /* Using malloc space */ struct Dwarf_Error_s { - Dwarf_Sword er_errval; + Dwarf_Signed er_errval; /* If non-zero the Dwarf_Error_s struct is not malloc'd. To aid when malloc returns NULL. @@ -49,5 +52,3 @@ struct Dwarf_Error_s { }; extern struct Dwarf_Error_s _dwarf_failsafe_error; - - diff --git a/thirdparty/dwarf/dwarf_form.c b/thirdparty/dwarf/dwarf_form.c index e20ad069..54fded21 100644 --- a/thirdparty/dwarf/dwarf_form.c +++ b/thirdparty/dwarf/dwarf_form.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2008-2016 David Anderson. All rights reserved. + Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -27,10 +27,16 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_die_deliv.h" +#define TRUE 1 +#define FALSE 0 + /* This code was repeated many times, now it is all in one place. */ static int @@ -94,11 +100,94 @@ dwarf_whatform_direct(Dwarf_Attribute attr, return (DW_DLV_OK); } +/* Pass in the content of a block and the length of that + content. On success return DW_DLV_OK and set *value_count + to the size of the array returned through value_array. */ +int +dwarf_uncompress_integer_block_a(Dwarf_Debug dbg, + Dwarf_Unsigned input_length_in_bytes, + void * input_block, + Dwarf_Unsigned * value_count, + Dwarf_Signed ** value_array, + Dwarf_Error * error) +{ + Dwarf_Unsigned output_length_in_units = 0; + Dwarf_Signed * output_block = 0; + unsigned i = 0; + char * ptr = 0; + int remain = 0; + Dwarf_Signed * array = 0; + Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ + input_length_in_bytes; -/* This code was contributed some time ago - and the return value is in the wrong form, - but we are not fixing it. - As of 2016 it is not clear that Sun Sparc + output_length_in_units = 0; + remain = input_length_in_bytes; + ptr = input_block; + while (remain > 0) { + Dwarf_Unsigned len = 0; + Dwarf_Signed value = 0; + int rres = 0; + + rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, + &len, &value,endptr); + if (rres != DW_DLV_OK) { + _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER); + return DW_DLV_ERROR; + } + ptr += len; + remain -= len; + output_length_in_units++; + } + if (remain != 0) { + _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + + output_block = (Dwarf_Signed*) + _dwarf_get_alloc(dbg, + DW_DLA_STRING, + output_length_in_units * sizeof(Dwarf_Signed)); + if (!output_block) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + array = output_block; + remain = input_length_in_bytes; + ptr = input_block; + for (i=0; i0; i++) { + Dwarf_Signed num; + Dwarf_Unsigned len; + int sres = 0; + + sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, + &len, &num,endptr); + if (sres != DW_DLV_OK) { + dwarf_dealloc(dbg,output_block,DW_DLA_STRING); + _dwarf_error(NULL, error, DW_DLE_LEB_IMPROPER); + return DW_DLV_ERROR; + } + ptr += len; + remain -= len; + array[i] = num; + } + + if (remain != 0) { + dwarf_dealloc(dbg, (unsigned char *)output_block, + DW_DLA_STRING); + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + + *value_count = output_length_in_units; + *value_array = output_block; + return DW_DLV_OK; +} + +/* This code was contributed around 2007 + and the return value is in the wrong form. + See dwarf_uncompress_integer_block_a() above. + + As of 2019 it is not clear that Sun Sparc compilers are in current use, nor whether there is a reason to make reads of this data format safe from corrupted object files. @@ -119,13 +208,19 @@ dwarf_uncompress_integer_block( unsigned i = 0; char * ptr = 0; int remain = 0; - Dwarf_sfixed * array = 0; + /* This only applies to Sun and there an unsigned + is 4 bytes so this works. As with + most linux. */ + unsigned * array = 0; + Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ + input_length_in_bytes; if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return((void *)DW_DLV_BADADDR); } + if (unit_is_signed == false || unit_length_in_bits != 32 || input_block == NULL || @@ -144,8 +239,15 @@ dwarf_uncompress_integer_block( remain = input_length_in_bytes; ptr = input_block; while (remain > 0) { - Dwarf_Word len = 0; - _dwarf_decode_s_leb128((unsigned char *)ptr, &len); + Dwarf_Unsigned len = 0; + Dwarf_Signed value = 0; + int rres = 0; + + rres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, + &len, &value,endptr); + if (rres != DW_DLV_OK) { + return ((void *)DW_DLV_BADADDR); + } ptr += len; remain -= len; output_length_in_units++; @@ -169,13 +271,20 @@ dwarf_uncompress_integer_block( /* then uncompress again and copy into new buffer */ - array = (Dwarf_sfixed *) output_block; + array = (unsigned *) output_block; remain = input_length_in_bytes; ptr = input_block; for (i=0; i0; i++) { Dwarf_Signed num; - Dwarf_Word len; - num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len); + Dwarf_Unsigned len; + int sres = 0; + + sres = _dwarf_decode_s_leb128_chk((unsigned char *)ptr, + &len, &num,endptr); + if (sres != DW_DLV_OK) { + dwarf_dealloc(dbg,output_block,DW_DLA_STRING); + return ((void *) DW_DLV_BADADDR); + } ptr += len; remain -= len; array[i] = num; @@ -354,19 +463,19 @@ dwarf_formref(Dwarf_Attribute attr, case DW_FORM_ref2: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Half), + attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); break; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_ufixed), + attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); break; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Unsigned), + attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); break; @@ -403,9 +512,13 @@ dwarf_formref(Dwarf_Attribute attr, It is used for precompiled headers. The valid condition will be: 'offset == maximumoffset'. */ Dwarf_Half tag = 0; - if (DW_DLV_OK != dwarf_tag(attr->ar_die,&tag,error)) { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); + int tres = dwarf_tag(attr->ar_die,&tag,error); + if (tres != DW_DLV_OK) { + if (tres == DW_DLV_NO_ENTRY) { + _dwarf_error(dbg, error, DW_DLE_NO_TAG_FOR_DIE); + return DW_DLV_ERROR; + } + return DW_DLV_ERROR; } if (DW_TAG_compile_unit != tag && @@ -414,7 +527,7 @@ dwarf_formref(Dwarf_Attribute attr, _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); /* Return the incorrect offset for better error reporting */ *ret_offset = (offset); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } } *ret_offset = (offset); @@ -528,19 +641,19 @@ dwarf_global_formref(Dwarf_Attribute attr, case DW_FORM_ref2: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Half), + attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref4: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_ufixed), + attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); goto fixoffset; case DW_FORM_ref8: READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Unsigned), + attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); goto fixoffset; @@ -579,7 +692,7 @@ dwarf_global_formref(Dwarf_Attribute attr, return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_ufixed), + attr->ar_debug_ptr, DWARF_32BIT_SIZE, error, section_end); /* The offset is global. */ break; @@ -589,7 +702,7 @@ dwarf_global_formref(Dwarf_Attribute attr, return (DW_DLV_ERROR); } READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Unsigned), + attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); /* The offset is global. */ break; @@ -607,11 +720,11 @@ dwarf_global_formref(Dwarf_Attribute attr, } if (length_size == 4) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_ufixed), + attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); } else if (length_size == 8) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Unsigned), + attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); } else { _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); @@ -622,21 +735,22 @@ dwarf_global_formref(Dwarf_Attribute attr, case DW_FORM_sec_offset: case DW_FORM_GNU_ref_alt: /* 2013 GNU extension */ case DW_FORM_GNU_strp_alt: /* 2013 GNU extension */ - case DW_FORM_strp_sup: /* DWARF5 */ + case DW_FORM_strp_sup: /* DWARF5, sup string section */ + case DW_FORM_line_strp: /* DWARF5, .debug_line_str section */ { /* DW_FORM_sec_offset first exists in DWARF4.*/ /* It is up to the caller to know what the offset of DW_FORM_sec_offset, DW_FORM_strp_sup - or DW_FORM_GNU_strp_alt refers to, + or DW_FORM_GNU_strp_alt etc refer to, the offset is not going to refer to .debug_info! */ unsigned length_size = cu_context->cc_length_size; if (length_size == 4) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_ufixed), + attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); } else if (length_size == 8) { READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Unsigned), + attr->ar_debug_ptr, DWARF_64BIT_SIZE, error,section_end); } else { _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); @@ -667,7 +781,7 @@ dwarf_global_formref(Dwarf_Attribute attr, elsewhere. New May 2014*/ int -_dwarf_get_addr_index_itself(UNUSEDARG int theform, +_dwarf_get_addr_index_itself(int theform, Dwarf_Small *info_ptr, Dwarf_Debug dbg, Dwarf_CU_Context cu_context, @@ -679,8 +793,36 @@ _dwarf_get_addr_index_itself(UNUSEDARG int theform, section_end = _dwarf_calculate_info_section_end_ptr(cu_context); - DECODE_LEB128_UWORD_CK(info_ptr,index, - dbg,error,section_end); + switch(theform){ + case DW_FORM_GNU_addr_index: + case DW_FORM_addrx: + DECODE_LEB128_UWORD_CK(info_ptr,index, + dbg,error,section_end); + break; + case DW_FORM_addrx1: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 1, + error,section_end); + break; + case DW_FORM_addrx2: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 2, + error,section_end); + break; + case DW_FORM_addrx3: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 3, + error,section_end); + break; + case DW_FORM_addrx4: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 4, + error,section_end); + break; + default: + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX); + return DW_DLV_ERROR; + } *val_out = index; return DW_DLV_OK; } @@ -713,9 +855,54 @@ dwarf_get_debug_addr_index(Dwarf_Attribute attr, return DW_DLV_ERROR; } +static int +dw_read_index_val_itself(Dwarf_Debug dbg, + unsigned theform, + Dwarf_Small *info_ptr, + Dwarf_Small *section_end, + Dwarf_Unsigned *return_index, + Dwarf_Error *error) +{ + Dwarf_Unsigned index = 0; + + switch(theform) { + case DW_FORM_strx: + case DW_FORM_GNU_str_index: + DECODE_LEB128_UWORD_CK(info_ptr,index, + dbg,error,section_end); + break; + case DW_FORM_strx1: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 1, + error,section_end); + break; + case DW_FORM_strx2: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 2, + error,section_end); + break; + case DW_FORM_strx3: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 3, + error,section_end); + break; + case DW_FORM_strx4: + READ_UNALIGNED_CK(dbg, index, Dwarf_Unsigned, + info_ptr, 4, + error,section_end); + break; + default: + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_STR_INDEX); + return DW_DLV_ERROR; + } + *return_index = index; + return DW_DLV_OK; +} + /* Part of DebugFission. So a dwarf dumper application can get the index and print it for the user. - A convenience function. New May 2014*/ + A convenience function. New May 2014 + Also used with DWARF5 forms. */ int dwarf_get_debug_str_index(Dwarf_Attribute attr, Dwarf_Unsigned *return_index, @@ -726,6 +913,9 @@ dwarf_get_debug_str_index(Dwarf_Attribute attr, Dwarf_Debug dbg = 0; int res = 0; Dwarf_Byte_Ptr section_end = 0; + Dwarf_Unsigned index = 0; + Dwarf_Small *info_ptr = 0; + int indxres = 0; res = get_attr_dbg(&dbg,&cu_context,attr,error); if (res != DW_DLV_OK) { @@ -733,21 +923,80 @@ dwarf_get_debug_str_index(Dwarf_Attribute attr, } section_end = _dwarf_calculate_info_section_end_ptr(cu_context); + info_ptr = attr->ar_debug_ptr; - if (theform == DW_FORM_strx || - theform == DW_FORM_GNU_str_index) { - Dwarf_Unsigned index = 0; - Dwarf_Small *info_ptr = attr->ar_debug_ptr; - - DECODE_LEB128_UWORD_CK(info_ptr,index, - dbg,error,section_end); + indxres = dw_read_index_val_itself(dbg, theform, info_ptr, + section_end, &index,error); + if (indxres == DW_DLV_OK) { *return_index = index; - return DW_DLV_OK; + return indxres; } - _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_NOT_ADDR_INDEX); - return (DW_DLV_ERROR); + return indxres; +} + + +int +_dwarf_extract_data16(Dwarf_Debug dbg, + Dwarf_Small *data, + Dwarf_Small *section_start, + Dwarf_Small *section_end, + Dwarf_Form_Data16 * returned_val, + Dwarf_Error *error) +{ + Dwarf_Small *data16end = 0; + + data16end = data + sizeof(Dwarf_Form_Data16); + if (data < section_start || + section_end < data16end) { + _dwarf_error(dbg, error,DW_DLE_DATA16_OUTSIDE_SECTION); + return DW_DLV_ERROR; + } + memcpy(returned_val, data, sizeof(Dwarf_Form_Data16)); + return DW_DLV_OK; + } +int +dwarf_formdata16(Dwarf_Attribute attr, + Dwarf_Form_Data16 * returned_val, + Dwarf_Error* error) +{ + Dwarf_Half attrform = 0; + Dwarf_CU_Context cu_context = 0; + Dwarf_Debug dbg = 0; + int res = 0; + Dwarf_Small *section_end = 0; + Dwarf_Unsigned section_length = 0; + Dwarf_Small *section_start = 0; + + if (attr == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return DW_DLV_ERROR; + } + if (returned_val == NULL) { + _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); + return DW_DLV_ERROR; + } + attrform = attr->ar_attribute_form; + if (attrform != DW_FORM_data16) { + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); + return DW_DLV_ERROR; + } + res = get_attr_dbg(&dbg,&cu_context,attr,error); + if (res != DW_DLV_OK) { + return res; + } + section_start = _dwarf_calculate_info_section_start_ptr( + cu_context,§ion_length); + section_end = section_start + section_length; + + res = _dwarf_extract_data16(dbg, attr->ar_debug_ptr, + section_start, section_end, + returned_val, error); + return res; +} + + int @@ -764,8 +1013,12 @@ dwarf_formaddr(Dwarf_Attribute attr, return res; } attrform = attr->ar_attribute_form; - if (attrform == DW_FORM_GNU_addr_index || - attrform == DW_FORM_addrx) { + if (attrform == DW_FORM_addrx || + attrform == DW_FORM_addrx1 || + attrform == DW_FORM_addrx2 || + attrform == DW_FORM_addrx3 || + attrform == DW_FORM_addrx4 || + attrform == DW_FORM_GNU_addr_index) { res = _dwarf_look_in_local_and_tied( attrform, cu_context, @@ -805,6 +1058,7 @@ dwarf_formflag(Dwarf_Attribute attr, Dwarf_Bool * ret_bool, Dwarf_Error * error) { Dwarf_CU_Context cu_context = 0; + Dwarf_Debug dbg = 0; if (attr == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); @@ -816,8 +1070,9 @@ dwarf_formflag(Dwarf_Attribute attr, _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); return (DW_DLV_ERROR); } + dbg = cu_context->cc_dbg; - if (cu_context->cc_dbg == NULL) { + if (dbg == NULL) { _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); return (DW_DLV_ERROR); } @@ -832,38 +1087,49 @@ dwarf_formflag(Dwarf_Attribute attr, *ret_bool = *(Dwarf_Small *)(attr->ar_debug_ptr); return (DW_DLV_OK); } - _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); + _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } +Dwarf_Bool +_dwarf_allow_formudata(unsigned form) +{ + switch(form) { + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + case DW_FORM_loclistx: + return TRUE; + } + return FALSE; +} /* If the form is DW_FORM_constx and the .debug_addr section is missing, this returns DW_DLV_ERROR and the error number in the Dwarf_Error is DW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION. When that arises, a consumer should call dwarf_get_debug_addr_index() and use that on the appropriate .debug_addr section in the executable or another object. */ + int -dwarf_formudata(Dwarf_Attribute attr, - Dwarf_Unsigned * return_uval, Dwarf_Error * error) +_dwarf_formudata_internal(Dwarf_Debug dbg, + unsigned form, + Dwarf_Byte_Ptr data, + Dwarf_Byte_Ptr section_end, + Dwarf_Unsigned *return_uval, + Dwarf_Unsigned *bytes_read, + Dwarf_Error *error) { Dwarf_Unsigned ret_value = 0; - Dwarf_Debug dbg = 0; - Dwarf_CU_Context cu_context = 0; - Dwarf_Byte_Ptr section_end = 0; - - int res = get_attr_dbg(&dbg,&cu_context,attr,error); - if (res != DW_DLV_OK) { - return res; - } - section_end = - _dwarf_calculate_info_section_end_ptr(cu_context); - switch (attr->ar_attribute_form) { + switch (form) { case DW_FORM_data1: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Small), + data, sizeof(Dwarf_Small), error,section_end); *return_uval = ret_value; + *bytes_read = 1; return DW_DLV_OK; /* READ_UNALIGNED does the right thing as it reads @@ -871,36 +1137,41 @@ dwarf_formudata(Dwarf_Attribute attr, So we can just assign to *return_uval. */ case DW_FORM_data2:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Half), + data, DWARF_HALF_SIZE, error,section_end); *return_uval = ret_value; + *bytes_read = 2; return DW_DLV_OK; } case DW_FORM_data4:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - attr->ar_debug_ptr, - sizeof(Dwarf_ufixed), + data, + DWARF_32BIT_SIZE, error,section_end); *return_uval = ret_value; + *bytes_read = DWARF_32BIT_SIZE;; return DW_DLV_OK; } case DW_FORM_data8:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - attr->ar_debug_ptr, - sizeof(Dwarf_Unsigned), + data, + DWARF_64BIT_SIZE, error,section_end); *return_uval = ret_value; + *bytes_read = DWARF_64BIT_SIZE; return DW_DLV_OK; } break; /* real udata */ + case DW_FORM_loclistx: case DW_FORM_udata: { - Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; - - DECODE_LEB128_UWORD_CK(tmp, ret_value,dbg,error,section_end); + Dwarf_Unsigned leblen = 0; + DECODE_LEB128_UWORD_LEN_CK(data, ret_value,leblen, + dbg,error,section_end); *return_uval = ret_value; + *bytes_read = leblen; return DW_DLV_OK; } @@ -915,6 +1186,31 @@ dwarf_formudata(Dwarf_Attribute attr, return (DW_DLV_ERROR); } +int +dwarf_formudata(Dwarf_Attribute attr, + Dwarf_Unsigned * return_uval, Dwarf_Error * error) +{ + Dwarf_Debug dbg = 0; + Dwarf_CU_Context cu_context = 0; + Dwarf_Byte_Ptr section_end = 0; + Dwarf_Unsigned bytes_read = 0; + Dwarf_Byte_Ptr data = attr->ar_debug_ptr; + unsigned form = 0; + + int res = get_attr_dbg(&dbg,&cu_context,attr,error); + if (res != DW_DLV_OK) { + return res; + } + section_end = + _dwarf_calculate_info_section_end_ptr(cu_context); + form = attr->ar_attribute_form; + + res = _dwarf_formudata_internal(dbg, + form, data, section_end, return_uval, + &bytes_read, error); + return res; +} + int dwarf_formsdata(Dwarf_Attribute attr, @@ -934,6 +1230,10 @@ dwarf_formsdata(Dwarf_Attribute attr, switch (attr->ar_attribute_form) { case DW_FORM_data1: + if ( attr->ar_debug_ptr >= section_end) { + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return DW_DLV_ERROR; + } *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_ptr); return DW_DLV_OK; @@ -943,7 +1243,7 @@ dwarf_formsdata(Dwarf_Attribute attr, case DW_FORM_data2:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, - sizeof(Dwarf_Shalf), + DWARF_HALF_SIZE, error,section_end); *return_sval = (Dwarf_Shalf) ret_value; return DW_DLV_OK; @@ -953,21 +1253,29 @@ dwarf_formsdata(Dwarf_Attribute attr, case DW_FORM_data4:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, - sizeof(Dwarf_sfixed), + DWARF_32BIT_SIZE, error,section_end); - *return_sval = (Dwarf_sfixed) ret_value; + SIGN_EXTEND(ret_value,DWARF_32BIT_SIZE); + *return_sval = (Dwarf_Signed) ret_value; return DW_DLV_OK; } case DW_FORM_data8:{ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Signed, attr->ar_debug_ptr, - sizeof(Dwarf_Signed), + DWARF_64BIT_SIZE, error,section_end); + /* No SIGN_EXTEND needed, we are filling all bytes already.*/ *return_sval = (Dwarf_Signed) ret_value; return DW_DLV_OK; } + /* DW_FORM_implicit_const is a value in the + abbreviations, not in the DIEs. */ + case DW_FORM_implicit_const: + *return_sval = attr->ar_implicit_const; + return DW_DLV_OK; + case DW_FORM_sdata: { Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; @@ -1020,21 +1328,21 @@ dwarf_formblock(Dwarf_Attribute attr, case DW_FORM_block2: READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_Half), + attr->ar_debug_ptr, DWARF_HALF_SIZE, error,section_end); - data = attr->ar_debug_ptr + sizeof(Dwarf_Half); + data = attr->ar_debug_ptr + DWARF_HALF_SIZE; break; case DW_FORM_block4: READ_UNALIGNED_CK(dbg, length, Dwarf_Unsigned, - attr->ar_debug_ptr, sizeof(Dwarf_ufixed), + attr->ar_debug_ptr, DWARF_32BIT_SIZE, error,section_end); - data = attr->ar_debug_ptr + sizeof(Dwarf_ufixed); + data = attr->ar_debug_ptr + DWARF_32BIT_SIZE; break; case DW_FORM_block: { Dwarf_Byte_Ptr tmp = attr->ar_debug_ptr; - Dwarf_Word leblen = 0; + Dwarf_Unsigned leblen = 0; DECODE_LEB128_UWORD_LEN_CK(tmp, length, leblen, dbg,error,section_end); @@ -1058,6 +1366,14 @@ dwarf_formblock(Dwarf_Attribute attr, _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); return (DW_DLV_ERROR); } + if (data > section_end) { + _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); + return (DW_DLV_ERROR); + } + if ((data + length) > section_end) { + _dwarf_error(dbg, error, DW_DLE_FORM_BLOCK_LENGTH_ERROR); + return (DW_DLV_ERROR); + } ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1); if (ret_block == NULL) { @@ -1077,7 +1393,8 @@ dwarf_formblock(Dwarf_Attribute attr, int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, - Dwarf_Small *info_data_ptr, + Dwarf_Small *data_ptr, + Dwarf_Small *end_data_ptr, UNUSEDARG Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, @@ -1089,21 +1406,22 @@ _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, Dwarf_Unsigned offsetintable = 0; Dwarf_Unsigned end_offsetintable = 0; int res = 0; - Dwarf_Byte_Ptr section_end = 0; + int idxres = 0; res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); if (res != DW_DLV_OK) { return res; } + idxres = dw_read_index_val_itself(dbg, + attrform,data_ptr,end_data_ptr,&index_to_offset_entry,error); + if ( idxres != DW_DLV_OK) { + return idxres; + } - section_end = - _dwarf_calculate_info_section_end_ptr(cu_context); - DECODE_LEB128_UWORD_CK(info_data_ptr,index_to_offset_entry, - dbg,error,section_end); /* DW_FORM_GNU_str_index has no 'base' value. - DW_FORM_strx has a base value + DW_FORM_strx* has a base value for the offset table */ - if( attrform == DW_FORM_strx) { + if( attrform != DW_FORM_GNU_str_index) { res = _dwarf_get_string_base_attr_value(dbg,cu_context, &offset_base,error); if (res != DW_DLV_OK) { @@ -1161,6 +1479,10 @@ _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, if (attrform == DW_FORM_strp || attrform == DW_FORM_line_strp || attrform == DW_FORM_GNU_str_index || + attrform == DW_FORM_strx1 || + attrform == DW_FORM_strx2 || + attrform == DW_FORM_strx3 || + attrform == DW_FORM_strx4 || attrform == DW_FORM_strx) { /* The 'offset' into .debug_str or .debug_line_str is given, here we turn that into a pointer. */ @@ -1181,7 +1503,7 @@ _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, secbegin = dbg->de_debug_line_str.dss_data; strbegin= dbg->de_debug_line_str.dss_data + offset; } else { - /* DW_FORM_strp */ + /* DW_FORM_strp etc */ res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); if (res != DW_DLV_OK) { return res; @@ -1197,7 +1519,8 @@ _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, _dwarf_error(dbg, error, errcode); return (DW_DLV_ERROR); } - res= _dwarf_check_string_valid(dbg,secbegin,strbegin, secend,error); + res= _dwarf_check_string_valid(dbg,secbegin,strbegin, secend, + errcode,error); if (res != DW_DLV_OK) { return res; } @@ -1209,9 +1532,6 @@ _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, return (DW_DLV_ERROR); } - - - /* Contrary to pre-2005 documentation, The string pointer returned thru return_str must never have dwarf_dealloc() applied to it. @@ -1255,7 +1575,8 @@ dwarf_formstring(Dwarf_Attribute attr, case DW_FORM_string: { Dwarf_Small *begin = attr->ar_debug_ptr; - res= _dwarf_check_string_valid(dbg,secdataptr,begin, secend,error); + res= _dwarf_check_string_valid(dbg,secdataptr,begin, secend, + DW_DLE_FORM_STRING_BAD_STRING,error); if (res != DW_DLV_OK) { return res; } @@ -1309,10 +1630,15 @@ dwarf_formstring(Dwarf_Attribute attr, return res; } case DW_FORM_GNU_str_index: - case DW_FORM_strx: { + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: { Dwarf_Unsigned offsettostr= 0; res = _dwarf_extract_string_offset_via_str_offsets(dbg, infoptr, + secend, attr->ar_attribute, attr->ar_attribute_form, cu_context, @@ -1391,6 +1717,7 @@ _dwarf_get_string_from_tied(Dwarf_Debug dbg, return (DW_DLV_ERROR); } res= _dwarf_check_string_valid(tieddbg,secbegin,strbegin, secend, + DW_DLE_NO_TIED_STRING_AVAILABLE, &localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); @@ -1426,7 +1753,7 @@ dwarf_formexprloc(Dwarf_Attribute attr, } if (attr->ar_attribute_form == DW_FORM_exprloc ) { Dwarf_Die die = 0; - Dwarf_Word leb_len = 0; + Dwarf_Unsigned leb_len = 0; Dwarf_Byte_Ptr section_start = 0; Dwarf_Unsigned section_len = 0; Dwarf_Byte_Ptr section_end = 0; @@ -1448,7 +1775,8 @@ dwarf_formexprloc(Dwarf_Attribute attr, } die = attr->ar_die; /* Is the block entirely in the section, or is - there bug somewhere? */ + there bug somewhere? + Here the final addr may be 1 past end of section. */ if (_dwarf_reference_outside_section(die, (Dwarf_Small *)addr, ((Dwarf_Small *)addr)+exprlen +leb_len)) { _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); diff --git a/thirdparty/dwarf/dwarf_frame.c b/thirdparty/dwarf/dwarf_frame.c index b27d6533..2eceef77 100644 --- a/thirdparty/dwarf/dwarf_frame.c +++ b/thirdparty/dwarf/dwarf_frame.c @@ -1,35 +1,46 @@ /* - Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ #include "config.h" -#include "dwarf_incl.h" #include #include +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_arange.h" /* Using Arange as a way to build a list */ @@ -48,6 +59,21 @@ #define MIN(a,b) (((a) < (b))? a:b) +#if 0 +static void +dump_bytes(const char *msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + printf("%s (0x%lx) ",msg,(unsigned long)start); + for (; cur < end; cur++) { + printf("%02x", *cur); + } + printf("\n"); +} +#endif /* 0 */ + + static int dwarf_initialize_fde_table(Dwarf_Debug dbg, struct Dwarf_Frame_s *fde_table, unsigned table_real_data_size, @@ -191,7 +217,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Cie cie, Dwarf_Debug dbg, Dwarf_Half reg_num_of_cfa, - Dwarf_Sword * returned_count, + Dwarf_Signed * returned_count, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error *error) @@ -224,8 +250,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, pc-value corresponding to the frame instructions. Starts at zero when the caller has no value to pass in. */ - /* Must be min de_pointer_size bytes and must be at least sizeof - Dwarf_ufixed */ + /* Must be min de_pointer_size bytes and must be at least 4 */ Dwarf_Unsigned adv_loc = 0; unsigned reg_count = dbg->de_frame_reg_rules_entry_count; @@ -249,7 +274,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, dbg->de_pointer_size; /* Counts the number of frame instructions executed. */ - Dwarf_Word instr_count = 0; + Dwarf_Unsigned instr_count = 0; /* These contain the current fields of the current frame instruction. */ @@ -284,8 +309,8 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, /* These are the alignment_factors taken from the Cie provided. When no input Cie is provided they are set to 1, because only factored offsets are required. */ - Dwarf_Sword code_alignment_factor = 1; - Dwarf_Sword data_alignment_factor = 1; + Dwarf_Signed code_alignment_factor = 1; + Dwarf_Signed data_alignment_factor = 1; /* This flag indicates when an actual alignment factor is needed. So if a frame instruction that computes an offset using an @@ -293,7 +318,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, is returned because the Cie did not have a valid augmentation. */ Dwarf_Bool need_augmentation = false; - Dwarf_Word i; + Dwarf_Unsigned i; /* Initialize first row from associated Cie. Using temp regs explicity */ @@ -341,7 +366,6 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, } else { need_augmentation = !make_instr; } - instr_ptr = start_instr_ptr; while ((instr_ptr < final_instr_ptr) && (!search_over)) { Dwarf_Small instr = 0; @@ -460,8 +484,11 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, case DW_CFA_advance_loc1: { - fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr; + READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, + instr_ptr, sizeof(Dwarf_Small), + error,final_instr_ptr); instr_ptr += sizeof(Dwarf_Small); + fp_offset = adv_loc; if (need_augmentation) { SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); @@ -482,9 +509,9 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, case DW_CFA_advance_loc2: { READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, - instr_ptr, sizeof(Dwarf_Half), + instr_ptr, DWARF_HALF_SIZE, error,final_instr_ptr); - instr_ptr += sizeof(Dwarf_Half); + instr_ptr += DWARF_HALF_SIZE; fp_offset = adv_loc; if (need_augmentation) { @@ -505,9 +532,31 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, case DW_CFA_advance_loc4: { READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, - instr_ptr, sizeof(Dwarf_ufixed), + instr_ptr, DWARF_32BIT_SIZE, error,final_instr_ptr); - instr_ptr += sizeof(Dwarf_ufixed); + instr_ptr += DWARF_32BIT_SIZE; + fp_offset = adv_loc; + + if (need_augmentation) { + SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION); + } + adv_loc *= code_alignment_factor; + + possible_subsequent_pc = current_loc + adv_loc; + search_over = search_pc && + (possible_subsequent_pc > search_pc_val); + /* If gone past pc needed, retain old pc. */ + if (!search_over) { + current_loc = possible_subsequent_pc; + } + break; + } + case DW_CFA_MIPS_advance_loc8: + { + READ_UNALIGNED_CK(dbg, adv_loc, Dwarf_Unsigned, + instr_ptr, DWARF_64BIT_SIZE, + error,final_instr_ptr); + instr_ptr += DWARF_64BIT_SIZE; fp_offset = adv_loc; if (need_augmentation) { @@ -768,7 +817,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, cfa_reg.ru_value_type = DW_EXPR_EXPRESSION; cfa_reg.ru_offset_or_block_len = block_len; cfa_reg.ru_block = instr_ptr; - fp_offset = (Dwarf_Unsigned) instr_ptr; + fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; instr_ptr += block_len; } break; @@ -793,7 +842,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION; localregtab[lreg].ru_offset_or_block_len = block_len; localregtab[lreg].ru_block = instr_ptr; - fp_offset = (Dwarf_Unsigned) instr_ptr; + fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; fp_register = reg_no; instr_ptr += block_len; } @@ -958,7 +1007,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION; localregtab[lreg].ru_offset_or_block_len = block_len; localregtab[lreg].ru_block = instr_ptr; - fp_offset = (Dwarf_Unsigned) instr_ptr; + fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr; instr_ptr += block_len; fp_register = reg_no; @@ -983,11 +1032,16 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, register exists yet to save this in */ case DW_CFA_GNU_args_size: { - Dwarf_Unsigned lreg; + UNUSEDARG Dwarf_Unsigned lreg = 0; DECODE_LEB128_UWORD_CK(instr_ptr, lreg, dbg,error,final_instr_ptr); - reg_no = (reg_num_type) lreg; + /* We have nowhere to store lreg. + FIXME + This is the total size of arguments pushed on + the stack. + https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA.junk/dwarfext.html + */ break; } @@ -1082,14 +1136,14 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, } if (make_instr) { - /* Allocate list of pointers to Dwarf_Frame_Op's. */ + /* Allocate array of Dwarf_Frame_Op structs. */ head_instr_block = (Dwarf_Frame_Op *) _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count); if (head_instr_block == NULL) { SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL); } - /* Store pointers to Dwarf_Frame_Op's in this list and + /* Store Dwarf_Frame_Op instances in this array and deallocate the structs that chain the Dwarf_Frame_Op's. */ curr_instr_item = head_instr_chain; for (i = 0; i < instr_count; i++) { @@ -1102,7 +1156,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN); } *ret_frame_instr = head_instr_block; - *returned_count = (Dwarf_Sword) instr_count; + *returned_count = (Dwarf_Signed) instr_count; } else { *returned_count = 0; } @@ -1126,9 +1180,13 @@ _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr, Dwarf_Error *error) { Dwarf_Unsigned uvalue = 0; - Dwarf_Word leb128_length = 0; + Dwarf_Unsigned leb128_length = 0; if (version == 1) { + if (frame_ptr >= section_end) { + _dwarf_error(NULL, error, DW_DLE_DF_FRAME_DECODING_ERROR); + return DW_DLV_ERROR; + } *size = 1; uvalue = *(unsigned char *) frame_ptr; *return_address_register = uvalue; @@ -1240,7 +1298,6 @@ dwarf_get_fde_list(Dwarf_Debug dbg, DW_CIE_ID, /* use_gnu_cie_calc= */ 0, error); - return res; } @@ -1315,8 +1372,9 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg, if (res == DW_DLV_ERROR) { return res; } - if (res == DW_DLV_NO_ENTRY) + if (res == DW_DLV_NO_ENTRY) { return res; + } fde_ptr = prefix.cf_addr_after_prefix; cie_id = prefix.cf_cie_id; /* Pass NULL, not section pointer, for 3rd argument. @@ -1548,7 +1606,7 @@ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, { Dwarf_Debug dbg = 0; Dwarf_Cie cie = 0; - Dwarf_Sword icount = 0; + Dwarf_Signed icount = 0; int res = 0; if (fde == NULL) { @@ -1589,7 +1647,8 @@ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, return DW_DLV_ERROR; } dwarf_init_reg_rules_ru(cie->ci_initial_table->fr_reg, - 0, cie->ci_initial_table->fr_reg_count,dbg->de_frame_rule_initial_value); + 0, cie->ci_initial_table->fr_reg_count, + 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, @@ -1669,7 +1728,7 @@ dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, /* Table size: DW_REG_TABLE_SIZE */ struct Dwarf_Frame_s fde_table; - Dwarf_Sword i = 0; + Dwarf_Signed i = 0; struct Dwarf_Reg_Rule_s *rule = NULL; struct Dwarf_Regtable_Entry_s *out_rule = NULL; int res = 0; @@ -1742,7 +1801,7 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, { struct Dwarf_Frame_s fde_table; - Dwarf_Sword i = 0; + Dwarf_Signed i = 0; int res = 0; struct Dwarf_Reg_Rule_s *rule = NULL; struct Dwarf_Regtable_Entry3_s *out_rule = NULL; @@ -1758,6 +1817,9 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, res = dwarf_initialize_fde_table(dbg, &fde_table, output_table_real_data_size, error); + if (res != DW_DLV_OK) { + return res; + } /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ @@ -1802,11 +1864,14 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, return DW_DLV_OK; } -/* Gets the register info for a single register at a given PC value +/* Obsolete as of 2006. + Gets the register info for a single register at a given PC value for the FDE specified. This is the old MIPS interface and should no longer be used. - Use dwarf_get_fde_info_for_reg3() instead. */ + Use dwarf_get_fde_info_for_reg3() instead. + It can not handle DWARF3 or later properly as it + assumes the CFA is representable as a table column. */ int dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, @@ -1899,6 +1964,48 @@ dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Ptr * block_ptr, Dwarf_Addr * row_pc_out, Dwarf_Error * error) +{ + int res = dwarf_get_fde_info_for_reg3_b(fde, + table_column, pc_requested, value_type, + offset_relevant, register_num, + offset_or_block_len, + block_ptr, + row_pc_out, + /* Not looking for the has_more_rows flag + nor for the next pc in the frame data. */ + NULL,NULL, + error); + return res; +} + + +/* New May 2018. + If one is tracking the value of a single table + column through a function, this lets us + skip to the next pc value easily. + + if pc_requested is a change from the last + pc_requested on this pc, this function + returns *has_more_rows and *subsequent_pc + (null pointers passed are acceptable, the + assignment through the pointer is skipped + if the pointer is null). + Otherwise *has_more_rows and *subsequent_pc + are not set. + */ +int +dwarf_get_fde_info_for_reg3_b(Dwarf_Fde fde, + Dwarf_Half table_column, + Dwarf_Addr pc_requested, + Dwarf_Small * value_type, + Dwarf_Signed * offset_relevant, + Dwarf_Signed * register_num, + Dwarf_Signed * offset_or_block_len, + Dwarf_Ptr * block_ptr, + Dwarf_Addr * row_pc_out, + Dwarf_Bool * has_more_rows, + Dwarf_Addr * subsequent_pc, + Dwarf_Error * error) { struct Dwarf_Frame_s * fde_table = &(fde->fd_fde_table); int res = DW_DLV_ERROR; @@ -1909,6 +2016,9 @@ dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); if (!fde->fd_have_fde_tab || + /* The test is just in case it's not inside the table. For non-MIPS + it could be outside the table and that is just fine, it was + really a mistake to put it in the table in 1993. */ fde->fd_fde_pc_requested != pc_requested) { if (fde->fd_have_fde_tab) { dwarf_free_fde_table(fde_table); @@ -1926,12 +2036,12 @@ dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return (DW_DLV_ERROR); } - + /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks */ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, fde_table, dbg->de_frame_cfa_col_number, - NULL,NULL, + has_more_rows,subsequent_pc, error); if (res != DW_DLV_OK) { dwarf_free_fde_table(fde_table); @@ -1964,10 +2074,18 @@ dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, } -/* New June 11,2016. Two new arguments which - can be used to more efficiently traverse - frame data (primarily for dwarfdump and like - programs). */ +/* New 2006. + For current DWARF, this is a preferred interface. + + Compared to dwarf_get_fde_info_for_reg() + it more correctly deals with the CFA by not + making the CFA a column number, which means + DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE, + a special value, not something one uses as an index. + + See also dwarf_get_fde_info_for_cfa_reg3_b(), which + is slightly preferred. + */ int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, @@ -1995,8 +2113,18 @@ dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, error); return res; } -/* For latest DWARF, this is the preferred interface. - It more portably deals with the CFA by not + +/* New June 11,2016. + For current DWARF, this is a preferred interface. + + Has extra arguments has_more_rows and next_pc + (compared to dwarf_get_fde_info_for_cfa_reg3()) + which can be used to more efficiently traverse + frame data (primarily for dwarfdump and like + programs). + + Like dwarf_get_fde_info_for_cfa_reg3() it + deals with the CFA by not making the CFA a column number, which means DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE, a special value, not something one uses as an index. @@ -2142,11 +2270,6 @@ dwarf_get_fde_at_pc(Dwarf_Fde * fde_data, /* Assumes fde_data table has at least one entry. */ entryfde = *fde_data; FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg); - - if (dbg == NULL) { - _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); - return (DW_DLV_ERROR); - } fdecount = entryfde->fd_is_eh? dbg->de_fde_count_eh:dbg->de_fde_count; { @@ -2205,7 +2328,7 @@ dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Signed * returned_op_count, Dwarf_Error * error) { - Dwarf_Sword instr_count; + Dwarf_Signed instr_count; int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; Dwarf_Small * instr_start = instruction; @@ -2228,10 +2351,6 @@ dwarf_expand_frame_instructions(Dwarf_Cie cie, return DW_DLV_ERROR; } - /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe - as it is just an i_length offset from 'instruction' itself. A - caller has made a big mistake if the result is not a valid - pointer. */ res = _dwarf_exec_frame_instr( /* make_instr= */ true, returned_op_list, /* search_pc */ false, diff --git a/thirdparty/dwarf/dwarf_frame.h b/thirdparty/dwarf/dwarf_frame.h index e7a521a4..f24158e7 100644 --- a/thirdparty/dwarf/dwarf_frame.h +++ b/thirdparty/dwarf/dwarf_frame.h @@ -408,7 +408,7 @@ _dwarf_exec_frame_instr(Dwarf_Bool make_instr, Dwarf_Cie cie, Dwarf_Debug dbg, Dwarf_Half reg_num_of_cfa, - Dwarf_Sword * returned_count, + Dwarf_Signed * returned_count, Dwarf_Bool * has_more_rows, Dwarf_Addr * subsequent_pc, Dwarf_Error * error); diff --git a/thirdparty/dwarf/dwarf_frame2.c b/thirdparty/dwarf/dwarf_frame2.c index e741707a..35f13130 100644 --- a/thirdparty/dwarf/dwarf_frame2.c +++ b/thirdparty/dwarf/dwarf_frame2.c @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it @@ -29,15 +29,46 @@ and related helper functions for reading cie/fde data. */ #include "config.h" -#include "dwarf_incl.h" #include #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_arange.h" /* using Arange as a way to build a list */ +/* For a little information about .eh_frame see + https://stackoverflow.com/questions/14091231/what-do-the-eh-frame-and-eh-frame-hdr-sections-store-exactly + http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html + The above give information about fields and sizes but + very very little about content. + + .eh_frame_hdr contains data for C++ unwinding. Namely + tables for fast access into .eh_frame. +*/ + + + #define TRUE 1 #define FALSE 0 +#if 0 /* FOR DEBUGGING */ +/* For debugging only. */ +static void +dump_bytes(const char *msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + printf("%s (0x%lx) ",msg,(unsigned long)start); + for (; cur < end; cur++) { + printf("%02x", *cur); + } + printf("\n"); +} + +#endif + static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, Dwarf_Cie cur_cie_ptr, Dwarf_Cie * cie_ptr_to_use_out, @@ -62,7 +93,6 @@ static int get_gcc_eh_augmentation(Dwarf_Debug dbg, *size_of_augmentation_data, enum Dwarf_augmentation_type augtype, Dwarf_Small * section_end_pointer, - Dwarf_Small * fde_eh_encoding_out, char *augmentation, Dwarf_Error *error); @@ -89,7 +119,26 @@ static int read_encoded_ptr(Dwarf_Debug dbg, -static int qsort_compare(const void *elem1, const void *elem2); +/* Called by qsort to compare FDE entries. + Consumer code expects the array of FDE pointers to be + in address order. +*/ +static int +qsort_compare(const void *elem1, const void *elem2) +{ + const Dwarf_Fde fde1 = *(const Dwarf_Fde *) elem1; + const Dwarf_Fde fde2 = *(const Dwarf_Fde *) elem2; + Dwarf_Addr addr1 = fde1->fd_initial_location; + Dwarf_Addr addr2 = fde2->fd_initial_location; + + if (addr1 < addr2) { + return -1; + } else if (addr1 > addr2) { + return 1; + } + return 0; +} + /* Adds 'newone' to the end of the list starting at 'head' @@ -141,15 +190,27 @@ validate_length(Dwarf_Debug dbg, Dwarf_Small * ciefde_start, const char * cieorfde) { - Dwarf_Unsigned address_size = cieptr->ci_address_size; + Dwarf_Unsigned address_size = 0; Dwarf_Unsigned length_field_summed = length_size + extension_size; Dwarf_Unsigned total_len = length + length_field_summed; - Dwarf_Unsigned mod = total_len % address_size; + Dwarf_Unsigned mod = 0; + if (cieptr) { + address_size = cieptr->ci_address_size; + } else { + address_size = dbg->de_pointer_size; + } + mod = total_len % address_size; if (mod != 0) { - char msg[DW_HARMLESS_ERROR_MSG_STRING_SIZE]; + static char msg[DW_HARMLESS_ERROR_MSG_STRING_SIZE]; Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr; - snprintf(msg,sizeof(msg), + + if (!cieorfde || (strlen(cieorfde) > 3)) { + /* Coding error or memory corruption? */ + cieorfde = "ERROR!"; + } + + sprintf(msg, "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE" " len=0x%" DW_PR_XZEROS DW_PR_DUx ", len size=0x%" DW_PR_XZEROS DW_PR_DUx @@ -177,10 +238,10 @@ static void print_prefix(struct cie_fde_prefix_s *prefix, int line) { printf("prefix-print, prefix at 0x%lx, line %d\n", - (long) prefix, line); + (unsigned long) prefix, line); printf(" start addr 0x%lx after prefix 0x%lx\n", - (long) prefix->cf_start_addr, - (long) prefix->cf_addr_after_prefix); + (unsigned long) prefix->cf_start_addr, + (unsigned long) prefix->cf_addr_after_prefix); printf(" length 0x%" DW_PR_DUx ", len size %d ext size %d\n", (Dwarf_Unsigned) prefix->cf_length, prefix->cf_local_length_size, @@ -190,10 +251,11 @@ print_prefix(struct cie_fde_prefix_s *prefix, int line) (long) prefix->cf_cie_id_addr); printf (" sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n", - (long) prefix->cf_section_ptr, + (unsigned long) prefix->cf_section_ptr, (Dwarf_Signed) prefix->cf_section_index, (Dwarf_Unsigned) prefix->cf_section_length, - (long) prefix->cf_section_ptr + prefix->cf_section_length); + (unsigned long) prefix->cf_section_ptr + + (unsigned long)prefix->cf_section_length); } #endif @@ -267,7 +329,7 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, Dwarf_Cie head_cie_ptr = NULL; Dwarf_Cie cur_cie_ptr = NULL; Dwarf_Cie tail_cie_ptr = NULL; - Dwarf_Word cie_count = 0; + Dwarf_Unsigned cie_count = 0; /* Points to a list of contiguous pointers to Dwarf_Cie structures. */ @@ -278,13 +340,13 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, cur_fde_ptr are used to chain them up. */ Dwarf_Fde head_fde_ptr = NULL; Dwarf_Fde cur_fde_ptr = NULL; - Dwarf_Word fde_count = 0; + Dwarf_Unsigned fde_count = 0; /* Points to a list of contiguous pointers to Dwarf_Fde structures. */ Dwarf_Fde *fde_list_ptr = NULL; - Dwarf_Word i = 0; + Dwarf_Unsigned i = 0; int res = DW_DLV_ERROR; if (frame_ptr == 0) { @@ -322,8 +384,9 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, if (prefix.cf_cie_id == cie_id_value) { /* This is a CIE. */ Dwarf_Cie cie_ptr_to_use = 0; + int resc = 0; - int resc = dwarf_find_existing_cie_ptr(prefix.cf_start_addr, + resc = dwarf_find_existing_cie_ptr(prefix.cf_start_addr, cur_cie_ptr, &cie_ptr_to_use, head_cie_ptr); @@ -341,13 +404,11 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, use_gnu_cie_calc, &cie_ptr_to_use, error); - /* ASSERT: res==DW_DLV_NO_ENTRY impossible. */ - if (resc == DW_DLV_ERROR) { + if (resc != DW_DLV_OK) { dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resc; } - /* ASSERT res != DW_DLV_NO_ENTRY */ cie_count++; chain_up_cie(cie_ptr_to_use, &head_cie_ptr, &tail_cie_ptr); @@ -371,13 +432,12 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, int resf = DW_DLV_ERROR; Dwarf_Cie cie_ptr_to_use = 0; Dwarf_Fde fde_ptr_to_use = 0; + Dwarf_Small *cieptr_val = 0; - Dwarf_Small *cieptr_val = - get_cieptr_given_offset(prefix.cf_cie_id, - use_gnu_cie_calc, - section_ptr, - prefix.cf_cie_id_addr); - + cieptr_val = get_cieptr_given_offset(prefix.cf_cie_id, + use_gnu_cie_calc, + section_ptr, + prefix.cf_cie_id_addr); resf = dwarf_find_existing_cie_ptr(cieptr_val, cur_cie_ptr, &cie_ptr_to_use, @@ -401,7 +461,7 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); return resf; - } else if (res == DW_DLV_NO_ENTRY) { + } else if (resf == DW_DLV_NO_ENTRY) { return resf; } ++cie_count; @@ -425,14 +485,17 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, error); if (resf == DW_DLV_ERROR) { return resf; + } else if (resf == DW_DLV_NO_ENTRY) { + /* impossible. */ + return resf; } chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr); fde_count++; /* ASSERT: DW_DLV_OK. */ - frame_ptr = fde_ptr_to_use->fd_fde_start + - fde_ptr_to_use->fd_length + - fde_ptr_to_use->fd_length_size + - fde_ptr_to_use->fd_extension_size; + frame_ptr = cur_fde_ptr->fd_fde_start + + cur_fde_ptr->fd_length + + cur_fde_ptr->fd_length_size + + cur_fde_ptr->fd_extension_size; if (frame_ptr < fde_ptr_to_use->fd_fde_instr_start) { /* Sanity check. With a really short fde instruction set and address_size we think is 8 @@ -444,8 +507,6 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH); return DW_DLV_ERROR; } - - continue; } } @@ -468,6 +529,11 @@ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return DW_DLV_ERROR; } + if (!head_cie_ptr) { + /* Should be impossible. */ + _dwarf_error(dbg, error,DW_DLE_DEBUGFRAME_ERROR); + return DW_DLV_ERROR; + } cur_cie_ptr = head_cie_ptr; for (i = 0; i < cie_count; i++) { *(cie_list_ptr + i) = cur_cie_ptr; @@ -542,14 +608,13 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, in DWARF2 or DWARF3 cie data, below we set it right if it is present. */ Dwarf_Half address_size = dbg->de_pointer_size; - Dwarf_Small eh_fde_encoding = 0; Dwarf_Small *augmentation = 0; Dwarf_Half segment_size = 0; - Dwarf_Sword data_alignment_factor = -1; - Dwarf_Word code_alignment_factor = 4; + Dwarf_Signed data_alignment_factor = -1; + Dwarf_Unsigned code_alignment_factor = 4; Dwarf_Unsigned return_address_register = 31; int local_length_size = 0; - Dwarf_Word leb128_length = 0; + Dwarf_Unsigned leb128_length = 0; Dwarf_Unsigned cie_aug_data_len = 0; Dwarf_Small *cie_aug_data = 0; Dwarf_Addr gnu_personality_handler_addr = 0; @@ -557,14 +622,18 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, unsigned char gnu_lsda_encoding = 0; unsigned char gnu_fde_begin_encoding = 0; int res = 0; + Dwarf_Small version = 0; enum Dwarf_augmentation_type augt = aug_unknown; - /* This is a CIE, Common Information Entry: See the dwarf spec, section 6.4.1 */ - Dwarf_Small version = *(Dwarf_Small *) frame_ptr; + if (frame_ptr >= section_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return DW_DLV_ERROR; + } + version = *(Dwarf_Small *) frame_ptr; if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); @@ -581,7 +650,8 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, augmentation = frame_ptr; res = _dwarf_check_string_valid(dbg,section_pointer, - frame_ptr,section_ptr_end,error); + frame_ptr,section_ptr_end, + DW_DLE_AUGMENTATION_STRING_OFF_END,error); if (res != DW_DLV_OK) { return res; } @@ -617,7 +687,7 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, } address_size = *((unsigned char *)frame_ptr); if (address_size < 1) { - _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR); + _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO); return (DW_DLV_ERROR); } if (address_size > sizeof(Dwarf_Addr)) { @@ -637,16 +707,18 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, } } - /* Not a great test. FIXME */ + /* Not a great test. But the DECODE* do checking so ok. */ if ((frame_ptr+2) >= section_ptr_end) { _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error,section_ptr_end); - code_alignment_factor = (Dwarf_Word) lreg; - data_alignment_factor = - (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr, - &leb128_length); + code_alignment_factor = (Dwarf_Unsigned) lreg; + res = (Dwarf_Signed) _dwarf_decode_s_leb128_chk(frame_ptr, + &leb128_length,&data_alignment_factor,section_ptr_end); + if(res != DW_DLV_OK) { + return res; + } frame_ptr = frame_ptr + leb128_length; /* Not a great test. FIXME */ if ((frame_ptr+1) >= section_ptr_end) { @@ -675,11 +747,11 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, break; case aug_irix_exception_table:{ Dwarf_Unsigned lreg = 0; - Dwarf_Word length_of_augmented_fields; + Dwarf_Unsigned length_of_augmented_fields; /* Decode the length of augmented fields. */ DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error,section_ptr_end); - length_of_augmented_fields = (Dwarf_Word) lreg; + length_of_augmented_fields = (Dwarf_Unsigned) lreg; /* set the frame_ptr to point at the instruction start. */ frame_ptr += length_of_augmented_fields; } @@ -698,7 +770,6 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment, augt, section_ptr_end, - &eh_fde_encoding, (char *) augmentation,error); if (err == DW_DLV_ERROR) { _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN); @@ -722,9 +793,14 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, dbg,error,section_ptr_end); cie_aug_data_len = adlen; cie_aug_data = frame_ptr; - if (frame_ptr + adlen > section_ptr_end) { - _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); - return DW_DLV_ERROR; + if (adlen) { + Dwarf_Small *cie_aug_data_end = cie_aug_data+adlen; + if (cie_aug_data_end < cie_aug_data || + cie_aug_data_end > section_ptr_end) { + /* Bad adlen */ + _dwarf_error(dbg, error, DW_DLE_AUG_DATA_LENGTH_BAD); + return DW_DLV_ERROR; + } } resz = gnu_aug_encodings(dbg, (char *) augmentation, @@ -773,7 +849,7 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, new_cie->ci_cie_version_number = version; new_cie->ci_initial_table = NULL; - new_cie->ci_length = (Dwarf_Word) prefix->cf_length; + new_cie->ci_length = (Dwarf_Unsigned) prefix->cf_length; new_cie->ci_length_size = prefix->cf_local_length_size; new_cie->ci_extension_size = prefix->cf_local_extension_size; new_cie->ci_augmentation = (char *) augmentation; @@ -784,6 +860,11 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, (Dwarf_Small) code_alignment_factor; new_cie->ci_return_address_register = return_address_register; new_cie->ci_cie_start = prefix->cf_start_addr; + + if ( frame_ptr > section_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); + return (DW_DLV_ERROR); + } new_cie->ci_cie_instr_start = frame_ptr; new_cie->ci_dbg = dbg; new_cie->ci_augmentation_type = augt; @@ -800,7 +881,12 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, new_cie->ci_section_ptr = prefix->cf_section_ptr; new_cie->ci_section_end = section_ptr_end; new_cie->ci_cie_end = new_cie->ci_cie_start + new_cie->ci_length + - new_cie->ci_length_size+ new_cie->ci_extension_size, + new_cie->ci_length_size+ new_cie->ci_extension_size; + if ( new_cie->ci_cie_end > section_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); + return (DW_DLV_ERROR); + } + /* The Following new in DWARF4 */ new_cie->ci_address_size = address_size; new_cie->ci_segment_size = segment_size; @@ -817,7 +903,8 @@ dwarf_create_cie_from_after_start(Dwarf_Debug dbg, /* Internal function, not called by consumer code. 'prefix' has accumulated the info up thru the cie-id - and now we consume the rest and build a Dwarf_Fde_s structure. */ + and now we consume the rest and build a Dwarf_Fde_s structure. + Can be called with cie_ptr_in NULL from dwarf_frame.c */ int dwarf_create_fde_from_after_start(Dwarf_Debug dbg, @@ -831,12 +918,11 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, Dwarf_Error * error) { Dwarf_Fde new_fde = 0; - Dwarf_Cie cieptr = cie_ptr_in; + Dwarf_Cie cieptr = 0; Dwarf_Small *saved_frame_ptr = 0; Dwarf_Small *initloc = frame_ptr; Dwarf_Signed offset_into_exception_tables - /* must be min dwarf_sfixed in size */ = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; Dwarf_Small *fde_aug_data = 0; Dwarf_Unsigned fde_aug_data_len = 0; @@ -845,11 +931,17 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, bytes in size */ Dwarf_Addr address_range = 0; /* must be min de_pointer_size bytes in size */ - Dwarf_Half address_size = cie_ptr_in->ci_address_size; + Dwarf_Half address_size = 0; Dwarf_Unsigned eh_table_value = 0; Dwarf_Bool eh_table_value_set = FALSE; + /* Temporary assumption. */ + enum Dwarf_augmentation_type augt = aug_empty_string; - enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type; + if (cie_ptr_in) { + cieptr = cie_ptr_in; + address_size = cieptr->ci_address_size; + augt = cieptr->ci_augmentation_type; + } if (augt == aug_gcc_eh_z) { /* If z augmentation this is eh_frame, and initial_location and @@ -894,6 +986,14 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, fde_aug_data_len = adlen; fde_aug_data = frame_ptr; frame_ptr += adlen; + if (adlen) { + if (frame_ptr < fde_aug_data || + frame_ptr >= section_ptr_end ) { + /* Bad adlen */ + _dwarf_error(dbg, error, DW_DLE_AUG_DATA_LENGTH_BAD); + return DW_DLV_ERROR; + } + } } } else { @@ -916,24 +1016,24 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, break; case aug_irix_exception_table:{ Dwarf_Unsigned lreg = 0; - Dwarf_Word length_of_augmented_fields = 0; + Dwarf_Unsigned length_of_augmented_fields = 0; DECODE_LEB128_UWORD_CK(frame_ptr, lreg, dbg,error,section_ptr_end); - length_of_augmented_fields = (Dwarf_Word) lreg; + length_of_augmented_fields = (Dwarf_Unsigned) lreg; saved_frame_ptr = frame_ptr; /* The first word is an offset into exception tables. Defined as a 32bit offset even for CC -64. */ - if ((frame_ptr + sizeof(Dwarf_sfixed)) > section_ptr_end) { + if ((frame_ptr + DWARF_32BIT_SIZE) > section_ptr_end) { _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); return DW_DLV_ERROR; } READ_UNALIGNED_CK(dbg, offset_into_exception_tables, - Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed), + Dwarf_Addr, frame_ptr, DWARF_32BIT_SIZE, error,section_ptr_end); SIGN_EXTEND(offset_into_exception_tables, - sizeof(Dwarf_sfixed)); + DWARF_32BIT_SIZE); frame_ptr = saved_frame_ptr + length_of_augmented_fields; } break; @@ -977,6 +1077,11 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return DW_DLV_ERROR; } /* End switch on augmentation type */ + if ( frame_ptr > section_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); + return (DW_DLV_ERROR); + } + new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); if (new_fde == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); @@ -988,16 +1093,24 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, new_fde->fd_extension_size = prefix->cf_local_extension_size; new_fde->fd_is_eh = use_gnu_cie_calc; new_fde->fd_cie_offset = cie_base_offset; - new_fde->fd_cie_index = cieptr->ci_index; + if (cieptr) { + new_fde->fd_cie_index = cieptr->ci_index; + } new_fde->fd_cie = cieptr; new_fde->fd_initial_location = initial_location; new_fde->fd_initial_loc_pos = initloc; new_fde->fd_address_range = address_range; new_fde->fd_fde_start = prefix->cf_start_addr; + new_fde->fd_fde_instr_start = frame_ptr; new_fde->fd_fde_end = prefix->cf_start_addr + prefix->cf_length + prefix->cf_local_length_size + prefix->cf_local_extension_size; + if ( new_fde->fd_fde_end > section_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR); + return (DW_DLV_ERROR); + } + new_fde->fd_dbg = dbg; new_fde->fd_offset_into_exception_tables = offset_into_exception_tables; @@ -1017,33 +1130,10 @@ dwarf_create_fde_from_after_start(Dwarf_Debug dbg, validate_length(dbg,cieptr,new_fde->fd_length, new_fde->fd_length_size, new_fde->fd_extension_size, new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde"); - - *fde_ptr_out = new_fde; return DW_DLV_OK; } -/* Called by qsort to compare FDE entries. - Consumer code expects the array of FDE pointers to be - in address order. -*/ -static int -qsort_compare(const void *elem1, const void *elem2) -{ - const Dwarf_Fde fde1 = *(const Dwarf_Fde *) elem1; - const Dwarf_Fde fde2 = *(const Dwarf_Fde *) elem2; - Dwarf_Addr addr1 = fde1->fd_initial_location; - Dwarf_Addr addr2 = fde2->fd_initial_location; - - if (addr1 < addr2) { - return -1; - } else if (addr1 > addr2) { - return 1; - } - return 0; -} - - /* Read in the common cie/fde prefix, including reading the cie-value which shows which this is: cie or fde. */ int @@ -1250,20 +1340,6 @@ dwarf_create_cie_from_start(Dwarf_Debug dbg, aug_data_len - length of areas aug_data points to. */ -#if 0 /* FOR DEBUGGING */ -/* For debugging only. */ -void -dump_bytes(Dwarf_Small * start, long len) -{ - Dwarf_Small *end = start + len; - Dwarf_Small *cur = start; - - for (; cur < end; cur++) { - printf(" byte %d, data %02x\n", (int) (cur - start), *cur); - } - -} -#endif /* It is not clear if this is entirely correct. */ static int @@ -1437,11 +1513,10 @@ read_encoded_ptr(Dwarf_Debug dbg, case DW_EH_PE_udata4:{ Dwarf_Unsigned ret_value = 0; - /* ASSERT: sizeof(Dwarf_ufixed) == 4 */ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - input_field, sizeof(Dwarf_ufixed),error,section_end); + input_field, DWARF_32BIT_SIZE,error,section_end); *addr = ret_value; - *input_field_updated = input_field + sizeof(Dwarf_ufixed); + *input_field_updated = input_field + DWARF_32BIT_SIZE; } break; @@ -1450,9 +1525,9 @@ read_encoded_ptr(Dwarf_Debug dbg, /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - input_field, sizeof(Dwarf_Unsigned),error,section_end); + input_field, DWARF_64BIT_SIZE,error,section_end); *addr = ret_value; - *input_field_updated = input_field + sizeof(Dwarf_Unsigned); + *input_field_updated = input_field + DWARF_64BIT_SIZE; } break; @@ -1478,13 +1553,12 @@ read_encoded_ptr(Dwarf_Debug dbg, case DW_EH_PE_sdata4:{ Dwarf_Unsigned val = 0; - /* ASSERT: sizeof(Dwarf_ufixed) == 4 */ READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, - sizeof(Dwarf_ufixed),error,section_end); - SIGN_EXTEND(val, sizeof(Dwarf_ufixed)); + DWARF_32BIT_SIZE,error,section_end); + SIGN_EXTEND(val, DWARF_32BIT_SIZE); *addr = (Dwarf_Unsigned) val; - *input_field_updated = input_field + sizeof(Dwarf_ufixed); + *input_field_updated = input_field + DWARF_32BIT_SIZE; } break; case DW_EH_PE_sdata8:{ @@ -1493,9 +1567,9 @@ read_encoded_ptr(Dwarf_Debug dbg, /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, - sizeof(Dwarf_Unsigned),error,section_end); + DWARF_64BIT_SIZE,error,section_end); *addr = (Dwarf_Unsigned) val; - *input_field_updated = input_field + sizeof(Dwarf_Unsigned); + *input_field_updated = input_field + DWARF_64BIT_SIZE; } break; default: @@ -1522,14 +1596,12 @@ read_encoded_ptr(Dwarf_Debug dbg, return DW_DLV_OK; } - - - /* All augmentation string checking done here now. For .eh_frame, gcc from 3.3 uses the z style, earlier used only "eh" as augmentation. We don't yet handle decoding .eh_frame with the z style extensions like L P. + gnu_aug_encodings() does handle L P. These are nasty heuristics, but then that's life as augmentations are implementation specific. */ @@ -1598,7 +1670,6 @@ _dwarf_get_augmentation_type(UNUSEDARG Dwarf_Debug dbg, 'frame_ptr' points within section. 'section_end' points to end of section area of interest. - Why is fde_eh_encoding_out there? It's unused. */ /* ARGSUSED */ static int @@ -1606,7 +1677,6 @@ get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, unsigned long *size_of_augmentation_data, enum Dwarf_augmentation_type augtype, Dwarf_Small * section_ptr_end, - Dwarf_Small * fde_eh_encoding_out, char *augmentation, Dwarf_Error *error) { @@ -1616,7 +1686,7 @@ get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, if (augtype == aug_gcc_eh_z) { /* Has leading 'z'. */ UNUSEDARG Dwarf_Unsigned val = 0; - Dwarf_Word leb128_length = 0; + Dwarf_Unsigned leb128_length = 0; /* Dwarf_Unsigned eh_value = */ DECODE_LEB128_UWORD_LEN_CK(frame_ptr,val,leb128_length, @@ -1629,7 +1699,8 @@ get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, suffix = augmentation + 2; } /* FIXME: This could run too far. */ - for (; *suffix; ++suffix) { + /* for (; *suffix; ++suffix) if we think we can do something */ + if (*suffix) { /* We have no idea what this is as yet. Some extensions beyond dwarf exist which we do not yet handle. */ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); diff --git a/thirdparty/dwarf/dwarf_frame3.c b/thirdparty/dwarf/dwarf_frame3.c deleted file mode 100644 index aa64fa02..00000000 --- a/thirdparty/dwarf/dwarf_frame3.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - - Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. - -*/ - -#include "config.h" -#include "dwarf_incl.h" -#include -#include -#include "dwarf_frame.h" -#include "dwarf_arange.h" /* using Arange as a way to build a list */ - -/* Used by rqs (an IRIX application). - Not needed except for that one application. - Should be moved to its own source file since - it is so rarely needed. - Returns DW_DLV_OK if returns the arrays. - Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?) - Returns DW_DLV_ERROR if there is an error. - - Uses DW_FRAME_CFA_COL because IRIX is only DWARF2 - and that is what IRIX compilers and compatible - compilers support on IRIX. -*/ -int -_dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, - Dwarf_Off ** offsetlist, - Dwarf_Signed * returncount, - Dwarf_Error * err) -{ - int retval = DW_DLV_OK; - int res = DW_DLV_ERROR; - Dwarf_Cie *cie_data = 0; - Dwarf_Signed cie_count = 0; - Dwarf_Fde *fde_data = 0; - Dwarf_Signed fde_count = 0; - Dwarf_Signed i = 0; - Dwarf_Unsigned u = 0; - Dwarf_Frame_Op *frame_inst = 0; - Dwarf_Fde fdep = 0; - Dwarf_Cie ciep = 0; - Dwarf_Chain curr_chain = 0; - Dwarf_Chain head_chain = 0; - Dwarf_Chain prev_chain = 0; - Dwarf_Arange arange = 0; - Dwarf_Unsigned arange_count = 0; - Dwarf_Addr *arange_addrs = 0; - Dwarf_Off *arange_offsets = 0; - - res = dwarf_get_fde_list(dbg, &cie_data, &cie_count, - &fde_data, &fde_count, err); - if (res != DW_DLV_OK) { - return res; - } - - res = _dwarf_load_section(dbg, &dbg->de_debug_frame, err); - if (res != DW_DLV_OK) { - return res; - } - if (!dbg->de_debug_frame.dss_size) { - return (DW_DLV_NO_ENTRY); - } - - for (i = 0; i < cie_count; i++) { - Dwarf_Off instoff = 0; - Dwarf_Signed initial_instructions_length = 0; - Dwarf_Small *instr_end = 0; - Dwarf_Sword icount = 0; - int j = 0; - - ciep = cie_data[i]; - instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame.dss_data; - initial_instructions_length = ciep->ci_length + - ciep->ci_length_size + ciep->ci_extension_size - - (ciep->ci_cie_instr_start - ciep->ci_cie_start); - instr_end = ciep->ci_cie_instr_start + - initial_instructions_length; - res = _dwarf_exec_frame_instr( /* make_instr */ true, - &frame_inst, - /* search_pc= */ false, - /* search_pc_val= */ 0, - /* location */ 0, - ciep->ci_cie_instr_start, - instr_end, - /* Dwarf_frame= */ 0, - /* cie= */ 0, - dbg, - DW_FRAME_CFA_COL, - &icount, - NULL, NULL,err); - if (res == DW_DLV_ERROR) { - return res; - } else if (res == DW_DLV_NO_ENTRY) { - continue; - } - - for (j = 0; j < icount; ++j) { - Dwarf_Frame_Op *finst = frame_inst + j; - - if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) { - /* is DW_CFA_set_loc */ - Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset; - Dwarf_Off off = finst->fp_instr_offset + instoff; - - arange = (Dwarf_Arange) - _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); - if (arange == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - arange->ar_address = add; - arange->ar_info_offset = off; - arange_count++; - curr_chain = (Dwarf_Chain) - _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); - if (curr_chain == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - curr_chain->ch_item = arange; - if (head_chain == NULL) - head_chain = prev_chain = curr_chain; - else { - prev_chain->ch_next = curr_chain; - prev_chain = curr_chain; - } - } - } - dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK); - - } - for (i = 0; i < fde_count; i++) { - Dwarf_Small *instr_end = 0; - Dwarf_Sword icount = 0; - Dwarf_Signed instructions_length = 0; - Dwarf_Off instoff = 0; - Dwarf_Off off = 0; - Dwarf_Addr addr = 0; - int j = 0; - - fdep = fde_data[i]; - off = fdep->fd_initial_loc_pos - dbg->de_debug_frame.dss_data; - addr = fdep->fd_initial_location; - arange = (Dwarf_Arange) - _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); - if (arange == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - arange->ar_address = addr; - arange->ar_info_offset = off; - arange_count++; - curr_chain = (Dwarf_Chain) - _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); - if (curr_chain == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - curr_chain->ch_item = arange; - if (head_chain == NULL) - head_chain = prev_chain = curr_chain; - else { - prev_chain->ch_next = curr_chain; - prev_chain = curr_chain; - } - - - instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame.dss_data; - instructions_length = fdep->fd_length + - fdep->fd_length_size + fdep->fd_extension_size - - (fdep->fd_fde_instr_start - fdep->fd_fde_start); - instr_end = fdep->fd_fde_instr_start + instructions_length; - res = _dwarf_exec_frame_instr( /* make_instr */ true, - &frame_inst, - /* search_pc= */ false, - /* search_pc_val= */ 0, - /* location */ 0, - fdep->fd_fde_instr_start, - instr_end, - /* Dwarf_frame= */ 0, - /* cie= */ 0, - dbg, - DW_FRAME_CFA_COL, - &icount, - NULL,NULL,err); - if (res == DW_DLV_ERROR) { - return res; - } else if (res == DW_DLV_NO_ENTRY) { - continue; - } - - for (j = 0; j < icount; ++j) { - Dwarf_Frame_Op *finst2 = frame_inst + j; - - if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) { - /* is DW_CFA_set_loc */ - Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset; - Dwarf_Off off2 = finst2->fp_instr_offset + instoff; - - arange = (Dwarf_Arange) - _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); - if (arange == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - arange->ar_address = add; - arange->ar_info_offset = off2; - arange_count++; - curr_chain = (Dwarf_Chain) - _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); - if (curr_chain == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - curr_chain->ch_item = arange; - if (head_chain == NULL) - head_chain = prev_chain = curr_chain; - else { - prev_chain->ch_next = curr_chain; - prev_chain = curr_chain; - } - - } - } - dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK); - - } - dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); - dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); - arange_addrs = (Dwarf_Addr *) - _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); - if (arange_addrs == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - arange_offsets = (Dwarf_Off *) - _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); - if (arange_offsets == NULL) { - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - - curr_chain = head_chain; - for (u = 0; u < arange_count; u++) { - Dwarf_Arange ar = curr_chain->ch_item; - - arange_addrs[u] = ar->ar_address; - arange_offsets[u] = ar->ar_info_offset; - prev_chain = curr_chain; - curr_chain = curr_chain->ch_next; - dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); - dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); - } - *returncount = arange_count; - *offsetlist = arange_offsets; - *addrlist = arange_addrs; - return retval; -} diff --git a/thirdparty/dwarf/dwarf_funcs.c b/thirdparty/dwarf/dwarf_funcs.c index 1ff81433..64c9cad4 100644 --- a/thirdparty/dwarf/dwarf_funcs.c +++ b/thirdparty/dwarf/dwarf_funcs.c @@ -26,8 +26,9 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_error.h" #include "dwarf_funcs.h" #include "dwarf_global.h" diff --git a/thirdparty/dwarf/dwarf_gdbindex.c b/thirdparty/dwarf/dwarf_gdbindex.c index 15a45546..cee3389a 100644 --- a/thirdparty/dwarf/dwarf_gdbindex.c +++ b/thirdparty/dwarf/dwarf_gdbindex.c @@ -1,6 +1,6 @@ /* - Copyright (C) 2014-2014 David Anderson. All Rights Reserved. + Copyright (C) 2014-2019 David Anderson. All Rights Reserved. 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 @@ -25,9 +25,13 @@ */ #include "config.h" -#include "dwarf_incl.h" #include #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "memcpy_swap.h" #include "dwarf_gdbindex.h" #define TRUE 1 @@ -60,7 +64,7 @@ struct gi_fileheader_s { - gdbindex_offset_type headerval[6]; + char gfs [4][6]; }; struct dwarf_64bitpair { @@ -107,13 +111,13 @@ set_base(Dwarf_Debug dbg, } /* entry length includes pad. */ hdr->dg_entry_length = 2*sizeof(gdbindex_64) + - sizeof(gdbindex_offset_type); + DWARF_32BIT_SIZE; count = end - start; count = count / hdr->dg_entry_length; hdr->dg_count = count; /* The dg_fieldlen is a fake, the fields are not all the same length. */ - hdr->dg_fieldlen = sizeof(gdbindex_offset_type); + hdr->dg_fieldlen = DWARF_32BIT_SIZE; hdr->dg_type = type; } return DW_DLV_OK; @@ -148,7 +152,8 @@ dwarf_gdbindex_header(Dwarf_Debug dbg, } } - if (dbg->de_debug_gdbindex.dss_size < sizeof(struct gi_fileheader_s) ) { + if (dbg->de_debug_gdbindex.dss_size < + sizeof(struct gi_fileheader_s) ) { _dwarf_error(dbg, error, DW_DLE_ERRONEOUS_GDB_INDEX_SECTION); return (DW_DLV_ERROR); } @@ -165,22 +170,22 @@ dwarf_gdbindex_header(Dwarf_Debug dbg, indexptr->gi_section_length = dbg->de_debug_gdbindex.dss_size; READ_GDBINDEX(indexptr->gi_version ,Dwarf_Unsigned, dbg->de_debug_gdbindex.dss_data, - sizeof(gdbindex_offset_type)); + DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_cu_list_offset ,Dwarf_Unsigned, - dbg->de_debug_gdbindex.dss_data + sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type)); + dbg->de_debug_gdbindex.dss_data + DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_types_cu_list_offset ,Dwarf_Unsigned, - dbg->de_debug_gdbindex.dss_data + 2*sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type)); + dbg->de_debug_gdbindex.dss_data + 2*DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_address_area_offset ,Dwarf_Unsigned, - dbg->de_debug_gdbindex.dss_data + 3*sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type)); + dbg->de_debug_gdbindex.dss_data + 3*DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_symbol_table_offset ,Dwarf_Unsigned, - dbg->de_debug_gdbindex.dss_data + 4*sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type)); + dbg->de_debug_gdbindex.dss_data + 4*DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE); READ_GDBINDEX(indexptr->gi_constant_pool_offset ,Dwarf_Unsigned, - dbg->de_debug_gdbindex.dss_data + 5*sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type)); + dbg->de_debug_gdbindex.dss_data + 5*DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE); res = set_base(dbg,&indexptr->gi_culisthdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_cu_list_offset, @@ -188,37 +193,51 @@ dwarf_gdbindex_header(Dwarf_Debug dbg, 2*sizeof(gdbindex_64), sizeof(gdbindex_64), git_std,error); + if (res == DW_DLV_ERROR) { + return res; + } res = set_base(dbg,&indexptr->gi_typesculisthdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_types_cu_list_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset, 3*sizeof(gdbindex_64), sizeof(gdbindex_64), git_std,error); + if (res == DW_DLV_ERROR) { + return res; + } res = set_base(dbg,&indexptr->gi_addressareahdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_address_area_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset, 3*sizeof(gdbindex_64), sizeof(gdbindex_64), git_address,error); + if (res == DW_DLV_ERROR) { + return res; + } res = set_base(dbg,&indexptr->gi_symboltablehdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_symbol_table_offset, dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset, - 2*sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type), + 2*DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE, git_std,error); + if (res == DW_DLV_ERROR) { + return res; + } res = set_base(dbg,&indexptr->gi_cuvectorhdr, dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset, /* There is no real single vector size. but we'll use the entire rest as if there was. */ dbg->de_debug_gdbindex.dss_data + indexptr->gi_section_length, - sizeof(gdbindex_offset_type), - sizeof(gdbindex_offset_type), + DWARF_32BIT_SIZE, + DWARF_32BIT_SIZE, git_cuvec,error); + if (res == DW_DLV_ERROR) { + return res; + } /* Really just pointing to constant pool area. */ indexptr->gi_string_pool = dbg->de_debug_gdbindex.dss_data + indexptr->gi_constant_pool_offset; - *gdbindexptr = indexptr; *version = indexptr->gi_version; *cu_list_offset = indexptr->gi_cu_list_offset; @@ -229,7 +248,6 @@ dwarf_gdbindex_header(Dwarf_Debug dbg, *section_size = indexptr->gi_section_length; *unused_reserved = 0; *section_name = dbg->de_debug_gdbindex.dss_name; - return DW_DLV_OK; @@ -364,7 +382,7 @@ dwarf_gdbindex_addressarea_entry( sizeof(gdbindex_64)); READ_GDBINDEX(cuindex ,Dwarf_Unsigned, base+ (2*sizeof(gdbindex_64)), - sizeof(gdbindex_offset_type)); + DWARF_32BIT_SIZE); *low_address = lowaddr; *high_address = highaddr; *cu_index = cuindex; diff --git a/thirdparty/dwarf/dwarf_gdbindex.h b/thirdparty/dwarf/dwarf_gdbindex.h index 269b25a8..c8f80a11 100644 --- a/thirdparty/dwarf/dwarf_gdbindex.h +++ b/thirdparty/dwarf/dwarf_gdbindex.h @@ -47,7 +47,7 @@ We simply assume unsigned int is 32 bits FIXME. */ -typedef __uint32_t gdbindex_offset_type; +typedef unsigned int gdbindex_offset_type; typedef Dwarf_Unsigned gdbindex_64; enum gdbindex_type_e { @@ -87,11 +87,3 @@ struct Dwarf_Gdbindex_s { Dwarf_Small * gi_string_pool; }; - - - - - - - - diff --git a/thirdparty/dwarf/dwarf_generic_init.c b/thirdparty/dwarf/dwarf_generic_init.c new file mode 100644 index 00000000..56664301 --- /dev/null +++ b/thirdparty/dwarf/dwarf_generic_init.c @@ -0,0 +1,337 @@ +/* + Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. + Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. + Portions Copyright 2011-2019 David Anderson. All rights reserved. + Portions Copyright 2012 SN Systems Ltd. All rights reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + +#include "config.h" +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_STDLIB_H +#include +#endif /* HAVE_STDLIB_H */ +#ifdef HAVE_UNISTD_H +#include +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#endif /* HAVE_UNISTD_H */ + +#include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_object_detector.h" +#include "dwarf_elf_access.h" /* Needed while libelf in use */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* O_BINARY */ + +/* This is the initialization set intended to + handle multiple object formats. + Created September 2018 + + The init functions here cannot process archives. + For archives the libelf-only dwarf_elf_init*() + functions are used if present, else archives + cannot be read. +*/ + + +#define DWARF_DBG_ERROR(dbg,errval,retval) \ + _dwarf_error(dbg, error, errval); return(retval); + + +#define FALSE 0 +#define TRUE 1 +/* An original basic dwarf initializer function for consumers. + Return a libdwarf error code on error, return DW_DLV_OK + if this succeeds. + dwarf_init_b() is a better choice where there + are section groups in an object file. */ +int +dwarf_init(int fd, + Dwarf_Unsigned access, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) +{ + return dwarf_init_b(fd,access, DW_GROUPNUMBER_ANY, + errhand,errarg,ret_dbg,error); +} + +static int +open_a_file(const char * name) +{ + /* Set to a file number that cannot be legal. */ + int fd = -1; + +#if HAVE_ELF_OPEN + /* It is not possible to share file handles + between applications or DLLs. Each application has its own + file-handle table. For two applications to use the same file + using a DLL, they must both open the file individually. + Let the 'libelf' dll open and close the file. */ + fd = elf_open(name, O_RDONLY | O_BINARY); +#else + fd = open(name, O_RDONLY | O_BINARY); +#endif + return fd; +} + +/* New in December 2018. */ +int dwarf_init_path(const char *path, + char *true_path_out_buffer, + unsigned true_path_bufferlen, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug* ret_dbg, + UNUSEDARG const char * reserved1, + UNUSEDARG Dwarf_Unsigned reserved2, + UNUSEDARG Dwarf_Unsigned * reserved3, + Dwarf_Error* error) +{ + unsigned ftype = 0; + unsigned endian = 0; + unsigned offsetsize = 0; + Dwarf_Unsigned filesize = 0; + int res = 0; + int errcode = 0; + int fd = -1; + Dwarf_Debug dbg = 0; + + res = dwarf_object_detector_path(path, + true_path_out_buffer, + true_path_bufferlen, + &ftype,&endian,&offsetsize,&filesize,&errcode); + if (res == DW_DLV_NO_ENTRY) { + return res; + } + if (res == DW_DLV_ERROR) { + DWARF_DBG_ERROR(NULL, DW_DLE_FILE_UNAVAILABLE, DW_DLV_ERROR); + } + if (true_path_out_buffer) { + fd = open_a_file(true_path_out_buffer); + } else { + fd = open_a_file(path); + } + if(fd == -1) { + DWARF_DBG_ERROR(NULL, DW_DLE_FILE_UNAVAILABLE, + DW_DLV_ERROR); + } + switch(ftype) { + case DW_FTYPE_ELF: { + res = _dwarf_elf_nlsetup(fd, + true_path_out_buffer? + true_path_out_buffer:(char *)path, + ftype,endian,offsetsize,filesize, + access,groupnumber,errhand,errarg,&dbg,error); + if (res != DW_DLV_OK) { + close(fd); + } else { + dbg->de_fd = fd; + dbg->de_owns_fd = TRUE; + } + *ret_dbg = dbg; + return res; + } + case DW_FTYPE_MACH_O: { + res = _dwarf_macho_setup(fd, + true_path_out_buffer? + true_path_out_buffer:(char *)path, + ftype,endian,offsetsize,filesize, + access,groupnumber,errhand,errarg,&dbg,error); + if (res != DW_DLV_OK) { + close(fd); + } else { + dbg->de_fd = fd; + dbg->de_owns_fd = TRUE; + } + *ret_dbg = dbg; + return res; + } + case DW_FTYPE_PE: { + res = _dwarf_pe_setup(fd, + true_path_out_buffer? + true_path_out_buffer:(char *)path, + ftype,endian,offsetsize,filesize, + access,groupnumber,errhand,errarg,&dbg,error); + if (res != DW_DLV_OK) { + close(fd); + } else { + dbg->de_fd = fd; + dbg->de_owns_fd = TRUE; + } + *ret_dbg = dbg; + return res; + } + default: + close(fd); + DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); + } + return DW_DLV_NO_ENTRY; /* placeholder for now */ +} + + +/* New March 2017, this provides for reading + object files with multiple elf section groups. */ +int +dwarf_init_b(int fd, + Dwarf_Unsigned access, + unsigned group_number, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug * ret_dbg, + Dwarf_Error * error) +{ + unsigned ftype = 0; + unsigned endian = 0; + unsigned offsetsize = 0; + Dwarf_Unsigned filesize = 0; + int res = 0; + int errcode = 0; + + res = dwarf_object_detector_fd(fd, &ftype, + &endian,&offsetsize,&filesize,&errcode); + if (res == DW_DLV_NO_ENTRY) { + return res; + } else if (res == DW_DLV_ERROR) { + DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); + } + switch(ftype) { + case DW_FTYPE_ELF: { + res = _dwarf_elf_nlsetup(fd,"", + ftype,endian,offsetsize,filesize, + access,group_number,errhand,errarg,ret_dbg,error); + return res; + } + case DW_FTYPE_MACH_O: { + res = _dwarf_macho_setup(fd,"", + ftype,endian,offsetsize,filesize, + access,group_number,errhand,errarg,ret_dbg,error); + return res; + } + + case DW_FTYPE_PE: { + res = _dwarf_pe_setup(fd, + "", + ftype,endian,offsetsize,filesize, + access,group_number,errhand,errarg,ret_dbg,error); + return res; + } + } + DWARF_DBG_ERROR(NULL, DW_DLE_FILE_WRONG_TYPE, DW_DLV_ERROR); + return res; +} + +/* + Frees all memory that was not previously freed + by dwarf_dealloc. + Aside from certain categories. + + Applicable when dwarf_init() or dwarf_elf_init() + or the -b() form was used to init 'dbg'. +*/ +int +dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) +{ + if(!dbg) { + DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); + } + if (dbg->de_obj_file) { + /* The initial character of a valid + dbg->de_obj_file->object struct is a letter: + E, F, M, or P */ + char otype = *(char *)(dbg->de_obj_file->object); + + switch(otype) { + case 'E': +#ifdef DWARF_WITH_LIBELF + dwarf_elf_object_access_finish(dbg->de_obj_file); +#endif /* DWARF_WITH_LIBELF */ + break; + case 'F': + /* Non-libelf elf access */ + _dwarf_destruct_elf_nlaccess(dbg->de_obj_file); + break; + case 'M': + _dwarf_destruct_macho_access(dbg->de_obj_file); + break; + case 'P': + _dwarf_destruct_pe_access(dbg->de_obj_file); + break; + default: + /* Do nothing. A serious internal error */ + break; + } + } + if (dbg->de_owns_fd) { + close(dbg->de_fd); + dbg->de_owns_fd = FALSE; + } + return dwarf_object_finish(dbg, error); +} + +/* + tieddbg should be the executable or .o + that has the .debug_addr section that + the base dbg refers to. See Split Objects in DWARF5. + + Allows setting to NULL (NULL is the default + of de_tied_data.td_tied_object). + New September 2015. +*/ +int +dwarf_set_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug tieddbg,Dwarf_Error*error) +{ + if(!dbg) { + DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); + } + dbg->de_tied_data.td_tied_object = tieddbg; + if (tieddbg) { + tieddbg->de_tied_data.td_is_tied_object = TRUE; + } + return DW_DLV_OK; +} + +/* Unsure of the use-case of this. + New September 2015. */ +int +dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out, + UNUSEDARG Dwarf_Error*error) +{ + *tieddbg_out = dbg->de_tied_data.td_tied_object; + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/dwarf_global.c b/thirdparty/dwarf/dwarf_global.c index 523bbb5c..22b80771 100644 --- a/thirdparty/dwarf/dwarf_global.c +++ b/thirdparty/dwarf/dwarf_global.c @@ -26,8 +26,11 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_global.h" @@ -151,6 +154,7 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, int version_err_num) { Dwarf_Small *pubnames_like_ptr = 0; + Dwarf_Off pubnames_section_offset = 0; Dwarf_Small *section_end_ptr = section_data_ptr +section_length; /* Points to the context for the current set of global names, and @@ -225,15 +229,17 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, pubnames_like_ptr, local_length_size, local_extension_size,error,section_length,section_end_ptr); pubnames_context->pu_length_size = local_length_size; + pubnames_context->pu_length = length; pubnames_context->pu_extension_size = local_extension_size; pubnames_context->pu_dbg = dbg; - + pubnames_context->pu_pub_offset = pubnames_section_offset; pubnames_ptr_past_end_cu = pubnames_like_ptr + length; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, - pubnames_like_ptr, sizeof(Dwarf_Half), + pubnames_like_ptr, DWARF_HALF_SIZE, error,section_end_ptr); - pubnames_like_ptr += sizeof(Dwarf_Half); + pubnames_context->pu_version = version; + pubnames_like_ptr += DWARF_HALF_SIZE; /* ASSERT: DW_PUBNAMES_VERSION2 == DW_PUBTYPES_VERSION2 */ if (version != DW_PUBNAMES_VERSION2) { _dwarf_error(dbg, error, version_err_num); @@ -272,8 +278,50 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, pubnames_like_ptr += pubnames_context->pu_length_size; FIX_UP_OFFSET_IRIX_BUG(dbg, die_offset_in_cu, "offset of die in cu"); + if (pubnames_like_ptr > (section_data_ptr + section_length)) { + _dwarf_error(dbg, error, length_err_num); + return DW_DLV_ERROR; + } /* Loop thru pairs. DIE off with CU followed by string. */ + if (dbg->de_return_empty_pubnames && die_offset_in_cu == 0) { + /* Here we have a pubnames CU with no actual + entries so we fake up an entry to hold the + header data. There are no 'pairs' here, + just the end of list zero value. We do this + only if de_return_empty_pubnames is set + so that we by default return exactly the same + data this always returned, yet dwarfdump can + request the empty-cu records get created + to test that feature. + see dwarf_get_globals_header() */ + global = + (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1); + if (global == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + global_count++; + global->gl_context = pubnames_context; + global->gl_named_die_offset_within_cu = 0; + global->gl_name = (Dwarf_Small *)""; + /* Finish off current entry chain */ + curr_chain = + (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); + if (curr_chain == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + /* Put current global on singly_linked list. */ + curr_chain->ch_item = (Dwarf_Global) global; + if (head_chain == NULL) + head_chain = prev_chain = curr_chain; + else { + prev_chain->ch_next = curr_chain; + prev_chain = curr_chain; + } + /* There is no next entry, we are at it already */ + } while (die_offset_in_cu != 0) { int res; @@ -294,7 +342,8 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, global->gl_name = pubnames_like_ptr; res = _dwarf_check_string_valid(dbg,section_data_ptr, - pubnames_like_ptr,section_end_ptr,error); + pubnames_like_ptr,section_end_ptr, + DW_DLE_STRING_OFF_END_PUBNAMES_LIKE,error); if (res != DW_DLV_OK) { return res; } @@ -308,10 +357,8 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } - /* Put current global on singly_linked list. */ curr_chain->ch_item = (Dwarf_Global) global; - if (head_chain == NULL) head_chain = prev_chain = curr_chain; else { @@ -319,7 +366,7 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, prev_chain = curr_chain; } - /* Fead offset for the *next* entry */ + /* Read offset for the *next* entry */ READ_UNALIGNED_CK(dbg, die_offset_in_cu, Dwarf_Off, pubnames_like_ptr, pubnames_context->pu_length_size, error,section_end_ptr); @@ -328,7 +375,7 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, die_offset_in_cu, "offset of next die in cu"); if (pubnames_like_ptr > (section_data_ptr + section_length)) { _dwarf_error(dbg, error, length_err_num); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } } /* ASSERT: die_offset_in_cu == 0 */ @@ -337,27 +384,34 @@ _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, The encoding is wrong or the length in the header for this cu's contribution is wrong. */ _dwarf_error(dbg, error, length_err_num); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } /* If there is some kind of padding at the end of the section, as emitted by some compilers, skip over that padding and simply ignore the bytes thus passed-over. With most compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at this point */ + { + Dwarf_Unsigned increment = + pubnames_context->pu_length_size + + pubnames_context->pu_length + + pubnames_context->pu_extension_size; + pubnames_section_offset += increment; + } pubnames_like_ptr = pubnames_ptr_past_end_cu; - - } while (pubnames_like_ptr < (section_data_ptr + section_length)); + } while (pubnames_like_ptr < section_end_ptr); /* Points to contiguous block of Dwarf_Global's. */ ret_globals = (Dwarf_Global *) _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count); if (ret_globals == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } /* Store pointers to Dwarf_Global_s structs in contiguous block, - and deallocate the chain. */ + and deallocate the chain. This ignores the various + headers */ curr_chain = head_chain; for (i = 0; i < global_count; i++) { *(ret_globals + i) = curr_chain->ch_item; @@ -469,7 +523,7 @@ dwarf_global_name_offsets(Dwarf_Global global, { Dwarf_Global_Context con = 0; Dwarf_Debug dbg = 0; - Dwarf_Off off = 0; + Dwarf_Off cuhdr_off = 0; if (global == NULL) { _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); @@ -483,7 +537,7 @@ dwarf_global_name_offsets(Dwarf_Global global, return (DW_DLV_ERROR); } - off = con->pu_offset_of_cu_header; + cuhdr_off = con->pu_offset_of_cu_header; /* The offset had better not be too close to the end. If it is, _dwarf_length_of_cu_header() will step off the end and therefore must not be used. 10 is a meaningless heuristic, but no CU @@ -499,18 +553,27 @@ dwarf_global_name_offsets(Dwarf_Global global, } /* Cannot refer to debug_types */ if (dbg->de_debug_info.dss_size && - ((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) { + ((cuhdr_off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) { _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); return (DW_DLV_ERROR); } #undef MIN_CU_HDR_SIZE - if (die_offset != NULL) { - *die_offset = global->gl_named_die_offset_within_cu + off; + /* If global->gl_named_die_offset_within_cu + is zero then this is a fake global for + a pubnames CU with no pubnames. The offset is from the + start of the CU header, so no die can have a zero + offset, all valid offsets are positive numbers */ + if (die_offset) { + if(global->gl_named_die_offset_within_cu) { + *die_offset = global->gl_named_die_offset_within_cu + cuhdr_off; + } else { + *die_offset = 0; + } } *ret_name = (char *) global->gl_name; - if (cu_die_offset != NULL) { + if (cu_die_offset) { /* Globals cannot refer to debug_types */ int cres = 0; Dwarf_Unsigned headerlen = 0; @@ -524,20 +587,76 @@ dwarf_global_name_offsets(Dwarf_Global global, therefore must not be used. 10 is a meaningless heuristic, but no CU header is that small so it is safe. */ /* Globals cannot refer to debug_types */ - if ((off + 10) >= dbg->de_debug_info.dss_size) { + if ((cuhdr_off + 10) >= dbg->de_debug_info.dss_size) { _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD); return (DW_DLV_ERROR); } - cres = _dwarf_length_of_cu_header(dbg, off,true, + cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,true, &headerlen,error); if(cres != DW_DLV_OK) { return cres; } - *cu_die_offset = off + headerlen; + *cu_die_offset = cuhdr_off + headerlen; } return DW_DLV_OK; } + +/* New February 2019 from better dwarfdump printing + of debug_pubnames and pubtypes. + For ao the Dwarf_Global records in one pubnames + CU group exactly the same data will be returned. + +*/ +int +dwarf_get_globals_header(Dwarf_Global global, + Dwarf_Off *pub_section_hdr_offset, + Dwarf_Unsigned *pub_offset_size, + Dwarf_Unsigned *pub_cu_length, + Dwarf_Unsigned *version, + Dwarf_Off *info_header_offset, + Dwarf_Unsigned *info_length, + Dwarf_Error* error) +{ + Dwarf_Global_Context con = 0; + Dwarf_Debug dbg = 0; + + if (global == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); + return DW_DLV_ERROR; + } + con = global->gl_context; + if (con == NULL) { + _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); + return DW_DLV_ERROR; + } + dbg = con->pu_dbg; + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return DW_DLV_ERROR; + } + if(pub_section_hdr_offset) { + *pub_section_hdr_offset = con->pu_pub_offset; + } + if (pub_offset_size) { + *pub_offset_size = con->pu_length_size; + } + if (pub_cu_length) { + *pub_cu_length = con->pu_length; + } + if (version) { + *version = con->pu_version; + } + if(info_header_offset) { + *info_header_offset = con->pu_offset_of_cu_header; + } + if (info_length) { + *info_length = con->pu_info_length; + } + return DW_DLV_OK; +} + + /* We have the offset to a CU header. Return thru outFileOffset the offset of the CU DIE. @@ -625,3 +744,19 @@ dwarf_CU_dieoffset_given_die(Dwarf_Die die, die->di_is_info, return_offset,error); return DW_DLV_OK; } + +int dwarf_return_empty_pubnames(Dwarf_Debug dbg, + int flag , + Dwarf_Error* error) +{ + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return DW_DLV_ERROR; + } + if (flag && flag != 1) { + _dwarf_error(NULL, error,DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR); + return DW_DLV_ERROR; + } + dbg->de_return_empty_pubnames = (unsigned char)flag; + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/dwarf_global.h b/thirdparty/dwarf/dwarf_global.h index 1864dc4a..f39596c0 100644 --- a/thirdparty/dwarf/dwarf_global.h +++ b/thirdparty/dwarf/dwarf_global.h @@ -48,18 +48,21 @@ typedef struct Dwarf_Global_Context_s *Dwarf_Global_Context; */ struct Dwarf_Global_Context_s { - /* Length in .debug_pubnames (etc) of a set of names for a - compilation-unit. Dwarf_Word pu_length; The value is not made - available outside libdwarf and not used inside, so no need to - record it. */ - /* For this context, size of a length. 4 or 8 */ unsigned char pu_length_size; + /* Size of the pubnames data for the CU */ + unsigned char pu_length; + /* For this CU, size of the extension 0 except for dwarf2 extension 64bit, in which case is 4. */ unsigned char pu_extension_size; + Dwarf_Half pu_version; /* 2,3, or 4 */ + + /* offset in pubnames of the pu header. */ + Dwarf_Off pu_pub_offset; + /* Offset into .debug_info of the compilation-unit header (not DIE) for this set of pubnames. */ Dwarf_Off pu_offset_of_cu_header; @@ -83,6 +86,7 @@ struct Dwarf_Global_s { /* Context for this pubname. */ Dwarf_Global_Context gl_context; + }; int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, @@ -114,4 +118,3 @@ void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, #else /* ! __sgi */ #define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) #endif /* __sgi */ - diff --git a/thirdparty/dwarf/dwarf_groups.c b/thirdparty/dwarf/dwarf_groups.c new file mode 100644 index 00000000..932a6756 --- /dev/null +++ b/thirdparty/dwarf/dwarf_groups.c @@ -0,0 +1,392 @@ +/* + Copyright (C) 2017-2018 David Anderson. All Rights Reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. + +*/ + +#include "config.h" +#include +#include +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ +#include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_tsearch.h" + +#define TRUE 1 +#define FALSE 0 + +#define HASHSEARCH + +/* It has not escaped our attention that the section-group + tsearch hash table could + be replaced by a simple array with space for each possible + section number, each element being the group number. + This would be much simpler than what follows here. */ + +/* Each section number can appear in at most one record in the hash + because each section belongs in only one group. + Each group number appears as often as appropriate. */ + +struct Dwarf_Group_Map_Entry_s { + unsigned gm_key; /* section number */ + unsigned gm_group_number; /* What group number is. */ + + /* The name is from static storage or from elf, + so there is nothing to free on record delete. */ + const char * gm_section_name; +}; + +static void * +grp_make_entry(unsigned section, unsigned group,const char *name) +{ + struct Dwarf_Group_Map_Entry_s *e = 0; + e = calloc(1,sizeof(struct Dwarf_Group_Map_Entry_s)); + if(e) { + e->gm_key = section; + e->gm_group_number = group; + e->gm_section_name = name; + } + return e; +} + + +static DW_TSHASHTYPE +grp_data_hashfunc(const void *keyp) +{ + const struct Dwarf_Group_Map_Entry_s * enp = keyp; + DW_TSHASHTYPE hashv = 0; + + hashv = enp->gm_key; + return hashv; +} + +static int +grp_compare_function(const void *l, const void *r) +{ + const struct Dwarf_Group_Map_Entry_s * lp = l; + const struct Dwarf_Group_Map_Entry_s * rp = r; + + if (lp->gm_key < rp->gm_key) { + return -1; + } + if (lp->gm_key > rp->gm_key) { + return 1; + } + + /* match. */ + return 0; +} + +static void +_dwarf_grp_destroy_free_node(void*nodep) +{ + struct Dwarf_Group_Map_Entry_s * enp = nodep; + free(enp); + return; +} + +int +_dwarf_insert_in_group_map(Dwarf_Debug dbg, + unsigned groupnum, + unsigned section_index, + const char *name, + Dwarf_Error * error) +{ + struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; + + void *entry2 = 0; + struct Dwarf_Group_Map_Entry_s * entry3 = 0; + + if (!grp->gd_map) { + /* Number of sections is a kind of decent guess + as to how much space would be useful. */ + dwarf_initialize_search_hash(&grp->gd_map, + grp_data_hashfunc,grp->gd_number_of_sections); + if (!grp->gd_map) { + /* It's really an error I suppose. */ + return DW_DLV_NO_ENTRY; + } + } + entry3 = grp_make_entry(section_index,groupnum,name); + if (!entry3) { + _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_ALLOC); + return DW_DLV_ERROR; + } + entry2 = dwarf_tsearch(entry3,&grp->gd_map,grp_compare_function); + if (!entry2) { + free(entry3); + _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_ALLOC); + return DW_DLV_ERROR; + } else { + struct Dwarf_Group_Map_Entry_s *re = 0; + re = *(struct Dwarf_Group_Map_Entry_s **)entry2; + if (re != entry3) { + free(entry3); + _dwarf_error(dbg, error, DW_DLE_GROUP_MAP_DUPLICATE); + return DW_DLV_ERROR; + } else { + ++grp->gd_map_entry_count; + /* OK. Added. Fall thru */ + } + } + return DW_DLV_OK; +} + +int +_dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, + unsigned obj_section_index, + unsigned * groupnumber_out, + UNUSEDARG Dwarf_Error * error) +{ + struct Dwarf_Group_Map_Entry_s entry; + struct Dwarf_Group_Map_Entry_s *entry2; + struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; + + if (!grp->gd_map) { + return DW_DLV_NO_ENTRY; + } + entry.gm_key = obj_section_index; + entry.gm_group_number = 0; /* FAKE */ + entry.gm_section_name = ""; /* FAKE */ + + entry2 = dwarf_tfind(&entry, &grp->gd_map,grp_compare_function); + if (entry2) { + struct Dwarf_Group_Map_Entry_s *e2 = + *(struct Dwarf_Group_Map_Entry_s **)entry2;; + *groupnumber_out = e2->gm_group_number; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + + + + +/* New May 2017. So users can find out what groups (dwo or COMDAT) + are in the object and how much to allocate so one can get the + group-section map data. */ +int dwarf_sec_group_sizes(Dwarf_Debug dbg, + Dwarf_Unsigned * section_count_out, + Dwarf_Unsigned * group_count_out, + Dwarf_Unsigned * selected_group_out, + Dwarf_Unsigned * map_entry_count_out, + UNUSEDARG Dwarf_Error * error) +{ + struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; + + *section_count_out = grp->gd_number_of_sections; + *group_count_out = grp->gd_number_of_groups; + *selected_group_out = dbg->de_groupnumber; + *map_entry_count_out = grp->gd_map_entry_count; + return DW_DLV_OK; +} + + +static Dwarf_Unsigned map_reccount = 0; +static struct temp_map_struc_s { + Dwarf_Unsigned section; + Dwarf_Unsigned group; + const char *name; +} *temp_map_data; + + +static void +grp_walk_map(const void *nodep, + const DW_VISIT which, + UNUSEDARG const int depth) +{ + struct Dwarf_Group_Map_Entry_s *re = 0; + + re = *(struct Dwarf_Group_Map_Entry_s **)nodep; + if (which == dwarf_postorder || which == dwarf_endorder) { + return; + } + temp_map_data[map_reccount].group = re->gm_group_number; + temp_map_data[map_reccount].section = re->gm_key; + temp_map_data[map_reccount].name = re->gm_section_name; + map_reccount += 1; +} + +/* Looks better sorted by group then sec num. */ +static int +map_sort_compar(const void*l, const void*r) +{ + struct temp_map_struc_s *lv = (struct temp_map_struc_s *)l; + struct temp_map_struc_s *rv = (struct temp_map_struc_s *)r; + + if (lv->group < rv->group) { + return -1; + } + if (lv->group > rv->group) { + return 1; + } + if (lv->section < rv->section) { + return -1; + } + if (lv->section > rv->section) { + return 1; + } + /* Should never get here! */ + return 0; + +} + +/* New May 2017. Reveals the map between group numbers + and section numbers. + Caller must allocate the arrays with space for 'map_entry_count' + values and this function fills in the array entries. + Output ordered by group number and section number. + */ +int dwarf_sec_group_map(Dwarf_Debug dbg, + Dwarf_Unsigned map_entry_count, + Dwarf_Unsigned * group_numbers_array, + Dwarf_Unsigned * sec_numbers_array, + const char ** sec_names_array, + Dwarf_Error * error) +{ + Dwarf_Unsigned i = 0; + struct Dwarf_Group_Data_s *grp = 0; + + if(temp_map_data) { + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + map_reccount = 0; + grp = &dbg->de_groupnumbers; + if (map_entry_count < grp->gd_map_entry_count) { + _dwarf_error(dbg,error,DW_DLE_GROUP_COUNT_ERROR); + return DW_DLV_ERROR; + } + temp_map_data = calloc(map_entry_count,sizeof(struct temp_map_struc_s)); + if(!temp_map_data) { + _dwarf_error(dbg,error,DW_DLE_GROUP_MAP_ALLOC); + return DW_DLV_ERROR; + } + dwarf_twalk(grp->gd_map,grp_walk_map); + if (map_reccount != grp->gd_map_entry_count) { + /* Impossible. */ + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + + qsort(temp_map_data,map_reccount,sizeof(struct temp_map_struc_s), + map_sort_compar); + for (i =0 ; i < map_reccount; ++i) { + sec_numbers_array[i] = temp_map_data[i].section; + group_numbers_array[i] = temp_map_data[i].group; + sec_names_array[i] = temp_map_data[i].name; + } + free(temp_map_data); + map_reccount = 0; + temp_map_data = 0; + return DW_DLV_OK; +} + +static const char *dwo_secnames[] = { +".debug_info.dwo", +".debug_types.dwo", +".debug_abbrev.dwo", +".debug_line.dwo", +".debug_loc.dwo", +".debug_str.dwo", +".debug_loclists.dwo", +".debug_rnglists.dwo", +".debug_str_offsets.dwo", +".debug_macro.dwo", +".debug_cu_index", +".debug_tu_index", +0 }; + +/* Assumption: dwo sections are never in a COMDAT group + (groupnumber >2) + and by definition here are never group 1. + Assumption: the map of COMDAT groups (not necessarily all + sections, but at least all COMDAT) is complete. */ +int +_dwarf_dwo_groupnumber_given_name( + const char *name, + unsigned *grpnum_out) +{ + const char **s = 0; + + for (s = dwo_secnames; *s; s++) { + if(!strcmp(name,*s)) { + *grpnum_out = DW_GROUPNUMBER_DWO; + return DW_DLV_OK; + } + } + return DW_DLV_NO_ENTRY; +} + +static unsigned target_group = 0; +static int found_name_in_group = 0; +const char *lookfor_name = 0; + +static void +grp_walk_for_name(const void *nodep, + const DW_VISIT which, + UNUSEDARG const int depth) +{ + struct Dwarf_Group_Map_Entry_s *re = 0; + + re = *(struct Dwarf_Group_Map_Entry_s **)nodep; + if (which == dwarf_postorder || which == dwarf_endorder) { + return; + } + if (re->gm_group_number == target_group) { + if(!strcmp(lookfor_name,re->gm_section_name)) { + found_name_in_group = TRUE; + } + } +} + + +/* returns TRUE or FALSE */ +int +_dwarf_section_in_group_by_name(Dwarf_Debug dbg, + const char * scn_name, + unsigned groupnum) +{ + struct Dwarf_Group_Data_s *grp = 0; + + grp = &dbg->de_groupnumbers; + found_name_in_group = FALSE; + target_group = groupnum; + lookfor_name = scn_name; + dwarf_twalk(grp->gd_map,grp_walk_for_name); + return found_name_in_group; +} + +void +_dwarf_destroy_group_map(Dwarf_Debug dbg) +{ + dwarf_tdestroy(dbg->de_groupnumbers.gd_map,_dwarf_grp_destroy_free_node); + dbg->de_groupnumbers.gd_map = 0; +} diff --git a/thirdparty/dwarf/dwarf_harmless.c b/thirdparty/dwarf/dwarf_harmless.c index 6c3b5bdc..5d330a71 100644 --- a/thirdparty/dwarf/dwarf_harmless.c +++ b/thirdparty/dwarf/dwarf_harmless.c @@ -1,6 +1,5 @@ /* - - Copyright (C) 2010-2012 David Anderson. All Rights Reserved. + Copyright (C) 2010-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -225,4 +224,3 @@ dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp) dhp->dh_errors = 0; dhp->dh_maxcount = 0; } - diff --git a/thirdparty/dwarf/dwarf_harmless.h b/thirdparty/dwarf/dwarf_harmless.h index e696806b..79c58706 100644 --- a/thirdparty/dwarf/dwarf_harmless.h +++ b/thirdparty/dwarf/dwarf_harmless.h @@ -28,4 +28,3 @@ void dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size); void dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp); - diff --git a/thirdparty/dwarf/dwarf_incl.h b/thirdparty/dwarf/dwarf_incl.h index e1b6ea4c..dc8ac6e2 100644 --- a/thirdparty/dwarf/dwarf_incl.h +++ b/thirdparty/dwarf/dwarf_incl.h @@ -31,31 +31,22 @@ #define DWARF_INCL_H #if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) /* At a certain point libelf.h requires _GNU_SOURCE. - here we assume the criteria in configure determine that + here we assume the criteria in configure determined that usefully. */ #define _GNU_SOURCE 1 #endif -#ifdef HAVE_STDAFX_H /* Windows specific. */ +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ #include "libdwarfdefs.h" -#include - -#ifdef HAVE_ELF_H -#include -#endif - -#include -#include -#include - +#include /* strcpy() strlen() */ +#include +#include "dwarf.h" +#include "libdwarf.h" #include "dwarf_base_types.h" -#include "dwarf_alloc.h" -#include "dwarf_xu_index.h" #include "dwarf_opaque.h" -#include "dwarf_error.h" -#include "dwarf_util.h" #endif /* DWARF_INCL_H */ diff --git a/thirdparty/dwarf/dwarf_init_finish.c b/thirdparty/dwarf/dwarf_init_finish.c index 6b681dc1..40e60710 100644 --- a/thirdparty/dwarf/dwarf_init_finish.c +++ b/thirdparty/dwarf/dwarf_init_finish.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. - Portions Copyright (C) 2009-2016 David Anderson. All Rights Reserved. + Portions Copyright (C) 2009-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ */ #include "config.h" -#include "dwarf_incl.h" - #include #include #include @@ -36,12 +34,13 @@ #include #include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "memcpy_swap.h" #include "dwarf_harmless.h" /* For consistency, use the HAVE_LIBELF_H symbol */ -#ifdef HAVE_ELF_H -#include -#endif #ifdef HAVE_LIBELF_H #include #else @@ -67,6 +66,17 @@ #ifndef SHT_RELA #define SHT_RELA 4 #endif +/* For COMDAT GROUPS. Guarantees we can compile. We hope. */ +#ifndef SHT_GROUP +#define SHT_GROUP 17 +#endif + +#ifndef SHF_COMPRESSED +/* This from ubuntu xenial. Is in top of trunk binutils + as of February 2016. Elf Section Flag */ +#define SHF_COMPRESSED (1 << 11) +#endif + #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); @@ -74,7 +84,9 @@ #define FALSE 0 #define TRUE 1 - +/* Global definition of the function pointer type, typedef + in dwarf_opaque.h */ +_dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr; /* This static is copied to the dbg on dbg init so that the static need not be referenced at @@ -105,6 +117,36 @@ dwarf_set_stringcheck(int newval) return oldval; } +static int +startswith(const char * input, char* ckfor) +{ + size_t cklen = strlen(ckfor); + + if (! strncmp(input,ckfor,cklen)) { + return TRUE; + } + return FALSE; +} +#if 0 +static int +endswith(const char * input, char* ckfor) +{ + size_t inlen = strlen(input); + size_t endlen = strlen(ckfor); + const char * endck = 0; + + if (endlen > inlen) { + return FALSE; + } + endck = input+inlen - endlen; + + if (! strcmp(endck,ckfor) ) { + return TRUE; + } + return FALSE; +} +#endif + /* Unifies the basic duplicate/empty testing and section data setting to one place. */ static int @@ -112,6 +154,7 @@ get_basic_section_data(Dwarf_Debug dbg, struct Dwarf_Section_s *secdata, struct Dwarf_Obj_Access_Section_s *doas, Dwarf_Half section_index, + unsigned group_number, Dwarf_Error* error, int duperr, int emptyerr ) { @@ -124,8 +167,11 @@ get_basic_section_data(Dwarf_Debug dbg, DWARF_DBG_ERROR(dbg, duperr, DW_DLV_ERROR); } if (doas->size == 0) { + /* As of 2018 it seems impossible to detect + (via dwarfdump) whether emptyerr has any + practical effect, whether TRUE or FALSE. */ if (emptyerr == 0 ) { - /* Allow empty section. */ + /* Allow empty section. */ return DW_DLV_OK; } /* Know no reason to allow section */ @@ -133,6 +179,7 @@ get_basic_section_data(Dwarf_Debug dbg, } secdata->dss_index = section_index; secdata->dss_size = doas->size; + secdata->dss_group_number = group_number; secdata->dss_addr = doas->addr; secdata->dss_link = doas->link; secdata->dss_entrysize = doas->entrysize; @@ -161,15 +208,17 @@ get_basic_section_data(Dwarf_Debug dbg, secdata->dss_flags = flags; secdata->dss_addralign = addralign; if (flags & SHF_COMPRESSED) { - secdata->dss_requires_decompress = TRUE; + secdata->dss_shf_compressed = TRUE; } + /* We are not looking at section bytes so we + do not know if the first 4 bytes are ZLIB */ } return DW_DLV_OK; } static void -add_rela_data( struct Dwarf_Section_s *secdata, +add_rela_data_to_secdata( struct Dwarf_Section_s *secdata, struct Dwarf_Obj_Access_Section_s *doas, Dwarf_Half section_index) { @@ -193,8 +242,10 @@ static int add_debug_section_info(Dwarf_Debug dbg, /* Name as seen in object file. */ const char *name, + const char *standard_section_name, unsigned obj_sec_num, struct Dwarf_Section_s *secdata, + unsigned groupnum, /* The have_dwarf flag is a somewhat imprecise way to determine if there is at least one 'meaningful' DWARF information section present in the object file. @@ -216,14 +267,16 @@ add_debug_section_info(Dwarf_Debug dbg, debug_section->ds_name = name; debug_section->ds_number = obj_sec_num; debug_section->ds_secdata = secdata; - secdata->dss_name = name; + debug_section->ds_groupnumber = groupnum; + secdata->dss_name = name; /* Actual name from object file. */ + secdata->dss_standard_name = standard_section_name; secdata->dss_number = obj_sec_num; - secdata->dss_requires_decompress = havezdebug; + secdata->dss_zdebug_requires_decompress = havezdebug; + /* We don't yet know about SHF_COMPRESSED */ debug_section->ds_duperr = duperr; debug_section->ds_emptyerr = emptyerr; debug_section->ds_have_dwarf = have_dwarf; debug_section->ds_have_zdebug = havezdebug; - ++dbg->de_debug_sections_total_entries; return DW_DLV_OK; } @@ -235,17 +288,31 @@ add_debug_section_info(Dwarf_Debug dbg, return DW_DLV_ERROR; } + #if 0 static void -dump_bytes(Dwarf_Small * start, long len) +dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; Dwarf_Small *cur = start; + printf("dump_bytes: %s ",msg); for (; cur < end; cur++) { - printf(" byte %d, data %02x\n", (int) (cur - start), *cur); + printf("%02x",*cur); } + printf("\n"); +} +static int +all_sig8_bits_zero(Dwarf_Sig8 *val) +{ + unsigned u = 0; + for( ; u < sizeof(*val); ++u) { + if (val->signature[u] != 0) { + return FALSE; + } + } + return TRUE; } #endif @@ -253,69 +320,97 @@ dump_bytes(Dwarf_Small * start, long len) /* Return DW_DLV_OK etc. */ static int set_up_section(Dwarf_Debug dbg, - /* Section name from object format. */ - const char *secname, - /* Section number from object format */ - unsigned obj_sec_num, - /* The name associated with this secdata */ - const char *targname, - struct Dwarf_Section_s *secdata, - int duperr,int emptyerr,int have_dwarf, - int *err) + /* Section name from object format. + Might start with .zdebug not .debug if compressed section. */ + const char *secname, + /* Standard section name, such as .debug_info */ + const char *sec_standard_name, + /* Section number from object format */ + unsigned obj_sec_num, + /* The name associated with this secdata in libdwarf */ + const char *targname, + /* DW_GROUPNUMBER_ANY or BASE or DWO or some other group num */ + unsigned groupnum_of_sec, + struct Dwarf_Section_s *secdata, + int duperr,int emptyerr,int have_dwarf, + int *err) { /* Here accomodate the .debug or .zdebug version, (and of course non- .debug too, but those never zlib) . SECNAMEMAX should be a little bigger than any section - name we care about as possibly compressed. */ - #define SECNAMEMAX 30 - char buildsecname[SECNAMEMAX]; - unsigned secnamelen = strlen(secname); - static const char *dprefix = ".debug_"; + name we care about as possibly compressed, which + is to say bigger than any standard section name. */ +#define SECNAMEMAX 30 + int secnamelen = strlen(secname); + /* static const char *dprefix = ".debug_"; */ +#define DPREFIXLEN 7 static const char *zprefix = ".zdebug_"; +#define ZPREFIXLEN 8 int havezdebug = FALSE; - unsigned targnamelen = strlen(targname); - const char *finalname = targname; - - if(secnamelen < SECNAMEMAX && strncmp(secname,zprefix,8) == 0) { - strcpy(buildsecname,zprefix); - /* Now lets see if a targname updated with z matches - secname. */ - /* 2 ensures NUL and added 'z' are ok */ - if ((targnamelen+2) < SECNAMEMAX && strncmp(targname,dprefix,7) == 0 ){ - strcat(buildsecname,targname+7); - /* We turned tarname .debug_info to .zdebug_info, for example. */ - finalname = buildsecname; - if (strcmp(finalname,secname) == 0) { - havezdebug = TRUE; - } - } + int namesmatch = FALSE; + + /* For example, if the secname is .zdebug_info + we update the finaltargname to .debug_info + to match with the particular (known, predefined) + object section name. + We add one character, so check + to see if it will, in the end, fit. + See the SET_UP_SECTION macro. */ + + if(secnamelen >= SECNAMEMAX) { + /* This is not the target section. + our caller will keep looking. */ + return DW_DLV_NO_ENTRY; + } + if((secnamelen+1) < SECNAMEMAX && + !strncmp(secname,zprefix,ZPREFIXLEN) && + !strcmp(secname+ZPREFIXLEN,targname+DPREFIXLEN)) { + /* zprefix version matches the object section + name so the section is compressed and is + the section this targname applies to. */ + havezdebug = TRUE; + namesmatch = TRUE; + } else if (!strcmp(secname,targname)) { + namesmatch = TRUE; + } +#undef ZPREFIXLEN +#undef DPREFIXLEN +#undef SECNAMEMAX + if(!namesmatch) { + /* This is not the target section. + our caller will keep looking. */ + return DW_DLV_NO_ENTRY; } - if(!strcmp(secname,finalname)) { + /* SETUP_SECTION. See also BUILDING_SECTIONS, BUILDING_MAP */ + { /* The section name is a match with targname, or the .zdebug version of targname. */ - int sectionerr = add_debug_section_info(dbg,secname, + int sectionerr = 0; + + sectionerr = add_debug_section_info(dbg,secname, + sec_standard_name, obj_sec_num, secdata, + groupnum_of_sec, duperr,emptyerr, have_dwarf, havezdebug,err); if (sectionerr != DW_DLV_OK) { /* *err is set already */ return sectionerr; } - return DW_DLV_OK; } - /* This is not the target section. - our caller will keep looking. */ - return DW_DLV_NO_ENTRY; + return DW_DLV_OK; } -#define SET_UP_SECTION(mdbg,mname,mtarg,minfo,me1,me2,mdw,mer) \ +#define SET_UP_SECTION(mdbg,mname,mtarg,mgrp,minfo,me1,me2,mdw,mer) \ { \ int lerr = 0; \ - lerr = set_up_section(mdbg, mname, \ + lerr = set_up_section(mdbg, \ + mname, /* actual section name */ \ + mtarg, /* std section name */ \ /* scn_number from macro use context */ \ - scn_number,mtarg, \ + scn_number,mtarg,mgrp, \ minfo, \ me1,me2,mdw,mer); \ if (lerr != DW_DLV_NO_ENTRY) { \ @@ -334,109 +429,176 @@ enter_section_in_de_debug_sections_array(Dwarf_Debug dbg, const char *scn_name, /* This is the number of the section in the object file. */ unsigned scn_number, + unsigned group_number, int *err) { /* Setup the table that contains the basic information about the sections that are DWARF related. The entries are very unlikely to change very often. */ SET_UP_SECTION(dbg,scn_name,".debug_info", + group_number, &dbg->de_debug_info, DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_info.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_info, DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_types", + group_number, &dbg->de_debug_types, DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_types.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_types, DW_DLE_DEBUG_TYPES_DUPLICATE,DW_DLE_DEBUG_TYPES_NULL, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_abbrev", + group_number, &dbg->de_debug_abbrev, /*03*/ DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL, - FALSE,err); + TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_abbrev.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_abbrev, /*03*/ DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL, - FALSE,err); + TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_aranges", + group_number, &dbg->de_debug_aranges, DW_DLE_DEBUG_ARANGES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_line", + group_number, &dbg->de_debug_line, DW_DLE_DEBUG_LINE_DUPLICATE,0, - FALSE,err); + TRUE,err); + /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_line_str", + group_number, &dbg->de_debug_line_str, DW_DLE_DEBUG_LINE_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_line.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_line, DW_DLE_DEBUG_LINE_DUPLICATE,0, - FALSE,err); + TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_frame", + group_number, &dbg->de_debug_frame, DW_DLE_DEBUG_FRAME_DUPLICATE,0, TRUE,err); /* gnu egcs-1.1.2 data */ SET_UP_SECTION(dbg,scn_name,".eh_frame", + group_number, &dbg->de_debug_frame_eh_gnu, DW_DLE_DEBUG_FRAME_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_loc", + group_number, &dbg->de_debug_loc, DW_DLE_DEBUG_LOC_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_loc.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_loc, DW_DLE_DEBUG_LOC_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_pubnames", + group_number, &dbg->de_debug_pubnames, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_str", + group_number, &dbg->de_debug_str, DW_DLE_DEBUG_STR_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_str.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_str, DW_DLE_DEBUG_STR_DUPLICATE,0, FALSE,err); /* Section new in DWARF3. */ SET_UP_SECTION(dbg,scn_name,".debug_pubtypes", + group_number, &dbg->de_debug_pubtypes, /*13*/ DW_DLE_DEBUG_PUBTYPES_DUPLICATE,0, FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_names", + group_number, + &dbg->de_debug_names, + /*13*/ DW_DLE_DEBUG_NAMES_DUPLICATE,0, + FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_loclists", + group_number, + &dbg->de_debug_loclists, + /*13*/ DW_DLE_DEBUG_LOClISTS_DUPLICATE,0, + FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_loclists.dwo", + DW_GROUPNUMBER_DWO, + &dbg->de_debug_loclists, + /*13*/ DW_DLE_DEBUG_LOClISTS_DUPLICATE,0, + FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_rnglists", + group_number, + &dbg->de_debug_rnglists, + /*13*/ DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0, + FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_rnglists.dwo", + DW_GROUPNUMBER_DWO, + &dbg->de_debug_rnglists, + /*13*/ DW_DLE_DEBUG_RNGLISTS_DUPLICATE,0, + FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_str_offsets", + group_number, + &dbg->de_debug_str_offsets, + DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, + FALSE,err); + /* DWARF5 */ + SET_UP_SECTION(dbg,scn_name,".debug_str_offsets.dwo", + DW_GROUPNUMBER_DWO, + &dbg->de_debug_str_offsets, + DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, + FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_funcnames", + group_number, &dbg->de_debug_funcnames, /*11*/ DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only, created years before DWARF3. Content essentially identical to .debug_pubtypes. */ SET_UP_SECTION(dbg,scn_name,".debug_typenames", + group_number, &dbg->de_debug_typenames, /*12*/ DW_DLE_DEBUG_TYPENAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_varnames", + group_number, &dbg->de_debug_varnames, DW_DLE_DEBUG_VARNAMES_DUPLICATE,0, FALSE,err); /* SGI IRIX-only. */ SET_UP_SECTION(dbg,scn_name,".debug_weaknames", + group_number, &dbg->de_debug_weaknames, DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".debug_macinfo", + group_number, &dbg->de_debug_macinfo, DW_DLE_DEBUG_MACINFO_DUPLICATE,0, TRUE,err); @@ -445,48 +607,46 @@ enter_section_in_de_debug_sections_array(Dwarf_Debug dbg, /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_macro", + group_number, &dbg->de_debug_macro, DW_DLE_DEBUG_MACRO_DUPLICATE,0, TRUE,err); /* DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_macro.dwo", + DW_GROUPNUMBER_DWO, &dbg->de_debug_macro, DW_DLE_DEBUG_MACRO_DUPLICATE,0, TRUE,err); SET_UP_SECTION(dbg,scn_name,".debug_ranges", + group_number, &dbg->de_debug_ranges, DW_DLE_DEBUG_RANGES_DUPLICATE,0, TRUE,err); /* No .debug_ranges.dwo allowed. */ - /* New DWARF5 */ - SET_UP_SECTION(dbg,scn_name,".debug_str_offsets", - &dbg->de_debug_str_offsets, - DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, - TRUE,err); - /* New DWARF5 */ - SET_UP_SECTION(dbg,scn_name,".debug_str_offsets.dwo", - &dbg->de_debug_str_offsets, - DW_DLE_DEBUG_STR_OFFSETS_DUPLICATE,0, - TRUE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_sup", + group_number, &dbg->de_debug_sup, DW_DLE_DEBUG_SUP_DUPLICATE,0, TRUE,err); /* No .debug_sup.dwo allowed. */ + /* .symtab and .strtab have to be in any group. */ SET_UP_SECTION(dbg,scn_name,".symtab", + group_number, &dbg->de_elf_symtab, DW_DLE_DEBUG_SYMTAB_ERR,0, FALSE,err); SET_UP_SECTION(dbg,scn_name,".strtab", + group_number, &dbg->de_elf_strtab, DW_DLE_DEBUG_STRTAB_ERR,0, FALSE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_addr", + group_number, &dbg->de_debug_addr, DW_DLE_DEBUG_ADDR_DUPLICATE,0, TRUE,err); @@ -494,44 +654,45 @@ enter_section_in_de_debug_sections_array(Dwarf_Debug dbg, /* gdb added this. */ SET_UP_SECTION(dbg,scn_name,".gdb_index", + group_number, &dbg->de_debug_gdbindex, DW_DLE_DUPLICATE_GDB_INDEX,0, FALSE,err); /* New DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_names", + group_number, &dbg->de_debug_names, DW_DLE_DEBUG_NAMES_DUPLICATE,0, FALSE,err); /* No .debug_names.dwo allowed. */ - /* gdb added this in DW4. It is in standard DWARF5 */ + /* gdb added this in DW4. It is in standard DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_cu_index", + DW_GROUPNUMBER_DWO, &dbg->de_debug_cu_index, DW_DLE_DUPLICATE_CU_INDEX,0, FALSE,err); /* gdb added this in DW4. It is in standard DWARF5 */ SET_UP_SECTION(dbg,scn_name,".debug_tu_index", + DW_GROUPNUMBER_DWO, &dbg->de_debug_tu_index, DW_DLE_DUPLICATE_TU_INDEX,0, FALSE,err); return DW_DLV_NO_ENTRY; } static int -is_section_known_already(Dwarf_Debug dbg, - const char *scn_name, - unsigned *found_section_number, - unsigned start_number, - UNUSEDARG int *err) +is_section_name_known_already(Dwarf_Debug dbg, const char *scn_name) { - unsigned i = start_number; + unsigned i = 0; for ( ; i < dbg->de_debug_sections_total_entries; ++i) { struct Dwarf_dbg_sect_s *section = &dbg->de_debug_sections[i]; if (!strcmp(scn_name, section->ds_name)) { - *found_section_number = i; + /* The caller will declare this a duplicate, an error. */ return DW_DLV_OK; } } + /* This is normal, we expect we've not accepted scn_name already. */ return DW_DLV_NO_ENTRY; } @@ -562,55 +723,440 @@ is_section_known_already(Dwarf_Debug dbg, of the definition of .rela relocations in Elf. */ + +/* For an object file with an incorrect rela section name, + readelf prints correct debug information, + as the tool takes the section type instead + of the section name. So check the + section name but test section type. */ +static int +is_a_rela_section(const char *scn_name,int type) +{ + if(startswith(scn_name,".rela.")) { + return TRUE; + } + if (type == SHT_RELA) { + return TRUE; + } + return FALSE; +} + +/* ASSERT: names like .debug_ or .zdebug_ never passed in here! */ +static int +is_a_special_section_semi_dwarf(const char *scn_name) +{ + if (!strcmp(scn_name,".strtab") || + !strcmp(scn_name,".symtab")) { + return TRUE; + } + /* It's not one of these special sections referenced in + the test. */ + return FALSE; +} + static int this_section_dwarf_relevant(const char *scn_name,int type) { /* A small helper function for _dwarf_setup(). */ - if (0 ==strncmp(scn_name, ".zdebug_", 8) || - 0 == strncmp(scn_name, ".debug_", 7) ) { + if (startswith(scn_name, ".zdebug_") || + startswith(scn_name, ".debug_")) { + /* standard debug */ return TRUE; } - if( strcmp(scn_name, ".eh_frame") - && strcmp(scn_name, ".symtab") - && strcmp(scn_name, ".strtab") - && strcmp(scn_name, ".gdb_index") - && strncmp(scn_name, ".rela.",6) - /* For an object file with incorrect rela section name, - readelf prints correct debug information, - as the tool takes the section type instead - of the section name. Include the incorrect - section name, until this test uses the section type. */ - && type != SHT_RELA) { - /* Other sections should be ignored, they - are not relevant for DWARF data. */ - return FALSE; + /* Now check if a special section could be + in a section_group, but though seems unlikely. */ + if (!strcmp(scn_name, ".eh_frame")) { + /* This is not really a group related file, but + it is harmless to consider it such. */ + return TRUE; } - /* This is one of ours. */ - return TRUE; + if(!strcmp(scn_name, ".gdb_index")) { + return TRUE; + } + if(is_a_special_section_semi_dwarf(scn_name)) { + return TRUE; + } + if(is_a_rela_section(scn_name,type)) { + return TRUE; + } + /* All sorts of sections are of no interest: .text + .rel. and many others. */ + return FALSE; +} + +/* This assumes any non-Elf object files have no SHT_GROUP + sections. So this code will not be invoked on non-Elf objects. + One supposes this is unlikely to match any non-Elf + version of COMDAT. */ +static int +insert_sht_list_in_group_map(Dwarf_Debug dbg, + struct Dwarf_Obj_Access_Section_s *doas, + unsigned comdat_group_number, + unsigned section_number, + Dwarf_Unsigned section_count, + struct Dwarf_Obj_Access_Interface_s * obj, + unsigned *did_add_map, + Dwarf_Error *error) +{ + struct Dwarf_Section_s secdata; + Dwarf_Small * data = 0; + int res = 0; + Dwarf_Small* secend = 0; + + memset(&secdata,0,sizeof(secdata)); + secdata.dss_size = doas->size; + secdata.dss_entrysize = doas->entrysize; + secdata.dss_group_number = 1; /* arbitrary. */ + secdata.dss_index = section_number; + secdata.dss_name = ".group"; + secdata.dss_standard_name = ".group"; + secdata.dss_number = section_number; + secdata.dss_ignore_reloc_group_sec = TRUE; + res = _dwarf_load_section(dbg,&secdata,error); + if (res != DW_DLV_OK) { + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + return res; + } + if (!secdata.dss_data) { + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + if (doas->entrysize != 4) { + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + /* So now pick up the data in dss_data. + It is an array of 32 bit fields. + Entry zero is just a constant 1. + Each additional is a section number. */ + data = secdata.dss_data; + secend = data + secdata.dss_size; + { + unsigned i = 1; + unsigned count = doas->size/doas->entrysize; + Dwarf_Unsigned fval = 0; + + /* The fields treatments with regard + to endianness is unclear. In any case a single + bit should be on, as 0x01000000 + without any endiannes swapping. + Or so it seems given limited evidence. + We read with length checking and allow the + reader to byte swap and then fix things. + At least one test case has big-endian + data but little-endian SHT_GROUP data. */ + if ((data+DWARF_32BIT_SIZE) > secend) { + /* Duplicates the check in READ_UNALIGNED_CK + so we can free allocated memory bere. */ + free(secdata.dss_data); + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + READ_UNALIGNED_CK(dbg,fval,Dwarf_Unsigned, + data, + DWARF_32BIT_SIZE, + error, + secend); + if (fval != 1 && fval != 0x1000000) { + /* Could be corrupted elf object. */ + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + + data = data + doas->entrysize; + for (i = 1 ; i < count ; ++i) { + Dwarf_Unsigned val = 0; + + if ((data+DWARF_32BIT_SIZE) > secend) { + /* Duplicates the check in READ_UNALIGNED_CK + so we can free allocated memory bere. */ + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + READ_UNALIGNED_CK(dbg,val,Dwarf_Unsigned, + data, + DWARF_32BIT_SIZE, + error, + secend); + if (val > section_count) { + /* Might be confused endianness by + the compiler generating the SHT_GROUP. + This is pretty horrible. */ + Dwarf_Unsigned valr = 0; + _dwarf_memcpy_swap_bytes(&valr,&val, + DWARF_32BIT_SIZE); + if (valr > section_count) { + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_ERROR; + } + /* Ok. Yes, ugly. */ + val = valr; + } + { + /* Ensure this group entry DWARF relevant before + adding to group map */ + struct Dwarf_Obj_Access_Section_s doasx; + int resx = DW_DLV_ERROR; + int err = 0; + + memset(&doasx,0,sizeof(doasx)); + resx = obj->methods->get_section_info(obj->object, + val, + &doasx, &err); + if (resx == DW_DLV_NO_ENTRY){ + /* Should we really ignore this? */ + continue; + } else if (resx == DW_DLV_ERROR){ + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + _dwarf_error(dbg,error,err); + return resx; + } + if (!this_section_dwarf_relevant(doasx.name, + doasx.type) ) { + continue; + } + data += DWARF_32BIT_SIZE; + *did_add_map = TRUE; + res = _dwarf_insert_in_group_map(dbg, + comdat_group_number,val, + doasx.name, + error); + if (res != DW_DLV_OK) { + free(secdata.dss_data); + return res; + } + } + } + } + if (secdata.dss_data_was_malloc) { + free(secdata.dss_data); + } + return DW_DLV_OK; +} + + + +/* Split dwarf CUs can be in an object with non-split + or split may be in a separate object. + If all in one object the default is to deal with group_number + and ignore DW_GROUPNUMBER_DWO. + If only .dwo the default is DW_GROUPNUMBER_DWO(2). + Otherwise use DW_GROUP_NUMBER_BASE(1). + + If there are COMDAT SHT_GROUP sections, these + are assigned group numbers 3-N as needed. + + At present this makes the assumption that COMDAT group + (ie, SHT_GROUP) sections + have lower section numbers than the sections COMDAT refers to. + It is not clear whether this is guaranteed, COMDAT is not + an official Elf thing and documentation is scarce. + In the 1990's SGI folks and others formed a committee + and attempted to get COMDAT and a feature allowing section + numbers greater than 16 bits into Elf, but there was no + group that was able to approve such things. + + This is called once at dbg init time. +*/ + +static int +determine_target_group(Dwarf_Unsigned section_count, + struct Dwarf_Obj_Access_Interface_s * obj, + unsigned *group_number_out, + Dwarf_Debug dbg, + Dwarf_Error *error) +{ + unsigned obj_section_index = 0; + int found_group_one = 0; + int found_group_two = 0; + struct Dwarf_Group_Data_s *grp = 0; + unsigned comdat_group_next = 3; + unsigned lowest_comdat_groupnum = 0; + + grp = &dbg->de_groupnumbers; + grp->gd_number_of_groups = 0; + grp->gd_number_of_sections = section_count; + if (grp->gd_map) { + _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); + return DW_DLV_OK; + } + for (obj_section_index = 0; obj_section_index < section_count; + ++obj_section_index) { + + struct Dwarf_Obj_Access_Section_s doas; + int res = DW_DLV_ERROR; + int err = 0; + const char *scn_name = 0; + unsigned groupnumber = 0; + unsigned mapgroupnumber = 0; + + memset(&doas,0,sizeof(doas)); + res = obj->methods->get_section_info(obj->object, + obj_section_index, + &doas, &err); + if (res == DW_DLV_NO_ENTRY){ + return res; + } else if (res == DW_DLV_ERROR){ + _dwarf_error(dbg, error,err); + return res; + } + + if (doas.type == SHT_GROUP) { + /* See assumptions in function comment above. */ + unsigned did_add_map = 0; + /* Add to our map. Here we + are assuming SHT_GROUP records come first. + Till proven wrong. */ + res = insert_sht_list_in_group_map(dbg,&doas, + comdat_group_next, + obj_section_index, + section_count, + obj, + &did_add_map,error); + if (res != DW_DLV_OK) { + return res; + } + if (!lowest_comdat_groupnum) { + lowest_comdat_groupnum = comdat_group_next; + } + if (did_add_map) { + ++grp->gd_number_of_groups; + ++comdat_group_next; + } + continue; + } + scn_name = doas.name; + if (!this_section_dwarf_relevant(scn_name,doas.type) ) { + continue; + } + + /* Now at a 'normal' section, though we do not + quite know what group it is. */ + + res = _dwarf_section_get_target_group_from_map(dbg, + obj_section_index,&groupnumber,error); + if (res == DW_DLV_OK ) { + /* groupnumber is set. Fall through. + All COMDAT group should get here. */ + mapgroupnumber = groupnumber; + } else if (res == DW_DLV_ERROR) { + return res; + } else { /* DW_DLV_NO_ENTRY */ + /* Normal non-COMDAT. groupnumber is zero. */ + } + + + /* BUILDING_MAP. See also BUILDING_SECTIONS, SETUP_SECTION */ + if (!groupnumber) { + res =_dwarf_dwo_groupnumber_given_name(scn_name, + &groupnumber); + /* DW_DLV_ERROR impossible here. */ + if (res == DW_DLV_OK) { + /* groupnumber set 2 */ + } else { + /* This is what it has to be. + .rela in here too. */ + groupnumber = DW_GROUPNUMBER_BASE; + } + } + if (is_a_rela_section(scn_name,doas.type)) { + unsigned linkgroup = 0; + res = _dwarf_section_get_target_group_from_map(dbg, + doas.info, + &linkgroup,error); + if (res == DW_DLV_OK ) { + /* Fall through. + linkgroup is in group map already. */ + } else if (res == DW_DLV_ERROR) { + return res; + } else { /* DW_DLV_NO_ENTRY */ + res = _dwarf_insert_in_group_map(dbg, + linkgroup,obj_section_index, + scn_name, + error); + if (res != DW_DLV_OK ) { + return res; + } + } + continue; + } + + /* ASSERT: groupnumber non-zero now */ + if (!is_a_special_section_semi_dwarf(scn_name)) { + if (mapgroupnumber) { + /* Already in group map */ + continue; + } + /* !mapgroupnumber */ + res = _dwarf_insert_in_group_map(dbg, + groupnumber,obj_section_index, + scn_name, + error); + if (res != DW_DLV_OK) { + return res; + } + if (groupnumber == 1) { + found_group_one++; + } else if (groupnumber == 2) { + found_group_two++; + } + continue; + } + } + if (found_group_two) { + ++grp->gd_number_of_groups; + } + if (found_group_one) { + *group_number_out = DW_GROUPNUMBER_BASE; + ++grp->gd_number_of_groups; + } else { + if (found_group_two) { + *group_number_out = DW_GROUPNUMBER_DWO; + } else { + if (lowest_comdat_groupnum) { + *group_number_out = lowest_comdat_groupnum; + } else { + *group_number_out = DW_GROUPNUMBER_BASE; + } + } + } + return DW_DLV_OK; } + static int _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) { const char *scn_name = 0; - int foundDwarf = 0; struct Dwarf_Obj_Access_Interface_s * obj = 0; - - Dwarf_Endianness endianness; - - /* Table with pointers to debug sections */ + int resn = 0; struct Dwarf_Section_s **sections = 0; - + Dwarf_Endianness endianness; Dwarf_Unsigned section_count = 0; + unsigned default_group_number = 0; + unsigned foundDwarf = FALSE; unsigned obj_section_index = 0; - foundDwarf = FALSE; - dbg->de_assume_string_in_bounds = _dwarf_assume_string_in_bounds; - dbg->de_same_endian = 1; - dbg->de_copy_word = memcpy; + dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; obj = dbg->de_obj_file; endianness = obj->methods->get_byte_order(obj->object); #ifdef WORDS_BIGENDIAN @@ -636,7 +1182,14 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) dbg->de_pointer_size = obj->methods->get_pointer_size(obj->object); section_count = obj->methods->get_section_count(obj->object); - + resn = determine_target_group(section_count,obj, + &default_group_number,dbg,error); + if (resn == DW_DLV_ERROR) { + return DW_DLV_ERROR; + } + if (dbg->de_groupnumber == DW_GROUPNUMBER_ANY) { + dbg->de_groupnumber = default_group_number; + } /* Allocate space to record references to debug sections, that can be referenced by RELA sections in the 'sh_info' field. */ sections = (struct Dwarf_Section_s **)calloc(section_count + 1, @@ -659,13 +1212,29 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) here. So the get_section_info() must adapt to the situation (the elf version does automatically as a result of Elf having a section zero with zero length and an empty name). */ + + /* ASSERT: all group map entries set up. */ + for (obj_section_index = 0; obj_section_index < section_count; ++obj_section_index) { struct Dwarf_Obj_Access_Section_s doas; int res = DW_DLV_ERROR; int err = 0; - + unsigned groupnumber = 0; + unsigned mapgroupnumber = 0; + + res = _dwarf_section_get_target_group_from_map(dbg,obj_section_index, + &groupnumber,error); + if (res == DW_DLV_OK ) { + /* groupnumber is set. Fall through */ + mapgroupnumber = groupnumber; + } else if (res == DW_DLV_ERROR) { + free(sections); + return res; + } else { /* DW_DLV_NO_ENTRY */ + /* fall through, a BASE or DWO group, possibly */ + } memset(&doas,0,sizeof(doas)); res = obj->methods->get_section_info(obj->object, obj_section_index, @@ -677,23 +1246,51 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) free(sections); DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } - scn_name = doas.name; - + if (!groupnumber) { + /* This finds dwo sections, group 2 */ + res = _dwarf_dwo_groupnumber_given_name(scn_name, + &groupnumber); + if (res == DW_DLV_NO_ENTRY) { + /* No, must be group 1 */ + groupnumber = DW_GROUPNUMBER_BASE; + } + } if (!this_section_dwarf_relevant(scn_name,doas.type) ) { continue; - } else { + } + if (!is_a_rela_section(scn_name,doas.type) + && !is_a_special_section_semi_dwarf(scn_name)) { + /* We do these actions only for group-related + sections. Do for .debug_info etc, + never for .strtab or .rela.* + We already tested for relevance, so that part + is not news. */ + if(mapgroupnumber == dbg->de_groupnumber) { + /* OK. Mapped. Part of the group.. This will + catch the cases where there are versions of + a section in multiple COMDATs and in BASE + an DWO to get the right one */ + } else { + /* This section not mapped into this group. */ + if (groupnumber == 1 && dbg->de_groupnumber > 2 && + !_dwarf_section_in_group_by_name(dbg,scn_name, + dbg->de_groupnumber)) { + /* Load the section (but as group 1) */ + } else { + continue; + } + } + } + /* BUILDING_SECTIONS. See also BUILDING_MAP, SETUP_SECTION */ + { /* Build up the sections table and the de_debug* etc pointers in Dwarf_Debug. */ struct Dwarf_dbg_sect_s *section; int found_match = FALSE; - unsigned initial_start_number = 0; - unsigned dbg_section_number = 0; - res = is_section_known_already(dbg,scn_name, - &dbg_section_number, - initial_start_number, - &err); + + res = is_section_name_known_already(dbg,scn_name); if (res == DW_DLV_OK) { /* DUPLICATE */ free(sections); @@ -705,41 +1302,26 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) } /* No entry: new-to-us section, the normal case. */ res = enter_section_in_de_debug_sections_array(dbg,scn_name, - obj_section_index,&err); + obj_section_index, groupnumber,&err); if (res == DW_DLV_OK) { - /* We just added a new entry in the dbg - de_debug_sections array. So we know its number. */ - unsigned real_start_number = - dbg->de_debug_sections_total_entries-1; - res = is_section_known_already(dbg,scn_name, - &dbg_section_number, - real_start_number, - &err); - if (res == DW_DLV_OK) { - section = &dbg->de_debug_sections[dbg_section_number]; - res = get_basic_section_data(dbg, - section->ds_secdata, &doas, - obj_section_index, error, - section->ds_duperr, - section->ds_emptyerr); - if (res != DW_DLV_OK) { - free(sections); - return res; - } - sections[obj_section_index] = section->ds_secdata; - foundDwarf += section->ds_have_dwarf; - found_match = TRUE; - /* Normal section set up. - Fall through. */ - }else if (res == DW_DLV_NO_ENTRY) { - /* Some sort of bug in the code here. - Should be impossible to get here. */ + section = &dbg->de_debug_sections[ + dbg->de_debug_sections_total_entries-1]; + res = get_basic_section_data(dbg, + section->ds_secdata, &doas, + obj_section_index, + groupnumber, + error, + section->ds_duperr, + section->ds_emptyerr); + if (res != DW_DLV_OK) { free(sections); - DWARF_DBG_ERROR(dbg, DW_DLE_SECTION_ERROR, DW_DLV_ERROR); - } else { - free(sections); - DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); + return res; } + sections[obj_section_index] = section->ds_secdata; + foundDwarf += section->ds_have_dwarf; + found_match = TRUE; + /* Normal section set up. + Fall through. */ } else if (res == DW_DLV_NO_ENTRY) { /* We get here for relocation sections. Fall through. */ @@ -755,10 +1337,11 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) of the section name. If the current section is a RELA one and the 'sh_info' refers to a debug section, add the relocation data. */ - if (doas.type == SHT_RELA) { + if (is_a_rela_section(scn_name,doas.type)) { if ( doas.info < section_count) { if (sections[doas.info]) { - add_rela_data(sections[doas.info],&doas, + add_rela_data_to_secdata(sections[doas.info], + &doas, obj_section_index); } } else { @@ -780,20 +1363,6 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) return DW_DLV_NO_ENTRY; } -#if 0 -static int -all_sig8_bits_zero(Dwarf_Sig8 *val) -{ - unsigned u = 0; - for( ; u < sizeof(*val); ++u) { - if (val->signature[u] != 0) { - return FALSE; - } - } - return TRUE; -} -#endif /* if 0 */ - /* There is one table per CU and one per TU, and each table refers to the associated other DWARF data for that CU or TU. @@ -862,9 +1431,22 @@ load_debugfission_tables(Dwarf_Debug dbg,Dwarf_Error *error) wishes. */ int -dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, +dwarf_object_init(Dwarf_Obj_Access_Interface* obj, + Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg, Dwarf_Error* error) +{ + return dwarf_object_init_b(obj,errhand,errarg, + DW_GROUPNUMBER_ANY,ret_dbg,error); +} + +/* New March 2017. Enables dealing with DWARF5 split dwarf more fully. */ +int +dwarf_object_init_b(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, + Dwarf_Ptr errarg, + unsigned groupnumber, + Dwarf_Debug* ret_dbg, + Dwarf_Error* error) { Dwarf_Debug dbg = 0; int setup_result = DW_DLV_OK; @@ -893,7 +1475,7 @@ dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL; dbg->de_obj_file = obj; - + dbg->de_groupnumber = groupnumber; setup_result = _dwarf_setup(dbg, error); if (setup_result == DW_DLV_OK) { int fission_result = load_debugfission_tables(dbg,error); @@ -908,6 +1490,7 @@ dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, } if (setup_result != DW_DLV_OK) { int freeresult = 0; + int myerr = 0; /* We cannot use any _dwarf_setup() error here as we are freeing dbg, making that error (setup @@ -916,7 +1499,6 @@ dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, But error might be NULL and the init call error-handler function might be set. */ - int myerr = 0; if ( (setup_result == DW_DLV_ERROR) && error ) { /* Preserve our _dwarf_setup error number, but this does not apply if error NULL. */ @@ -956,12 +1538,11 @@ dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand, return DW_DLV_OK; } - /* A finish routine that is completely unaware of ELF. Frees all memory that was not previously freed by dwarf_dealloc. - Aside frmo certain categories. */ + Aside from certain categories. */ int dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error) { @@ -993,6 +1574,11 @@ dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error) and the decompressed_length. Then what follows the implicit Chdr is decompressed. */ + +/* ALLOWED_ZLIB_INFLATION is a heuristic, not necessarily right. + The test case klingler2/compresseddebug.amd64 actually + inflates about 8 times. */ +#define ALLOWED_ZLIB_INFLATION 16 static int do_decompress_zlib(Dwarf_Debug dbg, struct Dwarf_Section_s *section, @@ -1012,6 +1598,7 @@ do_decompress_zlib(Dwarf_Debug dbg, if ((src + 12) >endsection) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR); } + section->dss_compressed_length = section->dss_size; if(!strncmp("ZLIB",(const char *)src,4)) { unsigned i = 0; unsigned l = 8; @@ -1022,6 +1609,8 @@ do_decompress_zlib(Dwarf_Debug dbg, } src = src + 12; srclen -= 12; + section->dss_uncompressed_length = uncompressed_len; + section->dss_ZLIB_compressed = TRUE; } else if (flags & SHF_COMPRESSED) { /* The prefix is a struct: unsigned int type; followed by pad if following are 64bit! @@ -1035,23 +1624,50 @@ do_decompress_zlib(Dwarf_Debug dbg, unsigned fldsize = dbg->de_pointer_size; unsigned structsize = 3* fldsize; - READ_UNALIGNED_CK(dbg,type,Dwarf_Unsigned,ptr,sizeof(Dwarf_ufixed), + READ_UNALIGNED_CK(dbg,type,Dwarf_Unsigned,ptr, + DWARF_32BIT_SIZE, error,endsection); ptr += fldsize; READ_UNALIGNED_CK(dbg,size,Dwarf_Unsigned,ptr,fldsize, error,endsection); - ptr += fldsize; if (type != ELFCOMPRESS_ZLIB) { - DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, DW_DLV_ERROR); + DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, + DW_DLV_ERROR); } uncompressed_len = size; - /* Not using addralign. - READ_UNALIGNED(dbg,addralign,Dwarf_Unsigned,ptr,fldsize); */ - + section->dss_uncompressed_length = uncompressed_len; src += structsize; srclen -= structsize; + section->dss_shf_compressed = TRUE; } else { - DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, DW_DLV_ERROR); + DWARF_DBG_ERROR(dbg, DW_DLE_ZDEBUG_INPUT_FORMAT_ODD, + DW_DLV_ERROR); + } + { + /* According to zlib.net zlib essentially never expands + the data when compressing. There is no statement + about any effective limit in the compression factor + though we, here, assume such a limit to check + for sanity in the object file. + These tests are heuristics. */ + Dwarf_Unsigned max_inflated_len = srclen*ALLOWED_ZLIB_INFLATION; + + if (srclen > 50) { + /* If srclen not super tiny lets check the following. */ + if (uncompressed_len < (srclen/2)) { + /* Violates the approximate invariant about + compression not actually inflating. */ + DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, + DW_DLV_ERROR); + } + } + if (max_inflated_len < srclen) { + /* The calculation overflowed. */ + DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); + } + if (uncompressed_len > max_inflated_len) { + DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_UNCOMPRESS_ERROR, DW_DLV_ERROR); + } } if( (src +srclen) > endsection) { DWARF_DBG_ERROR(dbg, DW_DLE_ZLIB_SECTION_SHORT, DW_DLV_ERROR); @@ -1077,7 +1693,7 @@ do_decompress_zlib(Dwarf_Debug dbg, section->dss_data = dest; section->dss_size = destlen; section->dss_data_was_malloc = TRUE; - section->dss_requires_decompress = FALSE; + section->dss_did_decompress = TRUE; return DW_DLV_OK; } #endif /* HAVE_ZLIB */ @@ -1099,14 +1715,17 @@ _dwarf_load_section(Dwarf_Debug dbg, return DW_DLV_OK; } o = dbg->de_obj_file; - /* There is an elf convention that section index 0 is reserved, - and that section is always empty. - Non-elf object formats must honor that by ensuring that - (when they assign numbers to 'sections' or 'section-like-things') - they never assign a real section section-number 0 to dss_index. - - There is also a convention for 'bss' that that section and its - like sections have no data but do have a size. + /* There is an elf convention that section index 0 + is reserved, and that section is always empty. + Non-elf object formats must honor + that by ensuring that (when they + assign numbers to 'sections' or + 'section-like-things') they never + assign a real section section-number + 0 to dss_index. + + There is also a convention for 'bss' that that section + and its like sections have no data but do have a size. That is never true of DWARF sections */ res = o->methods->load_section( o->object, section->dss_index, @@ -1114,6 +1733,12 @@ _dwarf_load_section(Dwarf_Debug dbg, if (res == DW_DLV_ERROR) { DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } + /* For PE and mach-o all section data was always + malloc'd. We do not need to set dss_data_was_malloc + though as the o->object data will eventually free + the original section data. + The first character of any o->object struct gives the type. */ + if (res == DW_DLV_NO_ENTRY) { /* Gets this for section->dss_index 0. Which by ELF definition is a section index @@ -1124,7 +1749,14 @@ _dwarf_load_section(Dwarf_Debug dbg, no DWARF related section could possbly be bss. */ return res; } - if (section->dss_requires_decompress) { + if (section->dss_ignore_reloc_group_sec) { + /* Neither zdebug nor reloc apply to .group sections. */ + return res; + } + if ((section->dss_zdebug_requires_decompress || + section->dss_shf_compressed || + section->dss_ZLIB_compressed) && + !section->dss_did_decompress) { if (!section->dss_data) { /* Impossible. This makes no sense. Corrupt object. */ @@ -1135,6 +1767,7 @@ _dwarf_load_section(Dwarf_Debug dbg, if (res != DW_DLV_OK) { return res; } + section->dss_did_decompress = TRUE; #else DWARF_DBG_ERROR(dbg,DW_DLE_ZDEBUG_REQUIRES_ZLIB, DW_DLV_ERROR); #endif @@ -1222,7 +1855,7 @@ dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, return DW_DLV_OK; } -/* Now with sections new to DWARF5 */ +/* Now with sections new to DWARF5 (unofficial list,preliminary) */ int dwarf_get_section_max_offsets_c(Dwarf_Debug dbg, Dwarf_Unsigned * debug_info_size, @@ -1263,6 +1896,53 @@ dwarf_get_section_max_offsets_c(Dwarf_Debug dbg, return DW_DLV_OK; } +/* Now with final sections new to DWARF5 (final) */ +int +dwarf_get_section_max_offsets_d(Dwarf_Debug dbg, + Dwarf_Unsigned * debug_info_size, + Dwarf_Unsigned * debug_abbrev_size, + Dwarf_Unsigned * debug_line_size, + Dwarf_Unsigned * debug_loc_size, + Dwarf_Unsigned * debug_aranges_size, + Dwarf_Unsigned * debug_macinfo_size, + Dwarf_Unsigned * debug_pubnames_size, + Dwarf_Unsigned * debug_str_size, + Dwarf_Unsigned * debug_frame_size, + Dwarf_Unsigned * debug_ranges_size, + Dwarf_Unsigned * debug_typenames_size, + Dwarf_Unsigned * debug_types_size, + Dwarf_Unsigned * debug_macro_size, + Dwarf_Unsigned * debug_str_offsets_size, + Dwarf_Unsigned * debug_sup_size, + Dwarf_Unsigned * debug_cu_index_size, + Dwarf_Unsigned * debug_tu_index_size, + Dwarf_Unsigned * debug_names_size, + Dwarf_Unsigned * debug_loclists_size, + Dwarf_Unsigned * debug_rnglists_size) +{ + *debug_info_size = dbg->de_debug_info.dss_size; + *debug_abbrev_size = dbg->de_debug_abbrev.dss_size; + *debug_line_size = dbg->de_debug_line.dss_size; + *debug_loc_size = dbg->de_debug_loc.dss_size; + *debug_aranges_size = dbg->de_debug_aranges.dss_size; + *debug_macinfo_size = dbg->de_debug_macinfo.dss_size; + *debug_pubnames_size = dbg->de_debug_pubnames.dss_size; + *debug_str_size = dbg->de_debug_str.dss_size; + *debug_frame_size = dbg->de_debug_frame.dss_size; + *debug_ranges_size = dbg->de_debug_ranges.dss_size; + *debug_typenames_size = dbg->de_debug_typenames.dss_size; + *debug_types_size = dbg->de_debug_types.dss_size; + *debug_macro_size = dbg->de_debug_macro.dss_size; + *debug_str_offsets_size = dbg->de_debug_str_offsets.dss_size; + *debug_sup_size = dbg->de_debug_sup.dss_size; + *debug_cu_index_size = dbg->de_debug_cu_index.dss_size; + *debug_tu_index_size = dbg->de_debug_tu_index.dss_size; + *debug_names_size = dbg->de_debug_names.dss_size; + *debug_loclists_size = dbg->de_debug_loclists.dss_size; + *debug_rnglists_size = dbg->de_debug_rnglists.dss_size; + return DW_DLV_OK; +} + /* Given a section name, get its size and address */ int dwarf_get_section_info_by_name(Dwarf_Debug dbg, @@ -1349,6 +2029,7 @@ dwarf_get_section_count(Dwarf_Debug dbg) { struct Dwarf_Obj_Access_Interface_s * obj = dbg->de_obj_file; if (NULL == obj) { + /* -1 */ return DW_DLV_NO_ENTRY; } return obj->methods->get_section_count(obj->object); diff --git a/thirdparty/dwarf/dwarf_leb.c b/thirdparty/dwarf/dwarf_leb.c index c0e3b8e6..980748c5 100644 --- a/thirdparty/dwarf/dwarf_leb.c +++ b/thirdparty/dwarf/dwarf_leb.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. + Portions Copyright 2011-2018 David Anderson. All Rights Reserved. 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 @@ -25,9 +24,19 @@ */ + #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_util.h" + +/* Note that with 'make check') + many of the test items + only make sense if Dwarf_Unsigned (and Dwarf_Signed) + are 64 bits. The encode/decode logic should + be fine whether those types are 64 or 32 bits. + See runtests.sh */ /* 10 bytes of leb, 7 bits each part of the number, gives room for a 64bit number. @@ -37,96 +46,20 @@ be strange. */ #define BYTESLEBMAX 10 +#define BITSPERBYTE 8 -/* Decode ULEB */ -Dwarf_Unsigned -_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length) -{ - unsigned char byte = 0; - Dwarf_Word word_number = 0; - Dwarf_Unsigned number = 0; - Dwarf_Sword shift = 0; - /* The byte_length value will be a small non-negative integer. */ - unsigned byte_length = 0; - - /* The following unrolls-the-loop for the first few bytes and - unpacks into 32 bits to make this as fast as possible. - word_number is assumed big enough that the shift has a defined - result. */ - if ((*leb128 & 0x80) == 0) { - if (leb128_length) { - *leb128_length = 1; - } - return (*leb128); - } else if ((*(leb128 + 1) & 0x80) == 0) { - if (leb128_length) { - *leb128_length = 2; - } - word_number = *leb128 & 0x7f; - word_number |= (*(leb128 + 1) & 0x7f) << 7; - return (word_number); - } else if ((*(leb128 + 2) & 0x80) == 0) { - if (leb128_length) { - *leb128_length = 3; - } - word_number = *leb128 & 0x7f; - word_number |= (*(leb128 + 1) & 0x7f) << 7; - word_number |= (*(leb128 + 2) & 0x7f) << 14; - return (word_number); - } else if ((*(leb128 + 3) & 0x80) == 0) { - if (leb128_length) { - *leb128_length = 4; - } - word_number = *leb128 & 0x7f; - word_number |= (*(leb128 + 1) & 0x7f) << 7; - word_number |= (*(leb128 + 2) & 0x7f) << 14; - word_number |= (*(leb128 + 3) & 0x7f) << 21; - return (word_number); - } - - /* The rest handles long numbers Because the 'number' may be larger - than the default int/unsigned, we must cast the 'byte' before - the shift for the shift to have a defined result. */ - number = 0; - shift = 0; - byte_length = 1; - byte = *leb128; - for (;;) { - number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift; - - if ((byte & 0x80) == 0) { - if (leb128_length) { - *leb128_length = byte_length; - } - return (number); - } - shift += 7; - - byte_length++; - if (byte_length > BYTESLEBMAX) { - /* Erroneous input. What to do? - Abort? Return error? Just stop here? - Call _dwarf_decode_u_leb128_chk instead. */ - if( leb128_length) { - *leb128_length = BYTESLEBMAX; - } - return number; - } - ++leb128; - byte = *leb128; - } -} - /* Decode ULEB with checking */ int -_dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, - Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr) +_dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, + Dwarf_Unsigned * leb128_length, + Dwarf_Unsigned *outval, + Dwarf_Byte_Ptr endptr) { - unsigned char byte = 0; - Dwarf_Word word_number = 0; + Dwarf_Unsigned byte = 0; + Dwarf_Unsigned word_number = 0; Dwarf_Unsigned number = 0; - Dwarf_Sword shift = 0; + unsigned shift = 0; /* The byte_length value will be a small non-negative integer. */ unsigned byte_length = 0; @@ -167,8 +100,10 @@ _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, byte_length = 1; byte = *leb128; for (;;) { - number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift; - + if (shift >= (sizeof(number)*BITSPERBYTE)) { + return DW_DLV_ERROR; + } + number |= (byte & 0x7f) << shift; if ((byte & 0x80) == 0) { if (leb128_length) { *leb128_length = byte_length; @@ -177,7 +112,6 @@ _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, return DW_DLV_OK; } shift += 7; - byte_length++; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ @@ -198,59 +132,14 @@ _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, #define BITSINBYTE 8 -/* decode SLEB */ -Dwarf_Signed -_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length) -{ - Dwarf_Signed number = 0; - Dwarf_Bool sign = 0; - Dwarf_Word shift = 0; - unsigned char byte = *leb128; - /* The byte_length value will be a small non-negative integer. */ - unsigned byte_length = 1; - - /* byte_length being the number of bytes of data absorbed so far in - turning the leb into a Dwarf_Signed. */ - for (;;) { - sign = byte & 0x40; - number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift; - shift += 7; - - if ((byte & 0x80) == 0) { - break; - } - ++leb128; - byte = *leb128; - byte_length++; - if (byte_length > BYTESLEBMAX) { - /* Erroneous input, as who would put leading - 0x80 for leading zeros? - call _dwarf_decode_s_leb128_chk instead. */ - if (leb128_length) { - *leb128_length = BYTESLEBMAX; - } - return number; - } - } - - if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) { - number |= -((Dwarf_Signed) 1 << shift); - } - - if (leb128_length) { - *leb128_length = byte_length; - } - return number; -} - int -_dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, +_dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length, Dwarf_Signed *outval,Dwarf_Byte_Ptr endptr) { + Dwarf_Unsigned byte = 0; Dwarf_Signed number = 0; Dwarf_Bool sign = 0; - Dwarf_Word shift = 0; - unsigned char byte = 0; + Dwarf_Unsigned shift = 0; /* The byte_length value will be a small non-negative integer. */ unsigned byte_length = 1; @@ -265,18 +154,21 @@ _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, byte = *leb128; for (;;) { sign = byte & 0x40; - number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift; + if (shift >= (sizeof(number)*BITSPERBYTE)) { + return DW_DLV_ERROR; + } + number |= ((Dwarf_Unsigned) ((byte & 0x7f))) << shift; shift += 7; if ((byte & 0x80) == 0) { break; } ++leb128; - byte = *leb128; - byte_length++; if (leb128 >= endptr) { return DW_DLV_ERROR; } + byte = *leb128; + byte_length++; if (byte_length > BYTESLEBMAX) { /* Erroneous input. */ if (leb128_length) { @@ -286,8 +178,14 @@ _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, } } - if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) { - number |= -((Dwarf_Signed) 1 << shift); + if (sign) { + /* The following avoids undefined behavior. */ + unsigned shiftlim = sizeof(Dwarf_Signed) * BITSINBYTE -1; + if (shift < shiftlim) { + number |= -(Dwarf_Signed)(((Dwarf_Unsigned)1) << shift); + } else if (shift == shiftlim) { + number |= (((Dwarf_Unsigned)1) << shift); + } } if (leb128_length) { @@ -296,4 +194,3 @@ _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Word * leb128_length, *outval = number; return DW_DLV_OK; } - diff --git a/thirdparty/dwarf/dwarf_leb_test.c b/thirdparty/dwarf/dwarf_leb_test.c new file mode 100644 index 00000000..e89e9f11 --- /dev/null +++ b/thirdparty/dwarf/dwarf_leb_test.c @@ -0,0 +1,346 @@ +/* + Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright 2011-2018 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + + +#include "config.h" +#include +#include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "pro_encode_nm.h" + + +static void +printinteresting(void) +{ + return; +} + +static Dwarf_Signed stest[] = { +0,0xff, +0x800000000000002f, +0x800000000000003f, +0x800000000000004f, +0x8000000000000070, +0x800000000000007f, +0x8000000000000080, +0x8000000000000000, +0x800000ffffffffff, +0x80000000ffffffff, +0x800000ffffffffff, +0x8000ffffffffffff, +0xffffffffffffffff, +-1703944 /*18446744073707847672 as signed*/, +562949951588368, +-1, +-127, +-100000, +-2000000000, +-4000000000, +-8000000000, +-800000000000, +}; +static Dwarf_Unsigned utest[] = { +0,0xff,0x7f,0x80, +0x800000000000002f, +0x800000000000003f, +0x800000000000004f, +0x8000000000000070, +0x800000000000007f, +0x8000000000000080, +0x800000ffffffffff, +0x80000000ffffffff, +0x800000ffffffffff, +0x8000ffffffffffff, +9223372036854775808ULL, +-1703944 /*18446744073707847672 as signed*/, +562949951588368, +0xffff, +0xffffff, +0xffffffff, +0xffffffffff, +0xffffffffffff, +0xffffffffffffff, +0xffffffffffffffff +}; + + +#if 0 /* FOR DEBUGGING */ +static void +dump_encoded(char *space,int len) +{ + int t; + + printf("encode len %d: ",len); + for ( t = 0; t < len; ++t) { + printf("%02x",space[t] & 0xff); + } + printf("\n"); +} +#endif + + +#define BUFFERLEN 100 + + +static unsigned +signedtest(unsigned len) +{ + unsigned errcnt = 0; + unsigned t = 0; + char bufferspace[BUFFERLEN]; + + for ( ; t < len; ++t) { + int res = 0; + int encodelen = 0; + Dwarf_Unsigned decodelen = 0; + Dwarf_Signed decodeval = 0; + + res = _dwarf_pro_encode_signed_leb128_nm( + stest[t],&encodelen,bufferspace,BUFFERLEN); + if (res != DW_DLV_OK) { + printf("FAIL signed encode index %u val 0x%llx\n", + t,stest[t]); + ++errcnt; + } + res = _dwarf_decode_s_leb128_chk( + (Dwarf_Small *)bufferspace, + &decodelen, + &decodeval, + (Dwarf_Byte_Ptr)(&bufferspace[BUFFERLEN-1])); + if (res != DW_DLV_OK) { + printf("FAIL signed decode index %u val 0x%llx\n", + t,stest[t]); + ++errcnt; + } + if (stest[t] != decodeval) { + printf("FAIL signed decode val index %u val 0x%llx vs 0x%llx\n", + t,stest[t],decodeval); + ++errcnt; + } + if ((Dwarf_Unsigned)encodelen != decodelen) { + printf("FAIL signed decodelen val index %u val 0x%llx\n", + t,stest[t]); + ++errcnt; + } + } + return errcnt; +} + +static unsigned +unsignedtest(unsigned len) +{ + unsigned errcnt = 0; + unsigned t = 0; + char bufferspace[BUFFERLEN]; + + for ( ; t < len; ++t) { + int res = 0; + int encodelen = 0; + Dwarf_Unsigned decodelen = 0; + Dwarf_Unsigned decodeval = 0; + + res = _dwarf_pro_encode_leb128_nm( + utest[t],&encodelen,bufferspace,BUFFERLEN); + if (res != DW_DLV_OK) { + printf("FAIL signed encode index %u val 0x%llx", + t,utest[t]); + ++errcnt; + } + res = _dwarf_decode_u_leb128_chk( + (Dwarf_Small *)bufferspace, + &decodelen, + &decodeval, + (Dwarf_Byte_Ptr)(&bufferspace[BUFFERLEN-1])); + if (res != DW_DLV_OK) { + printf("FAIL signed decode index %u val 0x%llx\n", + t,utest[t]); + ++errcnt; + } + if (utest[t] != decodeval) { + printf("FAIL signed decode val index %u val 0x%llx vs 0x%llx\n", + t,utest[t],decodeval); + ++errcnt; + } + if ((Dwarf_Unsigned)encodelen != decodelen) { + printf("FAIL signed decodelen val index %u val 0x%llx\n", + t,utest[t]); + ++errcnt; + } + } + return errcnt; +} +static unsigned char v1[] = { +0x90, 0x90, 0x90, +0x90, 0x90, 0x90, +0x90, 0x90, 0x90, +0x90, 0x90, 0x90, +0x90 }; + +static unsigned char v2[] = { +0xf4,0xff, +0xff, +0xff, +0x0f, +0x4c, +0x00, +0x00, +0x00}; + +/* 9223372036854775808 == -9223372036854775808 */ +static unsigned char v3[] = { +0x80, 0x80, 0x80, +0x80, 0x80, 0x80, +0x80, 0x80, 0x80, +0x41 }; + + +/* This warning with --enable-sanitize is fixed + as of November 11, 2016 when decoding test v4. + dwarf_leb.c: runtime error: negation of -9223372036854775808 cannot be + represented in type 'Dwarf_Signed' (aka 'long long'); + cast to an unsigned type to negate this value to itself. + The actual value here is -4611686018427387904 0xc000000000000000 */ +static unsigned char v4[] = { +0x80, 0x80, 0x80, +0x80, 0x80, 0x80, +0x80, 0x80, 0x40 }; + + +static unsigned +specialtests(void) +{ + unsigned errcnt = 0; + unsigned vlen = 0; + Dwarf_Unsigned decodelen = 0; + Dwarf_Signed decodeval = 0; + Dwarf_Unsigned udecodeval = 0; + int res; + + vlen = sizeof(v1)/sizeof(char); + res = _dwarf_decode_s_leb128_chk( + (Dwarf_Small *)v1, + &decodelen, + &decodeval, + (Dwarf_Byte_Ptr)(&v1[vlen])); + if (res != DW_DLV_ERROR) { + printf("FAIL unsigned decode special v1 \n"); + ++errcnt; + } + res = _dwarf_decode_u_leb128_chk( + (Dwarf_Small *)v1, + &decodelen, + &udecodeval, + (Dwarf_Byte_Ptr)(&v1[vlen])); + if (res != DW_DLV_ERROR) { + printf("FAIL unsigned decode special v1 \n"); + ++errcnt; + } + + vlen = sizeof(v2)/sizeof(char); + res = _dwarf_decode_s_leb128_chk( + (Dwarf_Small *)v2, + &decodelen, + &decodeval, + (Dwarf_Byte_Ptr)(&v2[vlen])); + if (res != DW_DLV_OK) { + printf("FAIL signed decode special v2 \n"); + ++errcnt; + } + /* If you just do (byte & 0x7f) << shift + and byte is (or is promoted to) a signed type + on the following decode you get the wrong value. + Undefined effect in C leads to error. */ + res = _dwarf_decode_u_leb128_chk( + (Dwarf_Small *)v2, + &decodelen, + &udecodeval, + (Dwarf_Byte_Ptr)(&v2[vlen])); + if (res != DW_DLV_OK) { + printf("FAIL unsigned decode special v2 \n"); + ++errcnt; + } + + vlen = sizeof(v3)/sizeof(char); + res = _dwarf_decode_s_leb128_chk( + (Dwarf_Small *)v3, + &decodelen, + &decodeval, + (Dwarf_Byte_Ptr)(&v3[vlen])); + if (res != DW_DLV_OK) { + printf("FAIL signed decode special v3 \n"); + ++errcnt; + } + if ((Dwarf_Unsigned)decodeval != + (Dwarf_Unsigned)0x8000000000000000) { + printf("FAIL signed decode special v3 value check %lld vs %lld \n", + decodeval,(Dwarf_Signed)0x8000000000000000); + ++errcnt; + } + + vlen = sizeof(v4)/sizeof(char); + res = _dwarf_decode_s_leb128_chk( + (Dwarf_Small *)v4, + &decodelen, + &decodeval, + (Dwarf_Byte_Ptr)(&v4[vlen])); + if (res != DW_DLV_OK) { + printf("FAIL signed decode special v4 \n"); + ++errcnt; + } + if (decodeval != -4611686018427387904) { + printf("FAIL signed decode special v4 value check %lld vs %lld \n", + decodeval,-4611686018427387904LL); + printf("FAIL signed decode special v4 value check 0x%llx vs 0x%llx \n", + decodeval,-4611686018427387904LL); + ++errcnt; + } + + return errcnt; + + return errcnt; +} + +int main(void) +{ + unsigned slen = sizeof(stest)/sizeof(Dwarf_Signed); + unsigned ulen = sizeof(utest)/sizeof(Dwarf_Unsigned); + int errs = 0; + + printinteresting(); + errs += signedtest(slen); + + errs += unsignedtest(ulen); + + errs += specialtests(); + + if (errs) { + printf("FAIL. leb encode/decode errors\n"); + return 1; + } + printf("PASS leb tests\n"); + return 0; +} diff --git a/thirdparty/dwarf/dwarf_line.c b/thirdparty/dwarf/dwarf_line.c index 5cc6f968..c061a1ff 100644 --- a/thirdparty/dwarf/dwarf_line.c +++ b/thirdparty/dwarf/dwarf_line.c @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2015 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved. @@ -27,17 +27,20 @@ */ #include "config.h" -#include "dwarf_incl.h" #include #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_line.h" /* Line Register Set initial conditions. */ static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = { /* Dwarf_Addr lr_address */ 0, - /* Dwarf_Word lr_file */ 1, - /* Dwarf_Word lr_line */ 1, - /* Dwarf_Word lr_column */ 0, + /* 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, @@ -52,9 +55,14 @@ static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = { void _dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs, + unsigned lineversion, Dwarf_Bool is_stmt) { *regs = _dwarf_line_table_regs_default_values; + if (lineversion == DW_LINE_VERSION5) { + /* DWARF5 file base is zero. */ + regs->lr_file = 0; + } regs->lr_is_stmt = is_stmt; } @@ -104,7 +112,7 @@ _dwarf_file_name_is_full_path(Dwarf_Small *fname) /* End Windows style */ return 0; } -#include "dwarf_line_table_reader_common.c" +#include "dwarf_line_table_reader_common.h" static void special_cat(char *dst,char *src, @@ -277,11 +285,11 @@ dwarf_srcfiles(Dwarf_Die die, { /* This pointer is used to scan the portion of the .debug_line section for the current cu. */ - Dwarf_Small *line_ptr; + Dwarf_Small *line_ptr = 0; /* Pointer to a DW_AT_stmt_list attribute in case it exists in the die. */ - Dwarf_Attribute stmt_list_attr; + Dwarf_Attribute stmt_list_attr = 0; const char * const_comp_name = 0; /* Pointer to name of compilation directory. */ @@ -329,34 +337,41 @@ dwarf_srcfiles(Dwarf_Die die, } if (dbg->de_debug_line.dss_index == 0) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL); return (DW_DLV_ERROR); } res = _dwarf_load_section(dbg, &dbg->de_debug_line,error); if (res != DW_DLV_OK) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return res; } if (!dbg->de_debug_line.dss_size) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return (DW_DLV_NO_ENTRY); } section_start = dbg->de_debug_line.dss_data; lres = dwarf_whatform(stmt_list_attr,&attrform,error); if (lres != DW_DLV_OK) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 && attrform != DW_FORM_sec_offset && attrform != DW_FORM_GNU_ref_alt) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_WRONG_FORM); return (DW_DLV_ERROR); } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return (DW_DLV_ERROR); } @@ -367,11 +382,13 @@ dwarf_srcfiles(Dwarf_Die die, int resl = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if(resl != DW_DLV_OK) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return resl; } line_ptr += fission_offset; if (line_ptr > dbg->de_debug_line.dss_data + dbg->de_debug_line.dss_size) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR); return DW_DLV_ERROR; } @@ -416,7 +433,6 @@ dwarf_srcfiles(Dwarf_Die die, line_context = 0; return dres; } - line_ptr = line_ptr_out; } /* For DWARF5, use of DW_AT_comp_dir not needed. Line table file names and directories @@ -424,10 +440,18 @@ dwarf_srcfiles(Dwarf_Die die, line_context->lc_compilation_directory = comp_dir; /* We are in dwarf_srcfiles() */ { - Dwarf_File_Entry fe = line_context->lc_file_entries; - Dwarf_File_Entry fe2 = fe; - for (i = 0; i < line_context->lc_file_entry_count; - ++i,fe2 = fe->fi_next ) { + Dwarf_File_Entry fe = 0; + Dwarf_File_Entry fe2 =line_context->lc_file_entries; + Dwarf_Signed baseindex = 0; + Dwarf_Signed file_count = 0; + Dwarf_Signed endindex = 0; + + res = dwarf_srclines_files_indexes(line_context, &baseindex, + &file_count, &endindex, error); + if (res != DW_DLV_OK) { + return res; + } + for (i = baseindex; i < endindex; ++i,fe2 = fe->fi_next ) { int sres = 0; char *name_out = 0; @@ -455,13 +479,19 @@ dwarf_srcfiles(Dwarf_Die die, } } } + if (!head_chain) { + dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); + *srcfiles = NULL; + *srcfilecount = 0; + return DW_DLV_NO_ENTRY; + } /* We are in dwarf_srcfiles() */ if (line_context->lc_file_entry_count == 0) { dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT); *srcfiles = NULL; *srcfilecount = 0; - return (DW_DLV_NO_ENTRY); + return DW_DLV_NO_ENTRY; } ret_files = (char **) @@ -589,10 +619,12 @@ _dwarf_internal_srclines(Dwarf_Die die, } lres = dwarf_global_formref(stmt_list_attr, &line_offset, error); if (lres != DW_DLV_OK) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return lres; } if (line_offset >= dbg->de_debug_line.dss_size) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); return (DW_DLV_ERROR); } @@ -603,6 +635,7 @@ _dwarf_internal_srclines(Dwarf_Die die, int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE, &fission_offset,&fission_size,error); if(resf != DW_DLV_OK) { + dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); return resf; } line_ptr += fission_offset; @@ -771,8 +804,9 @@ _dwarf_internal_srclines(Dwarf_Die die, } } } - if (!is_new_interface && - (*linecount == 0 && (linecount_actuals == NULL || *linecount_actuals == 0))) { + if (!is_new_interface && linecount && + (linecount == 0 ||*linecount == 0) && + (linecount_actuals == 0 || *linecount_actuals == 0)) { /* Here we have no actual lines of any kind. In other words, it looks like a debugfission line table skeleton or a caller not prepared for skeletons or two-level reading.. @@ -1105,7 +1139,8 @@ dwarf_srclines_subprog_data(Dwarf_Line_Context line_context, return DW_DLV_OK; } -/* New October 2015. */ +/* New October 2015. See also + dwarf_srclines_files_indexes() */ int dwarf_srclines_files_count(Dwarf_Line_Context line_context, Dwarf_Signed *count_out, @@ -1130,24 +1165,81 @@ dwarf_srclines_files_data(Dwarf_Line_Context line_context, Dwarf_Unsigned * last_mod_time, Dwarf_Unsigned * file_length, Dwarf_Error * error) +{ + return dwarf_srclines_files_data_b( + line_context,index_in,name,directory_index, + last_mod_time,file_length,0,error); +} + + +/* New March 2018 making iteration through file names. */ +int +dwarf_srclines_files_indexes(Dwarf_Line_Context line_context, + Dwarf_Signed *baseindex, + Dwarf_Signed *file_count, + Dwarf_Signed *endindex, + Dwarf_Error * error) +{ + if(line_context->lc_magic != DW_CONTEXT_MAGIC) { + _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); + return DW_DLV_ERROR; + } + *baseindex = line_context->lc_file_entry_baseindex; + *file_count = line_context->lc_file_entry_count; + *endindex = line_context->lc_file_entry_endindex; + return DW_DLV_OK; +} + +/* New March 2018 adding DWARF5 data. */ +int +dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, + Dwarf_Signed index_in, + const char ** name, + Dwarf_Unsigned * directory_index, + Dwarf_Unsigned * last_mod_time, + Dwarf_Unsigned * file_length, + Dwarf_Form_Data16 ** data16ptr, + Dwarf_Error * error) { Dwarf_File_Entry fi = 0; - Dwarf_Unsigned i =0; + Dwarf_Signed i =0; + Dwarf_Signed baseindex = 0; + Dwarf_Signed file_count = 0; + Dwarf_Signed endindex = 0; /* Negative values not sensible. Leaving traditional signed interfaces. */ - Dwarf_Unsigned index = (Dwarf_Unsigned)index_in; + Dwarf_Signed index = index_in; + int res = 0; + + if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); return (DW_DLV_ERROR); } - if (index < 1 || index > line_context->lc_file_entry_count) { - _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); - return (DW_DLV_ERROR); + + /* Special accomodation of the special gnu experimental + version number (a high number) so we cannot just + say '5 or greater'. This is awkward, but at least + if there is a version 6 or later it still allows + the experimental table. */ + res = dwarf_srclines_files_indexes(line_context, &baseindex, + &file_count, &endindex, error); + if (res != DW_DLV_OK) { + return res; } fi = line_context->lc_file_entries; - for ( i = 1; i < index; i++) { + if (index < baseindex || index >= endindex) { + _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG); + return DW_DLV_ERROR; + } + for ( i = baseindex;i < index; i++) { fi = fi->fi_next; + if(!fi) { + _dwarf_error(NULL, error, DW_DLE_LINE_HEADER_CORRUPT); + return DW_DLV_ERROR; + } } + if(name) { *name = (const char *)fi->fi_file_name; } @@ -1160,10 +1252,19 @@ dwarf_srclines_files_data(Dwarf_Line_Context line_context, if (file_length) { *file_length = fi->fi_file_length; } + if (data16ptr) { + if (fi->fi_md5_present) { + *data16ptr = &fi->fi_md5_value; + } else { + *data16ptr = 0; + } + } return DW_DLV_OK; } + + /* New October 2015. */ int dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context, @@ -1188,7 +1289,7 @@ dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context, /* It never made sense that the srclines used a signed count. But that cannot be fixed in interfaces for compatibility. So we adjust here. */ - Dwarf_Word index = index_in; + Dwarf_Unsigned index = index_in; if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH); @@ -1286,8 +1387,10 @@ dwarf_lineno(Dwarf_Line line, meaningless (see dwarf_lineendsequence(), just above). The file number returned is an index into the file table produced by dwarf_srcfiles(), but care is required: the - li_file begins with 1 for real files, so that the li_file returned here + li_file begins with 1 for DWARF2,3,4 + files, so that the li_file returned here is 1 greater than its index into the dwarf_srcfiles() output array. + And entries from DW_LNE_define_file don't appear in the dwarf_srcfiles() output so file indexes from here may exceed the size of the dwarf_srcfiles() output array size. @@ -1298,12 +1401,13 @@ dwarf_line_srcfileno(Dwarf_Line line, { if (line == NULL || ret_fileno == 0) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } /* li_file must be <= line->li_context->lc_file_entry_count else it is trash. li_file 0 means not attributable to any source file - per dwarf2/3 spec. */ + per dwarf2/3 spec. + For DWARF5, li_file < lc_file_entry_count */ *ret_fileno = (line->li_addr_line.li_l_data.li_file); return DW_DLV_OK; } @@ -1391,32 +1495,35 @@ dwarf_lineoff_b(Dwarf_Line line, static int dwarf_filename(Dwarf_Line_Context context, - Dwarf_Sword fileno_in, + Dwarf_Signed fileno_in, char **ret_filename, Dwarf_Error *error) { - Dwarf_Unsigned i = 0; + Dwarf_Signed i = 0; Dwarf_File_Entry file_entry = 0; Dwarf_Debug dbg = context->lc_dbg; int res = 0; + Dwarf_Signed baseindex = 0; + Dwarf_Signed file_count = 0; + Dwarf_Signed endindex = 0; /* Negative values not sensible. Leaving traditional - signed interfaces. */ - Dwarf_Word fileno = (Dwarf_Word)fileno_in; + signed interfaces in place. */ + Dwarf_Signed fileno = fileno_in; - if (fileno > context->lc_file_entry_count) { - _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD); - return (DW_DLV_ERROR); + res = dwarf_srclines_files_indexes(context, &baseindex, + &file_count, &endindex, error); + if (res != DW_DLV_OK) { + return res; } - - if (fileno == 0) { - /* No file name known: see dwarf2/3 spec. */ + if (fileno < baseindex || fileno >= endindex) { _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); return (DW_DLV_ERROR); } + file_entry = context->lc_file_entries; /* ASSERT: li_file > 0, dwarf correctness issue, see line table definition of dwarf2/3 spec. */ - for (i = 1; i < fileno ; i++) { + for (i = baseindex; i < fileno ; i++) { file_entry = file_entry->fi_next; } @@ -1430,17 +1537,14 @@ dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error) { if (line == NULL) { _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } - if (line->li_context == NULL) { _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } - return dwarf_filename(line->li_context, line->li_addr_line.li_l_data.li_file, ret_linesrc, error); - } /* Every line table entry potentially has the basic-block-start @@ -1590,6 +1694,9 @@ delete_line_context_itself(Dwarf_Line_Context context) fe = fenext; } context->lc_file_entries = 0; + context->lc_file_entry_count = 0; + context->lc_file_entry_baseindex = 0; + context->lc_file_entry_endindex = 0; if (context->lc_subprogs) { free(context->lc_subprogs); context->lc_subprogs = 0; @@ -1812,7 +1919,8 @@ _dwarf_decode_line_string_form(Dwarf_Debug dbg, *line_ptr += offset_size; strptr = secstart + offset; res = _dwarf_check_string_valid(dbg, - secstart,strptr,secend,error); + secstart,strptr,secend, + DW_DLE_LINE_STRP_OFFSET_BAD,error); if (res != DW_DLV_OK) { return res; } @@ -1824,7 +1932,7 @@ _dwarf_decode_line_string_form(Dwarf_Debug dbg, Dwarf_Small *strptr = *line_ptr; res = _dwarf_check_string_valid(dbg, - strptr ,strptr,secend,error); + strptr ,strptr,secend,DW_DLE_LINE_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } @@ -1898,6 +2006,18 @@ _dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe) } context->lc_last_entry = fe; context->lc_file_entry_count++; + /* Here we attempt to write code to make it easy to interate + though source file names without having to code specially + for DWARF2,3,4 vs DWARF5 */ + if (context->lc_version_number >= DW_LINE_VERSION5 && + context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) { + context->lc_file_entry_baseindex = 0; + context->lc_file_entry_endindex = context->lc_file_entry_count; + } else { + /* DWARF2,3,4 and the EXPERIMENTAL_LINE_TABLES_VERSION. */ + context->lc_file_entry_baseindex = 1; + context->lc_file_entry_endindex = context->lc_file_entry_count+1; + } return DW_DLV_OK; } @@ -1941,9 +2061,11 @@ _dwarf_line_context_destructor(void *m) t->fi_next = 0; free(t); } - line_context->lc_file_entries = 0; - line_context->lc_last_entry = 0; + line_context->lc_file_entries = 0; + line_context->lc_last_entry = 0; line_context->lc_file_entry_count = 0; + line_context->lc_file_entry_baseindex = 0; + line_context->lc_file_entry_endindex = 0; } if (line_context->lc_subprogs) { diff --git a/thirdparty/dwarf/dwarf_line.h b/thirdparty/dwarf/dwarf_line.h index d87594d8..ed7446e2 100644 --- a/thirdparty/dwarf/dwarf_line.h +++ b/thirdparty/dwarf/dwarf_line.h @@ -59,13 +59,16 @@ struct Dwarf_File_Entry_s { /* Index into the list of directories of the directory in which this file exits. */ - Dwarf_Word fi_dir_index; + Dwarf_Unsigned fi_dir_index; /* Time of last modification of the file. */ Dwarf_Unsigned fi_time_last_mod; /* Length in bytes of the file. */ Dwarf_Unsigned fi_file_length; + + Dwarf_Form_Data16 fi_md5_value; + char fi_md5_present; }; /* Part of two-level line tables support. */ @@ -161,7 +164,10 @@ struct Dwarf_Line_Context_s { Dwarf_File_Entry lc_last_entry; /* Count of number of source files for this set of Dwarf_Line structures. */ - Dwarf_Word lc_file_entry_count; + Dwarf_Unsigned lc_file_entry_count; + /* Values Easing the process of indexing through lc_file_entries. */ + Dwarf_Unsigned lc_file_entry_baseindex; + Dwarf_Unsigned lc_file_entry_endindex; /* Points to the portion of .debug_line section that @@ -170,7 +176,7 @@ struct Dwarf_Line_Context_s { An array of pointers to strings. */ Dwarf_Small **lc_include_directories; /* Count of the number of included directories. */ - Dwarf_Word lc_include_directories_count; + Dwarf_Unsigned lc_include_directories_count; /* Points to an array of subprogram entries. @@ -180,10 +186,10 @@ struct Dwarf_Line_Context_s { /* Count of the number of subprogram entries With Two level line tables this may be non-zero. */ - Dwarf_Word lc_subprogs_count; + Dwarf_Unsigned lc_subprogs_count; /* Count of the number of lines for this cu. */ - Dwarf_Word lc_line_count; + Dwarf_Unsigned lc_line_count; /* Points to name of compilation directory. That string is in a .debug section so @@ -217,9 +223,9 @@ struct Dwarf_Line_Context_s { but preceded by lr_. */ struct Dwarf_Line_Registers_s { Dwarf_Addr lr_address; /* DWARF2 */ - Dwarf_Word lr_file ; /* DWARF2 */ - Dwarf_Word lr_line ; /* DWARF2 */ - Dwarf_Word lr_column ; /* DWARF2 */ + Dwarf_Unsigned lr_file ; /* DWARF2 */ + Dwarf_Unsigned lr_line ; /* DWARF2 */ + Dwarf_Unsigned lr_column ; /* DWARF2 */ Dwarf_Bool lr_is_stmt; /* DWARF2 */ Dwarf_Bool lr_basic_block; /* DWARF2 */ Dwarf_Bool lr_end_sequence; /* DWARF2 */ @@ -232,7 +238,9 @@ struct Dwarf_Line_Registers_s { Dwarf_Unsigned lr_subprogram; /* EXPERIMENTAL */ }; typedef struct Dwarf_Line_Registers_s *Dwarf_Line_Registers; -void _dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs, +void _dwarf_set_line_table_regs_default_values( + Dwarf_Line_Registers regs, + unsigned lineversion, Dwarf_Bool is_stmt); @@ -261,13 +269,13 @@ struct Dwarf_Line_s { li_file is a number 1-N, indexing into a conceptual source file table as described in dwarf2/3 spec line table doc. (see Dwarf_File_Entry lc_file_entries; and - Dwarf_Word lc_file_entry_count;) */ - Dwarf_Word li_file; + Dwarf_Unsigned lc_file_entry_count;) */ + Dwarf_Unsigned li_file; /* In single-level table is line number in source file. 1-N In logicals table is not used. In actuals table is index into logicals table. 1-N*/ - Dwarf_Word li_line; + Dwarf_Unsigned li_line; Dwarf_Half li_column; /* source file column number 1-N */ Dwarf_Small li_isa; /* New as of DWARF4. */ @@ -390,23 +398,6 @@ int _dwarf_internal_srclines(Dwarf_Die die, #define MAX_LINE_OP_CODE 255 - -# if 0 -/* The following structs (Line_Table_File_Entry_s,Dwarf_Line_Context_s) - and functions allow refactoring common code into a single - reader routine. -*/ -Not used once Prefix struct folded into line context struct. -/* There can be zero of more of these needed for 1 line prologue. */ -struct Line_Table_File_Entry_s { - Dwarf_Small *lte_filename; - Dwarf_Unsigned lte_directory_index; - Dwarf_Unsigned lte_last_modification_time; - Dwarf_Unsigned lte_length_of_file; -}; -#endif - - /* Operand counts per standard operand. The initial zero is for DW_LNS_copy. This is an economical way to verify we understand the table diff --git a/thirdparty/dwarf/dwarf_line2.c b/thirdparty/dwarf/dwarf_line2.c deleted file mode 100644 index 9dd86abe..00000000 --- a/thirdparty/dwarf/dwarf_line2.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - - Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2008-2011 David Anderson, Inc. All rights reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. - -*/ - -/* This source file used for SGI-IRIX rqs processing. - Unused otherwise. -*/ - -#include "config.h" -#include "dwarf_incl.h" -#include -#include "dwarf_line.h" - -#ifdef __sgi /* SGI IRIX ONLY */ -/* Return DW_DLV_OK or, if error, - DW_DLV_ERROR. - - Thru pointers, return 2 arrays and a count - for rqs (IRIX run-time linker). - ONLY meant for SGI IRIX */ -int -_dwarf_line_address_offsets(Dwarf_Debug dbg, - Dwarf_Die die, - Dwarf_Addr ** addrs, - Dwarf_Off ** offs, - Dwarf_Unsigned * returncount, - Dwarf_Error * err) -{ - Dwarf_Addr *laddrs; - Dwarf_Off *loffsets; - Dwarf_Signed lcount; - Dwarf_Signed i; - int res; - Dwarf_Line *linebuf; - - res = _dwarf_internal_srclines(die, /* version= */ NULL, - &linebuf, &lcount, - /* actuals= */ NULL, /* actualscount= */ NULL, - /* addrlist= */ true, - /* linelist= */ false, - err); - if (res != DW_DLV_OK) { - return res; - } - laddrs = (Dwarf_Addr *) - _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); - if (laddrs == NULL) { - dwarf_srclines_dealloc(dbg, linebuf, lcount); - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - loffsets = (Dwarf_Off *) - _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); - if (loffsets == NULL) { - dwarf_srclines_dealloc(dbg, linebuf, lcount); - /* We already allocated what laddrs points at, so we'e better - deallocate that space since we are not going to return the - pointer to the caller. */ - dwarf_dealloc(dbg, laddrs, DW_DLA_ADDR); - _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); - } - - for (i = 0; i < lcount; i++) { - laddrs[i] = linebuf[i]->li_address; - loffsets[i] = linebuf[i]->li_addr_line.li_offset; - } - dwarf_srclines_dealloc(dbg, linebuf, lcount); - *returncount = lcount; - *offs = loffsets; - *addrs = laddrs; - return DW_DLV_OK; -} -#endif /* __sgi */ - diff --git a/thirdparty/dwarf/dwarf_line_table_reader_common.c b/thirdparty/dwarf/dwarf_line_table_reader_common.h similarity index 86% rename from thirdparty/dwarf/dwarf_line_table_reader_common.c rename to thirdparty/dwarf/dwarf_line_table_reader_common.h index 6c9869ee..483a6332 100644 --- a/thirdparty/dwarf/dwarf_line_table_reader_common.c +++ b/thirdparty/dwarf/dwarf_line_table_reader_common.h @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2013 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved. @@ -100,6 +100,26 @@ operandmismatch(unsigned char * table,unsigned table_length, return FALSE; } +/* Encapsulates DECODE_LEB128_UWORD_CK + so the caller can free resources + in case of problems. */ +static int +read_uword_de(Dwarf_Small **lp, + Dwarf_Unsigned *out_p, + Dwarf_Debug dbg, + Dwarf_Error *err, + Dwarf_Small *lpend) +{ + Dwarf_Small *inptr = *lp; + Dwarf_Unsigned out = 0; + DECODE_LEB128_UWORD_CK(inptr, + out, + dbg,err,lpend); + *lp = inptr; + *out_p = out; + return DW_DLV_OK; +} + /* Common line table header reading code. Returns DW_DLV_OK, DW_DLV_ERROR. @@ -179,10 +199,10 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, line_context->lc_total_length = total_length; READ_UNALIGNED_CK(dbg, version, Dwarf_Half, - line_ptr, sizeof(Dwarf_Half), + line_ptr, DWARF_HALF_SIZE, err,line_ptr_end); line_context->lc_version_number = version; - line_ptr += sizeof(Dwarf_Half); + line_ptr += DWARF_HALF_SIZE; if (version != DW_LINE_VERSION2 && version != DW_LINE_VERSION3 && version != DW_LINE_VERSION4 && @@ -192,8 +212,16 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, return (DW_DLV_ERROR); } if (version == DW_LINE_VERSION5) { + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } line_context->lc_address_size = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } line_context->lc_segment_selector_size = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); @@ -209,12 +237,10 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, line_context->lc_prologue_length = prologue_length; line_ptr += local_length_size; line_context->lc_line_prologue_start = line_ptr; - if(line_ptr >= line_ptr_end) { - _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); - return DW_DLV_ERROR; + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); } - - line_context->lc_minimum_instruction_length = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); @@ -222,20 +248,31 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, if (version == DW_LINE_VERSION4 || version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } line_context->lc_maximum_ops_per_instruction = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); } + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } line_context->lc_default_is_stmt = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLV_ERROR); + } line_context->lc_line_base = *(signed char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Sbyte); if(line_ptr >= line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD); return DW_DLV_ERROR; } - line_context->lc_line_range = *(unsigned char *) line_ptr; if (!line_context->lc_line_range) { _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_RANGE_ZERO); @@ -380,7 +417,8 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, line_context->lc_include_directories[directories_count] = line_ptr; res = _dwarf_check_string_valid(dbg, - data_start,line_ptr,line_ptr_end,err); + data_start,line_ptr,line_ptr_end, + DW_DLE_LINE_STRING_BAD,err); if (res != DW_DLV_OK) { return res; } @@ -396,6 +434,8 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { /* Empty old style dir entry list. */ line_ptr++; + } else if (version == 5) { + /* handled below */ } else { /* No old style directory entries. */ } @@ -429,13 +469,14 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, currfile->fi_file_name = line_ptr; resl = _dwarf_check_string_valid(dbg, - data_start,line_ptr,line_ptr_end,err); + data_start,line_ptr,line_ptr_end, + DW_DLE_LINE_STRING_BAD,err); if (resl != DW_DLV_OK) { return resl; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; DECODE_LEB128_UWORD_CK(line_ptr, utmp,dbg,err,line_ptr_end); - dir_index = (Dwarf_Word) utmp; + dir_index = (Dwarf_Unsigned) utmp; if (dir_index > line_context->lc_include_directories_count) { _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD); return (DW_DLV_ERROR); @@ -458,11 +499,17 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, /* Skip trailing nul byte */ ++line_ptr; } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) { + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); + return (DW_DLV_ERROR); + } if (*line_ptr != 0) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } line_ptr++; + } else if (version == 5) { + /* handled below */ } else { /* No old style filenames entries. */ } @@ -478,6 +525,10 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, unsigned i = 0; for ( ; i < 5; ++i) { + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); + return (DW_DLV_ERROR); + } if (*line_ptr != expbytes[i]) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); @@ -500,13 +551,19 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, if (version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { - /* DWARF 5. */ + /* DWARF 5. directory names.*/ Dwarf_Unsigned directory_format_count = 0; Dwarf_Unsigned *directory_entry_types = 0; Dwarf_Unsigned *directory_entry_forms = 0; Dwarf_Unsigned directories_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; + int dres = 0; + + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); + return (DW_DLV_ERROR); + } directory_format_count = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); if (directory_format_count > 0) { @@ -524,14 +581,37 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, return (DW_DLV_ERROR); } for (i = 0; i < directory_format_count; i++) { - DECODE_LEB128_UWORD_CK(line_ptr, directory_entry_types[i], + dres=read_uword_de(&line_ptr,directory_entry_types+i, dbg,err,line_ptr_end); - DECODE_LEB128_UWORD_CK(line_ptr, directory_entry_forms[i], + if (dres != DW_DLV_OK) { + free(directory_entry_types); + free(directory_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, + directory_entry_types[i], + dbg,err,line_ptr_end); */ + dres=read_uword_de(&line_ptr,directory_entry_forms+i, dbg,err,line_ptr_end); + if (dres != DW_DLV_OK) { + free(directory_entry_types); + free(directory_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, + directory_entry_forms[i], + dbg,err,line_ptr_end); */ } } - DECODE_LEB128_UWORD_CK(line_ptr, directories_count, + dres = read_uword_de(&line_ptr,&directories_count, dbg,err,line_ptr_end); + if (dres != DW_DLV_OK) { + free(directory_entry_types); + free(directory_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, directories_count, + dbg,err,line_ptr_end); */ line_context->lc_include_directories = malloc(sizeof(Dwarf_Small *) * directories_count); if (line_context->lc_include_directories == NULL) { @@ -542,7 +622,10 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, } if (directory_format_count ==0 && directories_count > 0) { - _dwarf_error(dbg, err, DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH); + free(directory_entry_types); + free(directory_entry_forms); + _dwarf_error(dbg, err, + DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH); return (DW_DLV_ERROR); } memset(line_context->lc_include_directories, 0, @@ -592,21 +675,26 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, if (version == DW_LINE_VERSION5 || version == EXPERIMENTAL_LINE_TABLES_VERSION) { - /* DWARF 5. */ + /* DWARF 5. file names.*/ Dwarf_Unsigned filename_format_count = 0; Dwarf_Unsigned *filename_entry_types = 0; Dwarf_Unsigned *filename_entry_forms = 0; Dwarf_Unsigned files_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; + int dres = 0; + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); + return (DW_DLV_ERROR); + } filename_format_count = *(unsigned char *) line_ptr; line_ptr = line_ptr + sizeof(Dwarf_Small); filename_entry_types = malloc(sizeof(Dwarf_Unsigned) * filename_format_count); if (filename_entry_types == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } filename_entry_forms = malloc(sizeof(Dwarf_Unsigned) * filename_format_count); @@ -616,13 +704,34 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, return (DW_DLV_ERROR); } for (i = 0; i < filename_format_count; i++) { - DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_types[i], + dres=read_uword_de(&line_ptr,filename_entry_types+i, dbg,err,line_ptr_end); - DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_forms[i], + if (dres != DW_DLV_OK) { + free(filename_entry_types); + free(filename_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_types[i] + dbg,err,line_ptr_end); */ + dres=read_uword_de(&line_ptr,filename_entry_forms+i, dbg,err,line_ptr_end); + if (dres != DW_DLV_OK) { + free(filename_entry_types); + free(filename_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_forms[i], + dbg,err,line_ptr_end); */ } - DECODE_LEB128_UWORD_CK(line_ptr, files_count, + dres=read_uword_de(&line_ptr,&files_count, dbg,err,line_ptr_end); + if (dres != DW_DLV_OK) { + free(filename_entry_types); + free(filename_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, files_count, + dbg,err,line_ptr_end); */ for (i = 0; i < files_count; i++) { Dwarf_File_Entry curline = 0; @@ -630,6 +739,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, malloc(sizeof(struct Dwarf_File_Entry_s)); if (curline == NULL) { free(filename_entry_types); + free(filename_entry_forms); _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } @@ -692,11 +802,33 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, return res; } break; - case DW_LNCT_MD5: /* Not yet implemented */ + case DW_LNCT_MD5: { /* form DW_FORM_data16 */ + if (filename_entry_forms[j] != DW_FORM_data16) { + free(filename_entry_types); + free(filename_entry_forms); + _dwarf_error(dbg, err,DW_DLE_LNCT_MD5_WRONG_FORM); + return DW_DLV_ERROR; + } + res = _dwarf_extract_data16(dbg, + line_ptr, + line_ptr, + line_ptr_end, + &curline->fi_md5_value, + err); + if (res != DW_DLV_OK) { + free(filename_entry_types); + free(filename_entry_forms); + return res; + } + curline->fi_md5_present = TRUE; + line_ptr = line_ptr + sizeof(curline->fi_md5_value); + } + break; + default: free(filename_entry_types); free(filename_entry_forms); - _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); + _dwarf_error(dbg, err,DW_DLE_LINE_NUMBER_HEADER_ERROR); return (DW_DLV_ERROR); } if (line_ptr > line_ptr_end) { @@ -718,6 +850,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, Dwarf_Unsigned subprogs_count = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned j = 0; + int dres = 0; if (line_ptr > line_ptr_end) { _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR); @@ -740,13 +873,35 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, } for (i = 0; i < subprog_format_count; i++) { - DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_types[i], + + dres=read_uword_de(&line_ptr,subprog_entry_types+i, dbg,err,line_ptr_end); - DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_forms[i], + if (dres != DW_DLV_OK) { + free(subprog_entry_types); + free(subprog_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_types[i], + dbg,err,line_ptr_end); */ + dres=read_uword_de(&line_ptr,subprog_entry_forms+i, dbg,err,line_ptr_end); + if (dres != DW_DLV_OK) { + free(subprog_entry_types); + free(subprog_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_forms[i], + dbg,err,line_ptr_end); */ } - DECODE_LEB128_UWORD_CK(line_ptr, subprogs_count, + dres=read_uword_de(&line_ptr,&subprogs_count, dbg,err,line_ptr_end); + if (dres != DW_DLV_OK) { + free(subprog_entry_types); + free(subprog_entry_forms); + return dres; + } + /* DECODE_LEB128_UWORD_CK(line_ptr, subprogs_count, + dbg,err,line_ptr_end); */ line_context->lc_subprogs = malloc(sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count); if (line_context->lc_subprogs == NULL) { @@ -762,7 +917,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, line_context->lc_subprogs + i; for (j = 0; j < subprog_format_count; j++) { switch (subprog_entry_types[j]) { - case DW_LNCT_subprogram_name: + case DW_LNCT_GNU_subprogram_name: res = _dwarf_decode_line_string_form(dbg, subprog_entry_forms[j], local_length_size, @@ -776,7 +931,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, return res; } break; - case DW_LNCT_decl_file: + case DW_LNCT_GNU_decl_file: res = _dwarf_decode_line_udata_form(dbg, subprog_entry_forms[j], &line_ptr, @@ -789,7 +944,7 @@ _dwarf_read_line_table_header(Dwarf_Debug dbg, return res; } break; - case DW_LNCT_decl_line: + case DW_LNCT_GNU_decl_line: res = _dwarf_decode_line_udata_form(dbg, subprog_entry_forms[j], &line_ptr, @@ -887,7 +1042,7 @@ read_line_table_program(Dwarf_Debug dbg, Dwarf_Error *error, UNUSEDARG int *err_count_out) { - Dwarf_Word i = 0; + Dwarf_Unsigned i = 0; Dwarf_File_Entry cur_file_entry = 0; Dwarf_Line *logicals = line_context->lc_linebuf_logicals; Dwarf_Unsigned logicals_count = line_context->lc_linecount_logicals; @@ -901,18 +1056,18 @@ read_line_table_program(Dwarf_Debug dbg, /* These variables are used to decode leb128 numbers. Leb128_num holds the decoded number, and leb128_length is its length in bytes. */ - Dwarf_Word leb128_num = 0; - Dwarf_Sword advance_line = 0; + Dwarf_Unsigned leb128_num = 0; + Dwarf_Signed advance_line = 0; /* This is the operand of the latest fixed_advance_pc extended opcode. */ Dwarf_Half fixed_advance_pc = 0; /* Counts the number of lines in the line matrix. */ - Dwarf_Word line_count = 0; + Dwarf_Unsigned line_count = 0; /* This is the length of an extended opcode instr. */ - Dwarf_Word instr_length = 0; + Dwarf_Unsigned instr_length = 0; /* Used to chain together pointers to line table entries that are @@ -931,6 +1086,7 @@ read_line_table_program(Dwarf_Debug dbg, /* Initialize the one state machine variable that depends on the prefix. */ _dwarf_set_line_table_regs_default_values(®s, + line_context->lc_version_number, line_context->lc_default_is_stmt); /* Start of statement program. */ @@ -1010,6 +1166,13 @@ read_line_table_program(Dwarf_Debug dbg, regs.lr_line = regs.lr_line + line_context->lc_line_base + opcode % line_context->lc_line_range; + if ((Dwarf_Signed)regs.lr_line < 0) { + /* Something is badly wrong */ + regs.lr_line = 0; + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_LINENO_ERROR); + return DW_DLV_ERROR; + } #ifdef PRINTING_DETAILS sprintf(special, "Specialop %3u", origop); print_line_detail(dbg,special, @@ -1031,9 +1194,9 @@ read_line_table_program(Dwarf_Debug dbg, curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = - (Dwarf_Sword) regs.lr_file; + (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = - (Dwarf_Sword) regs.lr_line; + (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = @@ -1096,9 +1259,9 @@ read_line_table_program(Dwarf_Debug dbg, curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = - (Dwarf_Sword) regs.lr_file; + (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = - (Dwarf_Sword) regs.lr_line; + (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = @@ -1150,10 +1313,10 @@ read_line_table_program(Dwarf_Debug dbg, "DW_LNS_advance_pc val %" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DUx "\n", - (Dwarf_Signed) (Dwarf_Word) utmp2, - (Dwarf_Unsigned) (Dwarf_Word) utmp2); + (Dwarf_Signed) utmp2, + (Dwarf_Unsigned)utmp2); #endif /* PRINTING_DETAILS */ - leb128_num = (Dwarf_Word) utmp2; + leb128_num = utmp2; regs.lr_address = regs.lr_address + line_context->lc_minimum_instruction_length * leb128_num; @@ -1164,7 +1327,7 @@ read_line_table_program(Dwarf_Debug dbg, DECODE_LEB128_SWORD_CK(line_ptr, stmp, dbg,error,line_ptr_end); - advance_line = (Dwarf_Sword) stmp; + advance_line = (Dwarf_Signed) stmp; #ifdef PRINTING_DETAILS dwarf_printf(dbg, @@ -1174,6 +1337,13 @@ read_line_table_program(Dwarf_Debug dbg, (Dwarf_Signed) advance_line); #endif /* PRINTING_DETAILS */ regs.lr_line = regs.lr_line + advance_line; + if ((Dwarf_Signed)regs.lr_line < 0) { + /* Something is badly wrong */ + regs.lr_line = 0; + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_LINENO_ERROR); + return DW_DLV_ERROR; + } } break; case DW_LNS_set_file:{ @@ -1181,7 +1351,7 @@ read_line_table_program(Dwarf_Debug dbg, DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); - regs.lr_file = (Dwarf_Word) utmp2; + regs.lr_file = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_file %ld\n", (long) regs.lr_file); @@ -1193,7 +1363,7 @@ read_line_table_program(Dwarf_Debug dbg, DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); - regs.lr_column = (Dwarf_Word) utmp2; + regs.lr_column = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, "DW_LNS_set_column val %" DW_PR_DSd " 0x%" @@ -1248,8 +1418,13 @@ read_line_table_program(Dwarf_Debug dbg, break; case DW_LNS_fixed_advance_pc:{ READ_UNALIGNED_CK(dbg, fixed_advance_pc, Dwarf_Half, - line_ptr, sizeof(Dwarf_Half),error,line_ptr_end); - line_ptr += sizeof(Dwarf_Half); + line_ptr, DWARF_HALF_SIZE,error,line_ptr_end); + line_ptr += DWARF_HALF_SIZE; + if (line_ptr > line_ptr_end) { + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_BAD); + return DW_DLV_ERROR; + } regs.lr_address = regs.lr_address + fixed_advance_pc; regs.lr_op_index = 0; #ifdef PRINTING_DETAILS @@ -1317,8 +1492,15 @@ read_line_table_program(Dwarf_Debug dbg, DECODE_LEB128_SWORD_CK(line_ptr, stmp, dbg,error,line_ptr_end); - advance_line = (Dwarf_Sword) stmp; + advance_line = (Dwarf_Signed) stmp; regs.lr_line = regs.lr_line + advance_line; + if ((Dwarf_Signed)regs.lr_line < 0) { + /* Something is badly wrong */ + regs.lr_line = 0; + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_LINENO_ERROR); + return DW_DLV_ERROR; + } if (regs.lr_line >= 1 && regs.lr_line - 1 < logicals_count) { regs.lr_address = @@ -1347,7 +1529,7 @@ read_line_table_program(Dwarf_Debug dbg, regs.lr_call_context = 0; DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); - regs.lr_subprogram = (Dwarf_Word) utmp2; + regs.lr_subprogram = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg,"DW_LNS_set_subprogram " "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx "\n", @@ -1426,12 +1608,22 @@ read_line_table_program(Dwarf_Debug dbg, DECODE_LEB128_UWORD_CK(line_ptr, utmp3, dbg,error,line_ptr_end); - instr_length = (Dwarf_Word) utmp3; + instr_length = utmp3; /* Dwarf_Small is a ubyte and the extended opcode is a ubyte, though not stated as clearly in the 2.0.0 spec as one might hope. */ + if (line_ptr >= line_ptr_end) { + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_BAD); + return DW_DLV_ERROR; + } ext_opcode = *(Dwarf_Small *) line_ptr; line_ptr++; + if (line_ptr > line_ptr_end) { + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_BAD); + return DW_DLV_ERROR; + } switch (ext_opcode) { case DW_LNE_end_sequence:{ @@ -1452,9 +1644,9 @@ read_line_table_program(Dwarf_Debug dbg, #endif /* PRINTING_DETAILS */ curr_line->li_address = regs.lr_address; curr_line->li_addr_line.li_l_data.li_file = - (Dwarf_Sword) regs.lr_file; + (Dwarf_Signed) regs.lr_file; curr_line->li_addr_line.li_l_data.li_line = - (Dwarf_Sword) regs.lr_line; + (Dwarf_Signed) regs.lr_line; curr_line->li_addr_line.li_l_data.li_column = (Dwarf_Half) regs.lr_column; curr_line->li_addr_line.li_l_data.li_is_stmt = @@ -1488,6 +1680,7 @@ read_line_table_program(Dwarf_Debug dbg, _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain); } _dwarf_set_line_table_regs_default_values(®s, + line_context->lc_version_number, line_context->lc_default_is_stmt); } break; @@ -1536,6 +1729,11 @@ read_line_table_program(Dwarf_Debug dbg, } regs.lr_op_index = 0; line_ptr += address_size; + if (line_ptr > line_ptr_end) { + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_BAD); + return DW_DLV_ERROR; + } } break; @@ -1553,16 +1751,16 @@ read_line_table_program(Dwarf_Debug dbg, _dwarf_add_to_files_list(line_context,cur_file_entry); cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr; res = _dwarf_check_string_valid(dbg, - line_ptr,line_ptr,line_ptr_end,error); + line_ptr,line_ptr,line_ptr_end, + DW_DLE_DEFINE_FILE_STRING_BAD,error); if (res != DW_DLV_OK) { _dwarf_free_chain_entries(dbg,head_chain,line_count); return res; } line_ptr = line_ptr + strlen((char *) line_ptr) + 1; - DECODE_LEB128_UWORD_CK(line_ptr,value, dbg,error,line_ptr_end); - cur_file_entry->fi_dir_index = (Dwarf_Sword)value; + cur_file_entry->fi_dir_index = (Dwarf_Signed)value; DECODE_LEB128_UWORD_CK(line_ptr,value, dbg,error,line_ptr_end); cur_file_entry->fi_time_last_mod = value; @@ -1595,7 +1793,7 @@ read_line_table_program(Dwarf_Debug dbg, DECODE_LEB128_UWORD_CK(line_ptr, utmp2, dbg,error,line_ptr_end); - regs.lr_discriminator = (Dwarf_Word) utmp2; + regs.lr_discriminator = utmp2; #ifdef PRINTING_DETAILS dwarf_printf(dbg, @@ -1612,7 +1810,7 @@ read_line_table_program(Dwarf_Debug dbg, if (instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) { _dwarf_free_chain_entries(dbg,head_chain,line_count); _dwarf_error(dbg, error, - DW_DLE_LINE_EXT_OPCODE_BAD); + DW_DLE_LINE_TABLE_BAD); return (DW_DLV_ERROR); } @@ -1628,11 +1826,20 @@ read_line_table_program(Dwarf_Debug dbg, dwarf_printf(dbg, "%02x",(unsigned char)(*(line_ptr))); line_ptr++; + if (line_ptr > line_ptr_end) { + _dwarf_error(dbg, error, + DW_DLE_LINE_TABLE_BAD); + return (DW_DLV_ERROR); + } remaining_bytes--; } } #else /* ! PRINTING_DETAILS */ line_ptr += remaining_bytes; + if (line_ptr > line_ptr_end) { + _dwarf_error(dbg, error, DW_DLE_LINE_TABLE_BAD); + return (DW_DLV_ERROR); + } #endif /* PRINTING_DETAILS */ dwarf_printf(dbg,"\n"); } diff --git a/thirdparty/dwarf/dwarf_loc.c b/thirdparty/dwarf/dwarf_loc.c index bb970425..3b8525fc 100644 --- a/thirdparty/dwarf/dwarf_loc.c +++ b/thirdparty/dwarf/dwarf_loc.c @@ -1,34 +1,46 @@ /* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2015 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ #include "config.h" +#include /* for debugging only. */ +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ #include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_loc.h" -#include /* for debugging only. */ #define TRUE 1 #define FALSE 0 @@ -126,14 +138,18 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, Dwarf_Unsigned operand2 = 0; Dwarf_Unsigned operand3 = 0; Dwarf_Small atom = 0; - Dwarf_Word leb128_length = 0; + Dwarf_Unsigned leb128_length = 0; + if (offset > loc_block->bl_len) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } loc_len = loc_block->bl_len; - loc_ptr = (Dwarf_Small*)loc_block->bl_data + offset; - if (offset == loc_len) { return DW_DLV_NO_ENTRY; } + + loc_ptr = (Dwarf_Small*)loc_block->bl_data + offset; if ((loc_ptr+1) > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); return DW_DLV_ERROR; @@ -143,6 +159,7 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, curr_loc->lr_opnumber = opnumber; curr_loc->lr_offset = offset; + /* loc_ptr is ok to deref, see loc_ptr+1 test just above. */ atom = *(Dwarf_Small *) loc_ptr; loc_ptr++; offset++; @@ -233,6 +250,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_const1u: + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { @@ -243,6 +264,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_const1s: + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Sbyte *) loc_ptr; SIGN_EXTEND(operand1,1); loc_ptr = loc_ptr + 1; @@ -368,6 +393,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_pick: + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { @@ -384,6 +413,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_deref_size: + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { @@ -397,6 +430,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_xderef_type: /* DWARF5 */ + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { @@ -411,6 +448,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_xderef_size: + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { @@ -516,6 +557,10 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, break; case DW_OP_deref_type: /* DWARF5 */ case DW_OP_GNU_deref_type: /* 0xf6 */ + if (loc_ptr >= section_end) { + _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); + return DW_DLV_ERROR; + } operand1 = *(Dwarf_Small *) loc_ptr; loc_ptr = loc_ptr + 1; if (loc_ptr > section_end) { @@ -541,7 +586,7 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, /* This using the second operand as a pointer is quite ugly. */ /* This gets an ugly compiler warning. Sorry. */ - operand2 = (Dwarf_Unsigned)loc_ptr; + operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; offset = offset + operand1; loc_ptr = loc_ptr + operand1; if (loc_ptr > section_end) { @@ -625,7 +670,7 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, /* This using the second operand as a pointer is quite ugly. */ /* This gets an ugly compiler warning. Sorry. */ - operand2 = (Dwarf_Unsigned)loc_ptr; + operand2 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; offset = offset + operand1; loc_ptr = loc_ptr + operand1; if (loc_ptr > section_end) { @@ -649,7 +694,7 @@ _dwarf_read_loc_expr_op(Dwarf_Debug dbg, /* Operand 3 points to a value in the block of size just gotten as operand2. */ /* This gets an ugly compiler warning. Sorry. */ - operand3 = (Dwarf_Unsigned) loc_ptr; + operand3 = (Dwarf_Unsigned)(uintptr_t)loc_ptr; loc_ptr = loc_ptr + operand2; if (loc_ptr > section_end) { _dwarf_error(dbg,error,DW_DLE_LOCEXPR_OFF_SECTION_END); @@ -893,7 +938,8 @@ _dwarf_read_loc_section(Dwarf_Debug dbg, Dwarf_Error * error) { Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset; - Dwarf_Small *loc_section_end = beg + dbg->de_debug_loc.dss_size; + Dwarf_Small *loc_section_end = + dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size; /* start_addr and end_addr are actually offsets of the applicable base address of the CU. @@ -902,7 +948,7 @@ _dwarf_read_loc_section(Dwarf_Debug dbg, Dwarf_Addr end_addr = 0; Dwarf_Half exprblock_size = 0; Dwarf_Unsigned exprblock_off = - 2 * address_size + sizeof(Dwarf_Half); + 2 * address_size + DWARF_HALF_SIZE; if (sec_offset >= dbg->de_debug_loc.dss_size) { /* We're at the end. No more present. */ @@ -925,17 +971,21 @@ _dwarf_read_loc_section(Dwarf_Debug dbg, /* If start_addr and end_addr are 0, it's the end and no exprblock_size field follows. */ exprblock_size = 0; - exprblock_off -= sizeof(Dwarf_Half); + exprblock_off -= DWARF_HALF_SIZE; } else if (start_addr == MAX_ADDR) { /* End address is a base address, no exprblock_size field here either */ exprblock_size = 0; - exprblock_off -= sizeof(Dwarf_Half); + exprblock_off -= DWARF_HALF_SIZE; } else { READ_UNALIGNED_CK(dbg, exprblock_size, Dwarf_Half, - beg + 2 * address_size, sizeof(Dwarf_Half), + beg + 2 * address_size, DWARF_HALF_SIZE, error,loc_section_end); /* exprblock_size can be zero, means no expression */ + if ( exprblock_size >= dbg->de_debug_loc.dss_size) { + _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); + return DW_DLV_ERROR; + } if ((sec_offset +exprblock_off + exprblock_size) > dbg->de_debug_loc.dss_size) { _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); @@ -1026,14 +1076,16 @@ _dwarf_setup_loc(Dwarf_Attribute attr, static int _dwarf_get_loclist_header_start(Dwarf_Debug dbg, Dwarf_Attribute attr, - Dwarf_Unsigned * loclist_offset, + Dwarf_Unsigned * loclist_offset_out, Dwarf_Error * error) { - int blkres = dwarf_global_formref(attr, loclist_offset, error); + Dwarf_Unsigned loc_sec_size = 0; + Dwarf_Unsigned loclist_offset = 0; + + int blkres = dwarf_global_formref(attr, &loclist_offset, error); if (blkres != DW_DLV_OK) { return (blkres); } - if (!dbg->de_debug_loc.dss_data) { int secload = _dwarf_load_section(dbg, &dbg->de_debug_loc,error); if (secload != DW_DLV_OK) { @@ -1043,17 +1095,32 @@ _dwarf_get_loclist_header_start(Dwarf_Debug dbg, return (DW_DLV_NO_ENTRY); } } + loc_sec_size = dbg->de_debug_loc.dss_size; + if (loclist_offset >= loc_sec_size) { + _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); + return DW_DLV_ERROR; + } + { int fisres = 0; Dwarf_Unsigned fissoff = 0; Dwarf_Unsigned size = 0; - fisres = _dwarf_get_fission_addition_die(attr->ar_die, DW_SECT_LOC, + fisres = _dwarf_get_fission_addition_die(attr->ar_die, DW_SECT_LOCLISTS, &fissoff, &size,error); if(fisres != DW_DLV_OK) { return fisres; } - *loclist_offset += fissoff; + if (fissoff >= loc_sec_size) { + _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); + return DW_DLV_ERROR; + } + loclist_offset += fissoff; + if (loclist_offset >= loc_sec_size) { + _dwarf_error(dbg, error, DW_DLE_LOCLIST_OFFSET_BAD); + return DW_DLV_ERROR; + } } + *loclist_offset_out = loclist_offset; return DW_DLV_OK; } @@ -1103,8 +1170,6 @@ context_is_cu_not_tu(Dwarf_CU_Context context, DWARF4 with location extensions. Does not work for .debug_loc.dwo - - Use dwarf_get_loclist_b() and associated functions. */ int dwarf_loclist_n(Dwarf_Attribute attr, @@ -1193,8 +1258,6 @@ dwarf_loclist_n(Dwarf_Attribute attr, return (DW_DLV_ERROR); } - loc_section_end = dbg->de_debug_loc.dss_data+ - dbg->de_debug_loc.dss_size; for (lli = 0; lli < loclist_count; ++lli) { int lres = 0; @@ -1627,4 +1690,4 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, } /* Bring in the code for the October 2015 interfaces. */ -#include "dwarf_loc2.c" +#include "dwarf_loc2.h" diff --git a/thirdparty/dwarf/dwarf_loc.h b/thirdparty/dwarf/dwarf_loc.h index c80ddf00..6e712994 100644 --- a/thirdparty/dwarf/dwarf_loc.h +++ b/thirdparty/dwarf/dwarf_loc.h @@ -146,4 +146,3 @@ struct Dwarf_Loc_Head_c_s { int _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, Dwarf_Block_c *loc_block,Dwarf_Error*error); - diff --git a/thirdparty/dwarf/dwarf_loc2.c b/thirdparty/dwarf/dwarf_loc2.h similarity index 89% rename from thirdparty/dwarf/dwarf_loc2.c rename to thirdparty/dwarf/dwarf_loc2.h index 169a8bb1..b75544af 100644 --- a/thirdparty/dwarf/dwarf_loc2.c +++ b/thirdparty/dwarf/dwarf_loc2.h @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, overridden by our caller with the true ld_lle_value. */ static int -_dwarf_get_locdesc_c(Dwarf_Debug dbg, +_dwarf_get_locdesc_op_c(Dwarf_Debug dbg, Dwarf_Unsigned locdesc_index, Dwarf_Loc_Head_c loc_head, Dwarf_Block_c * loc_block, @@ -90,22 +90,28 @@ _dwarf_get_locdesc_c(Dwarf_Debug dbg, /* ***** BEGIN CODE ***** */ blockdataptr = loc_block->bl_data; - res = _dwarf_what_section_are_we(dbg, - blockdataptr,§ion_name,§ion_start, - §ion_size,§ion_end,error); - if (res != DW_DLV_OK) { - _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN); - return DW_DLV_ERROR; - } - res = _dwarf_loc_block_sanity_check(dbg,loc_block,error); - if (res != DW_DLV_OK) { - return res; + if (!blockdataptr || !loc_block->bl_len) { + /* an empty block has no operations so + no section or tests need be done.. */ + } else { + res = _dwarf_what_section_are_we(dbg, + blockdataptr,§ion_name,§ion_start, + §ion_size,§ion_end,error); + if (res != DW_DLV_OK) { + _dwarf_error(dbg, error,DW_DLE_POINTER_SECTION_UNKNOWN); + return DW_DLV_ERROR; + } + res = _dwarf_loc_block_sanity_check(dbg,loc_block,error); + if (res != DW_DLV_OK) { + return res; + } } /* New loop getting Loc operators. Non DWO */ while (offset <= loc_block->bl_len) { Dwarf_Unsigned nextoffset = 0; struct Dwarf_Loc_c_s temp_loc; + /* This call is ok even if bl_data NULL and bl_len 0 */ res = _dwarf_read_loc_expr_op(dbg,loc_block, op_count, version_stamp, @@ -120,7 +126,8 @@ _dwarf_get_locdesc_c(Dwarf_Debug dbg, return res; } if (res == DW_DLV_NO_ENTRY) { - /* Normal end. */ + /* Normal end. + Also the end for an empty loc_block. */ break; } op_count++; @@ -139,8 +146,6 @@ _dwarf_get_locdesc_c(Dwarf_Debug dbg, new_loc->lc_number2 = temp_loc.lr_number2; new_loc->lc_number3 = temp_loc.lr_number3; new_loc->lc_offset = temp_loc.lr_offset; - offset = nextoffset; - if (head_loc == NULL) head_loc = prev_loc = new_loc; else { @@ -158,6 +163,7 @@ _dwarf_get_locdesc_c(Dwarf_Debug dbg, return DW_DLV_ERROR; } + /* op_count could be zero. */ new_loc = head_loc; for (i = 0; i < op_count; i++) { /* Copying only the fields needed by DWARF 2,3,4 */ @@ -173,11 +179,11 @@ _dwarf_get_locdesc_c(Dwarf_Debug dbg, } /* Synthesizing the DW_LLE values. */ if(highpc == 0 && lowpc == 0) { - locdesc->ld_lle_value = DW_LLE_end_of_list_entry; + locdesc->ld_lle_value = DW_LLEX_end_of_list_entry; } else if(lowpc == MAX_ADDR) { - locdesc->ld_lle_value = DW_LLE_base_address_selection_entry; + locdesc->ld_lle_value = DW_LLEX_base_address_selection_entry; } else { - locdesc->ld_lle_value = DW_LLE_offset_pair_entry; + locdesc->ld_lle_value = DW_LLEX_offset_pair_entry; } locdesc->ld_cents = op_count; locdesc->ld_s = block_loc; @@ -204,7 +210,6 @@ _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, Dwarf_Small *beg = dbg->de_debug_loc.dss_data + sec_offset; Dwarf_Small *locptr = 0; Dwarf_Small llecode = 0; - Dwarf_Word leb128_length = 0; Dwarf_Unsigned expr_offset = sec_offset; Dwarf_Byte_Ptr section_end = dbg->de_debug_loc.dss_data + dbg->de_debug_loc.dss_size; @@ -223,12 +228,12 @@ _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, locptr = beg +1; expr_offset++; switch(llecode) { - case DW_LLE_end_of_list_entry: + case DW_LLEX_end_of_list_entry: *at_end = TRUE; return_block->bl_section_offset = expr_offset; expr_offset++; break; - case DW_LLE_base_address_selection_entry: { + case DW_LLEX_base_address_selection_entry: { Dwarf_Unsigned addr_index = 0; DECODE_LEB128_UWORD_CK(locptr,addr_index, @@ -239,27 +244,30 @@ _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, *highpc=addr_index; } break; - case DW_LLE_start_end_entry: { + case DW_LLEX_start_end_entry: { Dwarf_Unsigned addr_indexs = 0; Dwarf_Unsigned addr_indexe= 0; - Dwarf_Half exprlen = 0; + Dwarf_Unsigned exprlen = 0; + Dwarf_Unsigned leb128_length = 0; - DECODE_LEB128_UWORD_CK(locptr,addr_indexs, + DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexs, + leb128_length, dbg,error,section_end); expr_offset += leb128_length; - DECODE_LEB128_UWORD_CK(locptr,addr_indexe, + DECODE_LEB128_UWORD_LEN_CK(locptr,addr_indexe, + leb128_length, dbg,error,section_end); expr_offset +=leb128_length; *lowpc=addr_indexs; *highpc=addr_indexe; - READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Half, locptr, - sizeof(exprlen), + READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, + DWARF_HALF_SIZE, error,section_end); - locptr += sizeof(exprlen); - expr_offset += sizeof(exprlen); + locptr += DWARF_HALF_SIZE; + expr_offset += DWARF_HALF_SIZE; return_block->bl_len = exprlen; return_block->bl_data = locptr; @@ -273,26 +281,28 @@ _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, } } break; - case DW_LLE_start_length_entry: { + case DW_LLEX_start_length_entry: { Dwarf_Unsigned addr_index = 0; - Dwarf_ufixed range_length = 0; - Dwarf_Half exprlen = 0; + Dwarf_Unsigned range_length = 0; + Dwarf_Unsigned exprlen = 0; + Dwarf_Unsigned leb128_length = 0; - DECODE_LEB128_UWORD_CK(locptr,addr_index, + DECODE_LEB128_UWORD_LEN_CK(locptr,addr_index, + leb128_length, dbg,error,section_end); expr_offset +=leb128_length; - READ_UNALIGNED_CK(dbg, range_length, Dwarf_ufixed, locptr, - sizeof(range_length), + READ_UNALIGNED_CK(dbg, range_length, Dwarf_Unsigned, locptr, + DWARF_32BIT_SIZE, error,section_end); - locptr += sizeof(range_length); - expr_offset += sizeof(range_length); + locptr += DWARF_32BIT_SIZE; + expr_offset += DWARF_32BIT_SIZE; - READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Half, locptr, - sizeof(exprlen), + READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, + DWARF_HALF_SIZE, error,section_end); - locptr += sizeof(exprlen); - expr_offset += sizeof(exprlen); + locptr += DWARF_HALF_SIZE; + expr_offset += DWARF_HALF_SIZE; *lowpc = addr_index; *highpc = range_length; @@ -308,30 +318,32 @@ _dwarf_read_loc_section_dwo(Dwarf_Debug dbg, } } break; - case DW_LLE_offset_pair_entry: { - Dwarf_ufixed startoffset = 0; - Dwarf_ufixed endoffset = 0; - Dwarf_Half exprlen = 0; - - READ_UNALIGNED_CK(dbg, startoffset, Dwarf_ufixed, locptr, - sizeof(startoffset), + case DW_LLEX_offset_pair_entry: { + Dwarf_Unsigned startoffset = 0; + Dwarf_Unsigned endoffset = 0; + Dwarf_Unsigned exprlen = 0; + + READ_UNALIGNED_CK(dbg, startoffset, + Dwarf_Unsigned, locptr, + DWARF_32BIT_SIZE, error,section_end); - locptr += sizeof(startoffset); - expr_offset += sizeof(startoffset); + locptr += DWARF_32BIT_SIZE; + expr_offset += DWARF_32BIT_SIZE; - READ_UNALIGNED_CK(dbg, endoffset, Dwarf_ufixed, locptr, - sizeof(endoffset), + READ_UNALIGNED_CK(dbg, endoffset, + Dwarf_Unsigned, locptr, + DWARF_32BIT_SIZE, error,section_end); - locptr += sizeof(endoffset); - expr_offset += sizeof(endoffset); + locptr += DWARF_32BIT_SIZE; + expr_offset += DWARF_32BIT_SIZE; *lowpc= startoffset; *highpc = endoffset; - READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Half, locptr, - sizeof(exprlen), + READ_UNALIGNED_CK(dbg, exprlen, Dwarf_Unsigned, locptr, + DWARF_HALF_SIZE, error,section_end); - locptr += sizeof(exprlen); - expr_offset += sizeof(exprlen); + locptr += DWARF_HALF_SIZE; + expr_offset += DWARF_HALF_SIZE; return_block->bl_len = exprlen; return_block->bl_data = locptr; @@ -433,6 +445,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, /* If this is a form_block then it's a location expression. If it's DW_FORM_data4 or DW_FORM_data8 in DWARF2 or DWARF3 (or in DWARF4 or 5 a DW_FORM_sec_offset) it's a loclist offset */ + /* In final DWARF5 the situation changes . FIXME */ if (((cuvstamp == DW_CU_VERSION2 || cuvstamp == DW_CU_VERSION3) && (form == DW_FORM_data4 || form == DW_FORM_data8)) || ((cuvstamp == DW_CU_VERSION4 || cuvstamp == DW_CU_VERSION5) && @@ -448,6 +461,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, it could not have a loclist. */ /* A reference to .debug_loc.dwo, with an offset in .debug_loc.dwo of a loclist */ + /* In DWARF5 the situation changes . FIXME */ Dwarf_Unsigned loclist_offset = 0; int off_res = DW_DLV_ERROR; int count_res = DW_DLV_ERROR; @@ -464,11 +478,9 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, if (count_res != DW_DLV_OK) { return count_res; } - listlen = loclist_count; if (loclist_count == 0) { return DW_DLV_NO_ENTRY; } - llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { @@ -507,8 +519,8 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, dwarf_loc_head_c_dealloc(llhead); return blkres; } - /* Fills in the locdesc at index lli */ - lres = _dwarf_get_locdesc_c(dbg, + /* Fills in the locdesc op at index lli */ + lres = _dwarf_get_locdesc_op_c(dbg, lli, llhead, &loc_block, @@ -550,7 +562,6 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, } count_res = _dwarf_get_loclist_count(dbg, loclist_offset, address_size, &loclist_count, error); - listlen = loclist_count; if (count_res != DW_DLV_OK) { return count_res; } @@ -598,7 +609,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, loc_block.bl_locdesc_offset = loclist_offset; /* Fills in the locdesc at index lli */ - lres = _dwarf_get_locdesc_c(dbg, + lres = _dwarf_get_locdesc_op_c(dbg, lli, llhead, &loc_block, @@ -656,7 +667,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, } listlen = 1; /* One by definition of a location entry. */ /* This hack ensures that the Locdesc_c - is marked DW_LLE_start_end_entry */ + is marked DW_LLEX_start_end_entry */ lowpc = 0; /* HACK */ highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ @@ -680,7 +691,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, set. Dwarf2, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ /* Fills in the locdesc at index 0 */ - blkres = _dwarf_get_locdesc_c(dbg, + blkres = _dwarf_get_locdesc_op_c(dbg, 0, /* fake locdesc is index 0 */ llhead, &loc_block, @@ -753,7 +764,7 @@ dwarf_loclist_from_expr_c(Dwarf_Debug dbg, section 2.4.1 In other words, it is not an error, and we don't test for block length 0 specially here. */ - res = _dwarf_get_locdesc_c(dbg, + res = _dwarf_get_locdesc_op_c(dbg, 0, llhead, &loc_block, @@ -859,4 +870,3 @@ dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head) } dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C); } - diff --git a/thirdparty/dwarf/dwarf_macho_loader.h b/thirdparty/dwarf/dwarf_macho_loader.h new file mode 100644 index 00000000..881bbe7c --- /dev/null +++ b/thirdparty/dwarf/dwarf_macho_loader.h @@ -0,0 +1,1523 @@ +/* This is a cut-down version of loader.h from cctools-895, + shrunk to eliminate aspects unwanted in libdwarf and to avoid + #include entirely. All tab characters replaced with 4 spaces + so various things no line up as they used to. + cctools-895 in its original form + is available from https://opensource.apple.com/ + see Developer Tools version 8.2.1. cctools-895/include/loader.h */ +/* +* Copyright (c) 1999-2010 Apple Inc. All Rights Reserved. +* +* @APPLE_LICENSE_HEADER_START@ +* +* This file contains Original Code and/or Modifications of Original Code +* as defined in and that are subject to the Apple Public Source License +* Version 2.0 (the 'License'). You may not use this file except in +* compliance with the License. Please obtain a copy of the License at +* http://www.opensource.apple.com/apsl/ and read it before using this +* file. +* +* The Original Code and all software distributed under the License are +* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +* Please see the License for the specific language governing rights and +* limitations under the License. +* +* @APPLE_LICENSE_HEADER_END@ +*/ +#ifndef MACHO_LOADER_H +#define MACHO_LOADER_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#if 0 /* Not used here. DavidA. September 2018 */ +/* +* This file describes the format of mach object files. +*/ +#include + +/* +* is needed here for the cpu_type_t and cpu_subtype_t types +* and contains the constants for the possible values of these types. +*/ +#include + +/* +* is needed here for the vm_prot_t type and contains the +* constants that are or'ed together for the possible values of this type. +*/ +#include + +/* +* is expected to define the flavors of the thread +* states and the structures of those flavors for each machine. +*/ +#include +#include +#endif /* 0 */ + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif /* TYP */ + +/* +* The 32-bit mach header appears at the very beginning of the object file for +* 32-bit architectures. +*/ +struct mach_header { + TYP(magic,4); /* mach magic number identifier */ + TYP(cputype,4); /* cpu specifier */ + TYP(cpusubtype,4); /* machine specifier */ + TYP(filetype,4); /* type of file */ + TYP(ncmds,4); /* number of load commands */ + TYP(sizeofcmds,4); /* the size of all the load commands */ + TYP(flags,4); /* flags */ +}; + +/* Constant for the magic field of the + mach_header (32-bit architectures) + MH_MAGIC MH_MAGIC_64 appear in big-endian objects + MH_CIGAM MH_CIGAM_64 appear in little-endian objects */ +#define MH_MAGIC 0xfeedface /* the mach magic number */ +#define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ + +/* +* The 64-bit mach header appears at the very beginning of object files for +* 64-bit architectures. +*/ +struct mach_header_64 { + TYP(magic,4); /* mach magic number identifier */ + TYP(cputype,4); /* cpu specifier */ + TYP(cpusubtype,4); /* machine specifier */ + TYP(filetype,4); /* type of file */ + TYP(ncmds,4); /* number of load commands */ + TYP(sizeofcmds,4); /* the size of all the load commands */ + TYP(flags,4); /* flags */ + TYP(reserved,4); /* reserved */ +}; + +/* Constant for the magic field of the mach_header_64 (64-bit architectures) */ +#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ +#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ + +/* +* The layout of the file depends on the filetype. For all but the MH_OBJECT +* file type the segments are padded out and aligned on a segment alignment +* boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, +* MH_DYLINKER and MH_BUNDLE file types also have the headers included as part +* of their first segment. +* +* The file type MH_OBJECT is a compact format intended as output of the +* assembler and input (and possibly output) of the link editor (the .o +* format). All sections are in one unnamed segment with no segment padding. +* This format is used as an executable format when the file is so small the +* segment padding greatly increases its size. +* +* The file type MH_PRELOAD is an executable format intended for things that +* are not executed under the kernel (proms, stand alones, kernels, etc). The +* format can be executed under the kernel but may demand paged it and not +* preload it before execution. +* +* A core file is in MH_CORE format and can be any in an arbritray legal +* Mach-O file. +* +* Constants for the filetype field of the mach_header +*/ +#define MH_OBJECT 0x1 /* relocatable object file */ +#define MH_EXECUTE 0x2 /* demand paged executable file */ +#define MH_FVMLIB 0x3 /* fixed VM shared library file */ +#define MH_CORE 0x4 /* core file */ +#define MH_PRELOAD 0x5 /* preloaded executable file */ +#define MH_DYLIB 0x6 /* dynamically bound shared library */ +#define MH_DYLINKER 0x7 /* dynamic link editor */ +#define MH_BUNDLE 0x8 /* dynamically bound bundle file */ +#define MH_DYLIB_STUB 0x9 /* shared library stub for static */ + /* linking only, no section contents */ +#define MH_DSYM 0xa /* companion file with only debug */ + /* sections */ +#define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */ + +/* Constants for the flags field of the mach_header */ +#define MH_NOUNDEFS 0x1 /* the object file has no undefined + references */ +#define MH_INCRLINK 0x2 /* the object file is the output of an + incremental link against a base file + and can't be link edited again */ +#define MH_DYLDLINK 0x4 /* the object file is input for the + dynamic linker and can't be staticly + link edited again */ +#define MH_BINDATLOAD 0x8 /* the object file's undefined + references are bound by the dynamic + linker when loaded. */ +#define MH_PREBOUND 0x10 /* the file has its dynamic undefined + references prebound. */ +#define MH_SPLIT_SEGS 0x20 /* the file has its read-only and + read-write segments split */ +#define MH_LAZY_INIT 0x40 /* the shared library init routine is + to be run lazily via catching memory + faults to its writeable segments + (obsolete) */ +#define MH_TWOLEVEL 0x80 /* the image is using two-level name + space bindings */ +#define MH_FORCE_FLAT 0x100 /* the executable is forcing all images + to use flat name space bindings */ +#define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple + defintions of symbols in its + sub-images so the two-level namespace + hints can always be used. */ +#define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the + prebinding agent about this + executable */ +#define MH_PREBINDABLE 0x800 /* the binary is not prebound but can + have its prebinding redone. only used + when MH_PREBOUND is not set. */ +#define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to + all two-level namespace modules of + its dependent libraries. only used + when MH_PREBINDABLE and MH_TWOLEVEL + are both set. */ +#define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into + sub-sections via symbols for dead + code stripping */ +#define MH_CANONICAL 0x4000 /* the binary has been canonicalized + via the unprebind operation */ +#define MH_WEAK_DEFINES 0x8000 /* the final linked image contains + external weak symbols */ +#define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses + weak symbols */ + +#define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks + in the task will be given stack + execution privilege. Only used in + MH_EXECUTE filetypes. */ +#define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary + declares it is safe for use in + processes with uid zero */ + +#define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary + declares it is safe for use in + processes when issetugid() is true */ + +#define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, + the static linker does not need to + examine dependent dylibs to see + if any are re-exported */ +#define MH_PIE 0x200000 /* When this bit is set, the OS will + load the main executable at a + random address. Only used in + MH_EXECUTE filetypes. */ +#define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When + linking against a dylib that + has this bit set, the static linker + will automatically not create a + LC_LOAD_DYLIB load command to the + dylib if no symbols are being + referenced from the dylib. */ +#define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type + S_THREAD_LOCAL_VARIABLES */ + +#define MH_NO_HEAP_EXECUTION 0x1000000 /* When this bit is set, the OS will + run the main executable with + a non-executable heap even on + platforms (e.g. i386) that don't + require it. Only used in MH_EXECUTE + filetypes. */ + +#define MH_APP_EXTENSION_SAFE 0x02000000 /* The code was linked for use in an + application extension. */ + +/* +* The load commands directly follow the mach_header. The total size of all +* of the commands is given by the sizeofcmds field in the mach_header. All +* load commands must have as their first two fields cmd and cmdsize. The cmd +* field is filled in with a constant for that command type. Each command type +* has a structure specifically for it. The cmdsize field is the size in bytes +* of the particular load command structure plus anything that follows it that +* is a part of the load command (i.e. section structures, strings, etc.). To +* advance to the next load command the cmdsize can be added to the offset or +* pointer of the current load command. The cmdsize for 32-bit architectures +* MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple +* of 8 bytes (these are forever the maximum alignment of any load commands). +* The padded bytes must be zero. All tables in the object file must also +* follow these rules so the file can be memory mapped. Otherwise the pointers +* to these tables will not work well or at all on some machines. With all +* padding zeroed like objects will compare byte for byte. +*/ +struct load_command { + TYP(cmd,4); /* type of load command */ + TYP(cmdsize,4); /* total size of command in bytes */ +}; + +/* +* After MacOS X 10.1 when a new load command is added that is required to be +* understood by the dynamic linker for the image to execute properly the +* LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic +* linker sees such a load command it it does not understand will issue a +* "unknown load command required for execution" error and refuse to use the +* image. Other load commands without this bit that are not understood will +* simply be ignored. +*/ +#define LC_REQ_DYLD 0x80000000 + +/* Constants for the cmd field of all load commands, the type */ +#define LC_SEGMENT 0x1 /* segment of this file to be mapped */ +#define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ +#define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ +#define LC_THREAD 0x4 /* thread */ +#define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ +#define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ +#define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ +#define LC_IDENT 0x8 /* object identification info (obsolete) */ +#define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ +#define LC_PREPAGE 0xa /* prepage command (internal use) */ +#define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ +#define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ +#define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ +#define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ +#define LC_ID_DYLINKER 0xf /* dynamic linker identification */ +#define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ + /* linked shared library */ +#define LC_ROUTINES 0x11 /* image routines */ +#define LC_SUB_FRAMEWORK 0x12 /* sub framework */ +#define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ +#define LC_SUB_CLIENT 0x14 /* sub client */ +#define LC_SUB_LIBRARY 0x15 /* sub library */ +#define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ +#define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ + +/* +* load a dynamically linked shared library that is allowed to be missing +* (all symbols are weak imported). +*/ +#define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) + +#define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be + mapped */ +#define LC_ROUTINES_64 0x1a /* 64-bit image routines */ +#define LC_UUID 0x1b /* the uuid */ +#define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ +#define LC_CODE_SIGNATURE 0x1d /* local of code signature */ +#define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ +#define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ +#define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ +#define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ +#define LC_DYLD_INFO 0x22 /* compressed dyld information */ +#define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ +#define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ +#define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */ +#define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */ +#define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ +#define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat + like environment variable */ +#define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */ +#define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */ +#define LC_SOURCE_VERSION 0x2A /* source version used to build binary */ +#define LC_DYLIB_CODE_SIGN_DRS 0x2B /* Code signing DRs copied from linked dylibs */ +#define LC_ENCRYPTION_INFO_64 0x2C /* 64-bit encrypted segment information */ +#define LC_LINKER_OPTION 0x2D /* linker options in MH_OBJECT files */ +#define LC_LINKER_OPTIMIZATION_HINT 0x2E /* optimization hints in MH_OBJECT files */ +#define LC_VERSION_MIN_TVOS 0x2F /* build for AppleTV min OS version */ +#define LC_VERSION_MIN_WATCHOS 0x30 /* build for Watch min OS version */ + +/* +* A variable length string in a load command is represented by an lc_str +* union. The strings are stored just after the load command structure and +* the offset is from the start of the load command structure. The size +* of the string is reflected in the cmdsize field of the load command. +* Once again any padded bytes to bring the cmdsize field to a multiple +* of 4 bytes must be zero. +*/ +union lc_str { + TYP(offset,4); /* offset to the string */ +#ifndef __LP64__ + char *ptr; /* pointer to the string */ +#endif +}; + +/* +* The segment load command indicates that a part of this file is to be +* mapped into the task's address space. The size of this segment in memory, +* vmsize, maybe equal to or larger than the amount to map from this file, +* filesize. The file is mapped starting at fileoff to the beginning of +* the segment in memory, vmaddr. The rest of the memory of the segment, +* if any, is allocated zero fill on demand. The segment's maximum virtual +* memory protection and initial virtual memory protection are specified +* by the maxprot and initprot fields. If the segment has sections then the +* section structures directly follow the segment command and their size is +* reflected in cmdsize. +*/ +struct segment_command { /* for 32-bit architectures */ + TYP(cmd,4); /* LC_SEGMENT */ + TYP(cmdsize,4); /* includes sizeof section structs */ + char segname[16]; /* segment name */ + TYP(vmaddr,4); /* memory address of this segment */ + TYP(vmsize,4); /* memory size of this segment */ + TYP(fileoff,4); /* file offset of this segment */ + TYP(filesize,4); /* amount to map from the file */ + TYP(maxprot,4); /* maximum VM protection */ + TYP(initprot,4); /* initial VM protection */ + TYP(nsects,4); /* number of sections in segment */ + TYP(flags,4); /* flags */ +}; + +/* +* The 64-bit segment load command indicates that a part of this file is to be +* mapped into a 64-bit task's address space. If the 64-bit segment has +* sections then section_64 structures directly follow the 64-bit segment +* command and their size is reflected in cmdsize. +*/ +struct segment_command_64 { /* for 64-bit architectures */ + TYP(cmd,4); /* LC_SEGMENT_64 */ + TYP(cmdsize,4); /* includes sizeof section_64 structs */ + char segname[16]; /* segment name */ + TYP(vmaddr,8); /* memory address of this segment */ + TYP(vmsize,8); /* memory size of this segment */ + TYP(fileoff,8); /* file offset of this segment */ + TYP(filesize,8); /* amount to map from the file */ + TYP(maxprot,4); /* maximum VM protection */ + TYP(initprot,4); /* initial VM protection */ + TYP(nsects,4); /* number of sections in segment */ + TYP(flags,4); /* flags */ +}; + +/* Constants for the flags field of the segment_command */ +#define SG_HIGHVM 0x1 /* the file contents for this segment is for + the high part of the VM space, the low part + is zero filled (for stacks in core files) */ +#define SG_FVMLIB 0x2 /* this segment is the VM that is allocated by + a fixed VM library, for overlap checking in + the link editor */ +#define SG_NORELOC 0x4 /* this segment has nothing that was relocated + in it and nothing relocated to it, that is + it maybe safely replaced without relocation*/ +#define SG_PROTECTED_VERSION_1 0x8 /* This segment is protected. If the + segment starts at file offset 0, the + first page of the segment is not + protected. All other pages of the + segment are protected. */ + +/* +* A segment is made up of zero or more sections. Non-MH_OBJECT files have +* all of their segments with the proper sections in each, and padded to the +* specified segment alignment when produced by the link editor. The first +* segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header +* and load commands of the object file before its first section. The zero +* fill sections are always last in their segment (in all formats). This +* allows the zeroed segment padding to be mapped into memory where zero fill +* sections might be. The gigabyte zero fill sections, those with the section +* type S_GB_ZEROFILL, can only be in a segment with sections of this type. +* These segments are then placed after all other segments. +* +* The MH_OBJECT format has all of its sections in one segment for +* compactness. There is no padding to a specified segment boundary and the +* mach_header and load commands are not part of the segment. +* +* Sections with the same section name, sectname, going into the same segment, +* segname, are combined by the link editor. The resulting section is aligned +* to the maximum alignment of the combined sections and is the new section's +* alignment. The combined sections are aligned to their original alignment in +* the combined section. Any padded bytes to get the specified alignment are +* zeroed. +* +* The format of the relocation entries referenced by the reloff and nreloc +* fields of the section structure for mach object files is described in the +* header file . +*/ +struct section { /* for 32-bit architectures */ + char sectname[16]; /* name of this section */ + char segname[16]; /* segment this section goes in */ + TYP(addr,4); /* memory address of this section */ + TYP(size,4); /* size in bytes of this section */ + TYP(offset,4); /* file offset of this section */ + TYP(align,4); /* section alignment (power of 2) */ + TYP(reloff,4); /* file offset of relocation entries */ + TYP(nreloc,4); /* number of relocation entries */ + TYP(flags,4); /* flags (section type and attributes)*/ + TYP(reserved1,4); /* reserved (for offset or index) */ + TYP(reserved2,4); /* reserved (for count or sizeof) */ +}; + +struct section_64 { /* for 64-bit architectures */ + char sectname[16]; /* name of this section */ + char segname[16]; /* segment this section goes in */ + TYP(addr,8); /* memory address of this section */ + TYP(size,8); /* size in bytes of this section */ + TYP(offset,4); /* file offset of this section */ + TYP(align,4); /* section alignment (power of 2) */ + TYP(reloff,4); /* file offset of relocation entries */ + TYP(nreloc,4); /* number of relocation entries */ + TYP(flags,4); /* flags (section type and attributes)*/ + TYP(reserved1,4); /* reserved (for offset or index) */ + TYP(reserved2,4); /* reserved (for count or sizeof) */ + TYP(reserved3,4); /* reserved */ +}; + +/* +* The flags field of a section structure is separated into two parts a section +* type and section attributes. The section types are mutually exclusive (it +* can only have one type) but the section attributes are not (it may have more +* than one attribute). +*/ +#define SECTION_TYPE 0x000000ff /* 256 section types */ +#define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */ + +/* Constants for the type of a section */ +#define S_REGULAR 0x0 /* regular section */ +#define S_ZEROFILL 0x1 /* zero fill on demand section */ +#define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/ +#define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */ +#define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */ +#define S_LITERAL_POINTERS 0x5 /* section with only pointers to */ + /* literals */ +/* +* For the two types of symbol pointers sections and the symbol stubs section +* they have indirect symbol table entries. For each of the entries in the +* section the indirect symbol table entries, in corresponding order in the +* indirect symbol table, start at the index stored in the reserved1 field +* of the section structure. Since the indirect symbol table entries +* correspond to the entries in the section the number of indirect symbol table +* entries is inferred from the size of the section divided by the size of the +* entries in the section. For symbol pointers sections the size of the entries +* in the section is 4 bytes and for symbol stubs sections the byte size of the +* stubs is stored in the reserved2 field of the section structure. +*/ +#define S_NON_LAZY_SYMBOL_POINTERS 0x6 /* section with only non-lazy + symbol pointers */ +#define S_LAZY_SYMBOL_POINTERS 0x7 /* section with only lazy symbol + pointers */ +#define S_SYMBOL_STUBS 0x8 /* section with only symbol + stubs, byte size of stub in + the reserved2 field */ +#define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function + pointers for initialization*/ +#define S_MOD_TERM_FUNC_POINTERS 0xa /* section with only function + pointers for termination */ +#define S_COALESCED 0xb /* section contains symbols that + are to be coalesced */ +#define S_GB_ZEROFILL 0xc /* zero fill on demand section + (that can be larger than 4 + gigabytes) */ +#define S_INTERPOSING 0xd /* section with only pairs of + function pointers for + interposing */ +#define S_16BYTE_LITERALS 0xe /* section with only 16 byte + literals */ +#define S_DTRACE_DOF 0xf /* section contains + DTrace Object Format */ +#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy + symbol pointers to lazy + loaded dylibs */ +/* +* Section types to support thread local variables +*/ +#define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial + values for TLVs */ +#define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial + values for TLVs */ +#define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */ +#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV + descriptors */ +#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call + to initialize TLV + values */ + +/* +* Constants for the section attributes part of the flags field of a section +* structure. +*/ +#define SECTION_ATTRIBUTES_USR 0xff000000 /* User setable attributes */ +#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section contains only true + machine instructions */ +#define S_ATTR_NO_TOC 0x40000000 /* section contains coalesced + symbols that are not to be + in a ranlib table of + contents */ +#define S_ATTR_STRIP_STATIC_SYMS 0x20000000 /* ok to strip static symbols + in this section in files + with the MH_DYLDLINK flag */ +#define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */ +#define S_ATTR_LIVE_SUPPORT 0x08000000 /* blocks are live if they + reference live blocks */ +#define S_ATTR_SELF_MODIFYING_CODE 0x04000000 /* Used with i386 code stubs + written on by dyld */ +/* +* If a segment contains any sections marked with S_ATTR_DEBUG then all +* sections in that segment must have this attribute. No section other than +* a section marked with this attribute may reference the contents of this +* section. A section with this attribute may contain no symbols and must have +* a section type S_REGULAR. The static linker will not copy section contents +* from sections with this attribute into its output file. These sections +* generally contain DWARF debugging info. +*/ +#define S_ATTR_DEBUG 0x02000000 /* a debug section */ +#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */ +#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some + machine instructions */ +#define S_ATTR_EXT_RELOC 0x00000200 /* section has external + relocation entries */ +#define S_ATTR_LOC_RELOC 0x00000100 /* section has local + relocation entries */ + + +/* +* The names of segments and sections in them are mostly meaningless to the +* link-editor. But there are few things to support traditional UNIX +* executables that require the link-editor and assembler to use some names +* agreed upon by convention. +* +* The initial protection of the "__TEXT" segment has write protection turned +* off (not writeable). +* +* The link-editor will allocate common symbols at the end of the "__common" +* section in the "__DATA" segment. It will create the section and segment +* if needed. +*/ + +/* The currently known segment names and the section names in those segments */ + +#define SEG_PAGEZERO "__PAGEZERO" /* the pagezero segment which has no */ + /* protections and catches NULL */ + /* references for MH_EXECUTE files */ + + +#define SEG_TEXT "__TEXT" /* the tradition UNIX text segment */ +#define SECT_TEXT "__text" /* the real text part of the text */ + /* section no headers, and no padding */ +#define SECT_FVMLIB_INIT0 "__fvmlib_init0" /* the fvmlib initialization */ + /* section */ +#define SECT_FVMLIB_INIT1 "__fvmlib_init1" /* the section following the */ + /* fvmlib initialization */ + /* section */ + +#define SEG_DATA "__DATA" /* the tradition UNIX data segment */ +#define SECT_DATA "__data" /* the real initialized data section */ + /* no padding, no bss overlap */ +#define SECT_BSS "__bss" /* the real uninitialized data section*/ + /* no padding */ +#define SECT_COMMON "__common" /* the section common symbols are */ + /* allocated in by the link editor */ + +#define SEG_OBJC "__OBJC" /* objective-C runtime segment */ +#define SECT_OBJC_SYMBOLS "__symbol_table" /* symbol table */ +#define SECT_OBJC_MODULES "__module_info" /* module information */ +#define SECT_OBJC_STRINGS "__selector_strs" /* string table */ +#define SECT_OBJC_REFS "__selector_refs" /* string table */ + +#define SEG_ICON "__ICON" /* the icon segment */ +#define SECT_ICON_HEADER "__header" /* the icon headers */ +#define SECT_ICON_TIFF "__tiff" /* the icons in tiff format */ + +#define SEG_LINKEDIT "__LINKEDIT" /* the segment containing all structs */ + /* created and maintained by the link */ + /* editor. Created with -seglinkedit */ + /* option to ld(1) for MH_EXECUTE and */ + /* FVMLIB file types only */ + +#define SEG_UNIXSTACK "__UNIXSTACK" /* the unix stack segment */ + +#define SEG_IMPORT "__IMPORT" /* the segment for the self (dyld) */ + /* modifing code stubs that has read, */ + /* write and execute permissions */ + +/* +* Fixed virtual memory shared libraries are identified by two things. The +* target pathname (the name of the library as found for execution), and the +* minor version number. The address of where the headers are loaded is in +* header_addr. (THIS IS OBSOLETE and no longer supported). +*/ +struct fvmlib { + union lc_str name; /* library's target pathname */ + TYP(minor_version,4); /* library's minor version number */ + TYP(header_addr,4); /* library's header address */ +}; + +/* +* A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) +* contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library. +* An object that uses a fixed virtual shared library also contains a +* fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses. +* (THIS IS OBSOLETE and no longer supported). +*/ +struct fvmlib_command { + TYP(cmd,4); /* LC_IDFVMLIB or LC_LOADFVMLIB */ + TYP(cmdsize,4); /* includes pathname string */ + struct fvmlib fvmlib; /* the library identification */ +}; + +/* +* Dynamicly linked shared libraries are identified by two things. The +* pathname (the name of the library as found for execution), and the +* compatibility version number. The pathname must match and the compatibility +* number in the user of the library must be greater than or equal to the +* library being used. The time stamp is used to record the time a library was +* built and copied into user so it can be use to determined if the library used +* at runtime is exactly the same as used to built the program. +*/ +struct dylib { + union lc_str name; /* library's path name */ + TYP(timestamp,4); /* library's build time stamp */ + TYP(current_version,4); /* library's current version number */ + TYP(compatibility_version,4); /* library's compatibility vers number*/ +}; + +/* +* A dynamically linked shared library (filetype == MH_DYLIB in the mach header) +* contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library. +* An object that uses a dynamically linked shared library also contains a +* dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or +* LC_REEXPORT_DYLIB) for each library it uses. +*/ +struct dylib_command { + TYP(cmd,4); /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, + LC_REEXPORT_DYLIB */ + TYP(cmdsize,4); /* includes pathname string */ + struct dylib dylib; /* the library identification */ +}; + +/* +* A dynamically linked shared library may be a subframework of an umbrella +* framework. If so it will be linked with "-umbrella umbrella_name" where +* Where "umbrella_name" is the name of the umbrella framework. A subframework +* can only be linked against by its umbrella framework or other subframeworks +* that are part of the same umbrella framework. Otherwise the static link +* editor produces an error and states to link against the umbrella framework. +* The name of the umbrella framework for subframeworks is recorded in the +* following structure. +*/ +struct sub_framework_command { + TYP(cmd,4); /* LC_SUB_FRAMEWORK */ + TYP(cmdsize,4); /* includes umbrella string */ + union lc_str umbrella; /* the umbrella framework name */ +}; + +/* +* For dynamically linked shared libraries that are subframework of an umbrella +* framework they can allow clients other than the umbrella framework or other +* subframeworks in the same umbrella framework. To do this the subframework +* is built with "-allowable_client client_name" and an LC_SUB_CLIENT load +* command is created for each -allowable_client flag. The client_name is +* usually a framework name. It can also be a name used for bundles clients +* where the bundle is built with "-client_name client_name". +*/ +struct sub_client_command { + TYP(cmd,4); /* LC_SUB_CLIENT */ + TYP(cmdsize,4); /* includes client string */ + union lc_str client; /* the client name */ +}; + +/* +* A dynamically linked shared library may be a sub_umbrella of an umbrella +* framework. If so it will be linked with "-sub_umbrella umbrella_name" where +* Where "umbrella_name" is the name of the sub_umbrella framework. When +* staticly linking when -twolevel_namespace is in effect a twolevel namespace +* umbrella framework will only cause its subframeworks and those frameworks +* listed as sub_umbrella frameworks to be implicited linked in. Any other +* dependent dynamic libraries will not be linked it when -twolevel_namespace +* is in effect. The primary library recorded by the static linker when +* resolving a symbol in these libraries will be the umbrella framework. +* Zero or more sub_umbrella frameworks may be use by an umbrella framework. +* The name of a sub_umbrella framework is recorded in the following structure. +*/ +struct sub_umbrella_command { + TYP(cmd,4); /* LC_SUB_UMBRELLA */ + TYP(cmdsize,4); /* includes sub_umbrella string */ + union lc_str sub_umbrella; /* the sub_umbrella framework name */ +}; + +/* +* A dynamically linked shared library may be a sub_library of another shared +* library. If so it will be linked with "-sub_library library_name" where +* Where "library_name" is the name of the sub_library shared library. When +* staticly linking when -twolevel_namespace is in effect a twolevel namespace +* shared library will only cause its subframeworks and those frameworks +* listed as sub_umbrella frameworks and libraries listed as sub_libraries to +* be implicited linked in. Any other dependent dynamic libraries will not be +* linked it when -twolevel_namespace is in effect. The primary library +* recorded by the static linker when resolving a symbol in these libraries +* will be the umbrella framework (or dynamic library). Zero or more sub_library +* shared libraries may be use by an umbrella framework or (or dynamic library). +* The name of a sub_library framework is recorded in the following structure. +* For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc". +*/ +struct sub_library_command { + TYP(cmd,4); /* LC_SUB_LIBRARY */ + TYP(cmdsize,4); /* includes sub_library string */ + union lc_str sub_library; /* the sub_library name */ +}; + +/* +* A program (filetype == MH_EXECUTE) that is +* prebound to its dynamic libraries has one of these for each library that +* the static linker used in prebinding. It contains a bit vector for the +* modules in the library. The bits indicate which modules are bound (1) and +* which are not (0) from the library. The bit for module 0 is the low bit +* of the first byte. So the bit for the Nth module is: +* (linked_modules[N/8] >> N%8) & 1 +*/ +struct prebound_dylib_command { + TYP(cmd,4); /* LC_PREBOUND_DYLIB */ + TYP(cmdsize,4); /* includes strings */ + union lc_str name; /* library's path name */ + TYP(nmodules,4); /* number of modules in library */ + union lc_str linked_modules; /* bit vector of linked modules */ +}; + +/* +* A program that uses a dynamic linker contains a dylinker_command to identify +* the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker +* contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). +* A file can have at most one of these. +* This struct is also used for the LC_DYLD_ENVIRONMENT load command and +* contains string for dyld to treat like environment variable. +*/ +struct dylinker_command { + TYP(cmd,4); /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or + LC_DYLD_ENVIRONMENT */ + TYP(cmdsize,4); /* includes pathname string */ + union lc_str name; /* dynamic linker's path name */ +}; + +/* +* Thread commands contain machine-specific data structures suitable for +* use in the thread state primitives. The machine specific data structures +* follow the struct thread_command as follows. +* Each flavor of machine specific data structure is preceded by an unsigned +* long constant for the flavor of that data structure, an uint32_t +* that is the count of longs of the size of the state data structure and then +* the state data structure follows. This triple may be repeated for many +* flavors. The constants for the flavors, counts and state data structure +* definitions are expected to be in the header file . +* These machine specific data structures sizes must be multiples of +* 4 bytes The cmdsize reflects the total size of the thread_command +* and all of the sizes of the constants for the flavors, counts and state +* data structures. +* +* For executable objects that are unix processes there will be one +* thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor. +* This is the same as a LC_THREAD, except that a stack is automatically +* created (based on the shell's limit for the stack size). Command arguments +* and environment variables are copied onto that stack. +*/ +struct thread_command { + TYP(cmd,4); /* LC_THREAD or LC_UNIXTHREAD */ + TYP(cmdsize,4); /* total size of this command */ + /* uint32_t flavor flavor of thread state */ + /* uint32_t count count of longs in thread state */ + /* struct XXX_thread_state state thread state for this flavor */ + /* ... */ +}; + +/* +* The routines command contains the address of the dynamic shared library +* initialization routine and an index into the module table for the module +* that defines the routine. Before any modules are used from the library the +* dynamic linker fully binds the module that defines the initialization routine +* and then calls it. This gets called before any module initialization +* routines (used for C++ static constructors) in the library. +*/ +struct routines_command { /* for 32-bit architectures */ + TYP(cmd,4); /* LC_ROUTINES */ + TYP(cmdsize,4); /* total size of this command */ + TYP(init_address,4); /* address of initialization routine */ + TYP(init_module,4); /* index into the module table that */ + /* the init routine is defined in */ + TYP(reserved1,4); + TYP(reserved2,4); + TYP(reserved3,4); + TYP(reserved4,4); + TYP(reserved5,4); + TYP(reserved6,4); +}; + +/* +* The 64-bit routines command. Same use as above. +*/ +struct routines_command_64 { /* for 64-bit architectures */ + TYP(cmd,4); /* LC_ROUTINES_64 */ + TYP(cmdsize,4); /* total size of this command */ + TYP(init_address,8); /* address of initialization routine */ + TYP(init_module,8); /* index into the module table that */ + /* the init routine is defined in */ + TYP(reserved1,8); + TYP(reserved2,8); + TYP(reserved3,8); + TYP(reserved4,8); + TYP(reserved5,8); + TYP(reserved6,8); +}; + +/* +* The symtab_command contains the offsets and sizes of the link-edit 4.3BSD +* "stab" style symbol table information as described in the header files +* and . +*/ +struct symtab_command { + TYP(cmd,4); /* LC_SYMTAB */ + TYP(cmdsize,4); /* sizeof(struct symtab_command) */ + TYP(symoff,4); /* symbol table offset */ + TYP(nsyms,4); /* number of symbol table entries */ + TYP(stroff,4); /* string table offset */ + TYP(strsize,4); /* string table size in bytes */ +}; + +/* +* This is the second set of the symbolic information which is used to support +* the data structures for the dynamically link editor. +* +* The original set of symbolic information in the symtab_command which contains +* the symbol and string tables must also be present when this load command is +* present. When this load command is present the symbol table is organized +* into three groups of symbols: +* local symbols (static and debugging symbols) - grouped by module +* defined external symbols - grouped by module (sorted by name if not lib) +* undefined external symbols (sorted by name if MH_BINDATLOAD is not set, +* and in order the were seen by the static +* linker if MH_BINDATLOAD is set) +* In this load command there are offsets and counts to each of the three groups +* of symbols. +* +* This load command contains a the offsets and sizes of the following new +* symbolic information tables: +* table of contents +* module table +* reference symbol table +* indirect symbol table +* The first three tables above (the table of contents, module table and +* reference symbol table) are only present if the file is a dynamically linked +* shared library. For executable and object modules, which are files +* containing only one module, the information that would be in these three +* tables is determined as follows: +* table of contents - the defined external symbols are sorted by name +* module table - the file contains only one module so everything in the +* file is part of the module. +* reference symbol table - is the defined and undefined external symbols +* +* For dynamically linked shared library files this load command also contains +* offsets and sizes to the pool of relocation entries for all sections +* separated into two groups: +* external relocation entries +* local relocation entries +* For executable and object modules the relocation entries continue to hang +* off the section structures. +*/ +struct dysymtab_command { + TYP(cmd,4); /* LC_DYSYMTAB */ + TYP(cmdsize,4); /* sizeof(struct dysymtab_command) */ + + /* + * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command + * are grouped into the following three groups: + * local symbols (further grouped by the module they are from) + * defined external symbols (further grouped by the module they are from) + * undefined symbols + * + * The local symbols are used only for debugging. The dynamic binding + * process may have to use them to indicate to the debugger the local + * symbols for a module that is being bound. + * + * The last two groups are used by the dynamic binding process to do the + * binding (indirectly through the module table and the reference symbol + * table when this is a dynamically linked shared library file). + */ + TYP(ilocalsym,4); /* index to local symbols */ + TYP(nlocalsym,4); /* number of local symbols */ + + TYP(iextdefsym,4); /* index to externally defined symbols */ + TYP(nextdefsym,4); /* number of externally defined symbols */ + + TYP(iundefsym,4); /* index to undefined symbols */ + TYP(nundefsym,4); /* number of undefined symbols */ + + /* + * For the for the dynamic binding process to find which module a symbol + * is defined in the table of contents is used (analogous to the ranlib + * structure in an archive) which maps defined external symbols to modules + * they are defined in. This exists only in a dynamically linked shared + * library file. For executable and object modules the defined external + * symbols are sorted by name and is use as the table of contents. + */ + TYP(tocoff,4); /* file offset to table of contents */ + TYP(ntoc,4); /* number of entries in table of contents */ + + /* + * To support dynamic binding of "modules" (whole object files) the symbol + * table must reflect the modules that the file was created from. This is + * done by having a module table that has indexes and counts into the merged + * tables for each module. The module structure that these two entries + * refer to is described below. This exists only in a dynamically linked + * shared library file. For executable and object modules the file only + * contains one module so everything in the file belongs to the module. + */ + TYP(modtaboff,4); /* file offset to module table */ + TYP(nmodtab,4); /* number of module table entries */ + + /* + * To support dynamic module binding the module structure for each module + * indicates the external references (defined and undefined) each module + * makes. For each module there is an offset and a count into the + * reference symbol table for the symbols that the module references. + * This exists only in a dynamically linked shared library file. For + * executable and object modules the defined external symbols and the + * undefined external symbols indicates the external references. + */ + TYP(extrefsymoff,4); /* offset to referenced symbol table */ + TYP(nextrefsyms,4); /* number of referenced symbol table entries */ + + /* + * The sections that contain "symbol pointers" and "routine stubs" have + * indexes and (implied counts based on the size of the section and fixed + * size of the entry) into the "indirect symbol" table for each pointer + * and stub. For every section of these two types the index into the + * indirect symbol table is stored in the section header in the field + * reserved1. An indirect symbol table entry is simply a 32bit index into + * the symbol table to the symbol that the pointer or stub is referring to. + * The indirect symbol table is ordered to match the entries in the section. + */ + TYP(indirectsymoff,4); /* file offset to the indirect symbol table */ + TYP(nindirectsyms,4); /* number of indirect symbol table entries */ + + /* + * To support relocating an individual module in a library file quickly the + * external relocation entries for each module in the library need to be + * accessed efficiently. Since the relocation entries can't be accessed + * through the section headers for a library file they are separated into + * groups of local and external entries further grouped by module. In this + * case the presents of this load command who's extreloff, nextrel, + * locreloff and nlocrel fields are non-zero indicates that the relocation + * entries of non-merged sections are not referenced through the section + * structures (and the reloff and nreloc fields in the section headers are + * set to zero). + * + * Since the relocation entries are not accessed through the section headers + * this requires the r_address field to be something other than a section + * offset to identify the item to be relocated. In this case r_address is + * set to the offset from the vmaddr of the first LC_SEGMENT command. + * For MH_SPLIT_SEGS images r_address is set to the the offset from the + * vmaddr of the first read-write LC_SEGMENT command. + * + * The relocation entries are grouped by module and the module table + * entries have indexes and counts into them for the group of external + * relocation entries for that the module. + * + * For sections that are merged across modules there must not be any + * remaining external relocation entries for them (for merged sections + * remaining relocation entries must be local). + */ + TYP(extreloff,4); /* offset to external relocation entries */ + TYP(nextrel,4); /* number of external relocation entries */ + + /* + * All the local relocation entries are grouped together (they are not + * grouped by their module since they are only used if the object is moved + * from it staticly link edited address). + */ + TYP(locreloff,4); /* offset to local relocation entries */ + TYP(nlocrel,4); /* number of local relocation entries */ +}; + +/* +* An indirect symbol table entry is simply a 32bit index into the symbol table +* to the symbol that the pointer or stub is refering to. Unless it is for a +* non-lazy symbol pointer section for a defined symbol which strip(1) as +* removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the +* symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. +*/ +#define INDIRECT_SYMBOL_LOCAL 0x80000000 +#define INDIRECT_SYMBOL_ABS 0x40000000 + + +/* a table of contents entry */ +struct dylib_table_of_contents { + TYP(symbol_index,4); /* the defined external symbol + (index into the symbol table) */ + TYP(module_index,4); /* index into the module table this symbol + is defined in */ +}; + +/* a module table entry */ +struct dylib_module { + TYP(module_name,4); /* the module name (index into string table) */ + + TYP(iextdefsym,4); /* index into externally defined symbols */ + TYP(nextdefsym,4); /* number of externally defined symbols */ + TYP(irefsym,4); /* index into reference symbol table */ + TYP(nrefsym,4); /* number of reference symbol table entries */ + TYP(ilocalsym,4); /* index into symbols for local symbols */ + TYP(nlocalsym,4); /* number of local symbols */ + + TYP(iextrel,4); /* index into external relocation entries */ + TYP(nextrel,4); /* number of external relocation entries */ + + TYP(iinit_iterm,4); /* low 16 bits are the index into the init + section, high 16 bits are the index into + the term section */ + TYP(ninit_nterm,4); /* low 16 bits are the number of init section + entries, high 16 bits are the number of + term section entries */ + + /* for this module address of the start of */ + /* the (__OBJC,__module_info) section */ + TYP(objc_module_info_addr,4); + + /* for this module size of */ + /* the (__OBJC,__module_info) section */ + TYP(objc_module_info_size,4); +}; + +/* a 64-bit module table entry */ +struct dylib_module_64 { + TYP(module_name,4); /* the module name (index into string table) */ + + TYP(iextdefsym,4); /* index into externally defined symbols */ + TYP(nextdefsym,4); /* number of externally defined symbols */ + TYP(irefsym,4); /* index into reference symbol table */ + TYP(nrefsym,4); /* number of reference symbol table entries */ + TYP(ilocalsym,4); /* index into symbols for local symbols */ + TYP(nlocalsym,4); /* number of local symbols */ + + TYP(iextrel,4); /* index into external relocation entries */ + TYP(nextrel,4); /* number of external relocation entries */ + + TYP(iinit_iterm,4); /* low 16 bits are the index into the init + section, high 16 bits are the index into + the term section */ + TYP(ninit_nterm,4); /* low 16 bits are the number of init section + entries, high 16 bits are the number of + term section entries */ + + TYP(objc_module_info_size,4); /* for this module size of */ + /* the (__OBJC,__module_info) section */ + TYP(objc_module_info_addr,8); /* for this module address of the start of */ + /* the (__OBJC,__module_info) section */ +}; + +/* +* The entries in the reference symbol table are used when loading the module +* (both by the static and dynamic link editors) and if the module is unloaded +* or replaced. Therefore all external symbols (defined and undefined) are +* listed in the module's reference table. The flags describe the type of +* reference that is being made. The constants for the flags are defined in +* as they are also used for symbol table entries. +*/ +#if 0 /* dwarf readers not using this */ +struct dylib_reference { + UNUSED uint32_t isym:24, /* index into the symbol table */ + UNUSED flags:8; /* flags to indicate the type of reference */ +}; +#endif /* 0 */ + +/* +* The twolevel_hints_command contains the offset and number of hints in the +* two-level namespace lookup hints table. +*/ +struct twolevel_hints_command { + TYP(cmd,4); /* LC_TWOLEVEL_HINTS */ + TYP(cmdsize,4); /* sizeof(struct twolevel_hints_command) */ + TYP(offset,4); /* offset to the hint table */ + TYP(nhints,4); /* number of hints in the hint table */ +}; + +/* +* The entries in the two-level namespace lookup hints table are twolevel_hint +* structs. These provide hints to the dynamic link editor where to start +* looking for an undefined symbol in a two-level namespace image. The +* isub_image field is an index into the sub-images (sub-frameworks and +* sub-umbrellas list) that made up the two-level image that the undefined +* symbol was found in when it was built by the static link editor. If +* isub-image is 0 the the symbol is expected to be defined in library and not +* in the sub-images. If isub-image is non-zero it is an index into the array +* of sub-images for the umbrella with the first index in the sub-images being +* 1. The array of sub-images is the ordered list of sub-images of the umbrella +* that would be searched for a symbol that has the umbrella recorded as its +* primary library. The table of contents index is an index into the +* library's table of contents. This is used as the starting point of the +* binary search or a directed linear search. +*/ +#if 0 +/* Not used by dwarf readers. */ +struct twolevel_hint { + UNUSED uint32_t + isub_image:8, /* index into the sub images */ + itoc:24; /* index into the table of contents */ +}; +#endif + +/* +* The prebind_cksum_command contains the value of the original check sum for +* prebound files or zero. When a prebound file is first created or modified +* for other than updating its prebinding information the value of the check sum +* is set to zero. When the file has it prebinding re-done and if the value of +* the check sum is zero the original check sum is calculated and stored in +* cksum field of this load command in the output file. If when the prebinding +* is re-done and the cksum field is non-zero it is left unchanged from the +* input file. +*/ +struct prebind_cksum_command { + TYP(cmd,4); /* LC_PREBIND_CKSUM */ + TYP(cmdsize,4); /* sizeof(struct prebind_cksum_command) */ + TYP(cksum,4); /* the check sum or zero */ +}; + +/* +* The uuid load command contains a single 128-bit unique random number that +* identifies an object produced by the static link editor. +*/ +struct uuid_command { + TYP(cmd,4); /* LC_UUID */ + TYP(cmdsize,4); /* sizeof(struct uuid_command) */ + unsigned char uuid[16]; /* the 128-bit uuid */ +}; + +/* +* The rpath_command contains a path which at runtime should be added to +* the current run path used to find @rpath prefixed dylibs. +*/ +struct rpath_command { + TYP(cmd,4); /* LC_RPATH */ + TYP(cmdsize,4); /* includes string */ + union lc_str path; /* path to add to run path */ +}; + +/* +* The linkedit_data_command contains the offsets and sizes of a blob +* of data in the __LINKEDIT segment. +*/ +struct linkedit_data_command { + TYP(cmd,4); /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, + LC_FUNCTION_STARTS, LC_DATA_IN_CODE, + LC_DYLIB_CODE_SIGN_DRS or + LC_LINKER_OPTIMIZATION_HINT. */ + TYP(cmdsize,4); /* sizeof(struct linkedit_data_command) */ + TYP(dataoff,4); /* file offset of data in __LINKEDIT segment */ + TYP(datasize,4); /* file size of data in __LINKEDIT segment */ +}; + +/* +* The encryption_info_command contains the file offset and size of an +* of an encrypted segment. +*/ +struct encryption_info_command { + TYP(cmd,4); /* LC_ENCRYPTION_INFO */ + TYP(cmdsize,4); /* sizeof(struct encryption_info_command) */ + TYP(cryptoff,4); /* file offset of encrypted range */ + TYP(cryptsize,4); /* file size of encrypted range */ + TYP(cryptid,4); /* which enryption system, + 0 means not-encrypted yet */ +}; + +/* +* The encryption_info_command_64 contains the file offset and size of an +* of an encrypted segment (for use in x86_64 targets). +*/ +struct encryption_info_command_64 { + TYP(cmd,4); /* LC_ENCRYPTION_INFO_64 */ + TYP(cmdsize,4); /* sizeof(struct encryption_info_command_64) */ + TYP(cryptoff,4); /* file offset of encrypted range */ + TYP(cryptsize,4); /* file size of encrypted range */ + TYP(cryptid,4); /* which enryption system, + 0 means not-encrypted yet */ + TYP(pad,4); /* padding to make this struct's size a multiple + of 8 bytes */ +}; + +/* +* The version_min_command contains the min OS version on which this +* binary was built to run. +*/ +struct version_min_command { + TYP(cmd,4); /* LC_VERSION_MIN_MACOSX or + LC_VERSION_MIN_IPHONEOS or + LC_VERSION_MIN_WATCHOS or + LC_VERSION_MIN_TVOS */ + TYP(cmdsize,4); /* sizeof(struct min_version_command) */ + TYP(version,4); /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + TYP(sdk,4); /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ +}; + +/* +* The dyld_info_command contains the file offsets and sizes of +* the new compressed form of the information dyld needs to +* load the image. This information is used by dyld on Mac OS X +* 10.6 and later. All information pointed to by this command +* is encoded using byte streams, so no endian swapping is needed +* to interpret it. +*/ +struct dyld_info_command { + TYP(cmd,4); /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ + TYP(cmdsize,4); /* sizeof(struct dyld_info_command) */ + + /* + * Dyld rebases an image whenever dyld loads it at an address different + * from its preferred address. The rebase information is a stream + * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. + * Conceptually the rebase information is a table of tuples: + * + * The opcodes are a compressed way to encode the table by only + * encoding when a column changes. In addition simple patterns + * like "every n'th offset for m times" can be encoded in a few + * bytes. + */ + TYP(rebase_off,4); /* file offset to rebase info */ + TYP(rebase_size,4); /* size of rebase info */ + + /* + * Dyld binds an image during the loading process, if the image + * requires any pointers to be initialized to symbols in other images. + * The bind information is a stream of byte sized + * opcodes whose symbolic names start with BIND_OPCODE_. + * Conceptually the bind information is a table of tuples: + * + * The opcodes are a compressed way to encode the table by only + * encoding when a column changes. In addition simple patterns + * like for runs of pointers initialzed to the same value can be + * encoded in a few bytes. + */ + TYP(bind_off,4); /* file offset to binding info */ + TYP(bind_size,4); /* size of binding info */ + + /* + * Some C++ programs require dyld to unique symbols so that all + * images in the process use the same copy of some code/data. + * This step is done after binding. The content of the weak_bind + * info is an opcode stream like the bind_info. But it is sorted + * alphabetically by symbol name. This enable dyld to walk + * all images with weak binding information in order and look + * for collisions. If there are no collisions, dyld does + * no updating. That means that some fixups are also encoded + * in the bind_info. For instance, all calls to "operator new" + * are first bound to libstdc++.dylib using the information + * in bind_info. Then if some image overrides operator new + * that is detected when the weak_bind information is processed + * and the call to operator new is then rebound. + */ + TYP(weak_bind_off,4); /* file offset to weak binding info */ + TYP(weak_bind_size,4); /* size of weak binding info */ + + /* + * Some uses of external symbols do not need to be bound immediately. + * Instead they can be lazily bound on first use. The lazy_bind + * are contains a stream of BIND opcodes to bind all lazy symbols. + * Normal use is that dyld ignores the lazy_bind section when + * loading an image. Instead the static linker arranged for the + * lazy pointer to initially point to a helper function which + * pushes the offset into the lazy_bind area for the symbol + * needing to be bound, then jumps to dyld which simply adds + * the offset to lazy_bind_off to get the information on what + * to bind. + */ + TYP(lazy_bind_off,4); /* file offset to lazy binding info */ + TYP(lazy_bind_size,4); /* size of lazy binding infs */ + + /* + * The symbols exported by a dylib are encoded in a trie. This + * is a compact representation that factors out common prefixes. + * It also reduces LINKEDIT pages in RAM because it encodes all + * information (name, address, flags) in one small, contiguous range. + * The export area is a stream of nodes. The first node sequentially + * is the start node for the trie. + * + * Nodes for a symbol start with a uleb128 that is the length of + * the exported symbol information for the string so far. + * If there is no exported symbol, the node starts with a zero byte. + * If there is exported info, it follows the length. + * + * First is a uleb128 containing flags. Normally, it is followed by + * a uleb128 encoded offset which is location of the content named + * by the symbol from the mach_header for the image. If the flags + * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is + * a uleb128 encoded library ordinal, then a zero terminated + * UTF8 string. If the string is zero length, then the symbol + * is re-export from the specified dylib with the same name. + * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following + * the flags is two uleb128s: the stub offset and the resolver offset. + * The stub is used by non-lazy pointers. The resolver is used + * by lazy pointers and must be called to get the actual address to use. + * + * After the optional exported symbol information is a byte of + * how many edges (0-255) that this node has leaving it, + * followed by each edge. + * Each edge is a zero terminated UTF8 of the addition chars + * in the symbol, followed by a uleb128 offset for the node that + * edge points to. + * + */ + TYP(export_off,4); /* file offset to lazy binding info */ + TYP(export_size,4); /* size of lazy binding infs */ +}; + +/* +* The following are used to encode rebasing information +*/ +#define REBASE_TYPE_POINTER 1 +#define REBASE_TYPE_TEXT_ABSOLUTE32 2 +#define REBASE_TYPE_TEXT_PCREL32 3 + +#define REBASE_OPCODE_MASK 0xF0 +#define REBASE_IMMEDIATE_MASK 0x0F +#define REBASE_OPCODE_DONE 0x00 +#define REBASE_OPCODE_SET_TYPE_IMM 0x10 +#define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20 +#define REBASE_OPCODE_ADD_ADDR_ULEB 0x30 +#define REBASE_OPCODE_ADD_ADDR_IMM_SCALED 0x40 +#define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50 +#define REBASE_OPCODE_DO_REBASE_ULEB_TIMES 0x60 +#define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB 0x70 +#define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB 0x80 + + +/* +* The following are used to encode binding information +*/ +#define BIND_TYPE_POINTER 1 +#define BIND_TYPE_TEXT_ABSOLUTE32 2 +#define BIND_TYPE_TEXT_PCREL32 3 + +#define BIND_SPECIAL_DYLIB_SELF 0 +#define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1 +#define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 + +#define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 +#define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 0x8 + +#define BIND_OPCODE_MASK 0xF0 +#define BIND_IMMEDIATE_MASK 0x0F +#define BIND_OPCODE_DONE 0x00 +#define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM 0x10 +#define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB 0x20 +#define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30 +#define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40 +#define BIND_OPCODE_SET_TYPE_IMM 0x50 +#define BIND_OPCODE_SET_ADDEND_SLEB 0x60 +#define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 +#define BIND_OPCODE_ADD_ADDR_ULEB 0x80 +#define BIND_OPCODE_DO_BIND 0x90 +#define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB 0xA0 +#define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED 0xB0 +#define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0xC0 + + +/* +* The following are used on the flags byte of a terminal node +* in the export information. +*/ +#define EXPORT_SYMBOL_FLAGS_KIND_MASK 0x03 +#define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00 +#define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL 0x01 +#define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 +#define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 +#define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 + +/* +* The linker_option_command contains linker options embedded in object files. +*/ +struct linker_option_command { + TYP(cmd,4); /* LC_LINKER_OPTION only used in MH_OBJECT filetypes */ + TYP(cmdsize,4); + TYP(count,4); /* number of strings */ + /* concatenation of zero terminated UTF8 strings. + Zero filled at end to align */ +}; + +/* +* The symseg_command contains the offset and size of the GNU style +* symbol table information as described in the header file . +* The symbol roots of the symbol segments must also be aligned properly +* in the file. So the requirement of keeping the offsets aligned to a +* multiple of a 4 bytes translates to the length field of the symbol +* roots also being a multiple of a long. Also the padding must again be +* zeroed. (THIS IS OBSOLETE and no longer supported). +*/ +struct symseg_command { + TYP(cmd,4); /* LC_SYMSEG */ + TYP(cmdsize,4); /* sizeof(struct symseg_command) */ + TYP(offset,4); /* symbol segment offset */ + TYP(size,4); /* symbol segment size in bytes */ +}; + +/* +* The ident_command contains a free format string table following the +* ident_command structure. The strings are null terminated and the size of +* the command is padded out with zero bytes to a multiple of 4 bytes/ +* (THIS IS OBSOLETE and no longer supported). +*/ +struct ident_command { + TYP(cmd,4); /* LC_IDENT */ + TYP(cmdsize,4); /* strings that follow this command */ +}; + +/* +* The fvmfile_command contains a reference to a file to be loaded at the +* specified virtual address. (Presently, this command is reserved for +* internal use. The kernel ignores this command when loading a program into +* memory). +*/ +struct fvmfile_command { + TYP(cmd,4); /* LC_FVMFILE */ + TYP(cmdsize,4); /* includes pathname string */ + union lc_str name; /* files pathname */ + TYP(header_addr,4); /* files virtual address */ +}; + + +/* +* The entry_point_command is a replacement for thread_command. +* It is used for main executables to specify the location (file offset) +* of main(). If -stack_size was used at link time, the stacksize +* field will contain the stack size need for the main thread. +*/ +struct entry_point_command { + TYP(cmd,4); /* LC_MAIN only used in MH_EXECUTE filetypes */ + TYP(cmdsize,4); /* 24 */ + TYP(entryoff,8); /* file (__TEXT) offset of main() */ + TYP(stacksize,8); /* if not zero, initial stack size */ +}; + + +/* +* The source_version_command is an optional load command containing +* the version of the sources used to build the binary. +*/ +struct source_version_command { + TYP(cmd,4); /* LC_SOURCE_VERSION */ + TYP(cmdsize,4); /* 16 */ + TYP(version,8); /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */ +}; + + +/* +* The LC_DATA_IN_CODE load commands uses a linkedit_data_command +* to point to an array of data_in_code_entry entries. Each entry +* describes a range of data in a code section. +*/ +struct data_in_code_entry { + TYP(offset,4); /* from mach_header to start of data range*/ + TYP(length,2); /* number of bytes in data range */ + TYP(kind,2); /* a DICE_KIND_* value */ +}; +#define DICE_KIND_DATA 0x0001 +#define DICE_KIND_JUMP_TABLE8 0x0002 +#define DICE_KIND_JUMP_TABLE16 0x0003 +#define DICE_KIND_JUMP_TABLE32 0x0004 +#define DICE_KIND_ABS_JUMP_TABLE32 0x0005 + + + +/* +* Sections of type S_THREAD_LOCAL_VARIABLES contain an array +* of tlv_descriptor structures. +*/ +struct tlv_descriptor +{ + void* (*thunk)(struct tlv_descriptor*); + unsigned long key; + unsigned long offset; +}; +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* MACHO_LOADER_H */ diff --git a/thirdparty/dwarf/dwarf_machoread.c b/thirdparty/dwarf/dwarf_machoread.c new file mode 100644 index 00000000..b84d706e --- /dev/null +++ b/thirdparty/dwarf/dwarf_machoread.c @@ -0,0 +1,951 @@ +/* +Copyright (c) 2019, David Anderson +All rights reserved. +cc +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This file reads the parts of an Apple mach-o object + file appropriate to reading DWARF debugging data. + Overview: + _dwarf_macho_setup() Does all macho setup. + calls _dwarf_macho_access_init() + calls _dwarf_macho_object_access_internals_init() + Creates internals record 'M', + dwarf_macho_object_access_internals_t + Sets flags/data in internals record + Loads macho object data needed later. + Sets methods struct to access macho object. + calls _dwarf_object_init_b() Creates Dwarf_Debug, independent + of any macho code. + Sets internals record into dbg. + ---------------------- + _dwarf_destruct_macho_access(). This frees + the macho internals record created in + _dwarf_macho_object_access_internals_init() + in case of errors during setup or when + dwarf_finish() is called. Works safely for + partially or fully set-up macho internals record. + + Other than in _dwarf_macho_setup() the macho code + knows nothing about Dwarf_Debug, and the rest of + libdwarf knows nothing about the content of the + macho internals record. + +*/ + +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif /* _WIN32 */ + +#include "config.h" +#include +#ifdef HAVE_MALLOC_H +#include +#endif /* HAVE_MALLOC_H */ +#include +#include +#include +#include /* open() */ +#include /* open() */ +#include /* open() */ +#include +#ifdef HAVE_UNISTD_H +#include /* lseek read close */ +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#endif /* HAVE_UNISTD_H */ + +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) +#include "stdafx.h" +#endif /* HAVE_STDAFX_H */ + +#include "libdwarf.h" +#include "libdwarfdefs.h" +#include "dwarf_base_types.h" +#include "dwarf_opaque.h" +#include "dwarf_error.h" /* for _dwarf_error() declaration */ +#include "dwarf_reading.h" +#include "memcpy_swap.h" +#include "dwarf_object_read_common.h" +#include "dwarf_machoread.h" +#include "dwarf_object_detector.h" +#include "dwarf_macho_loader.h" + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif /* TYPE */ + +#ifdef WORDS_BIGENDIAN +#define ASNAR(func,t,s) \ + do { \ + unsigned tbyte = sizeof(t) - sizeof(s); \ + t = 0; \ + func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ + } while (0) +#else /* LITTLE ENDIAN */ +#define ASNAR(func,t,s) \ + do { \ + t = 0; \ + func(&t,&s[0],sizeof(s)); \ + } while (0) +#endif /* end LITTLE- BIG-ENDIAN */ + + +/* MACH-O and dwarf section names */ +static struct macho_sect_names_s { + char const *ms_moname; + char const *ms_dwname; +} const SectionNames [] = { + { "", "" }, /* ELF index-0 entry */ + { "__debug_abbrev", ".debug_abbrev" }, + { "__debug_aranges", ".debug_aranges" }, + { "__debug_frame", ".debug_frame" }, + { "__debug_info", ".debug_info" }, + { "__debug_line", ".debug_line" }, + { "__debug_macinfo", ".debug_macinfo" }, + { "__debug_loc", ".debug_loc" }, + { "__debug_pubnames", ".debug_pubnames" }, + { "__debug_pubtypes", ".debug_pubtypes" }, + { "__debug_str", ".debug_str" }, + { "__debug_ranges", ".debug_ranges" }, + { "__debug_macro", ".debug_macro" }, + { "__debug_gdb_scri", ".debug_gdb_scripts" } +}; + +static int +_dwarf_macho_object_access_init( + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + Dwarf_Obj_Access_Interface **binary_interface, + int *localerrnum); + + +static Dwarf_Endianness macho_get_byte_order (void *obj) +{ + dwarf_macho_object_access_internals_t *macho = + (dwarf_macho_object_access_internals_t*)(obj); + return macho->mo_endian; +} + + +static Dwarf_Small macho_get_length_size (void *obj) +{ + dwarf_macho_object_access_internals_t *macho = + (dwarf_macho_object_access_internals_t*)(obj); + return macho->mo_offsetsize/8; +} + + +static Dwarf_Small macho_get_pointer_size (void *obj) +{ + dwarf_macho_object_access_internals_t *macho = + (dwarf_macho_object_access_internals_t*)(obj); + return macho->mo_pointersize/8; +} + + +static Dwarf_Unsigned macho_get_section_count (void *obj) +{ + dwarf_macho_object_access_internals_t *macho = + (dwarf_macho_object_access_internals_t*)(obj); + return macho->mo_dwarf_sectioncount; +} + +static int macho_get_section_info (void *obj, + Dwarf_Half section_index, + Dwarf_Obj_Access_Section *return_section, + UNUSEDARG int *error) +{ + dwarf_macho_object_access_internals_t *macho = + (dwarf_macho_object_access_internals_t*)(obj); + + + if (section_index < macho->mo_dwarf_sectioncount) { + struct generic_macho_section *sp = 0; + + sp = macho->mo_dwarf_sections + section_index; + return_section->addr = 0; + return_section->type = 0; + return_section->size = sp->size; + return_section->name = sp->dwarfsectname; + return_section->link = 0; + return_section->info = 0; + return_section->entrysize = 0; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +static int +macho_load_section (void *obj, Dwarf_Half section_index, + Dwarf_Small **return_data, int *error) +{ + dwarf_macho_object_access_internals_t *macho = + (dwarf_macho_object_access_internals_t*)(obj); + + if (0 < section_index && + section_index < macho->mo_dwarf_sectioncount) { + int res = 0; + + struct generic_macho_section *sp = + macho->mo_dwarf_sections + section_index; + if(sp->loaded_data) { + *return_data = sp->loaded_data; + return DW_DLV_OK; + } + if (!sp->size) { + return DW_DLV_NO_ENTRY; + } + if ((sp->size + sp->offset) > + macho->mo_filesize) { + *error = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + + sp->loaded_data = malloc((size_t)sp->size); + if (!sp->loaded_data) { + *error = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = RRMOA(macho->mo_fd, + sp->loaded_data, (off_t)sp->offset, + (size_t)sp->size, (off_t)macho->mo_filesize, error); + if (res != DW_DLV_OK) { + free(sp->loaded_data); + sp->loaded_data = 0; + return res; + } + *return_data = sp->loaded_data; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +void +_dwarf_destruct_macho_access( + struct Dwarf_Obj_Access_Interface_s *aip) +{ + dwarf_macho_object_access_internals_t *mp = 0; + Dwarf_Unsigned i = 0; + + if(!aip) { + return; + } + mp = (dwarf_macho_object_access_internals_t *)aip->object; + if (mp->mo_destruct_close_fd) { + close(mp->mo_fd); + mp->mo_fd = -1; + } + if (mp->mo_commands){ + free(mp->mo_commands); + mp->mo_commands = 0; + } + if (mp->mo_segment_commands){ + free(mp->mo_segment_commands); + mp->mo_segment_commands = 0; + } + free((char *)mp->mo_path); + if (mp->mo_dwarf_sections) { + struct generic_macho_section *sp = 0; + + sp = mp->mo_dwarf_sections; + for( i=0; i < mp->mo_dwarf_sectioncount; ++i,++sp) { + if (sp->loaded_data) { + free(sp->loaded_data); + sp->loaded_data = 0; + } + } + free(mp->mo_dwarf_sections); + mp->mo_dwarf_sections = 0; + } + free(mp); + free(aip); + return; +} + +/* load_macho_header32(dwarf_macho_object_access_internals_t *mfp)*/ +static int +load_macho_header32(dwarf_macho_object_access_internals_t *mfp, int *errcode) +{ + struct mach_header mh32; + int res = 0; + + if (sizeof(mh32) > mfp->mo_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + res = RRMOA(mfp->mo_fd, &mh32, 0, sizeof(mh32), + (off_t)mfp->mo_filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + /* Do not adjust endianness of magic, leave as-is. */ + ASNAR(memcpy,mfp->mo_header.magic,mh32.magic); + ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh32.cputype); + ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype,mh32.cpusubtype); + ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh32.filetype); + ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh32.ncmds); + ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds,mh32.sizeofcmds); + ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh32.flags); + mfp->mo_header.reserved = 0; + mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds; + mfp->mo_command_start_offset = sizeof(mh32); + return DW_DLV_OK; +} + +/* load_macho_header64(dwarf_macho_object_access_internals_t *mfp) */ +static int +load_macho_header64(dwarf_macho_object_access_internals_t *mfp, + int *errcode) +{ + struct mach_header_64 mh64; + int res = 0; + + if (sizeof(mh64) > mfp->mo_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + res = RRMOA(mfp->mo_fd, &mh64, 0, sizeof(mh64), + (off_t)mfp->mo_filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + /* Do not adjust endianness of magic, leave as-is. */ + ASNAR(memcpy,mfp->mo_header.magic,mh64.magic); + ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh64.cputype); + ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype,mh64.cpusubtype); + ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh64.filetype); + ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh64.ncmds); + ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds,mh64.sizeofcmds); + ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh64.flags); + ASNAR(mfp->mo_copy_word,mfp->mo_header.reserved,mh64.reserved); + mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds; + mfp->mo_command_start_offset = sizeof(mh64); + return DW_DLV_OK; +} + +int +dwarf_load_macho_header(dwarf_macho_object_access_internals_t *mfp, + int *errcode) +{ + int res = 0; + + if (mfp->mo_offsetsize == 32) { + res = load_macho_header32(mfp,errcode); + } else if (mfp->mo_offsetsize == 64) { + res = load_macho_header64(mfp,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + return res; +} + + +static int +load_segment_command_content32( + dwarf_macho_object_access_internals_t *mfp, + struct generic_macho_command *mmp, + struct generic_macho_segment_command *msp, + Dwarf_Unsigned mmpindex, + int *errcode) +{ + struct segment_command sc; + int res = 0; + Dwarf_Unsigned filesize = mfp->mo_filesize; + Dwarf_Unsigned segoffset = mmp->offset_this_command; + Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc); + + if (mmp->offset_this_command > filesize || + mmp->cmdsize > filesize || + (mmp->cmdsize + mmp->offset_this_command) > filesize ) { + *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; + return DW_DLV_ERROR; + } + res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc), + (off_t)filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd); + ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize); + strncpy(msp->segname,sc.segname,16); + msp->segname[15] =0; + ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr); + ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize); + ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff); + ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize); + if (msp->fileoff > mfp->mo_filesize || + msp->filesize > mfp->mo_filesize) { + /* corrupt */ + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + if ((msp->fileoff+msp->filesize ) > filesize) { + /* corrupt */ + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot); + ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot); + ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects); + ASNAR(mfp->mo_copy_word,msp->flags,sc.flags); + msp->macho_command_index = mmpindex; + msp->sectionsoffset = afterseghdr; + return DW_DLV_OK; +} +static int +load_segment_command_content64( + dwarf_macho_object_access_internals_t *mfp, + struct generic_macho_command *mmp, + struct generic_macho_segment_command *msp, + Dwarf_Unsigned mmpindex,int *errcode) +{ + struct segment_command_64 sc; + int res = 0; + Dwarf_Unsigned filesize = mfp->mo_filesize; + Dwarf_Unsigned segoffset = mmp->offset_this_command; + Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc); + + if (mmp->offset_this_command > filesize || + mmp->cmdsize > filesize || + (mmp->cmdsize + mmp->offset_this_command) > filesize ) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc), + (off_t)filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd); + ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize); + strncpy(msp->segname,sc.segname,16); + msp->segname[16] =0; + ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr); + ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize); + ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff); + ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize); + if (msp->fileoff > filesize || + msp->filesize > filesize) { + /* corrupt */ + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + if ((msp->fileoff+msp->filesize ) > filesize) { + /* corrupt */ + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot); + ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot); + ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects); + ASNAR(mfp->mo_copy_word,msp->flags,sc.flags); + msp->macho_command_index = mmpindex; + msp->sectionsoffset = afterseghdr; + return DW_DLV_OK; +} + +static int +dwarf_macho_load_segment_commands( + dwarf_macho_object_access_internals_t *mfp,int *errcode) +{ + Dwarf_Unsigned i = 0; + struct generic_macho_command *mmp = 0; + struct generic_macho_segment_command *msp = 0; + + if (mfp->mo_segment_count < 1) { + return DW_DLV_OK; + } + mfp->mo_segment_commands = + (struct generic_macho_segment_command *) + calloc(sizeof(struct generic_macho_segment_command), + (size_t)mfp->mo_segment_count); + if (!mfp->mo_segment_commands) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + + mmp = mfp->mo_commands; + msp = mfp->mo_segment_commands; + for (i = 0 ; i < mfp->mo_command_count; ++i,++mmp) { + unsigned cmd = (unsigned)mmp->cmd; + int res = 0; + + if (cmd == LC_SEGMENT) { + res = load_segment_command_content32(mfp,mmp,msp,i,errcode); + ++msp; + } else if (cmd == LC_SEGMENT_64) { + res = load_segment_command_content64(mfp,mmp,msp,i,errcode); + ++msp; + } + if (res != DW_DLV_OK) { + return res; + } + } + return DW_DLV_OK; +} + +static int +dwarf_macho_load_dwarf_section_details32( + dwarf_macho_object_access_internals_t *mfp, + struct generic_macho_segment_command *segp, + Dwarf_Unsigned segi, int *errcode) +{ + Dwarf_Unsigned seci = 0; + Dwarf_Unsigned seccount = segp->nsects; + Dwarf_Unsigned secalloc = seccount+1; + Dwarf_Unsigned curoff = segp->sectionsoffset; + Dwarf_Unsigned shdrlen = sizeof(struct section); + + struct generic_macho_section *secs = 0; + + secs = (struct generic_macho_section *)calloc( + sizeof(struct generic_macho_section), + (size_t)secalloc); + if (!secs) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_OK; + } + mfp->mo_dwarf_sections = secs; + mfp->mo_dwarf_sectioncount = secalloc; + if ((curoff > mfp->mo_filesize) || + (seccount > mfp->mo_filesize) || + (curoff+(seccount*sizeof(struct section)) > + mfp->mo_filesize)) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + secs->offset_of_sec_rec = curoff; + /* Leave 0 section all zeros except our offset, + elf-like in a sense */ + secs->dwarfsectname = ""; + ++secs; + seci = 1; + for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) { + struct section mosec; + int res = 0; + + res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec), + (off_t)mfp->mo_filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + strncpy(secs->sectname,mosec.sectname,16); + secs->sectname[16] = 0; + strncpy(secs->segname,mosec.segname,16); + secs->segname[16] = 0; + ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr); + ASNAR(mfp->mo_copy_word,secs->size,mosec.size); + ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset); + ASNAR(mfp->mo_copy_word,secs->align,mosec.align); + ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff); + ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc); + ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags); + if (secs->offset > mfp->mo_filesize || + secs->size > mfp->mo_filesize || + (secs->offset+secs->size) > mfp->mo_filesize) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + secs->reserved1 = 0; + secs->reserved2 = 0; + secs->reserved3 = 0; + secs->generic_segment_num = segi; + secs->offset_of_sec_rec = curoff; + } + return DW_DLV_OK; +} +static int +dwarf_macho_load_dwarf_section_details64( + dwarf_macho_object_access_internals_t *mfp, + struct generic_macho_segment_command *segp, + Dwarf_Unsigned segi, + int *errcode) +{ + Dwarf_Unsigned seci = 0; + Dwarf_Unsigned seccount = segp->nsects; + Dwarf_Unsigned secalloc = seccount+1; + Dwarf_Unsigned curoff = segp->sectionsoffset; + Dwarf_Unsigned shdrlen = sizeof(struct section_64); + struct generic_macho_section *secs = 0; + + secs = (struct generic_macho_section *)calloc( + sizeof(struct generic_macho_section), + (size_t)secalloc); + if (!secs) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + mfp->mo_dwarf_sections = secs; + mfp->mo_dwarf_sectioncount = secalloc; + secs->offset_of_sec_rec = curoff; + /* Leave 0 section all zeros except our offset, + elf-like in a sense */ + secs->dwarfsectname = ""; + ++secs; + if ((curoff > mfp->mo_filesize) || + (seccount > mfp->mo_filesize) || + (curoff+(seccount*sizeof(struct section_64)) > + mfp->mo_filesize)) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + seci = 1; + for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) { + int res = 0; + struct section_64 mosec; + + res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec), + (off_t)mfp->mo_filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + strncpy(secs->sectname,mosec.sectname,16); + secs->sectname[16] = 0; + strncpy(secs->segname,mosec.segname,16); + secs->segname[16] = 0; + ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr); + ASNAR(mfp->mo_copy_word,secs->size,mosec.size); + ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset); + ASNAR(mfp->mo_copy_word,secs->align,mosec.align); + ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff); + ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc); + ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags); + if (secs->offset > mfp->mo_filesize || + secs->size > mfp->mo_filesize || + (secs->offset+secs->size) > mfp->mo_filesize) { + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_OK; + } + secs->reserved1 = 0; + secs->reserved2 = 0; + secs->reserved3 = 0; + secs->offset_of_sec_rec = curoff; + secs->generic_segment_num = segi; + } + return DW_DLV_OK; +} + +static int +dwarf_macho_load_dwarf_section_details( + dwarf_macho_object_access_internals_t *mfp, + struct generic_macho_segment_command *segp, + Dwarf_Unsigned segi,int *errcode) +{ + int res = 0; + + if (mfp->mo_offsetsize == 32) { + res = dwarf_macho_load_dwarf_section_details32(mfp, + segp,segi,errcode); + } else if (mfp->mo_offsetsize == 64) { + res = dwarf_macho_load_dwarf_section_details64(mfp, + segp,segi,errcode); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + return res; +} + +static int +dwarf_macho_load_dwarf_sections( + dwarf_macho_object_access_internals_t *mfp,int *errcode) +{ + Dwarf_Unsigned segi = 0; + + struct generic_macho_segment_command *segp = + mfp->mo_segment_commands; + for ( ; segi < mfp->mo_segment_count; ++segi,++segp) { + int res = 0; + + if (strcmp(segp->segname,"__DWARF")) { + continue; + } + /* Found DWARF, for now assume only one such. */ + res = dwarf_macho_load_dwarf_section_details(mfp,segp,segi,errcode); + return res; + } + return DW_DLV_OK; +} + +/* Works the same, 32 or 64 bit */ +int +dwarf_load_macho_commands( + dwarf_macho_object_access_internals_t *mfp,int *errcode) +{ + Dwarf_Unsigned cmdi = 0; + Dwarf_Unsigned curoff = mfp->mo_command_start_offset; + Dwarf_Unsigned cmdspace = 0; + struct load_command mc; + struct generic_macho_command *mcp = 0; + unsigned segment_command_count = 0; + int res = 0; + + if (mfp->mo_command_count >= mfp->mo_filesize) { + /* corrupt object. */ + *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; + return DW_DLV_ERROR; + } + if ((curoff + mfp->mo_command_count * sizeof(mc)) >= + mfp->mo_filesize) { + /* corrupt object. */ + *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD; + return DW_DLV_ERROR; + } + + mfp->mo_commands = (struct generic_macho_command *) calloc( + mfp->mo_command_count,sizeof(struct generic_macho_command)); + if( !mfp->mo_commands) { + /* out of memory */ + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + mcp = mfp->mo_commands; + for ( ; cmdi < mfp->mo_header.ncmds; ++cmdi,++mcp ) { + res = RRMOA(mfp->mo_fd, &mc, (off_t)curoff, sizeof(mc), + (off_t)mfp->mo_filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + ASNAR(mfp->mo_copy_word,mcp->cmd,mc.cmd); + ASNAR(mfp->mo_copy_word,mcp->cmdsize,mc.cmdsize); + mcp->offset_this_command = curoff; + curoff += mcp->cmdsize; + cmdspace += mcp->cmdsize; + if (mcp->cmdsize > mfp->mo_filesize || + curoff > mfp->mo_filesize) { + /* corrupt object */ + *errcode = DW_DLE_FILE_OFFSET_BAD; + return DW_DLV_ERROR; + } + if (mcp->cmd == LC_SEGMENT || mcp->cmd == LC_SEGMENT_64) { + segment_command_count++; + } + } + mfp->mo_segment_count = segment_command_count; + res = dwarf_macho_load_segment_commands(mfp,errcode); + if (res != DW_DLV_OK) { + return res; + } + res = dwarf_macho_load_dwarf_sections(mfp,errcode); + return res; +} +int +_dwarf_macho_setup(int fd, + char *true_path, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error) +{ + Dwarf_Obj_Access_Interface *binary_interface = 0; + dwarf_macho_object_access_internals_t *intfc = 0; + int res = DW_DLV_OK; + int localerrnum = 0; + + res = _dwarf_macho_object_access_init( + fd, + ftype,endian,offsetsize,filesize,access, + &binary_interface, + &localerrnum); + if (res != DW_DLV_OK) { + if (res == DW_DLV_NO_ENTRY) { + return res; + } + _dwarf_error(NULL, error, localerrnum); + return DW_DLV_ERROR; + } + /* allocates and initializes Dwarf_Debug, + generic code */ + res = dwarf_object_init_b(binary_interface, errhand, errarg, + groupnumber, dbg, error); + if (res != DW_DLV_OK){ + _dwarf_destruct_macho_access(binary_interface); + return res; + } + intfc = binary_interface->object; + intfc->mo_path = strdup(true_path); + return res; +} + + +static Dwarf_Obj_Access_Methods const macho_methods = { + macho_get_section_info, + macho_get_byte_order, + macho_get_length_size, + macho_get_pointer_size, + macho_get_section_count, + macho_load_section, + /* We do not do macho relocations. dsym files do not require it. */ + NULL +}; + +/* On any error this frees internals argument. */ +static int +_dwarf_macho_object_access_internals_init( + dwarf_macho_object_access_internals_t * internals, + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + UNUSEDARG Dwarf_Unsigned access, + int *errcode) +{ + dwarf_macho_object_access_internals_t * intfc = internals; + Dwarf_Unsigned i = 0; + struct generic_macho_section *sp = 0; + struct Dwarf_Obj_Access_Interface_s *localdoas; + int res = 0; + + /* Must malloc as _dwarf_destruct_macho_access() + forces that due to other uses. */ + localdoas = (struct Dwarf_Obj_Access_Interface_s *) + malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); + if (!localdoas) { + free(internals); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); + intfc->mo_ident[0] = 'M'; + intfc->mo_ident[1] = '1'; + intfc->mo_fd = fd; + intfc->mo_is_64bit = ((offsetsize==64)?TRUE:FALSE); + intfc->mo_offsetsize = offsetsize; + intfc->mo_pointersize = offsetsize; + intfc->mo_filesize = filesize; + intfc->mo_ftype = ftype; + +#ifdef WORDS_BIGENDIAN + if (endian == DW_ENDIAN_LITTLE ) { + intfc->mo_copy_word = _dwarf_memcpy_swap_bytes; + intfc->mo_endian = DW_OBJECT_LSB; + } else { + intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes; + intfc->mo_endian = DW_OBJECT_MSB; + } +#else /* LITTLE ENDIAN */ + if (endian == DW_ENDIAN_LITTLE ) { + intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes; + intfc->mo_endian = DW_OBJECT_LSB; + } else { + intfc->mo_copy_word = _dwarf_memcpy_swap_bytes; + intfc->mo_endian = DW_OBJECT_MSB; + } +#endif /* LITTLE- BIG-ENDIAN */ + res = dwarf_load_macho_header(intfc,errcode); + if (res != DW_DLV_OK) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_macho_access(localdoas); + return res; + } + /* Load sections */ + res = dwarf_load_macho_commands(intfc,errcode); + if (res != DW_DLV_OK) { + localdoas->methods = 0; + localdoas->object = intfc; + _dwarf_destruct_macho_access(localdoas); + return res; + } + sp = intfc->mo_dwarf_sections+1; + for(i = 1; i < intfc->mo_dwarf_sectioncount ; ++i,++sp) { + int j = 1; + int lim = sizeof(SectionNames)/sizeof(SectionNames[0]); + sp->dwarfsectname = ""; + for( ; j < lim; ++j) { + if(!strcmp(sp->sectname,SectionNames[j].ms_moname)) { + sp->dwarfsectname = SectionNames[j].ms_dwname; + break; + } + } + } + free(localdoas); + return DW_DLV_OK; +} + + +static int +_dwarf_macho_object_access_init( + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + Dwarf_Obj_Access_Interface **binary_interface, + int *localerrnum) +{ + + int res = 0; + dwarf_macho_object_access_internals_t *internals = 0; + Dwarf_Obj_Access_Interface *intfc = 0; + + internals = malloc(sizeof(dwarf_macho_object_access_internals_t)); + if (!internals) { + *localerrnum = DW_DLE_ALLOC_FAIL; + /* Impossible case, we hope. Give up. */ + return DW_DLV_ERROR; + } + memset(internals,0,sizeof(*internals)); + res = _dwarf_macho_object_access_internals_init(internals, + fd, + ftype, endian, offsetsize, filesize, + access, + localerrnum); + if (res != DW_DLV_OK){ + /* *err is already set and the call freed internals. */ + return DW_DLV_ERROR; + } + + intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); + if (!intfc) { + /* Impossible case, we hope. Give up. */ + free(internals); + *localerrnum = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + /* Initialize the interface struct */ + intfc->object = internals; + intfc->methods = &macho_methods; + *binary_interface = intfc; + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/dwarf_machoread.h b/thirdparty/dwarf/dwarf_machoread.h new file mode 100644 index 00000000..6c16d31a --- /dev/null +++ b/thirdparty/dwarf/dwarf_machoread.h @@ -0,0 +1,135 @@ +/* +Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef DWARF_MACHOREAD_H +#define DWARF_MACHOREAD_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct generic_macho_header { + Dwarf_Unsigned magic; + Dwarf_Unsigned cputype; + Dwarf_Unsigned cpusubtype; + Dwarf_Unsigned filetype; + Dwarf_Unsigned ncmds; /* number of load commands */ + Dwarf_Unsigned sizeofcmds; /* the size of all the load commands */ + Dwarf_Unsigned flags; + Dwarf_Unsigned reserved; +}; +struct generic_macho_command { + Dwarf_Unsigned cmd; + Dwarf_Unsigned cmdsize; + Dwarf_Unsigned offset_this_command; +}; + +struct generic_macho_segment_command { + Dwarf_Unsigned cmd; + Dwarf_Unsigned cmdsize; + char segname[24]; + Dwarf_Unsigned vmaddr; + Dwarf_Unsigned vmsize; + Dwarf_Unsigned fileoff; + Dwarf_Unsigned filesize; + Dwarf_Unsigned maxprot; + Dwarf_Unsigned initprot; + Dwarf_Unsigned nsects; + Dwarf_Unsigned flags; + + /* our index into mo_commands */ + Dwarf_Unsigned macho_command_index; + Dwarf_Unsigned sectionsoffset; +}; + +struct generic_macho_section { + /* Larger than in file, room for NUL guaranteed */ + char sectname[24]; + char segname[24]; + const char * dwarfsectname; + Dwarf_Unsigned addr; + Dwarf_Unsigned size; + Dwarf_Unsigned offset; + Dwarf_Unsigned align; + Dwarf_Unsigned reloff; + Dwarf_Unsigned nreloc; + Dwarf_Unsigned flags; + Dwarf_Unsigned reserved1; + Dwarf_Unsigned reserved2; + Dwarf_Unsigned reserved3; + Dwarf_Unsigned generic_segment_num; + Dwarf_Unsigned offset_of_sec_rec; + Dwarf_Small* loaded_data; +}; + + +/* ident[0] == 'M' means this is a macho header. + ident[1] will be 1 indicating version 1. + Other bytes in ident not defined, should be zero. */ +typedef struct dwarf_macho_filedata_s { + char mo_ident[8]; + const char * mo_path; /* libdwarf must free.*/ + int mo_fd; + int mo_destruct_close_fd; /*aka: lib owns fd */ + int mo_is_64bit; + Dwarf_Unsigned mo_filesize; + Dwarf_Small mo_offsetsize; /* 32 or 64 section data */ + Dwarf_Small mo_pointersize; + int mo_ftype; + Dwarf_Endianness mo_endian; + /*Dwarf_Small mo_machine; */ + void (*mo_copy_word) (void *, const void *, unsigned long); + + /* Used to hold 32 and 64 header data */ + struct generic_macho_header mo_header; + + unsigned mo_command_count; + Dwarf_Unsigned mo_command_start_offset; + struct generic_macho_command *mo_commands; + Dwarf_Unsigned mo_offset_after_commands; + + Dwarf_Unsigned mo_segment_count; + struct generic_macho_segment_command *mo_segment_commands; + + Dwarf_Unsigned mo_dwarf_sectioncount; + struct generic_macho_section *mo_dwarf_sections; +} dwarf_macho_object_access_internals_t; + +int dwarf_load_macho_header(dwarf_macho_object_access_internals_t * mfp, + int *errcode); +int dwarf_load_macho_commands(dwarf_macho_object_access_internals_t * mfp, + int *errcode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* DWARF_MACHOREAD_H */ diff --git a/thirdparty/dwarf/dwarf_macro.c b/thirdparty/dwarf/dwarf_macro.c index d320b389..5031c1e3 100644 --- a/thirdparty/dwarf/dwarf_macro.c +++ b/thirdparty/dwarf/dwarf_macro.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -27,12 +26,15 @@ */ #include "config.h" -#include "dwarf_incl.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_macro.h" @@ -86,9 +88,9 @@ dwarf_find_macro_value_start(char *str) */ struct macro_stack_s { Dwarf_Signed *st_base; - long max; - long next_to_use; - int was_fault; + long st_max; + long st_next_to_use; + int st_was_fault; }; static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms); @@ -104,55 +106,55 @@ static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms) { ms->st_base = 0; - ms->max = 0; - ms->next_to_use = 0; - ms->was_fault = 0; + ms->st_max = 0; + ms->st_next_to_use = 0; + ms->st_was_fault = 0; } static int _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx, struct macro_stack_s *ms) { - Dwarf_Signed *newbase; - if (ms->next_to_use >= ms->max) { - long new_size; + if (!ms->st_max || ms->st_next_to_use >= ms->st_max) { + long new_size = ms->st_max; + Dwarf_Signed *newbase = 0; - if (ms->max == 0) { - ms->max = STARTERMAX; + if (!new_size) { + new_size = STARTERMAX; } - new_size = ms->max * 2; + new_size = new_size * 2; newbase = (Dwarf_Signed *)_dwarf_get_alloc(dbg, DW_DLA_STRING, new_size * sizeof(Dwarf_Signed)); - if (newbase == 0) { + if (!newbase) { /* just leave the old array in place */ - ms->was_fault = 1; + ms->st_was_fault = 1; return DW_DLV_ERROR; } if (ms->st_base) { memcpy(newbase, ms->st_base, - ms->next_to_use * sizeof(Dwarf_Signed)); + ms->st_next_to_use * sizeof(Dwarf_Signed)); dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING); } ms->st_base = newbase; - ms->max = new_size; + ms->st_max = new_size; } - ms->st_base[ms->next_to_use] = indx; - ++ms->next_to_use; + ms->st_base[ms->st_next_to_use] = indx; + ++ms->st_next_to_use; return DW_DLV_OK; } static Dwarf_Signed _dwarf_macro_stack_pop_index(struct macro_stack_s *ms) { - if (ms->was_fault) { + if (ms->st_was_fault) { return -1; } - if (ms->next_to_use > 0) { - ms->next_to_use--; - return (ms->st_base[ms->next_to_use]); + if (ms->st_next_to_use > 0) { + ms->st_next_to_use--; + return (ms->st_base[ms->st_next_to_use]); } else { - ms->was_fault = 1; + ms->st_was_fault = 1; } return -1; } @@ -278,7 +280,8 @@ dwarf_get_macro_details(Dwarf_Debug dbg, return (DW_DLV_ERROR); } res = _dwarf_check_string_valid(dbg, - macro_base,pnext,macro_end,error); + macro_base,pnext,macro_end, + DW_DLE_MACINFO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } @@ -343,14 +346,11 @@ dwarf_get_macro_details(Dwarf_Debug dbg, return (DW_DLV_ERROR); } } - if (count == 0) { - free_macro_stack(dbg,&msdata); - _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR); - return (DW_DLV_ERROR); - } + /* ASSERT: The above loop will never let us get here + with count < 1. No need to test for a zero count. - /* We have 'count' array entries to allocate and str_space bytes of - string space to provide for. */ + We have 'count' array entries to allocate and + str_space bytes of string space to provide for. */ string_offset = count * sizeof(Dwarf_Macro_Details); @@ -408,7 +408,8 @@ dwarf_get_macro_details(Dwarf_Debug dbg, return (DW_DLV_ERROR); } res = _dwarf_check_string_valid(dbg, - macro_base,pnext,macro_end,error); + macro_base,pnext,macro_end, + DW_DLE_MACINFO_STRING_BAD,error); if (res != DW_DLV_OK) { return res; } diff --git a/thirdparty/dwarf/dwarf_macro5.c b/thirdparty/dwarf/dwarf_macro5.c index a3a273d8..743546f0 100644 --- a/thirdparty/dwarf/dwarf_macro5.c +++ b/thirdparty/dwarf/dwarf_macro5.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2015-2016 David Anderson. All Rights Reserved. + Copyright (C) 2015-2019 David Anderson. All Rights Reserved. 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 @@ -24,19 +24,18 @@ */ #include "config.h" -#include "dwarf_incl.h" #include #include #ifdef HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ + +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_macro5.h" -# if 0 -#define LEFTPAREN '(' -#define RIGHTPAREN ')' -#define SPACE ' ' -#endif #define TRUE 1 #define FALSE 0 @@ -51,23 +50,6 @@ static const Dwarf_Small dwarf_udata_strp_sup_form[] = {DW_FORM_udata,DW_FORM_st static const Dwarf_Small dwarf_secoffset_form[] = {DW_FORM_sec_offset}; static const Dwarf_Small dwarf_udata_strx_form[] = {DW_FORM_udata,DW_FORM_strx}; -#if 0 -/* We do not presently use this here. It's a view of DW2 macros. */ -struct Dwarf_Macro_Forms_s dw2formsarray[] = { - {0,0,0}, - {DW_MACINFO_define,2,dwarf_udata_string_form}, - {DW_MACINFO_undef,2,dwarf_udata_string_form}, - {DW_MACINFO_start_file,2,dwarf_udata_udata_form}, - {DW_MACINFO_end_file,0,0}, - {DW_MACINFO_vendor_ext,2,dwarf_udata_string_form}, -}; - -/* Represents original DWARF 2,3,4 macro info */ -static const struct Dwarf_Macro_OperationsList_s dwarf_default_macinfo_opslist= { -6, dw2formsarray -}; -#endif - struct Dwarf_Macro_Forms_s dw5formsarray[] = { {0,0,0}, {DW_MACRO_define,2,dwarf_udata_string_form}, @@ -145,7 +127,7 @@ _dwarf_skim_forms(Dwarf_Debug dbg, Dwarf_Unsigned ret_value = 0; Dwarf_Unsigned length; Dwarf_Small *mdata = mdata_start; - Dwarf_Word leb128_length = 0; + Dwarf_Unsigned leb128_length = 0; for( ; i < formcount; ++i) { curform = forms[i]; @@ -164,17 +146,17 @@ _dwarf_skim_forms(Dwarf_Debug dbg, break; case DW_FORM_block2: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - mdata, sizeof(Dwarf_Half), + mdata, DWARF_HALF_SIZE, error,section_end); - v = ret_value + sizeof(Dwarf_Half); + v = ret_value + DWARF_HALF_SIZE; totallen += v; mdata += v; break; case DW_FORM_block4: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - mdata, sizeof(Dwarf_ufixed), + mdata, DWARF_32BIT_SIZE, error,section_end); - v = ret_value + sizeof(Dwarf_ufixed); + v = ret_value + DWARF_32BIT_SIZE; totallen += v; mdata += v; break; @@ -203,10 +185,17 @@ _dwarf_skim_forms(Dwarf_Debug dbg, totallen += v; mdata += v; break; - case DW_FORM_string: + case DW_FORM_string: { + int res = _dwarf_check_string_valid(dbg, + mdata,mdata, section_end, + DW_DLE_MACRO_STRING_BAD,error); + if(res != DW_DLV_OK) { + return res; + } v = strlen((char *) mdata) + 1; totallen += v; mdata += v; + } break; case DW_FORM_block: DECODE_LEB128_UWORD_LEN_CK(mdata,length,leb128_length, @@ -259,7 +248,7 @@ _dwarf_skim_forms(Dwarf_Debug dbg, return DW_DLV_OK; } -#if 0 +#if 0 /* FOR DEBUGGING */ static void dump_bytes(Dwarf_Small * start, long len) { @@ -277,7 +266,23 @@ dump_bytes(Dwarf_Small * start, long len) } printf("\n"); } -#endif +Dwarf_Bool +is_defundef(unsigned op) +{ + switch(op){ + case DW_MACRO_define: + case DW_MACRO_undef: + case DW_MACRO_define_strp: + case DW_MACRO_undef_strp: + case DW_MACRO_define_strx: + case DW_MACRO_undef_strx: + case DW_MACRO_define_sup: + case DW_MACRO_undef_sup: + return TRUE; + } + return FALSE; +} +#endif /* FOR DEBUGGING */ /* On first call (for this macro_context), @@ -318,18 +323,9 @@ _dwarf_get_macro_ops_count_internal(Dwarf_Macro_Context macro_context, while (mdata < section_end) { Dwarf_Small op = 0; - if (mdata >= section_end) { - _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); - return DW_DLV_ERROR; - } op = *mdata; ++opcount; ++mdata; - /* Here so we would set it for the zero op, - though that is kind of redundant since - the curopsentry starts out zero-d. - if (build_ops_array) - curopsentry->mo_opcode = op; */ if (!op) { Dwarf_Unsigned opslen = 0; /* End of ops, this is terminator, count the ending 0 @@ -371,7 +367,9 @@ _dwarf_get_macro_ops_count_internal(Dwarf_Macro_Context macro_context, _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); return DW_DLV_ERROR; } - curopsentry++; + if (build_ops_array) { + curopsentry++; + } } _dwarf_error(dbg, error, DW_DLE_MACRO_PAST_END); return DW_DLV_ERROR; @@ -419,24 +417,6 @@ dwarf_get_macro_op(Dwarf_Macro_Context macro_context, return DW_DLV_OK; } -#if 0 -Dwarf_Bool -is_defundef(unsigned op) -{ - switch(op){ - case DW_MACRO_define: - case DW_MACRO_undef: - case DW_MACRO_define_strp: - case DW_MACRO_undef_strp: - case DW_MACRO_define_strx: - case DW_MACRO_undef_strx: - case DW_MACRO_define_sup: - case DW_MACRO_undef_sup: - return TRUE; - } - return FALSE; -} -#endif /* Here a DW_DLV_NO_ENTRY return means the macro operator is not a def/undef operator. */ @@ -491,7 +471,8 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, dbg, error,endptr); content = (const char *)mdata; res = _dwarf_check_string_valid(dbg, - startptr,mdata, endptr, error); + startptr,mdata, endptr, + DW_DLE_MACRO_STRING_BAD,error); if(res != DW_DLV_OK) { return res; } @@ -515,7 +496,6 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, READ_UNALIGNED_CK(dbg,stringoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); - mdata += macro_context->mc_offset_size; res = _dwarf_extract_local_debug_str_string_given_offset(dbg, form1, stringoffset, @@ -526,8 +506,8 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, *offset = stringoffset; *forms_count = lformscount; if (res == DW_DLV_ERROR) { - return res; *macro_string = ""; + return res; } else if (res == DW_DLV_NO_ENTRY) { *macro_string = ""; } else { @@ -557,6 +537,7 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, /* Redoes the index-getting. Gets offset. */ ress = _dwarf_extract_string_offset_via_str_offsets(dbg, mdata_copy, + endptr, DW_AT_macros, /*arbitrary, unused by called routine. */ form1, macro_context->mc_cu_context, @@ -565,7 +546,7 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, if (ress == DW_DLV_ERROR) { return ress; } - if (res == DW_DLV_OK) { + if (ress == DW_DLV_OK) { char *localstr = 0; *index = stringindex; @@ -603,7 +584,6 @@ dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context, READ_UNALIGNED_CK(dbg,supoffset,Dwarf_Unsigned, mdata,macro_context->mc_offset_size, error,endptr); - mdata += macro_context->mc_offset_size; *line_number = linenum; *index = 0; *offset = supoffset; @@ -1172,7 +1152,7 @@ _dwarf_internal_macro_context(Dwarf_Die die, } lres = _dwarf_internal_get_die_comp_dir(die, &comp_dir, &comp_name,error); - if (resattr == DW_DLV_ERROR) { + if (lres == DW_DLV_ERROR) { Dwarf_Signed i = 0; for (i = 0; i < srcfiles_count; ++i) { if(srcfiles[i]) { @@ -1294,7 +1274,7 @@ _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg, return DW_DLV_ERROR; } - if ((section_base + sizeof(Dwarf_Half) + sizeof(Dwarf_Small)) > section_end ) { + if ((section_base + DWARF_HALF_SIZE + sizeof(Dwarf_Small)) > section_end ) { dealloc_macro_srcfiles(srcfiles,srcfilescount); _dwarf_error(dbg, error, DW_DLE_MACRO_OFFSET_BAD); return DW_DLV_ERROR; @@ -1305,8 +1285,8 @@ _dwarf_internal_macro_context_by_offset(Dwarf_Debug dbg, macro_context->mc_cu_context = cu_context; READ_UNALIGNED_CK(dbg,version, Dwarf_Half, - macro_data,sizeof(Dwarf_Half),error,section_end); - macro_data += sizeof(Dwarf_Half); + macro_data, DWARF_HALF_SIZE,error,section_end); + macro_data += DWARF_HALF_SIZE; READ_UNALIGNED_CK(dbg,flags, Dwarf_Small, macro_data,sizeof(Dwarf_Small),error,section_end); macro_data += sizeof(Dwarf_Small); diff --git a/thirdparty/dwarf/dwarf_macro5.h b/thirdparty/dwarf/dwarf_macro5.h index f9f23035..47b682f2 100644 --- a/thirdparty/dwarf/dwarf_macro5.h +++ b/thirdparty/dwarf/dwarf_macro5.h @@ -62,7 +62,7 @@ struct Dwarf_Macro_Operator_s { /* Could be reordered to be most space efficient. That might be a little harder to read. Hmm. */ struct Dwarf_Macro_Context_s { - Dwarf_Word mc_sentinel; + Dwarf_Unsigned mc_sentinel; Dwarf_Half mc_version_number; /* Section_offset in .debug_macro of macro header */ diff --git a/thirdparty/dwarf/dwarf_names.c b/thirdparty/dwarf/dwarf_names.c new file mode 100644 index 00000000..3da68aa9 --- /dev/null +++ b/thirdparty/dwarf/dwarf_names.c @@ -0,0 +1,3308 @@ +/* Generated routines, do not edit. */ +/* Generated sourcedate 2019-05-29 08:43:30-07:00 */ + +/* BEGIN FILE */ + +#include "dwarf.h" + +#include "libdwarf.h" + +/* ARGSUSED */ +int +dwarf_get_TAG_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_TAG_array_type: + *s_out = "DW_TAG_array_type"; + return DW_DLV_OK; + case DW_TAG_class_type: + *s_out = "DW_TAG_class_type"; + return DW_DLV_OK; + case DW_TAG_entry_point: + *s_out = "DW_TAG_entry_point"; + return DW_DLV_OK; + case DW_TAG_enumeration_type: + *s_out = "DW_TAG_enumeration_type"; + return DW_DLV_OK; + case DW_TAG_formal_parameter: + *s_out = "DW_TAG_formal_parameter"; + return DW_DLV_OK; + case DW_TAG_imported_declaration: + *s_out = "DW_TAG_imported_declaration"; + return DW_DLV_OK; + case DW_TAG_label: + *s_out = "DW_TAG_label"; + return DW_DLV_OK; + case DW_TAG_lexical_block: + *s_out = "DW_TAG_lexical_block"; + return DW_DLV_OK; + case DW_TAG_member: + *s_out = "DW_TAG_member"; + return DW_DLV_OK; + case DW_TAG_pointer_type: + *s_out = "DW_TAG_pointer_type"; + return DW_DLV_OK; + case DW_TAG_reference_type: + *s_out = "DW_TAG_reference_type"; + return DW_DLV_OK; + case DW_TAG_compile_unit: + *s_out = "DW_TAG_compile_unit"; + return DW_DLV_OK; + case DW_TAG_string_type: + *s_out = "DW_TAG_string_type"; + return DW_DLV_OK; + case DW_TAG_structure_type: + *s_out = "DW_TAG_structure_type"; + return DW_DLV_OK; + case DW_TAG_subroutine_type: + *s_out = "DW_TAG_subroutine_type"; + return DW_DLV_OK; + case DW_TAG_typedef: + *s_out = "DW_TAG_typedef"; + return DW_DLV_OK; + case DW_TAG_union_type: + *s_out = "DW_TAG_union_type"; + return DW_DLV_OK; + case DW_TAG_unspecified_parameters: + *s_out = "DW_TAG_unspecified_parameters"; + return DW_DLV_OK; + case DW_TAG_variant: + *s_out = "DW_TAG_variant"; + return DW_DLV_OK; + case DW_TAG_common_block: + *s_out = "DW_TAG_common_block"; + return DW_DLV_OK; + case DW_TAG_common_inclusion: + *s_out = "DW_TAG_common_inclusion"; + return DW_DLV_OK; + case DW_TAG_inheritance: + *s_out = "DW_TAG_inheritance"; + return DW_DLV_OK; + case DW_TAG_inlined_subroutine: + *s_out = "DW_TAG_inlined_subroutine"; + return DW_DLV_OK; + case DW_TAG_module: + *s_out = "DW_TAG_module"; + return DW_DLV_OK; + case DW_TAG_ptr_to_member_type: + *s_out = "DW_TAG_ptr_to_member_type"; + return DW_DLV_OK; + case DW_TAG_set_type: + *s_out = "DW_TAG_set_type"; + return DW_DLV_OK; + case DW_TAG_subrange_type: + *s_out = "DW_TAG_subrange_type"; + return DW_DLV_OK; + case DW_TAG_with_stmt: + *s_out = "DW_TAG_with_stmt"; + return DW_DLV_OK; + case DW_TAG_access_declaration: + *s_out = "DW_TAG_access_declaration"; + return DW_DLV_OK; + case DW_TAG_base_type: + *s_out = "DW_TAG_base_type"; + return DW_DLV_OK; + case DW_TAG_catch_block: + *s_out = "DW_TAG_catch_block"; + return DW_DLV_OK; + case DW_TAG_const_type: + *s_out = "DW_TAG_const_type"; + return DW_DLV_OK; + case DW_TAG_constant: + *s_out = "DW_TAG_constant"; + return DW_DLV_OK; + case DW_TAG_enumerator: + *s_out = "DW_TAG_enumerator"; + return DW_DLV_OK; + case DW_TAG_file_type: + *s_out = "DW_TAG_file_type"; + return DW_DLV_OK; + case DW_TAG_friend: + *s_out = "DW_TAG_friend"; + return DW_DLV_OK; + case DW_TAG_namelist: + *s_out = "DW_TAG_namelist"; + return DW_DLV_OK; + case DW_TAG_namelist_item: + *s_out = "DW_TAG_namelist_item"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2c. DW_TAG_namelist_items */ + case DW_TAG_packed_type: + *s_out = "DW_TAG_packed_type"; + return DW_DLV_OK; + case DW_TAG_subprogram: + *s_out = "DW_TAG_subprogram"; + return DW_DLV_OK; + case DW_TAG_template_type_parameter: + *s_out = "DW_TAG_template_type_parameter"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2f. DW_TAG_template_type_param */ + case DW_TAG_template_value_parameter: + *s_out = "DW_TAG_template_value_parameter"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x30. DW_TAG_template_value_param */ + case DW_TAG_thrown_type: + *s_out = "DW_TAG_thrown_type"; + return DW_DLV_OK; + case DW_TAG_try_block: + *s_out = "DW_TAG_try_block"; + return DW_DLV_OK; + case DW_TAG_variant_part: + *s_out = "DW_TAG_variant_part"; + return DW_DLV_OK; + case DW_TAG_variable: + *s_out = "DW_TAG_variable"; + return DW_DLV_OK; + case DW_TAG_volatile_type: + *s_out = "DW_TAG_volatile_type"; + return DW_DLV_OK; + case DW_TAG_dwarf_procedure: + *s_out = "DW_TAG_dwarf_procedure"; + return DW_DLV_OK; + case DW_TAG_restrict_type: + *s_out = "DW_TAG_restrict_type"; + return DW_DLV_OK; + case DW_TAG_interface_type: + *s_out = "DW_TAG_interface_type"; + return DW_DLV_OK; + case DW_TAG_namespace: + *s_out = "DW_TAG_namespace"; + return DW_DLV_OK; + case DW_TAG_imported_module: + *s_out = "DW_TAG_imported_module"; + return DW_DLV_OK; + case DW_TAG_unspecified_type: + *s_out = "DW_TAG_unspecified_type"; + return DW_DLV_OK; + case DW_TAG_partial_unit: + *s_out = "DW_TAG_partial_unit"; + return DW_DLV_OK; + case DW_TAG_imported_unit: + *s_out = "DW_TAG_imported_unit"; + return DW_DLV_OK; + case DW_TAG_mutable_type: + *s_out = "DW_TAG_mutable_type"; + return DW_DLV_OK; + case DW_TAG_condition: + *s_out = "DW_TAG_condition"; + return DW_DLV_OK; + case DW_TAG_shared_type: + *s_out = "DW_TAG_shared_type"; + return DW_DLV_OK; + case DW_TAG_type_unit: + *s_out = "DW_TAG_type_unit"; + return DW_DLV_OK; + case DW_TAG_rvalue_reference_type: + *s_out = "DW_TAG_rvalue_reference_type"; + return DW_DLV_OK; + case DW_TAG_template_alias: + *s_out = "DW_TAG_template_alias"; + return DW_DLV_OK; + case DW_TAG_coarray_type: + *s_out = "DW_TAG_coarray_type"; + return DW_DLV_OK; + case DW_TAG_generic_subrange: + *s_out = "DW_TAG_generic_subrange"; + return DW_DLV_OK; + case DW_TAG_dynamic_type: + *s_out = "DW_TAG_dynamic_type"; + return DW_DLV_OK; + case DW_TAG_atomic_type: + *s_out = "DW_TAG_atomic_type"; + return DW_DLV_OK; + case DW_TAG_call_site: + *s_out = "DW_TAG_call_site"; + return DW_DLV_OK; + case DW_TAG_call_site_parameter: + *s_out = "DW_TAG_call_site_parameter"; + return DW_DLV_OK; + case DW_TAG_skeleton_unit: + *s_out = "DW_TAG_skeleton_unit"; + return DW_DLV_OK; + case DW_TAG_immutable_type: + *s_out = "DW_TAG_immutable_type"; + return DW_DLV_OK; + case DW_TAG_lo_user: + *s_out = "DW_TAG_lo_user"; + return DW_DLV_OK; + case DW_TAG_MIPS_loop: + *s_out = "DW_TAG_MIPS_loop"; + return DW_DLV_OK; + case DW_TAG_HP_array_descriptor: + *s_out = "DW_TAG_HP_array_descriptor"; + return DW_DLV_OK; + case DW_TAG_format_label: + *s_out = "DW_TAG_format_label"; + return DW_DLV_OK; + case DW_TAG_function_template: + *s_out = "DW_TAG_function_template"; + return DW_DLV_OK; + case DW_TAG_class_template: + *s_out = "DW_TAG_class_template"; + return DW_DLV_OK; + case DW_TAG_GNU_BINCL: + *s_out = "DW_TAG_GNU_BINCL"; + return DW_DLV_OK; + case DW_TAG_GNU_EINCL: + *s_out = "DW_TAG_GNU_EINCL"; + return DW_DLV_OK; + case DW_TAG_GNU_template_template_parameter: + *s_out = "DW_TAG_GNU_template_template_parameter"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x4106. DW_TAG_GNU_template_template_param */ + case DW_TAG_GNU_template_parameter_pack: + *s_out = "DW_TAG_GNU_template_parameter_pack"; + return DW_DLV_OK; + case DW_TAG_GNU_formal_parameter_pack: + *s_out = "DW_TAG_GNU_formal_parameter_pack"; + return DW_DLV_OK; + case DW_TAG_GNU_call_site: + *s_out = "DW_TAG_GNU_call_site"; + return DW_DLV_OK; + case DW_TAG_GNU_call_site_parameter: + *s_out = "DW_TAG_GNU_call_site_parameter"; + return DW_DLV_OK; + case DW_TAG_SUN_function_template: + *s_out = "DW_TAG_SUN_function_template"; + return DW_DLV_OK; + case DW_TAG_SUN_class_template: + *s_out = "DW_TAG_SUN_class_template"; + return DW_DLV_OK; + case DW_TAG_SUN_struct_template: + *s_out = "DW_TAG_SUN_struct_template"; + return DW_DLV_OK; + case DW_TAG_SUN_union_template: + *s_out = "DW_TAG_SUN_union_template"; + return DW_DLV_OK; + case DW_TAG_SUN_indirect_inheritance: + *s_out = "DW_TAG_SUN_indirect_inheritance"; + return DW_DLV_OK; + case DW_TAG_SUN_codeflags: + *s_out = "DW_TAG_SUN_codeflags"; + return DW_DLV_OK; + case DW_TAG_SUN_memop_info: + *s_out = "DW_TAG_SUN_memop_info"; + return DW_DLV_OK; + case DW_TAG_SUN_omp_child_func: + *s_out = "DW_TAG_SUN_omp_child_func"; + return DW_DLV_OK; + case DW_TAG_SUN_rtti_descriptor: + *s_out = "DW_TAG_SUN_rtti_descriptor"; + return DW_DLV_OK; + case DW_TAG_SUN_dtor_info: + *s_out = "DW_TAG_SUN_dtor_info"; + return DW_DLV_OK; + case DW_TAG_SUN_dtor: + *s_out = "DW_TAG_SUN_dtor"; + return DW_DLV_OK; + case DW_TAG_SUN_f90_interface: + *s_out = "DW_TAG_SUN_f90_interface"; + return DW_DLV_OK; + case DW_TAG_SUN_fortran_vax_structure: + *s_out = "DW_TAG_SUN_fortran_vax_structure"; + return DW_DLV_OK; + case DW_TAG_SUN_hi: + *s_out = "DW_TAG_SUN_hi"; + return DW_DLV_OK; + case DW_TAG_ALTIUM_circ_type: + *s_out = "DW_TAG_ALTIUM_circ_type"; + return DW_DLV_OK; + case DW_TAG_ALTIUM_mwa_circ_type: + *s_out = "DW_TAG_ALTIUM_mwa_circ_type"; + return DW_DLV_OK; + case DW_TAG_ALTIUM_rev_carry_type: + *s_out = "DW_TAG_ALTIUM_rev_carry_type"; + return DW_DLV_OK; + case DW_TAG_ALTIUM_rom: + *s_out = "DW_TAG_ALTIUM_rom"; + return DW_DLV_OK; + case DW_TAG_upc_shared_type: + *s_out = "DW_TAG_upc_shared_type"; + return DW_DLV_OK; + case DW_TAG_upc_strict_type: + *s_out = "DW_TAG_upc_strict_type"; + return DW_DLV_OK; + case DW_TAG_upc_relaxed_type: + *s_out = "DW_TAG_upc_relaxed_type"; + return DW_DLV_OK; + case DW_TAG_PGI_kanji_type: + *s_out = "DW_TAG_PGI_kanji_type"; + return DW_DLV_OK; + case DW_TAG_PGI_interface_block: + *s_out = "DW_TAG_PGI_interface_block"; + return DW_DLV_OK; + case DW_TAG_hi_user: + *s_out = "DW_TAG_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_children_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_children_no: + *s_out = "DW_children_no"; + return DW_DLV_OK; + case DW_children_yes: + *s_out = "DW_children_yes"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_FORM_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_FORM_addr: + *s_out = "DW_FORM_addr"; + return DW_DLV_OK; + case DW_FORM_block2: + *s_out = "DW_FORM_block2"; + return DW_DLV_OK; + case DW_FORM_block4: + *s_out = "DW_FORM_block4"; + return DW_DLV_OK; + case DW_FORM_data2: + *s_out = "DW_FORM_data2"; + return DW_DLV_OK; + case DW_FORM_data4: + *s_out = "DW_FORM_data4"; + return DW_DLV_OK; + case DW_FORM_data8: + *s_out = "DW_FORM_data8"; + return DW_DLV_OK; + case DW_FORM_string: + *s_out = "DW_FORM_string"; + return DW_DLV_OK; + case DW_FORM_block: + *s_out = "DW_FORM_block"; + return DW_DLV_OK; + case DW_FORM_block1: + *s_out = "DW_FORM_block1"; + return DW_DLV_OK; + case DW_FORM_data1: + *s_out = "DW_FORM_data1"; + return DW_DLV_OK; + case DW_FORM_flag: + *s_out = "DW_FORM_flag"; + return DW_DLV_OK; + case DW_FORM_sdata: + *s_out = "DW_FORM_sdata"; + return DW_DLV_OK; + case DW_FORM_strp: + *s_out = "DW_FORM_strp"; + return DW_DLV_OK; + case DW_FORM_udata: + *s_out = "DW_FORM_udata"; + return DW_DLV_OK; + case DW_FORM_ref_addr: + *s_out = "DW_FORM_ref_addr"; + return DW_DLV_OK; + case DW_FORM_ref1: + *s_out = "DW_FORM_ref1"; + return DW_DLV_OK; + case DW_FORM_ref2: + *s_out = "DW_FORM_ref2"; + return DW_DLV_OK; + case DW_FORM_ref4: + *s_out = "DW_FORM_ref4"; + return DW_DLV_OK; + case DW_FORM_ref8: + *s_out = "DW_FORM_ref8"; + return DW_DLV_OK; + case DW_FORM_ref_udata: + *s_out = "DW_FORM_ref_udata"; + return DW_DLV_OK; + case DW_FORM_indirect: + *s_out = "DW_FORM_indirect"; + return DW_DLV_OK; + case DW_FORM_sec_offset: + *s_out = "DW_FORM_sec_offset"; + return DW_DLV_OK; + case DW_FORM_exprloc: + *s_out = "DW_FORM_exprloc"; + return DW_DLV_OK; + case DW_FORM_flag_present: + *s_out = "DW_FORM_flag_present"; + return DW_DLV_OK; + case DW_FORM_strx: + *s_out = "DW_FORM_strx"; + return DW_DLV_OK; + case DW_FORM_addrx: + *s_out = "DW_FORM_addrx"; + return DW_DLV_OK; + case DW_FORM_ref_sup4: + *s_out = "DW_FORM_ref_sup4"; + return DW_DLV_OK; + case DW_FORM_strp_sup: + *s_out = "DW_FORM_strp_sup"; + return DW_DLV_OK; + case DW_FORM_data16: + *s_out = "DW_FORM_data16"; + return DW_DLV_OK; + case DW_FORM_line_strp: + *s_out = "DW_FORM_line_strp"; + return DW_DLV_OK; + case DW_FORM_ref_sig8: + *s_out = "DW_FORM_ref_sig8"; + return DW_DLV_OK; + case DW_FORM_implicit_const: + *s_out = "DW_FORM_implicit_const"; + return DW_DLV_OK; + case DW_FORM_loclistx: + *s_out = "DW_FORM_loclistx"; + return DW_DLV_OK; + case DW_FORM_rnglistx: + *s_out = "DW_FORM_rnglistx"; + return DW_DLV_OK; + case DW_FORM_ref_sup8: + *s_out = "DW_FORM_ref_sup8"; + return DW_DLV_OK; + case DW_FORM_strx1: + *s_out = "DW_FORM_strx1"; + return DW_DLV_OK; + case DW_FORM_strx2: + *s_out = "DW_FORM_strx2"; + return DW_DLV_OK; + case DW_FORM_strx3: + *s_out = "DW_FORM_strx3"; + return DW_DLV_OK; + case DW_FORM_strx4: + *s_out = "DW_FORM_strx4"; + return DW_DLV_OK; + case DW_FORM_addrx1: + *s_out = "DW_FORM_addrx1"; + return DW_DLV_OK; + case DW_FORM_addrx2: + *s_out = "DW_FORM_addrx2"; + return DW_DLV_OK; + case DW_FORM_addrx3: + *s_out = "DW_FORM_addrx3"; + return DW_DLV_OK; + case DW_FORM_addrx4: + *s_out = "DW_FORM_addrx4"; + return DW_DLV_OK; + case DW_FORM_GNU_addr_index: + *s_out = "DW_FORM_GNU_addr_index"; + return DW_DLV_OK; + case DW_FORM_GNU_str_index: + *s_out = "DW_FORM_GNU_str_index"; + return DW_DLV_OK; + case DW_FORM_GNU_ref_alt: + *s_out = "DW_FORM_GNU_ref_alt"; + return DW_DLV_OK; + case DW_FORM_GNU_strp_alt: + *s_out = "DW_FORM_GNU_strp_alt"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_AT_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_AT_sibling: + *s_out = "DW_AT_sibling"; + return DW_DLV_OK; + case DW_AT_location: + *s_out = "DW_AT_location"; + return DW_DLV_OK; + case DW_AT_name: + *s_out = "DW_AT_name"; + return DW_DLV_OK; + case DW_AT_ordering: + *s_out = "DW_AT_ordering"; + return DW_DLV_OK; + case DW_AT_subscr_data: + *s_out = "DW_AT_subscr_data"; + return DW_DLV_OK; + case DW_AT_byte_size: + *s_out = "DW_AT_byte_size"; + return DW_DLV_OK; + case DW_AT_bit_offset: + *s_out = "DW_AT_bit_offset"; + return DW_DLV_OK; + case DW_AT_bit_size: + *s_out = "DW_AT_bit_size"; + return DW_DLV_OK; + case DW_AT_element_list: + *s_out = "DW_AT_element_list"; + return DW_DLV_OK; + case DW_AT_stmt_list: + *s_out = "DW_AT_stmt_list"; + return DW_DLV_OK; + case DW_AT_low_pc: + *s_out = "DW_AT_low_pc"; + return DW_DLV_OK; + case DW_AT_high_pc: + *s_out = "DW_AT_high_pc"; + return DW_DLV_OK; + case DW_AT_language: + *s_out = "DW_AT_language"; + return DW_DLV_OK; + case DW_AT_member: + *s_out = "DW_AT_member"; + return DW_DLV_OK; + case DW_AT_discr: + *s_out = "DW_AT_discr"; + return DW_DLV_OK; + case DW_AT_discr_value: + *s_out = "DW_AT_discr_value"; + return DW_DLV_OK; + case DW_AT_visibility: + *s_out = "DW_AT_visibility"; + return DW_DLV_OK; + case DW_AT_import: + *s_out = "DW_AT_import"; + return DW_DLV_OK; + case DW_AT_string_length: + *s_out = "DW_AT_string_length"; + return DW_DLV_OK; + case DW_AT_common_reference: + *s_out = "DW_AT_common_reference"; + return DW_DLV_OK; + case DW_AT_comp_dir: + *s_out = "DW_AT_comp_dir"; + return DW_DLV_OK; + case DW_AT_const_value: + *s_out = "DW_AT_const_value"; + return DW_DLV_OK; + case DW_AT_containing_type: + *s_out = "DW_AT_containing_type"; + return DW_DLV_OK; + case DW_AT_default_value: + *s_out = "DW_AT_default_value"; + return DW_DLV_OK; + case DW_AT_inline: + *s_out = "DW_AT_inline"; + return DW_DLV_OK; + case DW_AT_is_optional: + *s_out = "DW_AT_is_optional"; + return DW_DLV_OK; + case DW_AT_lower_bound: + *s_out = "DW_AT_lower_bound"; + return DW_DLV_OK; + case DW_AT_producer: + *s_out = "DW_AT_producer"; + return DW_DLV_OK; + case DW_AT_prototyped: + *s_out = "DW_AT_prototyped"; + return DW_DLV_OK; + case DW_AT_return_addr: + *s_out = "DW_AT_return_addr"; + return DW_DLV_OK; + case DW_AT_start_scope: + *s_out = "DW_AT_start_scope"; + return DW_DLV_OK; + case DW_AT_bit_stride: + *s_out = "DW_AT_bit_stride"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2e. DW_AT_stride_size */ + case DW_AT_upper_bound: + *s_out = "DW_AT_upper_bound"; + return DW_DLV_OK; + case DW_AT_abstract_origin: + *s_out = "DW_AT_abstract_origin"; + return DW_DLV_OK; + case DW_AT_accessibility: + *s_out = "DW_AT_accessibility"; + return DW_DLV_OK; + case DW_AT_address_class: + *s_out = "DW_AT_address_class"; + return DW_DLV_OK; + case DW_AT_artificial: + *s_out = "DW_AT_artificial"; + return DW_DLV_OK; + case DW_AT_base_types: + *s_out = "DW_AT_base_types"; + return DW_DLV_OK; + case DW_AT_calling_convention: + *s_out = "DW_AT_calling_convention"; + return DW_DLV_OK; + case DW_AT_count: + *s_out = "DW_AT_count"; + return DW_DLV_OK; + case DW_AT_data_member_location: + *s_out = "DW_AT_data_member_location"; + return DW_DLV_OK; + case DW_AT_decl_column: + *s_out = "DW_AT_decl_column"; + return DW_DLV_OK; + case DW_AT_decl_file: + *s_out = "DW_AT_decl_file"; + return DW_DLV_OK; + case DW_AT_decl_line: + *s_out = "DW_AT_decl_line"; + return DW_DLV_OK; + case DW_AT_declaration: + *s_out = "DW_AT_declaration"; + return DW_DLV_OK; + case DW_AT_discr_list: + *s_out = "DW_AT_discr_list"; + return DW_DLV_OK; + case DW_AT_encoding: + *s_out = "DW_AT_encoding"; + return DW_DLV_OK; + case DW_AT_external: + *s_out = "DW_AT_external"; + return DW_DLV_OK; + case DW_AT_frame_base: + *s_out = "DW_AT_frame_base"; + return DW_DLV_OK; + case DW_AT_friend: + *s_out = "DW_AT_friend"; + return DW_DLV_OK; + case DW_AT_identifier_case: + *s_out = "DW_AT_identifier_case"; + return DW_DLV_OK; + case DW_AT_macro_info: + *s_out = "DW_AT_macro_info"; + return DW_DLV_OK; + case DW_AT_namelist_item: + *s_out = "DW_AT_namelist_item"; + return DW_DLV_OK; + case DW_AT_priority: + *s_out = "DW_AT_priority"; + return DW_DLV_OK; + case DW_AT_segment: + *s_out = "DW_AT_segment"; + return DW_DLV_OK; + case DW_AT_specification: + *s_out = "DW_AT_specification"; + return DW_DLV_OK; + case DW_AT_static_link: + *s_out = "DW_AT_static_link"; + return DW_DLV_OK; + case DW_AT_type: + *s_out = "DW_AT_type"; + return DW_DLV_OK; + case DW_AT_use_location: + *s_out = "DW_AT_use_location"; + return DW_DLV_OK; + case DW_AT_variable_parameter: + *s_out = "DW_AT_variable_parameter"; + return DW_DLV_OK; + case DW_AT_virtuality: + *s_out = "DW_AT_virtuality"; + return DW_DLV_OK; + case DW_AT_vtable_elem_location: + *s_out = "DW_AT_vtable_elem_location"; + return DW_DLV_OK; + case DW_AT_allocated: + *s_out = "DW_AT_allocated"; + return DW_DLV_OK; + case DW_AT_associated: + *s_out = "DW_AT_associated"; + return DW_DLV_OK; + case DW_AT_data_location: + *s_out = "DW_AT_data_location"; + return DW_DLV_OK; + case DW_AT_byte_stride: + *s_out = "DW_AT_byte_stride"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x51. DW_AT_stride */ + case DW_AT_entry_pc: + *s_out = "DW_AT_entry_pc"; + return DW_DLV_OK; + case DW_AT_use_UTF8: + *s_out = "DW_AT_use_UTF8"; + return DW_DLV_OK; + case DW_AT_extension: + *s_out = "DW_AT_extension"; + return DW_DLV_OK; + case DW_AT_ranges: + *s_out = "DW_AT_ranges"; + return DW_DLV_OK; + case DW_AT_trampoline: + *s_out = "DW_AT_trampoline"; + return DW_DLV_OK; + case DW_AT_call_column: + *s_out = "DW_AT_call_column"; + return DW_DLV_OK; + case DW_AT_call_file: + *s_out = "DW_AT_call_file"; + return DW_DLV_OK; + case DW_AT_call_line: + *s_out = "DW_AT_call_line"; + return DW_DLV_OK; + case DW_AT_description: + *s_out = "DW_AT_description"; + return DW_DLV_OK; + case DW_AT_binary_scale: + *s_out = "DW_AT_binary_scale"; + return DW_DLV_OK; + case DW_AT_decimal_scale: + *s_out = "DW_AT_decimal_scale"; + return DW_DLV_OK; + case DW_AT_small: + *s_out = "DW_AT_small"; + return DW_DLV_OK; + case DW_AT_decimal_sign: + *s_out = "DW_AT_decimal_sign"; + return DW_DLV_OK; + case DW_AT_digit_count: + *s_out = "DW_AT_digit_count"; + return DW_DLV_OK; + case DW_AT_picture_string: + *s_out = "DW_AT_picture_string"; + return DW_DLV_OK; + case DW_AT_mutable: + *s_out = "DW_AT_mutable"; + return DW_DLV_OK; + case DW_AT_threads_scaled: + *s_out = "DW_AT_threads_scaled"; + return DW_DLV_OK; + case DW_AT_explicit: + *s_out = "DW_AT_explicit"; + return DW_DLV_OK; + case DW_AT_object_pointer: + *s_out = "DW_AT_object_pointer"; + return DW_DLV_OK; + case DW_AT_endianity: + *s_out = "DW_AT_endianity"; + return DW_DLV_OK; + case DW_AT_elemental: + *s_out = "DW_AT_elemental"; + return DW_DLV_OK; + case DW_AT_pure: + *s_out = "DW_AT_pure"; + return DW_DLV_OK; + case DW_AT_recursive: + *s_out = "DW_AT_recursive"; + return DW_DLV_OK; + case DW_AT_signature: + *s_out = "DW_AT_signature"; + return DW_DLV_OK; + case DW_AT_main_subprogram: + *s_out = "DW_AT_main_subprogram"; + return DW_DLV_OK; + case DW_AT_data_bit_offset: + *s_out = "DW_AT_data_bit_offset"; + return DW_DLV_OK; + case DW_AT_const_expr: + *s_out = "DW_AT_const_expr"; + return DW_DLV_OK; + case DW_AT_enum_class: + *s_out = "DW_AT_enum_class"; + return DW_DLV_OK; + case DW_AT_linkage_name: + *s_out = "DW_AT_linkage_name"; + return DW_DLV_OK; + case DW_AT_string_length_bit_size: + *s_out = "DW_AT_string_length_bit_size"; + return DW_DLV_OK; + case DW_AT_string_length_byte_size: + *s_out = "DW_AT_string_length_byte_size"; + return DW_DLV_OK; + case DW_AT_rank: + *s_out = "DW_AT_rank"; + return DW_DLV_OK; + case DW_AT_str_offsets_base: + *s_out = "DW_AT_str_offsets_base"; + return DW_DLV_OK; + case DW_AT_addr_base: + *s_out = "DW_AT_addr_base"; + return DW_DLV_OK; + case DW_AT_rnglists_base: + *s_out = "DW_AT_rnglists_base"; + return DW_DLV_OK; + case DW_AT_dwo_id: + *s_out = "DW_AT_dwo_id"; + return DW_DLV_OK; + case DW_AT_dwo_name: + *s_out = "DW_AT_dwo_name"; + return DW_DLV_OK; + case DW_AT_reference: + *s_out = "DW_AT_reference"; + return DW_DLV_OK; + case DW_AT_rvalue_reference: + *s_out = "DW_AT_rvalue_reference"; + return DW_DLV_OK; + case DW_AT_macros: + *s_out = "DW_AT_macros"; + return DW_DLV_OK; + case DW_AT_call_all_calls: + *s_out = "DW_AT_call_all_calls"; + return DW_DLV_OK; + case DW_AT_call_all_source_calls: + *s_out = "DW_AT_call_all_source_calls"; + return DW_DLV_OK; + case DW_AT_call_all_tail_calls: + *s_out = "DW_AT_call_all_tail_calls"; + return DW_DLV_OK; + case DW_AT_call_return_pc: + *s_out = "DW_AT_call_return_pc"; + return DW_DLV_OK; + case DW_AT_call_value: + *s_out = "DW_AT_call_value"; + return DW_DLV_OK; + case DW_AT_call_origin: + *s_out = "DW_AT_call_origin"; + return DW_DLV_OK; + case DW_AT_call_parameter: + *s_out = "DW_AT_call_parameter"; + return DW_DLV_OK; + case DW_AT_call_pc: + *s_out = "DW_AT_call_pc"; + return DW_DLV_OK; + case DW_AT_call_tail_call: + *s_out = "DW_AT_call_tail_call"; + return DW_DLV_OK; + case DW_AT_call_target: + *s_out = "DW_AT_call_target"; + return DW_DLV_OK; + case DW_AT_call_target_clobbered: + *s_out = "DW_AT_call_target_clobbered"; + return DW_DLV_OK; + case DW_AT_call_data_location: + *s_out = "DW_AT_call_data_location"; + return DW_DLV_OK; + case DW_AT_call_data_value: + *s_out = "DW_AT_call_data_value"; + return DW_DLV_OK; + case DW_AT_noreturn: + *s_out = "DW_AT_noreturn"; + return DW_DLV_OK; + case DW_AT_alignment: + *s_out = "DW_AT_alignment"; + return DW_DLV_OK; + case DW_AT_export_symbols: + *s_out = "DW_AT_export_symbols"; + return DW_DLV_OK; + case DW_AT_deleted: + *s_out = "DW_AT_deleted"; + return DW_DLV_OK; + case DW_AT_defaulted: + *s_out = "DW_AT_defaulted"; + return DW_DLV_OK; + case DW_AT_loclists_base: + *s_out = "DW_AT_loclists_base"; + return DW_DLV_OK; + case DW_AT_HP_block_index: + *s_out = "DW_AT_HP_block_index"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2000. DW_AT_lo_user */ + case DW_AT_MIPS_fde: + *s_out = "DW_AT_MIPS_fde"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2001. DW_AT_HP_unmodifiable */ + /* Skipping alternate spelling of value 0x2001. DW_AT_CPQ_discontig_ranges */ + case DW_AT_MIPS_loop_begin: + *s_out = "DW_AT_MIPS_loop_begin"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2002. DW_AT_CPQ_semantic_events */ + case DW_AT_MIPS_tail_loop_begin: + *s_out = "DW_AT_MIPS_tail_loop_begin"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2003. DW_AT_CPQ_split_lifetimes_var */ + case DW_AT_MIPS_epilog_begin: + *s_out = "DW_AT_MIPS_epilog_begin"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2004. DW_AT_CPQ_split_lifetimes_rtn */ + case DW_AT_MIPS_loop_unroll_factor: + *s_out = "DW_AT_MIPS_loop_unroll_factor"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2005. DW_AT_CPQ_prologue_length */ + case DW_AT_MIPS_software_pipeline_depth: + *s_out = "DW_AT_MIPS_software_pipeline_depth"; + return DW_DLV_OK; + case DW_AT_MIPS_linkage_name: + *s_out = "DW_AT_MIPS_linkage_name"; + return DW_DLV_OK; + case DW_AT_MIPS_stride: + *s_out = "DW_AT_MIPS_stride"; + return DW_DLV_OK; + case DW_AT_MIPS_abstract_name: + *s_out = "DW_AT_MIPS_abstract_name"; + return DW_DLV_OK; + case DW_AT_MIPS_clone_origin: + *s_out = "DW_AT_MIPS_clone_origin"; + return DW_DLV_OK; + case DW_AT_MIPS_has_inlines: + *s_out = "DW_AT_MIPS_has_inlines"; + return DW_DLV_OK; + case DW_AT_MIPS_stride_byte: + *s_out = "DW_AT_MIPS_stride_byte"; + return DW_DLV_OK; + case DW_AT_MIPS_stride_elem: + *s_out = "DW_AT_MIPS_stride_elem"; + return DW_DLV_OK; + case DW_AT_MIPS_ptr_dopetype: + *s_out = "DW_AT_MIPS_ptr_dopetype"; + return DW_DLV_OK; + case DW_AT_MIPS_allocatable_dopetype: + *s_out = "DW_AT_MIPS_allocatable_dopetype"; + return DW_DLV_OK; + case DW_AT_MIPS_assumed_shape_dopetype: + *s_out = "DW_AT_MIPS_assumed_shape_dopetype"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2010. DW_AT_HP_actuals_stmt_list */ + case DW_AT_MIPS_assumed_size: + *s_out = "DW_AT_MIPS_assumed_size"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2011. DW_AT_HP_proc_per_section */ + case DW_AT_HP_raw_data_ptr: + *s_out = "DW_AT_HP_raw_data_ptr"; + return DW_DLV_OK; + case DW_AT_HP_pass_by_reference: + *s_out = "DW_AT_HP_pass_by_reference"; + return DW_DLV_OK; + case DW_AT_HP_opt_level: + *s_out = "DW_AT_HP_opt_level"; + return DW_DLV_OK; + case DW_AT_HP_prof_version_id: + *s_out = "DW_AT_HP_prof_version_id"; + return DW_DLV_OK; + case DW_AT_HP_opt_flags: + *s_out = "DW_AT_HP_opt_flags"; + return DW_DLV_OK; + case DW_AT_HP_cold_region_low_pc: + *s_out = "DW_AT_HP_cold_region_low_pc"; + return DW_DLV_OK; + case DW_AT_HP_cold_region_high_pc: + *s_out = "DW_AT_HP_cold_region_high_pc"; + return DW_DLV_OK; + case DW_AT_HP_all_variables_modifiable: + *s_out = "DW_AT_HP_all_variables_modifiable"; + return DW_DLV_OK; + case DW_AT_HP_linkage_name: + *s_out = "DW_AT_HP_linkage_name"; + return DW_DLV_OK; + case DW_AT_HP_prof_flags: + *s_out = "DW_AT_HP_prof_flags"; + return DW_DLV_OK; + case DW_AT_INTEL_other_endian: + *s_out = "DW_AT_INTEL_other_endian"; + return DW_DLV_OK; + case DW_AT_sf_names: + *s_out = "DW_AT_sf_names"; + return DW_DLV_OK; + case DW_AT_src_info: + *s_out = "DW_AT_src_info"; + return DW_DLV_OK; + case DW_AT_mac_info: + *s_out = "DW_AT_mac_info"; + return DW_DLV_OK; + case DW_AT_src_coords: + *s_out = "DW_AT_src_coords"; + return DW_DLV_OK; + case DW_AT_body_begin: + *s_out = "DW_AT_body_begin"; + return DW_DLV_OK; + case DW_AT_body_end: + *s_out = "DW_AT_body_end"; + return DW_DLV_OK; + case DW_AT_GNU_vector: + *s_out = "DW_AT_GNU_vector"; + return DW_DLV_OK; + case DW_AT_GNU_guarded_by: + *s_out = "DW_AT_GNU_guarded_by"; + return DW_DLV_OK; + case DW_AT_GNU_pt_guarded_by: + *s_out = "DW_AT_GNU_pt_guarded_by"; + return DW_DLV_OK; + case DW_AT_GNU_guarded: + *s_out = "DW_AT_GNU_guarded"; + return DW_DLV_OK; + case DW_AT_GNU_pt_guarded: + *s_out = "DW_AT_GNU_pt_guarded"; + return DW_DLV_OK; + case DW_AT_GNU_locks_excluded: + *s_out = "DW_AT_GNU_locks_excluded"; + return DW_DLV_OK; + case DW_AT_GNU_exclusive_locks_required: + *s_out = "DW_AT_GNU_exclusive_locks_required"; + return DW_DLV_OK; + case DW_AT_GNU_shared_locks_required: + *s_out = "DW_AT_GNU_shared_locks_required"; + return DW_DLV_OK; + case DW_AT_GNU_odr_signature: + *s_out = "DW_AT_GNU_odr_signature"; + return DW_DLV_OK; + case DW_AT_GNU_template_name: + *s_out = "DW_AT_GNU_template_name"; + return DW_DLV_OK; + case DW_AT_GNU_call_site_value: + *s_out = "DW_AT_GNU_call_site_value"; + return DW_DLV_OK; + case DW_AT_GNU_call_site_data_value: + *s_out = "DW_AT_GNU_call_site_data_value"; + return DW_DLV_OK; + case DW_AT_GNU_call_site_target: + *s_out = "DW_AT_GNU_call_site_target"; + return DW_DLV_OK; + case DW_AT_GNU_call_site_target_clobbered: + *s_out = "DW_AT_GNU_call_site_target_clobbered"; + return DW_DLV_OK; + case DW_AT_GNU_tail_call: + *s_out = "DW_AT_GNU_tail_call"; + return DW_DLV_OK; + case DW_AT_GNU_all_tail_call_sites: + *s_out = "DW_AT_GNU_all_tail_call_sites"; + return DW_DLV_OK; + case DW_AT_GNU_all_call_sites: + *s_out = "DW_AT_GNU_all_call_sites"; + return DW_DLV_OK; + case DW_AT_GNU_all_source_call_sites: + *s_out = "DW_AT_GNU_all_source_call_sites"; + return DW_DLV_OK; + case DW_AT_GNU_macros: + *s_out = "DW_AT_GNU_macros"; + return DW_DLV_OK; + case DW_AT_GNU_dwo_name: + *s_out = "DW_AT_GNU_dwo_name"; + return DW_DLV_OK; + case DW_AT_GNU_dwo_id: + *s_out = "DW_AT_GNU_dwo_id"; + return DW_DLV_OK; + case DW_AT_GNU_ranges_base: + *s_out = "DW_AT_GNU_ranges_base"; + return DW_DLV_OK; + case DW_AT_GNU_addr_base: + *s_out = "DW_AT_GNU_addr_base"; + return DW_DLV_OK; + case DW_AT_GNU_pubnames: + *s_out = "DW_AT_GNU_pubnames"; + return DW_DLV_OK; + case DW_AT_GNU_pubtypes: + *s_out = "DW_AT_GNU_pubtypes"; + return DW_DLV_OK; + case DW_AT_GNU_discriminator: + *s_out = "DW_AT_GNU_discriminator"; + return DW_DLV_OK; + case DW_AT_SUN_template: + *s_out = "DW_AT_SUN_template"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x2201. DW_AT_VMS_rtnbeg_pd_address */ + case DW_AT_SUN_alignment: + *s_out = "DW_AT_SUN_alignment"; + return DW_DLV_OK; + case DW_AT_SUN_vtable: + *s_out = "DW_AT_SUN_vtable"; + return DW_DLV_OK; + case DW_AT_SUN_count_guarantee: + *s_out = "DW_AT_SUN_count_guarantee"; + return DW_DLV_OK; + case DW_AT_SUN_command_line: + *s_out = "DW_AT_SUN_command_line"; + return DW_DLV_OK; + case DW_AT_SUN_vbase: + *s_out = "DW_AT_SUN_vbase"; + return DW_DLV_OK; + case DW_AT_SUN_compile_options: + *s_out = "DW_AT_SUN_compile_options"; + return DW_DLV_OK; + case DW_AT_SUN_language: + *s_out = "DW_AT_SUN_language"; + return DW_DLV_OK; + case DW_AT_SUN_browser_file: + *s_out = "DW_AT_SUN_browser_file"; + return DW_DLV_OK; + case DW_AT_SUN_vtable_abi: + *s_out = "DW_AT_SUN_vtable_abi"; + return DW_DLV_OK; + case DW_AT_SUN_func_offsets: + *s_out = "DW_AT_SUN_func_offsets"; + return DW_DLV_OK; + case DW_AT_SUN_cf_kind: + *s_out = "DW_AT_SUN_cf_kind"; + return DW_DLV_OK; + case DW_AT_SUN_vtable_index: + *s_out = "DW_AT_SUN_vtable_index"; + return DW_DLV_OK; + case DW_AT_SUN_omp_tpriv_addr: + *s_out = "DW_AT_SUN_omp_tpriv_addr"; + return DW_DLV_OK; + case DW_AT_SUN_omp_child_func: + *s_out = "DW_AT_SUN_omp_child_func"; + return DW_DLV_OK; + case DW_AT_SUN_func_offset: + *s_out = "DW_AT_SUN_func_offset"; + return DW_DLV_OK; + case DW_AT_SUN_memop_type_ref: + *s_out = "DW_AT_SUN_memop_type_ref"; + return DW_DLV_OK; + case DW_AT_SUN_profile_id: + *s_out = "DW_AT_SUN_profile_id"; + return DW_DLV_OK; + case DW_AT_SUN_memop_signature: + *s_out = "DW_AT_SUN_memop_signature"; + return DW_DLV_OK; + case DW_AT_SUN_obj_dir: + *s_out = "DW_AT_SUN_obj_dir"; + return DW_DLV_OK; + case DW_AT_SUN_obj_file: + *s_out = "DW_AT_SUN_obj_file"; + return DW_DLV_OK; + case DW_AT_SUN_original_name: + *s_out = "DW_AT_SUN_original_name"; + return DW_DLV_OK; + case DW_AT_SUN_hwcprof_signature: + *s_out = "DW_AT_SUN_hwcprof_signature"; + return DW_DLV_OK; + case DW_AT_SUN_amd64_parmdump: + *s_out = "DW_AT_SUN_amd64_parmdump"; + return DW_DLV_OK; + case DW_AT_SUN_part_link_name: + *s_out = "DW_AT_SUN_part_link_name"; + return DW_DLV_OK; + case DW_AT_SUN_link_name: + *s_out = "DW_AT_SUN_link_name"; + return DW_DLV_OK; + case DW_AT_SUN_pass_with_const: + *s_out = "DW_AT_SUN_pass_with_const"; + return DW_DLV_OK; + case DW_AT_SUN_return_with_const: + *s_out = "DW_AT_SUN_return_with_const"; + return DW_DLV_OK; + case DW_AT_SUN_import_by_name: + *s_out = "DW_AT_SUN_import_by_name"; + return DW_DLV_OK; + case DW_AT_SUN_f90_pointer: + *s_out = "DW_AT_SUN_f90_pointer"; + return DW_DLV_OK; + case DW_AT_SUN_pass_by_ref: + *s_out = "DW_AT_SUN_pass_by_ref"; + return DW_DLV_OK; + case DW_AT_SUN_f90_allocatable: + *s_out = "DW_AT_SUN_f90_allocatable"; + return DW_DLV_OK; + case DW_AT_SUN_f90_assumed_shape_array: + *s_out = "DW_AT_SUN_f90_assumed_shape_array"; + return DW_DLV_OK; + case DW_AT_SUN_c_vla: + *s_out = "DW_AT_SUN_c_vla"; + return DW_DLV_OK; + case DW_AT_SUN_return_value_ptr: + *s_out = "DW_AT_SUN_return_value_ptr"; + return DW_DLV_OK; + case DW_AT_SUN_dtor_start: + *s_out = "DW_AT_SUN_dtor_start"; + return DW_DLV_OK; + case DW_AT_SUN_dtor_length: + *s_out = "DW_AT_SUN_dtor_length"; + return DW_DLV_OK; + case DW_AT_SUN_dtor_state_initial: + *s_out = "DW_AT_SUN_dtor_state_initial"; + return DW_DLV_OK; + case DW_AT_SUN_dtor_state_final: + *s_out = "DW_AT_SUN_dtor_state_final"; + return DW_DLV_OK; + case DW_AT_SUN_dtor_state_deltas: + *s_out = "DW_AT_SUN_dtor_state_deltas"; + return DW_DLV_OK; + case DW_AT_SUN_import_by_lname: + *s_out = "DW_AT_SUN_import_by_lname"; + return DW_DLV_OK; + case DW_AT_SUN_f90_use_only: + *s_out = "DW_AT_SUN_f90_use_only"; + return DW_DLV_OK; + case DW_AT_SUN_namelist_spec: + *s_out = "DW_AT_SUN_namelist_spec"; + return DW_DLV_OK; + case DW_AT_SUN_is_omp_child_func: + *s_out = "DW_AT_SUN_is_omp_child_func"; + return DW_DLV_OK; + case DW_AT_SUN_fortran_main_alias: + *s_out = "DW_AT_SUN_fortran_main_alias"; + return DW_DLV_OK; + case DW_AT_SUN_fortran_based: + *s_out = "DW_AT_SUN_fortran_based"; + return DW_DLV_OK; + case DW_AT_ALTIUM_loclist: + *s_out = "DW_AT_ALTIUM_loclist"; + return DW_DLV_OK; + case DW_AT_use_GNAT_descriptive_type: + *s_out = "DW_AT_use_GNAT_descriptive_type"; + return DW_DLV_OK; + case DW_AT_GNAT_descriptive_type: + *s_out = "DW_AT_GNAT_descriptive_type"; + return DW_DLV_OK; + case DW_AT_GNU_numerator: + *s_out = "DW_AT_GNU_numerator"; + return DW_DLV_OK; + case DW_AT_GNU_denominator: + *s_out = "DW_AT_GNU_denominator"; + return DW_DLV_OK; + case DW_AT_GNU_bias: + *s_out = "DW_AT_GNU_bias"; + return DW_DLV_OK; + case DW_AT_go_kind: + *s_out = "DW_AT_go_kind"; + return DW_DLV_OK; + case DW_AT_go_key: + *s_out = "DW_AT_go_key"; + return DW_DLV_OK; + case DW_AT_go_elem: + *s_out = "DW_AT_go_elem"; + return DW_DLV_OK; + case DW_AT_go_embedded_field: + *s_out = "DW_AT_go_embedded_field"; + return DW_DLV_OK; + case DW_AT_go_runtime_type: + *s_out = "DW_AT_go_runtime_type"; + return DW_DLV_OK; + case DW_AT_upc_threads_scaled: + *s_out = "DW_AT_upc_threads_scaled"; + return DW_DLV_OK; + case DW_AT_PGI_lbase: + *s_out = "DW_AT_PGI_lbase"; + return DW_DLV_OK; + case DW_AT_PGI_soffset: + *s_out = "DW_AT_PGI_soffset"; + return DW_DLV_OK; + case DW_AT_PGI_lstride: + *s_out = "DW_AT_PGI_lstride"; + return DW_DLV_OK; + case DW_AT_APPLE_optimized: + *s_out = "DW_AT_APPLE_optimized"; + return DW_DLV_OK; + case DW_AT_APPLE_flags: + *s_out = "DW_AT_APPLE_flags"; + return DW_DLV_OK; + case DW_AT_APPLE_isa: + *s_out = "DW_AT_APPLE_isa"; + return DW_DLV_OK; + case DW_AT_APPLE_block: + *s_out = "DW_AT_APPLE_block"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x3fe4. DW_AT_APPLE_closure */ + case DW_AT_APPLE_major_runtime_vers: + *s_out = "DW_AT_APPLE_major_runtime_vers"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x3fe5. DW_AT_APPLE_major_runtime_vers */ + case DW_AT_APPLE_runtime_class: + *s_out = "DW_AT_APPLE_runtime_class"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x3fe6. DW_AT_APPLE_runtime_class */ + case DW_AT_APPLE_omit_frame_ptr: + *s_out = "DW_AT_APPLE_omit_frame_ptr"; + return DW_DLV_OK; + case DW_AT_hi_user: + *s_out = "DW_AT_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_OP_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_OP_addr: + *s_out = "DW_OP_addr"; + return DW_DLV_OK; + case DW_OP_deref: + *s_out = "DW_OP_deref"; + return DW_DLV_OK; + case DW_OP_const1u: + *s_out = "DW_OP_const1u"; + return DW_DLV_OK; + case DW_OP_const1s: + *s_out = "DW_OP_const1s"; + return DW_DLV_OK; + case DW_OP_const2u: + *s_out = "DW_OP_const2u"; + return DW_DLV_OK; + case DW_OP_const2s: + *s_out = "DW_OP_const2s"; + return DW_DLV_OK; + case DW_OP_const4u: + *s_out = "DW_OP_const4u"; + return DW_DLV_OK; + case DW_OP_const4s: + *s_out = "DW_OP_const4s"; + return DW_DLV_OK; + case DW_OP_const8u: + *s_out = "DW_OP_const8u"; + return DW_DLV_OK; + case DW_OP_const8s: + *s_out = "DW_OP_const8s"; + return DW_DLV_OK; + case DW_OP_constu: + *s_out = "DW_OP_constu"; + return DW_DLV_OK; + case DW_OP_consts: + *s_out = "DW_OP_consts"; + return DW_DLV_OK; + case DW_OP_dup: + *s_out = "DW_OP_dup"; + return DW_DLV_OK; + case DW_OP_drop: + *s_out = "DW_OP_drop"; + return DW_DLV_OK; + case DW_OP_over: + *s_out = "DW_OP_over"; + return DW_DLV_OK; + case DW_OP_pick: + *s_out = "DW_OP_pick"; + return DW_DLV_OK; + case DW_OP_swap: + *s_out = "DW_OP_swap"; + return DW_DLV_OK; + case DW_OP_rot: + *s_out = "DW_OP_rot"; + return DW_DLV_OK; + case DW_OP_xderef: + *s_out = "DW_OP_xderef"; + return DW_DLV_OK; + case DW_OP_abs: + *s_out = "DW_OP_abs"; + return DW_DLV_OK; + case DW_OP_and: + *s_out = "DW_OP_and"; + return DW_DLV_OK; + case DW_OP_div: + *s_out = "DW_OP_div"; + return DW_DLV_OK; + case DW_OP_minus: + *s_out = "DW_OP_minus"; + return DW_DLV_OK; + case DW_OP_mod: + *s_out = "DW_OP_mod"; + return DW_DLV_OK; + case DW_OP_mul: + *s_out = "DW_OP_mul"; + return DW_DLV_OK; + case DW_OP_neg: + *s_out = "DW_OP_neg"; + return DW_DLV_OK; + case DW_OP_not: + *s_out = "DW_OP_not"; + return DW_DLV_OK; + case DW_OP_or: + *s_out = "DW_OP_or"; + return DW_DLV_OK; + case DW_OP_plus: + *s_out = "DW_OP_plus"; + return DW_DLV_OK; + case DW_OP_plus_uconst: + *s_out = "DW_OP_plus_uconst"; + return DW_DLV_OK; + case DW_OP_shl: + *s_out = "DW_OP_shl"; + return DW_DLV_OK; + case DW_OP_shr: + *s_out = "DW_OP_shr"; + return DW_DLV_OK; + case DW_OP_shra: + *s_out = "DW_OP_shra"; + return DW_DLV_OK; + case DW_OP_xor: + *s_out = "DW_OP_xor"; + return DW_DLV_OK; + case DW_OP_bra: + *s_out = "DW_OP_bra"; + return DW_DLV_OK; + case DW_OP_eq: + *s_out = "DW_OP_eq"; + return DW_DLV_OK; + case DW_OP_ge: + *s_out = "DW_OP_ge"; + return DW_DLV_OK; + case DW_OP_gt: + *s_out = "DW_OP_gt"; + return DW_DLV_OK; + case DW_OP_le: + *s_out = "DW_OP_le"; + return DW_DLV_OK; + case DW_OP_lt: + *s_out = "DW_OP_lt"; + return DW_DLV_OK; + case DW_OP_ne: + *s_out = "DW_OP_ne"; + return DW_DLV_OK; + case DW_OP_skip: + *s_out = "DW_OP_skip"; + return DW_DLV_OK; + case DW_OP_lit0: + *s_out = "DW_OP_lit0"; + return DW_DLV_OK; + case DW_OP_lit1: + *s_out = "DW_OP_lit1"; + return DW_DLV_OK; + case DW_OP_lit2: + *s_out = "DW_OP_lit2"; + return DW_DLV_OK; + case DW_OP_lit3: + *s_out = "DW_OP_lit3"; + return DW_DLV_OK; + case DW_OP_lit4: + *s_out = "DW_OP_lit4"; + return DW_DLV_OK; + case DW_OP_lit5: + *s_out = "DW_OP_lit5"; + return DW_DLV_OK; + case DW_OP_lit6: + *s_out = "DW_OP_lit6"; + return DW_DLV_OK; + case DW_OP_lit7: + *s_out = "DW_OP_lit7"; + return DW_DLV_OK; + case DW_OP_lit8: + *s_out = "DW_OP_lit8"; + return DW_DLV_OK; + case DW_OP_lit9: + *s_out = "DW_OP_lit9"; + return DW_DLV_OK; + case DW_OP_lit10: + *s_out = "DW_OP_lit10"; + return DW_DLV_OK; + case DW_OP_lit11: + *s_out = "DW_OP_lit11"; + return DW_DLV_OK; + case DW_OP_lit12: + *s_out = "DW_OP_lit12"; + return DW_DLV_OK; + case DW_OP_lit13: + *s_out = "DW_OP_lit13"; + return DW_DLV_OK; + case DW_OP_lit14: + *s_out = "DW_OP_lit14"; + return DW_DLV_OK; + case DW_OP_lit15: + *s_out = "DW_OP_lit15"; + return DW_DLV_OK; + case DW_OP_lit16: + *s_out = "DW_OP_lit16"; + return DW_DLV_OK; + case DW_OP_lit17: + *s_out = "DW_OP_lit17"; + return DW_DLV_OK; + case DW_OP_lit18: + *s_out = "DW_OP_lit18"; + return DW_DLV_OK; + case DW_OP_lit19: + *s_out = "DW_OP_lit19"; + return DW_DLV_OK; + case DW_OP_lit20: + *s_out = "DW_OP_lit20"; + return DW_DLV_OK; + case DW_OP_lit21: + *s_out = "DW_OP_lit21"; + return DW_DLV_OK; + case DW_OP_lit22: + *s_out = "DW_OP_lit22"; + return DW_DLV_OK; + case DW_OP_lit23: + *s_out = "DW_OP_lit23"; + return DW_DLV_OK; + case DW_OP_lit24: + *s_out = "DW_OP_lit24"; + return DW_DLV_OK; + case DW_OP_lit25: + *s_out = "DW_OP_lit25"; + return DW_DLV_OK; + case DW_OP_lit26: + *s_out = "DW_OP_lit26"; + return DW_DLV_OK; + case DW_OP_lit27: + *s_out = "DW_OP_lit27"; + return DW_DLV_OK; + case DW_OP_lit28: + *s_out = "DW_OP_lit28"; + return DW_DLV_OK; + case DW_OP_lit29: + *s_out = "DW_OP_lit29"; + return DW_DLV_OK; + case DW_OP_lit30: + *s_out = "DW_OP_lit30"; + return DW_DLV_OK; + case DW_OP_lit31: + *s_out = "DW_OP_lit31"; + return DW_DLV_OK; + case DW_OP_reg0: + *s_out = "DW_OP_reg0"; + return DW_DLV_OK; + case DW_OP_reg1: + *s_out = "DW_OP_reg1"; + return DW_DLV_OK; + case DW_OP_reg2: + *s_out = "DW_OP_reg2"; + return DW_DLV_OK; + case DW_OP_reg3: + *s_out = "DW_OP_reg3"; + return DW_DLV_OK; + case DW_OP_reg4: + *s_out = "DW_OP_reg4"; + return DW_DLV_OK; + case DW_OP_reg5: + *s_out = "DW_OP_reg5"; + return DW_DLV_OK; + case DW_OP_reg6: + *s_out = "DW_OP_reg6"; + return DW_DLV_OK; + case DW_OP_reg7: + *s_out = "DW_OP_reg7"; + return DW_DLV_OK; + case DW_OP_reg8: + *s_out = "DW_OP_reg8"; + return DW_DLV_OK; + case DW_OP_reg9: + *s_out = "DW_OP_reg9"; + return DW_DLV_OK; + case DW_OP_reg10: + *s_out = "DW_OP_reg10"; + return DW_DLV_OK; + case DW_OP_reg11: + *s_out = "DW_OP_reg11"; + return DW_DLV_OK; + case DW_OP_reg12: + *s_out = "DW_OP_reg12"; + return DW_DLV_OK; + case DW_OP_reg13: + *s_out = "DW_OP_reg13"; + return DW_DLV_OK; + case DW_OP_reg14: + *s_out = "DW_OP_reg14"; + return DW_DLV_OK; + case DW_OP_reg15: + *s_out = "DW_OP_reg15"; + return DW_DLV_OK; + case DW_OP_reg16: + *s_out = "DW_OP_reg16"; + return DW_DLV_OK; + case DW_OP_reg17: + *s_out = "DW_OP_reg17"; + return DW_DLV_OK; + case DW_OP_reg18: + *s_out = "DW_OP_reg18"; + return DW_DLV_OK; + case DW_OP_reg19: + *s_out = "DW_OP_reg19"; + return DW_DLV_OK; + case DW_OP_reg20: + *s_out = "DW_OP_reg20"; + return DW_DLV_OK; + case DW_OP_reg21: + *s_out = "DW_OP_reg21"; + return DW_DLV_OK; + case DW_OP_reg22: + *s_out = "DW_OP_reg22"; + return DW_DLV_OK; + case DW_OP_reg23: + *s_out = "DW_OP_reg23"; + return DW_DLV_OK; + case DW_OP_reg24: + *s_out = "DW_OP_reg24"; + return DW_DLV_OK; + case DW_OP_reg25: + *s_out = "DW_OP_reg25"; + return DW_DLV_OK; + case DW_OP_reg26: + *s_out = "DW_OP_reg26"; + return DW_DLV_OK; + case DW_OP_reg27: + *s_out = "DW_OP_reg27"; + return DW_DLV_OK; + case DW_OP_reg28: + *s_out = "DW_OP_reg28"; + return DW_DLV_OK; + case DW_OP_reg29: + *s_out = "DW_OP_reg29"; + return DW_DLV_OK; + case DW_OP_reg30: + *s_out = "DW_OP_reg30"; + return DW_DLV_OK; + case DW_OP_reg31: + *s_out = "DW_OP_reg31"; + return DW_DLV_OK; + case DW_OP_breg0: + *s_out = "DW_OP_breg0"; + return DW_DLV_OK; + case DW_OP_breg1: + *s_out = "DW_OP_breg1"; + return DW_DLV_OK; + case DW_OP_breg2: + *s_out = "DW_OP_breg2"; + return DW_DLV_OK; + case DW_OP_breg3: + *s_out = "DW_OP_breg3"; + return DW_DLV_OK; + case DW_OP_breg4: + *s_out = "DW_OP_breg4"; + return DW_DLV_OK; + case DW_OP_breg5: + *s_out = "DW_OP_breg5"; + return DW_DLV_OK; + case DW_OP_breg6: + *s_out = "DW_OP_breg6"; + return DW_DLV_OK; + case DW_OP_breg7: + *s_out = "DW_OP_breg7"; + return DW_DLV_OK; + case DW_OP_breg8: + *s_out = "DW_OP_breg8"; + return DW_DLV_OK; + case DW_OP_breg9: + *s_out = "DW_OP_breg9"; + return DW_DLV_OK; + case DW_OP_breg10: + *s_out = "DW_OP_breg10"; + return DW_DLV_OK; + case DW_OP_breg11: + *s_out = "DW_OP_breg11"; + return DW_DLV_OK; + case DW_OP_breg12: + *s_out = "DW_OP_breg12"; + return DW_DLV_OK; + case DW_OP_breg13: + *s_out = "DW_OP_breg13"; + return DW_DLV_OK; + case DW_OP_breg14: + *s_out = "DW_OP_breg14"; + return DW_DLV_OK; + case DW_OP_breg15: + *s_out = "DW_OP_breg15"; + return DW_DLV_OK; + case DW_OP_breg16: + *s_out = "DW_OP_breg16"; + return DW_DLV_OK; + case DW_OP_breg17: + *s_out = "DW_OP_breg17"; + return DW_DLV_OK; + case DW_OP_breg18: + *s_out = "DW_OP_breg18"; + return DW_DLV_OK; + case DW_OP_breg19: + *s_out = "DW_OP_breg19"; + return DW_DLV_OK; + case DW_OP_breg20: + *s_out = "DW_OP_breg20"; + return DW_DLV_OK; + case DW_OP_breg21: + *s_out = "DW_OP_breg21"; + return DW_DLV_OK; + case DW_OP_breg22: + *s_out = "DW_OP_breg22"; + return DW_DLV_OK; + case DW_OP_breg23: + *s_out = "DW_OP_breg23"; + return DW_DLV_OK; + case DW_OP_breg24: + *s_out = "DW_OP_breg24"; + return DW_DLV_OK; + case DW_OP_breg25: + *s_out = "DW_OP_breg25"; + return DW_DLV_OK; + case DW_OP_breg26: + *s_out = "DW_OP_breg26"; + return DW_DLV_OK; + case DW_OP_breg27: + *s_out = "DW_OP_breg27"; + return DW_DLV_OK; + case DW_OP_breg28: + *s_out = "DW_OP_breg28"; + return DW_DLV_OK; + case DW_OP_breg29: + *s_out = "DW_OP_breg29"; + return DW_DLV_OK; + case DW_OP_breg30: + *s_out = "DW_OP_breg30"; + return DW_DLV_OK; + case DW_OP_breg31: + *s_out = "DW_OP_breg31"; + return DW_DLV_OK; + case DW_OP_regx: + *s_out = "DW_OP_regx"; + return DW_DLV_OK; + case DW_OP_fbreg: + *s_out = "DW_OP_fbreg"; + return DW_DLV_OK; + case DW_OP_bregx: + *s_out = "DW_OP_bregx"; + return DW_DLV_OK; + case DW_OP_piece: + *s_out = "DW_OP_piece"; + return DW_DLV_OK; + case DW_OP_deref_size: + *s_out = "DW_OP_deref_size"; + return DW_DLV_OK; + case DW_OP_xderef_size: + *s_out = "DW_OP_xderef_size"; + return DW_DLV_OK; + case DW_OP_nop: + *s_out = "DW_OP_nop"; + return DW_DLV_OK; + case DW_OP_push_object_address: + *s_out = "DW_OP_push_object_address"; + return DW_DLV_OK; + case DW_OP_call2: + *s_out = "DW_OP_call2"; + return DW_DLV_OK; + case DW_OP_call4: + *s_out = "DW_OP_call4"; + return DW_DLV_OK; + case DW_OP_call_ref: + *s_out = "DW_OP_call_ref"; + return DW_DLV_OK; + case DW_OP_form_tls_address: + *s_out = "DW_OP_form_tls_address"; + return DW_DLV_OK; + case DW_OP_call_frame_cfa: + *s_out = "DW_OP_call_frame_cfa"; + return DW_DLV_OK; + case DW_OP_bit_piece: + *s_out = "DW_OP_bit_piece"; + return DW_DLV_OK; + case DW_OP_implicit_value: + *s_out = "DW_OP_implicit_value"; + return DW_DLV_OK; + case DW_OP_stack_value: + *s_out = "DW_OP_stack_value"; + return DW_DLV_OK; + case DW_OP_implicit_pointer: + *s_out = "DW_OP_implicit_pointer"; + return DW_DLV_OK; + case DW_OP_addrx: + *s_out = "DW_OP_addrx"; + return DW_DLV_OK; + case DW_OP_constx: + *s_out = "DW_OP_constx"; + return DW_DLV_OK; + case DW_OP_entry_value: + *s_out = "DW_OP_entry_value"; + return DW_DLV_OK; + case DW_OP_const_type: + *s_out = "DW_OP_const_type"; + return DW_DLV_OK; + case DW_OP_regval_type: + *s_out = "DW_OP_regval_type"; + return DW_DLV_OK; + case DW_OP_deref_type: + *s_out = "DW_OP_deref_type"; + return DW_DLV_OK; + case DW_OP_xderef_type: + *s_out = "DW_OP_xderef_type"; + return DW_DLV_OK; + case DW_OP_convert: + *s_out = "DW_OP_convert"; + return DW_DLV_OK; + case DW_OP_reinterpret: + *s_out = "DW_OP_reinterpret"; + return DW_DLV_OK; + case DW_OP_GNU_push_tls_address: + *s_out = "DW_OP_GNU_push_tls_address"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0xe0. DW_OP_lo_user */ + /* Skipping alternate spelling of value 0xe0. DW_OP_HP_unknown */ + case DW_OP_HP_is_value: + *s_out = "DW_OP_HP_is_value"; + return DW_DLV_OK; + case DW_OP_HP_fltconst4: + *s_out = "DW_OP_HP_fltconst4"; + return DW_DLV_OK; + case DW_OP_HP_fltconst8: + *s_out = "DW_OP_HP_fltconst8"; + return DW_DLV_OK; + case DW_OP_HP_mod_range: + *s_out = "DW_OP_HP_mod_range"; + return DW_DLV_OK; + case DW_OP_HP_unmod_range: + *s_out = "DW_OP_HP_unmod_range"; + return DW_DLV_OK; + case DW_OP_HP_tls: + *s_out = "DW_OP_HP_tls"; + return DW_DLV_OK; + case DW_OP_INTEL_bit_piece: + *s_out = "DW_OP_INTEL_bit_piece"; + return DW_DLV_OK; + case DW_OP_GNU_uninit: + *s_out = "DW_OP_GNU_uninit"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0xf0. DW_OP_APPLE_uninit */ + case DW_OP_GNU_encoded_addr: + *s_out = "DW_OP_GNU_encoded_addr"; + return DW_DLV_OK; + case DW_OP_GNU_implicit_pointer: + *s_out = "DW_OP_GNU_implicit_pointer"; + return DW_DLV_OK; + case DW_OP_GNU_entry_value: + *s_out = "DW_OP_GNU_entry_value"; + return DW_DLV_OK; + case DW_OP_GNU_const_type: + *s_out = "DW_OP_GNU_const_type"; + return DW_DLV_OK; + case DW_OP_GNU_regval_type: + *s_out = "DW_OP_GNU_regval_type"; + return DW_DLV_OK; + case DW_OP_GNU_deref_type: + *s_out = "DW_OP_GNU_deref_type"; + return DW_DLV_OK; + case DW_OP_GNU_convert: + *s_out = "DW_OP_GNU_convert"; + return DW_DLV_OK; + case DW_OP_PGI_omp_thread_num: + *s_out = "DW_OP_PGI_omp_thread_num"; + return DW_DLV_OK; + case DW_OP_GNU_reinterpret: + *s_out = "DW_OP_GNU_reinterpret"; + return DW_DLV_OK; + case DW_OP_GNU_parameter_ref: + *s_out = "DW_OP_GNU_parameter_ref"; + return DW_DLV_OK; + case DW_OP_GNU_addr_index: + *s_out = "DW_OP_GNU_addr_index"; + return DW_DLV_OK; + case DW_OP_GNU_const_index: + *s_out = "DW_OP_GNU_const_index"; + return DW_DLV_OK; + case DW_OP_hi_user: + *s_out = "DW_OP_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ATE_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ATE_address: + *s_out = "DW_ATE_address"; + return DW_DLV_OK; + case DW_ATE_boolean: + *s_out = "DW_ATE_boolean"; + return DW_DLV_OK; + case DW_ATE_complex_float: + *s_out = "DW_ATE_complex_float"; + return DW_DLV_OK; + case DW_ATE_float: + *s_out = "DW_ATE_float"; + return DW_DLV_OK; + case DW_ATE_signed: + *s_out = "DW_ATE_signed"; + return DW_DLV_OK; + case DW_ATE_signed_char: + *s_out = "DW_ATE_signed_char"; + return DW_DLV_OK; + case DW_ATE_unsigned: + *s_out = "DW_ATE_unsigned"; + return DW_DLV_OK; + case DW_ATE_unsigned_char: + *s_out = "DW_ATE_unsigned_char"; + return DW_DLV_OK; + case DW_ATE_imaginary_float: + *s_out = "DW_ATE_imaginary_float"; + return DW_DLV_OK; + case DW_ATE_packed_decimal: + *s_out = "DW_ATE_packed_decimal"; + return DW_DLV_OK; + case DW_ATE_numeric_string: + *s_out = "DW_ATE_numeric_string"; + return DW_DLV_OK; + case DW_ATE_edited: + *s_out = "DW_ATE_edited"; + return DW_DLV_OK; + case DW_ATE_signed_fixed: + *s_out = "DW_ATE_signed_fixed"; + return DW_DLV_OK; + case DW_ATE_unsigned_fixed: + *s_out = "DW_ATE_unsigned_fixed"; + return DW_DLV_OK; + case DW_ATE_decimal_float: + *s_out = "DW_ATE_decimal_float"; + return DW_DLV_OK; + case DW_ATE_UTF: + *s_out = "DW_ATE_UTF"; + return DW_DLV_OK; + case DW_ATE_UCS: + *s_out = "DW_ATE_UCS"; + return DW_DLV_OK; + case DW_ATE_ASCII: + *s_out = "DW_ATE_ASCII"; + return DW_DLV_OK; + case DW_ATE_ALTIUM_fract: + *s_out = "DW_ATE_ALTIUM_fract"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x80. DW_ATE_lo_user */ + /* Skipping alternate spelling of value 0x80. DW_ATE_HP_float80 */ + case DW_ATE_ALTIUM_accum: + *s_out = "DW_ATE_ALTIUM_accum"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x81. DW_ATE_HP_complex_float80 */ + case DW_ATE_HP_float128: + *s_out = "DW_ATE_HP_float128"; + return DW_DLV_OK; + case DW_ATE_HP_complex_float128: + *s_out = "DW_ATE_HP_complex_float128"; + return DW_DLV_OK; + case DW_ATE_HP_floathpintel: + *s_out = "DW_ATE_HP_floathpintel"; + return DW_DLV_OK; + case DW_ATE_HP_imaginary_float80: + *s_out = "DW_ATE_HP_imaginary_float80"; + return DW_DLV_OK; + case DW_ATE_HP_imaginary_float128: + *s_out = "DW_ATE_HP_imaginary_float128"; + return DW_DLV_OK; + case DW_ATE_SUN_interval_float: + *s_out = "DW_ATE_SUN_interval_float"; + return DW_DLV_OK; + case DW_ATE_SUN_imaginary_float: + *s_out = "DW_ATE_SUN_imaginary_float"; + return DW_DLV_OK; + case DW_ATE_hi_user: + *s_out = "DW_ATE_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_DEFAULTED_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_DEFAULTED_no: + *s_out = "DW_DEFAULTED_no"; + return DW_DLV_OK; + case DW_DEFAULTED_in_class: + *s_out = "DW_DEFAULTED_in_class"; + return DW_DLV_OK; + case DW_DEFAULTED_out_of_class: + *s_out = "DW_DEFAULTED_out_of_class"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_IDX_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_IDX_compile_unit: + *s_out = "DW_IDX_compile_unit"; + return DW_DLV_OK; + case DW_IDX_type_unit: + *s_out = "DW_IDX_type_unit"; + return DW_DLV_OK; + case DW_IDX_die_offset: + *s_out = "DW_IDX_die_offset"; + return DW_DLV_OK; + case DW_IDX_parent: + *s_out = "DW_IDX_parent"; + return DW_DLV_OK; + case DW_IDX_type_hash: + *s_out = "DW_IDX_type_hash"; + return DW_DLV_OK; + case DW_IDX_hi_user: + *s_out = "DW_IDX_hi_user"; + return DW_DLV_OK; + case DW_IDX_lo_user: + *s_out = "DW_IDX_lo_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_LLEX_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_LLEX_end_of_list_entry: + *s_out = "DW_LLEX_end_of_list_entry"; + return DW_DLV_OK; + case DW_LLEX_base_address_selection_entry: + *s_out = "DW_LLEX_base_address_selection_entry"; + return DW_DLV_OK; + case DW_LLEX_start_end_entry: + *s_out = "DW_LLEX_start_end_entry"; + return DW_DLV_OK; + case DW_LLEX_start_length_entry: + *s_out = "DW_LLEX_start_length_entry"; + return DW_DLV_OK; + case DW_LLEX_offset_pair_entry: + *s_out = "DW_LLEX_offset_pair_entry"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_LLE_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_LLE_end_of_list: + *s_out = "DW_LLE_end_of_list"; + return DW_DLV_OK; + case DW_LLE_base_addressx: + *s_out = "DW_LLE_base_addressx"; + return DW_DLV_OK; + case DW_LLE_startx_endx: + *s_out = "DW_LLE_startx_endx"; + return DW_DLV_OK; + case DW_LLE_startx_length: + *s_out = "DW_LLE_startx_length"; + return DW_DLV_OK; + case DW_LLE_offset_pair: + *s_out = "DW_LLE_offset_pair"; + return DW_DLV_OK; + case DW_LLE_default_location: + *s_out = "DW_LLE_default_location"; + return DW_DLV_OK; + case DW_LLE_base_address: + *s_out = "DW_LLE_base_address"; + return DW_DLV_OK; + case DW_LLE_start_end: + *s_out = "DW_LLE_start_end"; + return DW_DLV_OK; + case DW_LLE_start_length: + *s_out = "DW_LLE_start_length"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_RLE_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_RLE_end_of_list: + *s_out = "DW_RLE_end_of_list"; + return DW_DLV_OK; + case DW_RLE_base_addressx: + *s_out = "DW_RLE_base_addressx"; + return DW_DLV_OK; + case DW_RLE_startx_endx: + *s_out = "DW_RLE_startx_endx"; + return DW_DLV_OK; + case DW_RLE_startx_length: + *s_out = "DW_RLE_startx_length"; + return DW_DLV_OK; + case DW_RLE_offset_pair: + *s_out = "DW_RLE_offset_pair"; + return DW_DLV_OK; + case DW_RLE_base_address: + *s_out = "DW_RLE_base_address"; + return DW_DLV_OK; + case DW_RLE_start_end: + *s_out = "DW_RLE_start_end"; + return DW_DLV_OK; + case DW_RLE_start_length: + *s_out = "DW_RLE_start_length"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_UT_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_UT_compile: + *s_out = "DW_UT_compile"; + return DW_DLV_OK; + case DW_UT_type: + *s_out = "DW_UT_type"; + return DW_DLV_OK; + case DW_UT_partial: + *s_out = "DW_UT_partial"; + return DW_DLV_OK; + case DW_UT_skeleton: + *s_out = "DW_UT_skeleton"; + return DW_DLV_OK; + case DW_UT_split_compile: + *s_out = "DW_UT_split_compile"; + return DW_DLV_OK; + case DW_UT_split_type: + *s_out = "DW_UT_split_type"; + return DW_DLV_OK; + case DW_UT_lo_user: + *s_out = "DW_UT_lo_user"; + return DW_DLV_OK; + case DW_UT_hi_user: + *s_out = "DW_UT_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_SECT_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_SECT_INFO: + *s_out = "DW_SECT_INFO"; + return DW_DLV_OK; + case DW_SECT_TYPES: + *s_out = "DW_SECT_TYPES"; + return DW_DLV_OK; + case DW_SECT_ABBREV: + *s_out = "DW_SECT_ABBREV"; + return DW_DLV_OK; + case DW_SECT_LINE: + *s_out = "DW_SECT_LINE"; + return DW_DLV_OK; + case DW_SECT_LOCLISTS: + *s_out = "DW_SECT_LOCLISTS"; + return DW_DLV_OK; + case DW_SECT_STR_OFFSETS: + *s_out = "DW_SECT_STR_OFFSETS"; + return DW_DLV_OK; + case DW_SECT_MACRO: + *s_out = "DW_SECT_MACRO"; + return DW_DLV_OK; + case DW_SECT_RNGLISTS: + *s_out = "DW_SECT_RNGLISTS"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_DS_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_DS_unsigned: + *s_out = "DW_DS_unsigned"; + return DW_DLV_OK; + case DW_DS_leading_overpunch: + *s_out = "DW_DS_leading_overpunch"; + return DW_DLV_OK; + case DW_DS_trailing_overpunch: + *s_out = "DW_DS_trailing_overpunch"; + return DW_DLV_OK; + case DW_DS_leading_separate: + *s_out = "DW_DS_leading_separate"; + return DW_DLV_OK; + case DW_DS_trailing_separate: + *s_out = "DW_DS_trailing_separate"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_END_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_END_default: + *s_out = "DW_END_default"; + return DW_DLV_OK; + case DW_END_big: + *s_out = "DW_END_big"; + return DW_DLV_OK; + case DW_END_little: + *s_out = "DW_END_little"; + return DW_DLV_OK; + case DW_END_lo_user: + *s_out = "DW_END_lo_user"; + return DW_DLV_OK; + case DW_END_hi_user: + *s_out = "DW_END_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ATCF_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ATCF_lo_user: + *s_out = "DW_ATCF_lo_user"; + return DW_DLV_OK; + case DW_ATCF_SUN_mop_bitfield: + *s_out = "DW_ATCF_SUN_mop_bitfield"; + return DW_DLV_OK; + case DW_ATCF_SUN_mop_spill: + *s_out = "DW_ATCF_SUN_mop_spill"; + return DW_DLV_OK; + case DW_ATCF_SUN_mop_scopy: + *s_out = "DW_ATCF_SUN_mop_scopy"; + return DW_DLV_OK; + case DW_ATCF_SUN_func_start: + *s_out = "DW_ATCF_SUN_func_start"; + return DW_DLV_OK; + case DW_ATCF_SUN_end_ctors: + *s_out = "DW_ATCF_SUN_end_ctors"; + return DW_DLV_OK; + case DW_ATCF_SUN_branch_target: + *s_out = "DW_ATCF_SUN_branch_target"; + return DW_DLV_OK; + case DW_ATCF_SUN_mop_stack_probe: + *s_out = "DW_ATCF_SUN_mop_stack_probe"; + return DW_DLV_OK; + case DW_ATCF_SUN_func_epilog: + *s_out = "DW_ATCF_SUN_func_epilog"; + return DW_DLV_OK; + case DW_ATCF_hi_user: + *s_out = "DW_ATCF_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ACCESS_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ACCESS_public: + *s_out = "DW_ACCESS_public"; + return DW_DLV_OK; + case DW_ACCESS_protected: + *s_out = "DW_ACCESS_protected"; + return DW_DLV_OK; + case DW_ACCESS_private: + *s_out = "DW_ACCESS_private"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_VIS_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_VIS_local: + *s_out = "DW_VIS_local"; + return DW_DLV_OK; + case DW_VIS_exported: + *s_out = "DW_VIS_exported"; + return DW_DLV_OK; + case DW_VIS_qualified: + *s_out = "DW_VIS_qualified"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_VIRTUALITY_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_VIRTUALITY_none: + *s_out = "DW_VIRTUALITY_none"; + return DW_DLV_OK; + case DW_VIRTUALITY_virtual: + *s_out = "DW_VIRTUALITY_virtual"; + return DW_DLV_OK; + case DW_VIRTUALITY_pure_virtual: + *s_out = "DW_VIRTUALITY_pure_virtual"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_LANG_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_LANG_C89: + *s_out = "DW_LANG_C89"; + return DW_DLV_OK; + case DW_LANG_C: + *s_out = "DW_LANG_C"; + return DW_DLV_OK; + case DW_LANG_Ada83: + *s_out = "DW_LANG_Ada83"; + return DW_DLV_OK; + case DW_LANG_C_plus_plus: + *s_out = "DW_LANG_C_plus_plus"; + return DW_DLV_OK; + case DW_LANG_Cobol74: + *s_out = "DW_LANG_Cobol74"; + return DW_DLV_OK; + case DW_LANG_Cobol85: + *s_out = "DW_LANG_Cobol85"; + return DW_DLV_OK; + case DW_LANG_Fortran77: + *s_out = "DW_LANG_Fortran77"; + return DW_DLV_OK; + case DW_LANG_Fortran90: + *s_out = "DW_LANG_Fortran90"; + return DW_DLV_OK; + case DW_LANG_Pascal83: + *s_out = "DW_LANG_Pascal83"; + return DW_DLV_OK; + case DW_LANG_Modula2: + *s_out = "DW_LANG_Modula2"; + return DW_DLV_OK; + case DW_LANG_Java: + *s_out = "DW_LANG_Java"; + return DW_DLV_OK; + case DW_LANG_C99: + *s_out = "DW_LANG_C99"; + return DW_DLV_OK; + case DW_LANG_Ada95: + *s_out = "DW_LANG_Ada95"; + return DW_DLV_OK; + case DW_LANG_Fortran95: + *s_out = "DW_LANG_Fortran95"; + return DW_DLV_OK; + case DW_LANG_PLI: + *s_out = "DW_LANG_PLI"; + return DW_DLV_OK; + case DW_LANG_ObjC: + *s_out = "DW_LANG_ObjC"; + return DW_DLV_OK; + case DW_LANG_ObjC_plus_plus: + *s_out = "DW_LANG_ObjC_plus_plus"; + return DW_DLV_OK; + case DW_LANG_UPC: + *s_out = "DW_LANG_UPC"; + return DW_DLV_OK; + case DW_LANG_D: + *s_out = "DW_LANG_D"; + return DW_DLV_OK; + case DW_LANG_Python: + *s_out = "DW_LANG_Python"; + return DW_DLV_OK; + case DW_LANG_OpenCL: + *s_out = "DW_LANG_OpenCL"; + return DW_DLV_OK; + case DW_LANG_Go: + *s_out = "DW_LANG_Go"; + return DW_DLV_OK; + case DW_LANG_Modula3: + *s_out = "DW_LANG_Modula3"; + return DW_DLV_OK; + case DW_LANG_Haskel: + *s_out = "DW_LANG_Haskel"; + return DW_DLV_OK; + case DW_LANG_C_plus_plus_03: + *s_out = "DW_LANG_C_plus_plus_03"; + return DW_DLV_OK; + case DW_LANG_C_plus_plus_11: + *s_out = "DW_LANG_C_plus_plus_11"; + return DW_DLV_OK; + case DW_LANG_OCaml: + *s_out = "DW_LANG_OCaml"; + return DW_DLV_OK; + case DW_LANG_Rust: + *s_out = "DW_LANG_Rust"; + return DW_DLV_OK; + case DW_LANG_C11: + *s_out = "DW_LANG_C11"; + return DW_DLV_OK; + case DW_LANG_Swift: + *s_out = "DW_LANG_Swift"; + return DW_DLV_OK; + case DW_LANG_Julia: + *s_out = "DW_LANG_Julia"; + return DW_DLV_OK; + case DW_LANG_Dylan: + *s_out = "DW_LANG_Dylan"; + return DW_DLV_OK; + case DW_LANG_C_plus_plus_14: + *s_out = "DW_LANG_C_plus_plus_14"; + return DW_DLV_OK; + case DW_LANG_Fortran03: + *s_out = "DW_LANG_Fortran03"; + return DW_DLV_OK; + case DW_LANG_Fortran08: + *s_out = "DW_LANG_Fortran08"; + return DW_DLV_OK; + case DW_LANG_RenderScript: + *s_out = "DW_LANG_RenderScript"; + return DW_DLV_OK; + case DW_LANG_BLISS: + *s_out = "DW_LANG_BLISS"; + return DW_DLV_OK; + case DW_LANG_lo_user: + *s_out = "DW_LANG_lo_user"; + return DW_DLV_OK; + case DW_LANG_Mips_Assembler: + *s_out = "DW_LANG_Mips_Assembler"; + return DW_DLV_OK; + case DW_LANG_Upc: + *s_out = "DW_LANG_Upc"; + return DW_DLV_OK; + case DW_LANG_SUN_Assembler: + *s_out = "DW_LANG_SUN_Assembler"; + return DW_DLV_OK; + case DW_LANG_ALTIUM_Assembler: + *s_out = "DW_LANG_ALTIUM_Assembler"; + return DW_DLV_OK; + case DW_LANG_hi_user: + *s_out = "DW_LANG_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ID_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ID_case_sensitive: + *s_out = "DW_ID_case_sensitive"; + return DW_DLV_OK; + case DW_ID_up_case: + *s_out = "DW_ID_up_case"; + return DW_DLV_OK; + case DW_ID_down_case: + *s_out = "DW_ID_down_case"; + return DW_DLV_OK; + case DW_ID_case_insensitive: + *s_out = "DW_ID_case_insensitive"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_CC_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_CC_normal: + *s_out = "DW_CC_normal"; + return DW_DLV_OK; + case DW_CC_program: + *s_out = "DW_CC_program"; + return DW_DLV_OK; + case DW_CC_nocall: + *s_out = "DW_CC_nocall"; + return DW_DLV_OK; + case DW_CC_pass_by_reference: + *s_out = "DW_CC_pass_by_reference"; + return DW_DLV_OK; + case DW_CC_pass_by_value: + *s_out = "DW_CC_pass_by_value"; + return DW_DLV_OK; + case DW_CC_lo_user: + *s_out = "DW_CC_lo_user"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x40. DW_CC_GNU_renesas_sh */ + case DW_CC_GNU_borland_fastcall_i386: + *s_out = "DW_CC_GNU_borland_fastcall_i386"; + return DW_DLV_OK; + case DW_CC_ALTIUM_interrupt: + *s_out = "DW_CC_ALTIUM_interrupt"; + return DW_DLV_OK; + case DW_CC_ALTIUM_near_system_stack: + *s_out = "DW_CC_ALTIUM_near_system_stack"; + return DW_DLV_OK; + case DW_CC_ALTIUM_near_user_stack: + *s_out = "DW_CC_ALTIUM_near_user_stack"; + return DW_DLV_OK; + case DW_CC_ALTIUM_huge_user_stack: + *s_out = "DW_CC_ALTIUM_huge_user_stack"; + return DW_DLV_OK; + case DW_CC_hi_user: + *s_out = "DW_CC_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_INL_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_INL_not_inlined: + *s_out = "DW_INL_not_inlined"; + return DW_DLV_OK; + case DW_INL_inlined: + *s_out = "DW_INL_inlined"; + return DW_DLV_OK; + case DW_INL_declared_not_inlined: + *s_out = "DW_INL_declared_not_inlined"; + return DW_DLV_OK; + case DW_INL_declared_inlined: + *s_out = "DW_INL_declared_inlined"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ORD_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ORD_row_major: + *s_out = "DW_ORD_row_major"; + return DW_DLV_OK; + case DW_ORD_col_major: + *s_out = "DW_ORD_col_major"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_DSC_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_DSC_label: + *s_out = "DW_DSC_label"; + return DW_DLV_OK; + case DW_DSC_range: + *s_out = "DW_DSC_range"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_LNCT_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_LNCT_path: + *s_out = "DW_LNCT_path"; + return DW_DLV_OK; + case DW_LNCT_directory_index: + *s_out = "DW_LNCT_directory_index"; + return DW_DLV_OK; + case DW_LNCT_timestamp: + *s_out = "DW_LNCT_timestamp"; + return DW_DLV_OK; + case DW_LNCT_size: + *s_out = "DW_LNCT_size"; + return DW_DLV_OK; + case DW_LNCT_MD5: + *s_out = "DW_LNCT_MD5"; + return DW_DLV_OK; + case DW_LNCT_GNU_subprogram_name: + *s_out = "DW_LNCT_GNU_subprogram_name"; + return DW_DLV_OK; + case DW_LNCT_GNU_decl_file: + *s_out = "DW_LNCT_GNU_decl_file"; + return DW_DLV_OK; + case DW_LNCT_GNU_decl_line: + *s_out = "DW_LNCT_GNU_decl_line"; + return DW_DLV_OK; + case DW_LNCT_lo_user: + *s_out = "DW_LNCT_lo_user"; + return DW_DLV_OK; + case DW_LNCT_hi_user: + *s_out = "DW_LNCT_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_LNS_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_LNS_copy: + *s_out = "DW_LNS_copy"; + return DW_DLV_OK; + case DW_LNS_advance_pc: + *s_out = "DW_LNS_advance_pc"; + return DW_DLV_OK; + case DW_LNS_advance_line: + *s_out = "DW_LNS_advance_line"; + return DW_DLV_OK; + case DW_LNS_set_file: + *s_out = "DW_LNS_set_file"; + return DW_DLV_OK; + case DW_LNS_set_column: + *s_out = "DW_LNS_set_column"; + return DW_DLV_OK; + case DW_LNS_negate_stmt: + *s_out = "DW_LNS_negate_stmt"; + return DW_DLV_OK; + case DW_LNS_set_basic_block: + *s_out = "DW_LNS_set_basic_block"; + return DW_DLV_OK; + case DW_LNS_const_add_pc: + *s_out = "DW_LNS_const_add_pc"; + return DW_DLV_OK; + case DW_LNS_fixed_advance_pc: + *s_out = "DW_LNS_fixed_advance_pc"; + return DW_DLV_OK; + case DW_LNS_set_prologue_end: + *s_out = "DW_LNS_set_prologue_end"; + return DW_DLV_OK; + case DW_LNS_set_epilogue_begin: + *s_out = "DW_LNS_set_epilogue_begin"; + return DW_DLV_OK; + case DW_LNS_set_isa: + *s_out = "DW_LNS_set_isa"; + return DW_DLV_OK; + case DW_LNS_set_address_from_logical: + *s_out = "DW_LNS_set_address_from_logical"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0xd. DW_LNS_set_subprogram */ + case DW_LNS_inlined_call: + *s_out = "DW_LNS_inlined_call"; + return DW_DLV_OK; + case DW_LNS_pop_context: + *s_out = "DW_LNS_pop_context"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_LNE_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_LNE_end_sequence: + *s_out = "DW_LNE_end_sequence"; + return DW_DLV_OK; + case DW_LNE_set_address: + *s_out = "DW_LNE_set_address"; + return DW_DLV_OK; + case DW_LNE_define_file: + *s_out = "DW_LNE_define_file"; + return DW_DLV_OK; + case DW_LNE_set_discriminator: + *s_out = "DW_LNE_set_discriminator"; + return DW_DLV_OK; + case DW_LNE_HP_negate_is_UV_update: + *s_out = "DW_LNE_HP_negate_is_UV_update"; + return DW_DLV_OK; + case DW_LNE_HP_push_context: + *s_out = "DW_LNE_HP_push_context"; + return DW_DLV_OK; + case DW_LNE_HP_pop_context: + *s_out = "DW_LNE_HP_pop_context"; + return DW_DLV_OK; + case DW_LNE_HP_set_file_line_column: + *s_out = "DW_LNE_HP_set_file_line_column"; + return DW_DLV_OK; + case DW_LNE_HP_set_routine_name: + *s_out = "DW_LNE_HP_set_routine_name"; + return DW_DLV_OK; + case DW_LNE_HP_set_sequence: + *s_out = "DW_LNE_HP_set_sequence"; + return DW_DLV_OK; + case DW_LNE_HP_negate_post_semantics: + *s_out = "DW_LNE_HP_negate_post_semantics"; + return DW_DLV_OK; + case DW_LNE_HP_negate_function_exit: + *s_out = "DW_LNE_HP_negate_function_exit"; + return DW_DLV_OK; + case DW_LNE_HP_negate_front_end_logical: + *s_out = "DW_LNE_HP_negate_front_end_logical"; + return DW_DLV_OK; + case DW_LNE_HP_define_proc: + *s_out = "DW_LNE_HP_define_proc"; + return DW_DLV_OK; + case DW_LNE_HP_source_file_correlation: + *s_out = "DW_LNE_HP_source_file_correlation"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x80. DW_LNE_lo_user */ + case DW_LNE_hi_user: + *s_out = "DW_LNE_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ISA_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ISA_UNKNOWN: + *s_out = "DW_ISA_UNKNOWN"; + return DW_DLV_OK; + case DW_ISA_ARM_thumb: + *s_out = "DW_ISA_ARM_thumb"; + return DW_DLV_OK; + case DW_ISA_ARM_arm: + *s_out = "DW_ISA_ARM_arm"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_MACRO_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_MACRO_define: + *s_out = "DW_MACRO_define"; + return DW_DLV_OK; + case DW_MACRO_undef: + *s_out = "DW_MACRO_undef"; + return DW_DLV_OK; + case DW_MACRO_start_file: + *s_out = "DW_MACRO_start_file"; + return DW_DLV_OK; + case DW_MACRO_end_file: + *s_out = "DW_MACRO_end_file"; + return DW_DLV_OK; + case DW_MACRO_define_strp: + *s_out = "DW_MACRO_define_strp"; + return DW_DLV_OK; + case DW_MACRO_undef_strp: + *s_out = "DW_MACRO_undef_strp"; + return DW_DLV_OK; + case DW_MACRO_import: + *s_out = "DW_MACRO_import"; + return DW_DLV_OK; + case DW_MACRO_define_sup: + *s_out = "DW_MACRO_define_sup"; + return DW_DLV_OK; + case DW_MACRO_undef_sup: + *s_out = "DW_MACRO_undef_sup"; + return DW_DLV_OK; + case DW_MACRO_import_sup: + *s_out = "DW_MACRO_import_sup"; + return DW_DLV_OK; + case DW_MACRO_define_strx: + *s_out = "DW_MACRO_define_strx"; + return DW_DLV_OK; + case DW_MACRO_undef_strx: + *s_out = "DW_MACRO_undef_strx"; + return DW_DLV_OK; + case DW_MACRO_lo_user: + *s_out = "DW_MACRO_lo_user"; + return DW_DLV_OK; + case DW_MACRO_hi_user: + *s_out = "DW_MACRO_hi_user"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_MACINFO_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_MACINFO_define: + *s_out = "DW_MACINFO_define"; + return DW_DLV_OK; + case DW_MACINFO_undef: + *s_out = "DW_MACINFO_undef"; + return DW_DLV_OK; + case DW_MACINFO_start_file: + *s_out = "DW_MACINFO_start_file"; + return DW_DLV_OK; + case DW_MACINFO_end_file: + *s_out = "DW_MACINFO_end_file"; + return DW_DLV_OK; + case DW_MACINFO_vendor_ext: + *s_out = "DW_MACINFO_vendor_ext"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_CFA_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_CFA_extended: + *s_out = "DW_CFA_extended"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x0. DW_CFA_nop */ + case DW_CFA_set_loc: + *s_out = "DW_CFA_set_loc"; + return DW_DLV_OK; + case DW_CFA_advance_loc1: + *s_out = "DW_CFA_advance_loc1"; + return DW_DLV_OK; + case DW_CFA_advance_loc2: + *s_out = "DW_CFA_advance_loc2"; + return DW_DLV_OK; + case DW_CFA_advance_loc4: + *s_out = "DW_CFA_advance_loc4"; + return DW_DLV_OK; + case DW_CFA_offset_extended: + *s_out = "DW_CFA_offset_extended"; + return DW_DLV_OK; + case DW_CFA_restore_extended: + *s_out = "DW_CFA_restore_extended"; + return DW_DLV_OK; + case DW_CFA_undefined: + *s_out = "DW_CFA_undefined"; + return DW_DLV_OK; + case DW_CFA_same_value: + *s_out = "DW_CFA_same_value"; + return DW_DLV_OK; + case DW_CFA_register: + *s_out = "DW_CFA_register"; + return DW_DLV_OK; + case DW_CFA_remember_state: + *s_out = "DW_CFA_remember_state"; + return DW_DLV_OK; + case DW_CFA_restore_state: + *s_out = "DW_CFA_restore_state"; + return DW_DLV_OK; + case DW_CFA_def_cfa: + *s_out = "DW_CFA_def_cfa"; + return DW_DLV_OK; + case DW_CFA_def_cfa_register: + *s_out = "DW_CFA_def_cfa_register"; + return DW_DLV_OK; + case DW_CFA_def_cfa_offset: + *s_out = "DW_CFA_def_cfa_offset"; + return DW_DLV_OK; + case DW_CFA_def_cfa_expression: + *s_out = "DW_CFA_def_cfa_expression"; + return DW_DLV_OK; + case DW_CFA_expression: + *s_out = "DW_CFA_expression"; + return DW_DLV_OK; + case DW_CFA_offset_extended_sf: + *s_out = "DW_CFA_offset_extended_sf"; + return DW_DLV_OK; + case DW_CFA_def_cfa_sf: + *s_out = "DW_CFA_def_cfa_sf"; + return DW_DLV_OK; + case DW_CFA_def_cfa_offset_sf: + *s_out = "DW_CFA_def_cfa_offset_sf"; + return DW_DLV_OK; + case DW_CFA_val_offset: + *s_out = "DW_CFA_val_offset"; + return DW_DLV_OK; + case DW_CFA_val_offset_sf: + *s_out = "DW_CFA_val_offset_sf"; + return DW_DLV_OK; + case DW_CFA_val_expression: + *s_out = "DW_CFA_val_expression"; + return DW_DLV_OK; + case DW_CFA_lo_user: + *s_out = "DW_CFA_lo_user"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x1c. DW_CFA_low_user */ + case DW_CFA_MIPS_advance_loc8: + *s_out = "DW_CFA_MIPS_advance_loc8"; + return DW_DLV_OK; + case DW_CFA_GNU_window_save: + *s_out = "DW_CFA_GNU_window_save"; + return DW_DLV_OK; + case DW_CFA_GNU_args_size: + *s_out = "DW_CFA_GNU_args_size"; + return DW_DLV_OK; + case DW_CFA_GNU_negative_offset_extended: + *s_out = "DW_CFA_GNU_negative_offset_extended"; + return DW_DLV_OK; + case DW_CFA_METAWARE_info: + *s_out = "DW_CFA_METAWARE_info"; + return DW_DLV_OK; + case DW_CFA_high_user: + *s_out = "DW_CFA_high_user"; + return DW_DLV_OK; + case DW_CFA_advance_loc: + *s_out = "DW_CFA_advance_loc"; + return DW_DLV_OK; + case DW_CFA_offset: + *s_out = "DW_CFA_offset"; + return DW_DLV_OK; + case DW_CFA_restore: + *s_out = "DW_CFA_restore"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_EH_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_EH_PE_absptr: + *s_out = "DW_EH_PE_absptr"; + return DW_DLV_OK; + case DW_EH_PE_uleb128: + *s_out = "DW_EH_PE_uleb128"; + return DW_DLV_OK; + case DW_EH_PE_udata2: + *s_out = "DW_EH_PE_udata2"; + return DW_DLV_OK; + case DW_EH_PE_udata4: + *s_out = "DW_EH_PE_udata4"; + return DW_DLV_OK; + case DW_EH_PE_udata8: + *s_out = "DW_EH_PE_udata8"; + return DW_DLV_OK; + case DW_EH_PE_sleb128: + *s_out = "DW_EH_PE_sleb128"; + return DW_DLV_OK; + case DW_EH_PE_sdata2: + *s_out = "DW_EH_PE_sdata2"; + return DW_DLV_OK; + case DW_EH_PE_sdata4: + *s_out = "DW_EH_PE_sdata4"; + return DW_DLV_OK; + case DW_EH_PE_sdata8: + *s_out = "DW_EH_PE_sdata8"; + return DW_DLV_OK; + case DW_EH_PE_pcrel: + *s_out = "DW_EH_PE_pcrel"; + return DW_DLV_OK; + case DW_EH_PE_textrel: + *s_out = "DW_EH_PE_textrel"; + return DW_DLV_OK; + case DW_EH_PE_datarel: + *s_out = "DW_EH_PE_datarel"; + return DW_DLV_OK; + case DW_EH_PE_funcrel: + *s_out = "DW_EH_PE_funcrel"; + return DW_DLV_OK; + case DW_EH_PE_aligned: + *s_out = "DW_EH_PE_aligned"; + return DW_DLV_OK; + case DW_EH_PE_omit: + *s_out = "DW_EH_PE_omit"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_FRAME_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_FRAME_CFA_COL: + *s_out = "DW_FRAME_CFA_COL"; + return DW_DLV_OK; + /* Skipping alternate spelling of value 0x0. DW_FRAME_LAST_REG_NUM */ + /* Skipping alternate spelling of value 0x0. DW_FRAME_RA_COL */ + /* Skipping alternate spelling of value 0x0. DW_FRAME_STATIC_LINK */ + case DW_FRAME_REG1: + *s_out = "DW_FRAME_REG1"; + return DW_DLV_OK; + case DW_FRAME_REG2: + *s_out = "DW_FRAME_REG2"; + return DW_DLV_OK; + case DW_FRAME_REG3: + *s_out = "DW_FRAME_REG3"; + return DW_DLV_OK; + case DW_FRAME_REG4: + *s_out = "DW_FRAME_REG4"; + return DW_DLV_OK; + case DW_FRAME_REG5: + *s_out = "DW_FRAME_REG5"; + return DW_DLV_OK; + case DW_FRAME_REG6: + *s_out = "DW_FRAME_REG6"; + return DW_DLV_OK; + case DW_FRAME_REG7: + *s_out = "DW_FRAME_REG7"; + return DW_DLV_OK; + case DW_FRAME_REG8: + *s_out = "DW_FRAME_REG8"; + return DW_DLV_OK; + case DW_FRAME_REG9: + *s_out = "DW_FRAME_REG9"; + return DW_DLV_OK; + case DW_FRAME_REG10: + *s_out = "DW_FRAME_REG10"; + return DW_DLV_OK; + case DW_FRAME_REG11: + *s_out = "DW_FRAME_REG11"; + return DW_DLV_OK; + case DW_FRAME_REG12: + *s_out = "DW_FRAME_REG12"; + return DW_DLV_OK; + case DW_FRAME_REG13: + *s_out = "DW_FRAME_REG13"; + return DW_DLV_OK; + case DW_FRAME_REG14: + *s_out = "DW_FRAME_REG14"; + return DW_DLV_OK; + case DW_FRAME_REG15: + *s_out = "DW_FRAME_REG15"; + return DW_DLV_OK; + case DW_FRAME_REG16: + *s_out = "DW_FRAME_REG16"; + return DW_DLV_OK; + case DW_FRAME_REG17: + *s_out = "DW_FRAME_REG17"; + return DW_DLV_OK; + case DW_FRAME_REG18: + *s_out = "DW_FRAME_REG18"; + return DW_DLV_OK; + case DW_FRAME_REG19: + *s_out = "DW_FRAME_REG19"; + return DW_DLV_OK; + case DW_FRAME_REG20: + *s_out = "DW_FRAME_REG20"; + return DW_DLV_OK; + case DW_FRAME_REG21: + *s_out = "DW_FRAME_REG21"; + return DW_DLV_OK; + case DW_FRAME_REG22: + *s_out = "DW_FRAME_REG22"; + return DW_DLV_OK; + case DW_FRAME_REG23: + *s_out = "DW_FRAME_REG23"; + return DW_DLV_OK; + case DW_FRAME_REG24: + *s_out = "DW_FRAME_REG24"; + return DW_DLV_OK; + case DW_FRAME_REG25: + *s_out = "DW_FRAME_REG25"; + return DW_DLV_OK; + case DW_FRAME_REG26: + *s_out = "DW_FRAME_REG26"; + return DW_DLV_OK; + case DW_FRAME_REG27: + *s_out = "DW_FRAME_REG27"; + return DW_DLV_OK; + case DW_FRAME_REG28: + *s_out = "DW_FRAME_REG28"; + return DW_DLV_OK; + case DW_FRAME_REG29: + *s_out = "DW_FRAME_REG29"; + return DW_DLV_OK; + case DW_FRAME_REG30: + *s_out = "DW_FRAME_REG30"; + return DW_DLV_OK; + case DW_FRAME_REG31: + *s_out = "DW_FRAME_REG31"; + return DW_DLV_OK; + case DW_FRAME_FREG0: + *s_out = "DW_FRAME_FREG0"; + return DW_DLV_OK; + case DW_FRAME_FREG1: + *s_out = "DW_FRAME_FREG1"; + return DW_DLV_OK; + case DW_FRAME_FREG2: + *s_out = "DW_FRAME_FREG2"; + return DW_DLV_OK; + case DW_FRAME_FREG3: + *s_out = "DW_FRAME_FREG3"; + return DW_DLV_OK; + case DW_FRAME_FREG4: + *s_out = "DW_FRAME_FREG4"; + return DW_DLV_OK; + case DW_FRAME_FREG5: + *s_out = "DW_FRAME_FREG5"; + return DW_DLV_OK; + case DW_FRAME_FREG6: + *s_out = "DW_FRAME_FREG6"; + return DW_DLV_OK; + case DW_FRAME_FREG7: + *s_out = "DW_FRAME_FREG7"; + return DW_DLV_OK; + case DW_FRAME_FREG8: + *s_out = "DW_FRAME_FREG8"; + return DW_DLV_OK; + case DW_FRAME_FREG9: + *s_out = "DW_FRAME_FREG9"; + return DW_DLV_OK; + case DW_FRAME_FREG10: + *s_out = "DW_FRAME_FREG10"; + return DW_DLV_OK; + case DW_FRAME_FREG11: + *s_out = "DW_FRAME_FREG11"; + return DW_DLV_OK; + case DW_FRAME_FREG12: + *s_out = "DW_FRAME_FREG12"; + return DW_DLV_OK; + case DW_FRAME_FREG13: + *s_out = "DW_FRAME_FREG13"; + return DW_DLV_OK; + case DW_FRAME_FREG14: + *s_out = "DW_FRAME_FREG14"; + return DW_DLV_OK; + case DW_FRAME_FREG15: + *s_out = "DW_FRAME_FREG15"; + return DW_DLV_OK; + case DW_FRAME_FREG16: + *s_out = "DW_FRAME_FREG16"; + return DW_DLV_OK; + case DW_FRAME_FREG17: + *s_out = "DW_FRAME_FREG17"; + return DW_DLV_OK; + case DW_FRAME_FREG18: + *s_out = "DW_FRAME_FREG18"; + return DW_DLV_OK; + case DW_FRAME_FREG19: + *s_out = "DW_FRAME_FREG19"; + return DW_DLV_OK; + case DW_FRAME_FREG20: + *s_out = "DW_FRAME_FREG20"; + return DW_DLV_OK; + case DW_FRAME_FREG21: + *s_out = "DW_FRAME_FREG21"; + return DW_DLV_OK; + case DW_FRAME_FREG22: + *s_out = "DW_FRAME_FREG22"; + return DW_DLV_OK; + case DW_FRAME_FREG23: + *s_out = "DW_FRAME_FREG23"; + return DW_DLV_OK; + case DW_FRAME_FREG24: + *s_out = "DW_FRAME_FREG24"; + return DW_DLV_OK; + case DW_FRAME_FREG25: + *s_out = "DW_FRAME_FREG25"; + return DW_DLV_OK; + case DW_FRAME_FREG26: + *s_out = "DW_FRAME_FREG26"; + return DW_DLV_OK; + case DW_FRAME_FREG27: + *s_out = "DW_FRAME_FREG27"; + return DW_DLV_OK; + case DW_FRAME_FREG28: + *s_out = "DW_FRAME_FREG28"; + return DW_DLV_OK; + case DW_FRAME_FREG29: + *s_out = "DW_FRAME_FREG29"; + return DW_DLV_OK; + case DW_FRAME_FREG30: + *s_out = "DW_FRAME_FREG30"; + return DW_DLV_OK; + case DW_FRAME_FREG31: + *s_out = "DW_FRAME_FREG31"; + return DW_DLV_OK; + case DW_FRAME_FREG32: + *s_out = "DW_FRAME_FREG32"; + return DW_DLV_OK; + case DW_FRAME_FREG33: + *s_out = "DW_FRAME_FREG33"; + return DW_DLV_OK; + case DW_FRAME_FREG34: + *s_out = "DW_FRAME_FREG34"; + return DW_DLV_OK; + case DW_FRAME_FREG35: + *s_out = "DW_FRAME_FREG35"; + return DW_DLV_OK; + case DW_FRAME_FREG36: + *s_out = "DW_FRAME_FREG36"; + return DW_DLV_OK; + case DW_FRAME_FREG37: + *s_out = "DW_FRAME_FREG37"; + return DW_DLV_OK; + case DW_FRAME_FREG38: + *s_out = "DW_FRAME_FREG38"; + return DW_DLV_OK; + case DW_FRAME_FREG39: + *s_out = "DW_FRAME_FREG39"; + return DW_DLV_OK; + case DW_FRAME_FREG40: + *s_out = "DW_FRAME_FREG40"; + return DW_DLV_OK; + case DW_FRAME_FREG41: + *s_out = "DW_FRAME_FREG41"; + return DW_DLV_OK; + case DW_FRAME_FREG42: + *s_out = "DW_FRAME_FREG42"; + return DW_DLV_OK; + case DW_FRAME_FREG43: + *s_out = "DW_FRAME_FREG43"; + return DW_DLV_OK; + case DW_FRAME_FREG44: + *s_out = "DW_FRAME_FREG44"; + return DW_DLV_OK; + case DW_FRAME_FREG45: + *s_out = "DW_FRAME_FREG45"; + return DW_DLV_OK; + case DW_FRAME_FREG46: + *s_out = "DW_FRAME_FREG46"; + return DW_DLV_OK; + case DW_FRAME_FREG47: + *s_out = "DW_FRAME_FREG47"; + return DW_DLV_OK; + case DW_FRAME_FREG48: + *s_out = "DW_FRAME_FREG48"; + return DW_DLV_OK; + case DW_FRAME_FREG49: + *s_out = "DW_FRAME_FREG49"; + return DW_DLV_OK; + case DW_FRAME_FREG50: + *s_out = "DW_FRAME_FREG50"; + return DW_DLV_OK; + case DW_FRAME_FREG51: + *s_out = "DW_FRAME_FREG51"; + return DW_DLV_OK; + case DW_FRAME_FREG52: + *s_out = "DW_FRAME_FREG52"; + return DW_DLV_OK; + case DW_FRAME_FREG53: + *s_out = "DW_FRAME_FREG53"; + return DW_DLV_OK; + case DW_FRAME_FREG54: + *s_out = "DW_FRAME_FREG54"; + return DW_DLV_OK; + case DW_FRAME_FREG55: + *s_out = "DW_FRAME_FREG55"; + return DW_DLV_OK; + case DW_FRAME_FREG56: + *s_out = "DW_FRAME_FREG56"; + return DW_DLV_OK; + case DW_FRAME_FREG57: + *s_out = "DW_FRAME_FREG57"; + return DW_DLV_OK; + case DW_FRAME_FREG58: + *s_out = "DW_FRAME_FREG58"; + return DW_DLV_OK; + case DW_FRAME_FREG59: + *s_out = "DW_FRAME_FREG59"; + return DW_DLV_OK; + case DW_FRAME_FREG60: + *s_out = "DW_FRAME_FREG60"; + return DW_DLV_OK; + case DW_FRAME_FREG61: + *s_out = "DW_FRAME_FREG61"; + return DW_DLV_OK; + case DW_FRAME_FREG62: + *s_out = "DW_FRAME_FREG62"; + return DW_DLV_OK; + case DW_FRAME_FREG63: + *s_out = "DW_FRAME_FREG63"; + return DW_DLV_OK; + case DW_FRAME_FREG64: + *s_out = "DW_FRAME_FREG64"; + return DW_DLV_OK; + case DW_FRAME_FREG65: + *s_out = "DW_FRAME_FREG65"; + return DW_DLV_OK; + case DW_FRAME_FREG66: + *s_out = "DW_FRAME_FREG66"; + return DW_DLV_OK; + case DW_FRAME_FREG67: + *s_out = "DW_FRAME_FREG67"; + return DW_DLV_OK; + case DW_FRAME_FREG68: + *s_out = "DW_FRAME_FREG68"; + return DW_DLV_OK; + case DW_FRAME_FREG69: + *s_out = "DW_FRAME_FREG69"; + return DW_DLV_OK; + case DW_FRAME_FREG70: + *s_out = "DW_FRAME_FREG70"; + return DW_DLV_OK; + case DW_FRAME_FREG71: + *s_out = "DW_FRAME_FREG71"; + return DW_DLV_OK; + case DW_FRAME_FREG72: + *s_out = "DW_FRAME_FREG72"; + return DW_DLV_OK; + case DW_FRAME_FREG73: + *s_out = "DW_FRAME_FREG73"; + return DW_DLV_OK; + case DW_FRAME_FREG74: + *s_out = "DW_FRAME_FREG74"; + return DW_DLV_OK; + case DW_FRAME_FREG75: + *s_out = "DW_FRAME_FREG75"; + return DW_DLV_OK; + case DW_FRAME_FREG76: + *s_out = "DW_FRAME_FREG76"; + return DW_DLV_OK; + case DW_FRAME_HIGHEST_NORMAL_REGISTER: + *s_out = "DW_FRAME_HIGHEST_NORMAL_REGISTER"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_CHILDREN_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_CHILDREN_no: + *s_out = "DW_CHILDREN_no"; + return DW_DLV_OK; + case DW_CHILDREN_yes: + *s_out = "DW_CHILDREN_yes"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} +/* ARGSUSED */ +int +dwarf_get_ADDR_name (unsigned int val,const char ** s_out) +{ + switch (val) { + case DW_ADDR_none: + *s_out = "DW_ADDR_none"; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +/* END FILE */ diff --git a/thirdparty/dwarf/dwarf_names.h b/thirdparty/dwarf/dwarf_names.h new file mode 100644 index 00000000..9cea3916 --- /dev/null +++ b/thirdparty/dwarf/dwarf_names.h @@ -0,0 +1,56 @@ +/* Generated routines, do not edit. */ +/* Generated sourcedate 2019-05-29 08:43:30-07:00 */ + +/* BEGIN FILE */ + +#ifndef DWARF_NAMES_H +#define DWARF_NAMES_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DWARF_NAMES_H */ + +/* END FILE */ diff --git a/thirdparty/dwarf/dwarf_names_enum.h b/thirdparty/dwarf/dwarf_names_enum.h new file mode 100644 index 00000000..37eb9144 --- /dev/null +++ b/thirdparty/dwarf/dwarf_names_enum.h @@ -0,0 +1,1110 @@ +/* Automatically generated, do not edit. */ +/* Generated sourcedate 2019-05-29 08:43:30-07:00 */ + +/* BEGIN FILE */ + +#ifndef __DWARF_NAMES_ENUM_H__ +#define __DWARF_NAMES_ENUM_H__ + +enum Dwarf_TAG_e { + DW_TAG_array_type = 0x0001, + DW_TAG_class_type = 0x0002, + DW_TAG_entry_point = 0x0003, + DW_TAG_enumeration_type = 0x0004, + DW_TAG_formal_parameter = 0x0005, + DW_TAG_imported_declaration = 0x0008, + DW_TAG_label = 0x000a, + DW_TAG_lexical_block = 0x000b, + DW_TAG_member = 0x000d, + DW_TAG_pointer_type = 0x000f, + DW_TAG_reference_type = 0x0010, + DW_TAG_compile_unit = 0x0011, + DW_TAG_string_type = 0x0012, + DW_TAG_structure_type = 0x0013, + DW_TAG_subroutine_type = 0x0015, + DW_TAG_typedef = 0x0016, + DW_TAG_union_type = 0x0017, + DW_TAG_unspecified_parameters = 0x0018, + DW_TAG_variant = 0x0019, + DW_TAG_common_block = 0x001a, + DW_TAG_common_inclusion = 0x001b, + DW_TAG_inheritance = 0x001c, + DW_TAG_inlined_subroutine = 0x001d, + DW_TAG_module = 0x001e, + DW_TAG_ptr_to_member_type = 0x001f, + DW_TAG_set_type = 0x0020, + DW_TAG_subrange_type = 0x0021, + DW_TAG_with_stmt = 0x0022, + DW_TAG_access_declaration = 0x0023, + DW_TAG_base_type = 0x0024, + DW_TAG_catch_block = 0x0025, + DW_TAG_const_type = 0x0026, + DW_TAG_constant = 0x0027, + DW_TAG_enumerator = 0x0028, + DW_TAG_file_type = 0x0029, + DW_TAG_friend = 0x002a, + DW_TAG_namelist = 0x002b, + DW_TAG_namelist_item = 0x002c, + DW_TAG_packed_type = 0x002d, + DW_TAG_subprogram = 0x002e, + DW_TAG_template_type_parameter = 0x002f, + DW_TAG_template_value_parameter = 0x0030, + DW_TAG_thrown_type = 0x0031, + DW_TAG_try_block = 0x0032, + DW_TAG_variant_part = 0x0033, + DW_TAG_variable = 0x0034, + DW_TAG_volatile_type = 0x0035, + DW_TAG_dwarf_procedure = 0x0036, + DW_TAG_restrict_type = 0x0037, + DW_TAG_interface_type = 0x0038, + DW_TAG_namespace = 0x0039, + DW_TAG_imported_module = 0x003a, + DW_TAG_unspecified_type = 0x003b, + DW_TAG_partial_unit = 0x003c, + DW_TAG_imported_unit = 0x003d, + DW_TAG_mutable_type = 0x003e, + DW_TAG_condition = 0x003f, + DW_TAG_shared_type = 0x0040, + DW_TAG_type_unit = 0x0041, + DW_TAG_rvalue_reference_type = 0x0042, + DW_TAG_template_alias = 0x0043, + DW_TAG_coarray_type = 0x0044, + DW_TAG_generic_subrange = 0x0045, + DW_TAG_dynamic_type = 0x0046, + DW_TAG_atomic_type = 0x0047, + DW_TAG_call_site = 0x0048, + DW_TAG_call_site_parameter = 0x0049, + DW_TAG_skeleton_unit = 0x004a, + DW_TAG_immutable_type = 0x004b, + DW_TAG_lo_user = 0x4080, + DW_TAG_MIPS_loop = 0x4081, + DW_TAG_HP_array_descriptor = 0x4090, + DW_TAG_format_label = 0x4101, + DW_TAG_function_template = 0x4102, + DW_TAG_class_template = 0x4103, + DW_TAG_GNU_BINCL = 0x4104, + DW_TAG_GNU_EINCL = 0x4105, + DW_TAG_GNU_template_template_parameter = 0x4106, + DW_TAG_GNU_template_parameter_pack = 0x4107, + DW_TAG_GNU_formal_parameter_pack = 0x4108, + DW_TAG_GNU_call_site = 0x4109, + DW_TAG_GNU_call_site_parameter = 0x410a, + DW_TAG_SUN_function_template = 0x4201, + DW_TAG_SUN_class_template = 0x4202, + DW_TAG_SUN_struct_template = 0x4203, + DW_TAG_SUN_union_template = 0x4204, + DW_TAG_SUN_indirect_inheritance = 0x4205, + DW_TAG_SUN_codeflags = 0x4206, + DW_TAG_SUN_memop_info = 0x4207, + DW_TAG_SUN_omp_child_func = 0x4208, + DW_TAG_SUN_rtti_descriptor = 0x4209, + DW_TAG_SUN_dtor_info = 0x420a, + DW_TAG_SUN_dtor = 0x420b, + DW_TAG_SUN_f90_interface = 0x420c, + DW_TAG_SUN_fortran_vax_structure = 0x420d, + DW_TAG_SUN_hi = 0x42ff, + DW_TAG_ALTIUM_circ_type = 0x5101, + DW_TAG_ALTIUM_mwa_circ_type = 0x5102, + DW_TAG_ALTIUM_rev_carry_type = 0x5103, + DW_TAG_ALTIUM_rom = 0x5111, + DW_TAG_upc_shared_type = 0x8765, + DW_TAG_upc_strict_type = 0x8766, + DW_TAG_upc_relaxed_type = 0x8767, + DW_TAG_PGI_kanji_type = 0xa000, + DW_TAG_PGI_interface_block = 0xa020, + DW_TAG_hi_user = 0xffff +}; + +enum Dwarf_children_e { + DW_children_no = 0x0000, + DW_children_yes = 0x0001 +}; + +enum Dwarf_FORM_e { + DW_FORM_addr = 0x0001, + DW_FORM_block2 = 0x0003, + DW_FORM_block4 = 0x0004, + DW_FORM_data2 = 0x0005, + DW_FORM_data4 = 0x0006, + DW_FORM_data8 = 0x0007, + DW_FORM_string = 0x0008, + DW_FORM_block = 0x0009, + DW_FORM_block1 = 0x000a, + DW_FORM_data1 = 0x000b, + DW_FORM_flag = 0x000c, + DW_FORM_sdata = 0x000d, + DW_FORM_strp = 0x000e, + DW_FORM_udata = 0x000f, + DW_FORM_ref_addr = 0x0010, + DW_FORM_ref1 = 0x0011, + DW_FORM_ref2 = 0x0012, + DW_FORM_ref4 = 0x0013, + DW_FORM_ref8 = 0x0014, + DW_FORM_ref_udata = 0x0015, + DW_FORM_indirect = 0x0016, + DW_FORM_sec_offset = 0x0017, + DW_FORM_exprloc = 0x0018, + DW_FORM_flag_present = 0x0019, + DW_FORM_strx = 0x001a, + DW_FORM_addrx = 0x001b, + DW_FORM_ref_sup4 = 0x001c, + DW_FORM_strp_sup = 0x001d, + DW_FORM_data16 = 0x001e, + DW_FORM_line_strp = 0x001f, + DW_FORM_ref_sig8 = 0x0020, + DW_FORM_implicit_const = 0x0021, + DW_FORM_loclistx = 0x0022, + DW_FORM_rnglistx = 0x0023, + DW_FORM_ref_sup8 = 0x0024, + DW_FORM_strx1 = 0x0025, + DW_FORM_strx2 = 0x0026, + DW_FORM_strx3 = 0x0027, + DW_FORM_strx4 = 0x0028, + DW_FORM_addrx1 = 0x0029, + DW_FORM_addrx2 = 0x002a, + DW_FORM_addrx3 = 0x002b, + DW_FORM_addrx4 = 0x002c, + DW_FORM_GNU_addr_index = 0x1f01, + DW_FORM_GNU_str_index = 0x1f02, + DW_FORM_GNU_ref_alt = 0x1f20, + DW_FORM_GNU_strp_alt = 0x1f21 +}; + +enum Dwarf_AT_e { + DW_AT_sibling = 0x0001, + DW_AT_location = 0x0002, + DW_AT_name = 0x0003, + DW_AT_ordering = 0x0009, + DW_AT_subscr_data = 0x000a, + DW_AT_byte_size = 0x000b, + DW_AT_bit_offset = 0x000c, + DW_AT_bit_size = 0x000d, + DW_AT_element_list = 0x000f, + DW_AT_stmt_list = 0x0010, + DW_AT_low_pc = 0x0011, + DW_AT_high_pc = 0x0012, + DW_AT_language = 0x0013, + DW_AT_member = 0x0014, + DW_AT_discr = 0x0015, + DW_AT_discr_value = 0x0016, + DW_AT_visibility = 0x0017, + DW_AT_import = 0x0018, + DW_AT_string_length = 0x0019, + DW_AT_common_reference = 0x001a, + DW_AT_comp_dir = 0x001b, + DW_AT_const_value = 0x001c, + DW_AT_containing_type = 0x001d, + DW_AT_default_value = 0x001e, + DW_AT_inline = 0x0020, + DW_AT_is_optional = 0x0021, + DW_AT_lower_bound = 0x0022, + DW_AT_producer = 0x0025, + DW_AT_prototyped = 0x0027, + DW_AT_return_addr = 0x002a, + DW_AT_start_scope = 0x002c, + DW_AT_bit_stride = 0x002e, + DW_AT_upper_bound = 0x002f, + DW_AT_abstract_origin = 0x0031, + DW_AT_accessibility = 0x0032, + DW_AT_address_class = 0x0033, + DW_AT_artificial = 0x0034, + DW_AT_base_types = 0x0035, + DW_AT_calling_convention = 0x0036, + DW_AT_count = 0x0037, + DW_AT_data_member_location = 0x0038, + DW_AT_decl_column = 0x0039, + DW_AT_decl_file = 0x003a, + DW_AT_decl_line = 0x003b, + DW_AT_declaration = 0x003c, + DW_AT_discr_list = 0x003d, + DW_AT_encoding = 0x003e, + DW_AT_external = 0x003f, + DW_AT_frame_base = 0x0040, + DW_AT_friend = 0x0041, + DW_AT_identifier_case = 0x0042, + DW_AT_macro_info = 0x0043, + DW_AT_namelist_item = 0x0044, + DW_AT_priority = 0x0045, + DW_AT_segment = 0x0046, + DW_AT_specification = 0x0047, + DW_AT_static_link = 0x0048, + DW_AT_type = 0x0049, + DW_AT_use_location = 0x004a, + DW_AT_variable_parameter = 0x004b, + DW_AT_virtuality = 0x004c, + DW_AT_vtable_elem_location = 0x004d, + DW_AT_allocated = 0x004e, + DW_AT_associated = 0x004f, + DW_AT_data_location = 0x0050, + DW_AT_byte_stride = 0x0051, + DW_AT_entry_pc = 0x0052, + DW_AT_use_UTF8 = 0x0053, + DW_AT_extension = 0x0054, + DW_AT_ranges = 0x0055, + DW_AT_trampoline = 0x0056, + DW_AT_call_column = 0x0057, + DW_AT_call_file = 0x0058, + DW_AT_call_line = 0x0059, + DW_AT_description = 0x005a, + DW_AT_binary_scale = 0x005b, + DW_AT_decimal_scale = 0x005c, + DW_AT_small = 0x005d, + DW_AT_decimal_sign = 0x005e, + DW_AT_digit_count = 0x005f, + DW_AT_picture_string = 0x0060, + DW_AT_mutable = 0x0061, + DW_AT_threads_scaled = 0x0062, + DW_AT_explicit = 0x0063, + DW_AT_object_pointer = 0x0064, + DW_AT_endianity = 0x0065, + DW_AT_elemental = 0x0066, + DW_AT_pure = 0x0067, + DW_AT_recursive = 0x0068, + DW_AT_signature = 0x0069, + DW_AT_main_subprogram = 0x006a, + DW_AT_data_bit_offset = 0x006b, + DW_AT_const_expr = 0x006c, + DW_AT_enum_class = 0x006d, + DW_AT_linkage_name = 0x006e, + DW_AT_string_length_bit_size = 0x006f, + DW_AT_string_length_byte_size = 0x0070, + DW_AT_rank = 0x0071, + DW_AT_str_offsets_base = 0x0072, + DW_AT_addr_base = 0x0073, + DW_AT_rnglists_base = 0x0074, + DW_AT_dwo_id = 0x0075, + DW_AT_dwo_name = 0x0076, + DW_AT_reference = 0x0077, + DW_AT_rvalue_reference = 0x0078, + DW_AT_macros = 0x0079, + DW_AT_call_all_calls = 0x007a, + DW_AT_call_all_source_calls = 0x007b, + DW_AT_call_all_tail_calls = 0x007c, + DW_AT_call_return_pc = 0x007d, + DW_AT_call_value = 0x007e, + DW_AT_call_origin = 0x007f, + DW_AT_call_parameter = 0x0080, + DW_AT_call_pc = 0x0081, + DW_AT_call_tail_call = 0x0082, + DW_AT_call_target = 0x0083, + DW_AT_call_target_clobbered = 0x0084, + DW_AT_call_data_location = 0x0085, + DW_AT_call_data_value = 0x0086, + DW_AT_noreturn = 0x0087, + DW_AT_alignment = 0x0088, + DW_AT_export_symbols = 0x0089, + DW_AT_deleted = 0x008a, + DW_AT_defaulted = 0x008b, + DW_AT_loclists_base = 0x008c, + DW_AT_HP_block_index = 0x2000, + DW_AT_MIPS_fde = 0x2001, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, + DW_AT_MIPS_linkage_name = 0x2007, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + DW_AT_MIPS_stride_byte = 0x200c, + DW_AT_MIPS_stride_elem = 0x200d, + DW_AT_MIPS_ptr_dopetype = 0x200e, + DW_AT_MIPS_allocatable_dopetype = 0x200f, + DW_AT_MIPS_assumed_shape_dopetype = 0x2010, + DW_AT_MIPS_assumed_size = 0x2011, + DW_AT_HP_raw_data_ptr = 0x2012, + DW_AT_HP_pass_by_reference = 0x2013, + DW_AT_HP_opt_level = 0x2014, + DW_AT_HP_prof_version_id = 0x2015, + DW_AT_HP_opt_flags = 0x2016, + DW_AT_HP_cold_region_low_pc = 0x2017, + DW_AT_HP_cold_region_high_pc = 0x2018, + DW_AT_HP_all_variables_modifiable = 0x2019, + DW_AT_HP_linkage_name = 0x201a, + DW_AT_HP_prof_flags = 0x201b, + DW_AT_INTEL_other_endian = 0x2026, + DW_AT_sf_names = 0x2101, + DW_AT_src_info = 0x2102, + DW_AT_mac_info = 0x2103, + DW_AT_src_coords = 0x2104, + DW_AT_body_begin = 0x2105, + DW_AT_body_end = 0x2106, + DW_AT_GNU_vector = 0x2107, + DW_AT_GNU_guarded_by = 0x2108, + DW_AT_GNU_pt_guarded_by = 0x2109, + DW_AT_GNU_guarded = 0x210a, + DW_AT_GNU_pt_guarded = 0x210b, + DW_AT_GNU_locks_excluded = 0x210c, + DW_AT_GNU_exclusive_locks_required = 0x210d, + DW_AT_GNU_shared_locks_required = 0x210e, + DW_AT_GNU_odr_signature = 0x210f, + DW_AT_GNU_template_name = 0x2110, + DW_AT_GNU_call_site_value = 0x2111, + DW_AT_GNU_call_site_data_value = 0x2112, + DW_AT_GNU_call_site_target = 0x2113, + DW_AT_GNU_call_site_target_clobbered = 0x2114, + DW_AT_GNU_tail_call = 0x2115, + DW_AT_GNU_all_tail_call_sites = 0x2116, + DW_AT_GNU_all_call_sites = 0x2117, + DW_AT_GNU_all_source_call_sites = 0x2118, + DW_AT_GNU_macros = 0x2119, + DW_AT_GNU_dwo_name = 0x2130, + DW_AT_GNU_dwo_id = 0x2131, + DW_AT_GNU_ranges_base = 0x2132, + DW_AT_GNU_addr_base = 0x2133, + DW_AT_GNU_pubnames = 0x2134, + DW_AT_GNU_pubtypes = 0x2135, + DW_AT_GNU_discriminator = 0x2136, + DW_AT_SUN_template = 0x2201, + DW_AT_SUN_alignment = 0x2202, + DW_AT_SUN_vtable = 0x2203, + DW_AT_SUN_count_guarantee = 0x2204, + DW_AT_SUN_command_line = 0x2205, + DW_AT_SUN_vbase = 0x2206, + DW_AT_SUN_compile_options = 0x2207, + DW_AT_SUN_language = 0x2208, + DW_AT_SUN_browser_file = 0x2209, + DW_AT_SUN_vtable_abi = 0x2210, + DW_AT_SUN_func_offsets = 0x2211, + DW_AT_SUN_cf_kind = 0x2212, + DW_AT_SUN_vtable_index = 0x2213, + DW_AT_SUN_omp_tpriv_addr = 0x2214, + DW_AT_SUN_omp_child_func = 0x2215, + DW_AT_SUN_func_offset = 0x2216, + DW_AT_SUN_memop_type_ref = 0x2217, + DW_AT_SUN_profile_id = 0x2218, + DW_AT_SUN_memop_signature = 0x2219, + DW_AT_SUN_obj_dir = 0x2220, + DW_AT_SUN_obj_file = 0x2221, + DW_AT_SUN_original_name = 0x2222, + DW_AT_SUN_hwcprof_signature = 0x2223, + DW_AT_SUN_amd64_parmdump = 0x2224, + DW_AT_SUN_part_link_name = 0x2225, + DW_AT_SUN_link_name = 0x2226, + DW_AT_SUN_pass_with_const = 0x2227, + DW_AT_SUN_return_with_const = 0x2228, + DW_AT_SUN_import_by_name = 0x2229, + DW_AT_SUN_f90_pointer = 0x222a, + DW_AT_SUN_pass_by_ref = 0x222b, + DW_AT_SUN_f90_allocatable = 0x222c, + DW_AT_SUN_f90_assumed_shape_array = 0x222d, + DW_AT_SUN_c_vla = 0x222e, + DW_AT_SUN_return_value_ptr = 0x2230, + DW_AT_SUN_dtor_start = 0x2231, + DW_AT_SUN_dtor_length = 0x2232, + DW_AT_SUN_dtor_state_initial = 0x2233, + DW_AT_SUN_dtor_state_final = 0x2234, + DW_AT_SUN_dtor_state_deltas = 0x2235, + DW_AT_SUN_import_by_lname = 0x2236, + DW_AT_SUN_f90_use_only = 0x2237, + DW_AT_SUN_namelist_spec = 0x2238, + DW_AT_SUN_is_omp_child_func = 0x2239, + DW_AT_SUN_fortran_main_alias = 0x223a, + DW_AT_SUN_fortran_based = 0x223b, + DW_AT_ALTIUM_loclist = 0x2300, + DW_AT_use_GNAT_descriptive_type = 0x2301, + DW_AT_GNAT_descriptive_type = 0x2302, + DW_AT_GNU_numerator = 0x2303, + DW_AT_GNU_denominator = 0x2304, + DW_AT_GNU_bias = 0x2305, + DW_AT_go_kind = 0x2900, + DW_AT_go_key = 0x2901, + DW_AT_go_elem = 0x2902, + DW_AT_go_embedded_field = 0x2903, + DW_AT_go_runtime_type = 0x2904, + DW_AT_upc_threads_scaled = 0x3210, + DW_AT_PGI_lbase = 0x3a00, + DW_AT_PGI_soffset = 0x3a01, + DW_AT_PGI_lstride = 0x3a02, + DW_AT_APPLE_optimized = 0x3fe1, + DW_AT_APPLE_flags = 0x3fe2, + DW_AT_APPLE_isa = 0x3fe3, + DW_AT_APPLE_block = 0x3fe4, + DW_AT_APPLE_major_runtime_vers = 0x3fe5, + DW_AT_APPLE_runtime_class = 0x3fe6, + DW_AT_APPLE_omit_frame_ptr = 0x3fe7, + DW_AT_hi_user = 0x3fff +}; + +enum Dwarf_OP_e { + DW_OP_addr = 0x0003, + DW_OP_deref = 0x0006, + DW_OP_const1u = 0x0008, + DW_OP_const1s = 0x0009, + DW_OP_const2u = 0x000a, + DW_OP_const2s = 0x000b, + DW_OP_const4u = 0x000c, + DW_OP_const4s = 0x000d, + DW_OP_const8u = 0x000e, + DW_OP_const8s = 0x000f, + DW_OP_constu = 0x0010, + DW_OP_consts = 0x0011, + DW_OP_dup = 0x0012, + DW_OP_drop = 0x0013, + DW_OP_over = 0x0014, + DW_OP_pick = 0x0015, + DW_OP_swap = 0x0016, + DW_OP_rot = 0x0017, + DW_OP_xderef = 0x0018, + DW_OP_abs = 0x0019, + DW_OP_and = 0x001a, + DW_OP_div = 0x001b, + DW_OP_minus = 0x001c, + DW_OP_mod = 0x001d, + DW_OP_mul = 0x001e, + DW_OP_neg = 0x001f, + DW_OP_not = 0x0020, + DW_OP_or = 0x0021, + DW_OP_plus = 0x0022, + DW_OP_plus_uconst = 0x0023, + DW_OP_shl = 0x0024, + DW_OP_shr = 0x0025, + DW_OP_shra = 0x0026, + DW_OP_xor = 0x0027, + DW_OP_bra = 0x0028, + DW_OP_eq = 0x0029, + DW_OP_ge = 0x002a, + DW_OP_gt = 0x002b, + DW_OP_le = 0x002c, + DW_OP_lt = 0x002d, + DW_OP_ne = 0x002e, + DW_OP_skip = 0x002f, + DW_OP_lit0 = 0x0030, + DW_OP_lit1 = 0x0031, + DW_OP_lit2 = 0x0032, + DW_OP_lit3 = 0x0033, + DW_OP_lit4 = 0x0034, + DW_OP_lit5 = 0x0035, + DW_OP_lit6 = 0x0036, + DW_OP_lit7 = 0x0037, + DW_OP_lit8 = 0x0038, + DW_OP_lit9 = 0x0039, + DW_OP_lit10 = 0x003a, + DW_OP_lit11 = 0x003b, + DW_OP_lit12 = 0x003c, + DW_OP_lit13 = 0x003d, + DW_OP_lit14 = 0x003e, + DW_OP_lit15 = 0x003f, + DW_OP_lit16 = 0x0040, + DW_OP_lit17 = 0x0041, + DW_OP_lit18 = 0x0042, + DW_OP_lit19 = 0x0043, + DW_OP_lit20 = 0x0044, + DW_OP_lit21 = 0x0045, + DW_OP_lit22 = 0x0046, + DW_OP_lit23 = 0x0047, + DW_OP_lit24 = 0x0048, + DW_OP_lit25 = 0x0049, + DW_OP_lit26 = 0x004a, + DW_OP_lit27 = 0x004b, + DW_OP_lit28 = 0x004c, + DW_OP_lit29 = 0x004d, + DW_OP_lit30 = 0x004e, + DW_OP_lit31 = 0x004f, + DW_OP_reg0 = 0x0050, + DW_OP_reg1 = 0x0051, + DW_OP_reg2 = 0x0052, + DW_OP_reg3 = 0x0053, + DW_OP_reg4 = 0x0054, + DW_OP_reg5 = 0x0055, + DW_OP_reg6 = 0x0056, + DW_OP_reg7 = 0x0057, + DW_OP_reg8 = 0x0058, + DW_OP_reg9 = 0x0059, + DW_OP_reg10 = 0x005a, + DW_OP_reg11 = 0x005b, + DW_OP_reg12 = 0x005c, + DW_OP_reg13 = 0x005d, + DW_OP_reg14 = 0x005e, + DW_OP_reg15 = 0x005f, + DW_OP_reg16 = 0x0060, + DW_OP_reg17 = 0x0061, + DW_OP_reg18 = 0x0062, + DW_OP_reg19 = 0x0063, + DW_OP_reg20 = 0x0064, + DW_OP_reg21 = 0x0065, + DW_OP_reg22 = 0x0066, + DW_OP_reg23 = 0x0067, + DW_OP_reg24 = 0x0068, + DW_OP_reg25 = 0x0069, + DW_OP_reg26 = 0x006a, + DW_OP_reg27 = 0x006b, + DW_OP_reg28 = 0x006c, + DW_OP_reg29 = 0x006d, + DW_OP_reg30 = 0x006e, + DW_OP_reg31 = 0x006f, + DW_OP_breg0 = 0x0070, + DW_OP_breg1 = 0x0071, + DW_OP_breg2 = 0x0072, + DW_OP_breg3 = 0x0073, + DW_OP_breg4 = 0x0074, + DW_OP_breg5 = 0x0075, + DW_OP_breg6 = 0x0076, + DW_OP_breg7 = 0x0077, + DW_OP_breg8 = 0x0078, + DW_OP_breg9 = 0x0079, + DW_OP_breg10 = 0x007a, + DW_OP_breg11 = 0x007b, + DW_OP_breg12 = 0x007c, + DW_OP_breg13 = 0x007d, + DW_OP_breg14 = 0x007e, + DW_OP_breg15 = 0x007f, + DW_OP_breg16 = 0x0080, + DW_OP_breg17 = 0x0081, + DW_OP_breg18 = 0x0082, + DW_OP_breg19 = 0x0083, + DW_OP_breg20 = 0x0084, + DW_OP_breg21 = 0x0085, + DW_OP_breg22 = 0x0086, + DW_OP_breg23 = 0x0087, + DW_OP_breg24 = 0x0088, + DW_OP_breg25 = 0x0089, + DW_OP_breg26 = 0x008a, + DW_OP_breg27 = 0x008b, + DW_OP_breg28 = 0x008c, + DW_OP_breg29 = 0x008d, + DW_OP_breg30 = 0x008e, + DW_OP_breg31 = 0x008f, + DW_OP_regx = 0x0090, + DW_OP_fbreg = 0x0091, + DW_OP_bregx = 0x0092, + DW_OP_piece = 0x0093, + DW_OP_deref_size = 0x0094, + DW_OP_xderef_size = 0x0095, + DW_OP_nop = 0x0096, + DW_OP_push_object_address = 0x0097, + DW_OP_call2 = 0x0098, + DW_OP_call4 = 0x0099, + DW_OP_call_ref = 0x009a, + DW_OP_form_tls_address = 0x009b, + DW_OP_call_frame_cfa = 0x009c, + DW_OP_bit_piece = 0x009d, + DW_OP_implicit_value = 0x009e, + DW_OP_stack_value = 0x009f, + DW_OP_implicit_pointer = 0x00a0, + DW_OP_addrx = 0x00a1, + DW_OP_constx = 0x00a2, + DW_OP_entry_value = 0x00a3, + DW_OP_const_type = 0x00a4, + DW_OP_regval_type = 0x00a5, + DW_OP_deref_type = 0x00a6, + DW_OP_xderef_type = 0x00a7, + DW_OP_convert = 0x00a8, + DW_OP_reinterpret = 0x00a9, + DW_OP_GNU_push_tls_address = 0x00e0, + DW_OP_HP_is_value = 0x00e1, + DW_OP_HP_fltconst4 = 0x00e2, + DW_OP_HP_fltconst8 = 0x00e3, + DW_OP_HP_mod_range = 0x00e4, + DW_OP_HP_unmod_range = 0x00e5, + DW_OP_HP_tls = 0x00e6, + DW_OP_INTEL_bit_piece = 0x00e8, + DW_OP_GNU_uninit = 0x00f0, + DW_OP_GNU_encoded_addr = 0x00f1, + DW_OP_GNU_implicit_pointer = 0x00f2, + DW_OP_GNU_entry_value = 0x00f3, + DW_OP_GNU_const_type = 0x00f4, + DW_OP_GNU_regval_type = 0x00f5, + DW_OP_GNU_deref_type = 0x00f6, + DW_OP_GNU_convert = 0x00f7, + DW_OP_PGI_omp_thread_num = 0x00f8, + DW_OP_GNU_reinterpret = 0x00f9, + DW_OP_GNU_parameter_ref = 0x00fa, + DW_OP_GNU_addr_index = 0x00fb, + DW_OP_GNU_const_index = 0x00fc, + DW_OP_hi_user = 0x00ff +}; + +enum Dwarf_ATE_e { + DW_ATE_address = 0x0001, + DW_ATE_boolean = 0x0002, + DW_ATE_complex_float = 0x0003, + DW_ATE_float = 0x0004, + DW_ATE_signed = 0x0005, + DW_ATE_signed_char = 0x0006, + DW_ATE_unsigned = 0x0007, + DW_ATE_unsigned_char = 0x0008, + DW_ATE_imaginary_float = 0x0009, + DW_ATE_packed_decimal = 0x000a, + DW_ATE_numeric_string = 0x000b, + DW_ATE_edited = 0x000c, + DW_ATE_signed_fixed = 0x000d, + DW_ATE_unsigned_fixed = 0x000e, + DW_ATE_decimal_float = 0x000f, + DW_ATE_UTF = 0x0010, + DW_ATE_UCS = 0x0011, + DW_ATE_ASCII = 0x0012, + DW_ATE_ALTIUM_fract = 0x0080, + DW_ATE_ALTIUM_accum = 0x0081, + DW_ATE_HP_float128 = 0x0082, + DW_ATE_HP_complex_float128 = 0x0083, + DW_ATE_HP_floathpintel = 0x0084, + DW_ATE_HP_imaginary_float80 = 0x0085, + DW_ATE_HP_imaginary_float128 = 0x0086, + DW_ATE_SUN_interval_float = 0x0091, + DW_ATE_SUN_imaginary_float = 0x0092, + DW_ATE_hi_user = 0x00ff +}; + +enum Dwarf_DEFAULTED_e { + DW_DEFAULTED_no = 0x0000, + DW_DEFAULTED_in_class = 0x0001, + DW_DEFAULTED_out_of_class = 0x0002 +}; + +enum Dwarf_IDX_e { + DW_IDX_compile_unit = 0x0001, + DW_IDX_type_unit = 0x0002, + DW_IDX_die_offset = 0x0003, + DW_IDX_parent = 0x0004, + DW_IDX_type_hash = 0x0005, + DW_IDX_hi_user = 0x0fff, + DW_IDX_lo_user = 0x2000 +}; + +enum Dwarf_LLEX_e { + DW_LLEX_end_of_list_entry = 0x0000, + DW_LLEX_base_address_selection_entry = 0x0001, + DW_LLEX_start_end_entry = 0x0002, + DW_LLEX_start_length_entry = 0x0003, + DW_LLEX_offset_pair_entry = 0x0004 +}; + +enum Dwarf_LLE_e { + DW_LLE_end_of_list = 0x0000, + DW_LLE_base_addressx = 0x0001, + DW_LLE_startx_endx = 0x0002, + DW_LLE_startx_length = 0x0003, + DW_LLE_offset_pair = 0x0004, + DW_LLE_default_location = 0x0005, + DW_LLE_base_address = 0x0006, + DW_LLE_start_end = 0x0007, + DW_LLE_start_length = 0x0008 +}; + +enum Dwarf_RLE_e { + DW_RLE_end_of_list = 0x0000, + DW_RLE_base_addressx = 0x0001, + DW_RLE_startx_endx = 0x0002, + DW_RLE_startx_length = 0x0003, + DW_RLE_offset_pair = 0x0004, + DW_RLE_base_address = 0x0005, + DW_RLE_start_end = 0x0006, + DW_RLE_start_length = 0x0007 +}; + +enum Dwarf_UT_e { + DW_UT_compile = 0x0001, + DW_UT_type = 0x0002, + DW_UT_partial = 0x0003, + DW_UT_skeleton = 0x0004, + DW_UT_split_compile = 0x0005, + DW_UT_split_type = 0x0006, + DW_UT_lo_user = 0x0080, + DW_UT_hi_user = 0x00ff +}; + +enum Dwarf_SECT_e { + DW_SECT_INFO = 0x0001, + DW_SECT_TYPES = 0x0002, + DW_SECT_ABBREV = 0x0003, + DW_SECT_LINE = 0x0004, + DW_SECT_LOCLISTS = 0x0005, + DW_SECT_STR_OFFSETS = 0x0006, + DW_SECT_MACRO = 0x0007, + DW_SECT_RNGLISTS = 0x0008 +}; + +enum Dwarf_DS_e { + DW_DS_unsigned = 0x0001, + DW_DS_leading_overpunch = 0x0002, + DW_DS_trailing_overpunch = 0x0003, + DW_DS_leading_separate = 0x0004, + DW_DS_trailing_separate = 0x0005 +}; + +enum Dwarf_END_e { + DW_END_default = 0x0000, + DW_END_big = 0x0001, + DW_END_little = 0x0002, + DW_END_lo_user = 0x0040, + DW_END_hi_user = 0x00ff +}; + +enum Dwarf_ATCF_e { + DW_ATCF_lo_user = 0x0040, + DW_ATCF_SUN_mop_bitfield = 0x0041, + DW_ATCF_SUN_mop_spill = 0x0042, + DW_ATCF_SUN_mop_scopy = 0x0043, + DW_ATCF_SUN_func_start = 0x0044, + DW_ATCF_SUN_end_ctors = 0x0045, + DW_ATCF_SUN_branch_target = 0x0046, + DW_ATCF_SUN_mop_stack_probe = 0x0047, + DW_ATCF_SUN_func_epilog = 0x0048, + DW_ATCF_hi_user = 0x00ff +}; + +enum Dwarf_ACCESS_e { + DW_ACCESS_public = 0x0001, + DW_ACCESS_protected = 0x0002, + DW_ACCESS_private = 0x0003 +}; + +enum Dwarf_VIS_e { + DW_VIS_local = 0x0001, + DW_VIS_exported = 0x0002, + DW_VIS_qualified = 0x0003 +}; + +enum Dwarf_VIRTUALITY_e { + DW_VIRTUALITY_none = 0x0000, + DW_VIRTUALITY_virtual = 0x0001, + DW_VIRTUALITY_pure_virtual = 0x0002 +}; + +enum Dwarf_LANG_e { + DW_LANG_C89 = 0x0001, + DW_LANG_C = 0x0002, + DW_LANG_Ada83 = 0x0003, + DW_LANG_C_plus_plus = 0x0004, + DW_LANG_Cobol74 = 0x0005, + DW_LANG_Cobol85 = 0x0006, + DW_LANG_Fortran77 = 0x0007, + DW_LANG_Fortran90 = 0x0008, + DW_LANG_Pascal83 = 0x0009, + DW_LANG_Modula2 = 0x000a, + DW_LANG_Java = 0x000b, + DW_LANG_C99 = 0x000c, + DW_LANG_Ada95 = 0x000d, + DW_LANG_Fortran95 = 0x000e, + DW_LANG_PLI = 0x000f, + DW_LANG_ObjC = 0x0010, + DW_LANG_ObjC_plus_plus = 0x0011, + DW_LANG_UPC = 0x0012, + DW_LANG_D = 0x0013, + DW_LANG_Python = 0x0014, + DW_LANG_OpenCL = 0x0015, + DW_LANG_Go = 0x0016, + DW_LANG_Modula3 = 0x0017, + DW_LANG_Haskel = 0x0018, + DW_LANG_C_plus_plus_03 = 0x0019, + DW_LANG_C_plus_plus_11 = 0x001a, + DW_LANG_OCaml = 0x001b, + DW_LANG_Rust = 0x001c, + DW_LANG_C11 = 0x001d, + DW_LANG_Swift = 0x001e, + DW_LANG_Julia = 0x001f, + DW_LANG_Dylan = 0x0020, + DW_LANG_C_plus_plus_14 = 0x0021, + DW_LANG_Fortran03 = 0x0022, + DW_LANG_Fortran08 = 0x0023, + DW_LANG_RenderScript = 0x0024, + DW_LANG_BLISS = 0x0025, + DW_LANG_lo_user = 0x8000, + DW_LANG_Mips_Assembler = 0x8001, + DW_LANG_Upc = 0x8765, + DW_LANG_SUN_Assembler = 0x9001, + DW_LANG_ALTIUM_Assembler = 0x9101, + DW_LANG_hi_user = 0xffff +}; + +enum Dwarf_ID_e { + DW_ID_case_sensitive = 0x0000, + DW_ID_up_case = 0x0001, + DW_ID_down_case = 0x0002, + DW_ID_case_insensitive = 0x0003 +}; + +enum Dwarf_CC_e { + DW_CC_normal = 0x0001, + DW_CC_program = 0x0002, + DW_CC_nocall = 0x0003, + DW_CC_pass_by_reference = 0x0004, + DW_CC_pass_by_value = 0x0005, + DW_CC_lo_user = 0x0040, + DW_CC_GNU_borland_fastcall_i386 = 0x0041, + DW_CC_ALTIUM_interrupt = 0x0065, + DW_CC_ALTIUM_near_system_stack = 0x0066, + DW_CC_ALTIUM_near_user_stack = 0x0067, + DW_CC_ALTIUM_huge_user_stack = 0x0068, + DW_CC_hi_user = 0x00ff +}; + +enum Dwarf_INL_e { + DW_INL_not_inlined = 0x0000, + DW_INL_inlined = 0x0001, + DW_INL_declared_not_inlined = 0x0002, + DW_INL_declared_inlined = 0x0003 +}; + +enum Dwarf_ORD_e { + DW_ORD_row_major = 0x0000, + DW_ORD_col_major = 0x0001 +}; + +enum Dwarf_DSC_e { + DW_DSC_label = 0x0000, + DW_DSC_range = 0x0001 +}; + +enum Dwarf_LNCT_e { + DW_LNCT_path = 0x0001, + DW_LNCT_directory_index = 0x0002, + DW_LNCT_timestamp = 0x0003, + DW_LNCT_size = 0x0004, + DW_LNCT_MD5 = 0x0005, + DW_LNCT_GNU_subprogram_name = 0x0006, + DW_LNCT_GNU_decl_file = 0x0007, + DW_LNCT_GNU_decl_line = 0x0008, + DW_LNCT_lo_user = 0x2000, + DW_LNCT_hi_user = 0x3fff +}; + +enum Dwarf_LNS_e { + DW_LNS_copy = 0x0001, + DW_LNS_advance_pc = 0x0002, + DW_LNS_advance_line = 0x0003, + DW_LNS_set_file = 0x0004, + DW_LNS_set_column = 0x0005, + DW_LNS_negate_stmt = 0x0006, + DW_LNS_set_basic_block = 0x0007, + DW_LNS_const_add_pc = 0x0008, + DW_LNS_fixed_advance_pc = 0x0009, + DW_LNS_set_prologue_end = 0x000a, + DW_LNS_set_epilogue_begin = 0x000b, + DW_LNS_set_isa = 0x000c, + DW_LNS_set_address_from_logical = 0x000d, + DW_LNS_inlined_call = 0x000e, + DW_LNS_pop_context = 0x000f +}; + +enum Dwarf_LNE_e { + DW_LNE_end_sequence = 0x0001, + DW_LNE_set_address = 0x0002, + DW_LNE_define_file = 0x0003, + DW_LNE_set_discriminator = 0x0004, + DW_LNE_HP_negate_is_UV_update = 0x0011, + DW_LNE_HP_push_context = 0x0012, + DW_LNE_HP_pop_context = 0x0013, + DW_LNE_HP_set_file_line_column = 0x0014, + DW_LNE_HP_set_routine_name = 0x0015, + DW_LNE_HP_set_sequence = 0x0016, + DW_LNE_HP_negate_post_semantics = 0x0017, + DW_LNE_HP_negate_function_exit = 0x0018, + DW_LNE_HP_negate_front_end_logical = 0x0019, + DW_LNE_HP_define_proc = 0x0020, + DW_LNE_HP_source_file_correlation = 0x0080, + DW_LNE_hi_user = 0x00ff +}; + +enum Dwarf_ISA_e { + DW_ISA_UNKNOWN = 0x0000, + DW_ISA_ARM_thumb = 0x0001, + DW_ISA_ARM_arm = 0x0002 +}; + +enum Dwarf_MACRO_e { + DW_MACRO_define = 0x0001, + DW_MACRO_undef = 0x0002, + DW_MACRO_start_file = 0x0003, + DW_MACRO_end_file = 0x0004, + DW_MACRO_define_strp = 0x0005, + DW_MACRO_undef_strp = 0x0006, + DW_MACRO_import = 0x0007, + DW_MACRO_define_sup = 0x0008, + DW_MACRO_undef_sup = 0x0009, + DW_MACRO_import_sup = 0x000a, + DW_MACRO_define_strx = 0x000b, + DW_MACRO_undef_strx = 0x000c, + DW_MACRO_lo_user = 0x00e0, + DW_MACRO_hi_user = 0x00ff +}; + +enum Dwarf_MACINFO_e { + DW_MACINFO_define = 0x0001, + DW_MACINFO_undef = 0x0002, + DW_MACINFO_start_file = 0x0003, + DW_MACINFO_end_file = 0x0004, + DW_MACINFO_vendor_ext = 0x00ff +}; + +enum Dwarf_CFA_e { + DW_CFA_extended = 0x0000, + DW_CFA_set_loc = 0x0001, + DW_CFA_advance_loc1 = 0x0002, + DW_CFA_advance_loc2 = 0x0003, + DW_CFA_advance_loc4 = 0x0004, + DW_CFA_offset_extended = 0x0005, + DW_CFA_restore_extended = 0x0006, + DW_CFA_undefined = 0x0007, + DW_CFA_same_value = 0x0008, + DW_CFA_register = 0x0009, + DW_CFA_remember_state = 0x000a, + DW_CFA_restore_state = 0x000b, + DW_CFA_def_cfa = 0x000c, + DW_CFA_def_cfa_register = 0x000d, + DW_CFA_def_cfa_offset = 0x000e, + DW_CFA_def_cfa_expression = 0x000f, + DW_CFA_expression = 0x0010, + DW_CFA_offset_extended_sf = 0x0011, + DW_CFA_def_cfa_sf = 0x0012, + DW_CFA_def_cfa_offset_sf = 0x0013, + DW_CFA_val_offset = 0x0014, + DW_CFA_val_offset_sf = 0x0015, + DW_CFA_val_expression = 0x0016, + DW_CFA_lo_user = 0x001c, + DW_CFA_MIPS_advance_loc8 = 0x001d, + DW_CFA_GNU_window_save = 0x002d, + DW_CFA_GNU_args_size = 0x002e, + DW_CFA_GNU_negative_offset_extended = 0x002f, + DW_CFA_METAWARE_info = 0x0034, + DW_CFA_high_user = 0x003f, + DW_CFA_advance_loc = 0x0040, + DW_CFA_offset = 0x0080, + DW_CFA_restore = 0x00c0 +}; + +enum Dwarf_EH_e { + DW_EH_PE_absptr = 0x0000, + DW_EH_PE_uleb128 = 0x0001, + DW_EH_PE_udata2 = 0x0002, + DW_EH_PE_udata4 = 0x0003, + DW_EH_PE_udata8 = 0x0004, + DW_EH_PE_sleb128 = 0x0009, + DW_EH_PE_sdata2 = 0x000a, + DW_EH_PE_sdata4 = 0x000b, + DW_EH_PE_sdata8 = 0x000c, + DW_EH_PE_pcrel = 0x0010, + DW_EH_PE_textrel = 0x0020, + DW_EH_PE_datarel = 0x0030, + DW_EH_PE_funcrel = 0x0040, + DW_EH_PE_aligned = 0x0050, + DW_EH_PE_omit = 0x00ff +}; + +enum Dwarf_FRAME_e { + DW_FRAME_CFA_COL = 0x0000, + DW_FRAME_REG1 = 0x0001, + DW_FRAME_REG2 = 0x0002, + DW_FRAME_REG3 = 0x0003, + DW_FRAME_REG4 = 0x0004, + DW_FRAME_REG5 = 0x0005, + DW_FRAME_REG6 = 0x0006, + DW_FRAME_REG7 = 0x0007, + DW_FRAME_REG8 = 0x0008, + DW_FRAME_REG9 = 0x0009, + DW_FRAME_REG10 = 0x0010, + DW_FRAME_REG11 = 0x0011, + DW_FRAME_REG12 = 0x0012, + DW_FRAME_REG13 = 0x0013, + DW_FRAME_REG14 = 0x0014, + DW_FRAME_REG15 = 0x0015, + DW_FRAME_REG16 = 0x0016, + DW_FRAME_REG17 = 0x0017, + DW_FRAME_REG18 = 0x0018, + DW_FRAME_REG19 = 0x0019, + DW_FRAME_REG20 = 0x0020, + DW_FRAME_REG21 = 0x0021, + DW_FRAME_REG22 = 0x0022, + DW_FRAME_REG23 = 0x0023, + DW_FRAME_REG24 = 0x0024, + DW_FRAME_REG25 = 0x0025, + DW_FRAME_REG26 = 0x0026, + DW_FRAME_REG27 = 0x0027, + DW_FRAME_REG28 = 0x0028, + DW_FRAME_REG29 = 0x0029, + DW_FRAME_REG30 = 0x0030, + DW_FRAME_REG31 = 0x0031, + DW_FRAME_FREG0 = 0x0032, + DW_FRAME_FREG1 = 0x0033, + DW_FRAME_FREG2 = 0x0034, + DW_FRAME_FREG3 = 0x0035, + DW_FRAME_FREG4 = 0x0036, + DW_FRAME_FREG5 = 0x0037, + DW_FRAME_FREG6 = 0x0038, + DW_FRAME_FREG7 = 0x0039, + DW_FRAME_FREG8 = 0x0040, + DW_FRAME_FREG9 = 0x0041, + DW_FRAME_FREG10 = 0x0042, + DW_FRAME_FREG11 = 0x0043, + DW_FRAME_FREG12 = 0x0044, + DW_FRAME_FREG13 = 0x0045, + DW_FRAME_FREG14 = 0x0046, + DW_FRAME_FREG15 = 0x0047, + DW_FRAME_FREG16 = 0x0048, + DW_FRAME_FREG17 = 0x0049, + DW_FRAME_FREG18 = 0x0050, + DW_FRAME_FREG19 = 0x0051, + DW_FRAME_FREG20 = 0x0052, + DW_FRAME_FREG21 = 0x0053, + DW_FRAME_FREG22 = 0x0054, + DW_FRAME_FREG23 = 0x0055, + DW_FRAME_FREG24 = 0x0056, + DW_FRAME_FREG25 = 0x0057, + DW_FRAME_FREG26 = 0x0058, + DW_FRAME_FREG27 = 0x0059, + DW_FRAME_FREG28 = 0x0060, + DW_FRAME_FREG29 = 0x0061, + DW_FRAME_FREG30 = 0x0062, + DW_FRAME_FREG31 = 0x0063, + DW_FRAME_FREG32 = 0x0064, + DW_FRAME_FREG33 = 0x0065, + DW_FRAME_FREG34 = 0x0066, + DW_FRAME_FREG35 = 0x0067, + DW_FRAME_FREG36 = 0x0068, + DW_FRAME_FREG37 = 0x0069, + DW_FRAME_FREG38 = 0x0070, + DW_FRAME_FREG39 = 0x0071, + DW_FRAME_FREG40 = 0x0072, + DW_FRAME_FREG41 = 0x0073, + DW_FRAME_FREG42 = 0x0074, + DW_FRAME_FREG43 = 0x0075, + DW_FRAME_FREG44 = 0x0076, + DW_FRAME_FREG45 = 0x0077, + DW_FRAME_FREG46 = 0x0078, + DW_FRAME_FREG47 = 0x0079, + DW_FRAME_FREG48 = 0x0080, + DW_FRAME_FREG49 = 0x0081, + DW_FRAME_FREG50 = 0x0082, + DW_FRAME_FREG51 = 0x0083, + DW_FRAME_FREG52 = 0x0084, + DW_FRAME_FREG53 = 0x0085, + DW_FRAME_FREG54 = 0x0086, + DW_FRAME_FREG55 = 0x0087, + DW_FRAME_FREG56 = 0x0088, + DW_FRAME_FREG57 = 0x0089, + DW_FRAME_FREG58 = 0x0090, + DW_FRAME_FREG59 = 0x0091, + DW_FRAME_FREG60 = 0x0092, + DW_FRAME_FREG61 = 0x0093, + DW_FRAME_FREG62 = 0x0094, + DW_FRAME_FREG63 = 0x0095, + DW_FRAME_FREG64 = 0x0096, + DW_FRAME_FREG65 = 0x0097, + DW_FRAME_FREG66 = 0x0098, + DW_FRAME_FREG67 = 0x0099, + DW_FRAME_FREG68 = 0x0100, + DW_FRAME_FREG69 = 0x0101, + DW_FRAME_FREG70 = 0x0102, + DW_FRAME_FREG71 = 0x0103, + DW_FRAME_FREG72 = 0x0104, + DW_FRAME_FREG73 = 0x0105, + DW_FRAME_FREG74 = 0x0106, + DW_FRAME_FREG75 = 0x0107, + DW_FRAME_FREG76 = 0x0108, + DW_FRAME_HIGHEST_NORMAL_REGISTER = 0x0188 +}; + +enum Dwarf_CHILDREN_e { + DW_CHILDREN_no = 0x0000, + DW_CHILDREN_yes = 0x0001 +}; + +enum Dwarf_ADDR_e { + DW_ADDR_none = 0x0000 +}; +#endif /* __DWARF_NAMES_ENUM_H__ */ + +/* END FILE */ diff --git a/thirdparty/dwarf/dwarf_names_new.h b/thirdparty/dwarf/dwarf_names_new.h new file mode 100644 index 00000000..9e84f08b --- /dev/null +++ b/thirdparty/dwarf/dwarf_names_new.h @@ -0,0 +1,51 @@ +/* Automatically generated, do not edit. */ +/* Generated sourcedate 2019-05-29 08:43:30-07:00 */ + +/* BEGIN FILE */ + +/* define DWARF_PRINT_PREFIX before this + point if you wish to. */ +#ifndef DWARF_PRINT_PREFIX +#define DWARF_PRINT_PREFIX dwarf_ +#endif +#define dw_glue(x,y) x##y +#define dw_glue2(x,y) dw_glue(x,y) +#define DWPREFIX(x) dw_glue2(DWARF_PRINT_PREFIX,x) +int DWPREFIX(get_TAG_name) (unsigned int, const char **); +int DWPREFIX(get_children_name) (unsigned int, const char **); +int DWPREFIX(get_FORM_name) (unsigned int, const char **); +int DWPREFIX(get_AT_name) (unsigned int, const char **); +int DWPREFIX(get_OP_name) (unsigned int, const char **); +int DWPREFIX(get_ATE_name) (unsigned int, const char **); +int DWPREFIX(get_DEFAULTED_name) (unsigned int, const char **); +int DWPREFIX(get_IDX_name) (unsigned int, const char **); +int DWPREFIX(get_LLEX_name) (unsigned int, const char **); +int DWPREFIX(get_LLE_name) (unsigned int, const char **); +int DWPREFIX(get_RLE_name) (unsigned int, const char **); +int DWPREFIX(get_UT_name) (unsigned int, const char **); +int DWPREFIX(get_SECT_name) (unsigned int, const char **); +int DWPREFIX(get_DS_name) (unsigned int, const char **); +int DWPREFIX(get_END_name) (unsigned int, const char **); +int DWPREFIX(get_ATCF_name) (unsigned int, const char **); +int DWPREFIX(get_ACCESS_name) (unsigned int, const char **); +int DWPREFIX(get_VIS_name) (unsigned int, const char **); +int DWPREFIX(get_VIRTUALITY_name) (unsigned int, const char **); +int DWPREFIX(get_LANG_name) (unsigned int, const char **); +int DWPREFIX(get_ID_name) (unsigned int, const char **); +int DWPREFIX(get_CC_name) (unsigned int, const char **); +int DWPREFIX(get_INL_name) (unsigned int, const char **); +int DWPREFIX(get_ORD_name) (unsigned int, const char **); +int DWPREFIX(get_DSC_name) (unsigned int, const char **); +int DWPREFIX(get_LNCT_name) (unsigned int, const char **); +int DWPREFIX(get_LNS_name) (unsigned int, const char **); +int DWPREFIX(get_LNE_name) (unsigned int, const char **); +int DWPREFIX(get_ISA_name) (unsigned int, const char **); +int DWPREFIX(get_MACRO_name) (unsigned int, const char **); +int DWPREFIX(get_MACINFO_name) (unsigned int, const char **); +int DWPREFIX(get_CFA_name) (unsigned int, const char **); +int DWPREFIX(get_EH_name) (unsigned int, const char **); +int DWPREFIX(get_FRAME_name) (unsigned int, const char **); +int DWPREFIX(get_CHILDREN_name) (unsigned int, const char **); +int DWPREFIX(get_ADDR_name) (unsigned int, const char **); + +/* END FILE */ diff --git a/thirdparty/dwarf/dwarf_object_detector.c b/thirdparty/dwarf/dwarf_object_detector.c new file mode 100644 index 00000000..979af6cf --- /dev/null +++ b/thirdparty/dwarf/dwarf_object_detector.c @@ -0,0 +1,585 @@ +/* Copyright (c) 2018-2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" +#include +#include /* open() */ +#include /* open() */ +#include /* O_RDONLY */ +#ifdef HAVE_UNISTD_H +#include /* lseek read close */ +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#include +typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ +#endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STRING_H +#include /* memcpy, strcpy */ +#endif /* HAVE_STRING_H */ + +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) +#include "stdafx.h" +#endif /* HAVE_STDAFX_H */ + +#include "libdwarf.h" +#include "memcpy_swap.h" +#include "dwarf_object_read_common.h" +#include "dwarf_object_detector.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif /* O_BINARY */ + +/* This is the main() program for the object_detector executable. */ + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif /* TRUE */ + +#ifndef O_RDONLY +#define O_RDONLY 0 +#endif + +/* TYP, SIZEOFT32 and ASNAR + mean we can use correctly-sized arrays of char for the + struct members instead of determing a proper integer + that size. + + We are dealing with carefully constructed structs + that do not have any alignment-forced (hidden) + unused bytes so reading lengths from the real structs + works for each variable. */ + +#define TYP(n,l) char n[l] +#define SIZEOFT32 4 + + +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 + +#ifndef EI_NIDENT +#define EI_NIDENT 16 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 +#endif /* EI_NIDENT */ + +#define DSYM_SUFFIX ".dSYM/Contents/Resources/DWARF/" +#define PATHSIZE 2000 + +#ifndef MH_MAGIC +/* mach-o 32bit */ +#define MH_MAGIC 0xfeedface +#define MH_CIGAM 0xcefaedfe +#endif /* MH_MAGIC */ +#ifndef MH_MAGIC_64 +/* mach-o 64bit */ +#define MH_MAGIC_64 0xfeedfacf +#define MH_CIGAM_64 0xcffaedfe +#endif /* MH_MAGIC_64 */ + +static unsigned long +magic_copy(unsigned char *d, unsigned len) +{ + unsigned i = 0; + unsigned long v = 0; + + v = d[0]; + for(i = 1 ; i < len; ++i) { + v <<= 8; + v |= d[i]; + } + return v; +} + + +#ifdef WORDS_BIGENDIAN +#define ASNAR(func,t,s) \ + do { \ + unsigned tbyte = sizeof(t) - sizeof(s); \ + t = 0; \ + func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ + } while (0) +#else /* LITTLE ENDIAN */ +#define ASNAR(func,t,s) \ + do { \ + t = 0; \ + func(&t,&s[0],sizeof(s)); \ + } while (0) +#endif /* end LITTLE- BIG-ENDIAN */ + + +#define EI_NIDENT 16 +/* An incomplete elf header, good for 32 and 64bit elf */ +struct elf_header { + unsigned char e_ident[EI_NIDENT]; + TYP(e_type,2); + TYP(e_machine,2); + TYP(e_version,4); +#ifdef HAVE_CUSTOM_LIBELF + /* In the case of custom ELF, use extra space */ + TYP(e_custom,64); +#endif /* HAVE_CUSTOM_LIBELF */ +}; + +/* Windows. Certain PE objects. + The following references may be of interest. +https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx #PE format overview and various machine magic numbers + +https://msdn.microsoft.com/en-us/library/ms809762.aspx # describes some details of PE headers, basically an overview + +https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx #defines sizes of various types + +https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680313(v=vs.85).aspx #defines IMAGE_FILE_HEADER and Machine fields (32/64) + +https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680305(v=vs.85).aspx #defines IMAGE_DATA_DIRECTORY + +https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx #Defines IMAGE_OPTIONAL_HEADER and some magic numbers + +https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680336(v=vs.85).aspx # defines _IMAGE_NT_HEADERS 32 64 + +https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx # defines _IMAGE_SECTION_HEADER + +*/ + +/* ===== START pe structures */ + +struct dos_header { + TYP(dh_mz,2); + TYP(dh_dos_data,58); + TYP(dh_image_offset,4); +}; + +#define IMAGE_DOS_SIGNATURE_dw 0x5A4D +#define IMAGE_DOS_REVSIGNATURE_dw 0x4D5A +#define IMAGE_NT_SIGNATURE_dw 0x00004550 +#define IMAGE_FILE_MACHINE_I386_dw 0x14c +#define IMAGE_FILE_MACHINE_IA64_dw 0x200 +#define IMAGE_FILE_MACHINE_AMD64_dw 0x8664 + + +struct pe_image_file_header { + TYP(im_machine,2); + TYP(im_sectioncount,2); + TYP(im_ignoring,(3*4)); + TYP(im_opt_header_size,2); + TYP(im_ignoringb,2); +}; + +/* ===== END pe structures */ + + +/* For following MacOS file naming convention */ +static const char * +getseparator (const char *f) +{ + const char *p = 0; + const char *q = 0; + char c = 0;; + + p = NULL; + q = f; + do { + c = *q++; + if (c == '\\' || c == '/' || c == ':') { + p = q; + } + } while (c); + return p; +} + +static const char * +getbasename (const char *f) +{ + const char *pseparator = getseparator (f); + if (!pseparator) { + return f; + } + return pseparator; +} + +/* Not a standard function, though part of GNU libc + since 2008 (I have never examined the GNU version). */ +static char * +dw_stpcpy(char *dest,const char *src) +{ + const char *cp = src; + char *dp = dest; + + for ( ; *cp; ++cp,++dp) { + *dp = *cp; + } + *dp = 0; + return dp; +} + + + +/* This started like Elf, so check initial fields. */ +static int +fill_in_elf_fields(struct elf_header *h, + unsigned *endian, + /* Size of the object file offsets, not DWARF offset + size. */ + unsigned *objoffsetsize, + int *errcode) +{ + unsigned locendian = 0; + unsigned locoffsetsize = 0; + + switch(h->e_ident[EI_CLASS]) { + case ELFCLASS32: + locoffsetsize = 32; + break; + case ELFCLASS64: + locoffsetsize = 64; + break; + default: + *errcode = DW_DLE_ELF_CLASS_BAD; + return DW_DLV_ERROR; + } + switch(h->e_ident[EI_DATA]) { + case ELFDATA2LSB: + locendian = DW_ENDIAN_LITTLE; + break; + case ELFDATA2MSB: + locendian = DW_ENDIAN_BIG; + break; + default: + *errcode = DW_DLE_ELF_ENDIAN_BAD; + return DW_DLV_ERROR; + } + if (h->e_ident[EI_VERSION] != 1 /* EV_CURRENT */) { + *errcode = DW_DLE_ELF_VERSION_BAD; + return DW_DLV_ERROR; + } + *endian = locendian; + *objoffsetsize = locoffsetsize; + return DW_DLV_OK; +} +static char archive_magic[8] = { +'!','<','a','r','c','h','>',0x0a +}; +static int +is_archive_magic(struct elf_header *h) { + int i = 0; + int len = sizeof(archive_magic); + const char *cp = (const char *)h; + for( ; i < len; ++i) { + if (cp[i] != archive_magic[i]) { + return FALSE; + } + } + return TRUE; +} + +/* A bit unusual in that it always sets *is_pe_flag + Return of DW_DLV_OK it is a PE file we recognize. */ +static int +is_pe_object(int fd, + unsigned long filesize, + unsigned *endian, + unsigned *offsetsize, + int *errcode) +{ + unsigned dos_sig = 0; + unsigned locendian = 0; + void (*word_swap) (void *, const void *, unsigned long); + unsigned long nt_address = 0; + struct dos_header dhinmem; + char nt_sig_array[4]; + unsigned long nt_sig = 0; + struct pe_image_file_header ifh; + int res = 0; + + if (filesize < (sizeof (struct dos_header) + + SIZEOFT32 + sizeof(struct pe_image_file_header))) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(fd,(char *)&dhinmem, + 0,sizeof(dhinmem),filesize,errcode); + if (res != DW_DLV_OK) { + return res; + } + /* No swap here, want it as in the file */ + dos_sig = magic_copy((unsigned char *)dhinmem.dh_mz, + sizeof(dhinmem.dh_mz)); + if (dos_sig == IMAGE_DOS_SIGNATURE_dw) { + /* IMAGE_DOS_SIGNATURE_dw assumes bytes reversed by little-endian + load, so we intrepet a match the other way. */ + /* BIG ENDIAN. From looking at hex characters in object */ +#ifdef WORDS_BIGENDIAN + word_swap = _dwarf_memcpy_noswap_bytes; +#else /* LITTLE ENDIAN */ + word_swap = _dwarf_memcpy_swap_bytes; +#endif /* LITTLE- BIG-ENDIAN */ + locendian = DW_ENDIAN_BIG; + } else if (dos_sig == IMAGE_DOS_REVSIGNATURE_dw) { + /* raw load, so intrepet a match the other way. */ + /* LITTLE ENDIAN */ +#ifdef WORDS_BIGENDIAN + word_swap = _dwarf_memcpy_swap_bytes; +#else /* LITTLE ENDIAN */ + word_swap = _dwarf_memcpy_noswap_bytes; +#endif /* LITTLE- BIG-ENDIAN */ + locendian = DW_ENDIAN_LITTLE; + } else { + /* Not dos header not a PE file we recognize */ + *errcode = DW_DLE_FILE_WRONG_TYPE; + return DW_DLV_ERROR; + } + ASNAR(word_swap,nt_address, dhinmem.dh_image_offset); + if (filesize < nt_address) { + /* Not dos header not a PE file we recognize */ + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + if (filesize < (nt_address + SIZEOFT32 + + sizeof(struct pe_image_file_header))) { + *errcode = DW_DLE_FILE_TOO_SMALL; + /* Not dos header not a PE file we recognize */ + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(fd,(char *)&nt_sig_array[0], + nt_address, sizeof(nt_sig_array),filesize,errcode); + if (res != DW_DLV_OK) { + return res; + } + { unsigned long lsig = 0; + + ASNAR(word_swap,lsig,nt_sig_array); + nt_sig = lsig; + } + if (nt_sig != IMAGE_NT_SIGNATURE_dw) { + *errcode = DW_DLE_FILE_WRONG_TYPE; + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(fd,(char *)&ifh, + nt_address + SIZEOFT32, + sizeof(struct pe_image_file_header), + filesize, + errcode); + if (res != DW_DLV_OK) { + return res; + } + { + unsigned long machine = 0; + + ASNAR(word_swap,machine,ifh.im_machine); + switch(machine) { + case IMAGE_FILE_MACHINE_I386_dw: + *offsetsize = 32; + *endian = locendian; + return DW_DLV_OK; + case IMAGE_FILE_MACHINE_IA64_dw: + case IMAGE_FILE_MACHINE_AMD64_dw: + *offsetsize = 64; + *endian = locendian; + return DW_DLV_OK; + } + } + *errcode = DW_DLE_IMAGE_FILE_UNKNOWN_TYPE; + return DW_DLV_ERROR; +} + +static int +is_mach_o_magic(struct elf_header *h, + unsigned *endian, + unsigned *offsetsize) +{ + unsigned long magicval = 0; + unsigned locendian = 0; + unsigned locoffsetsize = 0; + + /* No swapping here. Need to match size of + Mach-o magic field. */ + magicval = magic_copy(h->e_ident,4); + if (magicval == MH_MAGIC) { + locendian = DW_ENDIAN_BIG; + locoffsetsize = 32; + } else if (magicval == MH_CIGAM) { + locendian = DW_ENDIAN_LITTLE; + locoffsetsize = 32; + }else if (magicval == MH_MAGIC_64) { + locendian = DW_ENDIAN_BIG; + locoffsetsize = 64; + } else if (magicval == MH_CIGAM_64) { + locendian = DW_ENDIAN_LITTLE; + locoffsetsize = 64; + } else { + return FALSE; + } + *endian = locendian; + *offsetsize = locoffsetsize; + return TRUE; +} + +int +dwarf_object_detector_fd(int fd, + unsigned *ftype, + unsigned *endian, + unsigned *offsetsize, + Dwarf_Unsigned *filesize, + int *errcode) +{ + struct elf_header h; + size_t readlen = sizeof(h); + int res = 0; + off_t fsize = 0; + off_t lsval = 0; + ssize_t readval = 0; + + fsize = lseek(fd,0L,SEEK_END); + if(fsize < 0) { + *errcode = DW_DLE_SEEK_ERROR; + return DW_DLV_ERROR; + } + if (fsize <= (off_t)readlen) { + /* Not a real object file */ + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + lsval = lseek(fd,0L,SEEK_SET); + if(lsval < 0) { + *errcode = DW_DLE_SEEK_ERROR; + return DW_DLV_ERROR; + } + readval = read(fd,&h,readlen); + if (readval != (ssize_t)readlen) { + *errcode = DW_DLE_READ_ERROR; + return DW_DLV_ERROR; + } + if (h.e_ident[0] == 0x7f && + h.e_ident[1] == 'E' && + h.e_ident[2] == 'L' && + h.e_ident[3] == 'F') { + /* is ELF */ + + res = fill_in_elf_fields(&h,endian,offsetsize,errcode); + if (res != DW_DLV_OK) { + return res; + } + *ftype = DW_FTYPE_ELF; + *filesize = (size_t)fsize; + return DW_DLV_OK; + } + if (is_mach_o_magic(&h,endian,offsetsize)) { + *ftype = DW_FTYPE_MACH_O; + *filesize = (size_t)fsize; + return DW_DLV_OK; + } + if (is_archive_magic(&h)) { + *ftype = DW_FTYPE_ARCHIVE; + *filesize = (size_t)fsize; + return DW_DLV_OK; + } + res = is_pe_object(fd,fsize,endian,offsetsize,errcode); + if (res == DW_DLV_OK ) { + *ftype = DW_FTYPE_PE; + *filesize = (size_t)fsize; + return DW_DLV_OK; + } + /* Check for custom ELF format. */ +#ifdef HAVE_CUSTOM_LIBELF + res = elf_is_custom_format(&h,readlen,&fsize,endian,offsetsize,errcode); + if (res == DW_DLV_OK) { + *ftype = DW_FTYPE_CUSTOM_ELF; + *filesize = (size_t)fsize; + return res; + } +#endif /* HAVE_CUSTOM_LIBELF */ + + /* Unknown object format. */ + return DW_DLV_NO_ENTRY; +} + +int +dwarf_object_detector_path(const char *path, + char *outpath,unsigned long outpath_len, + unsigned *ftype, + unsigned *endian, + unsigned *offsetsize, + Dwarf_Unsigned *filesize, + int *errcode) +{ + char *cp = 0; + size_t plen = strlen(path); + size_t dsprefixlen = sizeof(DSYM_SUFFIX); + int fd = -1; + int res = 0; + int have_outpath = outpath && outpath_len; + +#if !defined(S_ISREG) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif +#if !defined(S_ISDIR) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif + + if (have_outpath) { + if ((2*plen + dsprefixlen +2) >= outpath_len) { + *errcode = DW_DLE_PATH_SIZE_TOO_SMALL; + return DW_DLV_ERROR; + } + cp = dw_stpcpy(outpath,path); + cp = dw_stpcpy(cp,DSYM_SUFFIX); + dw_stpcpy(cp,getbasename(path)); + fd = open(outpath,O_RDONLY|O_BINARY); + if (fd < 0) { + *outpath = 0; + fd = open(path,O_RDONLY|O_BINARY); + dw_stpcpy(outpath,path); + } + } else { + fd = open(path,O_RDONLY|O_BINARY); + } + if (fd < 0) { + if (have_outpath) { + *outpath = 0; + } + return DW_DLV_NO_ENTRY; + } + res = dwarf_object_detector_fd(fd, + ftype,endian,offsetsize,filesize,errcode); + if (res != DW_DLV_OK && have_outpath) { + *outpath = 0; + } + close(fd); + return res; +} diff --git a/thirdparty/dwarf/dwarf_object_detector.h b/thirdparty/dwarf/dwarf_object_detector.h new file mode 100644 index 00000000..8e75e25e --- /dev/null +++ b/thirdparty/dwarf/dwarf_object_detector.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef DWARF_OBJECT_DETECTOR_H +#define DWARF_OBJECT_DETECTOR_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Declares the interface function. + outpath is a place you provide, of a length outpath_len + you consider reasonable, + where the final path used is recorded. + outpath_len must be larger than strlen(path); + + This matters as for mach-o if the path is a directory + name the function will look in the standard macho-place + for the object file (useful for dSYM) and return the + constructed path in oupath. + returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY */ + +#ifndef DW_FTYPE_UNKNOWN +#define DW_FTYPE_UNKNOWN 0 +#define DW_FTYPE_ELF 1 +#define DW_FTYPE_MACH_O 2 +#define DW_FTYPE_PE 3 +#define DW_FTYPE_ARCHIVE 4 /* unix archive */ +#endif /* DW_FTYPE_UNKNOWN */ + +#ifndef DW_ENDIAN_UNKNOWN +#define DW_ENDIAN_UNKNOWN 0 +#define DW_ENDIAN_BIG 1 +#define DW_ENDIAN_LITTLE 2 +#endif /* DW_ENDIAN_UNKNOWN */ + +/* offsetsize refers to the object-file-format. + Elf 32 or macho-32 or PE 32, for example. + Not to DWARF offset sizes. */ + +/* Path means look(first) for an dynsym object + of the same name per MacOS standards, + making the outpath space needed is more than + that in path. + Copies the actual path into outpath, (an error + if the length in outpath_len is less than needed + for the object found). + For non-MacOS outpath will contain the string + taken from path. + + If DW_DLV_NO_ENTRY or DW_DLV_ERROR returned + the argument values other than path + must be considered to be in an unknown state. */ + +/* The errcode is a small integer distinct from libdwarf + and simply printing the integer (returned through + *errcode when the function returns DW_DLV_ERROR) + will hopefully suffice for most purposes. */ + +int dwarf_object_detector_path(const char *path, + char *outpath, + unsigned long outpath_len, + unsigned *ftype, + unsigned *endian, + unsigned *offsetsize, + Dwarf_Unsigned *filesize, + int * errcode); + +int dwarf_object_detector_fd(int fd, + unsigned *ftype, + unsigned *endian, + unsigned *offsetsize, + Dwarf_Unsigned *filesize, + int * errcode); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* DWARF_OBJECT_DETECTOR_H */ diff --git a/thirdparty/dwarf/dwarf_object_read_common.c b/thirdparty/dwarf/dwarf_object_read_common.c new file mode 100644 index 00000000..6d54e004 --- /dev/null +++ b/thirdparty/dwarf/dwarf_object_read_common.c @@ -0,0 +1,105 @@ +/* +Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif /* _WIN32 */ + +#include "config.h" +#include +#include /* memcpy */ +#include /* lseek and read */ +#ifdef HAVE_UNISTD_H +#include /* lseek read close */ +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#include +typedef SSIZE_T ssize_t; /* MSVC does not have POSIX ssize_t */ +#endif /* HAVE_UNISTD_H */ + +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) +#include "stdafx.h" +#endif /* HAVE_STDAFX_H */ + +#include "libdwarf.h" /* For error codes. */ +#include "dwarf_object_read_common.h" + +/* Neither off_t nor ssize_t is in C90. + However, both are in Posix: + IEEE Std 1003.1-1990, aka + ISO/IEC 9954-1:1990. */ +int +_dwarf_object_read_random(int fd, char *buf, off_t loc, + size_t size, off_t filesize, int *errc) +{ + off_t scode = 0; + ssize_t rcode = 0; + off_t endpoint = 0; + + if (loc >= filesize) { + /* Seek can seek off the end. Lets not allow that. + The object is corrupt. */ + *errc = DW_DLE_SEEK_OFF_END; + return DW_DLV_ERROR; + } + endpoint = loc+size; + if (endpoint > filesize) { + /* Let us -not- try to read past end of object. + The object is corrupt. */ + *errc = DW_DLE_READ_OFF_END; + return DW_DLV_ERROR; + } + scode = lseek(fd,loc,SEEK_SET); + if (scode == (off_t)-1) { + *errc = DW_DLE_SEEK_ERROR; + return DW_DLV_ERROR; + } + rcode = read(fd,buf,size); + if (rcode == -1 || + (size_t)rcode != size) { + *errc = DW_DLE_READ_ERROR; + return DW_DLV_ERROR; + } + return DW_DLV_OK; +} + +void +_dwarf_safe_strcpy(char *out, long outlen, const char *in, long inlen) +{ + if (inlen >= (outlen - 1)) { + strncpy(out, in, outlen - 1); + out[outlen - 1] = 0; + } else { + strcpy(out, in); + } +} diff --git a/thirdparty/dwarf/dwarf_object_read_common.h b/thirdparty/dwarf/dwarf_object_read_common.h new file mode 100644 index 00000000..d19c4c92 --- /dev/null +++ b/thirdparty/dwarf/dwarf_object_read_common.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef DWARF_OBJECT_READ_COMMON_H +#define DWARF_OBJECT_READ_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +int _dwarf_object_read_random(int fd,char *buf,off_t loc, + size_t size,off_t filesize,int *errc); + +void _dwarf_safe_strcpy(char *out, long outlen, + const char *in, long inlen); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DWARF_OBJECT_READ_COMMON_H */ diff --git a/thirdparty/dwarf/dwarf_opaque.h b/thirdparty/dwarf/dwarf_opaque.h index 1b8f3067..d4f27ca0 100644 --- a/thirdparty/dwarf/dwarf_opaque.h +++ b/thirdparty/dwarf/dwarf_opaque.h @@ -1,7 +1,6 @@ /* - Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2013 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. This program is free software; you can redistribute it and/or modify it @@ -40,12 +39,15 @@ .debug_info 2 3 4 5 .debug_line 2 3 4 5 .debug_line_str - - - 5 - .debug_loc * * * 5 + .debug_loc * * * - + .debug_loclists - - - 5 .debug_macinfo * * * - .debug_macro - - - 5 + .debug_names - - - 5 .debug_pubnames 2 2 2 - .debug_pubtypes - 2 2 - - .debug_ranges - * * 5 + .debug_ranges - * * - + .debug_rnglists - - - 5 .debug_str * * * * .debug_str_offsets - - - 5 .debug_sup - - - 5 @@ -54,8 +56,10 @@ .debug_abbrev.dwo - - - * .debug_info.dwo - - - 5 .debug_line.dwo - - - 5 - .debug_loc.dwo - - - 5 + .debug_loc.dwo - - - - + .debug_loclists.dwo - - - 5 .debug_macro.dwo - - - 5 + .debug_rnglists.dwo - - - 5 .debug_str.dwo - - - * .debug_str_offsets.dwo - - - 5 @@ -64,8 +68,6 @@ */ -#include - /* The 'debug_info' names below are non-zero (non-NULL) only if we are processing a debug_info section. And vice versa for a debug_types section. */ @@ -92,6 +94,9 @@ struct Dwarf_Attribute_s { /* The following points to either debug_info or debug_types depending on if context is cc_is_info or not. */ Dwarf_Small *ar_debug_ptr; + /* If DW_FORM_implicit const, the value is here, not + in the DIE. */ + Dwarf_Signed ar_implicit_const; Dwarf_Die ar_die;/* Access to the DIE owning the attribute */ Dwarf_Attribute ar_next; @@ -170,19 +175,23 @@ struct Dwarf_CU_Context_s { Dwarf_Unsigned cc_debug_offset; /* cc_signature is in the TU header - of a type unit of a TU DIE. + of a type unit of a TU DIE (or for DW5 in the + skeleton or split_compile header is a dwo_id). Ignore this field if cc_signature_present is zero. If cc_unit_type == DW_UT_compile or DW_UT_partial - the signature is a CU signature. - If cc_unit_type == DW_UT_type + the signature is a CU signature (dwo_id). + Some early DW5 drafts encouraged DWARF4 output + of some compilers to include dwo_id, but + in a messier way(lacking DW_UT_*). + If cc_unit_type == DW_UT_type or DW_UT_split_type the signature is a type signature. */ Dwarf_Sig8 cc_type_signature; - /* cc_typeoffsets contains the + /* cc_type_signature_offset contains the section-local DIE offset of the type the signature applies to if the cc_unit_type - is DW_UT_type. */ + is DW_UT_type or DW_UT_split_type. */ Dwarf_Unsigned cc_type_signature_offset; /* For each CU and each TU @@ -211,7 +220,7 @@ struct Dwarf_CU_Context_s { This base field created in DWARF5 to reduce the number of string offset relocations a linker must do. - DW_AT_ranges_base similarly. + DW_AT_rnglists_base (briefly called DW_AT_ranges_base) similarly. Within the CU, this base means that DW_FORM_sec_offset values need not be realocated by the linker. @@ -234,7 +243,7 @@ struct Dwarf_CU_Context_s { /* FIXME from DW_AT_addr_base in CU DIE */ Dwarf_Unsigned cc_addr_base; /* Zero in .dwo */ - /* FIXME from DW_AT_ranges_base in CU DIE */ + /* FIXME from DW_AT_rnglists_base in CU DIE */ Dwarf_Unsigned cc_ranges_base; /* Zero in .dwo */ /* FIXME from DW_AT_str_offsets_base in CU DIE */ Dwarf_Unsigned cc_str_offsets_base; @@ -261,10 +270,6 @@ struct Dwarf_CU_Context_s { For DWARF 2,3,4 this is filled in initially from the CU header and refined by inspecting the TAG of the CU DIE to detect DW_UT_partial is applicable. */ - - /* If non-zero is the DW_AT_comp_dir string from - the DWARF data. Do not free. */ - const char * cc_at_comp_dir; }; /* Consolidates section-specific data in one place. @@ -282,7 +287,7 @@ struct Dwarf_Section_s { Dwarf_Unsigned dss_entrysize; /* dss_index is the section index as things are numbered in an object file being read. An Elf section number. */ - Dwarf_Word dss_index; + Dwarf_Unsigned dss_index; /* dss_addr is the 'section address' which is only non-zero for a GNU eh section. Purpose: to handle DW_EH_PE_pcrel encoding. Leaving @@ -293,25 +298,43 @@ struct Dwarf_Section_s { detect duplicates. Ignored after setup done. */ Dwarf_Small dss_is_in_use; + /* When loading COMDAT they refer (sometimes) to + base sections, so we need to have the BASE + group sections filled in when the corresponding is + not in the COMDAT group list. .debug_abbrev is + an example. */ + Dwarf_Unsigned dss_group_number; + + /* These for reporting compression */ + Dwarf_Unsigned dss_uncompressed_length; + Dwarf_Unsigned dss_compressed_length; + /* If this is zdebug, to start data/size are the raw section bytes. Initially for all sections dss_data_was_malloc set FALSE and dss_requires_decompress set FALSE. - For zdebug dss_requires_decompress then set TRUE + For zdebug set dss_zdebug_requires_decompress set TRUE + In that case it is likely ZLIB compressed but + we do not know that just scanning section headers. + If not .zdebug but it is SHF_COMPRESSED + then decompress is required. On translation (ie zlib use and malloc) Set dss_data dss_size to point to malloc space and malloc size. - Set dss_requires_decompress FALSE + Set dss_did_decompress FALSE Set dss_was_malloc TRUE */ - Dwarf_Small dss_requires_decompress; + Dwarf_Small dss_zdebug_requires_decompress; + Dwarf_Small dss_did_decompress; + Dwarf_Small dss_shf_compressed; /* section flag SHF_COMPRESS */ + Dwarf_Small dss_ZLIB_compressed; /* Section compression starts with ZLIB chars*/ /* For non-elf, leaving the following fields zero will mean they are ignored. */ /* dss_link should be zero unless a section has a link to another (sh_link). Used to access relocation data for a section (and for symtab section, access its strtab). */ - Dwarf_Word dss_link; + Dwarf_Unsigned dss_link; /* The following is used when reading .rela sections (such sections appear in some .o files). */ Dwarf_Half dss_reloc_index; /* Zero means ignore the reloc fields. */ @@ -325,13 +348,14 @@ struct Dwarf_Section_s { /* dss_reloc_link should be zero unless a reloc section has a link to another (sh_link). Used to access the symtab for relocations a section. */ - Dwarf_Word dss_reloc_link; + Dwarf_Unsigned dss_reloc_link; /* Pointer to the elf symtab, used for elf .rela. Leave it 0 if not relevant. */ struct Dwarf_Section_s *dss_symtab; - /* dss_name must never be freed, it is a quoted string - in libdwarf. */ + /* dss_name, dss_standard_name must never be freed, + they are static strings in libdwarf. */ const char * dss_name; + const char * dss_standard_name; /* Object section number in object file. */ unsigned dss_number; @@ -340,8 +364,13 @@ struct Dwarf_Section_s { just leave these fields zero. Which is essentially automatic as they are not in Dwarf_Obj_Access_Section_s. */ - Dwarf_Word dss_flags; - Dwarf_Word dss_addralign; + Dwarf_Unsigned dss_flags; + Dwarf_Unsigned dss_addralign; + + /* Set when loading .group section as those are special and + neither compressed nor have relocations so never malloc + space for libdwarf. */ + Dwarf_Small dss_ignore_reloc_group_sec; }; /* Overview: if next_to_use== first, no error slots are used. @@ -404,10 +433,11 @@ struct Dwarf_dbg_sect_s { (or the like) of the dbg struct. */ struct Dwarf_Section_s *ds_secdata; + unsigned ds_groupnumber; int ds_duperr; /* Error code for duplicated section */ int ds_emptyerr; /* Error code for empty section */ int ds_have_dwarf; /* Section contains DWARF */ - int ds_have_zdebug; /* Section compressed. */ + int ds_have_zdebug; /* Section compressed: .zdebug name */ }; /* As the number of debug sections does not change very often, in the case a @@ -420,7 +450,6 @@ struct Dwarf_dbg_sect_s { #define DWARF_MAX_DEBUG_SECTIONS 50 - /* These offsets and sizes (Dwarf_Fission*) are for the DebugFission DWP sections .debug_cu_index and .debug_tu_index. @@ -522,6 +551,24 @@ struct Dwarf_Tied_Data_s { }; +/* dg_groupnum 0 does not exist. + dg_groupnum 1 is base + dg_groupnum 2 is dwo + dg_groupnum 3 and higher are COMDAT groups (if any). + */ +struct Dwarf_Group_Data_s { + /* For traditional DWARF the value is one, just one group. */ + unsigned gd_number_of_groups; + + /* Raw elf (elf-like) section count. */ + unsigned gd_number_of_sections; + + unsigned gd_map_entry_count; + + /* A map from section number to group number. */ + void *gd_map; +}; + struct Dwarf_Debug_s { /* All file access methods and support data are hidden in this structure. @@ -532,15 +579,37 @@ struct Dwarf_Debug_s { Dwarf_Handler de_errhand; Dwarf_Ptr de_errarg; + /* Enabling us to close an fd if we own it, + as in the case of dwarf_init_path(). + de_fd is only meaningful + if de_owns_fd is set. Each object + file type has any necessary fd recorded + under de_obj_file. */ + int de_fd; + char de_owns_fd; + struct Dwarf_Debug_InfoTypes_s de_info_reading; struct Dwarf_Debug_InfoTypes_s de_types_reading; + /* DW_GROUPNUMBER_ANY, DW_GROUPNUMBER_BASE, DW_GROUPNUMBER_DWO, + or a comdat group number > 2 + Selected at init time of this dbg based on + user request and on data in the object. */ + unsigned de_groupnumber; + + /* Supporting data for groupnumbers. */ + struct Dwarf_Group_Data_s de_groupnumbers; + /* Number of bytes in the length, and offset field in various - .debug_* sections. It's not very meaningful, and is + .debu* sections. It's not very meaningful, and is only used in one 'approximate' calculation. de_offset_size would be a more appropos name. */ Dwarf_Small de_length_size; + /* Size of the object file in bytes. If Unknown + leave this zero. */ + Dwarf_Unsigned de_filesize; + /* number of bytes in a pointer of the target in various .debug_ sections. 4 in 32bit, 8 in MIPS 64, ia64. */ Dwarf_Small de_pointer_size; @@ -579,11 +648,13 @@ struct Dwarf_Debug_s { struct Dwarf_Section_s de_debug_loc; struct Dwarf_Section_s de_debug_aranges; struct Dwarf_Section_s de_debug_macinfo; - struct Dwarf_Section_s de_debug_macro; /* New in DWARF5 */ - struct Dwarf_Section_s de_debug_names; /* New in DWARF5 */ + struct Dwarf_Section_s de_debug_macro; /* New in DWARF5 */ + struct Dwarf_Section_s de_debug_names; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_pubnames; struct Dwarf_Section_s de_debug_str; - struct Dwarf_Section_s de_debug_sup; /* New in DWARF5 */ + struct Dwarf_Section_s de_debug_sup; /* New in DWARF5 */ + struct Dwarf_Section_s de_debug_loclists; /* New in DWARF5 */ + struct Dwarf_Section_s de_debug_rnglists; /* New in DWARF5 */ struct Dwarf_Section_s de_debug_frame; /* gnu: the g++ eh_frame section */ @@ -601,7 +672,7 @@ struct Dwarf_Debug_s { struct Dwarf_Section_s de_debug_weaknames; struct Dwarf_Section_s de_debug_ranges; - /* Following two part of DebugFission. */ + /* Following two part of DebugFission and DWARF5 */ struct Dwarf_Section_s de_debug_str_offsets; struct Dwarf_Section_s de_debug_addr; @@ -631,7 +702,7 @@ struct Dwarf_Debug_s { Dwarf_Xu_Index_Header de_cu_hashindex_data; Dwarf_Xu_Index_Header de_tu_hashindex_data; - void *(*de_copy_word) (void *, const void *, size_t); + void (*de_copy_word) (void *, const void *, unsigned long); unsigned char de_same_endian; unsigned char de_elf_must_close; /* If non-zero, then it was dwarf_init (not dwarf_elf_init) @@ -650,12 +721,25 @@ struct Dwarf_Debug_s { unsigned char de_big_endian_object; /* Non-zero if big-endian object opened. */ + /* Non-zero if dwarf_get_globals(), dwarf_get_funcs, + dwarf_get_types,dwarf_get_pubtypes, + dwarf_get_vars,dwarf_get_weaks should create + and return a special zero-die-offset for the + corresponding pubnames-style section CU header with + zero pubnames-style named DIEs. In that case the + list returned will have an entry with a zero for + the die-offset (which is an impossible debug_info + die_offset). New March 2019. + See dwarf_return_empty_pubnames() */ + unsigned char de_return_empty_pubnames; + struct Dwarf_dbg_sect_s de_debug_sections[DWARF_MAX_DEBUG_SECTIONS]; unsigned de_debug_sections_total_entries; /* Number actually used. */ struct Dwarf_Harmless_s de_harmless_errors; struct Dwarf_Printf_Callback_Info_s de_printf_callback; + void * de_printf_callback_null_device_handle; struct Dwarf_Tied_Data_s de_tied_data; @@ -680,16 +764,17 @@ struct Dwarf_Chain_o { }; /* Size of cu header version stamp field. */ -#define CU_VERSION_STAMP_SIZE sizeof(Dwarf_Half) +#define CU_VERSION_STAMP_SIZE DWARF_HALF_SIZE /* Size of cu header address size field. */ #define CU_ADDRESS_SIZE_SIZE sizeof(Dwarf_Small) -void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); - #define ORIGINAL_DWARF_OFFSET_SIZE 4 +/* The DISTINGUISHED VALUE is 4 byte value defined by DWARF + since DWARF3. */ #define DISTINGUISHED_VALUE 0xffffffff #define DISTINGUISHED_VALUE_OFFSET_SIZE 8 +#define DISTINGUISHED_VALUE_ARRAY(x) char x[4] = { 0xff,0xff,0xff,0xff } /* We don't load the sections until they are needed. This function is used to load the section. */ @@ -703,8 +788,9 @@ int _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, Dwarf_Unsigned *sbase_out, Dwarf_Error *error); -int _dwarf_exract_string_offset_via_str_offsets(Dwarf_Debug dbg, - Dwarf_Small *info_data_ptr, +int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, + Dwarf_Small *data_ptr, + Dwarf_Small *end_data_ptr, Dwarf_Half attrnum, Dwarf_Half attrform, Dwarf_CU_Context cu_context, @@ -718,14 +804,6 @@ int _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg, Dwarf_Addr *addr_out, Dwarf_Error *error); -int _dwarf_extract_string_offset_via_str_offsets(Dwarf_Debug dbg, - Dwarf_Small *info_data_ptr, - Dwarf_Half attrnum, - Dwarf_Half attrform, - Dwarf_CU_Context cu_context, - Dwarf_Unsigned *str_sect_offset_out, - Dwarf_Error *error); - int _dwarf_get_base_and_size_given_signature(Dwarf_CU_Context *context, Dwarf_Sig8 *signature_in, /* xu_sect_index means DW_SECT_info etc. */ @@ -780,6 +858,33 @@ _dwarf_search_for_signature(Dwarf_Debug dbg, void _dwarf_tied_destroy_free_node(void *node); +void _dwarf_destroy_group_map(Dwarf_Debug dbg); + +int _dwarf_section_get_target_group(Dwarf_Debug dbg, + unsigned obj_section_index, + unsigned * groupnumber, + Dwarf_Error * error); + +int _dwarf_dwo_groupnumber_given_name( + const char *name, + unsigned *grpnum_out); + +int _dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, + unsigned obj_section_index, + unsigned * groupnumber_out, + UNUSEDARG Dwarf_Error * error); + +int _dwarf_insert_in_group_map(Dwarf_Debug dbg, + unsigned groupnum, + unsigned section_index, + const char *name, + Dwarf_Error * error); + +/* returns TRUE/FALSE: meaning this section name is in + map for this groupnum or not.*/ +int _dwarf_section_in_group_by_name(Dwarf_Debug dbg, + const char * scn_name, + unsigned groupnum); int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, @@ -823,20 +928,92 @@ int _dwarf_extract_local_debug_str_string_given_offset(Dwarf_Debug dbg, int _dwarf_file_name_is_full_path(Dwarf_Small *fname); -/* This is an elf-only extension to get SHF_COMPRESSED flag from sh_flags. +/* This is an elf-only extension to + get SHF_COMPRESSED flag from sh_flags. if pointer not set (which is normal for non-elf objects) it is fine. */ -int (*_dwarf_get_elf_flags_func_ptr)( +typedef int (*_dwarf_get_elf_flags_func_ptr_type)( void* obj_in, Dwarf_Half section_index, Dwarf_Unsigned *flags_out, Dwarf_Unsigned *addralign_out, int *error); +extern _dwarf_get_elf_flags_func_ptr_type _dwarf_get_elf_flags_func_ptr; + +/* This is libelf access to Elf object. */ +extern int _dwarf_elf_setup(int fd, + char *true_path_out_buffer, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error); + +/* This is non-libelf Elf access */ +extern int +_dwarf_elf_nlsetup(int fd, + char *true_path, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error); +void _dwarf_destruct_elf_nlaccess(struct Dwarf_Obj_Access_Interface_s *aip); + +extern int _dwarf_macho_setup(int fd, + char *true_path, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error); +void _dwarf_destruct_macho_access(struct Dwarf_Obj_Access_Interface_s *aip); + +extern int _dwarf_pe_setup(int fd, + char *path, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error); +void _dwarf_destruct_pe_access(struct Dwarf_Obj_Access_Interface_s *aip); + +extern Dwarf_Bool _dwarf_allow_formudata(unsigned form); +extern int _dwarf_formudata_internal(Dwarf_Debug dbg, + unsigned form, + Dwarf_Byte_Ptr data, + Dwarf_Byte_Ptr section_end, + Dwarf_Unsigned *return_uval, + Dwarf_Unsigned *bytes_read, + Dwarf_Error *error); Dwarf_Byte_Ptr _dwarf_calculate_info_section_start_ptr(Dwarf_CU_Context context, Dwarf_Unsigned *section_len_out); Dwarf_Byte_Ptr _dwarf_calculate_info_section_end_ptr(Dwarf_CU_Context context); Dwarf_Byte_Ptr _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context); -void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno); +int _dwarf_extract_data16(Dwarf_Debug dbg, + Dwarf_Small *data, + Dwarf_Small *section_start, + Dwarf_Small *section_end, + Dwarf_Form_Data16 * returned_val, + Dwarf_Error *error); + +void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno); diff --git a/thirdparty/dwarf/dwarf_original_elf_init.c b/thirdparty/dwarf/dwarf_original_elf_init.c index f9a70628..36d40fdc 100644 --- a/thirdparty/dwarf/dwarf_original_elf_init.c +++ b/thirdparty/dwarf/dwarf_original_elf_init.c @@ -28,12 +28,6 @@ */ #include "config.h" -#include "dwarf_incl.h" -#include "dwarf_elf_access.h" - -#ifdef HAVE_ELF_H -#include -#endif #ifdef HAVE_LIBELF_H #include #else @@ -41,113 +35,154 @@ #include #endif #endif - #include #include #include #include #include +#include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_elf_access.h" +#include "dwarf_object_detector.h" + + #define DWARF_DBG_ERROR(dbg,errval,retval) \ _dwarf_error(dbg, error, errval); return(retval); #define FALSE 0 #define TRUE 1 -static int -dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer, - int libdwarf_owns_elf, +/* New March 2017 */ +int +dwarf_elf_init_b( +#ifndef DWARF_WITH_LIBELF + UNUSEDARG dwarf_elf_handle elf_file_pointer, + UNUSEDARG Dwarf_Unsigned access, + UNUSEDARG unsigned group_number, + UNUSEDARG Dwarf_Handler errhand, + UNUSEDARG Dwarf_Ptr errarg, + UNUSEDARG Dwarf_Debug * ret_dbg, +#else + dwarf_elf_handle elf_file_pointer, Dwarf_Unsigned access, + unsigned group_number, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, - Dwarf_Error * error); - - -/* The basic dwarf initializer function for consumers using - libelf. - Return a libdwarf error code on error, return DW_DLV_OK - if this succeeds. */ -int -dwarf_init(int fd, - Dwarf_Unsigned access, - Dwarf_Handler errhand, - Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) +#endif /* DWARF_WITH_LIBELF */ + Dwarf_Error * error) { - struct stat fstat_buf; - dwarf_elf_handle elf_file_pointer = 0; - /* ELF_C_READ is a portable value */ - Elf_Cmd what_kind_of_elf_read = ELF_C_READ; - -#if !defined(S_ISREG) -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - if (fstat(fd, &fstat_buf) != 0) { - DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR); - } - if (!S_ISREG(fstat_buf.st_mode)) { - DWARF_DBG_ERROR(NULL, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR); - } +#ifndef DWARF_WITH_LIBELF + DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR); +#else /* DWARF_WITH_LIBELF */ + Dwarf_Obj_Access_Interface *binary_interface = 0; + int res = DW_DLV_OK; + int localerrnum = 0; + int libdwarf_owns_elf = FALSE; if (access != DW_DLC_READ) { DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); } - elf_version(EV_CURRENT); - /* Changed to mmap request per bug 281217. 6/95 */ -#ifdef HAVE_ELF_C_READ_MMAP - /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX - libelf.h meaning read but use mmap. - It is never necessary -- it is just a convenience. - HAVE_ELF_C_READ_MMAP has not been in config.h via - configure since 2004 at least. */ - what_kind_of_elf_read = ELF_C_READ_MMAP; -#endif /* !HAVE_ELF_C_READ_MMAP */ - - elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0); - if (elf_file_pointer == NULL) { - DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); + /* This allocates and fills in *binary_interface. */ + res = dwarf_elf_object_access_init( + elf_file_pointer, + libdwarf_owns_elf, + &binary_interface, + &localerrnum); + if (res != DW_DLV_OK) { + if (res == DW_DLV_NO_ENTRY) { + return res; + } + DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR); } - return dwarf_elf_init_file_ownership(elf_file_pointer, - TRUE, access, errhand, errarg, ret_dbg, error); + /* allocates and initializes Dwarf_Debug */ + res = dwarf_object_init_b(binary_interface, errhand, errarg, + group_number, + ret_dbg, error); + if (res != DW_DLV_OK){ + dwarf_elf_object_access_finish(binary_interface); + return res; + } + /* DBG known */ + return res; +#endif /* DWARF_WITH_LIBELF */ } -/* An alternate dwarf setup call for consumers using - libelf. - When the caller has opened libelf already, so the - caller must free libelf. */ int -dwarf_elf_init(dwarf_elf_handle elf_file_pointer, +dwarf_elf_init( +#ifndef DWARF_WITH_LIBELF + UNUSEDARG dwarf_elf_handle elf_file_pointer, + UNUSEDARG Dwarf_Unsigned access, + UNUSEDARG Dwarf_Handler errhand, + UNUSEDARG Dwarf_Ptr errarg, + UNUSEDARG Dwarf_Debug * ret_dbg, +#else + dwarf_elf_handle elf_file_pointer, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, - Dwarf_Debug * ret_dbg, Dwarf_Error * error) + Dwarf_Debug * ret_dbg, +#endif + Dwarf_Error * error) { - return dwarf_elf_init_file_ownership(elf_file_pointer, - FALSE, access, errhand, errarg, ret_dbg, error); +#ifndef DWARF_WITH_LIBELF + DWARF_DBG_ERROR(NULL, DW_DLE_NO_ELF_SUPPORT, DW_DLV_ERROR); +#else /* DWARF_WITH_LIBELF */ + int res = 0; + res = dwarf_elf_init_b(elf_file_pointer, + DW_GROUPNUMBER_ANY, + access,errhand,errarg,ret_dbg,error); + return res; +#endif /* DWARF_WITH_LIBELF */ } - -/* Initialize the ELF object access for libdwarf. */ -static int -dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer, - int libdwarf_owns_elf, - Dwarf_Unsigned access, +int +_dwarf_elf_setup( +#ifndef DWARF_WITH_LIBELF + UNUSEDARG int fd, + UNUSEDARG char *path, + UNUSEDARG unsigned ftype, + UNUSEDARG unsigned endian, + UNUSEDARG unsigned offsetsize, + UNUSEDARG size_t filesize, + UNUSEDARG Dwarf_Unsigned access, + UNUSEDARG unsigned groupnumber, + UNUSEDARG Dwarf_Handler errhand, + UNUSEDARG Dwarf_Ptr errarg, + UNUSEDARG Dwarf_Debug *dbg, +#else + int fd, + UNUSEDARG char *path, + UNUSEDARG unsigned ftype, + UNUSEDARG unsigned endian, + UNUSEDARG unsigned offsetsize, + size_t filesize, + UNUSEDARG Dwarf_Unsigned access, + unsigned groupnumber, Dwarf_Handler errhand, Dwarf_Ptr errarg, - Dwarf_Debug * ret_dbg, - Dwarf_Error * error) + Dwarf_Debug *dbg, +#endif /* DWARF_WITH_LIBELF */ + Dwarf_Error *error) { - /* ELF is no longer tied to libdwarf. */ +#ifndef DWARF_WITH_LIBELF + DWARF_DBG_ERROR(NULL, DW_DLE_PRODUCER_CODE_NOT_AVAILABLE, DW_DLV_ERROR); +#else /* DWARF_WITH_LIBELF */ + Elf_Cmd what_kind_of_elf_read = ELF_C_READ; Dwarf_Obj_Access_Interface *binary_interface = 0; int res = DW_DLV_OK; int localerrnum = 0; + int libdwarf_owns_elf = TRUE; + dwarf_elf_handle elf_file_pointer = 0; - if (access != DW_DLC_READ) { - DWARF_DBG_ERROR(NULL, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); + elf_version(EV_CURRENT); + elf_file_pointer = elf_begin(fd, what_kind_of_elf_read, 0); + if (elf_file_pointer == NULL) { + DWARF_DBG_ERROR(NULL, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); } - - /* This allocates and fills in *binary_interface. */ + /* Sets up elf access function pointers. */ res = dwarf_elf_object_access_init( elf_file_pointer, libdwarf_owns_elf, @@ -159,65 +194,15 @@ dwarf_elf_init_file_ownership(dwarf_elf_handle elf_file_pointer, } DWARF_DBG_ERROR(NULL, localerrnum, DW_DLV_ERROR); } - - /* This mallocs space and returns pointer thru ret_dbg, - saving the binary interface in 'ret-dbg' */ - res = dwarf_object_init(binary_interface, errhand, errarg, - ret_dbg, error); + /* allocates and initializes Dwarf_Debug */ + res = dwarf_object_init_b(binary_interface, errhand, errarg, + groupnumber, + dbg, error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); + } else { + (*dbg)->de_filesize = filesize; } return res; -} - - -/* - Frees all memory that was not previously freed - by dwarf_dealloc. - Aside from certain categories. - - This is only applicable when dwarf_init() or dwarf_elf_init() - was used to init 'dbg'. -*/ -int -dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) -{ - if(!dbg) { - DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); - } - dwarf_elf_object_access_finish(dbg->de_obj_file); - - return dwarf_object_finish(dbg, error); -} - -/* - tieddbg should be the executable or .o - that has the .debug_addr section that - the base dbg refers to. See Split Objects in DWARF5. - - Allows setting to NULL (NULL is the default - of de_tied_data.td_tied_object). - New September 2015. -*/ -int -dwarf_set_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug tieddbg,Dwarf_Error*error) -{ - if(!dbg) { - DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); - } - dbg->de_tied_data.td_tied_object = tieddbg; - if (tieddbg) { - tieddbg->de_tied_data.td_is_tied_object = TRUE; - } - return DW_DLV_OK; -} - -/* Unsure of the use-case of this. - New September 2015. */ -int -dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out, - UNUSEDARG Dwarf_Error*error) -{ - *tieddbg_out = dbg->de_tied_data.td_tied_object; - return DW_DLV_OK; +#endif /* DWARF_WITH_LIBELF */ } diff --git a/thirdparty/dwarf/dwarf_pe_descr.h b/thirdparty/dwarf/dwarf_pe_descr.h new file mode 100644 index 00000000..c4d9db18 --- /dev/null +++ b/thirdparty/dwarf/dwarf_pe_descr.h @@ -0,0 +1,250 @@ +#ifndef DWARF_PE_DESCR_H +#define DWARF_PE_DESCR_H +/* +Copyright (c) 2018, David Anderson All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define IMAGE_DOS_SIGNATURE_dw 0x5a4d /* le on disk 'M' 'Z' */ +#define IMAGE_DOS_REVSIGNATURE_dw 0x4d5a /* be on disk */ +#define IMAGE_NT_SIGNATURE_dw 0x00004550 + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif /* TYPE */ + + +/* Data types + see https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx */ + +/*#define FIELD_OFFSET(type,field) ((LONG)(LONG_PTR)&(((type *)0)->field))*/ + +#define IMAGE_SIZEOF_SYMBOL 18 + +struct dos_header_dw { + TYP(dh_mz,2); + TYP(dh_dos_data,58); + TYP(dh_image_offset,4); +}; + +/* IMAGE_FILE_HEADER_dw + see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680313(v=vs.85).aspx */ + +typedef struct +{ + TYP(Machine,2); + TYP(NumberOfSections,2); + TYP(TimeDateStamp,4); + TYP(PointerToSymbolTable,4); + TYP(NumberOfSymbols,4); + TYP(SizeOfOptionalHeader,2); + TYP(Characteristics,2); +} IMAGE_FILE_HEADER_dw; + +/* IMAGE_DATA_DIRECTORY_dw + see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680305(v=vs.85).aspx */ + +typedef struct +{ + TYP(VirtualAddress,4); + TYP(Size,4); +} IMAGE_DATA_DIRECTORY_dw; + +/* IMAGE_OPTIONAL_HEADER + see https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx */ + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct +{ + TYP(Magic,2); + unsigned char MajorLinkerVersion; + unsigned char MinorLinkerVersion; + TYP(SizeOfCode,4); + TYP(SizeOfInitializedData,4); + TYP(SizeOfUninitializedData,4); + TYP(AddressOfEntryPoint,4); + TYP(BaseOfCode,4); + TYP(BaseOfData,4); + TYP(ImageBase,4); + TYP(SectionAlignment,4); + TYP(FileAlignment,4); + TYP(MajorOperatingSystemVersion,2); + TYP(MinorOperatingSystemVersion,2); + TYP(MajorImageVersion,2); + TYP(MinorImageVersion,2); + TYP(MajorSubsystemVersion,2); + TYP(MinorSubsystemVersion,2); + TYP(Win32VersionValue,4); + TYP(SizeOfImage,4); + TYP(SizeOfHeaders,4); + TYP(CheckSum,4); + TYP(Subsystem,2); + TYP(DllCharacteristics,2); + TYP(SizeOfStackReserve,4); + TYP(SizeOfStackCommit,4); + TYP(SizeOfHeapReserve,4); + TYP(SizeOfHeapCommit,4); + TYP(LoaderFlags,4); + TYP(NumberOfRvaAndSizes,4); + IMAGE_DATA_DIRECTORY_dw DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32_dw; + +typedef struct +{ + TYP(Magic,2); + unsigned char MajorLinkerVersion; + unsigned char MinorLinkerVersion; + TYP(SizeOfCode,4); + TYP(SizeOfInitializedData,4); + TYP(SizeOfUninitializedData,4); + TYP(AddressOfEntryPoint,4); + TYP(BaseOfCode,4); + TYP(ImageBase,8); + TYP(SectionAlignment,4); + TYP(FileAlignment,4); + TYP(MajorOperatingSystemVersion,2); + TYP(MinorOperatingSystemVersion,2); + TYP(MajorImageVersion,2); + TYP(MinorImageVersion,2); + TYP(MajorSubsystemVersion,2); + TYP(MinorSubsystemVersion,2); + TYP(Win32VersionValue,4); + TYP(SizeOfImage,4); + TYP(SizeOfHeaders,4); + TYP(CheckSum,4); + TYP(Subsystem,2); + TYP(DllCharacteristics,2); + TYP(SizeOfStackReserve,8); + TYP(SizeOfStackCommit,8); + TYP(SizeOfHeapReserve,8); + TYP(SizeOfHeapCommit,8); + TYP(LoaderFlags,4); + TYP(NumberOfRvaAndSizes,4); + IMAGE_DATA_DIRECTORY_dw DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64_dw; + +/* IMAGE_NT_HEADERS + see https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms680336(v=vs.85).aspx */ + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +typedef struct +{ + TYP(Signature,4); + IMAGE_FILE_HEADER_dw FileHeader; + IMAGE_OPTIONAL_HEADER64_dw OptionalHeader; +} IMAGE_NT_HEADERS64_dw, *PIMAGE_NT_HEADERS64_dw; + +typedef struct +{ + TYP(Signature,4); + IMAGE_FILE_HEADER_dw FileHeader; + IMAGE_OPTIONAL_HEADER32_dw OptionalHeader; +} IMAGE_NT_HEADERS32_dw, *PIMAGE_NT_HEADERS32_dw; + + +/* IMAGE_SECTION_HEADER_dw + see: + https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx + and, for details on VirtualSize and SizeOfRawData: + https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_image_section_header */ + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct +{ + char Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + TYP(PhysicalAddress,4); + TYP(VirtualSize,4); + } Misc; + TYP(VirtualAddress,4); + TYP(SizeOfRawData,4); + TYP(PointerToRawData,4); + TYP(PointerToRelocations,4); + TYP(PointerToLinenumbers,4); + TYP(NumberOfRelocations,2); + TYP(NumberOfLinenumbers,2); + TYP(Characteristics,4); +} IMAGE_SECTION_HEADER_dw, *PIMAGE_SECTION_HEADER_dw; + +#define IMAGE_SCN_SCALE_INDEX 0x00000001 +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 +#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 +#define IMAGE_SCN_MEM_FARDATA 0x00008000 +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 + +#define IMAGE_SCN_ALIGN_MASK 0x00F00000 +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* DWARF_PE_DESCR_H */ diff --git a/thirdparty/dwarf/dwarf_peread.c b/thirdparty/dwarf/dwarf_peread.c new file mode 100644 index 00000000..2502079b --- /dev/null +++ b/thirdparty/dwarf/dwarf_peread.c @@ -0,0 +1,877 @@ +/* +Copyright (c) 2019, David Anderson All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/* This file reads the parts of a Windows PE + file appropriate to reading DWARF debugging data. +*/ + +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif /* _WIN32 */ + +#include "config.h" +#include +#ifdef HAVE_MALLOC_H +#include +#endif /* HAVE_MALLOC_H */ +#include +#include /* memcpy */ +#include +#include /* open() */ +#include /* open() */ +#include /* open() */ +#include +#ifdef HAVE_UNISTD_H +#include /* lseek read close */ +#elif defined(_WIN32) && defined(_MSC_VER) +#include +#endif /* HAVE_UNISTD_H */ + +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) +#include "stdafx.h" +#endif /* HAVE_STDAFX_H */ + +#include "libdwarf.h" +#include "libdwarfdefs.h" +#include "dwarf_base_types.h" +#include "dwarf_opaque.h" +#include "memcpy_swap.h" +#include "dwarf_error.h" /* for _dwarf_error() declaration */ +#include "dwarf_reading.h" +#include "dwarf_object_read_common.h" +#include "dwarf_object_detector.h" +#include "dwarf_pe_descr.h" +#include "dwarf_peread.h" + +#ifdef HAVE_UNUSED_ATTRIBUTE +#define UNUSEDARG __attribute__ ((unused)) +#else +#define UNUSEDARG +#endif + +#define DOS_HEADER_LEN 64 + +#ifndef TYP +#define TYP(n,l) char n[l] +#endif /* TYP */ + + +#ifndef SIZEOFT32 +#define SIZEOFT32 4 +#endif /* SIZEOFT32 */ + +static int _dwarf_pe_object_access_init( + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + Dwarf_Obj_Access_Interface **binary_interface, + int *localerrnum); + +static unsigned long +magic_copy(char *d, unsigned len) +{ + unsigned i = 0; + unsigned long v = 0; + + v = d[0]; + for(i = 1 ; i < len; ++i) { + v <<= 8; + v |= 0xff&d[i]; + } + return v; +} + +#ifdef WORDS_BIGENDIAN +#define ASNAR(func,t,s) \ + do { \ + unsigned tbyte = sizeof(t) - sizeof(s); \ + t = 0; \ + func(((char *)&t)+tbyte ,&s[0],sizeof(s)); \ + } while (0) +#else /* LITTLE ENDIAN */ +#define ASNAR(func,t,s) \ + do { \ + t = 0; \ + func(&t,&s[0],sizeof(s)); \ + } while (0) +#endif /* end LITTLE- BIG-ENDIAN */ + +/* name_array is 8 byte string */ +static int +pe_section_name_get(dwarf_pe_object_access_internals_t *pep, + const char *name_array, + const char ** name_out, + int *errcode) +{ + + if (name_array[0] == '/') { + long v = 0; + unsigned long u = 0; + const char *s = 0; + char temp_array[9]; + + memcpy(temp_array,name_array+1,7); + temp_array[7] = 0; + v = atoi(temp_array); + if (v < 0) { + *errcode = DW_DLE_STRING_OFFSET_BAD; + return DW_DLV_ERROR; + } + u = v; + if (u > pep->pe_string_table_size) { + *errcode = DW_DLE_STRING_OFFSET_BAD; + return DW_DLV_ERROR; + } + s = pep->pe_string_table +u; + *name_out = s; + return DW_DLV_OK; + } + *name_out = name_array; + return DW_DLV_OK; +} + + +static Dwarf_Endianness +pe_get_byte_order (void *obj) +{ + dwarf_pe_object_access_internals_t *pep = + (dwarf_pe_object_access_internals_t*)(obj); + return pep->pe_endian; +} + + +static Dwarf_Small +pe_get_length_size (void *obj) +{ + dwarf_pe_object_access_internals_t *pep = + (dwarf_pe_object_access_internals_t*)(obj); + return pep->pe_offsetsize/8; +} + +static Dwarf_Small +pe_get_pointer_size (void *obj) +{ + dwarf_pe_object_access_internals_t *pep = + (dwarf_pe_object_access_internals_t*)(obj); + return pep->pe_pointersize/8; +} + + +static Dwarf_Unsigned +pe_get_section_count (void *obj) +{ + dwarf_pe_object_access_internals_t *pep = + (dwarf_pe_object_access_internals_t*)(obj); + return pep->pe_section_count; +} + +static int +pe_get_section_info (void *obj, + Dwarf_Half section_index, + Dwarf_Obj_Access_Section *return_section, + UNUSEDARG int *error) +{ + dwarf_pe_object_access_internals_t *pep = + (dwarf_pe_object_access_internals_t*)(obj); + + + if (section_index < pep->pe_section_count) { + struct dwarf_pe_generic_image_section_header *sp = 0; + sp = pep->pe_sectionptr + section_index; + return_section->addr = pep->pe_OptionalHeader.ImageBase + + sp->VirtualAddress; ; + return_section->type = 0; + /* SizeOfRawData can be rounded or truncated, + use VirtualSize for the real analog of Elf + section size. */ + return_section->size = sp->VirtualSize; + return_section->name = sp->dwarfsectname; + return_section->link = 0; + return_section->info = 0; + return_section->entrysize = 0; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + + +static int +load_optional_header32(dwarf_pe_object_access_internals_t *pep, + Dwarf_Unsigned offset, int*errcode) +{ + int res = 0; + IMAGE_OPTIONAL_HEADER32_dw hdr; + + pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER32_dw); + + if ((pep->pe_optional_header_size + offset) > + pep->pe_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + + res = _dwarf_object_read_random(pep->pe_fd, + (char *)&hdr, + (off_t)offset, sizeof(IMAGE_OPTIONAL_HEADER32_dw), + (off_t)pep->pe_filesize, + errcode); + if (res != DW_DLV_OK) { + return res; + } + + /* This is a subset of fields. */ + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.Magic, + hdr.Magic); + pep->pe_OptionalHeader.MajorLinkerVersion= hdr.MajorLinkerVersion; + pep->pe_OptionalHeader.MinorLinkerVersion= hdr.MinorLinkerVersion; + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.ImageBase, + hdr.ImageBase); + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfCode, + hdr.SizeOfCode); + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfImage, + hdr.SizeOfImage); + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfHeaders, + hdr.SizeOfHeaders); + pep->pe_OptionalHeader.SizeOfDataDirEntry = + sizeof(IMAGE_DATA_DIRECTORY_dw); + return DW_DLV_OK; +} +static int +load_optional_header64(dwarf_pe_object_access_internals_t *pep, + Dwarf_Unsigned offset, int*errcode ) +{ + IMAGE_OPTIONAL_HEADER64_dw hdr; + int res = 0; + + pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER64_dw); + if ((pep->pe_optional_header_size + offset) > + pep->pe_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(pep->pe_fd, + (char *)&hdr, + (off_t)offset, sizeof(IMAGE_OPTIONAL_HEADER64_dw), + (off_t)pep->pe_filesize, + errcode); + if (res != DW_DLV_OK) { + return res; + } + + /* This is a subset of fields. */ + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.Magic, + hdr.Magic); + pep->pe_OptionalHeader.MajorLinkerVersion= hdr.MajorLinkerVersion; + pep->pe_OptionalHeader.MinorLinkerVersion= hdr.MinorLinkerVersion; + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfCode, + hdr.SizeOfCode); + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfImage, + hdr.SizeOfImage); + ASNAR(pep->pe_copy_word,pep->pe_OptionalHeader.SizeOfHeaders, + hdr.SizeOfHeaders); + pep->pe_OptionalHeader.SizeOfDataDirEntry = + sizeof(IMAGE_DATA_DIRECTORY_dw); + return DW_DLV_OK; +} + +static int +pe_load_section (void *obj, Dwarf_Half section_index, + Dwarf_Small **return_data, int *error) +{ + dwarf_pe_object_access_internals_t *pep = + (dwarf_pe_object_access_internals_t*)(obj); + + if (0 < section_index && + section_index < pep->pe_section_count) { + int res = 0; + struct dwarf_pe_generic_image_section_header *sp = + pep->pe_sectionptr + section_index; + Dwarf_Unsigned read_length = 0; + + if(sp->loaded_data) { + *return_data = sp->loaded_data; + return DW_DLV_OK; + } + if (!sp->VirtualSize) { + return DW_DLV_NO_ENTRY; + } + read_length = sp->SizeOfRawData; + if(sp->VirtualSize < read_length) { + /* Don't read padding that wasn't allocated in memory */ + read_length = sp->VirtualSize; + } + if ((read_length + sp->PointerToRawData) > + pep->pe_filesize) { + *error = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + sp->loaded_data = malloc((size_t)sp->SizeOfRawData); + if(!sp->loaded_data) { + *error = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(pep->pe_fd, + (char *)sp->loaded_data, + (off_t)sp->PointerToRawData, (size_t)read_length, + (off_t)pep->pe_filesize, + error); + if (res != DW_DLV_OK) { + free(sp->loaded_data); + sp->loaded_data = 0; + return res; + } + if(sp->VirtualSize > read_length) { + /* Zero space that was allocated but + truncated from the file */ + memset(sp->loaded_data + read_length, 0, + (size_t)(sp->VirtualSize - read_length)); + } + *return_data = sp->loaded_data; + return DW_DLV_OK; + } + return DW_DLV_NO_ENTRY; +} + +void +_dwarf_destruct_pe_access( + struct Dwarf_Obj_Access_Interface_s *aip) +{ + dwarf_pe_object_access_internals_t *pep = 0; + Dwarf_Unsigned i = 0; + + if (!aip) { + return; + } + pep = (dwarf_pe_object_access_internals_t*)(aip->object); + if (pep->pe_destruct_close_fd) { + close(pep->pe_fd); + pep->pe_fd = -1; + } + free((char *)pep->pe_path); + pep->pe_path = 0; + if (pep->pe_sectionptr) { + struct dwarf_pe_generic_image_section_header *sp = 0; + + sp = pep->pe_sectionptr; + for( i=0; i < pep->pe_section_count; ++i,++sp) { + if (sp->loaded_data) { + free(sp->loaded_data); + sp->loaded_data = 0; + } + free(sp->name); + sp->name = 0; + free(sp->dwarfsectname); + sp->dwarfsectname = 0; + } + free(pep->pe_sectionptr); + pep->pe_section_count = 0; + } + free(pep->pe_string_table); + pep->pe_string_table = 0; + free(pep); + free(aip); + return; +} + + +static int +dwarf_pe_load_dwarf_section_headers( + dwarf_pe_object_access_internals_t *pep,int *errcode) +{ + Dwarf_Unsigned i = 0; + Dwarf_Unsigned input_count = + pep->pe_FileHeader.NumberOfSections; + Dwarf_Unsigned offset_in_input = pep->pe_section_table_offset; + Dwarf_Unsigned section_hdr_size = sizeof(IMAGE_SECTION_HEADER_dw); + struct dwarf_pe_generic_image_section_header *sec_outp = 0; + Dwarf_Unsigned cur_offset = offset_in_input; + Dwarf_Unsigned past_end_hdrs = offset_in_input + + section_hdr_size*input_count; + + /* internal sections include null initial section */ + pep->pe_section_count = input_count+1; + + if (past_end_hdrs > pep->pe_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + + if (!offset_in_input) { + *errcode = DW_DLE_PE_OFFSET_BAD; + return DW_DLV_ERROR; + } + pep->pe_sectionptr = + (struct dwarf_pe_generic_image_section_header * ) + calloc((size_t)pep->pe_section_count, + sizeof(struct dwarf_pe_generic_image_section_header)); + + + + if (!pep->pe_sectionptr) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + sec_outp = pep->pe_sectionptr; + sec_outp->name = strdup(""); + sec_outp->dwarfsectname = strdup(""); + sec_outp++; + for ( ; i < input_count; + ++i, cur_offset += section_hdr_size, sec_outp++) { + + int res = 0; + IMAGE_SECTION_HEADER_dw filesect; + char safe_name[IMAGE_SIZEOF_SHORT_NAME +1]; + const char *expname = 0; + + res = _dwarf_object_read_random(pep->pe_fd, + (char *)&filesect,(off_t)cur_offset, + sizeof(filesect), + (off_t)pep->pe_filesize, + errcode); + if (res != DW_DLV_OK) { + return res; + } + /* The following is safe. filesect.Name is + IMAGE_SIZEOF_SHORT_NAME bytes long and may + not (not sure) have a NUL terminator. */ + strncpy(safe_name,filesect.Name,IMAGE_SIZEOF_SHORT_NAME); + /* Then add NUL terminator. */ + safe_name[IMAGE_SIZEOF_SHORT_NAME] = 0; + sec_outp->name = strdup(safe_name); + res = pe_section_name_get(pep, + safe_name,&expname,errcode); + if (res != DW_DLV_OK) { + return res; + } + sec_outp->dwarfsectname = strdup(expname); + + if ( !sec_outp->name || !sec_outp->dwarfsectname) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + sec_outp->SecHeaderOffset = cur_offset; + ASNAR(pep->pe_copy_word,sec_outp->VirtualSize, + filesect.Misc.VirtualSize); + ASNAR(pep->pe_copy_word,sec_outp->VirtualAddress, + filesect.VirtualAddress); + ASNAR(pep->pe_copy_word,sec_outp->SizeOfRawData, + filesect.SizeOfRawData); + ASNAR(pep->pe_copy_word,sec_outp->PointerToRawData, + filesect.PointerToRawData); + if(sec_outp->SizeOfRawData > pep->pe_filesize || + sec_outp->PointerToRawData > pep->pe_filesize || + (sec_outp->SizeOfRawData+ + sec_outp->PointerToRawData > pep->pe_filesize)) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + ASNAR(pep->pe_copy_word,sec_outp->PointerToRelocations, + filesect.PointerToRelocations); + ASNAR(pep->pe_copy_word,sec_outp->PointerToLinenumbers, + filesect.PointerToLinenumbers); + ASNAR(pep->pe_copy_word,sec_outp->NumberOfRelocations, + filesect.NumberOfRelocations); + ASNAR(pep->pe_copy_word,sec_outp->NumberOfLinenumbers, + filesect.NumberOfLinenumbers); + ASNAR(pep->pe_copy_word,sec_outp->Characteristics, + filesect.Characteristics); + /* sec_outp->loaded data set when we load a section */ + } + return DW_DLV_OK; +} + + +static int +dwarf_load_pe_sections( + dwarf_pe_object_access_internals_t *pep,int *errcode) +{ + struct dos_header_dw dhinmem; + IMAGE_FILE_HEADER_dw ifh; + void (*word_swap) (void *, const void *, unsigned long); + unsigned locendian = 0; + int res = 0; + Dwarf_Unsigned dos_sig = 0; + Dwarf_Unsigned nt_address = 0; + char nt_sig_array[4]; + unsigned long nt_signature = 0; + + if ( (sizeof(ifh) + sizeof(dhinmem)) >= pep->pe_filesize) { + /* corrupt object. */ + *errcode = DW_DLE_PE_SIZE_SMALL; + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(pep->pe_fd,(char *)&dhinmem, + 0, sizeof(dhinmem),(off_t)pep->pe_filesize, errcode); + if (res != DW_DLV_OK) { + return res; + } + dos_sig = magic_copy((char *)dhinmem.dh_mz, + sizeof(dhinmem.dh_mz)); + if (dos_sig == IMAGE_DOS_SIGNATURE_dw) { + /* IMAGE_DOS_SIGNATURE_dw assumes bytes reversed by little-endian + load, so we intrepet a match the other way. */ + /* BIG ENDIAN. From looking at hex characters in object */ +#ifdef WORDS_BIGENDIAN + word_swap = _dwarf_memcpy_noswap_bytes; +#else /* LITTLE ENDIAN */ + word_swap = _dwarf_memcpy_swap_bytes; +#endif /* LITTLE- BIG-ENDIAN */ + locendian = DW_ENDIAN_BIG; + } else if (dos_sig == IMAGE_DOS_REVSIGNATURE_dw) { + /* raw load, so intrepet a match the other way. */ + /* LITTLE ENDIAN */ +#ifdef WORDS_BIGENDIAN + word_swap = _dwarf_memcpy_swap_bytes; +#else /* LITTLE ENDIAN */ + word_swap = _dwarf_memcpy_noswap_bytes; +#endif /* LITTLE- BIG-ENDIAN */ + locendian = DW_ENDIAN_LITTLE; + } else { + /* Not dos header not a PE file we recognize */ + *errcode = DW_DLE_FILE_WRONG_TYPE; + return DW_DLV_ERROR; + } + if (locendian != pep->pe_endian) { + /* Really this is a coding botch somewhere here, + not an object corruption. */ + *errcode = DW_DLE_FILE_WRONG_TYPE; + return DW_DLV_ERROR; + } + pep->pe_copy_word = word_swap; + ASNAR(word_swap,nt_address,dhinmem.dh_image_offset); + if (pep->pe_filesize < (nt_address + sizeof(nt_sig_array))) { + /* The nt_address is really a file offset. */ + *errcode = DW_DLE_FILE_TOO_SMALL; + /* Not dos header not a PE file we recognize */ + return DW_DLV_ERROR; + } + + res = _dwarf_object_read_random(pep->pe_fd, + (char *)&nt_sig_array[0], + (off_t)nt_address, sizeof(nt_sig_array), + (off_t)pep->pe_filesize,errcode); + if (res != DW_DLV_OK) { + return res; + } + { unsigned long lsig = 0; + + ASNAR(word_swap,lsig,nt_sig_array); + nt_signature = lsig; + } + if (nt_signature != IMAGE_NT_SIGNATURE_dw) { + *errcode = DW_DLE_FILE_WRONG_TYPE; + return DW_DLV_ERROR; + } + + pep->pe_nt_header_offset = nt_address + SIZEOFT32; + if (pep->pe_filesize < (pep->pe_nt_header_offset + + sizeof(ifh))) { + *errcode = DW_DLE_FILE_TOO_SMALL; + /* Not image header not a PE file we recognize */ + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(pep->pe_fd,(char *)&ifh, + (off_t)pep->pe_nt_header_offset, sizeof(ifh), + (off_t)pep->pe_filesize,errcode); + if (res != DW_DLV_OK) { + return res; + } + ASNAR(word_swap,pep->pe_FileHeader.Machine,ifh.Machine); + ASNAR(word_swap,pep->pe_FileHeader.NumberOfSections, + ifh.NumberOfSections); + ASNAR(word_swap,pep->pe_FileHeader.TimeDateStamp, + ifh.TimeDateStamp); + ASNAR(word_swap,pep->pe_FileHeader.PointerToSymbolTable, + ifh.PointerToSymbolTable); + ASNAR(word_swap,pep->pe_FileHeader.NumberOfSymbols, + ifh.NumberOfSymbols); + ASNAR(word_swap,pep->pe_FileHeader.SizeOfOptionalHeader, + ifh.SizeOfOptionalHeader); + ASNAR(word_swap,pep->pe_FileHeader.Characteristics, + ifh.Characteristics); + + pep->pe_optional_header_offset = pep->pe_nt_header_offset+ + sizeof(ifh); + if (pep->pe_offsetsize == 32) { + res = load_optional_header32(pep, + pep->pe_optional_header_offset,errcode); + pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER32_dw); + } else if (pep->pe_offsetsize == 64) { + res = load_optional_header64(pep, + pep->pe_optional_header_offset,errcode); + pep->pe_optional_header_size = sizeof(IMAGE_OPTIONAL_HEADER64_dw); + } else { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + if (res != DW_DLV_OK) { + return res; + } + + pep->pe_section_table_offset = pep->pe_optional_header_offset + + pep->pe_optional_header_size; + pep->pe_symbol_table_offset = + pep->pe_FileHeader.PointerToSymbolTable; + if (pep->pe_symbol_table_offset >= pep->pe_filesize) { + *errcode = DW_DLE_OFFSET_SIZE; + return DW_DLV_ERROR; + } + if (pep->pe_symbol_table_offset) { + pep->pe_string_table_offset = + pep->pe_symbol_table_offset + + (pep->pe_FileHeader.NumberOfSymbols * + IMAGE_SIZEOF_SYMBOL); + } + + if (pep->pe_string_table_offset >= pep->pe_filesize) { + *errcode = DW_DLE_OFFSET_SIZE; + pep->pe_string_table_size = 0; + return DW_DLV_ERROR; + } + if (pep->pe_string_table_offset) { + /* https://docs.microsoft.com/en-us/windows/desktop/debug/pe-format#coff-string-table */ + /* The first 4 bytes of the string table contain + the size of the string table. */ + char size_field[4]; + + if ((pep->pe_string_table_offset+sizeof(size_field)) > + pep->pe_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + memset(size_field,0,sizeof(size_field)); + res = _dwarf_object_read_random(pep->pe_fd, + (char *)size_field, (off_t)pep->pe_string_table_offset, + sizeof(size_field), + (off_t)pep->pe_filesize,errcode); + if (res != DW_DLV_OK) { + return res; + } + ASNAR(pep->pe_copy_word,pep->pe_string_table_size, + size_field); + if( pep->pe_string_table_size >= pep->pe_filesize ) { + *errcode = DW_DLE_PE_OFFSET_BAD; + return DW_DLV_ERROR; + } + if ((pep->pe_string_table_offset+pep->pe_string_table_size) > + pep->pe_filesize) { + *errcode = DW_DLE_FILE_TOO_SMALL; + return DW_DLV_ERROR; + } + pep->pe_string_table = + (char *)malloc((size_t)pep->pe_string_table_size); + if (!pep->pe_string_table) { + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + res = _dwarf_object_read_random(pep->pe_fd, + (char *)pep->pe_string_table, (off_t)pep->pe_string_table_offset, + (size_t)pep->pe_string_table_size, + (off_t)pep->pe_filesize,errcode); + if (res != DW_DLV_OK) { + return res; + } + } + res = dwarf_pe_load_dwarf_section_headers(pep,errcode); + return res; +} + +int +_dwarf_pe_setup(int fd, + char *true_path, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + unsigned groupnumber, + Dwarf_Handler errhand, + Dwarf_Ptr errarg, + Dwarf_Debug *dbg,Dwarf_Error *error) +{ + Dwarf_Obj_Access_Interface *binary_interface = 0; + dwarf_pe_object_access_internals_t *pep = 0; + int res = DW_DLV_OK; + int localerrnum = 0; + + res = _dwarf_pe_object_access_init( + fd, + ftype,endian,offsetsize,filesize,access, + &binary_interface, + &localerrnum); + if (res != DW_DLV_OK) { + if (res == DW_DLV_NO_ENTRY) { + return res; + } + _dwarf_error(NULL, error, localerrnum); + return DW_DLV_ERROR; + } + /* allocates and initializes Dwarf_Debug, + generic code */ + res = dwarf_object_init_b(binary_interface, errhand, errarg, + groupnumber, dbg, error); + if (res != DW_DLV_OK){ + _dwarf_destruct_pe_access(binary_interface); + return res; + } + pep = binary_interface->object; + pep->pe_path = strdup(true_path); + return res; +} + +static Dwarf_Obj_Access_Methods pe_methods = { + pe_get_section_info, + pe_get_byte_order, + pe_get_length_size, + pe_get_pointer_size, + pe_get_section_count, + pe_load_section, + 0 /* ignore pe relocations. */ +}; + +/* On any error this frees internals. */ +static int +_dwarf_pe_object_access_internals_init( + dwarf_pe_object_access_internals_t * internals, + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + UNUSEDARG Dwarf_Unsigned access, + int *errcode) +{ + dwarf_pe_object_access_internals_t * intfc = internals; + struct Dwarf_Obj_Access_Interface_s *localdoas = 0; + int res = 0; + + /* Must malloc as _dwarf_destruct_pe_access() + forces that due to other uses. */ + localdoas = (struct Dwarf_Obj_Access_Interface_s *) + malloc(sizeof(struct Dwarf_Obj_Access_Interface_s)); + if (!localdoas) { + free(internals); + *errcode = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s)); + intfc->pe_ident[0] = 'P'; + intfc->pe_ident[1] = '1'; + intfc->pe_fd = fd; + intfc->pe_is_64bit = ((offsetsize==64)?TRUE:FALSE); + intfc->pe_offsetsize = offsetsize; + intfc->pe_pointersize = offsetsize; + intfc->pe_filesize = filesize; + intfc->pe_ftype = ftype; + /* pe_path set by caller */ + +#ifdef WORDS_BIGENDIAN + if (endian == DW_ENDIAN_LITTLE ) { + intfc->pe_copy_word = _dwarf_memcpy_swap_bytes; + intfc->pe_endian = DW_ENDIAN_LITTLE; + } else { + intfc->pe_copy_word = _dwarf_memcpy_noswap_bytes; + intfc->pe_endian = DW_ENDIAN_BIG; + } +#else /* LITTLE ENDIAN */ + if (endian == DW_ENDIAN_LITTLE ) { + intfc->pe_copy_word = _dwarf_memcpy_noswap_bytes; + intfc->pe_endian = DW_ENDIAN_LITTLE; + } else { + intfc->pe_copy_word = _dwarf_memcpy_swap_bytes; + intfc->pe_endian = DW_ENDIAN_BIG; + } +#endif /* LITTLE- BIG-ENDIAN */ + res = dwarf_load_pe_sections(intfc,errcode); + if (res != DW_DLV_OK) { + localdoas->object = intfc; + localdoas->methods = 0; + _dwarf_destruct_pe_access(localdoas); + localdoas = 0; + return res; + } + free(localdoas); + localdoas = 0; + return DW_DLV_OK; +} + + +static int +_dwarf_pe_object_access_init( + int fd, + unsigned ftype, + unsigned endian, + unsigned offsetsize, + size_t filesize, + Dwarf_Unsigned access, + Dwarf_Obj_Access_Interface **binary_interface, + int *localerrnum) +{ + + int res = 0; + dwarf_pe_object_access_internals_t *internals = 0; + Dwarf_Obj_Access_Interface *intfc = 0; + + internals = malloc(sizeof(dwarf_pe_object_access_internals_t)); + if (!internals) { + *localerrnum = DW_DLE_ALLOC_FAIL; + /* Impossible case, we hope. Give up. */ + return DW_DLV_ERROR; + } + memset(internals,0,sizeof(*internals)); + res = _dwarf_pe_object_access_internals_init(internals, + fd, + ftype, endian, offsetsize, filesize, + access, + localerrnum); + if (res != DW_DLV_OK){ + /* *err is already set. and the call freed internals */ + return DW_DLV_ERROR; + } + + intfc = malloc(sizeof(Dwarf_Obj_Access_Interface)); + if (!intfc) { + /* Impossible case, we hope. Give up. */ + free(internals); + *localerrnum = DW_DLE_ALLOC_FAIL; + return DW_DLV_ERROR; + } + /* Initialize the interface struct */ + intfc->object = internals; + intfc->methods = &pe_methods; + *binary_interface = intfc; + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/dwarf_peread.h b/thirdparty/dwarf/dwarf_peread.h new file mode 100644 index 00000000..2bf31846 --- /dev/null +++ b/thirdparty/dwarf/dwarf_peread.h @@ -0,0 +1,155 @@ +#ifndef PE_GENERIC_H +#define PE_GENERIC_H +/* +Copyright (c) 2018, David Anderson All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +struct dwarf_pe_generic_file_header +{ + Dwarf_Unsigned Machine; + Dwarf_Unsigned NumberOfSections; + Dwarf_Unsigned TimeDateStamp; + Dwarf_Unsigned PointerToSymbolTable; + Dwarf_Unsigned NumberOfSymbols; + Dwarf_Unsigned SizeOfOptionalHeader; /* in object file */ + Dwarf_Unsigned Characteristics; +}; + +struct dwarf_pe_generic_data_directory +{ + Dwarf_Unsigned VirtualAddress; + Dwarf_Unsigned Size; +}; + +#define DWARF_PE_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 +struct dwarf_pe_generic_optional_header +{ + Dwarf_Unsigned Magic; + unsigned char MajorLinkerVersion; + unsigned char MinorLinkerVersion; + Dwarf_Unsigned SizeOfCode; + Dwarf_Unsigned SizeOfInitializedData; + Dwarf_Unsigned SizeOfUninitializedData; + Dwarf_Unsigned AddressOfEntryPoint; + Dwarf_Unsigned BaseOfCode; + Dwarf_Unsigned BaseOfData; + Dwarf_Unsigned ImageBase; + Dwarf_Unsigned SectionAlignment; + Dwarf_Unsigned FileAlignment; + Dwarf_Unsigned MajorOperatingSystemVersion; + Dwarf_Unsigned MinorOperatingSystemVersion; + Dwarf_Unsigned MajorImageVersion; + Dwarf_Unsigned MinorImageVersion; + Dwarf_Unsigned MajorSubsystemVersion; + Dwarf_Unsigned MinorSubsystemVersion; + Dwarf_Unsigned Win32VersionValue; + Dwarf_Unsigned SizeOfImage; /* size in object file */ + Dwarf_Unsigned SizeOfHeaders; /* size in object file */ + Dwarf_Unsigned CheckSum; + Dwarf_Unsigned Subsystem; + Dwarf_Unsigned DllCharacteristics; + Dwarf_Unsigned SizeOfStackReserve; + Dwarf_Unsigned SizeOfStackCommit; + Dwarf_Unsigned SizeOfHeapReserve; + Dwarf_Unsigned SizeOfHeapCommit; + Dwarf_Unsigned LoaderFlags; + Dwarf_Unsigned NumberOfRvaAndSizes; + Dwarf_Unsigned SizeOfDataDirEntry; /* size in object file */ + struct dwarf_pe_generic_data_directory DataDirectory[DWARF_PE_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; +}; + +struct dwarf_pe_generic_image_section_header +{ + char *name; /* Name must be freed */ + char *dwarfsectname; /* Name must be freed */ + Dwarf_Unsigned SecHeaderOffset; /* offset in object file */ + /* union { */ + /* Dwarf_Unsigned PhysicalAddress; */ + Dwarf_Unsigned VirtualSize; + /* } Misc; */ + Dwarf_Unsigned VirtualAddress; + Dwarf_Unsigned SizeOfRawData; /* size we need */ + Dwarf_Unsigned PointerToRawData; + Dwarf_Unsigned PointerToRelocations; + Dwarf_Unsigned PointerToLinenumbers; + Dwarf_Unsigned NumberOfRelocations; + Dwarf_Unsigned NumberOfLinenumbers; + Dwarf_Unsigned Characteristics; + Dwarf_Small * loaded_data; /* must be freed. */ +}; + +#define DWARF_PE_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define DWARF_PE_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define DWARF_PE_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +/* ident[0] == 'P' means this is a PE header. + ident[1] will be 1 indicating version 1. + Other bytes in ident not defined, should be zero. */ +typedef struct pe_filedata_s { + char pe_ident[8]; + const char * pe_path; /* must free.*/ + int pe_fd; + int pe_destruct_close_fd; /*aka: lib owns fd */ + int pe_is_64bit; + Dwarf_Unsigned pe_filesize; + Dwarf_Small pe_offsetsize; /* 32 or 64 section data */ + Dwarf_Small pe_pointersize; + int pe_ftype; + unsigned pe_endian; + /*Dwarf_Small pe_machine; */ + void (*pe_copy_word) (void *, const void *, unsigned long); + Dwarf_Unsigned pe_nt_header_offset; + Dwarf_Unsigned pe_optional_header_offset; + Dwarf_Unsigned pe_optional_header_size; + Dwarf_Unsigned pe_symbol_table_offset; + Dwarf_Unsigned pe_string_table_offset; + Dwarf_Unsigned pe_section_table_offset; + Dwarf_Unsigned pe_signature; + + struct dwarf_pe_generic_file_header pe_FileHeader; + + struct dwarf_pe_generic_optional_header pe_OptionalHeader; + + Dwarf_Unsigned pe_section_count; + struct dwarf_pe_generic_image_section_header *pe_sectionptr; + + Dwarf_Unsigned pe_string_table_size; + char *pe_string_table; +} dwarf_pe_object_access_internals_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PE_GENERIC_H */ diff --git a/thirdparty/dwarf/dwarf_print_lines.c b/thirdparty/dwarf/dwarf_print_lines.c index f400c7f5..7c648a00 100644 --- a/thirdparty/dwarf/dwarf_print_lines.c +++ b/thirdparty/dwarf/dwarf_print_lines.c @@ -1,6 +1,6 @@ /* Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2013 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -26,10 +26,14 @@ */ #include "config.h" -#include "dwarf_incl.h" #include #include #include + +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_line.h" #define PRINTING_DETAILS 1 @@ -167,8 +171,9 @@ print_line_detail( } -#include "dwarf_line_table_reader_common.c" +#include "dwarf_line_table_reader_common.h" +/* Not yet implemented, at least not usefully. FIXME */ void _dwarf_print_line_context_record(UNUSEDARG Dwarf_Debug dbg, UNUSEDARG Dwarf_Line_Context line_context) @@ -204,8 +209,8 @@ _dwarf_internal_printlines(Dwarf_Die die, attribute. */ Dwarf_Unsigned line_offset = 0; - Dwarf_Sword i=0; - Dwarf_Word u=0; + Dwarf_Signed i=0; + Dwarf_Unsigned u=0; /* These variables are used to decode leb128 numbers. Leb128_num holds the decoded number, and leb128_length is its length in @@ -431,16 +436,22 @@ _dwarf_internal_printlines(Dwarf_Die die, Dwarf_Unsigned tlm2 = 0; Dwarf_Unsigned di = 0; Dwarf_Unsigned fl = 0; + unsigned filenum = 0; fe = fe2; tlm2 = fe->fi_time_last_mod; di = fe->fi_dir_index; fl = fe->fi_file_length; + filenum = fiu+1; /* Assuming DWARF2,3,4 */ + if (line_context->lc_version_number == DW_LINE_VERSION5) { + /* index starts 0 for DWARF5, show 0 base. */ + filenum = fiu; + } dwarf_printf(dbg, " file[%u] %s (file-number: %u) \n", (unsigned) fiu, (char *) fe->fi_file_name, - (unsigned)(fiu+1)); + (unsigned)(filenum)); dwarf_printf(dbg, " dir index %d\n", (int) di); { @@ -454,6 +465,16 @@ _dwarf_internal_printlines(Dwarf_Die die, dwarf_printf(dbg, " file length %ld 0x%lx\n", (long) fl, (unsigned long) fl); + if (fe->fi_md5_present) { + char *c = (char *)&fe->fi_md5_value; + char *end = c+sizeof(fe->fi_md5_value); + dwarf_printf(dbg, " file md5 value 0x"); + while(c < end) { + dwarf_printf(dbg,"%02x",0xff&*c); + ++c; + } + dwarf_printf(dbg,"\n"); + } } } @@ -596,9 +617,6 @@ dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error,int *error_count) int res = _dwarf_internal_printlines(die, error, error_count, only_line_header); - if (res != DW_DLV_OK) { - return res; - } return res; } int @@ -610,9 +628,6 @@ _dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) &err_count, only_line_header); /* No way to get error count back in this interface */ - if (res != DW_DLV_OK) { - return res; - } return res; } @@ -630,5 +645,3 @@ dwarf_check_lineheader(Dwarf_Die die, int *err_count_out) only_line_header); return; } - - diff --git a/thirdparty/dwarf/dwarf_pubtypes.c b/thirdparty/dwarf/dwarf_pubtypes.c index 39768cac..d14fd7bd 100644 --- a/thirdparty/dwarf/dwarf_pubtypes.c +++ b/thirdparty/dwarf/dwarf_pubtypes.c @@ -28,8 +28,9 @@ /* Reads DWARF3 .debug_pubtypes section. */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_error.h" #include "dwarf_types.h" #include "dwarf_global.h" diff --git a/thirdparty/dwarf/dwarf_query.c b/thirdparty/dwarf/dwarf_query.c index 349221ba..90c9e6c2 100644 --- a/thirdparty/dwarf/dwarf_query.c +++ b/thirdparty/dwarf/dwarf_query.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2016 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -27,8 +26,11 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_die_deliv.h" #define TRUE 1 @@ -59,6 +61,22 @@ int dwarf_get_offset_size(Dwarf_Debug dbg, return DW_DLV_OK; } +#if 0 +static void +dump_bytes(char * msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + + printf("%s ",msg); + for (; cur < end; cur++) { + printf("%02x ", *cur); + } + printf("\n"); +} +#endif + + /* This is normally reliable. But not always. @@ -201,7 +219,7 @@ dwarf_offset_list(Dwarf_Debug dbg, Dwarf_Die sib_die = 0; Dwarf_Die cur_die = 0; Dwarf_Off cur_off = 0; - Dwarf_Word off_count = 0; + Dwarf_Unsigned off_count = 0; int res = 0; /* Temporary counter. */ @@ -303,8 +321,8 @@ dwarf_attrlist(Dwarf_Die die, Dwarf_Attribute ** attrbuf, Dwarf_Signed * attrcnt, Dwarf_Error * error) { - Dwarf_Word attr_count = 0; - Dwarf_Word i = 0; + Dwarf_Unsigned attr_count = 0; + Dwarf_Unsigned i = 0; Dwarf_Half attr = 0; Dwarf_Half attr_form = 0; Dwarf_Byte_Ptr abbrev_ptr = 0; @@ -333,7 +351,7 @@ dwarf_attrlist(Dwarf_Die die, return lres; } if (lres == DW_DLV_NO_ENTRY) { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + _dwarf_error(dbg, error, DW_DLE_ABBREV_MISSING); return DW_DLV_ERROR; } @@ -343,14 +361,26 @@ dwarf_attrlist(Dwarf_Die die, info_ptr = die->di_debug_ptr; SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); + if (info_ptr >= die_info_end) { + /* Stepped off the end SKIPping the leb */ + _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + return DW_DLV_ERROR; + } do { Dwarf_Unsigned utmp2; + Dwarf_Signed implicit_const = 0; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end); attr = (Dwarf_Half) utmp2; DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end); attr_form = (Dwarf_Half) utmp2; + if (attr_form == DW_FORM_implicit_const) { + /* The value is here, not in a DIE. */ + DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, + dbg,error,abbrev_end); + } + if (!_dwarf_valid_form_we_know(dbg,attr_form,attr)) { _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); return DW_DLV_ERROR; @@ -361,7 +391,7 @@ dwarf_attrlist(Dwarf_Die die, (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (new_attr == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (DW_DLV_ERROR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -369,24 +399,42 @@ dwarf_attrlist(Dwarf_Die die, new_attr->ar_attribute_form = attr_form; if (attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; + if (_dwarf_reference_outside_section(die, + (Dwarf_Small*) info_ptr, + ((Dwarf_Small*) info_ptr )+1)) { + _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); + return DW_DLV_ERROR; + } /* DECODE_LEB128_UWORD does info_ptr update */ DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end); attr_form = (Dwarf_Half) utmp6; new_attr->ar_attribute_form = attr_form; } - if (_dwarf_reference_outside_section(die, + /* Here the final address must be *inside* the + section, as we will read from there, and read + at least one byte, we think. + We do not want info_ptr to point past end so + we add 1 to the end-pointer. */ + if ( attr_form != DW_FORM_implicit_const && + _dwarf_reference_outside_section(die, (Dwarf_Small*) info_ptr, - (Dwarf_Small*) info_ptr)) { + ((Dwarf_Small*) info_ptr )+1)) { _dwarf_error(dbg, error,DW_DLE_ATTR_OUTSIDE_SECTION); return DW_DLV_ERROR; } new_attr->ar_cu_context = die->di_cu_context; new_attr->ar_debug_ptr = info_ptr; new_attr->ar_die = die; - { + if (attr_form == DW_FORM_implicit_const) { + /* The value is here, not in a DIE. + Do not increment info_ptr */ + new_attr->ar_implicit_const = implicit_const; + } else { Dwarf_Unsigned sov = 0; - int res = _dwarf_get_size_of_val(dbg, + int res = 0; + + res = _dwarf_get_size_of_val(dbg, attr_form, die->di_cu_context->cc_version_stamp, die->di_cu_context->cc_address_size, @@ -442,6 +490,11 @@ dwarf_attrlist(Dwarf_Die die, the given die in the .debug_info section. The form is returned in *attr_form. + If the attr_form is DW_FORM_implicit_const + (known signed, so most callers) + that is fine, but in that case we do not + need to actually set the *ptr_to_value. + Returns NULL on error, or if attr is not found. However, *attr_form is 0 on error, and positive otherwise. @@ -451,6 +504,7 @@ _dwarf_get_value_ptr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Half * attr_form, Dwarf_Byte_Ptr * ptr_to_value, + Dwarf_Signed *implicit_const_out, Dwarf_Error *error) { Dwarf_Byte_Ptr abbrev_ptr = 0; @@ -487,17 +541,21 @@ _dwarf_get_value_ptr(Dwarf_Die die, abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(context); info_ptr = die->di_debug_ptr; + /* This ensures and checks die_info_end >= info_ptr */ SKIP_LEB128_WORD_CK(info_ptr,dbg,error,die_info_end); do { - Dwarf_Unsigned utmp3 = 0; + Dwarf_Unsigned formtmp3 = 0; + Dwarf_Unsigned atmp3 = 0; Dwarf_Unsigned value_size=0; + Dwarf_Signed implicit_const = 0; int res = 0; - DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp3,dbg,error,abbrev_end); - curr_attr = (Dwarf_Half) utmp3; - DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp3,dbg,error,abbrev_end); - curr_attr_form = (Dwarf_Half) utmp3; + DECODE_LEB128_UWORD_CK(abbrev_ptr, atmp3,dbg,error,abbrev_end); + curr_attr = (Dwarf_Half) atmp3; + DECODE_LEB128_UWORD_CK(abbrev_ptr,formtmp3, + dbg,error,abbrev_end); + curr_attr_form = (Dwarf_Half) formtmp3; if (curr_attr_form == DW_FORM_indirect) { Dwarf_Unsigned utmp6; @@ -505,13 +563,19 @@ _dwarf_get_value_ptr(Dwarf_Die die, DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end); curr_attr_form = (Dwarf_Half) utmp6; } - + if (curr_attr_form == DW_FORM_implicit_const) { + /* The value is here, not in a DIE. */ + DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, + dbg,error,abbrev_end); + } if (curr_attr == attr) { *attr_form = curr_attr_form; + if(implicit_const_out) { + *implicit_const_out = implicit_const; + } *ptr_to_value = info_ptr; return DW_DLV_OK; } - res = _dwarf_get_size_of_val(dbg, curr_attr_form, die->di_cu_context->cc_version_stamp, @@ -524,11 +588,17 @@ _dwarf_get_value_ptr(Dwarf_Die die, if (res != DW_DLV_OK) { return res; } - if ((info_ptr + value_size) > die_info_end) { - /* Something badly wrong. We point past end - of debug_info or debug_types . */ - _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD); - return DW_DLV_ERROR; + { + /* ptrdiff_t is signed type, so use DW signed type */ + Dwarf_Signed len = die_info_end - info_ptr; + if (len < 0 || (value_size > ((Dwarf_Unsigned)len))) { + /* Something badly wrong. We point past end + of debug_info or debug_types or a + section is unreasonably sized or we are + pointing to two different sections? */ + _dwarf_error(dbg,error,DW_DLE_DIE_ABBREV_BAD); + return DW_DLV_ERROR; + } } info_ptr+= value_size; } while (curr_attr != 0 || curr_attr_form != 0); @@ -578,10 +648,12 @@ dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr_form = 0; Dwarf_Byte_Ptr info_ptr = 0; int res = 0; + Dwarf_Signed implicit_const; CHECK_DIE(die, DW_DLV_ERROR); - res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,error); + res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr, + &implicit_const,error); if(res == DW_DLV_ERROR) { return res; } @@ -603,11 +675,13 @@ dwarf_attr(Dwarf_Die die, Dwarf_Byte_Ptr info_ptr = 0; Dwarf_Debug dbg = 0; int res = 0; + Dwarf_Signed implicit_const = 0; CHECK_DIE(die, DW_DLV_ERROR); dbg = die->di_cu_context->cc_dbg; - res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr,error); + res = _dwarf_get_value_ptr(die, attr, &attr_form,&info_ptr, + &implicit_const,error); if(res == DW_DLV_ERROR) { return res; } @@ -615,7 +689,6 @@ dwarf_attr(Dwarf_Die die, return res; } - attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); if (attrib == NULL) { _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); @@ -626,6 +699,10 @@ dwarf_attr(Dwarf_Die die, attrib->ar_attribute_form = attr_form; attrib->ar_attribute_form_direct = attr_form; attrib->ar_cu_context = die->di_cu_context; + + /* Only nonzero if DW_FORM_implicit_const */ + attrib->ar_implicit_const = implicit_const; + /* Only nonnull if not DW_FORM_implicit_const */ attrib->ar_debug_ptr = info_ptr; attrib->ar_die = die; *ret_attr = (attrib); @@ -679,7 +756,7 @@ _dwarf_extract_address_from_debug_addr(Dwarf_Debug dbg, but with a base. */ sectionsize = dbg->de_debug_addr.dss_size; sectionend = sectionstart + sectionsize; - if ((addr_offset + context->cc_address_size) > sectionsize) { + if (addr_offset > (sectionsize - context->cc_address_size)) { _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); return (DW_DLV_ERROR); } @@ -806,7 +883,8 @@ dwarf_lowpc(Dwarf_Die die, dbg = context->cc_dbg; address_size = context->cc_address_size; offset_size = context->cc_length_size; - res = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form,&info_ptr,error); + res = _dwarf_get_value_ptr(die, DW_AT_low_pc, + &attr_form,&info_ptr,0,error); if(res == DW_DLV_ERROR) { return res; } @@ -818,7 +896,7 @@ dwarf_lowpc(Dwarf_Die die, offset_size,attr_form); if (class != DW_FORM_CLASS_ADDRESS) { /* Not the correct form for DW_AT_low_pc */ - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + _dwarf_error(dbg, error, DW_DLE_LOWPC_WRONG_CLASS); return (DW_DLV_ERROR); } @@ -863,7 +941,7 @@ dwarf_highpc(Dwarf_Die die, if (form != DW_FORM_addr) { /* Not the correct form for DWARF2/3 DW_AT_high_pc */ Dwarf_Debug dbg = die->di_cu_context->cc_dbg; - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); + _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM); return (DW_DLV_ERROR); } return (DW_DLV_OK); @@ -884,6 +962,7 @@ dwarf_dietype_offset(Dwarf_Die die, res = dwarf_attr(die,DW_AT_type,&attr,error); if (res == DW_DLV_OK) { res = dwarf_global_formref(attr,&offset,error); + dwarf_dealloc(die->di_cu_context->cc_dbg,attr,DW_DLA_ATTR); } *return_off = offset; return res; @@ -899,7 +978,6 @@ _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, { int res = 0; Dwarf_Die cudie = 0; - Dwarf_Small *cu_die_dataptr = 0; Dwarf_Unsigned cu_die_offset = 0; Dwarf_Attribute myattr = 0; @@ -909,12 +987,6 @@ _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, } cu_die_offset = context->cc_cu_die_global_sec_offset; context->cc_cu_die_offset_present = TRUE; - if(!cu_die_dataptr) { - _dwarf_error(dbg, error, - DW_DLE_DEBUG_CU_UNAVAILABLE_FOR_FORM); - return (DW_DLV_ERROR); - - } res = dwarf_offdie_b(dbg,cu_die_offset, context->cc_is_info, &cudie, @@ -930,7 +1002,14 @@ _dwarf_get_string_base_attr_value(Dwarf_Debug dbg, } if (res == DW_DLV_OK) { Dwarf_Unsigned val = 0; - res = dwarf_formudata(myattr,&val,error); + /* Expect DW_FORM_sec_offset */ + if (myattr->ar_attribute_form != DW_FORM_sec_offset) { + dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); + dwarf_dealloc(dbg,cudie,DW_DLA_DIE); + _dwarf_error(dbg, error,DW_DLE_STR_OFFSETS_BASE_WRONG_FORM); + return (DW_DLV_ERROR); + } + res = dwarf_global_formref(myattr,&val,error); dwarf_dealloc(dbg,myattr,DW_DLA_ATTR); dwarf_dealloc(dbg,cudie,DW_DLA_DIE); if(res != DW_DLV_OK) { @@ -1073,7 +1152,7 @@ _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg, if(res != DW_DLV_OK) { return res; } - res = dwarf_attr(cudie,DW_AT_ranges_base, + res = dwarf_attr(cudie,DW_AT_rnglists_base, &myattr,error); if(res == DW_DLV_ERROR) { dwarf_dealloc(dbg,cudie,DW_DLA_DIE); @@ -1093,7 +1172,7 @@ _dwarf_get_ranges_base_attr_value(Dwarf_Debug dbg, /* NO ENTRY, try the other attr. */ res = dwarf_attr(cudie,DW_AT_GNU_ranges_base, &myattr,error); if(res == DW_DLV_NO_ENTRY) { - res = dwarf_attr(cudie,DW_AT_ranges_base, &myattr,error); + res = dwarf_attr(cudie,DW_AT_rnglists_base, &myattr,error); if (res == DW_DLV_NO_ENTRY) { /* A .o or execeutable skeleton needs a base , but a .dwo does not. @@ -1153,14 +1232,16 @@ dwarf_highpc_b(Dwarf_Die die, dbg = die->di_cu_context->cc_dbg; address_size = die->di_cu_context->cc_address_size; - res = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form,&info_ptr,error); + res = _dwarf_get_value_ptr(die, DW_AT_high_pc, + &attr_form,&info_ptr,0,error); if(res == DW_DLV_ERROR) { return res; } if(res == DW_DLV_NO_ENTRY) { return res; } - die_info_end = _dwarf_calculate_info_section_end_ptr(die->di_cu_context); + die_info_end = _dwarf_calculate_info_section_end_ptr( + die->di_cu_context); version = die->di_cu_context->cc_version_stamp; offset_size = die->di_cu_context->cc_length_size; @@ -1216,8 +1297,13 @@ dwarf_highpc_b(Dwarf_Die die, } } *return_value = addr_out; - *return_form = attr_form; - *return_class = class; + /* Allow null args starting 22 April 2019. */ + if (return_form) { + *return_form = attr_form; + } + if (return_class) { + *return_class = class; + } return (DW_DLV_OK); } @@ -1232,12 +1318,13 @@ dwarf_highpc_b(Dwarf_Die die, &v,error); if(res3 != DW_DLV_OK) { Dwarf_Byte_Ptr info_ptr2 = 0; + res3 = _dwarf_get_value_ptr(die, DW_AT_high_pc, - &attr_form,&info_ptr2,error); + &attr_form,&info_ptr2,0,error); if(res3 == DW_DLV_ERROR) { return res3; } - if(res == DW_DLV_NO_ENTRY) { + if(res3 == DW_DLV_NO_ENTRY) { return res3; } if (attr_form == DW_FORM_sdata) { @@ -1249,16 +1336,21 @@ dwarf_highpc_b(Dwarf_Die die, dbg,error,die_info_end); *return_value = (Dwarf_Unsigned)sval; } else { - _dwarf_error(dbg, error, DW_DLE_DIE_BAD); - return (DW_DLV_ERROR); + _dwarf_error(dbg, error, DW_DLE_HIGHPC_WRONG_FORM); + return DW_DLV_ERROR; } } else { *return_value = v; } } - *return_form = attr_form; - *return_class = class; - return (DW_DLV_OK); + /* Allow null args starting 22 April 2019. */ + if (return_form) { + *return_form = attr_form; + } + if (return_class) { + *return_class = class; + } + return DW_DLV_OK; } /* The dbg and context here are a file with DW_FORM_addrx @@ -1399,13 +1491,16 @@ _dwarf_die_attr_unsigned_constant(Dwarf_Die die, die_info_end = _dwarf_calculate_info_section_end_ptr(die->di_cu_context); dbg = die->di_cu_context->cc_dbg; res = _dwarf_get_value_ptr(die,attr,&attr_form, - &info_ptr,error); + &info_ptr,0,error); if(res != DW_DLV_OK) { return res; } switch (attr_form) { case DW_FORM_data1: - *return_val = (*(Dwarf_Small *) info_ptr); + READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, + info_ptr, sizeof(Dwarf_Small), + error,die_info_end); + *return_val = ret_value; return (DW_DLV_OK); case DW_FORM_data2: @@ -1417,14 +1512,14 @@ _dwarf_die_attr_unsigned_constant(Dwarf_Die die, case DW_FORM_data4: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_sfixed), + info_ptr, DWARF_32BIT_SIZE, error,die_info_end); *return_val = ret_value; return (DW_DLV_OK); case DW_FORM_data8: READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - info_ptr, sizeof(Dwarf_Unsigned), + info_ptr, DWARF_64BIT_SIZE, error,die_info_end); *return_val = ret_value; return (DW_DLV_OK); @@ -1551,15 +1646,32 @@ dwarf_die_abbrev_children_flag(Dwarf_Die die,Dwarf_Half *ab_has_child) /* Helper function for finding form class. */ static enum Dwarf_Form_Class -dw_get_special_offset(Dwarf_Half attrnum) +dw_get_special_offset(Dwarf_Half attrnum, + Dwarf_Half dwversion) { switch (attrnum) { case DW_AT_stmt_list: return DW_FORM_CLASS_LINEPTR; - case DW_AT_macro_info: + case DW_AT_macro_info: /* DWARF2-DWARF4 */ return DW_FORM_CLASS_MACPTR; - case DW_AT_ranges: - return DW_FORM_CLASS_RANGELISTPTR; + case DW_AT_start_scope: + case DW_AT_ranges: { + if (dwversion <= 4) { + return DW_FORM_CLASS_RANGELISTPTR; + } + return DW_FORM_CLASS_RNGLIST; + } + case DW_AT_rnglists_base: /* DWARF5 */ + return DW_FORM_CLASS_RNGLISTSPTR; + case DW_AT_macros: /* DWARF5 */ + return DW_FORM_CLASS_MACROPTR; + case DW_AT_loclists_base: /* DWARF5 */ + return DW_FORM_CLASS_LOCLISTSPTR; + case DW_AT_addr_base: /* DWARF5 */ + return DW_FORM_CLASS_ADDRPTR; + case DW_AT_str_offsets_base: /* DWARF5 */ + return DW_FORM_CLASS_STROFFSETSPTR; + case DW_AT_location: case DW_AT_string_length: case DW_AT_return_addr: @@ -1568,8 +1680,12 @@ dw_get_special_offset(Dwarf_Half attrnum) case DW_AT_segment: case DW_AT_static_link: case DW_AT_use_location: - case DW_AT_vtable_elem_location: - return DW_FORM_CLASS_LOCLISTPTR; + case DW_AT_vtable_elem_location: { + if (dwversion <= 4) { + return DW_FORM_CLASS_LOCLISTPTR; + } + return DW_FORM_CLASS_LOCLIST; + } case DW_AT_sibling: case DW_AT_byte_size : case DW_AT_bit_offset : @@ -1617,13 +1733,13 @@ dwarf_get_form_class( Dwarf_Half form) { switch (form) { - case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS; - + case DW_FORM_addr: return DW_FORM_CLASS_ADDRESS; case DW_FORM_data2: return DW_FORM_CLASS_CONSTANT; case DW_FORM_data4: if (dwversion <= 3 && offset_size == 4) { - enum Dwarf_Form_Class class = dw_get_special_offset(attrnum); + enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, + dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } @@ -1631,16 +1747,17 @@ dwarf_get_form_class( return DW_FORM_CLASS_CONSTANT; case DW_FORM_data8: if (dwversion <= 3 && offset_size == 8) { - enum Dwarf_Form_Class class = dw_get_special_offset(attrnum); + enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, + dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } } return DW_FORM_CLASS_CONSTANT; - case DW_FORM_sec_offset: { - enum Dwarf_Form_Class class = dw_get_special_offset(attrnum); + enum Dwarf_Form_Class class = dw_get_special_offset(attrnum, + dwversion); if (class != DW_FORM_CLASS_UNKNOWN) { return class; } @@ -1656,6 +1773,7 @@ dwarf_get_form_class( case DW_FORM_block2: return DW_FORM_CLASS_BLOCK; case DW_FORM_block4: return DW_FORM_CLASS_BLOCK; + case DW_FORM_data16: return DW_FORM_CLASS_CONSTANT; case DW_FORM_data1: return DW_FORM_CLASS_CONSTANT; case DW_FORM_sdata: return DW_FORM_CLASS_CONSTANT; case DW_FORM_udata: return DW_FORM_CLASS_CONSTANT; @@ -1675,12 +1793,16 @@ dwarf_get_form_class( case DW_FORM_addrx: return DW_FORM_CLASS_ADDRESS; /* DWARF5 */ case DW_FORM_GNU_addr_index: return DW_FORM_CLASS_ADDRESS; - case DW_FORM_strx: return DW_FORM_CLASS_STRING; /* DWARF5 */ + case DW_FORM_strx: return DW_FORM_CLASS_STRING; /* DWARF5 */ case DW_FORM_GNU_str_index: return DW_FORM_CLASS_STRING; + case DW_FORM_rnglistx: return DW_FORM_CLASS_RNGLIST; /* DWARF5 */ + case DW_FORM_loclistx: return DW_FORM_CLASS_LOCLIST; /* DWARF5 */ + case DW_FORM_GNU_ref_alt: return DW_FORM_CLASS_REFERENCE; case DW_FORM_GNU_strp_alt: return DW_FORM_CLASS_STRING; - case DW_FORM_strp_sup: return DW_FORM_CLASS_STRING; /* DWARF5 */ + case DW_FORM_strp_sup: return DW_FORM_CLASS_STRING; /* DWARF5 */ + case DW_FORM_implicit_const: return DW_FORM_CLASS_CONSTANT; /* DWARF5 */ case DW_FORM_indirect: default: @@ -1766,7 +1888,3 @@ _dwarf_calculate_abbrev_section_end_ptr(Dwarf_CU_Context context) abbrev_end = abbrev_start + sec->dss_size; return abbrev_end; } - - - - diff --git a/thirdparty/dwarf/dwarf_ranges.c b/thirdparty/dwarf/dwarf_ranges.c index 5b441e58..82681005 100644 --- a/thirdparty/dwarf/dwarf_ranges.c +++ b/thirdparty/dwarf/dwarf_ranges.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2008-2016 David Anderson. All Rights Reserved. + Copyright (C) 2008-2018 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -27,6 +27,9 @@ #include "config.h" #include #include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" struct ranges_entry { struct ranges_entry *next; @@ -34,10 +37,45 @@ struct ranges_entry { }; +static void +free_allocated_ranges( struct ranges_entry *base) +{ + struct ranges_entry *cur = 0; + struct ranges_entry *next = 0; + for ( cur = base ; cur ; cur = next ) { + next = cur->next; + free(cur); + } +} + +/* We encapsulate the macro use so we can + free local malloc resources that would otherwise + leak. See the call points below. */ +static int +read_unaligned_addr_check(Dwarf_Debug dbg, + Dwarf_Addr *addr_out, + Dwarf_Small *rangeptr, + unsigned address_size, + Dwarf_Error *error, + Dwarf_Small *section_end) +{ + Dwarf_Addr a = 0; + + READ_UNALIGNED_CK(dbg,a, + Dwarf_Addr, rangeptr, + address_size, + error,section_end); + *addr_out = a; + return DW_DLV_OK; +} + /* Ranges are never in a split dwarf object. In the base object instead. So use the tied_object if present. We return an error which is on the incoming dbg, not - the possibly-tied-dbg localdbg. */ + the possibly-tied-dbg localdbg. + If incoming die is NULL there is no context, so do not look + for a tied file, and address_size is the size + of the overall object, not the address_size of the context. */ #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) int dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Off rangesoffset, @@ -62,7 +100,7 @@ int dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Debug localdbg = dbg; Dwarf_Error localerror = 0; - if (localdbg->de_tied_data.td_tied_object) { + if (die &&localdbg->de_tied_data.td_tied_object) { /* ASSERT: localdbg->de_debug_ranges is missing: DW_DLV_NO_ENTRY. So lets not look in dbg. */ Dwarf_CU_Context context = 0; @@ -111,28 +149,45 @@ int dwarf_get_ranges_a(Dwarf_Debug dbg, beginrangeptr = rangeptr; for (;;) { - struct ranges_entry * re = calloc(sizeof(struct ranges_entry),1); + struct ranges_entry * re = 0; + + if (rangeptr == section_end) { + break; + } + if (rangeptr > section_end) { + free_allocated_ranges(base); + _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); + return (DW_DLV_ERROR); + break; + } + re = calloc(sizeof(struct ranges_entry),1); if (!re) { + free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); return (DW_DLV_ERROR); } - if (rangeptr >= section_end) { - return (DW_DLV_NO_ENTRY); - } if ((rangeptr + (2*address_size)) > section_end) { + free(re); + free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OFFSET_BAD); return (DW_DLV_ERROR); } entry_count++; - READ_UNALIGNED_CK(localdbg,re->cur.dwr_addr1, - Dwarf_Addr, rangeptr, - address_size, - error,section_end); + res = read_unaligned_addr_check(localdbg,&re->cur.dwr_addr1, + rangeptr, address_size,error,section_end); + if (res != DW_DLV_OK) { + free(re); + free_allocated_ranges(base); + return res; + } rangeptr += address_size; - READ_UNALIGNED_CK(localdbg,re->cur.dwr_addr2 , - Dwarf_Addr, rangeptr, - address_size, - error,section_end); + res = read_unaligned_addr_check(localdbg,&re->cur.dwr_addr2, + rangeptr, address_size,error,section_end); + if (res != DW_DLV_OK) { + free(re); + free_allocated_ranges(base); + return res; + } rangeptr += address_size; if (!base) { base = re; @@ -156,6 +211,7 @@ int dwarf_get_ranges_a(Dwarf_Debug dbg, _dwarf_get_alloc(dbg,DW_DLA_RANGES,entry_count); if (!ranges_data_out) { /* Error, apply to original, not local dbg. */ + free_allocated_ranges(base); _dwarf_error(dbg, error, DW_DLE_DEBUG_RANGES_OUT_OF_MEM); return (DW_DLV_ERROR); } @@ -165,11 +221,12 @@ int dwarf_get_ranges_a(Dwarf_Debug dbg, for (copyindex = 0; curre && (copyindex < entry_count); ++copyindex,++ranges_data_out) { - struct ranges_entry *r = curre; *ranges_data_out = curre->cur; curre = curre->next; - free(r); } + /* ASSERT: curre == NULL */ + free_allocated_ranges(base); + base = 0; /* Callers will often not care about the bytes used. */ if (bytecount) { *bytecount = rangeptr - beginrangeptr; @@ -195,4 +252,3 @@ dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf, { dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES); } - diff --git a/thirdparty/dwarf/dwarf_reading.h b/thirdparty/dwarf/dwarf_reading.h new file mode 100644 index 00000000..e722d095 --- /dev/null +++ b/thirdparty/dwarf/dwarf_reading.h @@ -0,0 +1,75 @@ +/* +Copyright (c) 2018, David Anderson +All rights reserved. + +Redistribution and use in source and binary forms, with +or without modification, are permitted provided that the +following conditions are met: + + Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +#ifndef DWARF_READING_H +#define DWARF_READING_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef DW_DLV_OK +/* DW_DLV_OK must match libdwarf.h */ +/* DW_DLV_NO_ENTRY must match libdwarf.h */ +#define DW_DLV_OK 0 +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_ERROR 1 +#endif /* DW_DLV_OK */ + +#define TRUE 1 +#define FALSE 0 + +#define ALIGN4 4 +#define ALIGN8 8 + +#define PREFIX "\t" +#define LUFMT "%lu" +#define UFMT "%u" +#define DFMT "%d" +#define XFMT "0x%x" + +/* even if already seen, values must match, so no #ifdef needed. */ +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 + +#define P printf +#define F fflush(stdout) + +#define RRMOA(f,buf,loc,siz,fsiz,errc) _dwarf_object_read_random(f, \ + (char *)buf,loc,siz,fsiz,errc); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* DWARF_READING_H */ diff --git a/thirdparty/dwarf/dwarf_reloc_386.h b/thirdparty/dwarf/dwarf_reloc_386.h new file mode 100644 index 00000000..6aa88917 --- /dev/null +++ b/thirdparty/dwarf/dwarf_reloc_386.h @@ -0,0 +1,125 @@ +/* + Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2012 SN Systems Ltd. All rights reserved. + + 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 + published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, write the Free Software Foundation, Inc., 51 + Franklin Street - Fifth Floor, Boston MA 02110-1301, USA. +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DWARF_RELOC_386_H +#define DWARF_RELOC_386_H + +/* Include the definitions only in the case of Windows */ +#ifdef _WIN32 +/* Relocation types for i386 architecture */ +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 +#define R_386_TLS_IE 15 +#define R_386_TLS_GOTIE 16 +#define R_386_TLS_LE 17 +#define R_386_TLS_LDM 19 +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 +#define R_386_TLS_GD_PUSH 25 +#define R_386_TLS_GD_CALL 26 +#define R_386_TLS_GD_POP 27 +#define R_386_TLS_LDM_32 28 +#define R_386_TLS_LDM_PUSH 29 +#define R_386_TLS_LDM_CALL 30 +#define R_386_TLS_LDM_POP 31 +#define R_386_TLS_LDO_32 32 +#define R_386_TLS_IE_32 33 +#define R_386_TLS_LE_32 34 +#define R_386_TLS_DTPMOD32 35 +#define R_386_TLS_DTPOFF32 36 +#define R_386_TLS_TPOFF32 37 +#define R_386_SIZE32 38 +#define R_386_TLS_GOTDESC 39 +#define R_386_TLS_DESC_CALL 40 +#define R_386_TLS_DESC 41 +#define R_386_IRELATIVE 42 +#define R_386_NUM 43 + + +/* Keep this the last entry. */ +#define R_X86_64_NUM 39 +#endif /* _WIN32 */ + +/* Relocation types for X86_64 */ +static const char *reloc_type_names_386[] = { +"R_386_NONE", +"R_386_32", +"R_386_PC32", +"R_386_GOT32", +"R_386_PLT32", +"R_386_COPY", /* 5 */ +"R_386_GLOB_DAT", +"R_386_JMP_SLOT", +"R_386_RELATIVE", +"R_386_GOTOFF", +"R_386_GOTPC", /* 10 */ +"R_386_32PLT", +"R_386_TLS_TPOFF", +"R_386_TLS_IE", +"R_386_TLS_GOTIE", +"R_386_TLS_LE", +"R_386_TLS_LDM", +"R_386_16", /* 20 */ +"R_386_PC16", +"R_386_8", +"R_386_PC8", +"R_386_TLS_GD_32", +"R_386_TLS_GD_PUSH", /* 25 */ +"R_386_TLS_GD_CALL", +"R_386_TLS_GD_POP", +"R_386_TLS_LDM_32", +"R_386_TLS_LDM_PUSH", +"R_386_TLS_LDM_CALL", /* 30 */ +"R_386_TLS_LDM_POP", +"R_386_TLS_LDO_32", +"R_386_TLS_IE_32", +"R_386_TLS_LE_32", +"R_386_TLS_DTPMOD32", /* 35 */ +"R_386_TLS_DTPOFF32", +"R_386_TLS_TPOFF32", +"R_386_SIZE32", +"R_386_TLS_GOTDESC", +"R_386_TLS_DESC_CALL", /* 40 */ +"R_386_TLS_DESC", +"R_386_IRELATIVE", /* 42 */ +}; +#endif /* DWARF_RELOC_386_H */ diff --git a/thirdparty/dwarf/dwarf_sort_line.c b/thirdparty/dwarf/dwarf_sort_line.c deleted file mode 100644 index 33536dc9..00000000 --- a/thirdparty/dwarf/dwarf_sort_line.c +++ /dev/null @@ -1,665 +0,0 @@ -/* - Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. - -*/ - -/* This file was designed for SGI IRIX compiler use. - The static linker can rearrange the order of functions - in the layout in memory - and provided each has the right form - this will (when called by the SGI IRIX - static linker) rearrange the table so the line table - is arranged in the same order as the memory layout. */ - -#include "config.h" -#ifdef __sgi /* SGI IRIX ONLY */ -#include "dwarf_incl.h" -#include -#include -#include "dwarf_line.h" -#ifdef HAVE_ALLOCA_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif - -#define MINIMUM_POSSIBLE_PROLOG_LEN 10 /* 10 is based on */ -/* the definition of the DWARF2/3 line table prolog. The value - here should be >8 (accounting for a 64 bit read) and <= the - length of a legal DWARF2/3 line prolog, which is at least 10 - bytes long (but can be longer). What this constant helps - avoid is reading past the end of a malloc'd buffer in - _dwarf_update_line_sec(). */ - -static int -_dwarf_update_line_sec(Dwarf_Small * line_ptr, - unsigned long remaining_bytes, - int *any_change, - int length_size, - int *err_code, Dwarf_Small ** new_line_ptr); - -/* Used to construct - a linked list of so we can sort and reorder the line info. */ -struct a_line_area { - Dwarf_Addr ala_address; /* from DW_LNE_set_address */ - Dwarf_Unsigned ala_offset; /* byte offset in buffer */ - Dwarf_Unsigned ala_length; /* byte length in buffer */ - long ala_entry_num; /* to guarantee stable sort */ - struct a_line_area *ala_next; -}; - - -/* Written to support the SGI IRIX static linker. - It helps SGI IRIX ld - rearrange lines in .debug_line in a .o created with a text - section per function. The SGI IRIX linker option is: - -OPT:procedure_reorder=ON - where ld-cord (cord(1)ing by ld, - not by cord(1)) may have changed the function order. - - Returns - DW_DLV_OK if nothing went wrong. - DW_DLV_ERROR if could not do anything due to - error. the original buffer is unchanged. - - is_64_bit must be passed in by caller and tells - if this is a 32 or 64bit pointer object section - being processed. - - err_code must be a non-null pointer to integer. - If DW_DLV_ERROR is returned that integer is set - to a dwarf error code so the caller may - print it for diagnostic purposes. - - *any_change is set here - set 0 if no sorting (movement) done. - set 1 if some sorting (movement) done. - on all returns. On error return sets to 0. - - The _dwarf name form is now obsolete, - the dwarf_ name for is preferred. - Both names supported. */ -int -_dwarf_ld_sort_lines(void *orig_buffer, - unsigned long buffer_len, - int is_64_bit, int *any_change, int *err_code) -{ - return dwarf_ld_sort_lines(orig_buffer,buffer_len, - is_64_bit,any_change,err_code); -} -int -dwarf_ld_sort_lines(void *orig_buffer, - unsigned long buffer_len, - int is_64_bit, int *any_change, int *err_code) -{ - - int length_size = 4; - Dwarf_Small *orig_line_ptr; /* our local copy of the user's input - buffer */ - Dwarf_Small *line_ptr; /* starts at orig_line_ptr, gets - incremented thru to end of our copy - of the input buffer */ - Dwarf_Small *new_line_ptr; /* output of _dwarf_update_line_sec(), - used to update line_ptr as we pass - thru compilation units in a .o - .debug_line */ - - unsigned long remaining_bytes = buffer_len; /* total length of - original area left to be processed. Changes as we pass - thru compilation units in a .o .debug_line */ - - int sec_res; - int lany_change = 0; - int did_change = 0; - - if (is_64_bit) - length_size = 8; - - *any_change = 0; - line_ptr = malloc(buffer_len); - if (!line_ptr) { - *err_code = DW_DLE_ALLOC_FAIL; - return DW_DLV_ERROR; - } - orig_line_ptr = line_ptr; - memcpy(line_ptr, orig_buffer, buffer_len); - - - /* We must iterate thru each of a set of prologues and line data. - We process each set in turn. If all pass, we update the - passed-in buffer. */ - sec_res = DW_DLV_OK; - - for (sec_res = _dwarf_update_line_sec(line_ptr, - remaining_bytes, &lany_change, length_size, err_code, &new_line_ptr); - (sec_res == DW_DLV_OK) && (remaining_bytes > 0); - sec_res = _dwarf_update_line_sec(line_ptr, - remaining_bytes, &lany_change, length_size, - err_code, &new_line_ptr)) { - long bytes_used = new_line_ptr - line_ptr; - - line_ptr = new_line_ptr; - remaining_bytes -= bytes_used; - if (lany_change) { - did_change = 1; - } - if (remaining_bytes > 0) { - continue; - } - break; - } - if (sec_res == DW_DLV_ERROR) { - free(orig_line_ptr); - return sec_res; - } - - - /* all passed */ - if (did_change) { - /* So update the passed in buffer orig_buffer is caller's input - area. orig_line_ptr is our modified copy of input area. */ - memcpy(orig_buffer, orig_line_ptr, buffer_len); - *any_change = 1; - } - free(orig_line_ptr); - - return sec_res; -} - - -/* By setting ala_entry_num we guarantee a stable sort, - no duplicates - Sorting in address order. -*/ -static int -cmpr(const void *lin, const void *rin) -{ - const struct a_line_area *l = lin; - const struct a_line_area *r = rin; - - if (l->ala_address < r->ala_address) { - return -1; - } - if (l->ala_address > r->ala_address) { - return 1; - } - if (l->ala_entry_num < r->ala_entry_num) { - return -1; - } - if (l->ala_entry_num > r->ala_entry_num) { - return 1; - } - return 0; /* should never happen. */ -} - -/* The list of line area records is no longer needed. - Free the data allocated. */ -static void -free_area_data(struct a_line_area *arp) -{ - while (arp) { - struct a_line_area *next = arp->ala_next; - free(arp); - arp = next; - } -} - -/* On entry: - line_ptr must point to first - byte of a line group for one (original) .o - - remaining_bytes is the size of the area pointed to - by line_ptr: may be larger than the - current original compilation unit . - - length size is 4 for 32bit pointers, 8 for 64bit pointers - in the data pointed to. - - - On return: - return DW_DLV_OK if all ok. (ignore - *err_code in this case) - - return DW_DLV_ERROR and set *err_code if an error. - - If some line data was moved around, set *any_change to 1. - If error or no movement, set *any_change to 0; - - Set *new_line_ptr to one-byte-past the end of the - current original compilation unit (not necessary - if returning DW_DLV_ERROR, but not harmful). - - This copies the entire array to a malloc area, then - mallocs pieces of it (another malloc) for sorting a CU entries - and copying back. Then at end the whole new thing copied in. - The result is that on error, the input is not touched. - - An alternative would be to just update a piece at a time - and on error stop updating but leave what was done, done. - This alternative would save some temporary malloc space. */ -static int -_dwarf_update_line_sec(Dwarf_Small * line_ptr, - unsigned long remaining_bytes, - int *any_change, - int length_size, - int *err_code, Dwarf_Small ** new_line_ptr) -{ - /* This points to the last byte of the .debug_line portion for the - current cu. */ - Dwarf_Small *line_ptr_end = 0; - - /* This points to the end of the statement program prologue for the - current cu, and serves to check that the prologue was correctly - decoded. */ - - Dwarf_Small *orig_line_ptr = 0; - - /* These are the fields of the statement program header. */ - struct Dwarf_Debug_s dbg_data; - Dwarf_Debug dbg = &dbg_data; - - /* These are the state machine state variables. */ - Dwarf_Addr address = 0; - Dwarf_Word line = 1; - Dwarf_Bool is_stmt = false; - - /* Dwarf_Bool prologue_end; Dwarf_Bool epilogue_begin; */ - Dwarf_Small isa = 0; - - - struct a_line_area *area_base = 0; - struct a_line_area *area_current = 0; - long area_count = 0; - - Dwarf_Addr last_address = 0; - int need_to_sort = 0; - - /* This is the current opcode read from the statement program. */ - Dwarf_Small opcode = 0; - - - /* These variables are used to decode leb128 numbers. Leb128_num - holds the decoded number, and leb128_length is its length in - bytes. */ - Dwarf_Word leb128_num = 0; - Dwarf_Sword advance_line = 0; - - /* This is the operand of the latest fixed_advance_pc extended - opcode. */ - Dwarf_Half fixed_advance_pc = 0; - - /* This is the length of an extended opcode instr. */ - Dwarf_Word instr_length = 0; - Dwarf_Small ext_opcode = 0; - struct Line_Table_Prefix_s prefix; - - - - memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); - dbg->de_copy_word = memcpy; - /* Following is a straightforward decoding of the statement program - prologue information. */ - *any_change = 0; - - - orig_line_ptr = line_ptr; - if (remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) { - /* We are at the end. Remaining should be zero bytes, padding. - This is really just 'end of CU buffer' not an error. The is - no 'entry' left so report there is none. We don't want to - READ_UNALIGNED the total_length below and then belatedly - discover that we read off the end already. */ - return (DW_DLV_NO_ENTRY); - } - - dwarf_init_line_table_prefix(&prefix); - { - Dwarf_Small *line_ptr_out = 0; - Dwarf_Error error = 0; - int dres = _dwarf_read_line_table_prefix(dbg, - NULL, /* context*/ - line_ptr, - remaining_bytes, - &line_ptr_out, - &prefix, - NULL, NULL,&error, - NULL); - - if (dres == DW_DLV_ERROR) { - dwarf_free_line_table_prefix(&prefix); - *err_code = dwarf_errno(error); - dwarf_dealloc(dbg, error, DW_DLA_ERROR); - free_area_data(area_base); - return dres; - } - if (dres == DW_DLV_NO_ENTRY) { - dwarf_free_line_table_prefix(&prefix); - return dres; - } - line_ptr_end = prefix.pf_line_ptr_end; - line_ptr = line_ptr_out; - } - - /* Initialize the state machine. */ - /* file = 1; */ - /* column = 0; */ - is_stmt = prefix.pf_default_is_stmt; - /* basic_block = false; */ - /* end_sequence = false; */ - /* prologue_end = false; */ - /* epilogue_begin = false; */ - isa = 0; - - - /* Start of statement program. */ - while (line_ptr < line_ptr_end) { - int type; - Dwarf_Small *stmt_prog_entry_start = line_ptr; - - opcode = *(Dwarf_Small *) line_ptr; - line_ptr++; - /* 'type' is the output */ - WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base, - prefix.pf_opcode_length_table, line_ptr, - prefix.pf_std_op_count); - - if (type == LOP_DISCARD) { - int oc; - int opcnt = prefix.pf_opcode_length_table[opcode]; - - for (oc = 0; oc < opcnt; oc++) { - /* Read and discard operands we don't - understand. - arbitrary choice of unsigned read. - signed read would work as well. */ - /* utmp2 set but not used here */ - Dwarf_Unsigned utmp2; - - DECODE_LEB128_UWORD(line_ptr, utmp2); - } - - } else if (type == LOP_SPECIAL) { - opcode = opcode - prefix.pf_opcode_base; - address = address + prefix.pf_minimum_instruction_length * - (opcode / prefix.pf_line_range); - line = - line + prefix.pf_line_base + - opcode % prefix.pf_line_range; - - /* basic_block = false; */ - } else if (type == LOP_STANDARD) { - switch (opcode) { - case DW_LNS_copy:{ - /* basic_block = false; */ - break; - } - - case DW_LNS_advance_pc:{ - Dwarf_Unsigned utmp2; - - DECODE_LEB128_UWORD(line_ptr, utmp2); - leb128_num = (Dwarf_Word) utmp2; - address = address + - prefix.pf_minimum_instruction_length * leb128_num; - break; - } - - case DW_LNS_advance_line:{ - Dwarf_Signed stmp; - - DECODE_LEB128_SWORD(line_ptr, stmp); - advance_line = (Dwarf_Sword) stmp; - line = line + advance_line; - break; - } - - case DW_LNS_set_file:{ - /* utmp2 set but not used here. */ - Dwarf_Unsigned utmp2; - - DECODE_LEB128_UWORD(line_ptr, utmp2); - /* file = (Dwarf_Word)utmp2; */ - break; - } - - case DW_LNS_set_column:{ - /* utmp2 set but not used here. */ - Dwarf_Unsigned utmp2; - - DECODE_LEB128_UWORD(line_ptr, utmp2); - /* column = (Dwarf_Word)utmp2; */ - break; - } - - case DW_LNS_negate_stmt:{ - is_stmt = !is_stmt; - break; - } - - case DW_LNS_set_basic_block:{ - /* basic_block = true; */ - break; - } - - case DW_LNS_const_add_pc:{ - opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base; - address = address + - prefix.pf_minimum_instruction_length * - (opcode / prefix. pf_line_range); - break; - } - - case DW_LNS_fixed_advance_pc:{ - - READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, - line_ptr, sizeof(Dwarf_Half)); - line_ptr += sizeof(Dwarf_Half); - address = address + fixed_advance_pc; - break; - } - /* New in DWARF3 */ - case DW_LNS_set_prologue_end:{ - /* prologue_end = true; */ - break; - - - } - /* New in DWARF3 */ - case DW_LNS_set_epilogue_begin:{ - /* epilogue_begin = true; */ - break; - } - - /* New in DWARF3 */ - case DW_LNS_set_isa:{ - Dwarf_Unsigned utmp2; - - DECODE_LEB128_UWORD(line_ptr, utmp2); - isa = utmp2; - if (isa != utmp2) { - /* The value of the isa did not fit in our - local so we record it wrong. declare an - error. */ - dwarf_free_line_table_prefix(&prefix); - *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD; - free_area_data(area_base); - return (DW_DLV_ERROR); - } - break; - } - } - } else if (type == LOP_EXTENDED) { - Dwarf_Unsigned utmp3 = 0; - - DECODE_LEB128_UWORD(line_ptr, utmp3); - instr_length = (Dwarf_Word) utmp3; - ext_opcode = *(Dwarf_Small *) line_ptr; - line_ptr++; - switch (ext_opcode) { - - case DW_LNE_end_sequence:{ - /* end_sequence = true; */ - - address = 0; - /* file = 1; */ - line = 1; - /* column = 0; */ - is_stmt = prefix.pf_default_is_stmt; - /* basic_block = false; */ - /* end_sequence = false; */ - /* prologue_end = false; */ - /* epilogue_begin = false; */ - } - break; - case DW_LNE_set_address:{ - struct a_line_area *area = 0; - - READ_UNALIGNED(dbg, address, Dwarf_Addr, - line_ptr, length_size); - /* Here we need to remember the offset into the - buffer and check to see if address went - down. */ - if (address < last_address) { - need_to_sort = 1; - } - last_address = address; - - area = malloc(sizeof(struct a_line_area)); - area->ala_address = address; - area->ala_offset = stmt_prog_entry_start - - orig_line_ptr; - area->ala_entry_num = area_count; - area->ala_next = 0; - area->ala_length = 0; - if (area_current) { - area_current->ala_next = area; - area_current->ala_length = - area->ala_offset - - area_current->ala_offset; - } - ++area_count; - area_current = area; - if (area_base == 0) { - area_base = area; - } - - line_ptr += length_size; - } - break; - - case DW_LNE_define_file:{ - break; - } - - default:{ - Dwarf_Unsigned remaining_bytes2 = instr_length -1; - line_ptr += remaining_bytes2; - break; - } - } - - } - } - - - *new_line_ptr = line_ptr; - if (!need_to_sort) { - dwarf_free_line_table_prefix(&prefix); - free_area_data(area_base); - return (DW_DLV_OK); - } - - /* So now we have something to sort. First, finish off the last - area record: */ - area_current->ala_length = (line_ptr - orig_line_ptr) - -area_current->ala_offset; - - /* Build and sort a simple array of sections. Forcing a stable sort - by comparing on sequence number. We will use the sorted list to - move sections of this part of the line table. Each 'section' - starting with a DW_LNE_set_address opcode, on the assumption - that such only get out of order where there was an ld-cord - function rearrangement and that it is meaningful to restart the - line info there. */ - { - struct a_line_area *ala_array; - struct a_line_area *local; - long start_len; - Dwarf_Small *new_area; - long i; - - ala_array = malloc(area_count * sizeof(struct a_line_area)); - if (!ala_array) { - dwarf_free_line_table_prefix(&prefix); - *err_code = DW_DLE_ALLOC_FAIL; - free_area_data(area_base); - return DW_DLV_ERROR; - } - - for (local = area_base, i = 0; local; - local = local->ala_next, ++i) { - - ala_array[i] = *local; - } - free_area_data(area_base); - /* Zero the stale pointers so we don't use them accidentally. */ - area_base = 0; - area_current = 0; - - qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr); - - /* Now we must rearrange the pieces of the line table. */ - - start_len = - (prefix.pf_line_prologue_start + - prefix.pf_prologue_length) - orig_line_ptr; - new_area = malloc(remaining_bytes); - if (!new_area) { - free(ala_array); - *err_code = DW_DLE_ALLOC_FAIL; - dwarf_free_line_table_prefix(&prefix); - return DW_DLV_ERROR; - } - memcpy(new_area, orig_line_ptr, start_len); - line_ptr = new_area + start_len; - for (i = 0; i < area_count; ++i) { - memcpy(line_ptr, orig_line_ptr + - ala_array[i].ala_offset, ala_array[i].ala_length); - line_ptr += ala_array[i].ala_length; - } - - memcpy(orig_line_ptr, new_area, remaining_bytes); - - free(new_area); - free(ala_array); - ala_array = 0; - new_area = 0; - } - - *any_change = 1; - dwarf_free_line_table_prefix(&prefix); - return (DW_DLV_OK); -} -#endif /* __sgi */ diff --git a/thirdparty/dwarf/dwarf_str_offsets.c b/thirdparty/dwarf/dwarf_str_offsets.c new file mode 100644 index 00000000..f6dbb52a --- /dev/null +++ b/thirdparty/dwarf/dwarf_str_offsets.c @@ -0,0 +1,369 @@ +/* + Copyright (C) 2018-2018 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. + Any license provided herein, whether implied or + otherwise, applies only to this software file. + Patent licenses, if any, provided herein do not + apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, + Boston MA 02110-1301, + USA. +*/ + +#include "config.h" +#include +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "dwarf_str_offsets.h" + +#define TRUE 1 +#define FALSE 0 + +#define STR_OFFSETS_MAGIC 0x2feed2 + +#define VALIDATE_SOT(xsot) \ + if (!xsot) { \ + _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULLARGUMENT); \ + return DW_DLV_ERROR; \ + } \ + if (!xsot->so_dbg) { \ + _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULL_DBG); \ + return DW_DLV_ERROR; \ + } \ + if (xsot->so_magic_value != STR_OFFSETS_MAGIC) { \ + _dwarf_error(xsot->so_dbg,error,DW_DLE_STR_OFFSETS_NO_MAGIC); \ + return DW_DLV_ERROR; \ + } + +#if 0 +static void +dump_bytes(char * msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + + printf("%s ",msg); + for (; cur < end; cur++) { + printf("%02x ", *cur); + } + printf("\n"); +} +#endif + +int +dwarf_open_str_offsets_table_access(Dwarf_Debug dbg, + Dwarf_Str_Offsets_Table * table_data, + Dwarf_Error * error) +{ + int res = 0; + Dwarf_Str_Offsets_Table local_table_data = 0; + Dwarf_Small *offsets_start_ptr = 0; + Dwarf_Unsigned sec_size = 0; + + if (!dbg) { + _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULL_DBG); \ + return DW_DLV_ERROR; \ + } + if (!table_data) { + _dwarf_error(dbg,error,DW_DLE_STR_OFFSETS_NULLARGUMENT); \ + return DW_DLV_ERROR; \ + } + /* Considered testing for *table_data being NULL, but + not doing such a test. */ + + res = _dwarf_load_section(dbg, &dbg->de_debug_str_offsets,error); + if (res != DW_DLV_OK) { + return res; + } + offsets_start_ptr = dbg->de_debug_str_offsets.dss_data; + if (!offsets_start_ptr) { + return DW_DLV_NO_ENTRY; + } + sec_size = dbg->de_debug_str_offsets.dss_size; + local_table_data = (Dwarf_Str_Offsets_Table)_dwarf_get_alloc(dbg, + DW_DLA_STR_OFFSETS,1); + if(!local_table_data) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + local_table_data->so_dbg = dbg; + local_table_data->so_magic_value = STR_OFFSETS_MAGIC; + local_table_data->so_section_start_ptr = offsets_start_ptr; + local_table_data->so_section_end_ptr = offsets_start_ptr +sec_size; + local_table_data->so_section_size = sec_size; + local_table_data->so_next_table_offset = 0; + local_table_data->so_wasted_section_bytes = 0; + /* get_alloc zeroed all the bits, no need to repeat that here. */ + *table_data = local_table_data; + return DW_DLV_OK; +} + +int +dwarf_close_str_offsets_table_access( + Dwarf_Str_Offsets_Table table_data, + Dwarf_Error * error) +{ + Dwarf_Debug dbg = 0; + + VALIDATE_SOT(table_data) + dbg = table_data->so_dbg; + table_data->so_magic_value = 0xdead; + dwarf_dealloc(dbg,table_data, DW_DLA_STR_OFFSETS); + return DW_DLV_OK; +} + + +int +dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table sot, + Dwarf_Unsigned index, + Dwarf_Unsigned *stroffset, + Dwarf_Error *error) +{ + Dwarf_Small *entryptr = 0; + Dwarf_Unsigned val = 0; + + VALIDATE_SOT(sot) + if (index >= sot->so_array_entry_count) { + _dwarf_error(sot->so_dbg,error, DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG); + return DW_DLV_ERROR; + } + entryptr = sot->so_array_ptr + (index * sot->so_array_entry_size); + READ_UNALIGNED_CK(sot->so_dbg, val, Dwarf_Unsigned, + entryptr, sot->so_array_entry_size,error,sot->so_end_cu_ptr); + *stroffset = val; + return DW_DLV_OK; +} + +/* We are assuming we can look for a str_offsets table + header on 32bit boundaries. Any non-zero value + suggests we are at a table. So we assume it is a table. + Later we'll check for validity. + This is just so that unused zeroed 32bit words, if any, + do not stop our processing. */ +static int +find_next_str_offsets_tab(Dwarf_Str_Offsets_Table sot, + Dwarf_Unsigned starting_offset, + Dwarf_Unsigned *table_offset_out, + Dwarf_Error *error) +{ + Dwarf_Small *word_ptra = 0; + Dwarf_Small *word_ptrb = 0; + Dwarf_Unsigned offset = starting_offset; + + word_ptra = word_ptrb = sot->so_section_start_ptr +offset; + for ( ; ; word_ptrb += DWARF_32BIT_SIZE) { + Dwarf_Unsigned one32bit = 0; + if (word_ptrb >= sot->so_section_end_ptr) { + sot->so_wasted_section_bytes += (word_ptrb - word_ptra); + return DW_DLV_NO_ENTRY; + } + READ_UNALIGNED_CK(sot->so_dbg, one32bit, Dwarf_Unsigned, + word_ptrb, DWARF_32BIT_SIZE, + error,sot->so_section_end_ptr); + if (one32bit) { + /* Found a value */ + break; + } + offset += DWARF_32BIT_SIZE; + } + sot->so_wasted_section_bytes += (word_ptrb - word_ptra); + *table_offset_out = offset; + return DW_DLV_OK; +} + +/* The minimum possible area .debug_str_offsets header . */ +#define MIN_HEADER_LENGTH 8 + +/* New April 2018. + Beginning at starting_offset zero, + returns data about the first table found. + The value *next_table_offset is the value + of the next table (if any), one byte past + the end of the table whose data is returned.. + Returns DW_DLV_NO_ENTRY if the starting offset + is past the end of valid data. + + There is no guarantee that there are no non-0 nonsense + bytes in the section outside of useful tables, + so this can fail and return nonsense or + DW_DLV_ERROR if such garbage exists. +*/ + + +int +dwarf_next_str_offsets_table(Dwarf_Str_Offsets_Table sot, + Dwarf_Unsigned *unit_length_out, + Dwarf_Unsigned *unit_length_offset_out, + Dwarf_Unsigned *table_start_offset_out, + Dwarf_Half *entry_size_out, + Dwarf_Half *version_out, + Dwarf_Half *padding_out, + Dwarf_Unsigned *table_value_count_out, + Dwarf_Error * error) +{ + + Dwarf_Small *table_start_ptr = 0; + Dwarf_Small *table_end_ptr = 0; + Dwarf_Unsigned table_offset = 0; + Dwarf_Unsigned local_length_size = 0; + UNUSEDARG Dwarf_Unsigned local_extension_size = 0; + Dwarf_Unsigned length = 0; + Dwarf_Half version = 0; + Dwarf_Half padding = 0; + int res = 0; + + VALIDATE_SOT(sot) + + res = find_next_str_offsets_tab(sot, + sot->so_next_table_offset, + &table_offset,error); + if (res != DW_DLV_OK) { + /* As a special case, if unused zero bytess at the end, + count as wasted space. */ + if (res == DW_DLV_NO_ENTRY) { + if (table_offset > sot->so_next_table_offset) { + sot->so_wasted_section_bytes += + (table_offset - sot->so_next_table_offset); + } + } + return res; + } + if (table_offset > sot->so_next_table_offset) { + sot->so_wasted_section_bytes += + (table_offset - sot->so_next_table_offset); + } + table_start_ptr = sot->so_section_start_ptr + table_offset; + sot->so_header_ptr = table_start_ptr; + if (table_start_ptr >= sot->so_section_end_ptr) { + if (table_start_ptr == sot->so_section_end_ptr) { + /* At end of section. Done. */ + return DW_DLV_NO_ENTRY; + } + } + + if ((table_start_ptr + MIN_HEADER_LENGTH) > sot->so_section_end_ptr) { + /* We have some nonsense non-zero extra bytes! + Should we generate error? Or ignore? */ + _dwarf_error(sot->so_dbg,error, + DW_DLE_STR_OFFSETS_EXTRA_BYTES); + return DW_DLV_ERROR; + } + READ_AREA_LENGTH_CK(sot->so_dbg,length,Dwarf_Unsigned, + table_start_ptr,local_length_size, + local_extension_size,error, + sot->so_section_size,sot->so_section_end_ptr); + + /* The 'length' part of any header is + local_extension_size + local_length_size. + Standard DWARF2 sums to 4. + Standard DWARF3,4,5 sums to 4 or 12. + Nonstandard SGI IRIX 64bit dwarf sums to 8 (SGI IRIX + was all DWARF2 and could not have a .debug_str_offsets + section). + The header includes 2 bytes of version and two bytes + of padding. */ + + /* table_start_ptr was incremented past the length data. */ + table_end_ptr = table_start_ptr + length; + READ_UNALIGNED_CK(sot->so_dbg, version, Dwarf_Half, + table_start_ptr, DWARF_HALF_SIZE, + error,sot->so_section_end_ptr); + table_start_ptr += DWARF_HALF_SIZE; + READ_UNALIGNED_CK(sot->so_dbg, padding, Dwarf_Half, + table_start_ptr, DWARF_HALF_SIZE, + error,sot->so_section_end_ptr); + table_start_ptr += DWARF_HALF_SIZE; + + if (version != DW_STR_OFFSETS_VERSION5) { + _dwarf_error(sot->so_dbg,error, + DW_DLE_STR_OFFSETS_VERSION_WRONG); + return DW_DLV_ERROR; + } + + /* So now table_start_ptr points to a table of local_length_size + entries. + Each entry in this table is local_length_size bytes + long: 4 or 8. */ + { + Dwarf_Unsigned entrycount = 0; + Dwarf_Unsigned entrybytes = 0; + + entrybytes = table_end_ptr - table_start_ptr; + if (entrybytes % local_length_size) { + _dwarf_error(sot->so_dbg,error, + DW_DLE_STR_OFFSETS_ARRAY_SIZE); + return DW_DLV_ERROR; + } + entrycount = entrybytes/local_length_size; + sot->so_next_table_offset = table_end_ptr - + sot->so_section_start_ptr; + + sot->so_end_cu_ptr = table_end_ptr; + sot->so_array_ptr = table_start_ptr; + sot->so_table_start_offset = table_offset; + sot->so_array_start_offset = table_start_ptr - + sot->so_section_start_ptr; + sot->so_array_entry_count = entrycount; + sot->so_array_entry_size = local_length_size; + sot->so_table_count += 1; + + /* The data length in bytes following the unit_length field + of the header. */ + *unit_length_out = length; + + /* Where the unit_length field starts in the section. */ + *unit_length_offset_out = sot->so_table_start_offset; + + /* Where the table of offsets starts in the section. */ + *table_start_offset_out = sot->so_array_start_offset; + + /* Entrysize: 4 or 8 */ + *entry_size_out = local_length_size; + + /* Version is 5. */ + *version_out = version; + + /* This is supposed to be zero. */ + *padding_out = padding; + + /* How many entry_size entries are in the array. */ + *table_value_count_out = entrycount; + return DW_DLV_OK; + } +} + +/* Meant to be called after all tables accessed using + dwarf_next_str_offsets_table(). */ +int +dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table table_data, + Dwarf_Unsigned * wasted_byte_count, + Dwarf_Unsigned * table_count, + Dwarf_Error * error) +{ + VALIDATE_SOT(table_data) + if(wasted_byte_count) { + *wasted_byte_count = table_data->so_wasted_section_bytes; + } + if(table_count) { + *table_count = table_data->so_table_count; + } + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/dwarf_str_offsets.h b/thirdparty/dwarf/dwarf_str_offsets.h new file mode 100644 index 00000000..45f308b0 --- /dev/null +++ b/thirdparty/dwarf/dwarf_str_offsets.h @@ -0,0 +1,63 @@ +#ifndef DWARF_STR_OFFSETS_H +#define DWARF_STR_OFFSETS_H +/* + Copyright (C) 2018-2018 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. + Any license provided herein, whether implied or + otherwise, applies only to this software file. + Patent licenses, if any, provided herein do not + apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, + Boston MA 02110-1301, + USA. + +*/ + + +struct Dwarf_Str_Offsets_Table_s { + /* pointers are to dwarf-memory valid till Dwarf_Debug + is closed.. None are to be deallocated. */ + Dwarf_Unsigned so_magic_value; + Dwarf_Debug so_dbg; + + /* Section data. */ + Dwarf_Small *so_section_start_ptr; + Dwarf_Small *so_section_end_ptr; + Dwarf_Unsigned so_section_size; + /* Overall data about wasted space in the section. */ + Dwarf_Unsigned so_wasted_section_bytes; + /* The number of tables processed in the section. */ + Dwarf_Unsigned so_table_count; + + /* Used to iterate through the section getting + to each table */ + Dwarf_Unsigned so_next_table_offset; + + /* Per table (ie, a table is a + header and array of offsets) inside the section. */ + Dwarf_Small *so_header_ptr; + Dwarf_Small *so_end_cu_ptr; + Dwarf_Small *so_array_ptr; + Dwarf_Unsigned so_table_start_offset; + Dwarf_Unsigned so_array_start_offset; + Dwarf_Unsigned so_array_entry_count; + Dwarf_Half so_array_entry_size; + +}; +#endif /* DWARF_STR_OFFSETS_H */ diff --git a/thirdparty/dwarf/dwarf_string.c b/thirdparty/dwarf/dwarf_string.c index 2231eb2b..06c8224a 100644 --- a/thirdparty/dwarf/dwarf_string.c +++ b/thirdparty/dwarf/dwarf_string.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2009-2011 David Anderson. All Rights Reserved. + Portions Copyright (C) 2009-2018 David Anderson. All Rights Reserved. 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 @@ -27,6 +26,8 @@ #include "config.h" #include "dwarf_incl.h" +#include "dwarf_error.h" +#include "dwarf_util.h" int dwarf_get_str(Dwarf_Debug dbg, @@ -70,7 +71,8 @@ dwarf_get_str(Dwarf_Debug dbg, begin = (char *)secptr + offset; end = (char *)secptr + dbg->de_debug_str.dss_size; - res = _dwarf_check_string_valid(dbg,secptr,begin,end,error); + res = _dwarf_check_string_valid(dbg,secptr,begin,end, + DW_DLE_DEBUG_STR_OFFSET_BAD,error); if (res != DW_DLV_OK) { return res; } @@ -79,4 +81,3 @@ dwarf_get_str(Dwarf_Debug dbg, *returned_str_len = strlen(*string); return DW_DLV_OK; } - diff --git a/thirdparty/dwarf/dwarf_test_errmsg_list.c b/thirdparty/dwarf/dwarf_test_errmsg_list.c new file mode 100644 index 00000000..6a8cee80 --- /dev/null +++ b/thirdparty/dwarf/dwarf_test_errmsg_list.c @@ -0,0 +1,285 @@ +/* + Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2008-2018 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + +#include "config.h" +#include "dwarf_incl.h" +#include +#ifdef HAVE_STDLIB_H +#include /* For exit(), strtoul() declaration etc. */ +#endif + +#include "dwarf_errmsg_list.h" + + +#define FALSE 0 +#define TRUE 1 +/* This is just to help localize the error. */ +static void +printone(int i) +{ + int arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); + if ( i >= arraysize) { + printf("%d is outside the array! Missing something!\n",i); + } else { + printf("%d is: %s\n",i,_dwarf_errmsgs[i]); + } +} + +/* Arbitrary. A much smaller max length value would work. */ +#define MAX_NUM_LENGTH 12 + +/* return TRUE on error */ +static int +check_errnum_mismatches(unsigned i) +{ + unsigned nextstop = 0; + const char *sp = _dwarf_errmsgs[i]; + const char *cp = sp; + unsigned innit = FALSE; + unsigned prevchar = 0; + unsigned value = 0; + + for( ; *cp; cp++) { + unsigned c = 0; + c = 0xff & *cp; + if ( c >= '0' && c <= '9' && !innit + && prevchar != '(') { + /* Skip. number part of macro name. */ + prevchar = c; + continue; + } + if ( c >= '0' && c <= '9') { + value = value * 10; + value += (c - '0'); + nextstop++; + if (nextstop > MAX_NUM_LENGTH) { + break; + } + innit = TRUE; + } else { + if (innit) { + break; + } + prevchar= c; + } + } + if (innit) { + if (i != value) { + return TRUE; + } + return FALSE; + } + /* There is no number to check. Ignore it. */ + printf("mismatch value %d has no errnum to check %s\n",i,_dwarf_errmsgs[i]); + return TRUE; +} + +/* We don't allow arbitrary DW_DLE line length. */ +#define MAXDEFINELINE 200 + +static int +splmatches(char *base, unsigned baselen,char *test) +{ + if (baselen != strlen(test) ) { + return FALSE; + } + for ( ; *test; ++test,++base) { + if (*test != *base) { + return FALSE; + } + } + return TRUE; +} + +static void +check_dle_list(const char *path) +{ + /* The format should be + #definenamenumberoptional-c-comment + and we are intentionally quite rigid about it all except + that the number of spaces before any comment is allowed. */ + char buffer[MAXDEFINELINE]; + unsigned linenum = 0; + unsigned long prevdefval = 0; + unsigned foundlast = 0; + unsigned foundlouser = 0; + FILE*fin = 0; + + fin = fopen(path, "r"); + if(!fin) { + printf("Unable to open define list to read %s\n",path); + exit(1); + } + for(;;++linenum) { + char *line = 0; + unsigned linelen = 0; + char * curdefname = 0; + char * pastname = 0; + unsigned curdefname_len = 0; + char *numstart = 0; + char * endptr = 0; + unsigned long v = 0; + + line = fgets(buffer,MAXDEFINELINE,fin); + if(!line) { + break; + } + linelen = strlen(line); + if (linelen >= (unsigned)(MAXDEFINELINE-1)) { + printf("define line %u is too long!\n",linenum); + exit(1); + } + if(strncmp(line,"#define DW_DLE_",15)) { + printf("define line %u has wrong leading chars!\n",linenum); + exit(1); + } + curdefname = line+8; + /* ASSERT: line ends with NUL byte. */ + for( ; ; curdefname_len++) { + if (foundlouser) { + printf("define line %u has stuff after DW_DLE_LO_USER!\n", + linenum); + exit(1); + } + pastname = curdefname +curdefname_len; + if (!*pastname) { + /* At end of line. Missing value. */ + printf("define line %u of %s: has no number value!\n", + linenum,path); + exit(1); + } + if (*pastname == ' ') { + /* Ok. Now look for value. */ + numstart = pastname + 1; + break; + } + } + /* strtoul skips leading whitespace. */ + v = strtoul(numstart,&endptr,0); + /* This test is a bit odd. But is valid till + we decide it is inappropriate. */ + if (v > DW_DLE_LO_USER) { + printf("define line %u: number value unreasonable. %lu\n", + linenum,v); + exit(1); + } + if (v == 0 && endptr == numstart) { + printf("define line %u of %s: number value missing.\n", + linenum,path); + printf("Leaving a space as in #define A B 3" + " in libdwarf.h.in will cause this.\n"); + exit(1); + } + if (*endptr != ' ' && *endptr != '\n') { + printf("define line %u: number value terminates oddly\n", + linenum); + exit(1); + } + if (splmatches(curdefname,curdefname_len,"DW_DLE_LAST")) { + if (foundlast) { + printf("duplicated DW_DLE_LAST! line %u\n",linenum); + exit(1); + } + foundlast = 1; + if (v != prevdefval) { + printf("Invalid: Last value mismatch! %lu vs %lu\n", + v,prevdefval); + } + } else if (splmatches(curdefname,curdefname_len,"DW_DLE_LO_USER")) { + if (!foundlast) { + printf("error:expected DW_DLE_LO_USER after LAST! line %u\n", + linenum); + exit(1); + } + if (foundlouser) { + printf("Error:duplicated DW_DLE_LO_USER! line %u\n", + linenum); + exit(1); + } + foundlouser = 1; + continue; + } else { + if (linenum > 0) { + if (v != prevdefval+1) { + printf("Invalid: Missing value! %lu vs %lu\n", + prevdefval,v); + exit(1); + } + } + prevdefval = v; + } + /* Ignoring rest of line for now. */ + } + fclose(fin); +} + +int +main(int argc, char **argv) +{ + unsigned arraysize = sizeof(_dwarf_errmsgs) / sizeof(char *); + unsigned i = 0; + const char *path = 0; + + if (argc != 3) { + printf("Expected -f of DW_DLE lines from libdwarf.h"); + exit(1); + } + if (strcmp(argv[1],"-f")) { + printf("Expected -f"); + exit(1); + } + path = argv[2]; + check_dle_list(path); + + + if (arraysize != (DW_DLE_LAST + 1)) { + printf("Missing or extra entry in dwarf error strings array" + " %u expected DW_DLE_LAST+1 %d\n",arraysize, DW_DLE_LAST+1); + printone(1); + printone(100); + printone(200); + printone(250); + printone(260); + printone(262); + printone(263); + printone(264); + printone(265); + printone(273); + printone(274); + printone(275); + printone(300); + printone(328); + exit(1); + } + for ( i = 0; i <= DW_DLE_LAST; ++i) { + if(check_errnum_mismatches(i)) { + printf("mismatch value %d is: %s\n",i,_dwarf_errmsgs[i]); + exit(1); + } + } + /* OK. */ + exit(0); +} diff --git a/thirdparty/dwarf/dwarf_tied.c b/thirdparty/dwarf/dwarf_tied.c index f9df8117..3eaa058e 100644 --- a/thirdparty/dwarf/dwarf_tied.c +++ b/thirdparty/dwarf/dwarf_tied.c @@ -2,56 +2,49 @@ Copyright (C) 2015-2015 David Anderson. All Rights Reserved. - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "dwarf_incl.h" -#include "dwarf_tsearch.h" +#ifdef HAVE_STDLIB_H #include /* for free(). */ +#endif /* HAVE_STDLIB_H */ #include /* For debugging. */ +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ +#include "dwarf_tsearch.h" +#include "dwarf_tied_decls.h" #define TRUE 1 #define FALSE 0 -#define HASHSEARCH - -#ifdef HASHSEARCH -/* Only needed for hash based search in a tsearch style. */ -#define INITTREE(x,y) x = dwarf_initialize_search_hash(&(x),(y),0) -#else -#define INITTREE(x,y) -#endif /* HASHSEARCH */ - - - -/* Contexts are in a list in a dbg and - do not move once established. - So saving one is ok. as long as the dbg - exists. */ -struct Dwarf_Tied_Entry_s { - Dwarf_Sig8 dt_key; - Dwarf_CU_Context dt_context; -}; void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) @@ -67,8 +60,8 @@ _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) printf(" line %d\n",lineno); } -static void * -tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val) +void * +_dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val) { struct Dwarf_Tied_Entry_s *e = 0; e = calloc(1,sizeof(struct Dwarf_Tied_Entry_s)); @@ -84,8 +77,8 @@ tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val) A hash needed because we are using a hash search here. Would not be needed for the other tree searchs like balanced trees.. */ -static DW_TSHASHTYPE -tied_data_hashfunc(const void *keyp) +DW_TSHASHTYPE +_dwarf_tied_data_hashfunc(const void *keyp) { const struct Dwarf_Tied_Entry_s * enp = keyp; DW_TSHASHTYPE hashv = 0; @@ -94,8 +87,8 @@ tied_data_hashfunc(const void *keyp) return hashv; } -static int -tied_compare_function(const void *l, const void *r) +int +_dwarf_tied_compare_function(const void *l, const void *r) { const struct Dwarf_Tied_Entry_s * lp = l; const struct Dwarf_Tied_Entry_s * rp = r; @@ -123,7 +116,6 @@ _dwarf_tied_destroy_free_node(void*nodep) return; } -#ifndef TESTING /* This presumes only we are reading the debug_info CUs from tieddbg. That is a reasonable @@ -192,7 +184,7 @@ _dwarf_loop_reading_debug_info_for_cu( Dwarf_Sig8 consign = latestcontext->cc_type_signature; void *entry = - tied_make_entry(&consign,latestcontext); + _dwarf_tied_make_entry(&consign,latestcontext); if (!entry) { return DW_DLV_NO_ENTRY; @@ -200,18 +192,18 @@ _dwarf_loop_reading_debug_info_for_cu( /* Insert this signature and context. */ retval = dwarf_tsearch(entry, &tieddbg->de_tied_data.td_tied_search, - tied_compare_function); + _dwarf_tied_compare_function); if (!retval) { /* FAILED might be out of memory.*/ return DW_DLV_NO_ENTRY; } -#if 0 +#if 0 /* FIXME: do this? Not? */ /* This could be a compiler error. But let us not decide? FIXME */ if (!latestcontext->cc_addr_base_present) { } #endif - if (!tied_compare_function(&sig,&consign) ) { + if (!_dwarf_tied_compare_function(&sig,&consign) ) { /* Identical. We found the matching CU. */ return DW_DLV_OK; } @@ -239,7 +231,7 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg, if (!tied->td_tied_search) { dwarf_initialize_search_hash(&tied->td_tied_search, - tied_data_hashfunc,0); + _dwarf_tied_data_hashfunc,0); if (!tied->td_tied_search) { return DW_DLV_NO_ENTRY; } @@ -248,7 +240,7 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg, entry.dt_context = 0; entry2 = dwarf_tfind(&entry, &tied->td_tied_search, - tied_compare_function); + _dwarf_tied_compare_function); if (entry2) { struct Dwarf_Tied_Entry_s *e2 = *(struct Dwarf_Tied_Entry_s **)entry2; @@ -267,7 +259,7 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg, entry2 = dwarf_tfind(&entry, &tied->td_tied_search, - tied_compare_function); + _dwarf_tied_compare_function); if (entry2) { struct Dwarf_Tied_Entry_s *e2 = *(struct Dwarf_Tied_Entry_s **)entry2; @@ -276,155 +268,3 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg, } return DW_DLV_NO_ENTRY; } -#endif /* ndef TESTING */ - - -#ifdef TESTING - -struct test_data_s { - const char action; - unsigned long val; -} testdata[] = { -{'a', 0x33c8}, -{'a', 0x34d8}, -{'a', 0x35c8}, -{'a', 0x3640}, -{'a', 0x3820}, -{'a', 0x38d0}, -{'a', 0x3958}, -{'a', 0x39e8}, -{'a', 0x3a78}, -{'a', 0x3b08}, -{'a', 0x3b98}, -{'a', 0x3c28}, -{'a', 0x3cb8}, -{'d', 0x3c28}, -{'a', 0x3d48}, -{'d', 0x3cb8}, -{'a', 0x3dd8}, -{'d', 0x3d48}, -{'a', 0x3e68}, -{'d', 0x3dd8}, -{'a', 0x3ef8}, -{'a', 0x3f88}, -{'d', 0x3e68}, -{'a', 0x4018}, -{'d', 0x3ef8}, -{0,0} -}; - - -static struct Dwarf_Tied_Entry_s * -makeentry(unsigned long instance, unsigned ct) -{ - Dwarf_Sig8 s8; - Dwarf_CU_Context context = 0; - struct Dwarf_Tied_Entry_s * entry = 0; - - memset(&s8,0,sizeof(s8)); - /* Silly, but just a test...*/ - memcpy(&s8,&instance,sizeof(instance)); - context = (Dwarf_CU_Context)instance; - - entry = (struct Dwarf_Tied_Entry_s *) - tied_make_entry(&s8,context); - if (!entry) { - printf("Out of memory in test! %u\n",ct); - exit(1); - } - return entry; -} - -static int -insone(void**tree,unsigned long instance, unsigned ct) -{ - struct Dwarf_Tied_Entry_s * entry = 0; - void *retval = 0; - - entry = makeentry(instance, ct); - retval = dwarf_tsearch(entry,tree, tied_compare_function); - - if(retval == 0) { - printf("FAIL ENOMEM in search on rec %u adr 0x%lu," - " error in insone\n", - ct,(unsigned long)instance); - exit(1); - } else { - struct Dwarf_Tied_Entry_s *re = 0; - re = *(struct Dwarf_Tied_Entry_s **)retval; - if(re != entry) { - /* Found existing, error. */ - printf("insertone rec %u addr 0x%lu found record" - " preexisting, error\n", - ct,(unsigned long)instance); - _dwarf_tied_destroy_free_node(entry); - exit(1); - } else { - /* inserted new entry, make sure present. */ - struct Dwarf_Tied_Entry_s * entry2 = 0; - entry2 = makeentry(instance,ct); - retval = dwarf_tfind(entry2,tree, - tied_compare_function); - _dwarf_tied_destroy_free_node(entry2); - if(!retval) { - printf("insertonebypointer record %d addr 0x%lu " - "failed to add as desired," - " error\n", - ct,(unsigned long)instance); - exit(1); - } - } - } - return 0; -} - -static int -delone(void**tree,unsigned long instance, unsigned ct) -{ - struct Dwarf_Tied_Entry_s * entry = 0; - void *r = 0; - - - entry = makeentry(instance, ct); - r = dwarf_tfind(entry,(void *const*)tree, - tied_compare_function); - if (r) { - struct Dwarf_Tied_Entry_s *re3 = - *(struct Dwarf_Tied_Entry_s **)r; - re3 = *(struct Dwarf_Tied_Entry_s **)r; - dwarf_tdelete(entry,tree,tied_compare_function); - _dwarf_tied_destroy_free_node(entry); - _dwarf_tied_destroy_free_node(re3); - } else { - printf("delone could not find rec %u ! error! addr" - " 0x%lx\n", - ct,(unsigned long)instance); - exit(1) ; - } - return 0; - -} - -int main() -{ - void *tied_data = 0; - unsigned u = 0; - - INITTREE(tied_data,tied_data_hashfunc); - for ( ; testdata[u].action; ++u) { - char action = testdata[u].action; - unsigned long v = testdata[u].val; - if (action == 'a') { - insone(&tied_data,v,u); - } else if (action == 'd') { - delone(&tied_data,v,u); - } else { - printf("FAIL testtied on action %u, " - "not a or d\n",action); - exit(1); - } - } - printf("PASS tsearch works for Dwarf_Tied_Entry_s.\n"); - return 0; -} -#endif diff --git a/thirdparty/dwarf/dwarf_tied_decls.h b/thirdparty/dwarf/dwarf_tied_decls.h new file mode 100644 index 00000000..4850c202 --- /dev/null +++ b/thirdparty/dwarf/dwarf_tied_decls.h @@ -0,0 +1,50 @@ +/* + + Copyright (C) 2015-2015 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + + + +#define HASHSEARCH + +#ifdef HASHSEARCH +/* Only needed for hash based search in a tsearch style. */ +#define INITTREE(x,y) x = dwarf_initialize_search_hash(&(x),(y),0) +#else +#define INITTREE(x,y) +#endif /* HASHSEARCH */ + + +/* Contexts are in a list in a dbg and + do not move once established. + So saving one is ok. as long as the dbg + exists. */ +struct Dwarf_Tied_Entry_s { + Dwarf_Sig8 dt_key; + Dwarf_CU_Context dt_context; +}; + +int _dwarf_tied_compare_function(const void *l, const void *r); +void * _dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val); +DW_TSHASHTYPE _dwarf_tied_data_hashfunc(const void *keyp); diff --git a/thirdparty/dwarf/dwarf_tied_test.c b/thirdparty/dwarf/dwarf_tied_test.c new file mode 100644 index 00000000..6177f8aa --- /dev/null +++ b/thirdparty/dwarf/dwarf_tied_test.c @@ -0,0 +1,226 @@ +/* + + Copyright (C) 2015-2015 David Anderson. All Rights Reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. + +*/ + +#include "config.h" +#include "dwarf_incl.h" +#ifdef HAVE_STDLIB_H +#include /* for free(). */ +#endif /* HAVE_STDLIB_H */ +#include /* For debugging. */ +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ +#include "dwarf_tsearch.h" +#include "dwarf_tied_decls.h" + +#define TRUE 1 +#define FALSE 0 +#define TRUE 1 +#define FALSE 0 + +struct test_data_s { + const char action; + unsigned long val; +} testdata[] = { +{'a', 0x33c8}, +{'a', 0x34d8}, +{'a', 0x35c8}, +{'a', 0x3640}, +{'a', 0x3820}, +{'a', 0x38d0}, +{'a', 0x3958}, +{'a', 0x39e8}, +{'a', 0x3a78}, +{'a', 0x3b08}, +{'a', 0x3b98}, +{'a', 0x3c28}, +{'a', 0x3cb8}, +{'d', 0x3c28}, +{'a', 0x3d48}, +{'d', 0x3cb8}, +{'a', 0x3dd8}, +{'d', 0x3d48}, +{'a', 0x3e68}, +{'d', 0x3dd8}, +{'a', 0x3ef8}, +{'a', 0x3f88}, +{'d', 0x3e68}, +{'a', 0x4018}, +{'d', 0x3ef8}, +{0,0} +}; + +/* We don't test this here, referenced from dwarf_tied.c. */ +int +_dwarf_loop_reading_debug_info_for_cu( + UNUSEDARG Dwarf_Debug tieddbg, + UNUSEDARG Dwarf_Sig8 sig, + UNUSEDARG Dwarf_Error *error) +{ + return DW_DLV_NO_ENTRY; +} +/* We don't test this here, referenced from dwarf_tied.c. */ +int +_dwarf_next_cu_header_internal( + UNUSEDARG Dwarf_Debug dbg, + UNUSEDARG Dwarf_Bool is_info, + UNUSEDARG Dwarf_Unsigned * cu_header_length, + UNUSEDARG Dwarf_Half * version_stamp, + UNUSEDARG Dwarf_Unsigned * abbrev_offset, + UNUSEDARG Dwarf_Half * address_size, + UNUSEDARG Dwarf_Half * offset_size, + UNUSEDARG Dwarf_Half * extension_size, + UNUSEDARG Dwarf_Sig8 * signature, + UNUSEDARG Dwarf_Bool * has_signature, + UNUSEDARG Dwarf_Unsigned *typeoffset, + UNUSEDARG Dwarf_Unsigned * next_cu_offset, + UNUSEDARG Dwarf_Half * header_cu_type, + UNUSEDARG Dwarf_Error * error) +{ + return DW_DLV_NO_ENTRY; +} + + + +static struct Dwarf_Tied_Entry_s * +makeentry(unsigned long instance, unsigned ct) +{ + Dwarf_Sig8 s8; + Dwarf_CU_Context context = 0; + struct Dwarf_Tied_Entry_s * entry = 0; + + memset(&s8,0,sizeof(s8)); + /* Silly, but just a test...*/ + memcpy(&s8,&instance,sizeof(instance)); + context = (Dwarf_CU_Context)instance; + + entry = (struct Dwarf_Tied_Entry_s *) + _dwarf_tied_make_entry(&s8,context); + if (!entry) { + printf("Out of memory in test! %u\n",ct); + exit(1); + } + return entry; +} + +static int +insone(void**tree,unsigned long instance, unsigned ct) +{ + struct Dwarf_Tied_Entry_s * entry = 0; + void *retval = 0; + + entry = makeentry(instance, ct); + retval = dwarf_tsearch(entry,tree, _dwarf_tied_compare_function); + + if(retval == 0) { + printf("FAIL ENOMEM in search on rec %u adr 0x%lu," + " error in insone\n", + ct,(unsigned long)instance); + exit(1); + } else { + struct Dwarf_Tied_Entry_s *re = 0; + re = *(struct Dwarf_Tied_Entry_s **)retval; + if(re != entry) { + /* Found existing, error. */ + printf("insertone rec %u addr 0x%lu found record" + " preexisting, error\n", + ct,(unsigned long)instance); + _dwarf_tied_destroy_free_node(entry); + exit(1); + } else { + /* inserted new entry, make sure present. */ + struct Dwarf_Tied_Entry_s * entry2 = 0; + entry2 = makeentry(instance,ct); + retval = dwarf_tfind(entry2,tree, + _dwarf_tied_compare_function); + _dwarf_tied_destroy_free_node(entry2); + if(!retval) { + printf("insertonebypointer record %d addr 0x%lu " + "failed to add as desired," + " error\n", + ct,(unsigned long)instance); + exit(1); + } + } + } + return 0; +} + +static int +delone(void**tree,unsigned long instance, unsigned ct) +{ + struct Dwarf_Tied_Entry_s * entry = 0; + void *r = 0; + + + entry = makeentry(instance, ct); + r = dwarf_tfind(entry,(void *const*)tree, + _dwarf_tied_compare_function); + if (r) { + struct Dwarf_Tied_Entry_s *re3 = + *(struct Dwarf_Tied_Entry_s **)r; + re3 = *(struct Dwarf_Tied_Entry_s **)r; + dwarf_tdelete(entry,tree,_dwarf_tied_compare_function); + _dwarf_tied_destroy_free_node(entry); + _dwarf_tied_destroy_free_node(re3); + } else { + printf("delone could not find rec %u ! error! addr" + " 0x%lx\n", + ct,(unsigned long)instance); + exit(1) ; + } + return 0; + +} + +int main() +{ + void *tied_data = 0; + unsigned u = 0; + + INITTREE(tied_data,_dwarf_tied_data_hashfunc); + for ( ; testdata[u].action; ++u) { + char action = testdata[u].action; + unsigned long v = testdata[u].val; + if (action == 'a') { + insone(&tied_data,v,u); + } else if (action == 'd') { + delone(&tied_data,v,u); + } else { + printf("FAIL testtied on action %u, " + "not a or d\n",action); + exit(1); + } + } + printf("PASS tsearch works for Dwarf_Tied_Entry_s.\n"); + return 0; +} diff --git a/thirdparty/dwarf/dwarf_tsearch.h b/thirdparty/dwarf/dwarf_tsearch.h index b0d7bfab..48a17099 100644 --- a/thirdparty/dwarf/dwarf_tsearch.h +++ b/thirdparty/dwarf/dwarf_tsearch.h @@ -1,6 +1,6 @@ -#ifndef DWARF_TSEARCH -#define DWARF_TSEARCH -/* Copyright (c) 2013, David Anderson +#ifndef DWARF_TSEARCH_H +#define DWARF_TSEARCH_H +/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with @@ -38,7 +38,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. of any version of tsearch. Only uses of tsearch were examined, not tsearch source code. - See http://reality.sgiweb.org/davea/tsearch.html + See https://www.prevanders.net/tsearch.html + and https://www.prevanders.net/dwarf.html#tsearch for information about tsearch. We are matching the standard functional @@ -48,10 +49,10 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* The hashfunc return is now easily changed with - cc -Duintptr_t or something. */ +/* configure/cmake ensure uintptr_t defined, but if not, + possibly "-Duintptr_t=unsigned long" might help */ #ifndef DW_TSHASHTYPE -#define DW_TSHASHTYPE unsigned long +#define DW_TSHASHTYPE uintptr_t #endif /* The DW_VISIT values passed back to you through @@ -109,7 +110,6 @@ void dwarf_twalk(const void * /*root*/, void dwarf_tdestroy(void * /*root*/, void (* /*free_node*/)(void * /*nodep*/)); - /* Prints a simple tree representation to stdout. For debugging. */ void dwarf_tdump(const void*root, @@ -121,7 +121,4 @@ void dwarf_tdump(const void*root, void * dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE (*hashfunc)(const void *key), unsigned long size_estimate); -#endif /* DWARF_TSEARCH */ - - - +#endif /* DWARF_TSEARCH_H */ diff --git a/thirdparty/dwarf/dwarf_tsearchhash.c b/thirdparty/dwarf/dwarf_tsearchhash.c index c503d45a..6a2e8979 100644 --- a/thirdparty/dwarf/dwarf_tsearchhash.c +++ b/thirdparty/dwarf/dwarf_tsearchhash.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, David Anderson +/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with @@ -59,16 +59,33 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "config.h" -#include "dwarf_incl.h" +#ifdef HAVE_UNUSED_ATTRIBUTE +#define UNUSEDARG __attribute__ ((unused)) +#else +#define UNUSEDARG +#endif #include "stdlib.h" /* for free() etc */ #include /* for printf() */ +#ifdef HAVE_STDINT_H +#include /* for uintptr_t */ +#endif /* HAVE_STDINT_H */ +/* This must match the types and print options + found in libdwarf.h. */ +#define Dwarf_Unsigned unsigned long long +#if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) +#define DW_PR_DUx "I64x" +#define DW_PR_DUu "I64u" +#else +#define DW_PR_DUx "llx" +#define DW_PR_DUu "llu" +#endif /* DW_PR defines */ #include "dwarf_tsearch.h" /* A table of primes used to size and resize the hash table. From public sources of prime numbers, arbitrarily chosen to approximately double in size at each step. */ -static unsigned long long primes[] = +static unsigned long primes[] = { #if 0 /* for testing only */ 5,11, 17,23, 31, 47, 53, @@ -170,7 +187,7 @@ dwarf_initialize_search_hash( void **treeptr, DW_TSHASHTYPE(*hashfunc)(const void *key), unsigned long size_estimate) { - unsigned long prime_to_use =primes[0]; + unsigned long prime_to_use = primes[0]; unsigned entry_index = 0; unsigned k = 0; struct hs_base *base = 0; @@ -200,6 +217,7 @@ dwarf_initialize_search_hash( void **treeptr, base->allowed_fill_ = calculate_allowed_fill(allowed_fill_percent, prime_to_use); if( base->allowed_fill_< (base->tablesize_/2)) { + free(base); /* Oops. We are in trouble. Coding mistake here. */ return NULL; } @@ -218,6 +236,8 @@ dwarf_initialize_search_hash( void **treeptr, } +/* We don't really care whether hashpos or chainpos + are 32 or 64 bits. 32 suffices. */ static void print_entry(struct ts_entry *t,const char *descr, char *(* keyprint)(const void *), unsigned long hashpos, @@ -229,10 +249,12 @@ static void print_entry(struct ts_entry *t,const char *descr, } v = keyprint(t->keyptr); printf( - "[%4lu.%02lu] 0x%08lx %s\n", + "[%4lu.%02lu] 0x%08" DW_PR_DUx + " %s\n", hashpos,chainpos, - (unsigned long)t, - (unsigned long)t->keyptr, + (Dwarf_Unsigned)(uintptr_t)t, + (Dwarf_Unsigned)(uintptr_t)t->keyptr, v, descr); } @@ -249,11 +271,14 @@ dumptree_inner(const struct hs_base *h, unsigned long hashused = 0; unsigned long maxchainlength = 0; unsigned long chainsgt1 = 0; - printf("dumptree head ptr : 0x%08lx size %lu entries %lu allowed %lu %s\n", - (unsigned long)h, - (unsigned long)h->tablesize_, - (unsigned long)h->record_count_, - (unsigned long)h->allowed_fill_, + printf("dumptree head ptr : 0x%08" DW_PR_DUx + " size %" DW_PR_DUu + " entries %" DW_PR_DUu + " allowed %" DW_PR_DUu " %s\n", + (Dwarf_Unsigned)(uintptr_t)h, + (Dwarf_Unsigned)h->tablesize_, + (Dwarf_Unsigned)h->record_count_, + (Dwarf_Unsigned)h->allowed_fill_, descr); for( ; ix < tsize; ix++,p++) { unsigned long chainlength = 0; @@ -592,7 +617,7 @@ static void dwarf_twalk_inner(const struct hs_base *h, struct ts_entry *p, void (*action)(const void *nodep, const DW_VISIT which, - UNUSEDARG const int depth), + UNUSEDARG const int depth), UNUSEDARG unsigned level) { unsigned long ix = 0; @@ -611,7 +636,7 @@ dwarf_twalk_inner(const struct hs_base *h, void dwarf_twalk(const void *rootp, void (*action)(const void *nodep, const DW_VISIT which, - UNUSEDARG const int depth)) + UNUSEDARG const int depth)) { const struct hs_base *head = (const struct hs_base *)rootp; struct ts_entry *root = 0; @@ -673,6 +698,3 @@ dwarf_tdestroy(void *rootp, void (*free_node)(void *nodep)) free(root); free(head); } - - - diff --git a/thirdparty/dwarf/dwarf_types.c b/thirdparty/dwarf/dwarf_types.c index 01127a1b..af4ec11a 100644 --- a/thirdparty/dwarf/dwarf_types.c +++ b/thirdparty/dwarf/dwarf_types.c @@ -25,8 +25,9 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_error.h" #include "dwarf_types.h" #include "dwarf_global.h" diff --git a/thirdparty/dwarf/dwarf_util.c b/thirdparty/dwarf/dwarf_util.c index fd9676ee..5eee9a58 100644 --- a/thirdparty/dwarf/dwarf_util.c +++ b/thirdparty/dwarf/dwarf_util.c @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2016 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -26,10 +26,14 @@ */ #include "config.h" -#include "dwarf_incl.h" #include #include -#include /* For free() */ +#include /* For free() and emergency abort() */ +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" +#include "memcpy_swap.h" #include "dwarf_die_deliv.h" #include "pro_encode_nm.h" @@ -38,6 +42,27 @@ #define TRUE 1 #define FALSE 0 +#if _WIN32 +#define NULL_DEVICE_NAME "NUL" +#else +#define NULL_DEVICE_NAME "/dev/null" +#endif /* _WIN32 */ + +/* The function returned allows dwarfdump and other callers to + do an endian-sensitive copy-word with a chosen + source-length. */ +typedef void (*endian_funcp_type)(void *, const void *,unsigned long); + +endian_funcp_type +dwarf_get_endian_copy_function(Dwarf_Debug dbg) +{ + if (dbg) { + return dbg->de_copy_word; + } + return 0; +} + + Dwarf_Bool _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg) { @@ -149,7 +174,7 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, Dwarf_Error*error) { Dwarf_Unsigned length = 0; - Dwarf_Word leb128_length = 0; + Dwarf_Unsigned leb128_length = 0; Dwarf_Unsigned form_indirect = 0; Dwarf_Unsigned ret_value = 0; @@ -167,7 +192,8 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, return DW_DLV_ERROR; - case 0: return 0; + case 0: return DW_DLV_OK; + case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_strp_sup: @@ -202,21 +228,53 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, } return DW_DLV_OK; - case DW_FORM_block1: - *size_out = *(Dwarf_Small *) val_ptr + 1; + case DW_FORM_block1: { + ptrdiff_t sizeasptrdiff = 0; + + if (val_ptr >= section_end_ptr) { + _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); + return DW_DLV_ERROR; + } + ret_value = *(Dwarf_Small *) val_ptr; + sizeasptrdiff = (ptrdiff_t)ret_value; + if (sizeasptrdiff > (section_end_ptr - val_ptr) || + sizeasptrdiff < 0) { + _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); + return DW_DLV_ERROR; + } + *size_out = ret_value +1; + } return DW_DLV_OK; - case DW_FORM_block2: + case DW_FORM_block2: { + ptrdiff_t sizeasptrdiff = 0; + READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - val_ptr, sizeof(Dwarf_Half),error,section_end_ptr); - *size_out = ret_value + sizeof(Dwarf_Half); + val_ptr, DWARF_HALF_SIZE,error,section_end_ptr); + sizeasptrdiff = (ptrdiff_t)ret_value; + if (sizeasptrdiff > (section_end_ptr - val_ptr) || + sizeasptrdiff < 0) { + _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); + return DW_DLV_ERROR; + } + *size_out = ret_value + DWARF_HALF_SIZE; + } return DW_DLV_OK; - case DW_FORM_block4: + case DW_FORM_block4: { + ptrdiff_t sizeasptrdiff = 0; + READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned, - val_ptr, sizeof(Dwarf_ufixed), + val_ptr, DWARF_32BIT_SIZE, error,section_end_ptr); - *size_out = ret_value + sizeof(Dwarf_ufixed); + sizeasptrdiff = (ptrdiff_t)ret_value; + if (sizeasptrdiff > (section_end_ptr - val_ptr) || + sizeasptrdiff < 0) { + _dwarf_error(dbg,error,DW_DLE_FORM_BLOCK_LENGTH_ERROR); + return DW_DLV_ERROR; + } + *size_out = ret_value + DWARF_32BIT_SIZE; + } return DW_DLV_OK; case DW_FORM_data1: @@ -235,7 +293,21 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, *size_out = 8; return DW_DLV_OK; - case DW_FORM_string: + case DW_FORM_data16: + *size_out = 16; + return DW_DLV_OK; + + case DW_FORM_string: { + int res = 0; + res = _dwarf_check_string_valid(dbg,val_ptr, + val_ptr, + section_end_ptr, + DW_DLE_FORM_STRING_BAD_STRING, + error); + if ( res != DW_DLV_OK) { + return res; + } + } *size_out = strlen((char *) val_ptr) + 1; return DW_DLV_OK; @@ -273,9 +345,9 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, case DW_FORM_indirect: { - Dwarf_Word indir_len = 0; + Dwarf_Unsigned indir_len = 0; int res = 0; - Dwarf_Unsigned real_form_len = 0; + Dwarf_Unsigned info_data_len = 0; DECODE_LEB128_UWORD_LEN_CK(val_ptr,form_indirect,indir_len, dbg,error,section_end_ptr); @@ -287,19 +359,21 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, _dwarf_error(dbg,error,DW_DLE_NESTED_FORM_INDIRECT_ERROR); return DW_DLV_ERROR; } + /* If form_indirect is DW_FORM_implicit_const then + the following call will set info_data_len 0 */ res = _dwarf_get_size_of_val(dbg, form_indirect, cu_version, address_size, val_ptr + indir_len, v_length_size, - &real_form_len, + &info_data_len, section_end_ptr, error); if(res != DW_DLV_OK) { return res; } - *size_out = indir_len + real_form_len; + *size_out = indir_len + info_data_len; return DW_DLV_OK; } @@ -319,6 +393,13 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, *size_out = 8; return DW_DLV_OK; + /* DW_FORM_implicit_const is a value in the + abbreviations, not in the DIEs and this + functions measures DIE size. */ + case DW_FORM_implicit_const: + *size_out = 0; + return DW_DLV_OK; + case DW_FORM_sdata: { /* Discard the decoded value, we just want the length of the value. */ @@ -331,8 +412,40 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, *size_out = leb128_length; return DW_DLV_OK; } + case DW_FORM_ref_sup4: + *size_out = 4; + return DW_DLV_OK; + case DW_FORM_ref_sup8: + *size_out = 8; + return DW_DLV_OK; + case DW_FORM_addrx1: + *size_out = 1; + return DW_DLV_OK; + case DW_FORM_addrx2: + *size_out = 2; + return DW_DLV_OK; + case DW_FORM_addrx3: + *size_out = 4; + return DW_DLV_OK; + case DW_FORM_addrx4: + *size_out = 4; + return DW_DLV_OK; + case DW_FORM_strx1: + *size_out = 1; + return DW_DLV_OK; + case DW_FORM_strx2: + *size_out = 2; + return DW_DLV_OK; + case DW_FORM_strx3: + *size_out = 4; + return DW_DLV_OK; + case DW_FORM_strx4: + *size_out = 4; + return DW_DLV_OK; + case DW_FORM_loclistx: + case DW_FORM_rnglistx: case DW_FORM_addrx: case DW_FORM_GNU_addr_index: case DW_FORM_strx: @@ -345,6 +458,7 @@ _dwarf_get_size_of_val(Dwarf_Debug dbg, return DW_DLV_OK; } + case DW_FORM_line_strp: case DW_FORM_strp: *size_out = v_length_size; return DW_DLV_OK; @@ -414,7 +528,7 @@ _dwarf_valid_form_we_know(UNUSEDARG Dwarf_Debug dbg, if (at_name == 0) { return FALSE; } - if (at_form <= DW_FORM_ref_sig8) { + if (at_form <= DW_FORM_addrx4 ) { return TRUE; } if (at_form == DW_FORM_GNU_addr_index || @@ -452,7 +566,7 @@ _dwarf_valid_form_we_know(UNUSEDARG Dwarf_Debug dbg, See also dwarf_get_abbrev() in dwarf_abbrev.c. - Returns NULL on error. */ + Returns DW_DLV_ERROR on error. */ int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, Dwarf_Abbrev_List *list_out, @@ -462,11 +576,9 @@ _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table; Dwarf_Hash_Table_Entry entry_base = 0; Dwarf_Hash_Table_Entry entry_cur = 0; - Dwarf_Word hash_num = 0; + Dwarf_Unsigned hash_num = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Unsigned abbrev_tag = 0; - Dwarf_Unsigned attr_name = 0; - Dwarf_Unsigned attr_form = 0; Dwarf_Abbrev_List hash_abbrev_entry = 0; Dwarf_Abbrev_List inner_list_entry = 0; Dwarf_Hash_Table_Entry inner_hash_entry = 0; @@ -548,14 +660,20 @@ _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, /* ASSERT: size != 0 */ end_abbrev_ptr = abbrev_ptr + size; } else { - end_abbrev_ptr = abbrev_ptr + + end_abbrev_ptr = dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; } } /* End of abbrev's as we are past the end entirely. - This can happen. */ - if (abbrev_ptr > end_abbrev_ptr) { + This can happen,though it seems wrong. + Or we are at the end of the data block, + which we also take as + meaning done with abbrevs for this CU. An abbreviations table + is supposed to end with a zero byte. Not ended by end + of data block. But we are allowing what is possibly a bit + more flexible end policy here. */ + if (abbrev_ptr >= end_abbrev_ptr) { return DW_DLV_NO_ENTRY; } /* End of abbrev's for this cu, since abbrev code is 0. */ @@ -574,6 +692,11 @@ _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, DECODE_LEB128_UWORD_CK(abbrev_ptr, abbrev_tag, dbg,error,end_abbrev_ptr); + if (abbrev_ptr >= end_abbrev_ptr) { + _dwarf_error(dbg, error, DW_DLE_ABBREV_OFF_END); + return DW_DLV_ERROR; + } + inner_list_entry = (Dwarf_Abbrev_List) _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1); if (inner_list_entry == NULL) { @@ -601,24 +724,41 @@ _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, /* Cycle thru the abbrev content, ignoring the content except to find the end of the content. */ - do { - DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_name, - dbg,error,end_abbrev_ptr); - DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_form, - dbg,error,end_abbrev_ptr); - if (!_dwarf_valid_form_we_know(dbg,attr_form,attr_name)) { - _dwarf_error(dbg,error,DW_DLE_UNKNOWN_FORM); - return DW_DLV_ERROR; - } - atcount++; - } while (attr_name != 0 && attr_form != 0); + { + Dwarf_Unsigned attr_name = 0; + Dwarf_Unsigned attr_form = 0; + do { + DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_name, + dbg,error,end_abbrev_ptr); + DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_form, + dbg,error,end_abbrev_ptr); + if (attr_form == DW_FORM_implicit_const) { + UNUSEDARG Dwarf_Signed implicit_const = 0; + /* The value is here, not in a DIE. */ + DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, + dbg,error,end_abbrev_ptr); + } + if (!_dwarf_valid_form_we_know( + dbg,attr_form,attr_name)) { + _dwarf_error(dbg,error,DW_DLE_UNKNOWN_FORM); + return DW_DLV_ERROR; + } + atcount++; + } while (attr_name != 0 && attr_form != 0); + } /* We counted one too high, by counting the NUL byte pair at end of list. So decrement. */ inner_list_entry->abl_count = atcount-1; - /* We may have fallen off the end of content, that is not - a botch in the section, as there is no rule that the last - abbrev need have abbrev_code of 0. */ + /* The abbreviations table ends with an entry with a single + byte of zero for the abbreviation code. + Padding bytes following that zero are allowed, but + here we simply stop looking past that zero abbrev. + + We also stop looking if the block/section ends, + though the DWARF2 and later standards do not specifically + allow section/block end to terminate an abbreviations + list. */ } while ((abbrev_ptr < end_abbrev_ptr) && *abbrev_ptr != 0 && abbrev_code != code); @@ -644,18 +784,19 @@ _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code, int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, void *strptr, void *areaendptr, + int suggested_error, Dwarf_Error*error) { - Dwarf_Small *start = areaptr; Dwarf_Small *p = strptr; Dwarf_Small *end = areaendptr; + if (p < start) { - _dwarf_error(dbg,error,DW_DLE_DEBUG_STR_OFFSET_BAD); + _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (p >= end) { - _dwarf_error(dbg,error,DW_DLE_DEBUG_STR_OFFSET_BAD); + _dwarf_error(dbg,error,suggested_error); return DW_DLV_ERROR; } if (dbg->de_assume_string_in_bounds) { @@ -676,7 +817,13 @@ _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, /* Return non-zero if the start/end are not valid for the die's section. - Return 0 if valid*/ + If pastend matches the dss_data+dss_size then + pastend is a pointer that cannot be dereferenced. + But we allow it as valid here, it is normal for + a pointer to point one-past-end in + various circumstances (one must + avoid dereferencing it, of course). + Return 0 if valid. Return 1 if invalid. */ int _dwarf_reference_outside_section(Dwarf_Die die, Dwarf_Small * startaddr, @@ -708,10 +855,15 @@ _dwarf_reference_outside_section(Dwarf_Die die, for cross-endian use. Only 2,4,8 should be lengths passed in. */ -void * -_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len) +void +_dwarf_memcpy_noswap_bytes(void *s1, const void *s2, unsigned long len) +{ + memcpy(s1,s2,(size_t)len); + return; +} +void +_dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len) { - void *orig_s1 = s1; unsigned char *targ = (unsigned char *) s1; const unsigned char *src = (const unsigned char *) s2; @@ -737,10 +889,9 @@ _dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len) else if (len == 1) { targ[0] = src[0]; } else { - memcpy(s1, s2, len); + memcpy(s1, s2, (size_t)len); } - - return orig_s1; + return; } @@ -751,14 +902,17 @@ _dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len) given a known cu header location ( an offset in .debug_info or debug_types). */ /* ARGSUSED */ + int -_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, +_dwarf_length_of_cu_header(Dwarf_Debug dbg, + Dwarf_Unsigned offset, Dwarf_Bool is_info, Dwarf_Unsigned *area_length_out, Dwarf_Error *error) { int local_length_size = 0; int local_extension_size = 0; + Dwarf_Half version = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned final_size = 0; Dwarf_Small *section_start = @@ -775,19 +929,53 @@ _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, cuptr, local_length_size, local_extension_size, error,section_length,section_end_ptr); - final_size = local_extension_size + /* initial extension, if present */ - local_length_size + /* Size of cu length field. */ - sizeof(Dwarf_Half) + /* Size of version stamp field. */ - local_length_size + /* Size of abbrev offset field. */ - sizeof(Dwarf_Small); /* Size of address size field. */ - - if (!is_info) { - final_size += + READ_UNALIGNED_CK(dbg, version, Dwarf_Half, + cuptr, DWARF_HALF_SIZE,error,section_end_ptr); + cuptr += DWARF_HALF_SIZE; + if (version == 5) { + Dwarf_Ubyte unit_type = 0; + + READ_UNALIGNED_CK(dbg, unit_type, Dwarf_Ubyte, + cuptr, sizeof(Dwarf_Ubyte),error,section_end_ptr); + switch (unit_type) { + case DW_UT_compile: + final_size = local_extension_size + + local_length_size + /* Size of cu length field. */ + DWARF_HALF_SIZE + /* Size of version stamp field. */ + sizeof(Dwarf_Small)+ /* Size of unit type field. */ + sizeof(Dwarf_Small)+ /* Size of address size field. */ + local_length_size ; /* Size of abbrev offset field. */ + break; + case DW_UT_type: + case DW_UT_partial: + case DW_UT_skeleton: + case DW_UT_split_compile: + case DW_UT_split_type: + default: + _dwarf_error(dbg,error,DW_DLE_UNIT_TYPE_NOT_HANDLED); + return DW_DLV_ERROR; + } + } else if (version == 4) { + final_size = local_extension_size + + local_length_size + /* Size of cu length field. */ + DWARF_HALF_SIZE + /* Size of version stamp field. */ + local_length_size + /* Size of abbrev offset field. */ + sizeof(Dwarf_Small); /* Size of address size field. */ + if (!is_info) { + final_size += /* type signature size */ sizeof (Dwarf_Sig8) + /* type offset size */ local_length_size; + } + } else if (version < 4) { + final_size = local_extension_size + + local_length_size + + DWARF_HALF_SIZE + + local_length_size + + sizeof(Dwarf_Small); /* Size of address size field. */ } + *area_length_out = final_size; return DW_DLV_OK; } @@ -799,8 +987,8 @@ _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg, Dwarf_Bool dinfo) { Dwarf_Unsigned finalsize = 0; - finalsize = dbg->de_length_size + /* Size of cu length field. */ - sizeof(Dwarf_Half) + /* Size of version stamp field. */ + finalsize = dbg->de_length_size + /* Size of cu length field. */ + DWARF_HALF_SIZE + /* Size of version stamp field. */ dbg->de_length_size + /* Size of abbrev offset field. */ sizeof(Dwarf_Small); /* Size of address size field. */ if (!dinfo) { @@ -947,48 +1135,65 @@ dwarf_register_printf_callback( Dwarf_Debug dbg, } -/* start is a minimum size, but may be zero. */ -static void bufferdoublesize(struct Dwarf_Printf_Callback_Info_s *bufdata) +/* Allocate a bigger buffer if necessary. + Do not worry about previous content of the buffer. + Return 0 if we fail here. + Else return the requested len value. */ +static unsigned buffersetsize(Dwarf_Debug dbg, + struct Dwarf_Printf_Callback_Info_s *bufdata, + int len) { char *space = 0; - unsigned int targlen = 0; - if (bufdata->dp_buffer_len == 0) { - targlen = MINBUFLEN; - } else { - targlen = bufdata->dp_buffer_len * 2; - if (targlen < bufdata->dp_buffer_len) { - /* Overflow, we cannot do this doubling. */ - return; + + if (!dbg->de_printf_callback_null_device_handle) { + FILE *de = fopen(NULL_DEVICE_NAME,"w"); + if(!de) { + return 0; } + dbg->de_printf_callback_null_device_handle = de; + } + if (bufdata->dp_buffer_user_provided) { + return bufdata->dp_buffer_len; } /* Make big enough for a trailing NUL char. */ - space = (char *)malloc(targlen+1); + space = (char *)malloc(len+1); if (!space) { - /* Out of space, we cannot double it. */ - return; + /* Out of space, we cannot do anything. */ + return 0; } free(bufdata->dp_buffer); bufdata->dp_buffer = space; - bufdata->dp_buffer_len = targlen; - return; + bufdata->dp_buffer_len = len; + return len; } +/* We are only using C90 facilities, not C99, + in libdwarf/dwarfdump. */ int dwarf_printf(Dwarf_Debug dbg, const char * format, ...) { va_list ap; - int maxtries = 4; - int tries = 0; + unsigned bff = 0; struct Dwarf_Printf_Callback_Info_s *bufdata = &dbg->de_printf_callback; + FILE * null_device_handle = 0; + dwarf_printf_callback_function_type func = bufdata->dp_fptr; if (!func) { return 0; } - if (!bufdata->dp_buffer) { - bufferdoublesize(bufdata); + null_device_handle = + (FILE *) dbg->de_printf_callback_null_device_handle; + if (!bufdata->dp_buffer || !null_device_handle) { + /* Sets dbg device handle for later use if not + set already. */ + bff = buffersetsize(dbg,bufdata,MINBUFLEN); + if (!bff) { + /* Something is wrong. */ + return 0; + } if (!bufdata->dp_buffer) { /* Something is wrong. Possibly caller set up callback wrong. */ @@ -996,38 +1201,47 @@ dwarf_printf(Dwarf_Debug dbg, } } - /* Here we ensure (or nearly ensure) we expand - the buffer when necessary, but not excessively - (but only if we control the buffer size). */ - while (1) { - int olen = 0; - tries++; - va_start(ap,format); - olen = vsnprintf(bufdata->dp_buffer, - bufdata->dp_buffer_len, format,ap); - /* "The object ap may be passed as an argument to another - function; if that function invokes the va_arg() - macro with parameter ap, the value of ap in the calling - function is unspecified and shall be passed to the va_end() - macro prior to any further reference to ap." - Single Unix Specification. */ - va_end(ap); - if (olen > -1 && (long)olen < (long)bufdata->dp_buffer_len) { - /* The caller had better copy or dispose - of the contents, as next-call will overwrite them. */ - func(bufdata->dp_user_pointer,bufdata->dp_buffer); + { + int plen = 0; + int nlen = 0; + null_device_handle = + (FILE *) dbg->de_printf_callback_null_device_handle; + if (!null_device_handle) { + /* Something is wrong. */ return 0; } - if (bufdata->dp_buffer_user_provided) { - func(bufdata->dp_user_pointer,bufdata->dp_buffer); - return 0; + va_start(ap,format); + plen = vfprintf(null_device_handle,format,ap); + va_end(ap); + + if (!bufdata->dp_buffer_user_provided) { + if (plen >= (int)bufdata->dp_buffer_len) { + bff = buffersetsize(dbg,bufdata,plen+2); + if (!bff) { + /* Something is wrong. */ + return 0; + } + } + } else { + if (plen >= (int)bufdata->dp_buffer_len) { + /* We are stuck! User did not + give us space needed! */ + return 0; + } } - if (tries > maxtries) { - /* we did all we could, print what we have space for. */ - func(bufdata->dp_user_pointer,bufdata->dp_buffer); - return 0; + + va_start(ap,format); + nlen = vsprintf(bufdata->dp_buffer, + format,ap); + va_end(ap); + if ( nlen > plen) { + /* Impossible. Memory is corrupted now */ + fprintf(stderr,"\nlibdwarf impossible sprintf error %s %d\n", + __FILE__,__LINE__); + exit(1); } - bufferdoublesize(bufdata); + func(bufdata->dp_user_pointer,bufdata->dp_buffer); + return nlen; } /* Not reached. */ return 0; @@ -1158,6 +1372,3 @@ _dwarf_what_section_are_we(Dwarf_Debug dbg, sec_start_ptr_out, sec_len_out, sec_end_ptr_out); return DW_DLV_NO_ENTRY; } - - - diff --git a/thirdparty/dwarf/dwarf_util.h b/thirdparty/dwarf/dwarf_util.h index ebd7aa1d..a0c508b6 100644 --- a/thirdparty/dwarf/dwarf_util.h +++ b/thirdparty/dwarf/dwarf_util.h @@ -33,7 +33,7 @@ Make sure ptr is a pointer to a 1-byte type. In 2003 and earlier this was a hand-inlined version of _dwarf_decode_u_leb128() which did - not work correctly if Dwarf_Word was 64 bits. + not work correctly if Dwarf_Unsigned was 64 bits. April 2016: now uses a reader that is careful. 'return' only in case of error @@ -41,7 +41,7 @@ */ #define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \ do { \ - Dwarf_Word lu_leblen = 0; \ + Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Unsigned lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \ @@ -55,7 +55,7 @@ #define DECODE_LEB128_UWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \ do { \ - Dwarf_Word lu_leblen = 0; \ + Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Unsigned lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_u_leb128_chk(ptr,&lu_leblen,&lu_local,endptr); \ @@ -68,31 +68,17 @@ leblen = lu_leblen; \ } while (0) -#define DECODE_LEB128_UWORD(ptr, value) \ - do { \ - Dwarf_Word uleblen; \ - value = _dwarf_decode_u_leb128(ptr,&uleblen); \ - ptr += uleblen; \ - } while (0) - - /* Decodes signed leb128 encoded numbers. Make sure ptr is a pointer to a 1-byte type. In 2003 and earlier this was a hand-inlined version of _dwarf_decode_s_leb128() which did - not work correctly if Dwarf_Word was 64 bits. + not work correctly if Dwarf_Unsigned was 64 bits. */ -#define DECODE_LEB128_SWORD(ptr, value) \ - do { \ - Dwarf_Word sleblen = 0; \ - value = _dwarf_decode_s_leb128(ptr,&sleblen); \ - ptr += sleblen; \ - } while (0) #define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \ do { \ - Dwarf_Word uleblen = 0; \ + Dwarf_Unsigned uleblen = 0; \ Dwarf_Signed local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_s_leb128_chk(ptr,&uleblen,&local,endptr); \ @@ -105,7 +91,7 @@ } while (0) #define DECODE_LEB128_SWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \ do { \ - Dwarf_Word lu_leblen = 0; \ + Dwarf_Unsigned lu_leblen = 0; \ Dwarf_Signed lu_local = 0; \ int lu_res = 0; \ lu_res = _dwarf_decode_s_leb128_chk(ptr,&lu_leblen,\ @@ -127,19 +113,7 @@ These seem bogus as they assume 4 bytes get a 4 byte word. Wrong. FIXME -*/ -#define SKIP_LEB128_WORD(ptr) \ - do { \ - if ((*(ptr++) & 0x80) != 0) { \ - if ((*(ptr++) & 0x80) != 0) { \ - if ((*(ptr++) & 0x80) != 0) { \ - ptr++; \ - } \ - } \ - } \ - } while (0) -/* 'return' only in case of error else falls through. */ @@ -206,29 +180,21 @@ typedef Dwarf_Unsigned BIGGEST_UINT; #ifdef WORDS_BIGENDIAN -#define READ_UNALIGNED(dbg,dest,desttype, source, length) \ - do { \ - BIGGEST_UINT _ltmp = 0; \ - dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \ - source, length) ; \ - dest = (desttype)_ltmp; \ - } while (0) - #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \ - do { \ - BIGGEST_UINT _ltmp = 0; \ - Dwarf_Byte_Ptr readend = source+length; \ - if (readend < source) { \ - _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR); \ - return DW_DLV_ERROR; \ - } \ - if (readend > endptr) { \ - _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR); \ - return DW_DLV_ERROR; \ - } \ - dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \ - source, length) ; \ - dest = (desttype)_ltmp; \ + do { \ + BIGGEST_UINT _ltmp = 0; \ + Dwarf_Byte_Ptr readend = source+length; \ + if (readend < source) { \ + _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \ + return DW_DLV_ERROR; \ + } \ + if (readend > endptr) { \ + _dwarf_error(dbg, error, DW_DLE_READ_BIGENDIAN_ERROR); \ + return DW_DLV_ERROR; \ + } \ + dbg->de_copy_word( (((char *)(&_ltmp)) + \ + sizeof(_ltmp) - length),source, length) ; \ + dest = (desttype)_ltmp; \ } while (0) @@ -240,28 +206,23 @@ typedef Dwarf_Unsigned BIGGEST_UINT; on host endianness, not object file endianness. The memcpy args are the issue. */ -#define SIGN_EXTEND(dest, length) \ - do { \ - if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) { \ - memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \ - sizeof(dest) - length); \ - } \ +#define SIGN_EXTEND(dest, length) \ + do { \ + if (*(Dwarf_Sbyte *)((char *)&dest + \ + sizeof(dest) - length) < 0) { \ + memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\ + sizeof(dest) - length); \ + } \ } while (0) #else /* LITTLE ENDIAN */ - -#define READ_UNALIGNED(dbg,dest,desttype, source, length) \ - do { \ - BIGGEST_UINT _ltmp = 0; \ - dbg->de_copy_word( (char *)(&_ltmp) , \ - source, length) ; \ - dest = (desttype)_ltmp; \ - } while (0) - - #define READ_UNALIGNED_CK(dbg,dest,desttype, source, length,error,endptr) \ do { \ BIGGEST_UINT _ltmp = 0; \ Dwarf_Byte_Ptr readend = source+length; \ + if (readend < source) { \ + _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR);\ + return DW_DLV_ERROR; \ + } \ if (readend > endptr) { \ _dwarf_error(dbg, error, DW_DLE_READ_LITTLEENDIAN_ERROR);\ return DW_DLV_ERROR; \ @@ -333,48 +294,6 @@ typedef Dwarf_Unsigned BIGGEST_UINT; does not seem necessary (none of the 64bit length seems appropriate unless it's ident[EI_CLASS] == ELFCLASS64). */ -#if 0 -#define READ_AREA_LENGTH(r_dbg,w_target,r_targtype, \ - rw_src_data_p,w_length_size,w_exten_size) \ - do { \ - READ_UNALIGNED(r_dbg,w_target,r_targtype, \ - rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE); \ - if (w_target == DISTINGUISHED_VALUE) { \ - /* dwarf3 64bit extension */ \ - w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ - rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE; \ - w_exten_size = ORIGINAL_DWARF_OFFSET_SIZE; \ - READ_UNALIGNED(r_dbg,w_target,r_targtype, \ - rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE); \ - rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ - } else { \ - if (w_target == 0 && r_dbg->de_big_endian_object) { \ - /* Might be IRIX: We have to distinguish between */ \ - /* 32-bit DWARF format and IRIX 64-bit DWARF format. */ \ - if (r_dbg->de_length_size == 8) { \ - /* IRIX 64 bit, big endian. This test */ \ - /* is not a truly precise test, a precise test */ \ - /* would check if the target was IRIX. */ \ - READ_UNALIGNED(r_dbg,w_target,r_targtype, \ - rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE); \ - w_length_size = DISTINGUISHED_VALUE_OFFSET_SIZE; \ - rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE; \ - w_exten_size = 0; \ - } else { \ - /* 32 bit, big endian */ \ - w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \ - rw_src_data_p += w_length_size; \ - w_exten_size = 0; \ - } \ - } else { \ - /* Standard 32 bit dwarf2/dwarf3 */ \ - w_exten_size = 0; \ - w_length_size = ORIGINAL_DWARF_OFFSET_SIZE; \ - rw_src_data_p += w_length_size; \ - } \ - } \ - } while (0) -#endif /* 0 */ /* The w_target > r_sectionlen compare is done without adding in case the w_target value read is so large any addition would overflow. A basic value sanity check. */ @@ -439,21 +358,14 @@ typedef Dwarf_Unsigned BIGGEST_UINT; } while (0) -Dwarf_Unsigned -_dwarf_decode_u_leb128(Dwarf_Small * leb128, - Dwarf_Word * leb128_length); - /* Fuller checking. Returns DW_DLV_ERROR or DW_DLV_OK Caller must set Dwarf_Error */ int _dwarf_decode_u_leb128_chk(Dwarf_Small * leb128, - Dwarf_Word * leb128_length, + Dwarf_Unsigned * leb128_length, Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr); -Dwarf_Signed _dwarf_decode_s_leb128(Dwarf_Small * leb128, - Dwarf_Word * leb128_length); - int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, - Dwarf_Word * leb128_length, + Dwarf_Unsigned * leb128_length, Dwarf_Signed *outval, Dwarf_Byte_Ptr endptr); int @@ -507,7 +419,7 @@ int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, ** Presumption is the 'endptr' pts to end of some dwarf section data. */ int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, - void *startptr, void *endptr, Dwarf_Error *error); + void *startptr, void *endptr, int suggested_error, Dwarf_Error *error); int _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Bool is_info, @@ -539,5 +451,4 @@ int _dwarf_what_section_are_we(Dwarf_Debug dbg, Dwarf_Small **sec_end_ptr_out, Dwarf_Error *error); - #endif /* DWARF_UTIL_H */ diff --git a/thirdparty/dwarf/dwarf_vars.c b/thirdparty/dwarf/dwarf_vars.c index 5ce6260e..823f8531 100644 --- a/thirdparty/dwarf/dwarf_vars.c +++ b/thirdparty/dwarf/dwarf_vars.c @@ -26,8 +26,9 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_error.h" #include "dwarf_vars.h" #include "dwarf_global.h" diff --git a/thirdparty/dwarf/dwarf_weaks.c b/thirdparty/dwarf/dwarf_weaks.c index 8c1a7adc..55bf938f 100644 --- a/thirdparty/dwarf/dwarf_weaks.c +++ b/thirdparty/dwarf/dwarf_weaks.c @@ -26,8 +26,9 @@ */ #include "config.h" -#include "dwarf_incl.h" #include +#include "dwarf_incl.h" +#include "dwarf_error.h" #include "dwarf_weaks.h" #include "dwarf_global.h" diff --git a/thirdparty/dwarf/dwarf_xu_index.c b/thirdparty/dwarf/dwarf_xu_index.c index 79cbf739..85355ee9 100644 --- a/thirdparty/dwarf/dwarf_xu_index.c +++ b/thirdparty/dwarf/dwarf_xu_index.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2014-2015 David Anderson. All Rights Reserved. + Copyright (C) 2014-2019 David Anderson. All Rights Reserved. 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 @@ -36,9 +36,13 @@ #include "config.h" -#include "dwarf_incl.h" #include #include + +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_xu_index.h" #define HASHSIGNATURELEN 8 @@ -47,6 +51,9 @@ #define TRUE 1 #define FALSE 0 +/* zerohashkey used as all-zero-bits for comparison. */ +static Dwarf_Sig8 zerohashkey; + int dwarf_get_xu_index_header(Dwarf_Debug dbg, /* Pass in section_type "tu" or "cu" */ @@ -116,7 +123,6 @@ dwarf_get_xu_index_header(Dwarf_Debug dbg, READ_UNALIGNED_CK(dbg,num_slots, Dwarf_Unsigned, data,datalen32, error,section_end); - data += datalen32; hash_tab_offset = datalen32*4; indexes_tab_offset = hash_tab_offset + (num_slots * HASHSIGNATURELEN); /* Look for corrupt section data. */ @@ -159,7 +165,11 @@ dwarf_get_xu_index_header(Dwarf_Debug dbg, _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } - strcpy(indexptr->gx_type,section_type); + /* Only "cu" or "tu" allowed, that is checked above. + But for safety we just copy the allowed bytes*/ + indexptr->gx_type[0] = section_type[0]; + indexptr->gx_type[1] = section_type[1]; + indexptr->gx_type[2] = 0; indexptr->gx_dbg = dbg; indexptr->gx_section_length = sect->dss_size; indexptr->gx_section_data = sect->dss_data; @@ -236,7 +246,6 @@ int dwarf_get_xu_hash_entry(Dwarf_Xu_Index_Header xuhdr, indexentry = indextab + (index * LEN32BIT); memcpy(hash_value,&hashval,sizeof(hashval)); - READ_UNALIGNED_CK(dbg,indexval,Dwarf_Unsigned, indexentry, LEN32BIT, err,section_end); @@ -258,8 +267,8 @@ static const char * dwp_secnames[] = { "DW_SECT_LINE" /* 4 */ /*".debug_line.dwo"*/, "DW_SECT_LOC" /* 5 */ /*".debug_loc.dwo"*/, "DW_SECT_STR_OFFSETS" /* 6 */ /*".debug_str_offsets.dwo"*/, -"DW_SECT_MACINFO" /* 7 */ /*".debug_macinfo.dwo"*/, -"DW_SECT_MACRO" /* 8 */ /*".debug_macro.dwo"*/, +"DW_SECT_MACRO" /* 7 */ /*".debug_macro.dwo"*/, +"DW_SECT_RNGLISTS" /* 8 */ /*".debug_rnglists.dwo"*/, "No name > 8", }; @@ -290,7 +299,7 @@ dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr, READ_UNALIGNED_CK(dbg,sec_num,Dwarf_Unsigned, nameloc, LEN32BIT, err,section_end); - if (sec_num > DW_SECT_MACRO) { + if (sec_num > DW_SECT_RNGLISTS) { _dwarf_error(dbg, err, DW_DLE_XU_NAME_COL_ERROR); return DW_DLV_ERROR; } @@ -358,8 +367,6 @@ dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr, return DW_DLV_OK; } -/* zerohashkey used as all-zero-bits for comparison. */ -static Dwarf_Sig8 zerohashkey; static int _dwarf_search_fission_for_key(UNUSEDARG Dwarf_Debug dbg, @@ -623,5 +630,3 @@ dwarf_xu_header_free(Dwarf_Xu_Index_Header indexptr) dwarf_dealloc(dbg,indexptr,DW_DLA_XU_INDEX); } } - - diff --git a/thirdparty/dwarf/dwarf_xu_index.h b/thirdparty/dwarf/dwarf_xu_index.h index f01d8743..8010ac59 100644 --- a/thirdparty/dwarf/dwarf_xu_index.h +++ b/thirdparty/dwarf/dwarf_xu_index.h @@ -58,11 +58,3 @@ struct Dwarf_Xu_Index_Header_s { }; #endif /* DWARF_XU_INDEX_H */ - - - - - - - - diff --git a/thirdparty/dwarf/dwgetopt.c b/thirdparty/dwarf/dwgetopt.c new file mode 100644 index 00000000..52de7aaa --- /dev/null +++ b/thirdparty/dwarf/dwgetopt.c @@ -0,0 +1,377 @@ +/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ +/* Modified by David Anderson to work with GNU/Linux and freebsd. + Added {} for clarity. + Switched to standard dwarfdump formatting. + Treatment of : modified so that :: gets dwoptarg NULL + if space follows the letter + (the dwoptarg is set to null). + renamed to make it clear this is a private version. + Oct 17 2017: Created dwgetopt_long(). See dwgetopt.h +*/ +/* +* Copyright (c) 1987, 1993, 1994 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +/* This does not presently handle the option string + leading + or leading - features. Such are not used + by by libdwarfdump. Nor does it understand the + GNU Env var POSIXLY_CORRECT . + It does know of the leading ":" in the option string. + See BADCH below. + */ + +#include +#include /* For exit() */ +#include /* For strchr */ +#include "dwgetopt.h" + +#define STRIP_OFF_CONSTNESS(a) ((void *)(size_t)(const void *)(a)) + +int dwopterr = 1, /* if error message should be printed */ + dwoptind = 1, /* index into parent argv vector */ + dwoptopt, /* character checked for validity */ + dwoptreset; /* reset getopt */ +char *dwoptarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +#define TRUE 1 +#define FALSE 0 + +#if 0 /* FOR DEBUGGING ONLY */ +/* Use for testing dwgetopt only. + Not a standard function. */ +void +dwgetoptresetfortestingonly(void) +{ + dwopterr = 1; + dwoptind = 1; + dwoptopt = 0; + dwoptreset = 0; + dwoptarg = 0; +} +#endif /* FOR DEBUGGING ONLY */ + + +static const char *place = EMSG;/* option letter processing */ + + +/* Post Condition: + if return FALSE then *argerr is set false. */ +static int +dwoptnamematches( + const struct dwoption *dwlopt, + const char *iplace, + const char **argloc, + int *argerr) +{ + + const char *eq = 0; + size_t namelen = 0; + size_t arglen = 0; + int d = 0; + + for(eq = iplace; *eq; ++eq) { + if (*eq != '=') { + continue; + } + /* Found =, arg should follow */ + namelen = (eq - iplace); + if (namelen != (unsigned)strlen(dwlopt->name)) { + return FALSE; + } + eq++; + arglen = strlen(eq); + break; + } + if (namelen) { + d = strncmp(iplace,dwlopt->name,namelen); + if (d) { + return FALSE; + } + if (dwlopt->has_arg == 0) { + *argerr = TRUE; + return TRUE; + } + if (arglen) { + /* Discarding const, avoiding warning. + Data is in user space, so this is ok. */ + dwoptarg = (char *)eq; + *argloc = (const char *)eq; + } else { + /* Has arg = but arg is empty. */ + dwoptarg = 0; + } + return TRUE; + } else { + d = strcmp(iplace,dwlopt->name); + if (d) { + return FALSE; + } + if (dwlopt->has_arg == 1) { + *argerr = TRUE; + return TRUE; + } + dwoptarg = 0; + return TRUE; + } +} + + + +/* dwgetopt_long + A reimplemenation of a portion of + the getopt(3) GNU/Linux getopt_long(). + See dwgetopt.h for more details. +*/ +int dwgetopt_long(int nargc, char *const nargv[], + const char *ostr, + const struct dwoption* longopts, + int *longindex) +{ + char *lplace = 0; + if (dwoptreset) { + /* Not really supported. */ + place = EMSG; + return (-1); + } + if (*place) { + int v = dwgetopt(nargc,nargv,ostr); + return v; + } + /* Use local lplace in case we need to call getopt() + just below. */ + lplace = nargv[dwoptind]; + if (dwoptind >= nargc || *lplace++ != '-') { + /* Argument is absent or is not an option */ + place = EMSG; + return (-1); + } + if (*lplace != '-') { + /* Notice place not disturbed. */ + int v = dwgetopt(nargc,nargv,ostr); + return v; + } + /* Starts with two dashes. + Now we set the global place */ + place = lplace+1; + if (!*place) { + /* "--" => end of options */ + ++dwoptind; + place = EMSG; + return (-1); + } + + /* We think this is a longopt. */ + { + int lo_num = 0; + + for(;;lo_num++) { + const struct dwoption *dwlopt = longopts +lo_num; + const char * argloc = 0; + int argerr = 0; + int resmatch = 0; + + if (!dwlopt->name) { + dwoptind++; + (void)fprintf(stderr, + "%s: invalid long option '--%s'\n", + nargv[0]?nargv[0]:"", + place); + /* Leave longindex unchanged. */ + place = EMSG; + return (BADCH); + } + resmatch= dwoptnamematches(dwlopt,place, + &argloc,&argerr); + if (resmatch) { + dwoptarg = 0; + if (argloc) { + /* Must drop const here. Ugh. */ + dwoptarg = (char *)argloc; + } + } + if (argerr) { + /* resmatch == TRUE + + arg option missing if required, present + but not allowed. + GNU Behavior not well documented. + Had to experiment. + + if argument-not-allowed, and we have one, + do ??? + + If argument-required, + then here GNU + would take the next argv as the argument. + we are not currently doing that. */ + /**longindex = lo_num; */ + if (dwlopt->has_arg) { + /* Missing required arg, this does not + match GNU getopt_long behavior + of taking next argv as the arg value. + and thus making getopt_long succeed. */ + (void)fprintf(stderr, + "%s: missing required long option argument '--%s'\n", + nargv[0]?nargv[0]:"", + place); + } else { + /* has arg but should not */ + (void)fprintf(stderr, + "%s: option '--%s' does not allow an argument\n", + nargv[0]?nargv[0]:"", + dwlopt->name); + } + dwoptind++; + place = EMSG; + return (BADCH); + } + if (resmatch) { + *longindex = lo_num; + place = EMSG; + dwoptind++; + return dwlopt->val; + } + } + /* Can never get here */ + place = EMSG; + dwoptind++; + return (-1); + } +} + +/* + * getopt -- + * Parse argc/argv argument vector. + * a: means + * -afoo + * -a foo + * and 'foo' is returned in dwoptarg + * b:: means + * -b + * and dwoptarg is null + * -bother + * and dwoptarg is 'other' + */ +int +dwgetopt(int nargc, char * const nargv[], const char *ostr) +{ + char *oli; /* option letter list index */ + + if (dwoptreset || *place == 0) { /* update scanning pointer */ + dwoptreset = 0; + place = nargv[dwoptind]; + + if (dwoptind >= nargc || *place++ != '-') { + /* Argument is absent or is not an option */ + place = EMSG; + return (-1); + } + dwoptopt = *place++; + if (dwoptopt == '-' && *place == 0) { + /* "--" => end of options */ + ++dwoptind; + place = EMSG; + return (-1); + } + if (dwoptopt == 0) { + /* Solitary '-', treat as a '-' option + if the program (eg su) is looking for it. */ + place = EMSG; + if (strchr(ostr, '-') == NULL) { + return -1; + } + dwoptopt = '-'; + } + } else { + dwoptopt = *place++; + } + /* See if option letter is one the caller wanted... */ + if (dwoptopt == ':' || (oli = strchr(ostr, dwoptopt)) == NULL) { + if (*place == 0) { + ++dwoptind; + } + if (dwopterr && *ostr != ':') { + (void)fprintf(stderr, + "%s: invalid option -- '%c'\n", + nargv[0]?nargv[0]:"", + dwoptopt); + } + return (BADCH); + } + + /* Does this option need an argument? */ + if (oli[1] != ':') { + /* don't need argument */ + dwoptarg = NULL; + if (*place == 0) { + ++dwoptind; + } + } else { + int reqnextarg = 1; + if (oli[1] && (oli[2] == ':')) { + /* Pair of :: means special treatment of dwoptarg */ + reqnextarg = 0; + } + /* Option-argument is either the rest of this argument or the + entire next argument. */ + if (*place ) { + /* Whether : or :: */ + dwoptarg = STRIP_OFF_CONSTNESS(place); + } else if (reqnextarg) { + /* ! *place */ + if (nargc > (++dwoptind)) { + dwoptarg = nargv[dwoptind]; + } else { + place=EMSG; + /* Next arg required, but is missing */ + if (*ostr == ':') { + /* Leading : in ostr calls for BADARG return. */ + return (BADARG); + } + if (dwopterr) { + (void)fprintf(stderr, + "%s: option requires an argument. -- '%c'\n", + nargv[0]?nargv[0]:"", + dwoptopt); + } + return (BADCH); + } + } else { + /* ! *place */ + /* The key part of :: treatment. */ + dwoptarg = NULL; + } + place = EMSG; + ++dwoptind; + } + return (dwoptopt); /* return option letter */ +} diff --git a/thirdparty/dwarf/dwgetopt.h b/thirdparty/dwarf/dwgetopt.h new file mode 100644 index 00000000..74b9927f --- /dev/null +++ b/thirdparty/dwarf/dwgetopt.h @@ -0,0 +1,85 @@ +/* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/ +/* Modified by David Anderson to work with GNU/Linux and freebsd. + Added {} for clarity. + Switched to standard dwarfdump formatting. + Treatment of : modified so that :: gets dwoptarg NULL + if space follows the letter + (the dwoptarg is set to null). +*/ +/* +* Copyright (c) 1987, 1993, 1994 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +extern int dwopterr; +extern int dwoptind; +extern int dwoptopt; +extern int dwoptreset; +extern char *dwoptarg; + +int dwgetopt(int nargc, char * const nargv[], const char *ostr); + +/* As of October 2017 it seems adviseable to allow + long option names. So based on a reading of + 'man 3 getopt' we reimplement a portion of GNU getopt_long(). + It's a wonderfully sensible design and all the credit + should go to the original designers. + We are not implementing all the features of GNU/Linux + getopt_long(), just the features we wish to use. + Specifically, we require val be 0 and flag + be NULL and ignore those fields. + We do not implement GNU digit_optind at all. + Within these restrictions the interface behaves the same + as GNU getopt_long() (or so it appears from the + getopt documentation: + release 4.04 of the Linux man-pages project, + GETOPT(3), + http://www.kernel.org/doc/man-pages/). + */ + +struct dwoption { + const char *name; + int has_arg; + int *flag; + int val; +}; +#define dwno_argument 0 +#define dwrequired_argument 1 +#define dwoptional_argument 2 + +int dwgetopt_long(int nargc, char *const nargv[], + const char *ostr, + const struct dwoption* longopts, + int *longindex); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/thirdparty/dwarf/gennames.c b/thirdparty/dwarf/gennames.c new file mode 100644 index 00000000..55e2e8b6 --- /dev/null +++ b/thirdparty/dwarf/gennames.c @@ -0,0 +1,632 @@ +/* + Copyright 2009-2010 SN Systems Ltd. All rights reserved. + Portions Copyright 2009-2018 David Anderson. All rights reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + +*/ + +#ifdef _WIN32 +#define _CRT_SECURE_NO_WARNINGS +#endif /* _WIN32 */ + +#include +#include /* For exit() declaration etc. */ +#include /* For errno declaration. */ +#include +#include +#include "dwgetopt.h" +#include "libdwarf_version.h" /* for DW_VERSION_DATE_STR */ + +/* gennames.c + Prints routines to return constant name for the associated value + (such as the TAG name string for a particular tag). + + The input is dwarf.h + For each set of names with a common prefix, we create a routine + to return the name given the value. + Also print header file that gives prototypes of routines. + To handle cases where there are multiple names for a single + value (DW_AT_* has some due to ambiguities in the DWARF2 spec) + we take the first of a given value as the definitive name. + TAGs, Attributes, etc are given distinct checks. + + There are multiple output files as some people find one + form more pleasant than the other. + + The doprinting argument is so that when used by tag_tree.c, + and tag_attr.c that we don't get irritating messages on stderr + when those dwarfdump built-time applications are run. + + Some compilers generate better code for switch statements than + others, so the -s and -t options let the user decide which + is better for their compiler (when building dwarfdump): + a simple switch or code doing binary search. + This choice affects the runtime speed of dwarfdump. */ + +typedef int boolean; +#define TRUE 1 +#define FALSE 0 +#define FAILED 1 + +static void OpenAllFiles(void); +static void WriteFileTrailers(void); +static void CloseAllFiles(void); +static void GenerateInitialFileLines(void); +static void GenerateOneSet(void); +#ifdef TRACE_ARRAY +static void PrintArray(void); +#endif /* TRACE_ARRAY */ +static boolean is_skippable_line(char *pLine); +static void ParseDefinitionsAndWriteOutput(void); + +/* We don't need really long lines: the input file is simple. */ +#define MAX_LINE_SIZE 1000 +/* We don't need a variable array size, it just has to be big enough. */ +#define ARRAY_SIZE 300 + +#define MAX_NAME_LEN 64 + +/* To store entries from dwarf.h */ +typedef struct { + char name[MAX_NAME_LEN]; /* short name */ + unsigned value; /* value */ + /* Original spot in array. Lets us guarantee a stable sort. */ + unsigned original_position; +} array_data; + +/* A group_array is a grouping from dwarf.h. + All the TAGs are one group, all the + FORMs are another group, and so on. */ +static array_data group_array[ARRAY_SIZE]; +static unsigned array_count = 0; + +typedef int (*compfn)(const void *,const void *); +static int Compare(array_data *,array_data *); + +static const char *prefix_root = "DW_"; +static const unsigned prefix_root_len = 3; + +/* f_dwarf_in is the input dwarf.h. The others are output files. */ +static FILE *f_dwarf_in; +static FILE *f_names_h; +static FILE *f_names_c; +static FILE *f_names_enum_h; +static FILE *f_names_new_h; + +/* Size unchecked, but large enough. */ +static char prefix[200] = ""; + +static const char *usage[] = { + "Usage: gennames ", + " -i input-table-path", + " -o output-table-path", + " -s use 'switch' in generation", + " -t use 'tables' in generation", + "", +}; + +static void +print_args(int argc, char *argv[]) +{ + int index; + printf("Arguments: "); + for (index = 1; index < argc; ++index) { + printf("%s ",argv[index]); + } + printf("\n"); +} + + +char *program_name = 0; +static char *input_name = 0; +static char *output_name = 0; +static boolean use_switch = TRUE; +static boolean use_tables = FALSE; + +static void +print_version(const char * name) +{ +#ifdef _DEBUG + const char *acType = "Debug"; +#else + const char *acType = "Release"; +#endif /* _DEBUG */ + + printf("%s [%s %s]\n",name,DW_VERSION_DATE_STR,acType); +} + + +static void +print_usage_message(const char *options[]) +{ + int index; + for (index = 0; *options[index]; ++index) { + printf("%s\n",options[index]); + } +} + + +/* process arguments */ +static void +process_args(int argc, char *argv[]) +{ + int c = 0; + boolean usage_error = FALSE; + + program_name = argv[0]; + + while ((c = dwgetopt(argc, argv, "i:o:st")) != EOF) { + switch (c) { + case 'i': + input_name = dwoptarg; + break; + case 'o': + output_name = dwoptarg; + break; + case 's': + use_switch = TRUE; + use_tables = FALSE; + break; + case 't': + use_switch = FALSE; + use_tables = TRUE; + break; + default: + usage_error = TRUE; + break; + } + } + + if (usage_error || 1 == dwoptind || dwoptind != argc) { + print_usage_message(usage); + exit(FAILED); + } +} + +int +main(int argc,char **argv) +{ + print_version(argv[0]); + print_args(argc,argv); + process_args(argc,argv); + OpenAllFiles(); + GenerateInitialFileLines(); + ParseDefinitionsAndWriteOutput(); + WriteFileTrailers(); + CloseAllFiles(); + return 0; +} + +/* Print the array used to hold the tags, attributes values */ +#ifdef TRACE_ARRAY +static void +PrintArray(void) +{ + int i; + for (i = 0; i < array_count; ++i) { + printf("%d: Name %s_%s, Value 0x%04x\n", + i,prefix, + array[i].name, + array[i].value); + } +} +#endif /* TRACE_ARRAY */ + +/* By including original position we force a stable sort */ +static int +Compare(array_data *elem1,array_data *elem2) +{ + if (elem1->value < elem2->value) { + return -1; + } + if (elem1->value > elem2->value) { + return 1; + } + if (elem1->original_position < elem2->original_position) { + return -1; + } + if (elem1->original_position > elem2->original_position) { + return 1; + } + return 0; +} + +static FILE * +open_path(const char *base, const char *file, const char *direction) +{ + FILE *f = 0; + /* POSIX PATH_MAX would suffice, normally stdio BUFSIZ is larger + than PATH_MAX */ + static char path_name[BUFSIZ]; + + /* 2 == space for / and NUL */ + size_t netlen = strlen(file) +strlen(base) + 2; + + if (netlen >= BUFSIZ) { + printf("Error opening '%s/%s', name too long\n",base,file); + exit(1); + } + + strcpy(path_name,base); + strcat(path_name,"/"); + strcat(path_name,file); + + f = fopen(path_name,direction); + if (!f) { + printf("Error opening '%s'\n",path_name); + exit(1); + } + return f; +} + +/* Open files and write the basic headers */ +static void +OpenAllFiles(void) +{ + const char *dwarf_h = "dwarf.h"; + const char *names_h = "dwarf_names.h"; + const char *names_c = "dwarf_names.c"; + const char *names_enum_h = "dwarf_names_enum.h"; + const char *names_new_h = "dwarf_names_new.h"; + + f_dwarf_in = open_path(input_name,dwarf_h,"r"); + f_names_enum_h = open_path(output_name,names_enum_h,"w"); + f_names_new_h = open_path(output_name,names_new_h,"w"); + f_names_h = open_path(output_name,names_h,"w"); + f_names_c = open_path(output_name,names_c,"w"); +} + +static void +GenerateInitialFileLines(void) +{ + /* Generate entries for 'dwarf_names_enum.h' */ + fprintf(f_names_enum_h,"/* Automatically generated, do not edit. */\n"); + fprintf(f_names_enum_h,"/* Generated sourcedate %s */\n", + DW_VERSION_DATE_STR); + fprintf(f_names_enum_h,"\n/* BEGIN FILE */\n\n"); + fprintf(f_names_enum_h,"#ifndef __DWARF_NAMES_ENUM_H__\n"); + fprintf(f_names_enum_h,"#define __DWARF_NAMES_ENUM_H__\n"); + + /* Generate entries for 'dwarf_names_new.h' */ + fprintf(f_names_new_h,"/* Automatically generated, do not edit. */\n"); + fprintf(f_names_new_h,"/* Generated sourcedate %s */\n", + DW_VERSION_DATE_STR); + fprintf(f_names_new_h,"\n/* BEGIN FILE */\n\n"); + fprintf(f_names_new_h,"/* define DWARF_PRINT_PREFIX before this\n"); + fprintf(f_names_new_h," point if you wish to. */\n"); + fprintf(f_names_new_h,"#ifndef DWARF_PRINT_PREFIX\n"); + fprintf(f_names_new_h,"#define DWARF_PRINT_PREFIX dwarf_\n"); + fprintf(f_names_new_h,"#endif\n"); + fprintf(f_names_new_h,"#define dw_glue(x,y) x##y\n"); + fprintf(f_names_new_h,"#define dw_glue2(x,y) dw_glue(x,y)\n"); + fprintf(f_names_new_h,"#define DWPREFIX(x) dw_glue2(DWARF_PRINT_PREFIX,x)\n"); + + /* Generate entries for 'dwarf_names.h' */ + fprintf(f_names_h,"/* Generated routines, do not edit. */\n"); + fprintf(f_names_h,"/* Generated sourcedate %s */\n", + DW_VERSION_DATE_STR); + fprintf(f_names_h,"\n/* BEGIN FILE */\n\n"); + + fprintf(f_names_h,"#ifndef DWARF_NAMES_H\n"); + fprintf(f_names_h,"#define DWARF_NAMES_H\n\n"); + fprintf(f_names_h,"#ifdef __cplusplus\n"); + fprintf(f_names_h,"extern \"C\" {\n"); + fprintf(f_names_h,"#endif /* __cplusplus */\n\n"); + + /* Generate entries for 'dwarf_names.c' */ + fprintf(f_names_c,"/* Generated routines, do not edit. */\n"); + fprintf(f_names_c,"/* Generated sourcedate %s */\n", + DW_VERSION_DATE_STR); + fprintf(f_names_c,"\n/* BEGIN FILE */\n\n"); + fprintf(f_names_c,"#include \"dwarf.h\"\n\n"); + fprintf(f_names_c,"#include \"libdwarf.h\"\n\n"); + + if (use_tables) { + fprintf(f_names_c,"typedef struct Names_Data {\n"); + fprintf(f_names_c," const char *l_name; \n"); + fprintf(f_names_c," unsigned value; \n"); + fprintf(f_names_c,"} Names_Data;\n\n"); + + /* Generate code to find an entry */ + fprintf(f_names_c,"/* Use standard binary search to get entry */\n"); + fprintf(f_names_c,"static int\nfind_entry(Names_Data *table," + "const int last,unsigned value, const char **s_out)\n"); + fprintf(f_names_c,"{\n"); + fprintf(f_names_c," int low = 0;\n"); + fprintf(f_names_c," int high = last;\n"); + fprintf(f_names_c," int mid;\n"); + fprintf(f_names_c," unsigned maxval = table[last-1].value;\n"); + fprintf(f_names_c,"\n"); + fprintf(f_names_c," if (value > maxval) {\n"); + fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); + fprintf(f_names_c," }\n"); + fprintf(f_names_c," while (low < high) {\n"); + fprintf(f_names_c," mid = low + ((high - low) / 2);\n"); + fprintf(f_names_c," if(mid == last) {\n"); + fprintf(f_names_c," break;\n"); + fprintf(f_names_c," }\n"); + fprintf(f_names_c," if (table[mid].value < value) {\n"); + fprintf(f_names_c," low = mid + 1;\n"); + fprintf(f_names_c," }\n"); + fprintf(f_names_c," else {\n"); + fprintf(f_names_c," high = mid;\n"); + fprintf(f_names_c," }\n"); + fprintf(f_names_c," }\n"); + fprintf(f_names_c,"\n"); + fprintf(f_names_c," if (low < last && table[low].value == value) {\n"); + fprintf(f_names_c," /* Found: low is the entry */\n"); + fprintf(f_names_c," *s_out = table[low].l_name;\n"); + fprintf(f_names_c," return DW_DLV_OK;\n"); + fprintf(f_names_c," }\n"); + fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); + fprintf(f_names_c,"}\n"); + fprintf(f_names_c,"\n"); + } +} + +/* Close files and write basic trailers */ +static void +WriteFileTrailers(void) +{ + /* Generate entries for 'dwarf_names_enum.h' */ + fprintf(f_names_enum_h,"#endif /* __DWARF_NAMES_ENUM_H__ */\n"); + fprintf(f_names_enum_h,"\n/* END FILE */\n"); + + /* Generate entries for 'dwarf_names_new.h' */ + fprintf(f_names_new_h,"\n/* END FILE */\n"); + + /* Generate entries for 'dwarf_names.h' */ + + fprintf(f_names_h,"\n#ifdef __cplusplus\n"); + fprintf(f_names_h,"}\n"); + fprintf(f_names_h,"#endif /* __cplusplus */\n\n"); + fprintf(f_names_h,"#endif /* DWARF_NAMES_H */\n"); + fprintf(f_names_h,"\n/* END FILE */\n"); + + /* Generate entries for 'dwarf_names.c' */ + fprintf(f_names_c,"\n/* END FILE */\n"); +} + +static void +CloseAllFiles(void) +{ + fclose(f_dwarf_in); + fclose(f_names_enum_h); + fclose(f_names_new_h); + fclose(f_names_h); + fclose(f_names_c); +} + +/* Write the table and code for a common set of names */ +static void +GenerateOneSet(void) +{ + unsigned u; + unsigned prev_value = 0; + size_t len; + char *prefix_id = prefix + prefix_root_len; + unsigned actual_array_count = 0; + +#ifdef TRACE_ARRAY + printf("List before sorting:\n"); + PrintArray(); +#endif /* TRACE_ARRAY */ + + /* Sort the array, because the values in 'libdwarf.h' are not in + ascending order; if we use '-t' we must be sure the values are + sorted, for the binary search to work properly. + We want a stable sort, hence mergesort. */ + qsort((void *)&group_array,array_count,sizeof(array_data),(compfn)Compare); + +#ifdef TRACE_ARRAY + printf("\nList after sorting:\n"); + PrintArray(); +#endif /* TRACE_ARRAY */ + + /* Generate entries for 'dwarf_names_enum.h' */ + fprintf(f_names_enum_h,"\nenum Dwarf_%s_e {\n",prefix_id); + + /* Generate entries for 'dwarf_names_new.h' */ + fprintf(f_names_new_h,"int DWPREFIX(get_%s_name) (unsigned int, const char **);\n",prefix_id); + + /* Generate entries for 'dwarf_names.h' and libdwarf.h */ + fprintf(f_names_h,"extern int dwarf_get_%s_name(unsigned int /*val_in*/, const char ** /*s_out */);\n",prefix_id); + + /* Generate code for 'dwarf_names.c' */ + fprintf(f_names_c,"/* ARGSUSED */\n"); + fprintf(f_names_c,"int\n"); + fprintf(f_names_c,"dwarf_get_%s_name (unsigned int val,const char ** s_out)\n",prefix_id); + fprintf(f_names_c,"{\n"); + if (use_tables) { + fprintf(f_names_c," static Names_Data Dwarf_%s_n[] = {\n",prefix_id); + } else { + fprintf(f_names_c," switch (val) {\n"); + } + + for (u = 0; u < array_count; ++u) { + /* Check if value already dumped */ + if (u > 0 && group_array[u].value == prev_value) { + fprintf(f_names_c, + " /* Skipping alternate spelling of value 0x%x. %s_%s */\n", + (unsigned)prev_value, + prefix, + group_array[u].name); + continue; + } + prev_value = group_array[u].value; + + /* Generate entries for 'dwarf_names_enum.h'. + The 39 just makes nice formatting in the output. */ + len = 39 - strlen(prefix); + fprintf(f_names_enum_h," %s_%-*s = 0x%04x", + prefix,(int)len,group_array[u].name,group_array[u].value); + fprintf(f_names_enum_h,(u + 1 < array_count) ? ",\n" : "\n"); + + /* Generate entries for 'dwarf_names.c' */ + if (use_tables) { + fprintf(f_names_c," {/* %3u */ \"%s_%s\", ", + actual_array_count,prefix,group_array[u].name); + fprintf(f_names_c," %s_%s}", prefix,group_array[u].name); + fprintf(f_names_c,(u + 1 < array_count) ? ",\n" : "\n"); + } else { + fprintf(f_names_c," case %s_%s:\n", + prefix,group_array[u].name); + fprintf(f_names_c," *s_out = \"%s_%s\";\n", + prefix,group_array[u].name); + fprintf(f_names_c," return DW_DLV_OK;\n"); + } + ++actual_array_count; + } + + /* Closing entries for 'dwarf_names_enum.h' */ + fprintf(f_names_enum_h,"};\n"); + + if (use_tables) { + /* Closing entries for 'dwarf_names.c' */ + fprintf(f_names_c," };\n\n"); + + /* Closing code for 'dwarf_names.c' */ + fprintf(f_names_c," const int last_entry = %d;\n",actual_array_count); + fprintf(f_names_c," /* find the entry */\n"); + fprintf(f_names_c," int r = find_entry(Dwarf_%s_n,last_entry,val,s_out);\n",prefix_id); + fprintf(f_names_c," return r;\n"); + fprintf(f_names_c,"}\n"); + } else { + fprintf(f_names_c," }\n"); + fprintf(f_names_c," return DW_DLV_NO_ENTRY;\n"); + fprintf(f_names_c,"}\n"); + } + + /* Mark the group_array as empty */ + array_count = 0; +} + +/* Detect empty lines (and other lines we do not want to read) */ +static boolean +is_skippable_line(char *pLine) +{ + boolean empty = TRUE; + + for (; *pLine && empty; ++pLine) { + empty = isspace(*pLine); + } + return empty; +} + +static void +safe_strncpy(char *out, unsigned out_len, + char *in,unsigned in_len) +{ + if(in_len >= out_len) { + fprintf(stderr,"Impossible input line from dwarf.h. Giving up. \n"); + fprintf(stderr,"Length %u is too large, limited to %u.\n", + in_len,out_len); + exit(1); + } + strncpy(out,in,in_len); +} + + +/* Parse the 'dwarf.h' file and generate the tables */ +static void +ParseDefinitionsAndWriteOutput(void) +{ + char new_prefix[64]; + char *second_underscore = NULL; + char type[1000]; + char name[1000]; + char value[1000]; + char extra[1000]; + char line_in[MAX_LINE_SIZE]; + int pending = FALSE; + int prefix_len = 0; + + /* Process each line from 'dwarf.h' */ + while (!feof(f_dwarf_in)) { + /* errno is cleared here so printing errno after + the fgets is showing errno as set by fgets. */ + char *fgbad = 0; + errno = 0; + fgbad = fgets(line_in,sizeof(line_in),f_dwarf_in); + if(!fgbad) { + if(feof(f_dwarf_in)) { + break; + } + /* Is error. errno must be set. */ + fprintf(stderr,"Error reading dwarf.h!. Errno %d\n",errno); + exit(1); + } + if (is_skippable_line(line_in)) { + continue; + } + sscanf(line_in,"%s %s %s %s",type,name,value,extra); + if (strcmp(type,"#define") || + strncmp(name,prefix_root,prefix_root_len)) { + continue; + } + + second_underscore = strchr(name + prefix_root_len,'_'); + prefix_len = (int)(second_underscore - name); + safe_strncpy(new_prefix,sizeof(new_prefix),name,prefix_len); + new_prefix[prefix_len] = 0; + + /* Check for new prefix set */ + if (strcmp(prefix,new_prefix)) { + if (pending) { + /* Generate current prefix set */ + GenerateOneSet(); + } + pending = TRUE; + strcpy(prefix,new_prefix); + } + + /* Be sure we have a valid entry */ + if (array_count >= ARRAY_SIZE) { + printf("Too many entries for current group_array size of %d",ARRAY_SIZE); + exit(1); + } + + /* Move past the second underscore */ + ++second_underscore; + + { + unsigned long v = strtoul(value,NULL,16); + /* Some values are duplicated, that is ok. + After the sort we will weed out the duplicate values, + see GenerateOneSet(). */ + /* Record current entry */ + if (strlen(second_underscore) >= MAX_NAME_LEN) { + printf("Too long a name %s for max len %d\n", + second_underscore,MAX_NAME_LEN); + exit(1); + } + strcpy(group_array[array_count].name,second_underscore); + group_array[array_count].value = v; + group_array[array_count].original_position = array_count; + ++array_count; + } + } + if (pending) { + /* Generate final prefix set */ + GenerateOneSet(); + } +} diff --git a/thirdparty/dwarf/libdwarf.h b/thirdparty/dwarf/libdwarf.h index 4bbfd5a6..454f91b4 100644 --- a/thirdparty/dwarf/libdwarf.h +++ b/thirdparty/dwarf/libdwarf.h @@ -2,7 +2,7 @@ Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2008-2013 David Anderson. All rights reserved. + Portions Copyright 2008-2018 David Anderson. All rights reserved. Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved. Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved. @@ -70,60 +70,50 @@ typedef struct Elf* dwarf_elf_handle; */ /*#define DW_PR_XZEROS "" */ #define DW_PR_XZEROS "08" -#if (_MIPS_SZLONG == 64) -/* Special case for MIPS, so -64 (LP64) build gets simple -long-. - Non-MIPS LP64 or ILP64 environments should probably ensure - _MIPS_SZLONG set to 64 everywhere this header is #included. -*/ -typedef int Dwarf_Bool; /* boolean type */ -typedef unsigned long Dwarf_Off; /* 4 or 8 byte file offset */ -typedef unsigned long Dwarf_Unsigned; /* 4 or 8 byte unsigned value */ -typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ -typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ -typedef signed long Dwarf_Signed; /* 4 or 8 byte signed value */ -typedef unsigned long Dwarf_Addr; /* target memory address */ -#define DW_PR_DUx "lx" -#define DW_PR_DSx "lx" -#define DW_PR_DUu "lu" -#define DW_PR_DSd "ld" - -#else /* 32-bit */ -/* This is for ILP32, allowing i/o of 64bit dwarf info. - Also should be fine for LP64 and ILP64 cases. -*/ -typedef int Dwarf_Bool; /* boolean type */ -typedef unsigned long long Dwarf_Off; /* 8 byte file offset */ -typedef unsigned long long Dwarf_Unsigned; /* 8 byte unsigned value*/ -typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ -typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ -typedef signed long long Dwarf_Signed; /* 8 byte signed value */ -typedef unsigned long long Dwarf_Addr; /* target memory address */ -#define DW_PR_DUx "llx" -#define DW_PR_DSx "llx" -#define DW_PR_DUu "llu" -#define DW_PR_DSd "lld" -#endif -#ifdef HAVE_NONSTANDARD_PRINTF_64_FORMAT -/* Windows does not use std C formatting, so allow it. */ -#undef DW_PR_DUx -#undef DW_PR_DSx -#undef DW_PR_DUu -#undef DW_PR_DSd -#define DW_PR_DUx "I64x" -#define DW_PR_DSx "I64x" -#define DW_PR_DUu "I64u" -#define DW_PR_DSd "I64d" -#endif /* HAVE_NONSTANDARD_FORMAT */ + +typedef unsigned long long Dwarf_Unsigned; +typedef signed long long Dwarf_Signed; +typedef unsigned long long Dwarf_Off; +typedef unsigned long long Dwarf_Addr; +typedef int Dwarf_Bool; /* boolean type */ +typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */ +typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */ +/* If sizeof(Dwarf_Half) is greater than 2 + we believe libdwarf still works properly. */ + +#if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT) +#define DW_PR_DUx "I64x" +#define DW_PR_DSx "I64x" +#define DW_PR_DUu "I64u" +#define DW_PR_DSd "I64d" +#else +#define DW_PR_DUx "llx" +#define DW_PR_DSx "llx" +#define DW_PR_DUu "llu" +#define DW_PR_DSd "lld" +#endif /* DW_PR defines */ typedef void* Dwarf_Ptr; /* host machine pointer */ -/* Used for DW_FORM_ref_sig8 and DW_AT_dwo_id. +/* DWARF5: a container for a DW_FORM_data16 data item. + We have no integer types suitable so this special + struct is used instead. It is up to consumers/producers + to deal with the contents. + New October 18, 2017 . */ +typedef struct Dwarf_Form_Data16_s { + unsigned char fd_data[16]; +} Dwarf_Form_Data16; + + + +/* Used for signatures where ever they appear. It is not a string, it is 8 bytes of a signature one would use to find a type unit. See dwarf_formsig8() Sometimes it is used in calculations as - Dwarf_Unsigned, but that is hidden in libdwarf. + Dwarf_Unsigned, but that is done inside libdwarf + and the endianness question makes it a bit sketchy. */ struct Dwarf_Sig8_s { char signature[8]; @@ -169,6 +159,12 @@ typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context; +/* NEW September 2016. Allows easy access to DW_AT_discr_list + array of discriminant values. Input in blockpointer + is a block with a list of uleb or sleb numbers + (all one or the other, lebunsignedflag instructs + how to read the leb values properly) */ +typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head; /* Location record. Records up to 2 operand values. Not usable with DWARF5 or DWARF4 with location @@ -247,20 +243,6 @@ typedef struct { Dwarf_Off fp_instr_offset; } Dwarf_Frame_Op; /* DWARF2 */ -typedef struct { - Dwarf_Small fp_base_op; - Dwarf_Small fp_extended_op; - Dwarf_Half fp_register; - - /* Value may be signed, depends on op. - Any applicable data_alignment_factor has - not been applied, this is the raw offset. */ - Dwarf_Unsigned fp_offset_or_block_len; - Dwarf_Small *fp_expr_block; - - Dwarf_Off fp_instr_offset; -} Dwarf_Frame_Op3; /* DWARF3 and DWARF2 compatible */ - /* ***IMPORTANT NOTE, TARGET DEPENDENCY **** DW_REG_TABLE_SIZE must be at least as large as the number of registers @@ -568,6 +550,9 @@ struct Dwarf_Line_Context_s; typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context; struct Dwarf_Macro_Context_s; typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context; +struct Dwarf_Dnames_Head_s; +typedef struct Dwarf_Dnames_Head_s* Dwarf_Dnames_Head; + /* Opaque types for Producer Library. */ @@ -601,6 +586,12 @@ Projects using dwarf_elf_init() or dwarf_init() can ignore the Dwarf_Obj_Access* structures entirely as all these details are completed for you. +As of March 2017 additional +functions dwarf_elf_init_b +and dwarf_init_b +and dwarf_object_init_b +add a groupnumber argument so DWARF5 +split-dwarf sections can be accessed. */ typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface; @@ -780,13 +771,13 @@ struct Dwarf_Obj_Access_Methods_s { /* These structures are allocated and deallocated by your code when you are using the libdwarf Object File Interface - [dwarf_object_init() and dwarf_object_finish()] directly. - dwarf_object_finish() does not free + [dwarf_object_init and dwarf_object_finish)] directly. + dwarf_object_finish) does not free struct Dwarf_Obj_Access_Interface_s or its content. (libdwarf does record a pointer to this struct: you must ensure that pointer remains valid for as long as a libdwarf instance is open (meaning - after dwarf_init() and before dwarf_finish()). + after dwarf_init) and before dwarf_finish)). If you are reading Elf objects and libelf use dwarf_init() or dwarf_elf_init() which take care of these details. @@ -843,6 +834,10 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */ #define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */ #define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */ +/* 0x3d (61) is for libdwarf internal use. */ +#define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */ +#define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */ +#define DW_DLA_STR_OFFSETS 0x40 /* struct Dwarf_Str_Offsets_Table_s */ /* The augmenter string for CIE */ #define DW_CIE_AUGMENTER_STRING_V0 "z" @@ -853,7 +848,7 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLC_WRITE 1 /* write only access */ #define DW_DLC_RDWR 2 /* read/write access NOT SUPPORTED*/ -/* dwarf_producer_init*() access flag modifiers +/* dwarf_producer_init* access flag modifiers No longer depends on compile-time settings for how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64. Historic versions. One of @@ -874,7 +869,7 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLC_SIZE_32 0x20000000 /* 32-bit address-size target */ #define DW_DLC_OFFSET_SIZE_64 0x10000000 /* 64-bit offset-size DWARF */ -/* dwarf_producer_init*() access flag modifiers +/* dwarf_producer_init* access flag modifiers Some new April 2014. If DW_DLC_STREAM_RELOCATIONS is set the DW_DLC_ISA_* flags are ignored. See the Dwarf_Rel_Type enum. @@ -904,7 +899,7 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 /* Little endian target */ -/* dwarf_pcline() slide arguments +/* dwarf_pcline function, slide arguments */ #define DW_DLS_BACKWARD -1 /* slide backward to find line */ #define DW_DLS_NOSLIDE 0 /* match exactly without sliding */ @@ -992,7 +987,7 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLE_CIE_OFFS_ALLOC 75 #define DW_DLE_WRONG_ADDRESS 76 #define DW_DLE_EXTRA_NEIGHBORS 77 -#define DW_DLE_WRONG_TAG 78 +#define DW_DLE_WRONG_TAG 78 #define DW_DLE_DIE_ALLOC 79 #define DW_DLE_PARENT_EXISTS 80 #define DW_DLE_DBG_NULL 81 @@ -1187,8 +1182,7 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLE_XU_NAME_COL_ERROR 270 #define DW_DLE_XU_HASH_ROW_ERROR 271 #define DW_DLE_XU_HASH_INDEX_ERROR 272 - -/* DW_DLE_FAILSAFE_ERRVAL is an aid when out of memory. */ +/* ..._FAILSAFE_ERRVAL is an aid when out of memory. */ #define DW_DLE_FAILSAFE_ERRVAL 273 #define DW_DLE_ARANGE_ERROR 274 #define DW_DLE_PUBNAMES_ERROR 275 @@ -1264,9 +1258,110 @@ struct Dwarf_Obj_Access_Interface_s { #define DW_DLE_ERRONEOUS_XU_INDEX_SECTION 345 #define DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH 346 #define DW_DLE_COMPRESSED_EMPTY_SECTION 347 +#define DW_DLE_SIZE_WRAPAROUND 348 +#define DW_DLE_ILLOGICAL_TSEARCH 349 +#define DW_DLE_BAD_STRING_FORM 350 +#define DW_DLE_DEBUGSTR_ERROR 351 +#define DW_DLE_DEBUGSTR_UNEXPECTED_REL 352 +#define DW_DLE_DISCR_ARRAY_ERROR 353 +#define DW_DLE_LEB_OUT_ERROR 354 +#define DW_DLE_SIBLING_LIST_IMPROPER 355 +#define DW_DLE_LOCLIST_OFFSET_BAD 356 +#define DW_DLE_LINE_TABLE_BAD 357 +#define DW_DLE_DEBUG_LOClISTS_DUPLICATE 358 +#define DW_DLE_DEBUG_RNGLISTS_DUPLICATE 359 +#define DW_DLE_ABBREV_OFF_END 360 +#define DW_DLE_FORM_STRING_BAD_STRING 361 +#define DW_DLE_AUGMENTATION_STRING_OFF_END 362 +#define DW_DLE_STRING_OFF_END_PUBNAMES_LIKE 363 +#define DW_DLE_LINE_STRING_BAD 364 +#define DW_DLE_DEFINE_FILE_STRING_BAD 365 +#define DW_DLE_MACRO_STRING_BAD 366 +#define DW_DLE_MACINFO_STRING_BAD 367 +#define DW_DLE_ZLIB_UNCOMPRESS_ERROR 368 +#define DW_DLE_IMPROPER_DWO_ID 369 +#define DW_DLE_GROUPNUMBER_ERROR 370 +#define DW_DLE_ADDRESS_SIZE_ZERO 371 +#define DW_DLE_DEBUG_NAMES_HEADER_ERROR 372 +#define DW_DLE_DEBUG_NAMES_AUG_STRING_ERROR 373 +#define DW_DLE_DEBUG_NAMES_PAD_NON_ZERO 374 +#define DW_DLE_DEBUG_NAMES_OFF_END 375 +#define DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW 376 +#define DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION 377 +#define DW_DLE_DEBUG_NAMES_NULL_POINTER 378 +#define DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG 379 +#define DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET 380 +#define DW_DLE_DEBUG_NAMES_UNHANDLED_FORM 381 +#define DW_DLE_LNCT_CODE_UNKNOWN 382 +#define DW_DLE_LNCT_FORM_CODE_NOT_HANDLED 383 +#define DW_DLE_LINE_HEADER_LENGTH_BOTCH 384 +#define DW_DLE_STRING_HASHTAB_IDENTITY_ERROR 385 +#define DW_DLE_UNIT_TYPE_NOT_HANDLED 386 +#define DW_DLE_GROUP_MAP_ALLOC 387 +#define DW_DLE_GROUP_MAP_DUPLICATE 388 +#define DW_DLE_GROUP_COUNT_ERROR 389 +#define DW_DLE_GROUP_INTERNAL_ERROR 390 +#define DW_DLE_GROUP_LOAD_ERROR 391 +#define DW_DLE_GROUP_LOAD_READ_ERROR 392 +#define DW_DLE_AUG_DATA_LENGTH_BAD 393 +#define DW_DLE_ABBREV_MISSING 394 +#define DW_DLE_NO_TAG_FOR_DIE 395 +#define DW_DLE_LOWPC_WRONG_CLASS 396 +#define DW_DLE_HIGHPC_WRONG_FORM 397 +#define DW_DLE_STR_OFFSETS_BASE_WRONG_FORM 398 +#define DW_DLE_DATA16_OUTSIDE_SECTION 399 +#define DW_DLE_LNCT_MD5_WRONG_FORM 400 +#define DW_DLE_LINE_HEADER_CORRUPT 401 +#define DW_DLE_STR_OFFSETS_NULLARGUMENT 402 +#define DW_DLE_STR_OFFSETS_NULL_DBG 403 +#define DW_DLE_STR_OFFSETS_NO_MAGIC 404 +#define DW_DLE_STR_OFFSETS_ARRAY_SIZE 405 +#define DW_DLE_STR_OFFSETS_VERSION_WRONG 406 +#define DW_DLE_STR_OFFSETS_ARRAY_INDEX_WRONG 407 +#define DW_DLE_STR_OFFSETS_EXTRA_BYTES 408 +#define DW_DLE_DUP_ATTR_ON_DIE 409 +#define DW_DLE_SECTION_NAME_BIG 410 +#define DW_DLE_FILE_UNAVAILABLE 411 +#define DW_DLE_FILE_WRONG_TYPE 412 +#define DW_DLE_SIBLING_OFFSET_WRONG 413 +#define DW_DLE_OPEN_FAIL 414 +#define DW_DLE_OFFSET_SIZE 415 +#define DW_DLE_MACH_O_SEGOFFSET_BAD 416 +#define DW_DLE_FILE_OFFSET_BAD 417 +#define DW_DLE_SEEK_ERROR 418 +#define DW_DLE_READ_ERROR 419 +#define DW_DLE_ELF_CLASS_BAD 420 +#define DW_DLE_ELF_ENDIAN_BAD 421 +#define DW_DLE_ELF_VERSION_BAD 422 +#define DW_DLE_FILE_TOO_SMALL 423 +#define DW_DLE_PATH_SIZE_TOO_SMALL 424 +#define DW_DLE_BAD_TYPE_SIZE 425 +#define DW_DLE_PE_SIZE_SMALL 426 +#define DW_DLE_PE_OFFSET_BAD 427 +#define DW_DLE_PE_STRING_TOO_LONG 428 +#define DW_DLE_IMAGE_FILE_UNKNOWN_TYPE 429 +#define DW_DLE_LINE_TABLE_LINENO_ERROR 430 +#define DW_DLE_PRODUCER_CODE_NOT_AVAILABLE 431 +#define DW_DLE_NO_ELF_SUPPORT 432 +#define DW_DLE_NO_STREAM_RELOC_SUPPORT 433 +#define DW_DLE_RETURN_EMPTY_PUBNAMES_ERROR 434 +#define DW_DLE_SECTION_SIZE_ERROR 435 +#define DW_DLE_INTERNAL_NULL_POINTER 436 +#define DW_DLE_SECTION_STRING_OFFSET_BAD 437 +#define DW_DLE_SECTION_INDEX_BAD 438 +#define DW_DLE_INTEGER_TOO_SMALL 439 +#define DW_DLE_ELF_SECTION_LINK_ERROR 440 +#define DW_DLE_ELF_SECTION_GROUP_ERROR 441 +#define DW_DLE_ELF_SECTION_COUNT_MISMATCH 442 +#define DW_DLE_ELF_STRING_SECTION_MISSING 443 +#define DW_DLE_SEEK_OFF_END 444 +#define DW_DLE_READ_OFF_END 445 +#define DW_DLE_ELF_SECTION_ERROR 446 +#define DW_DLE_ELF_STRING_SECTION_ERROR 447 + + /* LAST MUST EQUAL LAST ERROR NUMBER */ +#define DW_DLE_LAST 447 - /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ -#define DW_DLE_LAST 347 #define DW_DLE_LO_USER 0x10000 /* Taken as meaning 'undefined value', this is not @@ -1322,22 +1417,78 @@ out what form-class it is. DW_FORM_CLASS_FRAMEPTR is MIPS/IRIX only, and refers to the DW_AT_MIPS_fde attribute (a reference to the .debug_frame section). + + DWARF5: + DW_FORM_CLASS_LOCLISTSPTR is like DW_FORM_CLASS_LOCLIST + except that LOCLISTSPTR is aways a section offset, + never an index, and LOCLISTSPTR is only referenced + by DW_AT_loclists_base. + Note DW_FORM_CLASS_LOCLISTSPTR spelling to distinguish + from DW_FORM_CLASS_LOCLISTPTR. + + DWARF5: + DW_FORM_CLASS_RNGLISTSPTR is like DW_FORM_CLASS_RNGLIST + except that RNGLISTSPTR is aways a section offset, + never an index. DW_FORM_CLASS_RNGLISTSPTR is only + referenced by DW_AT_rnglists_base. */ enum Dwarf_Form_Class { DW_FORM_CLASS_UNKNOWN, DW_FORM_CLASS_ADDRESS, DW_FORM_CLASS_BLOCK, DW_FORM_CLASS_CONSTANT, DW_FORM_CLASS_EXPRLOC, DW_FORM_CLASS_FLAG, - DW_FORM_CLASS_LINEPTR, DW_FORM_CLASS_LOCLISTPTR, - DW_FORM_CLASS_MACPTR, DW_FORM_CLASS_RANGELISTPTR, - DW_FORM_CLASS_REFERENCE, DW_FORM_CLASS_STRING, - DW_FORM_CLASS_FRAMEPTR + DW_FORM_CLASS_LINEPTR, + DW_FORM_CLASS_LOCLISTPTR, /* DWARF2,3,4 only */ + DW_FORM_CLASS_MACPTR, /* DWARF2,3,4 only */ + DW_FORM_CLASS_RANGELISTPTR, /* DWARF2,3,4 only */ + DW_FORM_CLASS_REFERENCE, + DW_FORM_CLASS_STRING, + DW_FORM_CLASS_FRAMEPTR, /* MIPS/IRIX DWARF2 only */ + DW_FORM_CLASS_MACROPTR, /* DWARF5 */ + DW_FORM_CLASS_ADDRPTR, /* DWARF5 */ + DW_FORM_CLASS_LOCLIST, /* DWARF5 */ + DW_FORM_CLASS_LOCLISTSPTR, /* DWARF5 */ + DW_FORM_CLASS_RNGLIST, /* DWARF5 */ + DW_FORM_CLASS_RNGLISTSPTR, /* DWARF5 */ + DW_FORM_CLASS_STROFFSETSPTR /* DWARF5 */ }; +/* These support opening DWARF5 split dwarf objects. */ +#define DW_GROUPNUMBER_ANY 0 +#define DW_GROUPNUMBER_BASE 1 +#define DW_GROUPNUMBER_DWO 2 /*===========================================================================*/ /* Dwarf consumer interface initialization and termination operations */ -/* Initialization based on Unix open fd (using libelf internally). */ +/* Initialization based on path. This is new October 2018. + The path actually used is copied to true_path_out + and in the case of MacOS dSYM may not match path. + So consider the value put in true_path_out the + actual file name. reserved1,2,3 should all be passed + as zero. */ +int dwarf_init_path(const char * /*path*/, + char * /*true_path_out_buffer*/, + unsigned /*true_path_bufferlen*/, + Dwarf_Unsigned /*access*/, + unsigned /*groupnumber*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Debug* /*dbg*/, + const char * /* reserved1 */, + Dwarf_Unsigned /* reserved2 */, + Dwarf_Unsigned * /* reserved3 */, + Dwarf_Error* /*error*/); + +/* Initialization based on Unix(etc) open fd */ +/* New March 2017 */ +int dwarf_init_b(int /*fd*/, + Dwarf_Unsigned /*access*/, + unsigned /*groupnumber*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Debug* /*dbg*/, + Dwarf_Error* /*error*/); + int dwarf_init(int /*fd*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, @@ -1345,7 +1496,18 @@ int dwarf_init(int /*fd*/, Dwarf_Debug* /*dbg*/, Dwarf_Error* /*error*/); -/* Initialization based on libelf/sgi-fastlibelf open pointer. */ +/* The dwarf_elf_init* functions continue to be supported, + but should be considered deprecated as they can ONLY + be used on Elf files. */ +/* Initialization based on libelf/sgi-fastlibelf open pointer. */ +/* New March 2017 */ +int dwarf_elf_init_b(dwarf_elf_handle /*elf*/, + Dwarf_Unsigned /*access*/, + unsigned /*group_number*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + Dwarf_Debug* /*dbg*/, + Dwarf_Error* /*error*/); int dwarf_elf_init(dwarf_elf_handle /*elf*/, Dwarf_Unsigned /*access*/, Dwarf_Handler /*errhand*/, @@ -1363,6 +1525,14 @@ int dwarf_get_elf(Dwarf_Debug /*dbg*/, int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); +/* NEW March 2017. */ +int dwarf_object_init_b(Dwarf_Obj_Access_Interface* /*obj*/, + Dwarf_Handler /*errhand*/, + Dwarf_Ptr /*errarg*/, + unsigned /*groupnumber*/, + Dwarf_Debug* /*dbg*/, + Dwarf_Error* /*error*/); + int dwarf_object_init(Dwarf_Obj_Access_Interface* /*obj*/, Dwarf_Handler /*errhand*/, Dwarf_Ptr /*errarg*/, @@ -1384,18 +1554,28 @@ int dwarf_object_finish(Dwarf_Debug /*dbg*/, /* Section name access. Because sections might now end with .dwo or be .zdebug or might not. */ -int -dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, +int dwarf_get_die_section_name(Dwarf_Debug /*dbg*/, Dwarf_Bool /*is_info*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); -int -dwarf_get_die_section_name_b(Dwarf_Die /*die*/, + +int dwarf_get_die_section_name_b(Dwarf_Die /*die*/, const char ** /*sec_name*/, Dwarf_Error * /*error*/); +int dwarf_get_real_section_name(Dwarf_Debug /*dbg*/, + const char * /*std_section_name*/, + const char ** /*actual_sec_name_out*/, + Dwarf_Small * /*marked_compressed*/, /* .zdebug... */ + Dwarf_Small * /*marked_zlib_compressed */, /* ZLIB string */ + Dwarf_Small * /*marked_shf_compressed*/, /* SHF_COMPRESSED */ + Dwarf_Unsigned * /*compressed_length*/, + Dwarf_Unsigned * /*uncompressed_length*/, + Dwarf_Error * /*error*/); + -/* dwarf_next_cu_header_d() traverses debug_types CU headers. + +/* dwarf_next_cu_header_d traverses debug_types CU headers. New in May, 2015. */ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, @@ -1413,7 +1593,7 @@ int dwarf_next_cu_header_d(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/); /* Die traversal operations. - dwarf_next_cu_header_b() traverses debug_info CU headers. + dwarf_next_cu_header_b traverses debug_info CU headers. Obsolete but supported. */ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, @@ -1426,7 +1606,7 @@ int dwarf_next_cu_header_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned* /*next_cu_header_offset*/, Dwarf_Error* /*error*/); -/* dwarf_next_cu_header_types() traverses debug_types CU headers. +/* dwarf_next_cu_header_types traverses debug_types CU headers. New in October, 2011. Obsolete but supported May 2015. */ int dwarf_next_cu_header_c(Dwarf_Debug /*dbg*/, @@ -1479,7 +1659,7 @@ int dwarf_offdie(Dwarf_Debug /*dbg*/, Dwarf_Die* /*return_die*/, Dwarf_Error* /*error*/); -/* dwarf_offdie_b() new October 2011 */ +/* dwarf_offdie_b new October 2011 */ /* Finding die given global (not CU-relative) offset. Applies to debug_info (is_info true) or debug_types (is_info false). */ int dwarf_offdie_b(Dwarf_Debug /*dbg*/, @@ -1521,8 +1701,7 @@ int dwarf_dieoffset(Dwarf_Die /*die*/, and if not there (because the dbg object is a dwo or dwp split dwarf object) will look in the tied object if tied is available. */ -int -dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, +int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, Dwarf_Unsigned /*index*/, Dwarf_Addr * /*return_addr*/, Dwarf_Error * /*error*/); @@ -1534,14 +1713,14 @@ dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/, (the passed in DIE can be any DIE). This information makes it possible for a consumer to find and print CU context information for any die. - See also dwarf_get_cu_die_offset_given_cu_header_offset(). */ + See also dwarf_get_cu_die_offset_given_cu_header_offset. */ int dwarf_CU_dieoffset_given_die(Dwarf_Die /*given_die*/, Dwarf_Off* /*return_offset*/, Dwarf_Error* /*error*/); /* dwarf_die_CU_offset returns the CU relative offset not the global debug_info section offset, given - any DIE in the CU. See also dwarf_CU_dieoffset_given_die(). + any DIE in the CU. See also dwarf_CU_dieoffset_given_die. */ int dwarf_die_CU_offset(Dwarf_Die /*die*/, Dwarf_Off* /*return_offset*/, @@ -1576,7 +1755,7 @@ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, /* Validate the sibling DIE. This only makes sense to call if the sibling's DIEs have been travsersed and - dwarf_child() called on each, + dwarf_child called on each, so that the last DIE dwarf_child saw was the last. Essentially ensuring that (after such traversal) that we are in the same place a sibling attribute would identify. @@ -1584,7 +1763,7 @@ int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, DIE traversed by dwarf_child is returned through *offset */ int dwarf_validate_die_sibling(Dwarf_Die /*sibling*/,Dwarf_Off* /*offset*/); -/* convenience functions, alternative to using dwarf_attrlist() */ +/* convenience functions, alternative to using dwarf_attrlist */ int dwarf_hasattr(Dwarf_Die /*die*/, Dwarf_Half /*attr*/, Dwarf_Bool * /*returned_bool*/, @@ -1643,15 +1822,15 @@ int dwarf_loclist_from_expr_c(Dwarf_Debug /*dbg*/, Dwarf_Error * /*error*/); /* This frees all memory allocated by the applicable - dwarf_get_loclist_c() */ + dwarf_get_loclist_c */ void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c /*loclist_head*/); /* END: loclist_c interfaces */ /* As of 2015 the preferred interface - is dwarf_get_loclist_c() - and only dwarf_get_loclist_c() will work + is dwarf_get_loclist_c + and only dwarf_get_loclist_c will work for DWARF5 (and also all earlier versions). */ int dwarf_loclist_n(Dwarf_Attribute /*attr*/, Dwarf_Locdesc*** /*llbuf*/, @@ -1667,9 +1846,9 @@ int dwarf_loclist(Dwarf_Attribute /*attr*/, /* inflexible! */ /* Extracts a dwarf expression from an expression byte stream. Useful to get expressions from DW_CFA_def_cfa_expression DW_CFA_expression DW_CFA_val_expression expression bytes. - 27 April 2009: dwarf_loclist_from_expr() interface with + 27 April 2009: dwarf_loclist_from_expr interface with no addr_size is obsolete but supported, - use dwarf_loclist_from_expr_a() instead. + use dwarf_loclist_from_expr_a instead. */ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Ptr /* expression_in*/, @@ -1678,7 +1857,7 @@ int dwarf_loclist_from_expr(Dwarf_Debug /*dbg*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /* error*/ ); -/* dwarf_loclist_from_expr_a() new 27 Apr 2009: +/* dwarf_loclist_from_expr_a new 27 Apr 2009: added addr_size argument. */ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*expression_in*/, @@ -1688,7 +1867,7 @@ int dwarf_loclist_from_expr_a(Dwarf_Debug /*dbg*/, Dwarf_Signed * /*listlen*/, Dwarf_Error * /*error*/); -/* dwarf_loclist_from_expr_b() new 13 Nov 2012: +/* dwarf_loclist_from_expr_b new 13 Nov 2012: added dwarf_version (DWARF version number of the applicable compilation unit) and offset_size arguments. Added for @@ -1796,7 +1975,7 @@ int dwarf_global_formref(Dwarf_Attribute /*attr*/, int dwarf_formsig8(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, Dwarf_Error* /*error*/); -/* dwarf_formsig8_b returns in the caller-provided 8 byte area +/* dwarf_formsig8_const returns in the caller-provided 8 byte area the 8 bytes of a form const (DW_FORM_data8). Not a string. */ int dwarf_formsig8_const(Dwarf_Attribute /*attr*/, Dwarf_Sig8 * /*returned sig bytes*/, @@ -1818,6 +1997,10 @@ int dwarf_formflag(Dwarf_Attribute /*attr*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); +int dwarf_formdata16(Dwarf_Attribute /*attr*/, + Dwarf_Form_Data16 * /*returned_val*/, + Dwarf_Error* /*error*/); + int dwarf_formudata(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*returned_val*/, Dwarf_Error* /*error*/); @@ -1838,8 +2021,7 @@ int dwarf_formstring(Dwarf_Attribute /*attr*/, get the string index (DW_FORM_strx) and print it. A convenience function. New May 2014. */ -int -dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, +int dwarf_get_debug_str_index(Dwarf_Attribute /*attr*/, Dwarf_Unsigned * /*return_index*/, Dwarf_Error * /*error*/); @@ -1869,7 +2051,7 @@ int dwarf_srclines(Dwarf_Die /*die*/, For two-level line tables, the version returned will be 0xf006. This interface can return data from two-level line tables, which are experimental. - Most users will not wish to use dwarf_srclines_two_level() */ + Most users will not wish to use dwarf_srclines_two_level */ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Unsigned * /*version*/, Dwarf_Line** /*linebuf*/, @@ -1879,13 +2061,13 @@ int dwarf_srclines_two_level(Dwarf_Die /*die*/, Dwarf_Error* /*error*/); /* dwarf_srclines_dealloc, created July 2005, is the - appropriate method for deallocating what dwarf_srclines() - and dwarf_srclines_two_level() return. + appropriate method for deallocating what dwarf_srclines + and dwarf_srclines_two_level return. More complete free than using dwarf_dealloc directly. When dwarf_srclines_two_level returns two line tables - user code should call dwarf_srclines_dealloc() - once on each linebuf returned by dwarf_srclines_two_level() + user code should call dwarf_srclines_dealloc + once on each linebuf returned by dwarf_srclines_two_level first on linebuf_actuals and then on linebuf{_logicals}. */ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, @@ -1894,13 +2076,11 @@ void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, /* New October 2015, must be used to deallocating - what is allocated by dwarf_srclines_b() and - dwarf_srclines_from_linecontext() use. + what is allocated by dwarf_srclines_b and + dwarf_srclines_from_linecontext use. Works for DWARF2,3,4,5 and for experimental line tables. New work should use the new Dwarf_Line_Context - interfaces. - This also opens a Dwarf_Line_Context struct which - is used by dwarf_srcfiles_b() + interface. This interface only reads the line table header, so it takes relatively little time. *is_single_table will be set non-zero for all standard dwarf line sections. @@ -1965,7 +2145,7 @@ int dwarf_srclines_comp_dir(Dwarf_Line_Context /*line_context*/, /* Count is the real count of suprogram array entries. */ int dwarf_srclines_subprog_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, - Dwarf_Error * /* error*/); + Dwarf_Error * /*error*/); /* New October 2015. */ /* Index starts with 1, last is 'count' */ @@ -1977,11 +2157,43 @@ int dwarf_srclines_subprog_data(Dwarf_Line_Context /*line_context*/, Dwarf_Error * /*error*/); /* New October 2015. */ -/* Count is the real count of files array entries. */ +/* Count is the real count of files array entries. + This remains supported though it is pretty useless for + DWARF5. To process DWARF5 as well + as DWARF 2,3,4 (in a uniform fashion) + use dwarf_srclines_files_indexes() instead. +*/ int dwarf_srclines_files_count(Dwarf_Line_Context /*line_context*/, Dwarf_Signed * /*count*/, Dwarf_Error * /*error*/); +/* New March 2018. */ +/* Count is the real count of files array entries. + Since DWARF 2,3,4 are zero origin indexes and + DWARF5 and later are one origin, this function + replaces dwarf_srclines_files_count(). */ +int dwarf_srclines_files_indexes(Dwarf_Line_Context /*line_context*/, + Dwarf_Signed * /*baseindex*/, + Dwarf_Signed * /*count*/, + Dwarf_Signed * /*endindex*/, + Dwarf_Error * /*error*/); + + +/* New March 2018. Same as dwarf_srclines_files_data, + but adds the md5ptr field so cases where DW_LNCT_MD5 + is present can return pointer to the MD5 value. + With DWARF 5 index starts with 0. + See dwarf_srclines_files_indexes() which makes + indexing through the files easy. */ +int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context, + Dwarf_Signed index_in, + const char ** name, + Dwarf_Unsigned * directory_index, + Dwarf_Unsigned * last_mod_time, + Dwarf_Unsigned * file_length, + Dwarf_Form_Data16 ** md5ptr, + Dwarf_Error * error); + /* New October 2015. */ /* Unlike dwarf_srcfiles() this returns the raw file table strings without the directory being prefixed. @@ -2031,18 +2243,6 @@ int dwarf_srcfiles(Dwarf_Die /*die*/, Dwarf_Signed * /*filecount*/, Dwarf_Error* /*error*/); -/* New October 2015. - Returns the same data as - dwarf_srcfiles, but is based on - a Dwarf_Line_Context created by - dwarf_srclines_b(). Using this avoids - rereading the line table header for this CU. */ -int dwarf_srcfiles_b(Dwarf_Line_Context /*context*/, - Dwarf_Unsigned * /*version*/, - char *** /*srcfiles*/, - Dwarf_Signed * /*filecount*/, - Dwarf_Error * /*error*/); - int dwarf_linebeginstatement(Dwarf_Line /*line*/, Dwarf_Bool * /*returned_bool*/, Dwarf_Error* /*error*/); @@ -2068,12 +2268,12 @@ int dwarf_lineaddr(Dwarf_Line /*line*/, Dwarf_Addr * /*returned_addr*/, Dwarf_Error* /*error*/); -/* dwarf_lineoff() is OBSOLETE as of December 2011. Do not use. */ +/* dwarf_lineoff is OBSOLETE as of December 2011. Do not use. */ int dwarf_lineoff(Dwarf_Line /*line*/, Dwarf_Signed * /*returned_lineoffset*/, Dwarf_Error* /*error*/); -/* dwarf_lineoff_b() correctly returns an unsigned column number +/* dwarf_lineoff_b correctly returns an unsigned column number through the pointer returned_lineoffset. dwarf_lineoff_b() is new in December 2011. */ int dwarf_lineoff_b(Dwarf_Line /*line*/, @@ -2132,7 +2332,166 @@ int dwarf_line_subprog(Dwarf_Line /*line*/, Dwarf_Error * /*error*/); /* End of line table interfaces. */ -/* global name space operations (.debug_pubnames access) */ +/* .debug_names names table interfaces. DWARF5 */ +/* New April 2017 */ +int dwarf_debugnames_header(Dwarf_Debug /*dbg*/, + Dwarf_Dnames_Head * /*dn_out*/, + + /* *dn_count_out returns the number of name indexes + in the .debug_names section */ + Dwarf_Unsigned * /*dn_index_count_out*/, + Dwarf_Error * /*error*/); + +/* Since there may be multiple name indexes in a .debug_names + section we use index_number starting at 0 through + dn_index_count_out-1. */ +int dwarf_debugnames_sizes(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + + Dwarf_Unsigned * /*section_offset*/, + Dwarf_Unsigned * /*version*/, + Dwarf_Unsigned * /*offset_size*/, /* 4 or 8 */ + + /* The counts are entry counts, not byte sizes. */ + Dwarf_Unsigned * /*comp_unit_count*/, + Dwarf_Unsigned * /*local_type_unit_count*/, + Dwarf_Unsigned * /*foreign_type_unit_count*/, + Dwarf_Unsigned * /*bucket_count*/, + Dwarf_Unsigned * /*name_count*/, + + /* The following are counted in bytes */ + Dwarf_Unsigned * /*indextable_overall_length*/, + Dwarf_Unsigned * /*abbrev_table_size*/, + Dwarf_Unsigned * /*entry_pool_size*/, + Dwarf_Unsigned * /*augmentation_string_size*/, + + Dwarf_Error * /*error*/); + +int dwarf_debugnames_cu_entry(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*offset_number*/, + Dwarf_Unsigned * /*offset_count*/, + Dwarf_Unsigned * /*offset*/, + Dwarf_Error * /*error*/); +int dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*offset_number*/, + Dwarf_Unsigned * /*offset_count*/, + Dwarf_Unsigned * /*offset*/, + Dwarf_Error * /*error*/); +int dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*sig_number*/, + Dwarf_Unsigned * /*sig_mininum*/, + Dwarf_Unsigned * /*sig_count*/, + Dwarf_Sig8 * /*signature*/, + Dwarf_Error * /*error*/); +int dwarf_debugnames_bucket(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*bucket_number*/, + Dwarf_Unsigned * /*bucket_count*/, + Dwarf_Unsigned * /*index_of_name_entry*/, + Dwarf_Error * /*error*/); + +int dwarf_debugnames_name(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*name_entry*/, + Dwarf_Unsigned * /*names_count*/, + Dwarf_Sig8 * /*signature*/, + Dwarf_Unsigned * /*offset_to_debug_str*/, + Dwarf_Unsigned * /*offset_in_entrypool*/, + Dwarf_Error * /*error*/); + +int dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*abbrev_entry*/, + Dwarf_Unsigned * /*abbrev_code*/, + Dwarf_Unsigned * /*tag*/, + + /* The number of valid abbrev_entry values: 0 to number_of_abbrev-1 + */ + Dwarf_Unsigned * /*number_of_abbrev*/, + + /* The number of attr/form pairs, not counting the trailing + 0,0 pair. */ + Dwarf_Unsigned * /*number_of_attr_form_entries*/, + Dwarf_Error * /*error*/); + +int dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*abbrev_code*/, + Dwarf_Unsigned * /*tag*/, + + /* The number of this code/tag as an array index. */ + Dwarf_Unsigned * /*index_of_abbrev*/, + + /* The number of attr/form pairs, not counting the trailing + 0,0 pair. */ + Dwarf_Unsigned * /*number_of_attr_form_entries*/, + Dwarf_Error * /*error*/); + +int dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*abbrev_entry_index*/, + Dwarf_Unsigned /*abbrev_form_index*/, + Dwarf_Unsigned * /*name_index_attr*/, + Dwarf_Unsigned * /*form*/, + Dwarf_Unsigned * /*number_of_attr_form_entries*/, + Dwarf_Error * /*error*/); + + +/* This, combined with dwarf_debugnames_entrypool_values(), + lets one examine as much or as little of an entrypool + as one wants to by alternately calling these two + functions. */ +int dwarf_debugnames_entrypool(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*offset_in_entrypool*/, + Dwarf_Unsigned * /*abbrev_code*/, + Dwarf_Unsigned * /*tag*/, + Dwarf_Unsigned * /*value_count*/, + Dwarf_Unsigned * /*index_of_abbrev*/, + Dwarf_Unsigned * /*offset_of_initial_value*/, + Dwarf_Error * /*error*/); + +/* Caller, knowing array size needed, passes in arrays + it allocates of for idx, form, offset-size-values, + and signature values. Caller must examine idx-number + and form to decide, for each array element, whether + the offset or the signature contains the value. + So this returns all the values for the abbrev code. + And points via offset_of_next to the next abbrev code. + */ +int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head /*dn*/, + Dwarf_Unsigned /*index_number*/, + Dwarf_Unsigned /*index_of_abbrev*/, + Dwarf_Unsigned /*offset_in_entrypool_of_values*/, + Dwarf_Unsigned * /*array_dw_idx_number*/, + Dwarf_Unsigned * /*array_form*/, + Dwarf_Unsigned * /*array_of_offsets*/, + Dwarf_Sig8 * /*array_of_signatures*/, + + /* offset of the next entrypool entry. */ + Dwarf_Unsigned * /*offset_of_next_entrypool*/, + Dwarf_Error * /*error*/); + +/* FIXME: add interfaces for string search given hash and + string */ + + + +/* end of .debug_names interfaces. */ + + +/* global name space operations (.debug_pubnames access) + * The pubnames and similar sections are rarely used. Few compilers + emit them. They are DWARF 2,3,4 only., not DWARF 5. */ + +/* New March 2019. Mostly special for dwarfdump. */ +int dwarf_return_empty_pubnames(Dwarf_Debug /*dbg*/, + int /* flag */, + Dwarf_Error* /*error*/); + int dwarf_get_globals(Dwarf_Debug /*dbg*/, Dwarf_Global** /*globals*/, Dwarf_Signed * /*number_of_globals*/, @@ -2181,6 +2540,20 @@ int dwarf_global_name_offsets(Dwarf_Global /*global*/, Dwarf_Off* /*cu_offset*/, Dwarf_Error* /*error*/); +/* New February 2019. For more complete dwarfdump printing. + For each CU represented in .debug_pubnames, etc, + there is a .debug_pubnames header. For any given + Dwarf_Global this returns the content of the applicable + header. */ +int dwarf_get_globals_header(Dwarf_Global /*global*/, + Dwarf_Off * /*offset_pub_header*/, + Dwarf_Unsigned * /*length_size*/, + Dwarf_Unsigned * /*length_pub*/, + Dwarf_Unsigned * /*version*/, + Dwarf_Unsigned * /*header_info_offset*/, + Dwarf_Unsigned * /*info_length*/, + Dwarf_Error* /*error*/); + /* Static function name operations. */ int dwarf_get_funcs(Dwarf_Debug /*dbg*/, Dwarf_Func** /*funcs*/, @@ -2501,11 +2874,24 @@ int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, Dwarf_Addr /*pc_requested*/, Dwarf_Small * /*value_type*/, Dwarf_Signed * /*offset_relevant*/, - Dwarf_Signed* /*register*/, - Dwarf_Signed* /*offset_or_block_len*/, - Dwarf_Ptr * /*block_ptr */, - Dwarf_Addr* /*row_pc_out*/, - Dwarf_Error* /*error*/); + Dwarf_Signed * /*register*/, + Dwarf_Signed * /*offset_or_block_len*/, + Dwarf_Ptr * /*block_ptr */, + Dwarf_Addr * /*row_pc_out*/, + Dwarf_Error * /*error*/); + +int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde /*fde*/, + Dwarf_Half /*table_column*/, + Dwarf_Addr /*pc_requested*/, + Dwarf_Small * /*value_type*/, + Dwarf_Signed * /*offset_relevant*/, + Dwarf_Signed * /*register*/, + Dwarf_Signed * /*offset_or_block_len*/, + Dwarf_Ptr * /*block_ptr */, + Dwarf_Addr * /*row_pc_out*/, + Dwarf_Bool * /* has_more_rows */, + Dwarf_Addr * /* subsequent_pc */, + Dwarf_Error * /*error*/); /* Use this or the next function to get the cfa. New function, June 11, 2016*/ @@ -2828,18 +3214,6 @@ int _dwarf_cie_section_offset(Dwarf_Debug /*dbg*/, typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details; -int dwarf_get_macro(Dwarf_Debug /*dbg*/, - char * /*requested_macro_name*/, - Dwarf_Addr /*pc_of_request*/, - char ** /*returned_macro_value*/, - Dwarf_Error * /*error*/); - -int dwarf_get_all_defined_macros(Dwarf_Debug /*dbg*/, - Dwarf_Addr /*pc_of_request*/, - Dwarf_Signed * /*returned_count*/, - char *** /*returned_pointers_to_macros*/, - Dwarf_Error * /*error*/); - char *dwarf_find_macro_value_start(char * /*macro_string*/); int dwarf_get_macro_details(Dwarf_Debug /*dbg*/, @@ -2962,7 +3336,8 @@ int dwarf_gdbindex_cuvector_inner_attributes(Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned * /*attr_value*/, Dwarf_Error * /*error*/); -int dwarf_gdbindex_cuvector_instance_expand_value(Dwarf_Gdbindex /*gdbindex*/, +int dwarf_gdbindex_cuvector_instance_expand_value( + Dwarf_Gdbindex /*gdbindex*/, Dwarf_Unsigned /*value*/, Dwarf_Unsigned * /*cu_index*/, Dwarf_Unsigned * /*reserved1*/, @@ -3092,6 +3467,7 @@ int dwarf_get_debugfission_for_key(Dwarf_Debug /*dbg*/, Dwarf_Unsigned dwarf_errno(Dwarf_Error /*error*/); char* dwarf_errmsg(Dwarf_Error /*error*/); +char* dwarf_errmsg_by_number(Dwarf_Unsigned /* errornum */); /* stringcheck zero is default and means do all string length validity checks. @@ -3157,9 +3533,30 @@ int dwarf_producer_init( Dwarf_P_Debug *, /* dbg_returned */ Dwarf_Error * /*error*/); +/* Returns DW_DLV_OK or DW_DLV_ERROR. + The desired form must be DW_FORM_string (the default) + or DW_FORM_strp. */ +int dwarf_pro_set_default_string_form(Dwarf_P_Debug /*dbg*/, + int /*desired_form*/, + Dwarf_Error* /*error*/); + +/* the old interface. Still supported. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); +/* New September 2016. The preferred interface. */ +int dwarf_transform_to_disk_form_a(Dwarf_P_Debug /*dbg*/, + Dwarf_Signed * /*nbufs_out*/, + Dwarf_Error* /*error*/); + +/* New September 2016. Preferred. */ +int dwarf_get_section_bytes_a(Dwarf_P_Debug /*dbg*/, + Dwarf_Signed /*dwarf_section*/, + Dwarf_Signed* /*elf_section_index*/, + Dwarf_Unsigned* /*length*/, + Dwarf_Ptr * /*section_bytes*/, + Dwarf_Error* /*error*/); +/* Original function. Checking for error is difficult. */ Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, Dwarf_Signed /*dwarf_section*/, Dwarf_Signed* /*elf_section_index*/, @@ -3193,6 +3590,13 @@ Dwarf_Signed dwarf_get_die_markers( Dwarf_Unsigned * /*marker_count*/, Dwarf_Error * /*error*/); +/* Preferred version December 2018. */ +int dwarf_get_die_markers_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Marker * /*marker_list*/, + Dwarf_Unsigned * /*marker_count*/, + Dwarf_Error * /*error*/); + int dwarf_get_string_attributes_count(Dwarf_P_Debug, Dwarf_Unsigned *, int *, @@ -3209,6 +3613,10 @@ void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/); Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); +/* Returns DW_DLV_OK or DW_DLV_ERROR */ +int dwarf_producer_finish_a(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + /* Producer attribute addition functions. */ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, @@ -3216,6 +3624,30 @@ Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Signed /*sym_index*/, Dwarf_Error* /*error*/); +Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pc_value*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_AT_targ_address_c(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pc_value*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_AT_block_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Small* /*block_data*/, + Dwarf_Unsigned /*block_len*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, @@ -3224,18 +3656,20 @@ Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*block_len*/, Dwarf_Error* /*error*/); -Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, +Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); -Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, +/* New December 2018. Preferred version. */ +int dwarf_add_AT_ref_address_a(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Unsigned /*pc_value*/, Dwarf_Unsigned /*sym_index*/, + Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, @@ -3244,12 +3678,28 @@ Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*value*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*value*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Signed /*value*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_signed_const_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Signed /*value*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, @@ -3267,6 +3717,14 @@ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*otherdie*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_reference_c(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_P_Die /*otherdie*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + /* The following is for out-of-order cu-local references. Allowing nominating the target Dwarf_P_Die after calling dwarf_add_AT_reference with a NULL otherdie @@ -3274,14 +3732,12 @@ Dwarf_P_Attribute dwarf_add_AT_reference_b(Dwarf_P_Debug /*dbg*/, for forward-references. New 22 October, 2013. */ -int -dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, +int dwarf_fixup_AT_reference_die(Dwarf_P_Debug /*dbg*/, Dwarf_Half /* attrnum */, Dwarf_P_Die /* sourcedie*/, Dwarf_P_Die /* targetdie*/, Dwarf_Error * /*error*/); - Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, @@ -3290,8 +3746,26 @@ Dwarf_P_Attribute dwarf_add_AT_dataref( Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); -Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die /*ownerdie*/, +/* New December 2018. Preferred version. */ +int dwarf_add_AT_dataref_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Unsigned /*pcvalue*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_const_value_string( + Dwarf_P_Die /*ownerdie*/, + char* /*string_value*/, + Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_AT_const_value_string_a( + Dwarf_P_Die /*ownerdie*/, char* /*string_value*/, + Dwarf_P_Attribute * /*attr_out*/, Dwarf_Error* /*error*/); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, @@ -3300,58 +3774,151 @@ Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, Dwarf_P_Expr /*loc_expr*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_location_expr_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_P_Expr /*loc_expr*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, char* /*string*/, Dwarf_Error* /*error*/); +/* Preferred as of December 2018. */ +int dwarf_add_AT_string_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + char* /*string*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attr*/, Dwarf_Small /*flag*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_flag_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attr*/, + Dwarf_Small /*flag*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, char* /*producer_string*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_producer_a(Dwarf_P_Die /*ownerdie*/, + char* /*producer_string*/, + Dwarf_P_Attribute * /*attr_out*/, + Dwarf_Error* /*error*/); + +/* October 2017 for DW_FORM_data16. Usable with any attribute, + though it should only be in limited use. DWARF5 only. + Returns DW_DLV_OK on success, DW_DLV_ERROR on failure. + Returns the new attribute pointer through *return_attr. */ +int dwarf_add_AT_data16(Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attrnum*/, + Dwarf_Form_Data16 * /* pointstovalue */, + Dwarf_P_Attribute * /* return_attr */, + Dwarf_Error * /*error*/); + +/* November 2018. DW_AT_implicit const generation. */ +int dwarf_add_AT_implicit_const(Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attrnum*/, + Dwarf_Signed /*signed_value*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error * /*error*/); + /* August 2013 sleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_sleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Signed /*signed_value*/, Dwarf_Error * /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attrnum*/, + Dwarf_Signed /*signed_value*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error * /*error*/); + /* Original sleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, Dwarf_Signed /*signed_value*/, Dwarf_Error* /*error*/); +/* Preferred as of December 2018. */ +int dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die /*ownerdie*/, + Dwarf_Signed /*signed_value*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error* /*error*/); + /* August 2013 uleb creator. For any attribute. */ Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die /*ownerdie*/, Dwarf_Half /*attrnum*/, Dwarf_Unsigned /*signed_value*/, Dwarf_Error * /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die /*ownerdie*/, + Dwarf_Half /*attrnum*/, + Dwarf_Unsigned /*signed_value*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error * /*error*/); + /* Original uleb creator. Only for DW_AT_const_value. */ Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint( Dwarf_P_Die /*ownerdie*/, Dwarf_Unsigned /*unsigned_value*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_const_value_unsignedint_a( + Dwarf_P_Die /*ownerdie*/, + Dwarf_Unsigned /*unsigned_value*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, char* /*current_working_directory*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_AT_comp_dir_a(Dwarf_P_Die /*ownerdie*/, + char* /*current_working_directory*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error* /*error*/); + Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die /*die*/, char* /*name*/, Dwarf_Error* /*error*/); -Dwarf_P_Attribute -dwarf_add_AT_with_ref_sig8( +/* New December 2018. Preferred version. */ +int dwarf_add_AT_name_a(Dwarf_P_Die /*die*/, + char* /*name*/, + Dwarf_P_Attribute * /*outattr*/, + Dwarf_Error* /*error*/); + +Dwarf_P_Attribute dwarf_add_AT_with_ref_sig8( + Dwarf_P_Die /*ownerdie */, + Dwarf_Half /*attrnum */, + const Dwarf_Sig8 * /*sig8_in*/, + Dwarf_Error * /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_AT_with_ref_sig8_a( Dwarf_P_Die /*ownerdie */, Dwarf_Half /*attrnum */, const Dwarf_Sig8 * /*sig8_in*/, + Dwarf_P_Attribute * /*outattr*/, Dwarf_Error * /*error*/); @@ -3360,6 +3927,12 @@ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_directory_decl_a(Dwarf_P_Debug /*dbg*/, + char* /*name*/, + Dwarf_Unsigned * /*index_in_directories*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, char* /*name*/, Dwarf_Unsigned /*dir_index*/, @@ -3367,6 +3940,29 @@ Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*length*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_file_decl_a(Dwarf_P_Debug /*dbg*/, + char* /*name*/, + Dwarf_Unsigned /*dir_index*/, + Dwarf_Unsigned /*time_last_modified*/, + Dwarf_Unsigned /*length*/, + Dwarf_Unsigned * /*file_entry_count_out*/, + Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_line_entry_c(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*file_index*/, + Dwarf_Addr /*code_address*/, + Dwarf_Unsigned /*lineno*/, + Dwarf_Signed /*column_number*/, + Dwarf_Bool /*is_source_stmt_begin*/, + Dwarf_Bool /*is_basic_block_begin*/, + Dwarf_Bool /*is_epilogue_begin*/, + Dwarf_Bool /*is_prologue_end*/, + Dwarf_Unsigned /*isa*/, + Dwarf_Unsigned /*discriminator*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, @@ -3379,6 +3975,7 @@ Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*isa*/, Dwarf_Unsigned /*discriminator*/, Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*file_index*/, Dwarf_Addr /*code_address*/, @@ -3393,10 +3990,21 @@ Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*symbol_index*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_lne_set_address_a(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*offset*/, + Dwarf_Unsigned /*symbol_index*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*end_address*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_lne_end_sequence_a(Dwarf_P_Debug /*dbg*/, + Dwarf_Addr /*end_address*/, + Dwarf_Error* /*error*/); + /* Producer .debug_frame functions */ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, char* /*augmenter*/, @@ -3407,6 +4015,17 @@ Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, Dwarf_Unsigned /*init_byte_len*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_frame_cie_a(Dwarf_P_Debug /*dbg*/, + char* /*augmenter*/, + Dwarf_Small /*code_alignment_factor*/, + Dwarf_Small /*data_alignment_factor*/, + Dwarf_Small /*return_address_reg*/, + Dwarf_Ptr /*initialization_bytes*/, + Dwarf_Unsigned /*init_byte_len*/, + Dwarf_Unsigned * /*cie_index_out*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_frame_fde( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, @@ -3429,6 +4048,36 @@ Dwarf_Unsigned dwarf_add_frame_fde_b( Dwarf_Addr /*offset_from_end_sym*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_frame_fde_c( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Fde /*fde*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned /*cie*/, + Dwarf_Addr /*virt_addr*/, + Dwarf_Unsigned /*code_len*/, + Dwarf_Unsigned /*sym_idx*/, + Dwarf_Unsigned /*sym_idx_of_end*/, + Dwarf_Addr /*offset_from_end_sym*/, + Dwarf_Unsigned * /*index_to_fde*/, + Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_frame_info_c( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Fde /*fde*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned /*cie*/, + Dwarf_Addr /*virt_addr*/, + Dwarf_Unsigned /*code_len*/, + Dwarf_Unsigned /*symidx*/, + Dwarf_Unsigned /*end_symbol */, + Dwarf_Addr /*offset_from_end_symbol */, + Dwarf_Signed /*offset_into_exception_tables*/, + Dwarf_Unsigned /*exception_table_symbol*/, + Dwarf_Unsigned * /*fde_index_out*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_frame_info_b( Dwarf_P_Debug /*dbg*/, Dwarf_P_Fde /*fde*/, @@ -3455,6 +4104,7 @@ Dwarf_Unsigned dwarf_add_frame_info( Dwarf_Unsigned /*exception_table_symbol*/, Dwarf_Error* /*error*/); +/* The fde returned is just the one passed in. Silly. */ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_P_Fde /*fde*/, Dwarf_Small /*op*/, @@ -3462,6 +4112,14 @@ Dwarf_P_Fde dwarf_add_fde_inst( Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_fde_inst_a( + Dwarf_P_Fde /*fde*/, + Dwarf_Small /*op*/, + Dwarf_Unsigned /*val1*/, + Dwarf_Unsigned /*val2*/, + Dwarf_Error* /*error*/); + /* New September 17, 2009 */ int dwarf_insert_fde_inst_bytes( Dwarf_P_Debug /*dbg*/, @@ -3470,8 +4128,13 @@ int dwarf_insert_fde_inst_bytes( Dwarf_Ptr /*ibytes*/, Dwarf_Error* /*error*/); +Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); -Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_new_fde_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Fde * /*fde_out*/, + Dwarf_Error* /*error*/); Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_P_Fde /*fde*/, @@ -3479,7 +4142,26 @@ Dwarf_P_Fde dwarf_fde_cfa_offset( Dwarf_Signed /*offset*/, Dwarf_Error* /*error*/); -/* die creation & addition routines */ +/* New December 2018. Preferred version. */ +int dwarf_fde_cfa_offset_a( + Dwarf_P_Fde /*fde*/, + Dwarf_Unsigned /*register_number*/, + Dwarf_Signed /*offset*/, + Dwarf_Error* /*error*/); + +/* die creation & addition routines + dwarf_new_die_a() new September 2016. + Preferred over dwarf_new_die(). */ +int dwarf_new_die_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_Tag /*tag*/, + Dwarf_P_Die /*parent*/, + Dwarf_P_Die /*child*/, + Dwarf_P_Die /*left */, + Dwarf_P_Die /*right*/, + Dwarf_P_Die * /*die_out*/, + Dwarf_Error* /*error*/); + Dwarf_P_Die dwarf_new_die( Dwarf_P_Debug /*dbg*/, Dwarf_Tag /*tag*/, @@ -3489,6 +4171,13 @@ Dwarf_P_Die dwarf_new_die( Dwarf_P_Die /*right*/, Dwarf_Error* /*error*/); +/* New September 2016. */ +int dwarf_add_die_to_debug_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + Dwarf_Error* /*error*/); + +/* Original form. */ Dwarf_Unsigned dwarf_add_die_to_debug( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, @@ -3503,12 +4192,35 @@ Dwarf_Unsigned dwarf_add_die_marker( Dwarf_Unsigned /*marker*/, Dwarf_Error * /*error*/); +/* Preferred version, new December 2018. */ +int dwarf_add_die_marker_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned marker, + Dwarf_Error * error); + Dwarf_Unsigned dwarf_get_die_marker( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, Dwarf_Unsigned * /*marker*/, Dwarf_Error * /*error*/); +/* Preferred version, new December 2018. */ +int dwarf_get_die_marker_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + Dwarf_Unsigned * /*marker*/, + Dwarf_Error * /*error*/); + +/* New September 2016. Preferred version */ +int dwarf_die_link_a( + Dwarf_P_Die /*die*/, + Dwarf_P_Die /*parent*/, + Dwarf_P_Die /*child*/, + Dwarf_P_Die /*left*/, + Dwarf_P_Die /*right*/, + Dwarf_Error* /*error*/); + +/* Original version. Use dwarf_die_link_a() instead. */ Dwarf_P_Die dwarf_die_link( Dwarf_P_Die /*die*/, Dwarf_P_Die /*parent*/, @@ -3522,13 +4234,31 @@ void dwarf_dealloc_compressed_block( void * ); -/* Call this passing in return value from dwarf_uncompress_integer_block() +/* Call this passing in return value from + dwarf_uncompress_integer_block() to free the space the decompression allocated. */ void dwarf_dealloc_uncompressed_block( Dwarf_Debug, void * ); +/* dwarf_compress_integer_block_a( new 11 February 2019. + Like the earlier version this turns an array of signed + integers into a block of sleb values (and if the + values are small enough it might be a compression! + Or it could be an expansion...). Return DW_DLV_OK + on success. Supercedes dwarf_compress_integer_block(): + as no ugly cast needed to know if + dwarf_compress_integer_block_a() succeeds or not. */ +int +dwarf_compress_integer_block_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned /*input_array_length*/, + Dwarf_Signed * /*input_array*/, + Dwarf_Unsigned * /*output_block_len*/, + void ** /*output_block_returned*/, + Dwarf_Error * /*error */); +/* The following should be avoided as of February 2019. */ void * dwarf_compress_integer_block( Dwarf_P_Debug, /*dbg*/ Dwarf_Bool, /*signed==true (or unsigned)*/ @@ -3539,6 +4269,21 @@ void * dwarf_compress_integer_block( Dwarf_Error* /*error*/ ); +/* New February 2019. On success returns DW_DLV_OK + and creates an array of Dwarf_Signed values + from the block of sleb numbers. + This interface supercedes + dwarf_uncompress_integer_block(). No ugly + cast needed to know if + dwarf_uncompress_integer_block_a() succeeds or not. */ +int +dwarf_uncompress_integer_block_a(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned /*input_length_in_bytes*/, + void * /*input_block*/, + Dwarf_Unsigned * /*value_count*/, + Dwarf_Signed ** /*value_array*/, + Dwarf_Error * /*error*/); + /* Decode an array of signed leb integers (so of course the array is not composed of fixed length values, but is instead a sequence of sleb values). @@ -3549,7 +4294,8 @@ void * dwarf_compress_integer_block( Size of integer units must be 32 (32 bits each) at this time. Number of bytes in block is a byte count (not array count). Returns number of units in output block (ie, number of elements - of the array that the return value points to) thru the argument. */ + of the array that the return value points to) thru the + argument. */ void * dwarf_uncompress_integer_block( Dwarf_Debug, /*dbg */ Dwarf_Bool, /*signed==true (or unsigned) */ @@ -3561,7 +4307,13 @@ void * dwarf_uncompress_integer_block( ); /* Operations to create location expressions. */ -Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/); +Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, + Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_new_expr_a(Dwarf_P_Debug /*dbg*/, + Dwarf_P_Expr * /*expr_out*/, + Dwarf_Error* /*error*/); void dwarf_expr_reset( Dwarf_P_Expr /*expr*/, @@ -3574,6 +4326,15 @@ Dwarf_Unsigned dwarf_add_expr_gen( Dwarf_Unsigned /*val2*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_expr_gen_a( + Dwarf_P_Expr /*expr*/, + Dwarf_Small /*opcode*/, + Dwarf_Unsigned /*val1*/, + Dwarf_Unsigned /*val2*/, + Dwarf_Unsigned * /*next_byte_offset*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_expr_addr( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned /*addr*/, @@ -3586,15 +4347,37 @@ Dwarf_Unsigned dwarf_add_expr_addr_b( Dwarf_Unsigned /*sym_index*/, Dwarf_Error* /*error*/); + +/* New December 2018. Preferred version. */ +int dwarf_add_expr_addr_c( + Dwarf_P_Expr /*expr*/, + Dwarf_Unsigned /*addr*/, + Dwarf_Unsigned /*sym_index*/, + Dwarf_Unsigned * /*next_byte_offset_out*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_expr_current_offset( Dwarf_P_Expr /*expr*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_expr_current_offset_a( + Dwarf_P_Expr /*expr*/, + Dwarf_Unsigned * /*next_byte_offset_out*/, + Dwarf_Error* /*error*/); + Dwarf_Addr dwarf_expr_into_block( Dwarf_P_Expr /*expr*/, Dwarf_Unsigned* /*length*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_expr_into_block_a( + Dwarf_P_Expr /*expr*/, + Dwarf_Unsigned* /*length*/, + Dwarf_Small ** /*start_address*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, Dwarf_Addr /*begin_address*/, Dwarf_Unsigned /*length*/, @@ -3610,12 +4393,29 @@ Dwarf_Unsigned dwarf_add_arange_b( Dwarf_Addr /*offset_from_end_symbol*/, Dwarf_Error * /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_arange_c( + Dwarf_P_Debug /*dbg*/, + Dwarf_Addr /*begin_address*/, + Dwarf_Unsigned /*length*/, + Dwarf_Unsigned /*symbol_index*/, + Dwarf_Unsigned /*end_symbol_index*/, + Dwarf_Addr /*offset_from_end_symbol*/, + Dwarf_Error * /*error*/); + Dwarf_Unsigned dwarf_add_pubname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*pubname_name*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_pubname_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*pubname_name*/, + Dwarf_Error* /*error*/); + /* Added 17 October 2013. Introduced in DWARF3. */ Dwarf_Unsigned dwarf_add_pubtype( Dwarf_P_Debug /*dbg*/, @@ -3623,6 +4423,12 @@ Dwarf_Unsigned dwarf_add_pubtype( char* /*pubtype_name*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_pubtype_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*pubtype_name*/, + Dwarf_Error* /*error*/); Dwarf_Unsigned dwarf_add_funcname( Dwarf_P_Debug /*dbg*/, @@ -3630,24 +4436,63 @@ Dwarf_Unsigned dwarf_add_funcname( char* /*func_name*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_funcname_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*func_name*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_typename( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*type_name*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_typename_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*type_name*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_varname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*var_name*/, Dwarf_Error* /*error*/); +/* New December 2018. Preferred version. */ +int dwarf_add_varname_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*var_name*/, + Dwarf_Error* /*error*/); + Dwarf_Unsigned dwarf_add_weakname( Dwarf_P_Debug /*dbg*/, Dwarf_P_Die /*die*/, char* /*weak_name*/, Dwarf_Error* /*error*/); +int dwarf_add_weakname_a( + Dwarf_P_Debug /*dbg*/, + Dwarf_P_Die /*die*/, + char* /*weak_name*/, + Dwarf_Error* /*error*/); + +/* .debug_names producer functions */ + +/* dwarf_force_debug_names forces creation + of .debug_names (if DWARF5 being produced) + even if empty. Only for testing libdwarf. */ +int dwarf_force_debug_names(Dwarf_P_Debug /* dbg */, + Dwarf_Error* /*error*/); + +/* Other debug_names functions are needed... FIXME */ + +/* end .debug_names producer functions */ + /* .debug_macinfo producer functions Functions must be called in right order: the section is output In the order these are presented. @@ -3688,8 +4533,7 @@ int dwarf_attr_offset(Dwarf_Die /*die*/, (which happened in an IRIX executable larger than 2GB with MIPSpro 7.3.1.3 toolchain.). */ -int -dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, +int dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, @@ -3704,8 +4548,7 @@ dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/, /* New October 2011., adds .debug_types section to the sizes returned. */ -int -dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, +int dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, @@ -3720,8 +4563,7 @@ dwarf_get_section_max_offsets_b(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_pubtypes_size*/, Dwarf_Unsigned * /*debug_types_size*/); -int -dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, +int dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_info_size*/, Dwarf_Unsigned * /*debug_abbrev_size*/, Dwarf_Unsigned * /*debug_line_size*/, @@ -3739,7 +4581,27 @@ dwarf_get_section_max_offsets_c(Dwarf_Debug /*dbg*/, Dwarf_Unsigned * /*debug_sup_size*/, Dwarf_Unsigned * /*debug_cu_index_size*/, Dwarf_Unsigned * /*debug_tu_index_size*/); - +int dwarf_get_section_max_offsets_d(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned * /*debug_info_size*/, + Dwarf_Unsigned * /*debug_abbrev_size*/, + Dwarf_Unsigned * /*debug_line_size*/, + Dwarf_Unsigned * /*debug_loc_size*/, + Dwarf_Unsigned * /*debug_aranges_size*/, + Dwarf_Unsigned * /*debug_macinfo_size*/, + Dwarf_Unsigned * /*debug_pubnames_size*/, + Dwarf_Unsigned * /*debug_str_size*/, + Dwarf_Unsigned * /*debug_frame_size*/, + Dwarf_Unsigned * /*debug_ranges_size*/, + Dwarf_Unsigned * /*debug_pubtypes_size*/, + Dwarf_Unsigned * /*debug_types_size*/, + Dwarf_Unsigned * /*debug_macro_size*/, + Dwarf_Unsigned * /*debug_str_offsets_size*/, + Dwarf_Unsigned * /*debug_sup_size*/, + Dwarf_Unsigned * /*debug_cu_index_size*/, + Dwarf_Unsigned * /*debug_tu_index_size*/, + Dwarf_Unsigned * /*debug_names_size*/, + Dwarf_Unsigned * /*debug_loclists_size*/, + Dwarf_Unsigned * /*debug_rnglists_size*/); /* The 'set' calls here return the original (before any change by these set routines) of the respective fields. */ @@ -3792,13 +4654,76 @@ void dwarf_ranges_dealloc(Dwarf_Debug /*dbg*/, Dwarf_Ranges * /*rangesbuf*/, Dwarf_Signed /*rangecount*/); +/* New April 2018. + Allows applications to print the .debug_str_offsets + section. + Beginning at starting_offset zero, + returns data about the first table found. + The value *next_table_offset is the value + of the next table (if any), one byte past + the end of the table whose data is returned.. + Returns DW_DLV_NO_ENTRY if the starting offset + is past the end of valid data. + + There is no guarantee that there are no non-0 nonsense + bytes in the section outside of useful tables, + so this can fail and return nonsense or + DW_DLV_ERROR if such garbage exists. +*/ + +struct Dwarf_Str_Offsets_Table_s; +typedef struct Dwarf_Str_Offsets_Table_s * Dwarf_Str_Offsets_Table; + +/* Allocates a struct Dwarf_Str_Offsets_Table_s for the section + and returns DW_DLV_OK and sets a pointer to the struct through + the table_data pointer if successful. + + If there is no such section it returns DW_DLV_NO_ENTRY. */ +int dwarf_open_str_offsets_table_access(Dwarf_Debug /*dbg*/, + Dwarf_Str_Offsets_Table * /*table_data*/, + Dwarf_Error * /*error*/); + +/* Close access, free table_data. */ +int dwarf_close_str_offsets_table_access( + Dwarf_Str_Offsets_Table /*table_data*/, + Dwarf_Error * /*error*/); + +/* Call till it returns DW_DLV_NO_ENTRY (normal end) + or DW_DLV_ERROR (error) and stop. + + On successful call, call dwarf_str_offsets_table_entry() + to get the individual table values on the now-active table. */ +int dwarf_next_str_offsets_table( Dwarf_Str_Offsets_Table /*table_data*/, + Dwarf_Unsigned * /*unit_length*/, + Dwarf_Unsigned * /*unit_length_offset*/, + Dwarf_Unsigned * /*table_start_offset*/, + Dwarf_Half * /*entry_size*/, + Dwarf_Half * /*version*/, + Dwarf_Half * /*padding*/, + Dwarf_Unsigned * /*table_value_count*/, + Dwarf_Error * /*error*/); + +/* Valid index values n: 0 <= n < table_entry_count + for the active table */ +int dwarf_str_offsets_value_by_index(Dwarf_Str_Offsets_Table /*table_data*/, + Dwarf_Unsigned /*index_to_entry*/, + Dwarf_Unsigned * /*entry_value*/, + Dwarf_Error * /*error*/); + +/* After all str_offsets read this reports final + wasted-bytes count. */ +int dwarf_str_offsets_statistics(Dwarf_Str_Offsets_Table /*table_data*/, + Dwarf_Unsigned * /*wasted_byte_count*/, + Dwarf_Unsigned * /*table_count*/, + Dwarf_Error * /*error*/); + /* The harmless error list is a circular buffer of errors we note but which do not stop us from processing the object. Created so dwarfdump or other tools can report such inconsequential errors without causing anything to stop early. */ #define DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE 4 -#define DW_HARMLESS_ERROR_MSG_STRING_SIZE 200 +#define DW_HARMLESS_ERROR_MSG_STRING_SIZE 300 /* User code supplies size of array of pointers errmsg_ptrs_array in count and the array of pointers (the pointers themselves need not be initialized). @@ -3856,42 +4781,43 @@ unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug /*dbg*/, /* The following copied from a generated dwarf_names.h */ /* BEGIN FILE */ - extern int dwarf_get_ACCESS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ADDR_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATCF_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ATE_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_AT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CC_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_CFA_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_children_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_DEFAULTED_name (unsigned int /*val_in*/,const char ** /*s_out*/); -extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_CHILDREN_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_DEFAULTED_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_DSC_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_DS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_EH_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_END_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FORM_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_FRAME_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ID_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_IDX_name (unsigned int /*val_in*/,const char ** /*s_out*/); +extern int dwarf_get_IDX_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_INL_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ISA_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LANG_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LLE_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_LNCT_name (unsigned int /*val_in*/,const char ** /*s_out*/); +/* dwarf_get_LLEX_name is likely just temporary. Not standard. */ +extern int dwarf_get_LLEX_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_LNCT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNE_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_LNS_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_MACINFO_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_MACRO_name (unsigned int /*val_in*/,const char ** /*s_out*/); +extern int dwarf_get_MACRO_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_OP_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_ORD_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_SECT_name (unsigned int /*val_in*/,const char ** /*s_out*/); +extern int dwarf_get_RLE_name(unsigned int /*val_in*/, const char ** /*s_out */); +extern int dwarf_get_SECT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_TAG_name(unsigned int /*val_in*/, const char ** /*s_out */); -extern int dwarf_get_UT_name (unsigned int /*val_in*/,const char ** /*s_out*/); +extern int dwarf_get_UT_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIRTUALITY_name(unsigned int /*val_in*/, const char ** /*s_out */); extern int dwarf_get_VIS_name(unsigned int /*val_in*/, const char ** /*s_out */); - /* END FILE */ /* Convert local offset into global offset */ @@ -3931,6 +4857,58 @@ int dwarf_get_version_of_die(Dwarf_Die /*die*/, Dwarf_Half * /*version*/, Dwarf_Half * /*offset_size*/); +int dwarf_discr_list(Dwarf_Debug /*dbg*/, + Dwarf_Small * /*blockpointer*/, + Dwarf_Unsigned /*blocklen*/, + Dwarf_Dsc_Head * /*dsc_head_out*/, + Dwarf_Unsigned * /*dsc_array_length_out*/, + Dwarf_Error * /*error*/); + +/* NEW September 2016. Allows easy access to DW_AT_discr_list + entry. Callers must know which is the appropriate + one of the following two interfaces, though both + will work. */ +int dwarf_discr_entry_u(Dwarf_Dsc_Head /* dsc */, + Dwarf_Unsigned /*entrynum*/, + Dwarf_Half * /*out_type*/, + Dwarf_Unsigned * /*out_discr_low*/, + Dwarf_Unsigned * /*out_discr_high*/, + Dwarf_Error * /*error*/); + +/* NEW September 2016. Allows easy access to DW_AT_discr_list + entry. */ +int dwarf_discr_entry_s(Dwarf_Dsc_Head /* dsc */, + Dwarf_Unsigned /*entrynum*/, + Dwarf_Half * /*out_type*/, + Dwarf_Signed * /*out_discr_low*/, + Dwarf_Signed * /*out_discr_high*/, + Dwarf_Error * /*error*/); + +/* New May 2017. So users can find out what groups (dwo or COMDAT) + are in the object and how much to allocate so one can get the + group-section map data. */ +int dwarf_sec_group_sizes(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned * /*section_count_out*/, + Dwarf_Unsigned * /*group_count_out*/, + Dwarf_Unsigned * /*selected_group_out*/, + Dwarf_Unsigned * /*map_entry_count_out*/, + Dwarf_Error * /*error*/); + +/* New May 2017. Reveals the map between group numbers and section numbers. + Caller must allocate the arrays with space for 'map_entry_count' + values and this function fills in the array entries. + Output ordered by group number and section number. + */ +int dwarf_sec_group_map(Dwarf_Debug /*dbg*/, + Dwarf_Unsigned /*map_entry_count*/, + Dwarf_Unsigned * /*group_numbers_array*/, + Dwarf_Unsigned * /*sec_numbers_array*/, + const char ** /*sec_names_array*/, + Dwarf_Error * /*error*/); + +/* dwarf_get_endian_copy_function new. December 2019. */ +void (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/))(void *, const void * /*src*/, unsigned long /*srclen*/); + /* These make the LEB encoding routines visible to libdwarf callers. Added November, 2012. */ int dwarf_encode_leb128(Dwarf_Unsigned /*val*/, @@ -3958,9 +4936,47 @@ extern Dwarf_Cmdline_Options dwarf_cmdline_options; /* Set libdwarf to reflect some application command line options. */ void dwarf_record_cmdline_options(Dwarf_Cmdline_Options /*options*/); +int dwarf_pro_get_string_stats(Dwarf_P_Debug /*dbg*/, + Dwarf_Unsigned * /*str_count*/, + Dwarf_Unsigned * /*str_total_length*/, + Dwarf_Unsigned * /*count_debug_str*/, + Dwarf_Unsigned * /*len_debug_str*/, + Dwarf_Unsigned * /*reused_count*/, + Dwarf_Unsigned * /*reused_len*/, + Dwarf_Error * /*error*/); + +#ifndef DW_FTYPE_UNKNOWN +#define DW_FTYPE_UNKNOWN 0 +#define DW_FTYPE_ELF 1 /* Unix/Linux/etc */ +#define DW_FTYPE_MACH_O 2 /* MacOS. */ +#define DW_FTYPE_PE 3 /* Windows */ +#define DW_FTYPE_ARCHIVE 4 /* unix archive */ +#define DW_FTYPE_CUSTOM_ELF 5 /* Custom ELF format. Ignore this. */ +#endif /* DW_FTYPE_UNKNOWN */ + +#ifndef DW_ENDIAN_UNKNOWN +#define DW_ENDIAN_UNKNOWN 0 +#define DW_ENDIAN_BIG 1 +#define DW_ENDIAN_LITTLE 2 +#endif /* DW_ENDIAN_UNKNOWN */ + +int dwarf_object_detector_path(const char *path, + char *outpath, + unsigned long, + unsigned *ftype, + unsigned *endian, + unsigned *offsetsize, + Dwarf_Unsigned *filesize, + int * errcode); + +int dwarf_object_detector_fd(int fd, + unsigned *ftype, + unsigned *endian, + unsigned *offsetsize, + Dwarf_Unsigned *filesize, + int * errcode); + #ifdef __cplusplus } #endif #endif /* _LIBDWARF_H */ - - diff --git a/thirdparty/dwarf/libdwarf_version.h b/thirdparty/dwarf/libdwarf_version.h new file mode 100644 index 00000000..aaa6424b --- /dev/null +++ b/thirdparty/dwarf/libdwarf_version.h @@ -0,0 +1,7 @@ +/* + This date string is hereby put into the public domain. + Copyrighting this is crazy. It's just a date string + and is modified from time to time. +*/ + +#define DW_VERSION_DATE_STR " 2019-05-29 08:43:30-07:00 " diff --git a/thirdparty/dwarf/libdwarfdefs.h b/thirdparty/dwarf/libdwarfdefs.h index 1ab392b2..344efc78 100644 --- a/thirdparty/dwarf/libdwarfdefs.h +++ b/thirdparty/dwarf/libdwarfdefs.h @@ -30,64 +30,12 @@ #ifndef LIBDWARFDEFS_H #define LIBDWARFDEFS_H -/* We want __uint32_t and __uint64_t and __int32_t __int64_t - properly defined but not duplicated, since duplicate typedefs - are not legal C. -*/ -/* - HAVE___UINT32_T - HAVE___UINT64_T will be set by configure if - our 4 types are predefined in compiler -*/ - - -#if (!defined(HAVE___UINT32_T)) && defined(HAVE___UINT32_T_IN_SGIDEFS_H) -#include /* sgidefs.h defines them */ -#define HAVE___UINT32_T 1 -#endif - -#if (!defined(HAVE___UINT64_T)) && defined(HAVE___UINT64_T_IN_SGIDEFS_H) -#include /* sgidefs.h defines them */ -#define HAVE___UINT64_T 1 -#endif - - -#if (!defined(HAVE___UINT32_T)) && \ - defined(HAVE_SYS_TYPES_H) && \ - defined(HAVE___UINT32_T_IN_SYS_TYPES_H) -# include -#define HAVE___UINT32_T 1 -#endif - -#if (!defined(HAVE___UINT64_T)) && \ - defined(HAVE_SYS_TYPES_H) && \ - defined(HAVE___UINT64_T_IN_SYS_TYPES_H) -# include -#define HAVE___UINT64_T 1 -#endif - -#ifndef HAVE___UINT32_T -typedef int __int32_t; -typedef unsigned __uint32_t; -#define HAVE___UINT32_T 1 -#endif - -#ifndef HAVE___UINT64_T -typedef long long __int64_t; -typedef unsigned long long __uint64_t; -#define HAVE___UINT64_T 1 -#endif - #ifdef HAVE_UNUSED_ATTRIBUTE #define UNUSEDARG __attribute__ ((unused)) #else #define UNUSEDARG #endif -#ifndef SHF_COMPRESSED -/* This from ubuntu xenial. Is in top of trunk binutils - as of February 2016. Elf Section Flag */ -#define SHF_COMPRESSED (1 << 11) -#endif +#define DWARF_HALF_SIZE 2 #endif /* LIBDWARFDEFS_H */ diff --git a/thirdparty/dwarf/memcpy_swap.h b/thirdparty/dwarf/memcpy_swap.h new file mode 100644 index 00000000..53e5e965 --- /dev/null +++ b/thirdparty/dwarf/memcpy_swap.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2018 David Anderson. All Rights Reserved. + + 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 Software Foundation. + + This program is distributed in the hope that it would + be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to + this software file. Patent licenses, if any, provided + herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write + the Free Software Foundation, Inc., 51 Franklin Street - + Fifth Floor, Boston MA 02110-1301, USA. +*/ + +#ifndef MEMCPY_SWAP_H +#define MEMCPY_SWAP_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +void _dwarf_memcpy_swap_bytes(void *s1, const void *s2, unsigned long len); +/* It's inconvenient to use memcpy directly as it + uses size_t and that requires */ +void _dwarf_memcpy_noswap_bytes(void *s1, const void *s2, unsigned long len); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* MEMCPY_SWAP_H */ diff --git a/thirdparty/dwarf/pro_alloc.c b/thirdparty/dwarf/pro_alloc.c index 3d8a0bb7..aa2caa5f 100644 --- a/thirdparty/dwarf/pro_alloc.c +++ b/thirdparty/dwarf/pro_alloc.c @@ -1,42 +1,57 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + Portions Copyright 2011-2019. David Anderson. All Rights Reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" #include "pro_alloc.h" #ifdef HAVE_STDLIB_H #include #else +#ifdef HAVE_MALLOC_H #include +#endif /* HAVE_MALLOC_H */ #endif /* HAVE_STDLIB_H */ #ifdef HAVE_STRING_H #include #endif /* HAVE_STRING_H */ +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ +#include "dwarf_tsearch.h" /* When each block is allocated, there is a two-word structure allocated at the beginning so the block can go on a list. @@ -132,21 +147,39 @@ void _dwarf_p_dealloc(UNUSEDARG Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */ { - memory_list_t *lp; - lp = BLOCK_TO_LIST(ptr); - - /* - Remove from a doubly linked, circular list. - Read carefully, use a white board if necessary. - If this is an empty list, the following statements are no-ops, and - will write to the same memory location they read from. - This should only happen when we deallocate the dbg structure itself. - */ + memory_list_t *lp; + lp = BLOCK_TO_LIST(ptr); + + /* Remove from a doubly linked, circular list. + Read carefully, use a white board if necessary. + If this is an empty list, the following statements are no-ops, and + will write to the same memory location they read from. + This should only happen when we deallocate the dbg structure itself. + */ + if (lp == lp->next) { + /* The list has a single item, itself. */ + lp->prev = 0; + lp->next = 0; + } else if (lp->next == lp->prev) { + /* List had exactly two entries. Reduce it to one, + cutting lp out. */ + memory_list_t * remaining = lp->next; + remaining->next = remaining; + remaining->prev = remaining; + } else { + /* Multi=entry. Just cut lp out. */ + lp->prev->next = lp->next; + lp->next->prev = lp->prev; + lp->prev = lp->next = 0; + } + free((void*)lp); +} - lp->prev->next = lp->next; - lp->next->prev = lp->prev; - free((void*)lp); +static void +_dwarf_str_hashtab_freenode(void * nodep) +{ + free(nodep); } @@ -159,23 +192,25 @@ void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg) { memory_list_t *dbglp; + memory_list_t *base_dbglp; if (dbg == NULL) { /* should throw an error */ return; } - dbglp = BLOCK_TO_LIST(dbg); - while (dbglp->next != dbglp) { - _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next)); - } - if (dbglp->next != dbglp || - dbglp->prev != dbglp) { + base_dbglp = BLOCK_TO_LIST(dbg); + dbglp = base_dbglp->next; - /* should throw error */ - /* For some reason we couldn't free all the blocks? */ - return; + while (dbglp != base_dbglp) { + memory_list_t*next = dbglp->next; + + _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp)); + dbglp = next; } - _dwarf_p_dealloc(NULL, (void*)dbg); + dwarf_tdestroy(dbg->de_debug_str_hashtab, + _dwarf_str_hashtab_freenode); + dwarf_tdestroy(dbg->de_debug_line_str_hashtab, + _dwarf_str_hashtab_freenode); + free((void *)base_dbglp); } - diff --git a/thirdparty/dwarf/pro_alloc.h b/thirdparty/dwarf/pro_alloc.h index 85ccbe34..83abe24c 100644 --- a/thirdparty/dwarf/pro_alloc.h +++ b/thirdparty/dwarf/pro_alloc.h @@ -25,6 +25,13 @@ */ +#ifndef PRO_ALLOC_H +#define PRO_ALLOC_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned); @@ -32,3 +39,8 @@ void dwarf_p_dealloc(Dwarf_Small * ptr); /* DO NOT USE. */ void _dwarf_p_dealloc(Dwarf_P_Debug,Dwarf_Small * ptr); void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* PRO_ALLOC_H */ diff --git a/thirdparty/dwarf/pro_arange.c b/thirdparty/dwarf/pro_arange.c index 8e529eb5..672544cc 100644 --- a/thirdparty/dwarf/pro_arange.c +++ b/thirdparty/dwarf/pro_arange.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. + Portions Copyright 2011-2019 David Anderson. All Rights Reserved. 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 @@ -33,11 +33,18 @@ #include #endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" #include "pro_arange.h" #include "pro_section.h" #include "pro_reloc.h" +#define SIZEOFT32 4 /* This function adds another address range to the list of address ranges for the @@ -49,36 +56,63 @@ dwarf_add_arange(Dwarf_P_Debug dbg, Dwarf_Unsigned length, Dwarf_Signed symbol_index, Dwarf_Error * error) { - return dwarf_add_arange_b(dbg, begin_address, length, symbol_index, + int res = 0; + + res = dwarf_add_arange_b(dbg, begin_address, length, symbol_index, /* end_symbol_index */ 0, /* offset_from_end_sym */ 0, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; + } /* This function adds another address range to the list of address ranges for the - given Dwarf_P_Debug. It returns 0 on error, - and 1 otherwise. */ + given Dwarf_P_Debug. It returns DW_DLV_ERROR on error, + and DW_DLV_OK otherwise. */ Dwarf_Unsigned dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr begin_address, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, - Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) + Dwarf_Addr offset_from_end_sym, + Dwarf_Error * error) +{ + int res = 0; + + res = dwarf_add_arange_c(dbg,begin_address,length, + symbol_index, end_symbol_index, + offset_from_end_sym,error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; +} +int +dwarf_add_arange_c(Dwarf_P_Debug dbg, + Dwarf_Addr begin_address, + Dwarf_Unsigned length, + Dwarf_Unsigned symbol_index, + Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_sym, + Dwarf_Error * error) { Dwarf_P_Arange arange; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return (0); + return DW_DLV_ERROR; } arange = (Dwarf_P_Arange) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s)); if (arange == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } arange->ag_begin_address = begin_address; @@ -94,13 +128,13 @@ dwarf_add_arange_b(Dwarf_P_Debug dbg, dbg->de_last_arange = arange; } dbg->de_arange_count++; - - return (1); + return DW_DLV_OK; } int -_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) +_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Total num of bytes in .debug_aranges section. */ Dwarf_Unsigned arange_num_bytes = 0; @@ -125,8 +159,11 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) const Dwarf_Signed big_zero = 0; int extension_word_size = dbg->de_64bit_extension ? 4 : 0; - int uword_size = dbg->de_offset_size; + int offset_size = dbg->de_offset_size; int upointer_size = dbg->de_pointer_size; + + /* All dwarf versions so far use 2 here. */ + Dwarf_Half version = 2; int res = 0; @@ -134,9 +171,9 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) /* Size of the .debug_aranges section header. */ arange_num_bytes = extension_word_size + - uword_size + /* Size of length field. */ - sizeof(Dwarf_Half) + /* Size of version field. */ - uword_size + /* Size of .debug_info offset. */ + offset_size + /* Size of length field. */ + DWARF_HALF_SIZE + /* Size of version field. */ + offset_size + /* Size of .debug_info offset. */ sizeof(Dwarf_Small) + /* Size of address size field. */ sizeof(Dwarf_Small); /* Size of segment size field. */ @@ -154,71 +191,76 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES], arange, (unsigned long) arange_num_bytes, error); arange_ptr = arange; - if (arange == NULL) { - _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); - } if (extension_word_size) { - Dwarf_Word x = DISTINGUISHED_VALUE; - + DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) arange_ptr, - (const void *) &x, - sizeof(x), extension_word_size); + (const void *)&v4[0] , + SIZEOFT32, extension_word_size); arange_ptr += extension_word_size; } /* Write the total length of .debug_aranges section. */ - adjusted_length = arange_num_bytes - uword_size + adjusted_length = arange_num_bytes - offset_size - extension_word_size; { Dwarf_Unsigned du = adjusted_length; WRITE_UNALIGNED(dbg, (void *) arange_ptr, - (const void *) &du, sizeof(du), uword_size); - arange_ptr += uword_size; + (const void *) &du, sizeof(du), offset_size); + arange_ptr += offset_size; } /* Write the version as 2 bytes. */ { - Dwarf_Half verstamp = CURRENT_VERSION_STAMP; + Dwarf_Half verstamp = version; WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &verstamp, - sizeof(verstamp), sizeof(Dwarf_Half)); - arange_ptr += sizeof(Dwarf_Half); + sizeof(verstamp), DWARF_HALF_SIZE); + arange_ptr += DWARF_HALF_SIZE; } /* Write the .debug_info offset. This is always 0. */ WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, - sizeof(big_zero), uword_size); - arange_ptr += uword_size; + sizeof(big_zero), offset_size); + arange_ptr += offset_size; { unsigned long count = dbg->de_arange_count + 1; int res2 = 0; + Dwarf_P_Per_Reloc_Sect p_reloc = + &dbg->de_reloc_sect[DEBUG_ARANGES]; - if (dbg->de_reloc_pair) { + if (dbg->de_relocate_pair_by_symbol) { count = (3 * dbg->de_arange_count) + 1; } /* The following is a small optimization: not needed for - correctness */ - res2 = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, - DEBUG_ARANGES, count); + correctness. Does nothing if + preloc->pr_first_block is non-null */ + res2 = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, + p_reloc, count); if (res2 != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } } /* reloc for .debug_info */ - res = dbg->de_reloc_name(dbg, + res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES, extension_word_size + - uword_size + sizeof(Dwarf_Half), + offset_size + DWARF_HALF_SIZE, dbg->de_sect_name_idx[DEBUG_INFO], - dwarf_drt_data_reloc, uword_size); + dwarf_drt_data_reloc, offset_size); + if (res == DW_DLV_NO_ENTRY) { + return res; + } + if (res == DW_DLV_ERROR) { + _dwarf_p_error(dbg, error,DW_DLE_RELOCS_ERROR); + return res; + } /* Write the size of addresses. */ *arange_ptr = dbg->de_pointer_size; @@ -244,13 +286,13 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) given_arange = given_arange->ag_next) { /* Write relocation record for beginning of address range. */ - res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, + res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset */ (long) given_arange->ag_symbol_index, dwarf_drt_data_reloc, upointer_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } /* Copy beginning address of range. */ @@ -260,7 +302,7 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) upointer_size); arange_ptr += upointer_size; - if (dbg->de_reloc_pair && + if (dbg->de_relocate_pair_by_symbol && given_arange->ag_end_symbol_index != 0 && given_arange->ag_length == 0) { /* symbolic reloc, need reloc for length What if we really @@ -268,7 +310,8 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) 'if'. */ Dwarf_Unsigned val; - res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, + res = dbg->de_relocate_pair_by_symbol(dbg, + DEBUG_ARANGES, arange_ptr - arange, /* r_offset */ given_arange->ag_symbol_index, given_arange->ag_end_symbol_index, @@ -276,7 +319,7 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) upointer_size); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } /* arange pre-calc so assem text can do .word end - begin @@ -306,5 +349,6 @@ _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) WRITE_UNALIGNED(dbg, (void *) arange_ptr, (const void *) &big_zero, sizeof(big_zero), upointer_size); - return (int) dbg->de_n_debug_sect; + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_die.c b/thirdparty/dwarf/pro_die.c index 97ffa287..d93c6738 100644 --- a/thirdparty/dwarf/pro_die.c +++ b/thirdparty/dwarf/pro_die.c @@ -2,43 +2,64 @@ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + Portions Copyright 2011-2017 David Anderson. All Rights Reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ #include "config.h" #include "libdwarfdefs.h" #include +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ #include +#include #include "pro_incl.h" +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_util.h" +#include "pro_alloc.h" #include "pro_die.h" +#include "pro_section.h" +#include "dwarf_tsearch.h" #ifndef R_MIPS_NONE #define R_MIPS_NONE 0 #endif -/* adds an attribute to a die */ -void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr); +#define TRUE 1 +#define FALSE 0 /* This function creates a new die. tag: tag of the new die to be created @@ -49,37 +70,88 @@ dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag tag, Dwarf_P_Die parent, Dwarf_P_Die child, - Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) + Dwarf_P_Die left, Dwarf_P_Die right, + Dwarf_Error * error) +{ + Dwarf_P_Die created = 0; + int res = 0; + + res = dwarf_new_die_a(dbg,tag,parent,child, + left,right,&created,error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Die)DW_DLV_BADADDR; + } + return created; +} + +/* New September 2016. Preferred as error checking + is easier, no need for ugly cast. */ +int +dwarf_new_die_a(Dwarf_P_Debug dbg, + Dwarf_Tag tag, + Dwarf_P_Die parent, + Dwarf_P_Die child, + Dwarf_P_Die left, Dwarf_P_Die right, + Dwarf_P_Die *die_out, + Dwarf_Error *error) { Dwarf_P_Die ret_die = 0; + int res = 0; - Dwarf_P_Die new_die = (Dwarf_P_Die) + ret_die = (Dwarf_P_Die) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s)); - if (new_die == NULL) { + if (ret_die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC, - (Dwarf_P_Die) DW_DLV_BADADDR); - } - new_die->di_parent = NULL; - new_die->di_left = NULL; - new_die->di_right = NULL; - new_die->di_child = NULL; - new_die->di_last_child = NULL; - new_die->di_tag = tag; - new_die->di_dbg = dbg; - new_die->di_marker = 0; - ret_die = - dwarf_die_link(new_die, parent, child, left, right, error); - return ret_die; + DW_DLV_ERROR); + } + ret_die->di_parent = NULL; + ret_die->di_left = NULL; + ret_die->di_right = NULL; + ret_die->di_child = NULL; + ret_die->di_last_child = NULL; + ret_die->di_tag = tag; + ret_die->di_dbg = dbg; + ret_die->di_marker = 0; + res = dwarf_die_link_a(ret_die, parent, child, left, right, + error); + if (res != DW_DLV_OK) { + _dwarf_p_dealloc(dbg,(Dwarf_Small *)ret_die); + ret_die = 0; + } else { + *die_out = ret_die; + } + return res; } /* This function links up a die to specified neighbors parent,child,left,right: specify neighbors of the new die. Only - one of these may be non-null */ + one of these may be non-null + This is the original version. Use dwarf_die_link_a() + instead as that function is easier to use (in checking for error). + */ Dwarf_P_Die dwarf_die_link(Dwarf_P_Die new_die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) +{ + int res = 0; + + res = dwarf_die_link_a(new_die,parent,child,left,right,error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Die)DW_DLV_BADADDR; + } + return new_die; +} + +/* New September 2016. + Error return easier to deal with + than dwarf_die_link(). */ +int +dwarf_die_link_a(Dwarf_P_Die new_die, + Dwarf_P_Die parent, + Dwarf_P_Die child, + Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error) { /* Count the # of non null neighbors. */ int n_nulls = 0; @@ -88,7 +160,7 @@ dwarf_die_link(Dwarf_P_Die new_die, n_nulls++; if (new_die->di_parent != NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP, - (Dwarf_P_Die) DW_DLV_BADADDR); + DW_DLV_ERROR); } new_die->di_parent = parent; if (parent->di_child) { @@ -112,7 +184,7 @@ dwarf_die_link(Dwarf_P_Die new_die, new_die->di_last_child = child; if (child->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, - (Dwarf_P_Die) DW_DLV_BADADDR); + DW_DLV_ERROR); } else { child->di_parent = new_die; } @@ -129,7 +201,7 @@ dwarf_die_link(Dwarf_P_Die new_die, left->di_right = new_die; if (new_die->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, - (Dwarf_P_Die) DW_DLV_BADADDR); + DW_DLV_ERROR); } else { new_die->di_parent = left->di_parent; } @@ -146,7 +218,7 @@ dwarf_die_link(Dwarf_P_Die new_die, right->di_left = new_die; if (new_die->di_parent) { DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS, - (Dwarf_P_Die) DW_DLV_BADADDR); + DW_DLV_ERROR); } else { new_die->di_parent = right->di_parent; } @@ -154,24 +226,35 @@ dwarf_die_link(Dwarf_P_Die new_die, if (n_nulls > 1) { /* Multiple neighbors! error! */ DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS, - (Dwarf_P_Die) DW_DLV_BADADDR); + DW_DLV_ERROR); } - return new_die; - + return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_die_marker(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Unsigned marker, - Dwarf_Error * error) -{ + Dwarf_Error * error) { if (die == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); } die->di_marker = marker; return 0; } +int +dwarf_add_die_marker_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned marker, + Dwarf_Error * error) +{ + if (die == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, + DW_DLV_ERROR); + } + die->di_marker = marker; + return DW_DLV_OK; +} Dwarf_Unsigned @@ -181,29 +264,59 @@ dwarf_get_die_marker(Dwarf_P_Debug dbg, Dwarf_Error * error) { if (die == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, + DW_DLV_NOCOUNT); } *marker = die->di_marker; return 0; } +int +dwarf_get_die_marker_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + Dwarf_Unsigned * marker, + Dwarf_Error * error) +{ + if (die == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, + DW_DLV_ERROR); + } + *marker = die->di_marker; + return DW_DLV_ERROR; +} -/*---------------------------------------------------------------------------- - This function adds a die to dbg struct. It should be called using - the root of all the dies. ------------------------------------------------------------------------------*/ +/*--------------------------------------------------------- + This function adds a die to dbg struct. It should + be called using the root of all the dies. +---------------------------------------------------------*/ +/* Original form of this call.. + dwarf_add_die_to_debug_a() is preferred now. */ Dwarf_Unsigned dwarf_add_die_to_debug(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error) +{ + int res = dwarf_add_die_to_debug_a(dbg,first_die,error); + if (res == DW_DLV_ERROR) { + return DW_DLV_NOCOUNT; + } + return 0; +} + +/* New September 2016. The new and preferred form. */ +int +dwarf_add_die_to_debug_a(Dwarf_P_Debug dbg, + Dwarf_P_Die first_die, Dwarf_Error * error) { if (first_die == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, + DW_DLV_ERROR); } if (first_die->di_tag != DW_TAG_compile_unit) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, + DW_DLV_ERROR); } dbg->de_dies = first_die; - return 0; + return DW_DLV_OK; } int @@ -215,13 +328,16 @@ _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, /* Add AT_stmt_list attribute */ new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(dbg, + sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, + DW_DLV_ERROR); } new_attr->ar_attribute = DW_AT_stmt_list; - new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form; + new_attr->ar_attribute_form = + dbg->de_ar_data_attribute_form; new_attr->ar_rel_type = dbg->de_offset_reloc; new_attr->ar_nbytes = uwordb_size; @@ -230,7 +346,8 @@ _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(NULL,DW_DLE_ADDR_ALLOC, + DW_DLV_ERROR); } { Dwarf_Unsigned du = 0; @@ -240,96 +357,438 @@ _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, } _dwarf_pro_add_at_to_die(first_die, new_attr); - return 0; + return DW_DLV_OK; +} + +static int +_dwarf_debug_str_compare_func(const void *l,const void *r) +{ + const struct Dwarf_P_debug_str_entry_s*el = l; + const struct Dwarf_P_debug_str_entry_s*er = r; + char *lname = 0; + char *rname = 0; + int ir = 0; + + if (el->dse_has_table_offset) { + /* When set the name is in the debug_str table. */ + /* ASSERT: dse_dbg->de_debug_str->ds_data + is non-zero. + ASSERT: dse_name NULL. */ + lname = el->dse_dbg->de_debug_str->ds_data + + el->dse_table_offset; + } else { + /* ASSERT: dse_name non-null */ + lname = el->dse_name; + } + if (er->dse_has_table_offset) { + /* When set the name is in the debug_str table. */ + /* ASSERT: dse_dbg->de_debug_str->ds_data + is non-zero. + ASSERT: dse_name NULL. */ + rname = er->dse_dbg->de_debug_str->ds_data + + er->dse_table_offset; + } else { + /* ASSERT: dse_name non-null */ + rname = er->dse_name; + } + ir = strcmp(lname,rname); + return ir; +} + +static void +debug_str_entry_free_func(void *m) +{ + free(m); +} + +static int +make_debug_str_entry(Dwarf_P_Debug dbg, + struct Dwarf_P_debug_str_entry_s **mt_out, + char *name, + unsigned slen, + unsigned char has_offset, + Dwarf_Unsigned offset_in_table, + Dwarf_Error *error) +{ + struct Dwarf_P_debug_str_entry_s *mt = + (struct Dwarf_P_debug_str_entry_s *)calloc( + sizeof(struct Dwarf_P_debug_str_entry_s),1); + if (!mt) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + + mt->dse_slen = slen; + mt->dse_table_offset = 0; + mt->dse_dbg = dbg; + if (has_offset) { + mt->dse_has_table_offset = TRUE; + mt->dse_table_offset = offset_in_table; + mt->dse_name = 0; + } else { + /* ASSERT: name != NULL */ + mt->dse_has_table_offset = FALSE; + /* We just set dse_table_offset so it has + a known value, though nothing should refer + to dse_table_offset because + dse_has_table_offset is FALSE.*/ + mt->dse_table_offset = 0; + mt->dse_name = name; + } + *mt_out = mt; + return DW_DLV_OK; +} +#define STRTAB_BASE_ALLOC_SIZE 2048 +static int +insert_debug_str_data_string(Dwarf_P_Debug dbg, + char *name, + unsigned slen, + Dwarf_P_Section_Data sd, + Dwarf_Unsigned*adding_at_offset, + Dwarf_Error * error) +{ + Dwarf_Unsigned current_offset = 0; + + if (!sd->ds_data) { + Dwarf_Unsigned initial_alloc = STRTAB_BASE_ALLOC_SIZE; + Dwarf_Unsigned base_insert_offset = 0; + + /* Inserting our first string. + The GNU linker refuses to commonize strings + if the section starts with a NUL byte, + so start with real string, using a + base_insert_offset of 0. */ + if ( (slen + base_insert_offset) >= STRTAB_BASE_ALLOC_SIZE) { + initial_alloc = slen *2+ base_insert_offset; + } + if (initial_alloc < slen) { + _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND); + return DW_DLV_ERROR; + } + sd->ds_data = calloc(1,initial_alloc); + if (!sd->ds_data) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + sd->ds_orig_alloc = initial_alloc; + *adding_at_offset = base_insert_offset; + sd->ds_nbytes = slen + base_insert_offset; + strcpy(sd->ds_data+base_insert_offset,name); + return DW_DLV_OK; + } + current_offset = sd->ds_nbytes; + if ( (current_offset + slen) >= sd->ds_orig_alloc) { + unsigned updated_length = sd->ds_orig_alloc; + char *newbuf = 0; + if (slen > updated_length) { + /* Very long string passed in. */ + updated_length = slen *2; + } else { + updated_length = updated_length *2; + } + if (updated_length < sd->ds_orig_alloc) { + _dwarf_p_error(dbg, error, DW_DLE_SIZE_WRAPAROUND); + return DW_DLV_ERROR; + } + newbuf = calloc(1,updated_length); + if (!newbuf) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + memcpy(newbuf,sd->ds_data,sd->ds_nbytes); + free(sd->ds_data); + sd->ds_data = newbuf; + sd->ds_orig_alloc = updated_length; + newbuf = 0; + } + strcpy(sd->ds_data + current_offset,name); + sd->ds_nbytes += slen; + *adding_at_offset = current_offset; + return DW_DLV_OK; +} + +/* Find the string offset using the hash table, + and if not known, insert the new string. */ +int +_dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg, + char *name, + enum dwarf_which_hash whash, + unsigned slen, /* includes space for trailing NUL */ + Dwarf_Unsigned *offset_in_debug_str, + Dwarf_Error *error) +{ + struct Dwarf_P_debug_str_entry_s *mt = 0; + struct Dwarf_P_debug_str_entry_s *mt2 = 0; + struct Dwarf_P_debug_str_entry_s *retval = 0; + struct Dwarf_P_debug_str_entry_s *re = 0; + int res = 0; + Dwarf_Unsigned adding_at_offset = 0; + void **hashtab = 0; + Dwarf_P_Section_Data sd = 0; + struct Dwarf_P_Str_stats_s * stats = 0; + + switch (whash) { + case _dwarf_hash_debug_str: + hashtab = &dbg->de_debug_str_hashtab; + sd = dbg->de_debug_str; + stats = &dbg->de_stats.ps_strp; + break; + case _dwarf_hash_debug_line_str: + hashtab = &dbg->de_debug_line_str_hashtab; + sd = dbg->de_debug_line_str; + stats = &dbg->de_stats.ps_line_strp; + break; + case _dwarf_hash_debug_str_sup: + default: + /* Not supported or unknown. */ + _dwarf_p_error(dbg, error, DW_DLE_STRING_HASHTAB_IDENTITY_ERROR); + return DW_DLV_ERROR; + } + res = make_debug_str_entry(dbg,&mt,name, + slen,FALSE, 0, error); + if (res != DW_DLV_OK) { + return res; + } + /* We do a find as we do not want the string pointer passed in + to be in the hash table, we want a pointer into the + debug_str table in the hash table. */ + retval = dwarf_tfind(mt,(void *const*)hashtab, + _dwarf_debug_str_compare_func); + if (retval) { + + stats->ps_strp_reused_count++; + stats->ps_strp_reused_len += slen; + + re = *(struct Dwarf_P_debug_str_entry_s **)retval; + *offset_in_debug_str = re->dse_table_offset; + debug_str_entry_free_func(mt); + return DW_DLV_OK; + } + + /* We know the string is not in .debug_str data yet. + Insert it into the big string table and get that + offset. */ + + debug_str_entry_free_func(mt); + mt = 0; + res = insert_debug_str_data_string(dbg,name,slen,sd, + &adding_at_offset, error); + if (res != DW_DLV_OK) { + return res; + } + + /* The name is in the string table itself, so use that pointer + and offset for the string. */ + res = make_debug_str_entry(dbg,&mt2, 0, + slen,TRUE,adding_at_offset,error); + if (res != DW_DLV_OK) { + return res; + } + retval = dwarf_tsearch(mt2, + (void *)hashtab, + _dwarf_debug_str_compare_func); + if (!retval) { + debug_str_entry_free_func(mt2); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + + /* This indirection is one of the surprises in using tsearch... */ + re = *(struct Dwarf_P_debug_str_entry_s **)retval; + if (re != mt2) { + debug_str_entry_free_func(mt2); + /* Found it in hash tab: illogical as the tsearch_find should + have found it. */ + _dwarf_p_error(dbg, error, DW_DLE_ILLOGICAL_TSEARCH); + return DW_DLV_ERROR; + } + stats->ps_strp_count_debug_str++; + stats->ps_strp_len_debug_str += slen; + /* we added it to hash, do not free mt2 (which == re). */ + *offset_in_debug_str = re->dse_table_offset; + return DW_DLV_OK; +} + +/* Returns DW_DLV_OK or DW_DLV_ERROR. */ +int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr, + Dwarf_P_Debug dbg, + char *name, + Dwarf_Error *error) +{ + int form = dbg->de_debug_default_str_form; + unsigned slen = strlen(name)+1; + + if (form == DW_FORM_string || + slen <= dbg->de_offset_size) { + new_attr->ar_nbytes = slen; + new_attr->ar_next = 0; + + new_attr->ar_data = + (char *) _dwarf_p_get_alloc(dbg, slen); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + dbg->de_stats.ps_str_count++; + dbg->de_stats.ps_str_total_length += slen; + + strcpy(new_attr->ar_data, name); + new_attr->ar_attribute_form = DW_FORM_string; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + return DW_DLV_OK; + } + if (form == DW_FORM_strp) { + int uwordb_size = dbg->de_offset_size; + Dwarf_Unsigned offset_in_debug_str = 0; + int res = 0; + + res = _dwarf_insert_or_find_in_debug_str(dbg,name, + _dwarf_hash_debug_str,slen, + &offset_in_debug_str,error); + if(res != DW_DLV_OK) { + return res; + } + new_attr->ar_attribute_form = form; + new_attr->ar_rel_type = dbg->de_offset_reloc; + new_attr->ar_nbytes = uwordb_size; + new_attr->ar_next = NULL; + new_attr->ar_reloc_len = uwordb_size; + /* During transform to disk + a symbol index will be applied. */ + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, uwordb_size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + { + Dwarf_Unsigned du = offset_in_debug_str; + + WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, + (const void *) &du, sizeof(du), uwordb_size); + } + + return DW_DLV_OK; + } + _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM); + return DW_DLV_ERROR; + } -/*----------------------------------------------------------------------------- + +/*------------------------------------------------------------------- Add AT_name attribute to die -------------------------------------------------------------------------------*/ +---------------------------------------------------------------------*/ +/* Original function. dwarf_add_AT_name_a() is the + suggested alternative. */ Dwarf_P_Attribute -dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error) +dwarf_add_AT_name(Dwarf_P_Die die, + char *name, + Dwarf_Error * error) { - Dwarf_P_Attribute new_attr; + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_name_a(die, name, + &a, error); + if (res == DW_DLV_ERROR) { + return (Dwarf_P_Attribute)(DW_DLV_BADADDR); + } + return a; +} + +/* New December 2018. */ +int +dwarf_add_AT_name_a(Dwarf_P_Die die, char *name, + Dwarf_P_Attribute *newattr_out, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr = 0; + int res = 0; if (die == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, - (Dwarf_P_Attribute) DW_DLV_BADADDR); + DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(die->di_dbg,sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(die->di_dbg, + sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, - (Dwarf_P_Attribute) DW_DLV_BADADDR); + DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_name; - /* assume that form is string, no debug_str yet */ - new_attr->ar_attribute_form = DW_FORM_string; - new_attr->ar_nbytes = strlen(name) + 1; - new_attr->ar_next = NULL; - new_attr->ar_reloc_len = 0; - new_attr->ar_data = (char *) - _dwarf_p_get_alloc(die->di_dbg, strlen(name)+1); - if (new_attr->ar_data == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC, - (Dwarf_P_Attribute) DW_DLV_BADADDR); + res = _dwarf_pro_set_string_attr(new_attr,die->di_dbg,name,error); + if (res != DW_DLV_OK) { + return DW_DLV_ERROR; } - strcpy(new_attr->ar_data, name); - - new_attr->ar_rel_type = R_MIPS_NONE; /* add attribute to the die */ _dwarf_pro_add_at_to_die(die, new_attr); - return new_attr; + *newattr_out = new_attr; + return DW_DLV_OK; } -/*----------------------------------------------------------------------------- +/*-------------------------------------------------------------------- Add AT_comp_dir attribute to die -------------------------------------------------------------------------------*/ +--------------------------------------------------------------------*/ Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie, char *current_working_directory, Dwarf_Error * error) { - Dwarf_P_Attribute new_attr; + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_comp_dir_a(ownerdie, + current_working_directory, + &a, error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Attribute)(DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_comp_dir_a(Dwarf_P_Die ownerdie, + char *current_working_directory, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr = 0; + int res = 0; if (ownerdie == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, - (Dwarf_P_Attribute) DW_DLV_BADADDR); + DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, - (Dwarf_P_Attribute) DW_DLV_BADADDR); + DW_DLV_ERROR); } /* fill in the information */ new_attr->ar_attribute = DW_AT_comp_dir; - /* assume that form is string, no debug_str yet */ - new_attr->ar_attribute_form = DW_FORM_string; - new_attr->ar_nbytes = strlen(current_working_directory) + 1; - new_attr->ar_next = NULL; - new_attr->ar_reloc_len = 0; - new_attr->ar_data = (char *) - _dwarf_p_get_alloc(ownerdie->di_dbg, - strlen(current_working_directory)+1); - if (new_attr->ar_data == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC, - (Dwarf_P_Attribute) DW_DLV_BADADDR); + res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg, + current_working_directory,error); + if (res != DW_DLV_OK) { + return res; } - strcpy(new_attr->ar_data, current_working_directory); - - new_attr->ar_rel_type = R_MIPS_NONE; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } + int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die, @@ -339,12 +798,12 @@ _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, int uwordb_size = dbg->de_offset_size; if (die == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1); + DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1); + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ @@ -357,7 +816,7 @@ _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = offset; @@ -365,12 +824,11 @@ _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data, (const void *) &du, sizeof(du), uwordb_size); } - _dwarf_pro_add_at_to_die(die, new_attr); - - return 0; + return DW_DLV_OK; } +/* Sept 2016: returns DW_DLV_OK or DW_DLV_ERROR */ int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, Dwarf_P_Die die, @@ -380,12 +838,12 @@ _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, int uwordb_size = dbg->de_offset_size; if (die == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1); + DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, DW_DLV_ERROR); } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1); + DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_ERROR); } /* fill in the information */ @@ -399,7 +857,7 @@ _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, new_attr->ar_data = (char *) _dwarf_p_get_alloc(dbg, uwordb_size); if (new_attr->ar_data == NULL) { - DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_ERROR); } { Dwarf_Unsigned du = offset; @@ -410,7 +868,7 @@ _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, _dwarf_pro_add_at_to_die(die, new_attr); - return 0; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_die.h b/thirdparty/dwarf/pro_die.h index 7e40313b..2d2c560a 100644 --- a/thirdparty/dwarf/pro_die.h +++ b/thirdparty/dwarf/pro_die.h @@ -38,8 +38,11 @@ struct Dwarf_P_Abbrev_s { Dwarf_Unsigned abb_idx; /* index of abbreviation */ Dwarf_Tag abb_tag; /* tag of die */ Dwarf_Ubyte abb_children; /* if children are present */ - Dwarf_ufixed *abb_attrs; /* holds names of attrs */ - Dwarf_ufixed *abb_forms; /* forms of attributes */ + Dwarf_Unsigned *abb_attrs; /* holds names of attrs */ + Dwarf_Unsigned *abb_forms; /* forms of attributes */ + + /* 0 but if DW_FORM_implicit_value is value */ + Dwarf_Signed *abb_implicits; int abb_n_attr; /* num of attrs = # of forms */ Dwarf_P_Abbrev abb_next; }; @@ -53,7 +56,16 @@ int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Error * error); + int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, Dwarf_Unsigned offset, Dwarf_Error * error); + +int _dwarf_pro_set_string_attr(Dwarf_P_Attribute new_attr, + Dwarf_P_Debug dbg, + char *name, + Dwarf_Error *error); + +/* adds an attribute to a die */ +void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr); diff --git a/thirdparty/dwarf/pro_dnames.c b/thirdparty/dwarf/pro_dnames.c new file mode 100644 index 00000000..ac43b384 --- /dev/null +++ b/thirdparty/dwarf/pro_dnames.c @@ -0,0 +1,76 @@ +/* + Copyright 2018-2018 David Anderson. All Rights Reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. + +*/ + +#include "config.h" +#include "libdwarfdefs.h" +#include +#include +#ifdef HAVE_ELFACCESS_H +#include +#endif +#include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" +#include "pro_arange.h" +#include "pro_section.h" +#include "pro_reloc.h" +#include "pro_dnames.h" + +#define FALSE 0 +#define TRUE 1 + + +int +dwarf_force_debug_names(Dwarf_P_Debug dbg, + Dwarf_Error * error) +{ + + Dwarf_P_Dnames dn; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return DW_DLV_ERROR; + } + + dn = (Dwarf_P_Dnames) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Dnames_s)); + if (dn == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + if (!dbg->de_dnames) { + dbg->de_dnames = dn; + } + dn->dn_create_section = TRUE; + + return DW_DLV_OK; +} diff --git a/thirdparty/dwarf/pro_dnames.h b/thirdparty/dwarf/pro_dnames.h new file mode 100644 index 00000000..d9d65f4d --- /dev/null +++ b/thirdparty/dwarf/pro_dnames.h @@ -0,0 +1,81 @@ +/* + Copyright (C) 2018 David Anderson All Rights Reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. + +*/ + +/* The numbers here are almost all 32 bits. + Not long long ever. + In the public function interfaces we'll use Dwarf_Unsigned though, + for call consistency with everything else. + Here we use Dwarf_Unsigned to avoid having to + even know what is or is not 32 bits. */ + +typedef Dwarf_Unsigned dn_type; + +struct Dwarf_P_Dnames_Head_s { + Dwarf_Unsigned dh_unit_length; + unsigned dh_version; + dn_type dh_comp_unit_count; + dn_type dh_local_type_unit_count; + dn_type dh_foreign_type_unit_count; + dn_type dh_bucket_count; + dn_type dh_name_count; + dn_type dh_abbrev_table_size; + dn_type dh_augmentation_string_size; + const char * dh_augmentation_string; +}; + +struct Dwarf_P_Dnames_uarray_s { + dn_type dne_allocated; + dn_type dne_used; + dn_type *dne_values; +}; +struct Dwarf_P_Dnames_sarray_s { + dn_type dne_allocated; + dn_type dne_used; + Dwarf_Sig8 *dne_values; +}; + + +struct Dwarf_P_Dnames_s { + Dwarf_Small dn_create_section; + struct Dwarf_P_Dnames_Head_s dn_header; + struct Dwarf_P_Dnames_uarray_s dn_cunit_offset; + struct Dwarf_P_Dnames_uarray_s dn_tunit_offset; + struct Dwarf_P_Dnames_sarray_s dn_sunit_sigs; + + struct Dwarf_P_Dnames_uarray_s dn_buckets; + + /* Hashes count applies to string offsets and entry offsets arrays too. */ + struct Dwarf_P_Dnames_uarray_s dn_hashes; + struct Dwarf_P_Dnames_uarray_s dn_string_offsets; + struct Dwarf_P_Dnames_uarray_s dn_entry_pool; + + Dwarf_Small *dn_index_entry_pool; + Dwarf_Small dn_index_entry_pool_size; + Dwarf_Small dn_index_entry_pool_used; + +}; diff --git a/thirdparty/dwarf/pro_encode_nm.c b/thirdparty/dwarf/pro_encode_nm.c index 44c414ef..f280f833 100644 --- a/thirdparty/dwarf/pro_encode_nm.c +++ b/thirdparty/dwarf/pro_encode_nm.c @@ -28,7 +28,9 @@ #include "config.h" #include "libdwarfdefs.h" #include -#include "pro_incl.h" +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_encode_nm.h" #define MORE_BYTES 0x80 #define DATA_MASK 0x7f @@ -64,7 +66,7 @@ _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes, *a = uc; a++; } while (val); - *nbytes = a - space; + *nbytes = (int)(a - space); return DW_DLV_OK; } @@ -103,6 +105,6 @@ _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes, *str = byte; str++; } while (more); - *nbytes = str - space; + *nbytes = (int)(str - space); return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_error.c b/thirdparty/dwarf/pro_error.c index 674157a5..ab526192 100644 --- a/thirdparty/dwarf/pro_error.c +++ b/thirdparty/dwarf/pro_error.c @@ -27,15 +27,19 @@ #include "config.h" #include "libdwarfdefs.h" -#ifdef HAVE_ELF_H -#include -#endif #include #include #include #include #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" + extern char *_dwarf_errmsgs[]; @@ -53,14 +57,13 @@ extern char *_dwarf_errmsgs[]; */ void _dwarf_p_error(Dwarf_P_Debug dbg, - Dwarf_Error * error, Dwarf_Word errval) + Dwarf_Error * error, Dwarf_Unsigned errval) { Dwarf_Error errptr; if (errval > DW_DLE_LAST) { /* We do not expect to ever see such an error number, DW_DLE_LO_USER is not used. */ - /* The 'standard' typedef for Dwarf_Word is "unsigned long". */ fprintf(stderr,"ERROR VALUE: %lu - %s\n", (unsigned long) errval, "this error value is unknown to libdwarf."); } @@ -74,7 +77,7 @@ _dwarf_p_error(Dwarf_P_Debug dbg, "Could not allocate Dwarf_Error structure\n"); abort(); } - errptr->er_errval = (Dwarf_Sword) errval; + errptr->er_errval = (Dwarf_Signed) errval; *error = errptr; return; } @@ -87,7 +90,7 @@ _dwarf_p_error(Dwarf_P_Debug dbg, "Could not allocate Dwarf_Error structure\n"); abort(); } - errptr->er_errval = (Dwarf_Sword) errval; + errptr->er_errval = (Dwarf_Signed) errval; dbg->de_errhand(errptr, dbg->de_errarg); return; } diff --git a/thirdparty/dwarf/pro_error.h b/thirdparty/dwarf/pro_error.h index 37fb741a..40fe8113 100644 --- a/thirdparty/dwarf/pro_error.h +++ b/thirdparty/dwarf/pro_error.h @@ -36,8 +36,8 @@ _dwarf_p_error(dbg,error,errval); return(retval); struct Dwarf_Error_s { - Dwarf_Sword er_errval; + Dwarf_Signed er_errval; }; void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error, - Dwarf_Word errval); + Dwarf_Unsigned errval); diff --git a/thirdparty/dwarf/pro_expr.c b/thirdparty/dwarf/pro_expr.c index f9e224be..6e3acf07 100644 --- a/thirdparty/dwarf/pro_expr.c +++ b/thirdparty/dwarf/pro_expr.c @@ -1,27 +1,30 @@ /* Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2011 David Anderson. All rights reserved. - - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + Portions Copyright 2011-2019 David Anderson. All rights reserved. + + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ @@ -29,9 +32,26 @@ #include "libdwarfdefs.h" #include #include +#include +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ #include "pro_incl.h" +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" #include "pro_expr.h" +#define SIZEOFT16 2 +#define SIZEOFT32 4 +#define SIZEOFT64 8 + /* This function creates a new expression struct that can be used to build up a @@ -59,12 +79,31 @@ dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) return (ret_expr); } - Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) +{ + Dwarf_Unsigned len = 0; + int res = 0; + + res = dwarf_add_expr_gen_a(expr,opcode, + val1,val2,&len,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return len; + +} + +int +dwarf_add_expr_gen_a(Dwarf_P_Expr expr, + Dwarf_Small opcode, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, + Dwarf_Unsigned *stream_length_out, + Dwarf_Error * error) { /* 2* since used to concatenate 2 leb's below */ char encode_buffer[2 * ENCODE_SPACE_NEEDED]; @@ -97,13 +136,13 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } dbg = expr->ex_dbg; if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = NULL; @@ -180,7 +219,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -190,7 +229,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -231,7 +270,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, case DW_OP_addr: _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; case DW_OP_const1u: case DW_OP_const1s: @@ -250,8 +289,9 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, case DW_OP_const4u: case DW_OP_const4s: operand = (Dwarf_Small *) & operand_buffer[0]; - WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); - operand_size = 4; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), + SIZEOFT32); + operand_size = SIZEOFT32; break; case DW_OP_const8u: @@ -266,7 +306,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, &operand_size, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -278,7 +318,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -290,7 +330,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -301,7 +341,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; /* put this one directly into 'operand' at tail of prev value */ @@ -311,7 +351,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer2)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand_size += operand2_size; @@ -359,7 +399,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -382,7 +422,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, case DW_OP_bra: /* FIX: unhandled! OP_bra, OP_skip! */ _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; case DW_OP_piece: res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, @@ -390,7 +430,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; break; @@ -401,14 +441,14 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, break; case DW_OP_call2: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; - WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); - operand_size = 2; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT16); + operand_size = SIZEOFT16; break; case DW_OP_call4: /* DWARF3 */ operand = (Dwarf_Small *) & operand_buffer[0]; - WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); - operand_size = 4; + WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32); + operand_size = SIZEOFT32; break; case DW_OP_call_ref: /* DWARF3 */ @@ -427,7 +467,7 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand = (Dwarf_Small *) encode_buffer; /* put this one directly into 'operand' at tail of prev value */ @@ -437,21 +477,20 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, sizeof(encode_buffer2)); if (res != DW_DLV_OK) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } operand_size += operand2_size; - - + break; default: _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } next_byte_ptr = @@ -459,16 +498,38 @@ dwarf_add_expr_gen(Dwarf_P_Expr expr, *next_byte_ptr = opcode; next_byte_ptr++; - memcpy(next_byte_ptr, operand, operand_size); + if (operand) { + memcpy(next_byte_ptr, operand, operand_size); + } expr->ex_next_byte_offset = next_byte_offset; - return (next_byte_offset); + *stream_length_out = next_byte_offset; + return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_addr_b(Dwarf_P_Expr expr, Dwarf_Unsigned addr, - Dwarf_Unsigned sym_index, Dwarf_Error * error) + Dwarf_Unsigned sym_index, + Dwarf_Error * error) +{ + Dwarf_Unsigned length = 0; + int res = 0; + + res = dwarf_add_expr_addr_c(expr,addr,sym_index, + &length,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return length; + +} +int +dwarf_add_expr_addr_c(Dwarf_P_Expr expr, + Dwarf_Unsigned addr, + Dwarf_Unsigned sym_index, + Dwarf_Unsigned *stream_length_out, + Dwarf_Error * error) { Dwarf_P_Debug dbg; Dwarf_Small *next_byte_ptr; @@ -477,20 +538,20 @@ dwarf_add_expr_addr_b(Dwarf_P_Expr expr, if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); - return (DW_DLV_NOCOUNT); + return (DW_DLV_ERROR); } dbg = expr->ex_dbg; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return (DW_DLV_NOCOUNT); + return (DW_DLV_ERROR); } upointer_size = dbg->de_pointer_size; next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); - return (DW_DLV_NOCOUNT); + return (DW_DLV_ERROR); } next_byte_ptr = @@ -503,41 +564,71 @@ dwarf_add_expr_addr_b(Dwarf_P_Expr expr, if (expr->ex_reloc_offset != 0) { _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); - return (DW_DLV_NOCOUNT); + return (DW_DLV_ERROR); } expr->ex_reloc_sym_index = sym_index; expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; expr->ex_next_byte_offset = next_byte_offset; - return (next_byte_offset); + *stream_length_out = next_byte_offset; + return DW_DLV_OK; } Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned addr, - Dwarf_Signed sym_index, Dwarf_Error * error) + Dwarf_Signed sym_index, + Dwarf_Error * error) { - return - dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index, - error); -} + Dwarf_Unsigned length = 0; + int res = 0; + Dwarf_P_Debug dbg = 0; + if (sym_index < 0) { + _dwarf_p_error(dbg, error, + DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD); + return DW_DLV_NOCOUNT; + } + res = dwarf_add_expr_addr_c(expr, + (Dwarf_Unsigned)addr, + (Dwarf_Unsigned)sym_index, + &length,error); + if (res != DW_DLV_OK) { + return (Dwarf_Unsigned)DW_DLV_NOCOUNT; + } + return length; +} Dwarf_Unsigned dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) +{ + Dwarf_Unsigned l = 0; + int res = 0; + + res = dwarf_expr_current_offset_a(expr,&l,error); + if (res != DW_DLV_OK) { + return (DW_DLV_NOCOUNT); + } + return l; +} + +int +dwarf_expr_current_offset_a(Dwarf_P_Expr expr, + Dwarf_Unsigned * stream_length_out, + Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return (DW_DLV_NOCOUNT); + return DW_DLV_ERROR; } - - return (expr->ex_next_byte_offset); + *stream_length_out = expr->ex_next_byte_offset; + return DW_DLV_OK; } void @@ -550,26 +641,40 @@ dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error) expr->ex_next_byte_offset=0; } - Dwarf_Addr dwarf_expr_into_block(Dwarf_P_Expr expr, - Dwarf_Unsigned * length, Dwarf_Error * error) + Dwarf_Unsigned * length, + Dwarf_Error * error) +{ + Dwarf_Small *addr = 0; + int res = 0; + + res = dwarf_expr_into_block_a(expr,length,&addr,error); + if (res != DW_DLV_OK) { + return (DW_DLV_BADADDR); + } + return (Dwarf_Addr)(uintptr_t)addr; +} + + +int +dwarf_expr_into_block_a(Dwarf_P_Expr expr, + Dwarf_Unsigned * length, + Dwarf_Small ** address, + Dwarf_Error * error) { if (expr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); - return (DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (expr->ex_dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return (DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (length != NULL) *length = expr->ex_next_byte_offset; - /* The following cast from pointer to integer is ok as long as - Dwarf_Addr is at least as large as a pointer. Which is a - requirement of libdwarf so must be satisfied (some compilers - emit a warning about the following line). */ - return ((Dwarf_Addr) & (expr->ex_byte_stream[0])); + *address = &(expr->ex_byte_stream[0]); + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_finish.c b/thirdparty/dwarf/pro_finish.c index ac5e68cd..aeacfa86 100644 --- a/thirdparty/dwarf/pro_finish.c +++ b/thirdparty/dwarf/pro_finish.c @@ -1,8 +1,7 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2011 David Anderson. All rights reserved. + Portions Copyright 2011-2018 David Anderson. All rights reserved. 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 @@ -29,17 +28,68 @@ #include "config.h" #include "libdwarfdefs.h" #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" + /* This routine deallocates all memory, and does some - finishing up */ + finishing up + This is the original version using a badly designed return + value approach. + Please use dwarf_producer_finish_a() instead. */ /*ARGSUSED*/ Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + int res = dwarf_producer_finish_a(dbg,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return 0; +} +/* This routine deallocates all memory, and does some + finishing up. New September 2016. */ +int +dwarf_producer_finish_a(Dwarf_P_Debug dbg, Dwarf_Error * error) { if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } /* this frees all blocks, then frees dbg. */ _dwarf_p_dealloc_all(dbg); - return 0; + return DW_DLV_OK ; +} + +/* FIXME: Add stats for debug_line_str. */ +int +dwarf_pro_get_string_stats(Dwarf_P_Debug dbg, + Dwarf_Unsigned * str_count, + Dwarf_Unsigned * str_total_length, + Dwarf_Unsigned * strp_count_debug_str, + Dwarf_Unsigned * strp_len_debug_str, + Dwarf_Unsigned * strp_reused_count, + Dwarf_Unsigned * strp_reused_len, + Dwarf_Error * error) +{ + struct Dwarf_P_Str_stats_s* ps = 0; + if (!dbg) { + _dwarf_p_error(dbg, error, DW_DLE_IA); + return DW_DLV_ERROR; + } + if (dbg->de_version_magic_number !=PRO_VERSION_MAGIC ) { + _dwarf_p_error(dbg, error, DW_DLE_VMM); + return DW_DLV_ERROR; + } + *str_count = dbg->de_stats.ps_str_count; + *str_total_length = dbg->de_stats.ps_str_total_length; + ps = &dbg->de_stats.ps_strp; + *strp_count_debug_str = ps->ps_strp_count_debug_str; + *strp_len_debug_str = ps->ps_strp_len_debug_str; + *strp_reused_count = ps->ps_strp_reused_count; + *strp_reused_len = ps->ps_strp_reused_len; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_forms.c b/thirdparty/dwarf/pro_forms.c index 663e6094..018b97cd 100644 --- a/thirdparty/dwarf/pro_forms.c +++ b/thirdparty/dwarf/pro_forms.c @@ -32,6 +32,14 @@ #include #include #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" +#include "pro_die.h" #include "pro_expr.h" #ifndef R_MIPS_NONE @@ -43,22 +51,83 @@ #define NO_ELF_SYM_INDEX 0 -/* Adds an attribute to a die */ -extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, - Dwarf_P_Attribute attr); +#ifdef WORDS_BIGENDIAN +#define ASNAR(t,s,l) \ + do { \ + unsigned tbyte = sizeof(t) - l; \ + t = 0; \ + memcpy(((char *)&t)+tbyte ,&s[0],l);\ + } while (0) +#else /* LITTLE ENDIAN */ +#define ASNAR(t,s,l) \ + do { \ + t = 0; \ + memcpy(&t,&s[0],l); \ + } while (0) +#endif /* end LITTLE- BIG-ENDIAN */ + + +#ifdef WORDS_BIGENDIAN +#define ASNOUT(t,s,l) \ + do { \ + unsigned sbyte = 0; \ + char *p = 0; \ + if (l > sizeof(s)) { \ + _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ + return DW_DLV_ERROR; \ + } \ + sbyte = sizeof(s) - l; \ + p = (const char *)(&s); \ + memcpy(t,(const void *)(p+sbyte),l);\ + } while (0) +#else /* LITTLEENDIAN */ +#define ASNOUT(t,s,l) \ + do { \ + const char *p = 0; \ + if (l > sizeof(s)) { \ + _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ + return DW_DLV_ERROR; \ + } \ + p = (const char *)(&s); \ + memcpy(t,(const void *)p,l); \ + } while (0) +#endif /* ENDIANNESS */ + +#ifdef WORDS_BIGENDIAN +#define SIGN_EXTEND(dest, length) \ + do { \ + if (*(Dwarf_Sbyte *)((char *)&dest + \ + sizeof(dest) - length) < 0) { \ + memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\ + sizeof(dest) - length); \ + } \ + } while (0) +#else /* LITTLE ENDIAN */ +#define SIGN_EXTEND(dest, length) \ + do { \ + if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \ + memcpy((char *)&dest+length, \ + "\xff\xff\xff\xff\xff\xff\xff\xff", \ + sizeof(dest) - length); \ + } \ + } while (0) + +#endif /* ! LITTLE_ENDIAN */ + /* This function adds an attribute whose value is a target address to the given die. The attribute is given the name provided by attr. The address is given in pc_value. */ -static Dwarf_P_Attribute -local_add_AT_address(Dwarf_P_Debug dbg, +static int +local_add_AT_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed form, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, + Dwarf_P_Attribute *attr_out, Dwarf_Error * error); /* old interface */ @@ -69,12 +138,22 @@ dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error * error) { - return - dwarf_add_AT_targ_address_b(dbg, - ownerdie, - attr, - pc_value, - (Dwarf_Unsigned) sym_index, error); + Dwarf_P_Attribute a = 0; + int res = 0; + + if (sym_index < 0) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + res = dwarf_add_AT_targ_address_c(dbg, + ownerdie, attr, pc_value, + (Dwarf_Unsigned) sym_index, + &a, + error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; + } /* New interface, replacing dwarf_add_AT_targ_address. @@ -88,6 +167,29 @@ dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_Unsigned sym_index, Dwarf_Error * error) { + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_targ_address_c(dbg, + ownerdie,attr,pc_value,sym_index, + &a, error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; + +} +int +dwarf_add_AT_targ_address_c(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + int res = 0; + switch (attr) { case DW_AT_low_pc: case DW_AT_high_pc: @@ -108,13 +210,14 @@ dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } - return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr, - pc_value, sym_index, error); + res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_addr, + pc_value, sym_index,attr_out, error); + return res; } Dwarf_P_Attribute @@ -125,6 +228,28 @@ dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_Unsigned sym_index, Dwarf_Error * error) { + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_ref_address_a(dbg,ownerdie, + attr,pc_value,sym_index,&a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_ref_address_a(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + int res = 0; + switch (attr) { case DW_AT_type: case DW_AT_import: @@ -133,7 +258,7 @@ dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } @@ -141,19 +266,22 @@ dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, /* FIXME: For DWARF3 and later this call is problematic as DW_FORM_ref_addr is really an offset in .debug_info , not an address. */ - return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr, - pc_value, sym_index, error); + res = local_add_AT_address_a(dbg, ownerdie, + attr, DW_FORM_ref_addr, + pc_value, sym_index,attr_out, error); + return res; } /* Make sure attribute types are checked before entering here. */ -static Dwarf_P_Attribute -local_add_AT_address(Dwarf_P_Debug dbg, +static int +local_add_AT_address_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Signed form, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, + Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr; @@ -161,13 +289,13 @@ local_add_AT_address(Dwarf_P_Debug dbg, if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } upointer_size = dbg->de_pointer_size; if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } /* attribute types have already been checked */ @@ -177,7 +305,7 @@ local_add_AT_address(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -196,7 +324,7 @@ local_add_AT_address(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, upointer_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &pc_value, @@ -204,16 +332,99 @@ local_add_AT_address(Dwarf_P_Debug dbg, /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } +/* Pass in array (ie a pointer to) of Dwarf_Signed + with input_array_length elements. + + A block of bytes is created + with the sleb data in it. + + A pointer to the glob of bytes is returned + through the output_block pointer and its length + through output_block_len pointer. */ +int +dwarf_compress_integer_block_a( + Dwarf_P_Debug dbg, + Dwarf_Unsigned input_array_length, + Dwarf_Signed * input_array, + Dwarf_Unsigned *output_block_len, + void ** output_block_returned, + Dwarf_Error* error +) +{ + Dwarf_Unsigned output_length_in_bytes = 0; + char * output_block = 0; + char encode_buffer[ENCODE_SPACE_NEEDED]; + unsigned u = 0; + char * ptr = 0; + int remain = 0; + int result = 0; + + if (dbg == NULL) { + _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); + return DW_DLV_ERROR; + } + /* First compress everything to find the total size. */ + + output_length_in_bytes = 0; + for (u=0; ude_ar_data_attribute_form, pc_value, sym_index, + attr_out, error); + return res; } +Dwarf_P_Attribute +dwarf_add_AT_dataref( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned pc_value, + Dwarf_Unsigned sym_index, + Dwarf_Error * error) +{ + Dwarf_P_Attribute a = 0; + int res = 0; + + /* TODO: Add checking here */ + res = local_add_AT_address_a(dbg, ownerdie, attr, + dbg->de_ar_data_attribute_form, + pc_value, + sym_index, + &a, + error); + if (res != DW_DLV_OK) { + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + return a; +} Dwarf_P_Attribute dwarf_add_AT_block( @@ -354,8 +598,27 @@ dwarf_add_AT_block( Dwarf_Half attr, Dwarf_Small *block_data, Dwarf_Unsigned block_size, - Dwarf_Error *error -) + Dwarf_Error *error) +{ + int res = 0; + Dwarf_P_Attribute new_attr = 0; + + res = dwarf_add_AT_block_a(dbg,ownerdie,attr, + block_data,block_size,&new_attr,error); + if (res != DW_DLV_OK) { + return((Dwarf_P_Attribute)DW_DLV_BADADDR); + } + return new_attr; +} +int +dwarf_add_AT_block_a( + Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Small *block_data, + Dwarf_Unsigned block_size, + Dwarf_P_Attribute* attr_out, + Dwarf_Error *error) { Dwarf_P_Attribute new_attr = 0; int result = 0; @@ -365,12 +628,12 @@ dwarf_add_AT_block( if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return((Dwarf_P_Attribute)DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return((Dwarf_P_Attribute)DW_DLV_BADADDR); + return DW_DLV_ERROR; } /* I don't mess with block1, block2, block4, not worth the effort */ @@ -380,7 +643,7 @@ dwarf_add_AT_block( encode_buffer,sizeof(encode_buffer)); if (result != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return((Dwarf_P_Attribute)DW_DLV_BADADDR); + return DW_DLV_ERROR; } /* Allocate the new attribute */ @@ -388,7 +651,7 @@ dwarf_add_AT_block( _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return((Dwarf_P_Attribute)DW_DLV_BADADDR); + return DW_DLV_ERROR; } /* Fill in the attribute */ @@ -403,7 +666,7 @@ dwarf_add_AT_block( /* free the block we got earlier */ _dwarf_p_dealloc(dbg, (unsigned char *) new_attr); _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return((Dwarf_P_Attribute)DW_DLV_BADADDR); + return DW_DLV_ERROR; } /* write length and data to attribute data buffer */ @@ -413,8 +676,8 @@ dwarf_add_AT_block( /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } @@ -429,6 +692,27 @@ dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_Error * error) +{ + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_unsigned_const_a(dbg, + ownerdie,attr,value, + &a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + + +int +dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Unsigned value, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; @@ -436,12 +720,12 @@ dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } switch (attr) { @@ -469,18 +753,21 @@ dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, case DW_AT_start_scope: case DW_AT_stride_size: /* DW_AT_bit_stride is DWARF3 name */ case DW_AT_count: + case DW_AT_high_pc: /* DWARF5: allowing const udata high_pc */ case DW_AT_associated: case DW_AT_allocated: case DW_AT_upper_bound: case DW_AT_lower_bound: case DW_AT_call_file: case DW_AT_call_line: + case DW_AT_data_member_location: + case DW_AT_trampoline: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } @@ -504,7 +791,7 @@ dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -518,14 +805,15 @@ dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &value, sizeof(value), size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } @@ -537,7 +825,27 @@ Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, - Dwarf_Signed value, Dwarf_Error * error) + Dwarf_Signed value, + Dwarf_Error * error) +{ + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_signed_const_a(dbg, + ownerdie,attr,value,&a,error); + if(res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_signed_const_a(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Signed value, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; Dwarf_Half attr_form = 0; @@ -545,12 +853,12 @@ dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } switch (attr) { @@ -570,7 +878,7 @@ dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } @@ -594,7 +902,7 @@ dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -608,14 +916,15 @@ dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } WRITE_UNALIGNED(dbg, new_attr->ar_data, (const void *) &value, sizeof(value), size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } @@ -626,6 +935,26 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error * error) +{ + int res = 0; + Dwarf_P_Attribute a = 0; + + res = dwarf_add_AT_location_expr_a(dbg,ownerdie,attr, + loc_expr,&a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +/* Preferred interface as of December 2018 */ +int +dwarf_add_AT_location_expr_a(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_P_Expr loc_expr, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) { char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; @@ -633,28 +962,28 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_Half attr_form = 0; char *len_str = 0; int len_size = 0; - unsigned block_size = 0; + Dwarf_Unsigned block_size = 0; char *block_dest_ptr = 0; int do_len_as_int = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (loc_expr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (loc_expr->ex_dbg != dbg) { _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } block_size = loc_expr->ex_next_byte_offset; @@ -683,12 +1012,14 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } - /* Compute the number of bytes needed to hold constant. */ + /* Compute the number of bytes needed to hold constant. + This is a bit fake in that the size will never + be particularly large and always < UINT_MAX. */ if (block_size <= UCHAR_MAX) { attr_form = DW_FORM_block1; len_size = 1; @@ -708,7 +1039,7 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, sizeof(encode_buffer)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } len_str = (char *) encode_buffer; } @@ -717,7 +1048,7 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -730,7 +1061,7 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, } new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; new_attr->ar_rel_offset = - (Dwarf_Word) loc_expr->ex_reloc_offset + len_size; + loc_expr->ex_reloc_offset + len_size; new_attr->ar_nbytes = block_size + len_size; @@ -739,7 +1070,7 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (do_len_as_int) { @@ -750,11 +1081,17 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, memcpy(block_dest_ptr, len_str, len_size); } block_dest_ptr += len_size; + if (block_size > sizeof(loc_expr->ex_byte_stream)) { + /* ex_byte_stream has a fixed max value. */ + _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return DW_DLV_ERROR; + } memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } @@ -770,29 +1107,30 @@ dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, the other die, and its di_offset value is used as the reference value. */ -static Dwarf_P_Attribute -_dwarf_add_AT_reference_internal(Dwarf_P_Debug dbg, +static int +_dwarf_add_AT_reference_internal_a(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, int check_otherdie, + Dwarf_P_Attribute *attr_out, Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (check_otherdie && (otherdie == NULL)) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } switch (attr) { @@ -829,7 +1167,7 @@ _dwarf_add_AT_reference_internal(Dwarf_P_Debug dbg, default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } @@ -838,7 +1176,7 @@ _dwarf_add_AT_reference_internal(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -851,20 +1189,54 @@ _dwarf_add_AT_reference_internal(Dwarf_P_Debug dbg, /* Add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } + +/* Allowing the target die to be identified later. + */ +int +dwarf_add_AT_reference_c(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_P_Die otherdie, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + int res = 0; + + res = _dwarf_add_AT_reference_internal_a(dbg, + ownerdie, + attr, + otherdie, + /* check otherdie */ 0, + attr_out, + error); + return res; +} + + + Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, Dwarf_P_Die otherdie, Dwarf_Error * error) { - return _dwarf_add_AT_reference_internal(dbg, + Dwarf_P_Attribute a = 0; + int res = 0; + + res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 1, + &a, error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Attribute)DW_DLV_BADADDR; + } + return a; } /* Allowing the target die to be identified later. @@ -876,12 +1248,20 @@ dwarf_add_AT_reference_b(Dwarf_P_Debug dbg, Dwarf_P_Die otherdie, Dwarf_Error * error) { - return _dwarf_add_AT_reference_internal(dbg, + Dwarf_P_Attribute a = 0; + int res = 0; + + res = _dwarf_add_AT_reference_internal_a(dbg, ownerdie, attr, otherdie, /* check otherdie */ 0, + &a, error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Attribute)DW_DLV_BADADDR; + } + return a; } @@ -924,25 +1304,43 @@ Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, - Dwarf_Small flag, Dwarf_Error * error) + Dwarf_Small flag, + Dwarf_Error * error) +{ + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_flag_a(dbg,ownerdie,attr,flag, + &a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} +int +dwarf_add_AT_flag_a(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + Dwarf_Small flag, + Dwarf_P_Attribute * attr_out, + Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } - if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attr; @@ -956,13 +1354,14 @@ dwarf_add_AT_flag(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, 1); if (new_attr->ar_data == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } memcpy(new_attr->ar_data, &flag, 1); /* Add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } @@ -973,99 +1372,125 @@ dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die ownerdie, Dwarf_Half attr, char *string, Dwarf_Error * error) { - Dwarf_P_Attribute new_attr; + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_string_a(dbg, + ownerdie,attr,string,&a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_string_a(Dwarf_P_Debug dbg, + Dwarf_P_Die ownerdie, + Dwarf_Half attr, + char *string, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr = 0; + int res = 0; if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (ownerdie == NULL) { _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr = (Dwarf_P_Attribute) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } switch (attr) { - case DW_AT_name: + /* See also: pro_section.c for same strings attribute list. */ case DW_AT_comp_dir: case DW_AT_const_value: + case DW_AT_linkage_name:/* DWARF5, but ok for any version really.*/ + case DW_AT_MIPS_abstract_name: + case DW_AT_MIPS_linkage_name: + case DW_AT_name: case DW_AT_producer: break; default: if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } break; } - new_attr->ar_attribute = attr; - new_attr->ar_attribute_form = DW_FORM_string; - new_attr->ar_nbytes = strlen(string) + 1; - new_attr->ar_next = 0; - - new_attr->ar_data = - (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1); - if (new_attr->ar_data == NULL) { - _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg, + string,error); + if (res != DW_DLV_OK) { + return res; } - strcpy(new_attr->ar_data, string); - new_attr->ar_rel_type = R_MIPS_NONE; - new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ - /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } - Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, char *string_value, Dwarf_Error * error) { - Dwarf_P_Attribute new_attr; + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_const_value_string_a(ownerdie, + string_value,&a,error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Attribute) DW_DLV_BADADDR; + } + return a; +} + +int +dwarf_add_AT_const_value_string_a(Dwarf_P_Die ownerdie, + char *string_value, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr = 0; + Dwarf_P_Debug dbg = 0; + int res = 0; if (ownerdie == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; } + dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } new_attr->ar_attribute = DW_AT_const_value; - new_attr->ar_attribute_form = DW_FORM_string; - new_attr->ar_nbytes = strlen(string_value) + 1; - new_attr->ar_next = 0; - - new_attr->ar_data = - (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1); - if (new_attr->ar_data == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + res = _dwarf_pro_set_string_attr(new_attr,dbg, + string_value,error); + if (res != DW_DLV_OK) { + return res; } - strcpy(new_attr->ar_data, string_value); - new_attr->ar_rel_type = R_MIPS_NONE; - new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ - /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } Dwarf_P_Attribute @@ -1073,18 +1498,39 @@ dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, const Dwarf_Sig8 *sig8_in, Dwarf_Error * error) +{ + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_with_ref_sig8_a(ownerdie, + attrnum,sig8_in,&a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_with_ref_sig8_a(Dwarf_P_Die ownerdie, + Dwarf_Half attrnum, + const Dwarf_Sig8 *sig8_in, + Dwarf_P_Attribute * attr_out, + Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; + Dwarf_P_Debug dbg = 0; + if (ownerdie == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; } + dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; new_attr->ar_attribute_form = DW_FORM_ref_sig8; @@ -1092,16 +1538,17 @@ dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie, new_attr->ar_next = 0; new_attr->ar_data = - (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(Dwarf_Sig8)); + (char *) _dwarf_p_get_alloc(dbg, sizeof(Dwarf_Sig8)); if (new_attr->ar_data == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } memcpy(new_attr->ar_data,sig8_in,sizeof(Dwarf_Sig8)); new_attr->ar_rel_type = R_MIPS_NONE; new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } @@ -1110,51 +1557,124 @@ Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die ownerdie, char *producer_string, Dwarf_Error * error) { - Dwarf_P_Attribute new_attr; + Dwarf_P_Attribute a = 0; + int res = 0; - if (ownerdie == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + res = dwarf_add_AT_producer_a(ownerdie, + producer_string,&a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute)DW_DLV_BADADDR); } + return a; +} + +int +dwarf_add_AT_producer_a(Dwarf_P_Die ownerdie, + char *producer_string, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr = 0; + Dwarf_P_Debug dbg = 0; + int res = 0; + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; + } + dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } new_attr->ar_attribute = DW_AT_producer; - new_attr->ar_attribute_form = DW_FORM_string; - new_attr->ar_nbytes = strlen(producer_string) + 1; - new_attr->ar_next = 0; - - new_attr->ar_data = - (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1); - if (new_attr->ar_data == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + res = _dwarf_pro_set_string_attr(new_attr,dbg, + producer_string,error); + if (res != DW_DLV_OK) { + return res; } - strcpy(new_attr->ar_data, producer_string); - new_attr->ar_rel_type = R_MIPS_NONE; - new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ - /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } +int +dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die ownerdie, + Dwarf_Signed signed_value, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + int res = 0; + + res = dwarf_add_AT_any_value_sleb_a( + ownerdie,DW_AT_const_value, + signed_value, + attr_out, error); + return res; +} Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, Dwarf_Signed signed_value, Dwarf_Error * error) { - return dwarf_add_AT_any_value_sleb( + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_any_value_sleb_a( ownerdie,DW_AT_const_value, signed_value, - error); + &a, error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Attribute)DW_DLV_BADADDR; + } + return a; +} + +int +dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie, + Dwarf_Half attrnum, + Dwarf_Signed signed_value, + Dwarf_P_Attribute *outattr, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr = 0; + Dwarf_P_Debug dbg = 0; + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; + } + dbg = ownerdie->di_dbg; + + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + + new_attr->ar_attribute = attrnum; + new_attr->ar_attribute_form = DW_FORM_implicit_const; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + new_attr->ar_next = 0; + + /* The value will go in the abbrev section. + Not the DIE. Encoding done with abbrev generation. */ + new_attr->ar_data = 0; + new_attr->ar_nbytes = 0; + new_attr->ar_implicit_const = signed_value; + + /* add attribute to the die */ + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + *outattr = new_attr; + return DW_DLV_OK; } Dwarf_P_Attribute @@ -1162,22 +1682,44 @@ dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Signed signed_value, Dwarf_Error * error) +{ + int res = 0; + Dwarf_P_Attribute a = 0; + + res = dwarf_add_AT_any_value_sleb_a(ownerdie, + attrnum, + signed_value, + &a, error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die ownerdie, + Dwarf_Half attrnum, + Dwarf_Signed signed_value, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) { Dwarf_P_Attribute new_attr = 0; int leb_size = 0; + Dwarf_P_Debug dbg = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int res = 0; if (ownerdie == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; } + dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; @@ -1190,21 +1732,22 @@ dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } new_attr->ar_data = (char *) - _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size); + _dwarf_p_get_alloc(dbg, leb_size); if (new_attr->ar_data == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } memcpy(new_attr->ar_data, encode_buffer, leb_size); new_attr->ar_nbytes = leb_size; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } /* AT_const_value, uleb */ @@ -1213,34 +1756,113 @@ dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, Dwarf_Unsigned unsigned_value, Dwarf_Error * error) { - return dwarf_add_AT_any_value_uleb( + Dwarf_P_Attribute a =0; + int res = 0; + + res = dwarf_add_AT_any_value_uleb_a( + ownerdie,DW_AT_const_value, + unsigned_value, + &a, + error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} + +int +dwarf_add_AT_const_value_unsignedint_a(Dwarf_P_Die ownerdie, + Dwarf_Unsigned unsigned_value, + Dwarf_P_Attribute *attr_out, + Dwarf_Error * error) +{ + + return dwarf_add_AT_any_value_uleb_a( ownerdie,DW_AT_const_value, unsigned_value, + attr_out, error); } +int +dwarf_add_AT_data16(Dwarf_P_Die ownerdie, + Dwarf_Half attrnum, + Dwarf_Form_Data16 * ptr_to_val, + Dwarf_P_Attribute * attr_return, + Dwarf_Error * error) +{ + Dwarf_P_Attribute new_attr; + int val_size = sizeof(Dwarf_Form_Data16); + Dwarf_P_Debug dbg = 0; + + if (ownerdie == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; + } + dbg = ownerdie->di_dbg; + new_attr = (Dwarf_P_Attribute) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); + if (new_attr == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + new_attr->ar_attribute = attrnum; + new_attr->ar_attribute_form = DW_FORM_data16; + new_attr->ar_rel_type = R_MIPS_NONE; + new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ + new_attr->ar_next = 0; + new_attr->ar_data = (char *) + _dwarf_p_get_alloc(dbg, val_size); + if (new_attr->ar_data == NULL) { + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; + } + memcpy(new_attr->ar_data, ptr_to_val->fd_data, val_size); + new_attr->ar_nbytes = val_size; + _dwarf_pro_add_at_to_die(ownerdie, new_attr); + *attr_return = new_attr; + return DW_DLV_OK; +} Dwarf_P_Attribute dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie, Dwarf_Half attrnum, Dwarf_Unsigned unsigned_value, Dwarf_Error * error) +{ + Dwarf_P_Attribute a = 0; + int res = 0; + + res = dwarf_add_AT_any_value_uleb_a(ownerdie, + attrnum,unsigned_value,&a,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + } + return a; +} +int +dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die ownerdie, + Dwarf_Half attrnum, + Dwarf_Unsigned unsigned_value, + Dwarf_P_Attribute * attr_out, + Dwarf_Error * error) { Dwarf_P_Attribute new_attr; int leb_size; + Dwarf_P_Debug dbg = 0; char encode_buffer[ENCODE_SPACE_NEEDED]; int res; if (ownerdie == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); + return DW_DLV_ERROR; } - + dbg = ownerdie->di_dbg; new_attr = (Dwarf_P_Attribute) - _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); if (new_attr == NULL) { _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + return DW_DLV_ERROR; } new_attr->ar_attribute = attrnum; @@ -1253,19 +1875,20 @@ dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie, encode_buffer, sizeof(encode_buffer)); if (res != DW_DLV_OK) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } new_attr->ar_data = (char *) - _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size); + _dwarf_p_get_alloc(dbg, leb_size); if (new_attr->ar_data == NULL) { - _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); - return ((Dwarf_P_Attribute) DW_DLV_BADADDR); + _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); + return DW_DLV_ERROR; } memcpy(new_attr->ar_data, encode_buffer, leb_size); new_attr->ar_nbytes = leb_size; /* add attribute to the die */ _dwarf_pro_add_at_to_die(ownerdie, new_attr); - return new_attr; + *attr_out = new_attr; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_frame.c b/thirdparty/dwarf/pro_frame.c index b2a983e0..59c9ab7a 100644 --- a/thirdparty/dwarf/pro_frame.c +++ b/thirdparty/dwarf/pro_frame.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011-2012 David Anderson. All Rights Reserved. + Portions Copyright 2011-2017 David Anderson. All Rights Reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it @@ -32,8 +32,47 @@ #include #include #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" +#include "pro_encode_nm.h" #include "pro_frame.h" +#define SIZEOFT16 2 +#define SIZEOFT32 4 +#define SIZEOFT64 8 + +/* Assuming endianness of t, s match...! FIXME */ +#ifdef WORDS_BIGENDIAN +#define ASNOUT(t,s,l) \ + do { \ + unsigned sbyte = 0; \ + const char *p = 0; \ + if (l > sizeof(s)) { \ + _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ + return DW_DLV_ERROR; \ + } \ + sbyte = sizeof(s) - l; \ + p = (const char *)(&s); \ + memcpy(t,(const void *)(p+sbyte),l);\ + } while (0) +#else /* LITTLEENDIAN */ +#define ASNOUT(t,s,l) \ + do { \ + const char *p = 0; \ + if (l > sizeof(s)) { \ + _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ + return DW_DLV_ERROR; \ + } \ + p = (const char *)(&s); \ + memcpy(t,(const void *)p,l); \ + } while (0) +#endif /* ENDIANNESS */ + + static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm inst); @@ -44,6 +83,8 @@ static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, data_align: alignment of data init_bytes: byts having initial instructions init_n_bytes: number of bytes of initial instructions */ + + Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, @@ -51,7 +92,33 @@ dwarf_add_frame_cie(Dwarf_P_Debug dbg, Dwarf_Small data_align, Dwarf_Small return_reg, Dwarf_Ptr init_bytes, - Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) + Dwarf_Unsigned init_n_bytes, + Dwarf_Error * error) +{ + Dwarf_Unsigned index = 0; + int res = 0; + + res = dwarf_add_frame_cie_a(dbg,augmenter, code_align, + data_align,return_reg,init_bytes, + init_n_bytes, + &index,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return index; +} + + +int +dwarf_add_frame_cie_a(Dwarf_P_Debug dbg, + char *augmenter, + Dwarf_Small code_align, + Dwarf_Small data_align, + Dwarf_Small return_reg, + Dwarf_Ptr init_bytes, + Dwarf_Unsigned init_n_bytes, + Dwarf_Unsigned * cie_index_out, + Dwarf_Error * error) { Dwarf_P_Cie curcie; char *tmpaug = 0; @@ -60,7 +127,7 @@ dwarf_add_frame_cie(Dwarf_P_Debug dbg, dbg->de_frame_cies = (Dwarf_P_Cie) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); if (dbg->de_frame_cies == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } curcie = dbg->de_frame_cies; dbg->de_n_cie = 1; @@ -70,17 +137,25 @@ dwarf_add_frame_cie(Dwarf_P_Debug dbg, curcie->cie_next = (Dwarf_P_Cie) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); if (curcie->cie_next == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } curcie = curcie->cie_next; dbg->de_n_cie++; dbg->de_last_cie = curcie; } - curcie->cie_version = DW_CIE_VERSION; - tmpaug = strdup(augmenter); + curcie->cie_version = 1; + if (dbg->de_output_version > 2) { + curcie->cie_version = dbg->de_output_version; + } else { + /* V2 dwarf has debug_frame as version 1, there + is no 2 used in this section. */ + curcie->cie_version = 1; + } + tmpaug = (char *)_dwarf_p_get_alloc(dbg,strlen(augmenter)+1); if (!tmpaug) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); } + strcpy(tmpaug,augmenter); curcie->cie_aug = tmpaug; curcie->cie_code_align = code_align; curcie->cie_data_align = data_align; @@ -88,7 +163,8 @@ dwarf_add_frame_cie(Dwarf_P_Debug dbg, curcie->cie_inst = (char *) init_bytes; curcie->cie_inst_bytes = (long) init_n_bytes; curcie->cie_next = NULL; - return dbg->de_n_cie; + *cie_index_out = dbg->de_n_cie; + return DW_DLV_OK; } @@ -109,10 +185,18 @@ dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_Unsigned code_len, Dwarf_Unsigned symidx, Dwarf_Error * error) { - return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, - code_len, symidx, 0, 0, error); + Dwarf_Unsigned index = 0; + int res = 0; + + res = dwarf_add_frame_fde_c(dbg, fde, die, cie, virt_addr, + code_len, symidx, 0, 0,&index, error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return index; } +/* There is no dwarf_add_frame_fde_a */ /*ARGSUSED10*/ Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, @@ -124,6 +208,32 @@ dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_Unsigned symidx, Dwarf_Unsigned symidx_of_end, Dwarf_Addr offset_from_end_sym, + Dwarf_Error * error) +{ + Dwarf_Unsigned index = 0; + int res = 0; + + res = dwarf_add_frame_fde_c(dbg,fde,die,cie, + virt_addr,code_len,symidx,symidx_of_end, + offset_from_end_sym,&index,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return index; +} + +/* New December 2018 */ +int +dwarf_add_frame_fde_c(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Unsigned symidx_of_end, + Dwarf_Addr offset_from_end_sym, + Dwarf_Unsigned *index_to_fde, UNUSEDARG Dwarf_Error * error) { Dwarf_P_Fde curfde; @@ -149,7 +259,8 @@ dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, dbg->de_last_fde = fde; dbg->de_n_fde++; } - return dbg->de_n_fde; + *index_to_fde = dbg->de_n_fde; + return DW_DLV_OK; } /* This function adds information to an fde. The fde is @@ -183,14 +294,20 @@ dwarf_add_frame_info(Dwarf_P_Debug dbg, Dwarf_Unsigned exception_table_symbol, Dwarf_Error * error) { + Dwarf_Unsigned fde_index = 0; + int res = 0; - return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr, + res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, code_len, symidx, /* end_symbol */ 0, /* offset_from_end */ 0, offset_into_exception_tables, - exception_table_symbol, error); - + exception_table_symbol, + &fde_index, error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return fde_index; } /*ARGSUSED*/ /* pretend all args used */ @@ -207,6 +324,36 @@ dwarf_add_frame_info_b(Dwarf_P_Debug dbg, Dwarf_Signed offset_into_exception_tables, Dwarf_Unsigned exception_table_symbol, UNUSEDARG Dwarf_Error * error) +{ + Dwarf_Unsigned fde_index = 0; + int res = 0; + + res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, + code_len, symidx, end_symidx, + offset_from_end_symbol, + offset_into_exception_tables, + exception_table_symbol, + &fde_index, error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return fde_index; +} + +int +dwarf_add_frame_info_c(Dwarf_P_Debug dbg, + Dwarf_P_Fde fde, + Dwarf_P_Die die, + Dwarf_Unsigned cie, + Dwarf_Unsigned virt_addr, + Dwarf_Unsigned code_len, + Dwarf_Unsigned symidx, + Dwarf_Unsigned end_symidx, + Dwarf_Unsigned offset_from_end_symbol, + Dwarf_Signed offset_into_exception_tables, + Dwarf_Unsigned exception_table_symbol, + Dwarf_Unsigned *fde_index_out, + UNUSEDARG Dwarf_Error * error) { Dwarf_P_Fde curfde; @@ -232,7 +379,8 @@ dwarf_add_frame_info_b(Dwarf_P_Debug dbg, dbg->de_last_fde = fde; dbg->de_n_fde++; } - return dbg->de_n_fde; + *fde_index_out = dbg->de_n_fde; + return DW_DLV_OK; } /* This is an alternate to inserting frame instructions @@ -248,7 +396,7 @@ dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, } if (fde->fde_block || fde->fde_inst) { DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK, - (int)DW_DLV_BADADDR); + DW_DLV_ERROR); } fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len); memcpy(fde->fde_block,ibytes,len); @@ -262,17 +410,32 @@ dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, /* Create a new fde. */ Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_P_Fde fde = 0; + int res = 0; + + res = dwarf_new_fde_a(dbg,&fde,error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Fde) DW_DLV_BADADDR; + } + return fde; +} +int +dwarf_new_fde_a(Dwarf_P_Debug dbg, + Dwarf_P_Fde *fde_out, + Dwarf_Error * error) { Dwarf_P_Fde fde; fde = (Dwarf_P_Fde) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); if (fde == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, - (Dwarf_P_Fde) DW_DLV_BADADDR); + DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, DW_DLV_ERROR); } + fde->fde_dbg = dbg; fde->fde_uwordb_size = dbg->de_offset_size; - return fde; + *fde_out = fde; + return DW_DLV_OK; } @@ -280,7 +443,24 @@ dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, - Dwarf_Signed offset, Dwarf_Error * error) + Dwarf_Signed offset, + Dwarf_Error * error) +{ + int res = 0; + + res = dwarf_fde_cfa_offset_a(fde,reg,offset,error); + if (res != DW_DLV_OK) { + return (Dwarf_P_Fde) DW_DLV_BADADDR; + } + return fde; +} + + +int +dwarf_fde_cfa_offset_a(Dwarf_P_Fde fde, + Dwarf_Unsigned reg, + Dwarf_Signed offset, + Dwarf_Error * error) { Dwarf_Ubyte opc, regno; char *ptr = 0; @@ -293,14 +473,12 @@ dwarf_fde_cfa_offset(Dwarf_P_Fde fde, curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, - (Dwarf_P_Fde) DW_DLV_BADADDR); + DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, DW_DLV_ERROR); } opc = DW_CFA_offset; regno = reg; if (regno & 0xc0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL, - (Dwarf_P_Fde) DW_DLV_BADADDR); + DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,DW_DLV_ERROR); } opc = opc | regno; /* lower 6 bits are register number */ curinst->dfp_opcode = opc; @@ -308,12 +486,12 @@ dwarf_fde_cfa_offset(Dwarf_P_Fde fde, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); @@ -322,7 +500,7 @@ dwarf_fde_cfa_offset(Dwarf_P_Fde fde, curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); - return fde; + return DW_DLV_OK; } /* Generic routine to add opcode to fde instructions. val1 and @@ -340,24 +518,42 @@ dwarf_fde_cfa_offset(Dwarf_P_Fde fde, For certain operations a val? value must be signed (though passed in as unsigned here). - Currently this does not check that the frame - version is 3(for dwarf3) or 4 (for dwarf4) + Does not check that the frame + version is 3(for dwarf3) or 4 (for dwarf4) or 5 when applying operations that are only valid for - dwarf3 or dwarf4. */ + particular versions. */ Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error * error) +{ + int res = 0; + + res = dwarf_add_fde_inst_a(fde,op,val1,val2,error); + if (res != DW_DLV_OK) { + return ((Dwarf_P_Fde) DW_DLV_BADADDR); + } + return fde; +} + +/* December 2018. A more sensible return value. */ +int +dwarf_add_fde_inst_a(Dwarf_P_Fde fde, + Dwarf_Small op, + Dwarf_Unsigned val1, + Dwarf_Unsigned val2, + Dwarf_Error * error) { Dwarf_P_Frame_Pgm curinst; - int nbytes, nbytes1, nbytes2; - Dwarf_Ubyte db; - Dwarf_Half dh; - Dwarf_Word dw; - Dwarf_Unsigned du; - char *ptr; - int res; + int nbytes = 0; + int nbytes1 = 0; + int nbytes2 = 0; + Dwarf_Ubyte db = 0; + Dwarf_Half dh = 0; + Dwarf_Unsigned du = 0; + char *ptr = 0; + int res = 0; char buff1[ENCODE_SPACE_NEEDED]; char buff2[ENCODE_SPACE_NEEDED]; Dwarf_P_Debug dbg = fde->fde_dbg; @@ -367,72 +563,84 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, int signed_first = 0; - nbytes = 0; - ptr = NULL; + buff1[0] = 0; + buff2[0] = 0; curinst = (Dwarf_P_Frame_Pgm) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); if (curinst == NULL) { _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } switch (op) { - case DW_CFA_advance_loc: + case DW_CFA_advance_loc: { if (val1 <= 0x3f) { db = val1; op |= db; - } - /* test not portable FIX */ - else if (val1 <= UCHAR_MAX) { + } else if (!(val1& ~0xff)) { op = DW_CFA_advance_loc1; db = val1; ptr = (char *) _dwarf_p_get_alloc(dbg, 1); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } memcpy((void *) ptr, (const void *) &db, 1); nbytes = 1; - } - /* test not portable FIX */ - else if (val1 <= USHRT_MAX) { + } else if (!(val1& (~(Dwarf_Unsigned)0xffff))) { + if (sizeof(dh) < SIZEOFT16) { + _dwarf_p_error(dbg, error, + DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return DW_DLV_ERROR; + } op = DW_CFA_advance_loc2; dh = val1; - ptr = (char *) _dwarf_p_get_alloc(dbg, 2); + ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT16); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; + } + /* No byte swapping, assuming running at + target endianness. */ + ASNOUT((void *) ptr, dh, SIZEOFT16); + nbytes = SIZEOFT16; + } else if (!(val1& ~(Dwarf_Unsigned)0xffffffff)) { + if (sizeof(du) < SIZEOFT32) { + _dwarf_p_error(dbg, error, + DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return DW_DLV_ERROR; } - memcpy((void *) ptr, (const void *) &dh, 2); - nbytes = 2; - } - /* test not portable FIX */ - else if (val1 <= ULONG_MAX) { op = DW_CFA_advance_loc4; - dw = (Dwarf_Word) val1; - ptr = (char *) _dwarf_p_get_alloc(dbg, 4); + du = val1; + ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT32); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } - memcpy((void *) ptr, (const void *) &dw, 4); - nbytes = 4; + ASNOUT((void *) ptr, du, SIZEOFT32); + nbytes = SIZEOFT32; } else { + if (sizeof(du) < SIZEOFT64) { + _dwarf_p_error(dbg, error, + DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return DW_DLV_ERROR; + } op = DW_CFA_MIPS_advance_loc8; du = val1; - ptr = - (char *) _dwarf_p_get_alloc(dbg, - sizeof(Dwarf_Unsigned)); + ptr = (char *) _dwarf_p_get_alloc(dbg, + SIZEOFT64); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } - memcpy((void *) ptr, (const void *) &du, 8); - nbytes = 8; + /* No byte swapping, assuming running at + target endianness. */ + ASNOUT((void *) ptr, du, SIZEOFT64); + nbytes = SIZEOFT64; } break; - + } case DW_CFA_offset: if (val1 <= MAX_6_BIT_VALUE) { db = val1; @@ -441,12 +649,12 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); @@ -480,7 +688,7 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } if (!signed_second) { res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, @@ -490,18 +698,22 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2, buff2, sizeof(buff2)); } + if (res != DW_DLV_OK) { + _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); + return DW_DLV_ERROR; + } res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes1); memcpy(ptr + nbytes1, buff2, nbytes2); @@ -524,12 +736,12 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, } if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); if (ptr == NULL) { _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } memcpy(ptr, buff1, nbytes); break; @@ -543,7 +755,7 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, FIXME: not handled yet. */ default: _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); - return ((Dwarf_P_Fde) DW_DLV_BADADDR); + return DW_DLV_ERROR; } curinst->dfp_opcode = op; @@ -552,7 +764,7 @@ dwarf_add_fde_inst(Dwarf_P_Fde fde, curinst->dfp_next = NULL; _dwarf_pro_add_to_fde(fde, curinst); - return fde; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_frame.h b/thirdparty/dwarf/pro_frame.h index 75229b2b..808f359d 100644 --- a/thirdparty/dwarf/pro_frame.h +++ b/thirdparty/dwarf/pro_frame.h @@ -1,6 +1,7 @@ /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) 2017 David Anderson. All Rights Reserved. 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 @@ -40,9 +41,6 @@ struct Dwarf_P_Frame_Pgm_s { Dwarf_Ubyte dfp_opcode; /* opcode - includes reg # */ char *dfp_args; /* operands */ int dfp_nbytes; /* number of bytes in args */ -#if 0 - Dwarf_Unsigned dfp_sym_index; /* 0 unless reloc needed */ -#endif Dwarf_P_Frame_Pgm dfp_next; }; @@ -52,7 +50,7 @@ struct Dwarf_P_Frame_Pgm_s { from user program, and later to transform to disk form */ struct Dwarf_P_Cie_s { - Dwarf_Ubyte cie_version; + Dwarf_Half cie_version; /* augmentation. The string is an strdup() copy and on freeing the Dwarf_P_Cie the string must be freed. */ @@ -77,7 +75,7 @@ struct Dwarf_P_Fde_s { Dwarf_P_Die fde_die; /* index to asso. cie */ - Dwarf_Word fde_cie; + Dwarf_Unsigned fde_cie; /* Address of first location of the code this frame applies to If fde_end_symbol non-zero, this represents the offset from the diff --git a/thirdparty/dwarf/pro_funcs.c b/thirdparty/dwarf/pro_funcs.c index 7426a830..679d6f77 100644 --- a/thirdparty/dwarf/pro_funcs.c +++ b/thirdparty/dwarf/pro_funcs.c @@ -33,6 +33,10 @@ #include #endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" #include "pro_section.h" /* This function adds another function name to the @@ -43,8 +47,23 @@ dwarf_add_funcname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *function_name, Dwarf_Error * error) { - return - _dwarf_add_simple_name_entry(dbg, die, function_name, - dwarf_snk_funcname, error); + int res = 0; + res = _dwarf_add_simple_name_entry(dbg, die, function_name, + dwarf_snk_funcname, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; +} +int +dwarf_add_funcname_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *function_name, Dwarf_Error * error) +{ + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, function_name, + dwarf_snk_funcname, error); + return res; } diff --git a/thirdparty/dwarf/pro_incl.h b/thirdparty/dwarf/pro_incl.h index b0beed1e..aeb40b47 100644 --- a/thirdparty/dwarf/pro_incl.h +++ b/thirdparty/dwarf/pro_incl.h @@ -27,12 +27,13 @@ */ -/* Windows specific */ -#ifdef HAVE_STDAFX_H +/* Windows specific header files */ +#if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" #endif /* HAVE_STDAFX_H */ -#ifdef HAVE_ELF_H +#ifdef DWARF_WITH_LIBELF +#ifdef HAVE_ELF_H /* does includes of elf.h libelf.h here. */ #include #elif defined(HAVE_LIBELF_H) /* On one platform without elf.h this gets Elf32_Rel @@ -41,7 +42,8 @@ /* Consider the other known directory too */ #elif defined(HAVE_LIBELF_LIBELF_H) #include -#endif +#endif /* HAVE_ELF_H or HAVE_LIBELF*H */ +#endif /* DWARF_WITH_LIBELF */ #if defined(sun) #include @@ -58,17 +60,14 @@ ((const char *)source) +(srclength)-(len_out),\ (len_out)) ; \ } - - #else /* LITTLE ENDIAN */ - #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \ { \ dbg->de_copy_word( (dest) , \ ((const char *)source) , \ (len_out)) ; \ } -#endif +#endif /* BIG- LITTLE-ENDIAN */ #if defined(sparc) && defined(sun) @@ -80,12 +79,3 @@ #define REL64 Elf64_Rel #define REL_SEC_PREFIX ".rel" #endif - -#include "dwarf.h" -#include "libdwarf.h" - -#include "pro_opaque.h" -#include "pro_error.h" -#include "pro_util.h" -#include "pro_encode_nm.h" -#include "pro_alloc.h" diff --git a/thirdparty/dwarf/pro_init.c b/thirdparty/dwarf/pro_init.c index 19e60103..28d75719 100644 --- a/thirdparty/dwarf/pro_init.c +++ b/thirdparty/dwarf/pro_init.c @@ -1,29 +1,31 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2008-2014 David Anderson, Inc. All rights reserved. + Portions Copyright 2008-2017 David Anderson, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. - 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 Software Foundation. + 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 + Software Foundation. - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ @@ -31,11 +33,26 @@ #include "libdwarfdefs.h" #include #include +#include +#ifdef HAVE_STDINT_H +#include /* For uintptr_t */ +#endif /* HAVE_STDINT_H */ +#ifdef HAVE_INTTYPES_H +#include +#endif /* HAVE_INTTYPES_H */ #include "pro_incl.h" +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" #include "pro_line.h" +#include "memcpy_swap.h" #include "pro_section.h" /* for MAGIC_SECT_NO */ #include "pro_reloc_symbolic.h" #include "pro_reloc_stream.h" +#include "dwarf_tsearch.h" #define IS_64BITPTR(dbg) ((dbg)->de_flags & DW_DLC_POINTER64 ? 1 : 0) #define ISA_IA64(dbg) ((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0) @@ -92,8 +109,6 @@ static int common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, const char *dwarf_version, int *error_ret); -void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); - /* This function sets up a new dwarf producing region. flags: Indicates type of access method, one of DW_DLC* macros func(): Used to create a new object file, a call back function @@ -105,6 +120,12 @@ void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); static struct Dwarf_P_Section_Data_s init_sect = { MAGIC_SECT_NO, 0, 0, 0, 0 }; +static struct Dwarf_P_Section_Data_s init_sect_debug_str = { + MAGIC_SECT_NO, 0, 0, 0, 0 +}; +static struct Dwarf_P_Section_Data_s init_sect_debug_line_str = { + MAGIC_SECT_NO, 0, 0, 0, 0 +}; /* New April 2014. Replaces all previous producer init functions. @@ -161,19 +182,35 @@ dwarf_producer_init(Dwarf_Unsigned flags, dbg->de_user_data = user_data; res = common_init(dbg, flags,isa_name,dwarf_version,&err_ret); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, err_ret, - DW_DLV_ERROR); + DWARF_P_DBG_ERROR(dbg, err_ret, DW_DLV_ERROR); } *dbg_returned = dbg; return DW_DLV_OK; } +int +dwarf_pro_set_default_string_form(Dwarf_P_Debug dbg, + int form, + UNUSEDARG Dwarf_Error * error) +{ + if (form != DW_FORM_string && + form != DW_FORM_strp) { + _dwarf_p_error(dbg, error, DW_DLE_BAD_STRING_FORM); + return DW_DLV_ERROR; + } + dbg->de_debug_default_str_form = form; + return DW_DLV_OK; +} + static int set_reloc_numbers(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Unsigned flags, const char *abiname) { struct isa_relocs_s *isap = 0; + if (!abiname) { + return DW_DLV_NO_ENTRY; + } for(isap = &isa_relocs[0]; ;isap++) { if (!isap->name_) { /* No more names known. Never found the one we wanted. */ @@ -199,6 +236,45 @@ set_reloc_numbers(Dwarf_P_Debug dbg, /* UNREACHED */ } +/* This is the Daniel J Bernstein hash function + originally posted to Usenet news. + http://en.wikipedia.org/wiki/List_of_hash_functions or + http://stackoverflow.com/questions/10696223/reason-for-5381-number-in-djb-hash-function). + See Also DWARF5 Section 7.33 +*/ +static DW_TSHASHTYPE +_dwarf_string_hashfunc(const char *str) +{ + DW_TSHASHTYPE up = 0; + DW_TSHASHTYPE hash = 5381; + int c = 0; + + /* Extra parens suppress warning about assign in test. */ + while ((c = *str++)) { + hash = hash * 33 + c ; + } + up = hash; + return up; +} +static DW_TSHASHTYPE +key_simple_string_hashfunc(const void *keyp) +{ + struct Dwarf_P_debug_str_entry_s* mt = + (struct Dwarf_P_debug_str_entry_s*) keyp; + const char *str = 0; + + if (mt->dse_has_table_offset) { + /* ASSERT: mt->dse_dbg->de_debug_str->ds_data not zero. */ + str = (const char *)mt->dse_dbg->de_debug_str->ds_data + + mt->dse_table_offset; + } else { + /* ASSERT: dse_name != 0 */ + str = (const char *)mt->dse_name; + } + return _dwarf_string_hashfunc(str); +} + + static int common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, const char *dwarf_version, @@ -210,9 +286,10 @@ common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, dbg->de_version_magic_number = PRO_VERSION_MAGIC; dbg->de_n_debug_sect = 0; dbg->de_debug_sects = &init_sect; + dbg->de_debug_str = &init_sect_debug_str; + dbg->de_debug_line_str = &init_sect_debug_line_str; dbg->de_current_active_section = &init_sect; dbg->de_flags = flags; - _dwarf_init_default_line_header_vals(dbg); if(dbg->de_flags & DW_DLC_POINTER64) { @@ -222,14 +299,16 @@ common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, dbg->de_pointer_size = 4; } if(dbg->de_flags & DW_DLC_OFFSET64) { + /* Standard DWARF 64bit offset, length field 12 bytes */ dbg->de_offset_size = 8; - dbg->de_64bit_extension = 0; + dbg->de_64bit_extension = 1; } else { if(dbg->de_flags & DW_DLC_IRIX_OFFSET64) { dbg->de_offset_size = 8; - dbg->de_64bit_extension = 1; + dbg->de_64bit_extension = 0; } else { - /* offset size 4 assumed. */ + /* offset size 4 assumed, it is + by far the most frequent case.. */ dbg->de_offset_size = 4; dbg->de_64bit_extension = 0; } @@ -249,35 +328,49 @@ common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, *err_ret = DW_DLE_BAD_ABINAME; return DW_DLV_ERROR; } - if(!dwarf_version) { - dbg->de_output_version = 2; - } else if (!strcmp(dwarf_version,"V2")) { - dbg->de_output_version = 2; - } else if (!strcmp(dwarf_version,"V3")) { - dbg->de_output_version = 3; - } else if (!strcmp(dwarf_version,"V4")) { - dbg->de_output_version = 4; - } else if (!strcmp(dwarf_version,"V5")) { - dbg->de_output_version = 5; - } else { - /* The default. */ - dbg->de_output_version = 2; + dbg->de_output_version = 2; + if(dwarf_version) { + if (!strcmp(dwarf_version,"V2")) { + dbg->de_output_version = 2; + } else if (!strcmp(dwarf_version,"V3")) { + dbg->de_output_version = 3; + } else if (!strcmp(dwarf_version,"V4")) { + dbg->de_output_version = 4; + } else if (!strcmp(dwarf_version,"V5")) { + dbg->de_output_version = 5; + } else { + *err_ret = DW_DLE_VERSION_STAMP_ERROR; + return DW_DLV_ERROR; + } } - if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { dbg->de_relocation_record_size = sizeof(struct Dwarf_Relocation_Data_s); } else { /* This is only going to work when the HOST == TARGET, surely? */ +#ifdef DWARF_WITH_LIBELF #if HAVE_ELF64_GETEHDR dbg->de_relocation_record_size = ((dbg->de_pointer_size == 8)? sizeof(REL64) : sizeof(REL32)); #else dbg->de_relocation_record_size = sizeof(REL32); #endif +#else /* DWARF_WITH_LIBELF */ + *err_ret = DW_DLE_NO_STREAM_RELOC_SUPPORT; + return DW_DLV_ERROR; +#endif /* DWARF_WITH_LIBELF */ + } + _dwarf_init_default_line_header_vals(dbg); + + /* For .debug_str creation. */ + dwarf_initialize_search_hash(&dbg->de_debug_str_hashtab, + key_simple_string_hashfunc,0); + dbg->de_debug_default_str_form = DW_FORM_string; + dwarf_initialize_search_hash(&dbg->de_debug_line_str_hashtab, + key_simple_string_hashfunc,0); /* FIXME: conditional on the DWARF version target, dbg->de_output_version. */ @@ -290,18 +383,27 @@ common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, } if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { - dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic; - dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic; + dbg->de_relocate_by_name_symbol = + _dwarf_pro_reloc_name_symbolic; + dbg->de_relocate_pair_by_symbol = + _dwarf_pro_reloc_length_symbolic; dbg->de_transform_relocs_to_disk = _dwarf_symbolic_relocs_to_disk; } else { +#ifdef DWARF_WITH_LIBELF if (IS_64BITPTR(dbg)) { - dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64; + dbg->de_relocate_by_name_symbol = + _dwarf_pro_reloc_name_stream64; } else { - dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32; + dbg->de_relocate_by_name_symbol = + _dwarf_pro_reloc_name_stream32; } - dbg->de_reloc_pair = 0; + dbg->de_relocate_pair_by_symbol = 0; dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk; +#else /* DWARF_WITH_LIBELF */ + *err_ret = DW_DLE_NO_STREAM_RELOC_SUPPORT; + return DW_DLV_ERROR; +#endif /* DWARF_WITH_LIBELF */ } for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { @@ -311,7 +413,7 @@ common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags, const char *abiname, } /* First assume host, target same endianness */ dbg->de_same_endian = 1; - dbg->de_copy_word = memcpy; + dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; #ifdef WORDS_BIGENDIAN /* host is big endian, so what endian is target? */ if (flags & DW_DLC_TARGET_LITTLEENDIAN) { diff --git a/thirdparty/dwarf/pro_line.c b/thirdparty/dwarf/pro_line.c index eec27520..99af3f67 100644 --- a/thirdparty/dwarf/pro_line.c +++ b/thirdparty/dwarf/pro_line.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. + Portions Copyright 2011-2019 David Anderson. All Rights Reserved. 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 @@ -29,14 +28,18 @@ #include "libdwarfdefs.h" #include #include -#ifdef HAVE_ELF_H -#include -#endif + #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" +#include "pro_encode_nm.h" #include "pro_line.h" -static -Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug, +static int _dwarf_pro_add_line_entry(Dwarf_P_Debug, Dwarf_Unsigned file_index, Dwarf_Addr code_address, Dwarf_Unsigned symidx, @@ -58,7 +61,11 @@ Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug, This function actually calls _dwarf_pro_add_line_entry(), with an extra parameter, the opcode. Done so that interface calls dwarf_lne_set_address() and dwarf_lne_end_sequence() can use - this internal routine. */ + this internal routine. + + The return value of the original + interfaces is really signed. Bogus interface. + With dwarf_add_line_entry_c the interface is corrected. */ Dwarf_Unsigned dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, @@ -77,6 +84,35 @@ dwarf_add_line_entry_b(Dwarf_P_Debug dbg, Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; + retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, + symidx, + line_no, col_no, is_stmt_begin, + is_bb_begin, + opc, + isepilbeg,isprolend,isa,discriminator, error); + if (retval != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return 0; +} +int +dwarf_add_line_entry_c(Dwarf_P_Debug dbg, + Dwarf_Unsigned file_index, + Dwarf_Addr code_address, + Dwarf_Unsigned line_no, + Dwarf_Signed col_no, + Dwarf_Bool is_stmt_begin, + Dwarf_Bool is_bb_begin, + Dwarf_Bool isepilbeg, + Dwarf_Bool isprolend, + Dwarf_Unsigned isa, + Dwarf_Unsigned discriminator, + Dwarf_Error * error) +{ + int retval = 0; + Dwarf_Ubyte opc = 0; + Dwarf_Unsigned symidx = 0; + retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, symidx, line_no, col_no, is_stmt_begin, @@ -85,6 +121,10 @@ dwarf_add_line_entry_b(Dwarf_P_Debug dbg, isepilbeg,isprolend,isa,discriminator, error); return retval; } + + + +/* The return value is really signed. Bogus interface.*/ Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, @@ -94,7 +134,7 @@ dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Error * error) { - Dwarf_Unsigned retval = 0; + int retval = 0; Dwarf_Ubyte opc = 0; Dwarf_Unsigned symidx = 0; Dwarf_Bool isepilbeg = 0; @@ -109,13 +149,17 @@ dwarf_add_line_entry(Dwarf_P_Debug dbg, opc, isepilbeg, isprolend, isa, discriminator, error); - return retval; + if (retval != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return 0; } void _dwarf_init_default_line_header_vals(Dwarf_P_Debug dbg) { - dbg->de_line_inits.pi_version = DW_LINE_VERSION2; + dbg->de_line_inits.pi_version = dbg->de_output_version; + dbg->de_line_inits.pi_default_is_stmt = DEFAULT_IS_STMT; dbg->de_line_inits.pi_minimum_instruction_length = MIN_INST_LENGTH; dbg->de_line_inits.pi_maximum_operations_per_instruction = 1; @@ -133,8 +177,22 @@ dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symidx, Dwarf_Error * error) { + int res = 0; + + res = dwarf_lne_set_address_a(dbg,offs,symidx,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return 0; + +} +int +dwarf_lne_set_address_a(Dwarf_P_Debug dbg, + Dwarf_Addr offs, + Dwarf_Unsigned symidx, Dwarf_Error * error) +{ + int retval = 0; Dwarf_Ubyte opc = 0; - Dwarf_Unsigned retval = 0; Dwarf_Unsigned file_index = 0; Dwarf_Unsigned line_no = 0; Dwarf_Signed col_no = 0; @@ -147,14 +205,13 @@ dwarf_lne_set_address(Dwarf_P_Debug dbg, opc = DW_LNE_set_address; - retval = - _dwarf_pro_add_line_entry(dbg, file_index, offs, - symidx, - line_no, col_no, is_stmt, - is_bb, - opc, - isepilbeg, isprolend, isa, discriminator, - error); + retval = _dwarf_pro_add_line_entry(dbg, file_index, offs, + symidx, + line_no, col_no, is_stmt, + is_bb, + opc, + isepilbeg, isprolend, isa, discriminator, + error); return retval; } @@ -164,9 +221,21 @@ dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr end_address, Dwarf_Error * error) +{ + int retval = 0; + + retval = dwarf_lne_end_sequence_a(dbg,end_address,error); + if (retval != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return 0; +} +int +dwarf_lne_end_sequence_a(Dwarf_P_Debug dbg, + Dwarf_Addr end_address, Dwarf_Error * error) { Dwarf_Ubyte opc = 0; - Dwarf_Unsigned retval = 0; + int retval = 0; Dwarf_Unsigned file_index = 0; Dwarf_Unsigned symidx = 0; Dwarf_Unsigned line_no = 0; @@ -179,22 +248,23 @@ dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Unsigned discriminator = 0; opc = DW_LNE_end_sequence; - retval = - _dwarf_pro_add_line_entry(dbg, file_index, end_address, - symidx, - line_no, col_no, is_stmt, - is_bb, - opc, - isepilbeg, isprolend, isa, discriminator, - error); + retval = _dwarf_pro_add_line_entry(dbg, file_index, end_address, + symidx, + line_no, col_no, is_stmt, + is_bb, + opc, + isepilbeg, isprolend, isa, discriminator, + error); return retval; } +/* As of December 2018 this returns DW_DLV_OK, DW_DLV_ERROR + not 0, DW_DLV_NOCOUNT*/ /* Add an entry in the internal list of lines mantained by producer. Opc indicates if an opcode needs to be generated, rather than just an entry in the matrix. During opcodes generation time, these opcodes will be used. */ -static Dwarf_Unsigned +static int _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file_index, Dwarf_Addr code_address, @@ -214,7 +284,7 @@ _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, dbg->de_lines = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (dbg->de_lines == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } dbg->de_last_line = dbg->de_lines; _dwarf_pro_reg_init(dbg,dbg->de_lines); @@ -223,7 +293,7 @@ _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, dbg->de_last_line->dpl_next = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (dbg->de_last_line->dpl_next == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } dbg->de_last_line = dbg->de_last_line->dpl_next; _dwarf_pro_reg_init(dbg,dbg->de_last_line); @@ -240,41 +310,62 @@ _dwarf_pro_add_line_entry(Dwarf_P_Debug dbg, dbg->de_last_line->dpl_epilogue_begin = isepilbeg; dbg->de_last_line->dpl_isa = isa; dbg->de_last_line->dpl_discriminator = discriminator; - return (0); + return DW_DLV_OK; } /* Add a directory declaration to the debug_line section. Stored in linked list. */ Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug dbg, - char *name, Dwarf_Error * error) + char *name, + Dwarf_Error * error) +{ + Dwarf_Unsigned index = 0; + int res = 0; + /* DW_DLV_NOCOUNT on error, de_n_inc_dirs on success. */ + + res = dwarf_add_directory_decl_a(dbg,name,&index,error); + if (res != DW_DLV_OK) { + return (Dwarf_Unsigned)DW_DLV_NOCOUNT; + } + return index; +} +int +dwarf_add_directory_decl_a(Dwarf_P_Debug dbg, + char *name, + Dwarf_Unsigned *index_in_directories, + Dwarf_Error * error) { if (dbg->de_inc_dirs == NULL) { - dbg->de_inc_dirs = (Dwarf_P_Inc_Dir) - _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s)); + dbg->de_inc_dirs = (Dwarf_P_F_Entry) + _dwarf_p_get_alloc(dbg, + sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_inc_dirs == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, + DW_DLV_ERROR); } dbg->de_last_inc_dir = dbg->de_inc_dirs; dbg->de_n_inc_dirs = 1; } else { - dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir) - _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s)); - if (dbg->de_last_inc_dir->did_next == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT); + dbg->de_last_inc_dir->dfe_next = (Dwarf_P_F_Entry) + _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); + if (dbg->de_last_inc_dir->dfe_next == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, + DW_DLV_ERROR); } - dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next; + dbg->de_last_inc_dir = dbg->de_last_inc_dir->dfe_next; dbg->de_n_inc_dirs++; } - dbg->de_last_inc_dir->did_name = + dbg->de_last_inc_dir->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); - if (dbg->de_last_inc_dir->did_name == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT); + if (dbg->de_last_inc_dir->dfe_name == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_ERROR); } - strcpy(dbg->de_last_inc_dir->did_name, name); - dbg->de_last_inc_dir->did_next = NULL; + strcpy(dbg->de_last_inc_dir->dfe_name, name); + dbg->de_last_inc_dir->dfe_next = NULL; - return dbg->de_n_inc_dirs; + *index_in_directories = dbg->de_n_inc_dirs; + return DW_DLV_OK; } /* Add a file entry declaration to the debug_line section. Stored @@ -285,7 +376,27 @@ dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dir_idx, Dwarf_Unsigned time_mod, - Dwarf_Unsigned length, Dwarf_Error * error) + Dwarf_Unsigned length, + Dwarf_Error * error) +{ + Dwarf_Unsigned filecount = 0; + int res = 0; + + res = dwarf_add_file_decl_a(dbg,name,dir_idx, + time_mod,length,&filecount,error); + if (res != DW_DLV_OK) { + return DW_DLV_NOCOUNT; + } + return filecount; +} +int +dwarf_add_file_decl_a(Dwarf_P_Debug dbg, + char *name, + Dwarf_Unsigned dir_idx, + Dwarf_Unsigned time_mod, + Dwarf_Unsigned length, + Dwarf_Unsigned *file_entry_count_out, + Dwarf_Error * error) { Dwarf_P_F_Entry cur; char *ptr = 0; @@ -300,7 +411,7 @@ dwarf_add_file_decl(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (dbg->de_file_entries == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, - DW_DLV_NOCOUNT); + DW_DLV_ERROR); } cur = dbg->de_file_entries; dbg->de_last_file_entry = cur; @@ -311,7 +422,7 @@ dwarf_add_file_decl(Dwarf_P_Debug dbg, _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s)); if (cur->dfe_next == NULL) { DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC, - DW_DLV_NOCOUNT); + DW_DLV_ERROR); } cur = cur->dfe_next; dbg->de_last_file_entry = cur; @@ -319,25 +430,31 @@ dwarf_add_file_decl(Dwarf_P_Debug dbg, } cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1); if (cur->dfe_name == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } strcpy((char *) cur->dfe_name, name); res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx, buffidx, sizeof(buffidx)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + /* DW_DLV_NO_ENTRY impossible */ + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time, bufftime, sizeof(bufftime)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + /* DW_DLV_NO_ENTRY impossible */ + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len, bufflen, sizeof(bufflen)); + if (res != DW_DLV_OK) { + /* DW_DLV_NO_ENTRY impossible */ + DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR,DW_DLV_ERROR); + } cur->dfe_args = (char *) _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len); if (cur->dfe_args == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_ERROR); } ptr = cur->dfe_args; memcpy((void *) ptr, buffidx, nbytes_idx); @@ -345,11 +462,10 @@ dwarf_add_file_decl(Dwarf_P_Debug dbg, memcpy((void *) ptr, bufftime, nbytes_time); ptr += nbytes_time; memcpy((void *) ptr, bufflen, nbytes_len); - ptr += nbytes_len; cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len; cur->dfe_next = NULL; - - return dbg->de_n_file_entries; + *file_entry_count_out = dbg->de_n_file_entries; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_line.h b/thirdparty/dwarf/pro_line.h index b440b3bc..7ff16cf9 100644 --- a/thirdparty/dwarf/pro_line.h +++ b/thirdparty/dwarf/pro_line.h @@ -2,6 +2,7 @@ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. + Portions Copyright 2017 David Anderson All rights reserved. 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 @@ -45,22 +46,26 @@ #define MAX_OPCODE 255 -/* This struct is used to hold entries in the include directories - part of statement prologue. */ -struct Dwarf_P_Inc_Dir_s { - char *did_name; /* name of directory */ - Dwarf_P_Inc_Dir did_next; -}; - -/* This struct holds file entries for the statement prologue. +/* This struct holds file or include_dir + entries for the statement prologue. Defined in pro_line.h */ struct Dwarf_P_F_Entry_s { char *dfe_name; + Dwarf_P_F_Entry dfe_next; + + /* DWARF 2,3,4, files only not inc dirs */ char *dfe_args; /* has dir index, time of modification, length in bytes. Encodes as leb128 */ int dfe_nbytes; /* number of bytes in args */ - Dwarf_P_F_Entry dfe_next; + + /* Dwarf5 Use or not depends on file_name_entry_format + actually used. */ + unsigned dfe_index; + Dwarf_Unsigned dfe_timestamp; + unsigned dfe_size; + unsigned char dfe_md5[16]; + }; @@ -73,13 +78,13 @@ struct Dwarf_P_Line_s { Dwarf_Addr dpl_address; /* file index, index into file entry */ - Dwarf_Word dpl_file; + Dwarf_Unsigned dpl_file; /* line number */ - Dwarf_Word dpl_line; + Dwarf_Unsigned dpl_line; /* column number */ - Dwarf_Word dpl_column; + Dwarf_Unsigned dpl_column; /* whether its a beginning of a stmt */ Dwarf_Ubyte dpl_is_stmt; diff --git a/thirdparty/dwarf/pro_macinfo.c b/thirdparty/dwarf/pro_macinfo.c index 23197d57..22e53114 100644 --- a/thirdparty/dwarf/pro_macinfo.c +++ b/thirdparty/dwarf/pro_macinfo.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. + Portions Copyright 2011-2019 David Anderson. All Rights Reserved. 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 @@ -30,6 +29,13 @@ #include #include #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" #include "pro_section.h" #include "pro_macinfo.h" @@ -338,16 +344,16 @@ dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error) length_est = COMMAND_LEN; res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est, &compose_error_type); - if (res != DW_DLV_OK) { - _dwarf_p_error(NULL, error, compose_error_type); + if (res == DW_DLV_ERROR) { + _dwarf_p_error(dbg, error, compose_error_type); return (DW_DLV_ERROR); } res = libdwarf_compose_complete(dbg, &compose_error_type); - if (res != DW_DLV_OK) { - _dwarf_p_error(NULL, error, compose_error_type); - return (DW_DLV_ERROR); + if (res == DW_DLV_ERROR) { + _dwarf_p_error(dbg, error, compose_error_type); + return res; } - return DW_DLV_OK; + return res; } int @@ -387,10 +393,6 @@ dwarf_vendor_ext(Dwarf_P_Debug dbg, } libdwarf_compose_add_string(dbg, string, len); libdwarf_compose_complete(dbg, &compose_error_type); - if (res != DW_DLV_OK) { - _dwarf_p_error(NULL, error, compose_error_type); - return (DW_DLV_ERROR); - } return DW_DLV_OK; } @@ -398,6 +400,7 @@ dwarf_vendor_ext(Dwarf_P_Debug dbg, int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error) { /* Total num of bytes in .debug_macinfo section. */ @@ -427,10 +430,6 @@ _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO], macinfo, (unsigned long) mac_num_bytes, error); - if (macinfo == NULL) { - _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); - } macinfo_ptr = macinfo; m_prev = 0; @@ -453,5 +452,6 @@ _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, dbg->de_first_macinfo = NULL; dbg->de_current_macinfo = NULL; - return (int) dbg->de_n_debug_sect; + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_macinfo.h b/thirdparty/dwarf/pro_macinfo.h index 8607d3f2..df1caf04 100644 --- a/thirdparty/dwarf/pro_macinfo.h +++ b/thirdparty/dwarf/pro_macinfo.h @@ -28,4 +28,5 @@ int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error); diff --git a/thirdparty/dwarf/pro_opaque.h b/thirdparty/dwarf/pro_opaque.h index 7cca2935..23f51319 100644 --- a/thirdparty/dwarf/pro_opaque.h +++ b/thirdparty/dwarf/pro_opaque.h @@ -2,7 +2,7 @@ Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2011-2014 David Anderson. All Rights Reserved. + Portions Copyright 2011-2017 David Anderson. All Rights Reserved. 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 @@ -26,33 +26,20 @@ */ - -#include - -/* - Sgidefs included to define __uint32_t, - a guaranteed 4-byte quantity. -*/ #include "libdwarfdefs.h" #define true 1 #define false 0 +/* The DISTINGUISHED VALUE is 4 byte value defined by DWARF + since DWARF3. */ +#define DISTINGUISHED_VALUE_ARRAY(x) unsigned char x[4] = { 0xff,0xff,0xff,0xff } +#define DISTINGUISHED_VALUE 0xffffffff /* 64bit extension flag */ + /* to identify a cie */ #define DW_CIE_ID ~(0x0) #define DW_CIE_VERSION 1 -/*Dwarf_Word is unsigned word usable for index, count in memory */ -/*Dwarf_Sword is signed word usable for index, count in memory */ -/* The are 32 or 64 bits depending if 64 bit longs or not, which -** fits the ILP32 and LP64 models -** These work equally well with ILP64. -*/ - -typedef unsigned long Dwarf_Word; -typedef long Dwarf_Sword; - - typedef signed char Dwarf_Sbyte; typedef unsigned char Dwarf_Ubyte; typedef signed short Dwarf_Shalf; @@ -64,11 +51,9 @@ typedef signed short Dwarf_Shalf; #define PRO_VERSION_MAGIC 0xdead1 -/* these 2 are fixed sizes which must not vary with the -** ILP32/LP64 model. These two stay at 32 bit. -*/ -typedef __uint32_t Dwarf_ufixed; -typedef __int32_t Dwarf_sfixed; +#define DWARF_HALF_SIZE 2 +#define DWARF_32BIT_SIZE 4 +#define DWARF_64BIT_SIZE 8 /* producer: @@ -80,14 +65,8 @@ typedef struct Dwarf_P_Section_Data_s *Dwarf_P_Section_Data; /* producer: - This struct is used to hold entries in the include directories - part of statement prologue. Definition in pro_line.h -*/ -typedef struct Dwarf_P_Inc_Dir_s *Dwarf_P_Inc_Dir; - -/* - producer: - This struct holds file entries for the statement prologue. + This struct holds file entries or + include file entries for the statement prologue. Defined in pro_line.h */ typedef struct Dwarf_P_F_Entry_s *Dwarf_P_F_Entry; @@ -114,6 +93,7 @@ typedef struct Dwarf_P_Simple_name_header_s *Dwarf_P_Simple_name_header; typedef struct Dwarf_P_Arange_s *Dwarf_P_Arange; typedef struct Dwarf_P_Per_Reloc_Sect_s *Dwarf_P_Per_Reloc_Sect; typedef struct Dwarf_P_Per_Sect_String_Attrs_s *Dwarf_P_Per_Sect_String_Attrs; +typedef struct Dwarf_P_Dnames_s *Dwarf_P_Dnames; /* Defined to get at the elf section numbers and section name indices in symtab for the dwarf sections @@ -126,20 +106,37 @@ typedef struct Dwarf_P_Per_Sect_String_Attrs_s *Dwarf_P_Per_Sect_String_Attrs; #define DEBUG_FRAME 3 #define DEBUG_ARANGES 4 #define DEBUG_PUBNAMES 5 -#define DEBUG_STR 6 -#define DEBUG_FUNCNAMES 7 -#define DEBUG_TYPENAMES 8 -#define DEBUG_VARNAMES 9 -#define DEBUG_WEAKNAMES 10 -#define DEBUG_MACINFO 11 -#define DEBUG_LOC 12 -#define DEBUG_RANGES 13 -#define DEBUG_TYPES 14 -#define DEBUG_PUBTYPES 15 +#define DEBUG_FUNCNAMES 6 +#define DEBUG_TYPENAMES 7 +#define DEBUG_VARNAMES 8 +#define DEBUG_WEAKNAMES 9 +#define DEBUG_MACINFO 10 /* DWARF 2,3,4 only */ +#define DEBUG_LOC 11 +#define DEBUG_RANGES 12 +#define DEBUG_TYPES 13 +#define DEBUG_PUBTYPES 14 +#define DEBUG_NAMES 15 /* DWARF5. aka dnames */ +#define DEBUG_STR 16 +#define DEBUG_LINE_STR 17 +#define DEBUG_MACRO 18 /* DWARF 5. */ +#define DEBUG_LOCLISTS 19 /* DWARF 5. */ +#define DEBUG_RNGLISTS 20 /* DWARF 5. */ /* Maximum number of debug_* sections not including the relocations */ -#define NUM_DEBUG_SECTIONS 16 +#define NUM_DEBUG_SECTIONS 21 + +/* The FORM codes available are defined in DWARF5 + on page 158, DW_LNCT_path */ +struct Dwarf_P_Line_format_s { + /* DW_LNCT_path etc. */ + unsigned def_content_type; + /* DW_FORM_string or DW_FORM_strp or DW_FORM_strp + or DW_FORM_strp_sup or for dwo, some others. */ + unsigned def_form_code; +}; + +#define DW_LINE_FORMATS_MAX 6 /* Describes the data needed to generate line table header info so we can vary the init at runtime. */ struct Dwarf_P_Line_Inits_s { @@ -149,8 +146,7 @@ struct Dwarf_P_Line_Inits_s { /* Size of the smallest instruction, in bytes. */ unsigned pi_minimum_instruction_length; - /* Make this >1 for VLIW machines. */ - unsigned pi_maximum_operations_per_instruction; + /* Normally opcode_base is determined by pi_version, but we allow manual setting here so we can generate data like @@ -161,13 +157,25 @@ struct Dwarf_P_Line_Inits_s { int pi_line_base; /* For line table header. */ int pi_line_range; /* For line table header. */ + + /* Make this >1 for VLIW machines. DWARF4,DWARF5 */ + unsigned pi_maximum_operations_per_instruction; + + /* DWARF 5 */ + unsigned pi_address_size; + unsigned pi_segment_size; + unsigned pi_directory_entry_format_count; + struct Dwarf_P_Line_format_s pi_incformats[DW_LINE_FORMATS_MAX]; + + unsigned pi_file_entry_format_count; + struct Dwarf_P_Line_format_s pi_fileformats[DW_LINE_FORMATS_MAX]; }; struct Dwarf_P_Die_s { Dwarf_Unsigned di_offset; /* offset in debug info */ char *di_abbrev; /* abbreviation */ - Dwarf_Word di_abbrev_nbytes; /* # of bytes in abbrev */ + Dwarf_Unsigned di_abbrev_nbytes; /* # of bytes in abbrev */ Dwarf_Tag di_tag; Dwarf_P_Die di_parent; /* parent of current die */ Dwarf_P_Die di_child; /* first child */ @@ -194,13 +202,17 @@ struct Dwarf_P_Attribute_s { Dwarf_Unsigned ar_rel_symidx; /* when attribute has a relocatable value, holds index of symbol in SYMTAB */ + Dwarf_Unsigned ar_debug_str_offset; /* Offset in .debug_str + if non-zero. Zero offset never assigned a string. */ Dwarf_Ubyte ar_rel_type; /* relocation type */ - Dwarf_Word ar_rel_offset; /* Offset of relocation within block */ + Dwarf_Unsigned ar_rel_offset; /* Offset of relocation within block */ char ar_reloc_len; /* Number of bytes that relocation applies to. 4 or 8. Unused and may be 0 if if ar_rel_type is R_MIPS_NONE */ Dwarf_P_Attribute ar_next; + /* set if form = DW_FORM_implicit_const; */ + Dwarf_Signed ar_implicit_const; }; /* A block of .debug_macinfo data: this forms a series of blocks. @@ -335,6 +347,37 @@ struct Dwarf_P_Per_Sect_String_Attrs_s { Dwarf_P_String_Attr sect_sa_list; }; +struct Dwarf_P_debug_str_entry_s { + Dwarf_P_Debug dse_dbg; + /* Name used initially with tfind. */ + char *dse_name; + + Dwarf_Unsigned dse_slen; /* includes space for NUL terminator */ + + /* See dse_has_table_offset below. */ + Dwarf_Unsigned dse_table_offset; + + /* For tsearch a hash table exists and we have a table offset. + dse_dbg->de_debug_str->ds_data + dse_table_offset + points to the string iff dse_has_table_offset != 0. */ + unsigned char dse_has_table_offset; +}; + +struct Dwarf_P_Str_stats_s { + Dwarf_Unsigned ps_strp_count_debug_str; + Dwarf_Unsigned ps_strp_len_debug_str; + Dwarf_Unsigned ps_strp_len_debug_line_str; + Dwarf_Unsigned ps_strp_reused_count; + Dwarf_Unsigned ps_strp_reused_len; +}; + +struct Dwarf_P_Stats_s { + Dwarf_Unsigned ps_str_count; + Dwarf_Unsigned ps_str_total_length; + struct Dwarf_P_Str_stats_s ps_strp; + struct Dwarf_P_Str_stats_s ps_line_strp; +}; + /* Fields used by producer */ struct Dwarf_P_Debug_s { /* Used to catch dso passing dbg to another DSO with incompatible @@ -357,15 +400,28 @@ struct Dwarf_P_Debug_s { /* Flags from producer_init call */ Dwarf_Unsigned de_flags; - /* This holds information on debug section stream output, including - the stream data */ + /* This holds information on debug info section + stream output, including the stream data */ Dwarf_P_Section_Data de_debug_sects; + /* Defaults set as DW_FORM_string, + meaning not using .debug_str by default. + This intended for the .debug_info section. */ + int de_debug_default_str_form; + + /* If form DW_FORM_strp */ + Dwarf_P_Section_Data de_debug_str; + void *de_debug_str_hashtab; /* for tsearch */ + + /* .debug_line_str section data if form DW_FORM_line_strp */ + Dwarf_P_Section_Data de_debug_line_str; + void *de_debug_line_str_hashtab; /* for tsearch */ + /* Pointer to the 'current active' section */ Dwarf_P_Section_Data de_current_active_section; /* Number of debug data streams globs. */ - Dwarf_Word de_n_debug_sect; + Dwarf_Unsigned de_n_debug_sect; /* File entry information, null terminated singly-linked list */ Dwarf_P_F_Entry de_file_entries; @@ -373,8 +429,8 @@ struct Dwarf_P_Debug_s { Dwarf_Unsigned de_n_file_entries; /* Has the directories used to search for source files */ - Dwarf_P_Inc_Dir de_inc_dirs; - Dwarf_P_Inc_Dir de_last_inc_dir; + Dwarf_P_F_Entry de_inc_dirs; + Dwarf_P_F_Entry de_last_inc_dir; Dwarf_Unsigned de_n_inc_dirs; /* Has all the line number info for the stmt program */ @@ -394,13 +450,15 @@ struct Dwarf_P_Debug_s { /* First die, leads to all others */ Dwarf_P_Die de_dies; - /* Pointer to list of strings */ - char *de_strings; - /* Pointer to chain of aranges */ Dwarf_P_Arange de_arange; Dwarf_P_Arange de_last_arange; - Dwarf_Sword de_arange_count; + Dwarf_Signed de_arange_count; + + /* debug_names de_dnames is base of dnames info + before disk form */ + Dwarf_P_Dnames de_dnames; + Dwarf_P_Section_Data de_dnames_sect; /* macinfo controls. */ /* first points to beginning of the list during creation */ @@ -418,18 +476,20 @@ struct Dwarf_P_Debug_s { de_simple_name_headers[dwarf_snk_entrycount]; /* Relocation data. not all sections will actally have relocation - info, of course */ + info, of course. de_reloc_sect, de_elf_sects, and de_sect_name_idx + arrays are exactly in parallel. Not every de_elf_sect has + any relocations for it, of course. */ struct Dwarf_P_Per_Reloc_Sect_s de_reloc_sect[NUM_DEBUG_SECTIONS]; int de_reloc_next_to_return; /* iterator on reloc sections (SYMBOLIC output) */ - /* used in remembering sections */ + /* Used in remembering sections. See de_reloc_sect above. */ int de_elf_sects[NUM_DEBUG_SECTIONS]; /* elf sect number of the section itself, DEBUG_LINE for example */ - Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS]; /* section - name index or handle for the name of the symbol for + /* Section name index or handle for the name of the symbol for DEBUG_LINE for example */ + Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS]; int de_offset_reloc; /* offset reloc type, R_MIPS_32 for example. Specific to the ABI being @@ -455,6 +515,9 @@ struct Dwarf_P_Debug_s { macro at run time MIPS -n32 4, -64 is 8. */ + /* Added April 19, 2017. For DWARF5 */ + unsigned char de_segment_selector_size; + unsigned char de_relocation_record_size; /* reloc record size varies by ABI and relocation-output @@ -465,17 +528,18 @@ struct Dwarf_P_Debug_s { offsets using dwarf2-99 extension proposal */ - int de_output_version; /* 2,3,4, or 5. The version number - of the output. (not necessarily that of each section). */ + unsigned char de_output_version; /* 2,3,4, or 5. The version number + of the output. (not necessarily that of each section, + which depends on the base version). */ int de_ar_data_attribute_form; /* data8, data4 abi &version dependent */ int de_ar_ref_attr_form; /* ref8 ref4 , abi dependent */ /* simple name relocations */ - _dwarf_pro_reloc_name_func_ptr de_reloc_name; + _dwarf_pro_reloc_name_func_ptr de_relocate_by_name_symbol; /* relocations for a length, requiring a pair of symbols */ - _dwarf_pro_reloc_length_func_ptr de_reloc_pair; + _dwarf_pro_reloc_length_func_ptr de_relocate_pair_by_symbol; _dwarf_pro_transform_relocs_func_ptr de_transform_relocs_to_disk; @@ -484,7 +548,7 @@ struct Dwarf_P_Debug_s { unsigned long de_compose_used_len; unsigned char de_same_endian; - void *(*de_copy_word) (void *, const void *, size_t); + void (*de_copy_word) (void *, const void *, unsigned long); /* Add new fields at the END of this struct to preserve some hope of sensible behavior on dbg passing between DSOs linked with @@ -496,18 +560,32 @@ struct Dwarf_P_Debug_s { int de_sect_sa_next_to_return; /* Iterator on sring attrib sects */ /* String attributes data of each section. */ struct Dwarf_P_Per_Sect_String_Attrs_s de_sect_string_attr[NUM_DEBUG_SECTIONS]; - /* Hold data needed to init new line output flexibly. */ + + /* Hold data needed to init line output flexibly. */ struct Dwarf_P_Line_Inits_s de_line_inits; + + struct Dwarf_P_Stats_s de_stats; }; #define CURRENT_VERSION_STAMP 2 -Dwarf_Unsigned _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, +int _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *entry_name, enum dwarf_sn_kind entrykind, Dwarf_Error * error); +enum dwarf_which_hash { + _dwarf_hash_debug_str, + _dwarf_hash_debug_line_str, + _dwarf_hash_debug_str_sup +}; -#define DISTINGUISHED_VALUE 0xffffffff /* 64bit extension flag */ +int +_dwarf_insert_or_find_in_debug_str(Dwarf_P_Debug dbg, + char *name, + enum dwarf_which_hash, + unsigned slen, /* includes space for trailing NUL */ + Dwarf_Unsigned *offset_in_debug_str, + Dwarf_Error *error); diff --git a/thirdparty/dwarf/pro_pubnames.c b/thirdparty/dwarf/pro_pubnames.c index a7baf8f9..507d0232 100644 --- a/thirdparty/dwarf/pro_pubnames.c +++ b/thirdparty/dwarf/pro_pubnames.c @@ -33,6 +33,11 @@ #include #endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" #include "pro_section.h" @@ -45,16 +50,54 @@ dwarf_add_pubname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubname_name, Dwarf_Error * error) { - return - _dwarf_add_simple_name_entry(dbg, die, pubname_name, - dwarf_snk_pubname, error); + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, pubname_name, + dwarf_snk_pubname, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; +} + +int +dwarf_add_pubname_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *pubname_name, Dwarf_Error * error) +{ + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, + pubname_name, + dwarf_snk_pubname, error); + return res; } + + + Dwarf_Unsigned dwarf_add_pubtype(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *pubtype_name, Dwarf_Error * error) { - return - _dwarf_add_simple_name_entry(dbg, die, pubtype_name, - dwarf_snk_pubtype, error); + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, pubtype_name, + dwarf_snk_pubtype, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; +} +int +dwarf_add_pubtype_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *pubtype_name, + Dwarf_Error * error) +{ + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, pubtype_name, + dwarf_snk_pubtype, error); + return res; } diff --git a/thirdparty/dwarf/pro_reloc.c b/thirdparty/dwarf/pro_reloc.c index b08dd624..72ffb9a9 100644 --- a/thirdparty/dwarf/pro_reloc.c +++ b/thirdparty/dwarf/pro_reloc.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2008-2011 David Anderson, Inc. All rights reserved. + Portions Copyright 2008-2016 David Anderson, Inc. All rights reserved. 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 @@ -31,6 +30,12 @@ #include /*#include */ #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" #include "pro_reloc.h" @@ -44,26 +49,28 @@ relocations count we can preallocate the right size block. Called from just 2 places. + We use 'slots' so we don't have to do a new + allocation for every relocation, just a new + allocation every n slots. slots_in_block. + returns DW_DLV_OK or DW_DLV_ERROR */ int -_dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, - int rel_sec_index, +_dwarf_pro_pre_alloc_specific_reloc_slots(Dwarf_P_Debug dbg, + Dwarf_P_Per_Reloc_Sect prel, Dwarf_Unsigned newslots) { unsigned long len = 0; struct Dwarf_P_Relocation_Block_s *data = 0; - Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index]; unsigned long slots_in_blk = (unsigned long) newslots; unsigned long rel_rec_size = dbg->de_relocation_record_size; - if (prel->pr_first_block) + if (prel->pr_first_block) { return DW_DLV_OK; /* do nothing */ + } len = sizeof(struct Dwarf_P_Relocation_Block_s) + slots_in_blk * rel_rec_size; - - data = (struct Dwarf_P_Relocation_Block_s *) _dwarf_p_get_alloc(dbg, len); if (!data) { @@ -82,8 +89,6 @@ _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, prel->pr_first_block = data; prel->pr_last_block = data; prel->pr_block_count = 1; - - return DW_DLV_OK; } @@ -117,20 +122,16 @@ _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index) prel->pr_last_block->rb_next = data; prel->pr_last_block = data; prel->pr_block_count += 1; - } else { - prel->pr_first_block = data; prel->pr_last_block = data; prel->pr_block_count = 1; } - data->rb_slots_in_block = slots_in_blk; data->rb_next_slot_to_use = 0; data->rb_where_to_add_next = ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s); data->rb_data = data->rb_where_to_add_next; - return DW_DLV_OK; } @@ -165,36 +166,28 @@ _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg, data = prel->pr_last_block; /* now we have an empty slot */ ret_addr = data->rb_where_to_add_next; - data->rb_where_to_add_next += rel_rec_size; data->rb_next_slot_to_use += 1; - prel->pr_reloc_total_count += 1; - *relrec_to_fill = (void *) ret_addr; - return DW_DLV_OK; } /* - On success returns count of - .rel.* sections that are symbolic - thru count_of_relocation_sections. + On success returns count of + .rel.* sections that are symbolic + thru count_of_relocation_sections. - On success, returns DW_DLV_OK. + On success, returns DW_DLV_OK. - If this is not a 'symbolic' run, returns + If this is not a 'symbolic' run, returns DW_DLV_NO_ENTRY. - No errors are possible. - - - - + No errors are possible. */ - -/*ARGSUSED*/ int +/*ARGSUSED*/ +int dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, Dwarf_Unsigned * count_of_relocation_sections, @@ -202,7 +195,7 @@ dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Error * error) { if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { - int i; + int i = 0; unsigned int count = 0; for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { @@ -214,6 +207,8 @@ dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; return DW_DLV_OK; } + /* Reset to start at beginning of reloc groups. */ + dbg->de_reloc_next_to_return = 0; return DW_DLV_NO_ENTRY; } @@ -228,19 +223,25 @@ dwarf_get_relocation_info(Dwarf_P_Debug dbg, int next = dbg->de_reloc_next_to_return; if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { - int i; + int i = 0; for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { + /* de_reloc_sect[] and de_elf_sects[] are + in direct parallel. */ Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i]; + int elf_sect_num = dbg->de_elf_sects[i]; if (prel->pr_reloc_total_count > 0) { + /* Set up 'next' for subsequent call to + dwarf_get_relocation_info(). */ dbg->de_reloc_next_to_return = i + 1; + /* ASSERT: prel->pr_block_count == 1 */ + *elf_section_index = prel->pr_sect_num_of_reloc_sect; - /* ASSERT: prel->.pr_block_count == 1 */ + /* Elf sec num in generated elf */ + *elf_section_index_link = elf_sect_num; - *elf_section_index = prel->pr_sect_num_of_reloc_sect; - *elf_section_index_link = dbg->de_elf_sects[i]; *relocation_buffer_count = prel->pr_reloc_total_count; *reldata_buffer = (Dwarf_Relocation_Data) (prel->pr_first_block->rb_data); diff --git a/thirdparty/dwarf/pro_reloc.h b/thirdparty/dwarf/pro_reloc.h index b6aba63d..357fab05 100644 --- a/thirdparty/dwarf/pro_reloc.h +++ b/thirdparty/dwarf/pro_reloc.h @@ -24,11 +24,8 @@ */ - - - -int _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg, - int rel_sec_index, +int _dwarf_pro_pre_alloc_specific_reloc_slots(Dwarf_P_Debug dbg, + Dwarf_P_Per_Reloc_Sect p_reloc, Dwarf_Unsigned newslots); int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index); diff --git a/thirdparty/dwarf/pro_reloc_stream.c b/thirdparty/dwarf/pro_reloc_stream.c index 080a9f65..651b3987 100644 --- a/thirdparty/dwarf/pro_reloc_stream.c +++ b/thirdparty/dwarf/pro_reloc_stream.c @@ -2,7 +2,7 @@ Copyright (C) 2000,2001,2004 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. - Portions Copyright 2008-2011 David Anderson, Inc. All rights reserved. + Portions Copyright 2008-2016 David Anderson, Inc. All rights reserved. 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 @@ -27,6 +27,7 @@ */ #include "config.h" +#ifdef DWARF_WITH_LIBELF #include "libdwarfdefs.h" #include #include @@ -38,6 +39,12 @@ #define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t)) #endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_reloc_stream.h" @@ -125,7 +132,7 @@ _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, elf32_reloc = (REL32*)relrec_to_fill; elf32_reloc->r_offset = (Elf32_Addr) offset; - Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type); + Set_REL32_info(*elf32_reloc, symidx, rel_type); return DW_DLV_OK; /* get a slot, fill in the slot entry */ @@ -165,17 +172,15 @@ _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count) { unsigned long total_size = 0; - Dwarf_Small *data = 0; - int sec_index = 0; - unsigned long i = 0; + int i = 0; Dwarf_Error erre = 0; Dwarf_Error *error = &erre; - Dwarf_Signed sec_count = 0; - Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0]; - - for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) { + for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { + Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect +i; + Dwarf_Small *data = 0; + int sec_index = 0; unsigned long ct = p_reloc->pr_reloc_total_count; unsigned len = 0; struct Dwarf_P_Relocation_Block_s *p_blk = 0; @@ -230,17 +235,13 @@ _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, block, simply copies to the output buffer. And frees the input block. The new block is in the de_debug_sects list. */ while (p_blk) { - unsigned long lenk = p_blk->rb_where_to_add_next - p_blk->rb_data; memcpy(data, p_blk->rb_data, lenk); - data += lenk; - p_blk_last = p_blk; p_blk = p_blk->rb_next; - _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); } /* ASSERT: sum of len copied == total_size */ @@ -250,7 +251,10 @@ _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg, p_reloc->pr_first_block = 0; p_reloc->pr_last_block = 0; } - *new_sec_count = sec_count; return DW_DLV_OK; } +#else /* DWARF_WITH_LIBELF */ +/* avoids empty file warning if no libelf */ +int dwarf_dummy_pro_reloc_stream = 2; +#endif /* DWARF_WITH_LIBELF */ diff --git a/thirdparty/dwarf/pro_reloc_stream.h b/thirdparty/dwarf/pro_reloc_stream.h index bcdfe1be..43b110bb 100644 --- a/thirdparty/dwarf/pro_reloc_stream.h +++ b/thirdparty/dwarf/pro_reloc_stream.h @@ -25,8 +25,6 @@ */ - - int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,/* r_offset of reloc */ diff --git a/thirdparty/dwarf/pro_reloc_symbolic.c b/thirdparty/dwarf/pro_reloc_symbolic.c index c6d38105..4f60b4da 100644 --- a/thirdparty/dwarf/pro_reloc_symbolic.c +++ b/thirdparty/dwarf/pro_reloc_symbolic.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. + Portions Copyright 2016 David Anderson. All Rights Reserved. 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 @@ -31,10 +31,23 @@ #include /*#include */ #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" #include "pro_section.h" #include "pro_reloc.h" #include "pro_reloc_symbolic.h" +#ifndef SHT_REL +#define SHT_REL 9 +#endif /* SHT_REL */ +#ifndef SHN_UNDEF +#define SHN_UNDEF 0 +#endif /* SHN_UNDEF */ + /* Return DW_DLV_ERROR on malloc error. Return DW_DLV_OK otherwise */ @@ -106,23 +119,6 @@ _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, return DW_DLV_OK; } -/* Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s - we must to allow adding a fresh new single - block easily (block consolidation use only). */ -static void -_dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk, - unsigned long ct) -{ - - - /* Do not zero pr_sect_num_of_reloc_sect */ - pblk->pr_reloc_total_count = 0; - pblk->pr_first_block = 0; - pblk->pr_last_block = 0; - pblk->pr_block_count = 0; - pblk->pr_slots_per_block_to_alloc = ct; -} - /* Ensure each stream is a single buffer and add that single buffer to the set of stream buffers. @@ -143,30 +139,24 @@ int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, Dwarf_Signed * new_sec_count) { - /* unsigned long total_size =0; */ - Dwarf_Small *data = 0; - int sec_index = 0; - int res = 0; - unsigned long i = 0; + int i = 0; Dwarf_Error error = 0; - Dwarf_Signed sec_count = 0; - Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0]; - for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) { + for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { + int sec_index = 0; + Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect + i; unsigned long ct = p_reloc->pr_reloc_total_count; - struct Dwarf_P_Relocation_Block_s *p_blk; - struct Dwarf_P_Relocation_Block_s *p_blk_last; - int err; + int err = 0; if (ct == 0) { + /* No relocations in here. Nothing to do. */ continue; } - /* len = dbg->de_relocation_record_size; */ - ++sec_count; - /* total_size = ct *len; */ sec_index = p_reloc->pr_sect_num_of_reloc_sect; if (sec_index == 0) { + /* sec_index zero means we have not processed this + section of relocations yet. */ /* Call de_callback_func getting section number of reloc section. */ int rel_section_index = 0; @@ -180,6 +170,8 @@ _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, real arrays. */ if (dbg->de_callback_func) { + /* For symbolic relocations de_callback_func + may well return 0. */ rel_section_index = dbg->de_callback_func(_dwarf_rel_section_names[i], dbg->de_relocation_record_size, @@ -199,30 +191,59 @@ _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, } } p_reloc->pr_sect_num_of_reloc_sect = rel_section_index; - sec_index = rel_section_index; } - p_blk = p_reloc->pr_first_block; - - if (p_reloc->pr_block_count > 1) { - struct Dwarf_P_Relocation_Block_s *new_blk; - /* HACK , not normal interfaces, trashing p_reloc current - contents! */ - _dwarf_reset_reloc_sect_info(p_reloc, ct); - - /* Creating new single block for all 'ct' entries */ - res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct); + /* If pr_block_count 0 or 1 then the blocks are + an array (with 0 or 1 entries) so we'll just + return to the for loop. No more work to do here. */ + if (p_reloc->pr_block_count < 2) { + continue; + } + { + /* Since more than one relocation on the section + we now convert the list of relocation blocks + into a proper array of blocks. */ + struct Dwarf_P_Relocation_Block_s *new_blk = 0; + struct Dwarf_P_Relocation_Block_s *p_blk = 0; + Dwarf_Small *data = 0; + int res = 0; + + p_blk = p_reloc->pr_first_block; + /* Do not zero pr_sect_num_of_reloc_sect */ + p_reloc->pr_reloc_total_count = 0; + p_reloc->pr_first_block = 0; + p_reloc->pr_last_block = 0; + p_reloc->pr_block_count = 0; + /* Now we know a number making a single + array. Replaces DEFAULT_SLOTS_PER_BLOCK */ + p_reloc->pr_slots_per_block_to_alloc = ct; + + /* Creating new single block for all 'ct' entries. + Assigns a pointer value to pr_first_block + (which means our p_reloc). + It updates p_reloc->pr_first_block */ + res = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, + p_reloc,ct); if (res != DW_DLV_OK) { return res; } - new_blk = p_reloc->pr_first_block; + new_blk = p_reloc->pr_first_block; data = (Dwarf_Small *) new_blk->rb_data; /* The following loop does the consolidation to a single - block and frees the input block(s). */ + block and frees the input block(s). + p_blk points to the old singly-linked-list + and is the + only access to that list. + data is a pointer to the new array of ct entries + which is our target(destination) of the copies. + */ do { + struct Dwarf_P_Relocation_Block_s *p_blk_last = 0; + /* len identifies the data in all the slots + in use in this block. */ unsigned long len = p_blk->rb_where_to_add_next - p_blk->rb_data; memcpy(data, p_blk->rb_data, len); @@ -231,15 +252,20 @@ _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, p_blk = p_blk->rb_next; _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); } while (p_blk); + /* ASSERT: the dangling p_blk list all dealloc'd + which is really a no-op, all deallocations + take place at producer_finish(). */ /* ASSERT: sum of len copied == total_size */ new_blk->rb_next_slot_to_use = ct; new_blk->rb_where_to_add_next = (char *) data; p_reloc->pr_reloc_total_count = ct; - /* Have now created a single block, but no change in slots - used (pr_reloc_total_count) */ + /* Have now created a single block, but no + change in slots used (pr_reloc_total_count) */ } } + /* There is no section data with symbolic, + so there is no count. */ *new_sec_count = 0; return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_section.c b/thirdparty/dwarf/pro_section.c index f6b3e9ab..b2448661 100644 --- a/thirdparty/dwarf/pro_section.c +++ b/thirdparty/dwarf/pro_section.c @@ -1,28 +1,31 @@ /* Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved. Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. Portions Copyright 2012 SN Systems Ltd. All rights reserved. - 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 Software Foundation. - - This program is distributed in the hope that it would be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - Further, this software is distributed without any warranty that it is - free of the rightful claim of any third person regarding infringement - or the like. Any license provided herein, whether implied or - otherwise, applies only to this software file. Patent licenses, if - any, provided herein do not apply to combinations of this program with - other software, or any other product whatsoever. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, - USA. + 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 + Software Foundation. + + This program is distributed in the hope that it would be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + + Further, this software is distributed without any warranty + that it is free of the rightful claim of any third person + regarding infringement or the like. Any license provided + herein, whether implied or otherwise, applies only to this + software file. Patent licenses, if any, provided herein + do not apply to combinations of this program with other + software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General + Public License along with this program; if not, write the + Free Software Foundation, Inc., 51 Franklin Street - Fifth + Floor, Boston MA 02110-1301, USA. */ @@ -33,13 +36,30 @@ #ifdef HAVE_ELFACCESS_H #include #endif +#ifdef HAVE_STDLIB_H +#include +#endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_util.h" +#include "pro_encode_nm.h" +#include "pro_alloc.h" #include "pro_section.h" #include "pro_line.h" #include "pro_frame.h" #include "pro_die.h" #include "pro_macinfo.h" #include "pro_types.h" +#include "pro_dnames.h" + + +#ifndef SHN_UNDEF +#define SHN_UNDEF 0 +#endif /* SHN_UNDEF */ #ifndef SHF_MIPS_NOSTRIP /* if this is not defined, we probably don't need it: just use 0 */ @@ -56,6 +76,43 @@ #define FALSE 0 #endif +#ifdef WORDS_BIGENDIAN +#define ASNOUT(t,s,l) \ + do { \ + unsigned sbyte = 0; \ + const char *p = 0; \ + if (l > sizeof(s)) { \ + _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ + return DW_DLV_ERROR; \ + } \ + sbyte = sizeof(s) - l; \ + p = (const char *)(&s); \ + memcpy(t,(const void *)(p+sbyte),l);\ + } while (0) +#else /* LITTLEENDIAN */ +#define ASNOUT(t,s,l) \ + do { \ + const char *p = 0; \ + if (l > sizeof(s)) { \ + _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ + return DW_DLV_ERROR; \ + } \ + p = (const char *)(&s); \ + memcpy(t,(const void *)p,l); \ + } while (0) +#endif /* ENDIANNESS */ + + +#define SIZEOFT32 4 + +struct Dwarf_Sort_Abbrev_s { + Dwarf_Unsigned dsa_attr; + Dwarf_Unsigned dsa_form; + Dwarf_Signed dsa_implicitvalue; + Dwarf_P_Attribute dsa_attrp; +}; + + /* Must match up with pro_section.h defines of DEBUG_INFO etc and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela" see pro_incl.h @@ -63,11 +120,10 @@ see pro_incl.h const char *_dwarf_rel_section_names[] = { REL_SEC_PREFIX ".debug_info", REL_SEC_PREFIX ".debug_line", - REL_SEC_PREFIX ".debug_abbrev", /* no relocations on this, really */ + REL_SEC_PREFIX ".debug_abbrev", /* Nothing here refers to anything. */ REL_SEC_PREFIX ".debug_frame", REL_SEC_PREFIX ".debug_aranges", REL_SEC_PREFIX ".debug_pubnames", - REL_SEC_PREFIX ".debug_str", REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */ REL_SEC_PREFIX ".debug_typenames", /* sgi extension */ REL_SEC_PREFIX ".debug_varnames", /* sgi extension */ @@ -77,6 +133,13 @@ const char *_dwarf_rel_section_names[] = { REL_SEC_PREFIX ".debug_ranges", REL_SEC_PREFIX ".debug_types", /* new in DWARF4 */ REL_SEC_PREFIX ".debug_pubtypes", /* new in DWARF3 */ + REL_SEC_PREFIX ".debug_names", /* DWARF5 aka dnames */ + REL_SEC_PREFIX ".debug_str", /* Nothing here refers to anything.*/ + REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */ + REL_SEC_PREFIX ".debug_line_str", /* DWARF5. Nothing referselsewhere */ + REL_SEC_PREFIX ".debug_macro", /* DWARF5. */ + REL_SEC_PREFIX ".debug_loclists", /* DWARF5. */ + REL_SEC_PREFIX ".debug_rnglists", /* DWARF5. */ }; /* names of sections. Ensure that it matches the defines @@ -90,7 +153,6 @@ const char *_dwarf_sectnames[] = { ".debug_frame", ".debug_aranges", ".debug_pubnames", - ".debug_str", ".debug_funcnames", /* sgi extension */ ".debug_typenames", /* sgi extension */ ".debug_varnames", /* sgi extension */ @@ -100,6 +162,12 @@ const char *_dwarf_sectnames[] = { ".debug_ranges", ".debug_types", /* new in DWARF4 */ ".debug_pubtypes", /* new in DWARF3 */ + ".debug_names", /* new in DWARF5. aka dnames */ + ".debug_str", + ".debug_line_str", /* new in DWARF5 */ + ".debug_macro", /* new in DWARF5 */ + ".debug_loclists", /* new in DWARF5 */ + ".debug_rnglists", /* new in DWARF5 */ }; @@ -138,24 +206,106 @@ struct Dwarf_P_Rel_Head_s { struct Dwarf_P_Rel_s *drh_tail; }; +static int +_dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error); +static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error); +static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, - Dwarf_Error * error); + Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, - Dwarf_Error * error); + Dwarf_Signed *nbufs, Dwarf_Error * error); static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, - Dwarf_Error * error); -static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev); -static int _dwarf_pro_match_attr - (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr); + Dwarf_Signed *nbufs, Dwarf_Error * error); + +#if 0 +static void +dump_bytes(char * msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + + printf("%s len %ld ",msg,len); + for (; cur < end; cur++) { + printf("%02x ", *cur); + } + printf("\n"); +} +#endif + +#if 0 +static void +print_single_abbrev(Dwarf_P_Abbrev c, unsigned idx) +{ + unsigned j = 0; + + printf(" %2u idx %2u tag 0x%x attrct %2u\n",idx, + (unsigned)c->abb_idx, + (unsigned)c->abb_tag, + (unsigned)c->abb_n_attr); + + for ( ; j < (unsigned)c->abb_n_attr; ++j) { + printf(" %2u attr 0x%2x form 0x%2x impl val %" DW_PR_DSd "\n", + j, + (unsigned)c->abb_attrs[j], + (unsigned)c->abb_forms[j]); + (unsigned)c->abb_implicits[j]); + } +} +static void +print_curabbrev(const char *where, + Dwarf_P_Abbrev curabbrev) +{ + Dwarf_P_Abbrev ca = 0; + unsigned i = 0; + for(ca = curabbrev; ca ; ca = ca->abb_next,++i) { + printf("ABBREV %u from %s\n",i,where); + print_single_abbrev(ca,i); + } +} +#endif -/* these macros used as return value for below functions */ + +/* These macros used as return value for _dwarf_pro_get_opc. */ #define OPC_INCS_ZERO -1 #define OPC_OUT_OF_RANGE -2 #define LINE_OUT_OF_RANGE -3 -static int _dwarf_pro_get_opc(Dwarf_P_Debug dbg,Dwarf_Unsigned addr_adv, int line_adv); +/* Given address advance and line advance, it gives + either special opcode, or a number < 0 + + FIXME: Check all three negative values. + Are any negatives really hard errors? +*/ +static int +_dwarf_pro_get_opc( + struct Dwarf_P_Line_Inits_s *inits, + Dwarf_Unsigned addr_adv, + int line_adv) +{ + int line_base = inits->pi_line_base; + int line_range =inits->pi_line_range; + Dwarf_Unsigned factored_adv = 0; + factored_adv = addr_adv / inits->pi_minimum_instruction_length; + if (line_adv == 0 && factored_adv == 0) { + return OPC_INCS_ZERO; + } + if (line_adv >= line_base && line_adv < line_base + line_range) { + int opc = (line_adv - line_base) + (factored_adv * line_range) + + inits->pi_opcode_base; + if (opc > 255) { + return OPC_OUT_OF_RANGE; + } + return opc; + } + return LINE_OUT_OF_RANGE; +} -/* BEGIN_LEN_SIZE is the size of the 'length' field in total. + + +/* OFFSET_PLUS_EXTENSION_SIZE is the size of the 'length' field in total. Which may be 4,8, or 12 bytes! 4 is standard DWARF2. 8 is non-standard MIPS-IRIX 64-bit. @@ -163,7 +313,7 @@ static int _dwarf_pro_get_opc(Dwarf_P_Debug dbg,Dwarf_Unsigned addr_adv, int lin Used in various routines: local variable names must match the names here. */ -#define BEGIN_LEN_SIZE (uwordb_size + extension_size) +#define OFFSET_PLUS_EXTENSION_SIZE (offset_size + extension_size) /* Return TRUE if we need the section, FALSE otherwise @@ -175,6 +325,9 @@ static int _dwarf_pro_get_opc(Dwarf_P_Debug dbg,Dwarf_Unsigned addr_adv, int lin static int dwarf_need_debug_line_section(Dwarf_P_Debug dbg) { + if (dbg->de_output_version > 4) { + return FALSE; + } if (dbg->de_lines == NULL && dbg->de_file_entries == NULL && dbg->de_inc_dirs == NULL) { return FALSE; @@ -182,25 +335,61 @@ dwarf_need_debug_line_section(Dwarf_P_Debug dbg) return TRUE; } +/* DWARF5 only. */ +static int +dwarf_need_debug_names_section(Dwarf_P_Debug dbg) +{ + if (dbg->de_output_version < 5) { + return FALSE; + } + if (!dbg->de_dnames) { + return FALSE; + } + if (!dbg->de_dnames->dn_create_section) { + return FALSE; + } + return TRUE; +} + /* Convert debug information to a format such that it can be written on disk. Called exactly once per execution. + This is the traditional interface. Bad interface design. */ Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) +{ + Dwarf_Signed count = 0; + int res = 0; + + res = dwarf_transform_to_disk_form_a(dbg, &count,error); + if (res == DW_DLV_ERROR) { + return DW_DLV_NOCOUNT; + } + return count; +} +/* Convert debug information to a format such that + it can be written on disk. + Called exactly once per execution. + This is the interface design used with the consumer + interface, so easier for callers to work with. +*/ +int +dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg, Dwarf_Signed *count, + Dwarf_Error * error) { /* Section data in written out in a number of buffers. Each _generate_*() function returns a cumulative count of buffers for all the sections. dwarf_get_section_bytes() returns pointers to these buffers one at a time. */ - int nbufs = 0; + Dwarf_Signed nbufs = 0; int sect = 0; int err = 0; Dwarf_Unsigned du = 0; if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } /* Create dwarf section headers */ @@ -254,7 +443,7 @@ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) break; case DEBUG_STR: - if (dbg->de_strings == NULL) { + if (dbg->de_debug_str->ds_data == NULL) { continue; } break; @@ -292,6 +481,11 @@ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) continue; } break; + case DEBUG_NAMES: /* DWARF5 */ + if (dwarf_need_debug_names_section(dbg) == FALSE) { + continue; + } + break; case DEBUG_LOC: /* Not handled yet. */ continue; @@ -301,9 +495,24 @@ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) case DEBUG_TYPES: /* Not handled yet. */ continue; + case DEBUG_MACRO: + /* Not handled yet. */ + continue; + case DEBUG_LOCLISTS: + /* Not handled yet. */ + continue; + case DEBUG_RNGLISTS: + /* Not handled yet. */ + continue; + case DEBUG_LINE_STR: + if (dwarf_need_debug_line_section(dbg) == FALSE) { + continue; + } + /* Not handled yet. */ + continue; default: /* logic error: missing a case */ - DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT); + DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR); } { int new_base_elf_sect = 0; @@ -318,10 +527,9 @@ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) } if (new_base_elf_sect == -1) { DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, - DW_DLV_NOCOUNT); + DW_DLV_ERROR); } dbg->de_elf_sects[sect] = new_base_elf_sect; - dbg->de_sect_name_idx[sect] = du; } } @@ -332,107 +540,147 @@ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) problems because of relocations. */ if (dwarf_need_debug_line_section(dbg) == TRUE) { - nbufs = _dwarf_pro_generate_debugline(dbg, error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR, - DW_DLV_NOCOUNT); + int res = _dwarf_pro_generate_debugline(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; } } if (dbg->de_frame_cies) { - nbufs = _dwarf_pro_generate_debugframe(dbg, error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR, - DW_DLV_NOCOUNT); + int res = _dwarf_pro_generate_debugframe(dbg,&nbufs,error); + if (res == DW_DLV_ERROR) { + return res; } } if (dbg->de_first_macinfo) { - nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR, - DW_DLV_NOCOUNT); + /* For DWARF 2,3,4 only */ + /* Need new code for DWARF5 macro info. FIXME*/ + int res = _dwarf_pro_transform_macro_info_to_disk(dbg, + &nbufs,error); + if (res == DW_DLV_ERROR) { + return res; } } if (dbg->de_dies) { - nbufs = _dwarf_pro_generate_debuginfo(dbg, error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, - DW_DLV_NOCOUNT); + int res= _dwarf_pro_generate_debuginfo(dbg, &nbufs, error); + if (res == DW_DLV_ERROR) { + return res; } } - if (dbg->de_arange) { - nbufs = _dwarf_transform_arange_to_disk(dbg, error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ARANGE_ERROR, - DW_DLV_NOCOUNT); + if (dbg->de_debug_str->ds_data) { + int res = _dwarf_pro_generate_debug_str(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; } } - - if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { - nbufs = _dwarf_transform_simplename_to_disk(dbg, - dwarf_snk_pubname, - DEBUG_PUBNAMES, - error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_PUBNAMES_ERROR, - DW_DLV_NOCOUNT); + if (dbg->de_debug_line_str->ds_data) { + int res = _dwarf_pro_generate_debug_line_str(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; } } - if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) { - nbufs = _dwarf_transform_simplename_to_disk(dbg, - dwarf_snk_pubtype, - DEBUG_PUBTYPES, - error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGPUBTYPES_ERROR, - DW_DLV_NOCOUNT); + + + + if (dbg->de_arange) { + int res = _dwarf_transform_arange_to_disk(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; } } + if (dbg->de_output_version < 5) { + if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { + int res = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_pubname, + DEBUG_PUBNAMES, + &nbufs, + error); + if (res == DW_DLV_ERROR) { + return res; + } + } + if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) { + int res = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_pubtype, + DEBUG_PUBTYPES, + &nbufs, + error); + if (res == DW_DLV_ERROR) { + return res; + } + } - if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { - nbufs = _dwarf_transform_simplename_to_disk(dbg, - dwarf_snk_funcname, - DEBUG_FUNCNAMES, - error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_FUNCNAMES_ERROR, - DW_DLV_NOCOUNT); + if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { + int res = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_funcname, + DEBUG_FUNCNAMES, + &nbufs, + error); + if (res == DW_DLV_ERROR) { + return res; + } } - } - if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { - nbufs = _dwarf_transform_simplename_to_disk(dbg, - dwarf_snk_typename, - DEBUG_TYPENAMES, - error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_TYPENAMES_ERROR, - DW_DLV_NOCOUNT); + if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { + int res = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_typename, + DEBUG_TYPENAMES, + &nbufs, + error); + if (res == DW_DLV_ERROR) { + return res; + } } - } - if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { - nbufs = _dwarf_transform_simplename_to_disk(dbg, - dwarf_snk_varname, - DEBUG_VARNAMES, - error); + if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { + int res = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_varname, + DEBUG_VARNAMES, + &nbufs, + error); + if (res == DW_DLV_ERROR) { + return res; + } + } - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_VARNAMES_ERROR, - DW_DLV_NOCOUNT); + if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { + int res = _dwarf_transform_simplename_to_disk(dbg, + dwarf_snk_weakname, DEBUG_WEAKNAMES, + &nbufs, + error); + if (res == DW_DLV_ERROR) { + return res; + } } } - - if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { - nbufs = _dwarf_transform_simplename_to_disk(dbg, - dwarf_snk_weakname, DEBUG_WEAKNAMES, error); - if (nbufs < 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_WEAKNAMES_ERROR, - DW_DLV_NOCOUNT); + if (dwarf_need_debug_names_section(dbg) == TRUE) { + int res = _dwarf_pro_generate_debug_names(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; + } + } +#if 0 /* FIXME: TODO new sections */ + if (dwarf_need_debug_macro_section(dbg) == TRUE) { + int res = _dwarf_pro_generate_debug_macro(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; + } + } + if (dwarf_need_debug_loclists_section(dbg) == TRUE) { + int res = _dwarf_pro_generate_debug_loclists(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; } } + if (dwarf_need_debug_rnglists_section(dbg) == TRUE) { + int res = _dwarf_pro_generate_debug_rnglists(dbg,&nbufs, error); + if (res == DW_DLV_ERROR) { + return res; + } + } +#endif { Dwarf_Signed new_chunks = 0; @@ -441,60 +689,72 @@ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks); if (res != DW_DLV_OK) { DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR, - DW_DLV_NOCOUNT); + DW_DLV_ERROR); } nbufs += new_chunks; } - return nbufs; + *count = nbufs; + return DW_DLV_OK; } -static unsigned +static int write_fixed_size(Dwarf_Unsigned val, Dwarf_P_Debug dbg, int elfsectno, Dwarf_Unsigned size, + unsigned * size_out, Dwarf_Error* error) { unsigned char *data = 0; - GET_CHUNK(dbg, elfsectno, data, size, error); + GET_CHUNK_ERR(dbg, elfsectno, data, size, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &val, sizeof(val), size); - return size; + *size_out = size; + return DW_DLV_OK; } -static unsigned +static int write_ubyte(unsigned val, Dwarf_P_Debug dbg, int elfsectno, + unsigned *len_out, Dwarf_Error* error) { Dwarf_Ubyte db = val; unsigned char *data = 0; unsigned len = sizeof(Dwarf_Ubyte); - GET_CHUNK(dbg, elfsectno, data, + GET_CHUNK_ERR(dbg, elfsectno, data, len, error); WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), len); - return 1; + *len_out = 1; + return DW_DLV_OK;; } -static unsigned +static int pretend_write_uval(Dwarf_Unsigned val, - UNUSEDARG Dwarf_P_Debug dbg, - UNUSEDARG int elfsectno, - UNUSEDARG Dwarf_Error* error) + Dwarf_P_Debug dbg, + unsigned *uval_len_out, + Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; int nbytes = 0; - _dwarf_pro_encode_leb128_nm(val, + int res = 0; + + res = _dwarf_pro_encode_leb128_nm(val, &nbytes, buff1, sizeof(buff1)); - return nbytes; + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR , DW_DLV_ERROR); + } + *uval_len_out = nbytes; + return DW_DLV_OK; } -static unsigned +static int write_sval(Dwarf_Signed val, Dwarf_P_Debug dbg, int elfsectno, + unsigned *sval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; @@ -504,17 +764,43 @@ write_sval(Dwarf_Signed val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } GET_CHUNK(dbg, elfsectno, data, nbytes, error); memcpy((void *) data, (const void *) buff1, nbytes); - return nbytes; + *sval_len_out = nbytes; + return DW_DLV_OK; } -static unsigned +/* This one does not allocate a chunk, uses + an already existing chunk. + data points into that existing chunk. */ +static int +append_uval(Dwarf_Unsigned val, + Dwarf_P_Debug dbg, + unsigned char *data, + unsigned * uval_len_out, + Dwarf_Error* error) +{ + char buff1[ENCODE_SPACE_NEEDED]; + int nbytes = 0; + int res = _dwarf_pro_encode_leb128_nm(val, + &nbytes, buff1, + sizeof(buff1)); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); + } + memcpy((void *) data, (const void *) buff1, nbytes); + *uval_len_out = nbytes; + return DW_DLV_OK; +} + + +static int write_uval(Dwarf_Unsigned val, Dwarf_P_Debug dbg, int elfsectno, + unsigned * uval_len_out, Dwarf_Error* error) { char buff1[ENCODE_SPACE_NEEDED]; @@ -524,183 +810,737 @@ write_uval(Dwarf_Unsigned val, &nbytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); } - GET_CHUNK(dbg, elfsectno, data, nbytes, error); + GET_CHUNK_ERR(dbg, elfsectno, data, nbytes, error); memcpy((void *) data, (const void *) buff1, nbytes); - return nbytes; + *uval_len_out = nbytes; + return DW_DLV_OK; } + + static unsigned write_opcode_uval(int opcode, Dwarf_P_Debug dbg, int elfsectno, Dwarf_Unsigned val, + unsigned *len_out, Dwarf_Error* error) { - unsigned totallen = write_ubyte(opcode,dbg,elfsectno,error); - totallen += write_uval(val,dbg,elfsectno,error); - return totallen; + unsigned ublen = 0; + int res = 0; + unsigned uvlen = 0; + res = write_ubyte(opcode,dbg,elfsectno,&ublen,error); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); + } + res = write_uval(val,dbg,elfsectno,&uvlen,error); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR); + } + *len_out = ublen +uvlen; + return DW_DLV_OK; } -/* Generate debug_line section */ static int -_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) +determine_form_size(Dwarf_P_Debug dbg, + unsigned format_count, + struct Dwarf_P_Line_format_s *format, + unsigned *size_out, + Dwarf_Bool write_out, + unsigned char *data, + Dwarf_Error *error) { - Dwarf_P_Inc_Dir curdir = 0; - Dwarf_P_F_Entry curentry = 0; - Dwarf_P_Line curline = 0; - Dwarf_P_Line prevline = 0; - - /* all data named cur* are used to loop thru linked lists */ - - int sum_bytes = 0; - int prolog_size = 0; - unsigned char *data = 0; /* holds disk form data */ - int elfsectno = 0; - unsigned char *start_line_sec = 0; /* pointer to the buffer at - section start */ - /* temps for memcpy */ - Dwarf_Unsigned du = 0; - Dwarf_Ubyte db = 0; - Dwarf_Half dh = 0; + unsigned calculated_size = 0; + unsigned n = 0; int res = 0; - int uwordb_size = dbg->de_offset_size; - int extension_size = dbg->de_64bit_extension ? 4 : 0; - int upointer_size = dbg->de_pointer_size; - - sum_bytes = 0; - elfsectno = dbg->de_elf_sects[DEBUG_LINE]; + /* entry format itself */ + calculated_size += sizeof_ubyte(dbg); - /* include directories */ - curdir = dbg->de_inc_dirs; - while (curdir) { - prolog_size += strlen(curdir->did_name) + 1; - curdir = curdir->did_next; - } - prolog_size++; /* last null following last directory - entry. */ + /* Space for the format details. */ + for(n = 0; n < format_count; ++n) { + struct Dwarf_P_Line_format_s *lf = format+n; + unsigned val_len = 0; + unsigned val_len2 = 0; - /* file entries */ - curentry = dbg->de_file_entries; - while (curentry) { - prolog_size += - strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; - curentry = curentry->dfe_next; + if (write_out) { + res = append_uval(lf->def_content_type, dbg, + data, + &val_len,error); + } else { + res = pretend_write_uval(lf->def_content_type, dbg, + &val_len,error); + } + data += val_len; + if(res != DW_DLV_OK) { + return res; + } + if (write_out) { + res = append_uval(lf->def_form_code, dbg, + data, + &val_len2,error); + } else { + res = pretend_write_uval(lf->def_form_code, dbg, + &val_len2,error); + } + if(res != DW_DLV_OK) { + return res; + } + data += val_len2; + calculated_size += val_len + val_len2; } - prolog_size++; /* last null byte */ - - - prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */ - uwordb_size + /* header length */ - sizeof_ubyte(dbg) + /* min_instr length */ - sizeof_ubyte(dbg) + /* default is_stmt */ - sizeof_ubyte(dbg) + /* linebase */ - sizeof_ubyte(dbg) + /* linerange */ - sizeof_ubyte(dbg); /* opcode base */ + *size_out = calculated_size; + return DW_DLV_OK; +} - /* length of table specifying # of opnds */ - prolog_size += dbg->de_line_inits.pi_opcode_base-1; - if (dbg->de_line_inits.pi_version == DW_LINE_VERSION4) { - /* For maximum_operations_per_instruction. */ - prolog_size += sizeof_ubyte(dbg); +static int +determine_file_content_size(Dwarf_P_Debug dbg, + Dwarf_P_F_Entry entry_list, + Dwarf_Unsigned format_count, + struct Dwarf_P_Line_format_s *format, + unsigned *size_out, + Dwarf_Bool write_out, + unsigned char *data, + Dwarf_Error *error) +{ + unsigned calculated_size = 0; + unsigned count_len = 0; + Dwarf_P_F_Entry cur = 0; + Dwarf_P_F_Entry nxt = 0; + unsigned n = 0; + int res = 0; + Dwarf_Unsigned offset_size = 0; + + offset_size = dbg->de_offset_size; + res = pretend_write_uval(format_count,dbg, + &count_len,error); + if(res != DW_DLV_OK) { + return res; } + calculated_size += count_len; + + cur = entry_list; + for(n = 0; cur; n++,cur = nxt) { + unsigned f = 0; + nxt = cur->dfe_next; + + for( ; f < format_count; f++) { + struct Dwarf_P_Line_format_s *lf = format+f; + unsigned ctype = lf->def_content_type; + unsigned cform = lf->def_form_code; + + switch (ctype) { + case DW_LNCT_path: { + switch(cform) { + case DW_FORM_string: { + unsigned slen = strlen(cur->dfe_name) +1; + calculated_size += slen; + if (write_out) { + strcpy((char *)data, cur->dfe_name); + data += slen; + } + } + break; + case DW_FORM_strp: { + unsigned slen = strlen(cur->dfe_name) +1; + if (write_out) { + Dwarf_Unsigned stroffset = 0; + res = _dwarf_insert_or_find_in_debug_str( + dbg, + cur->dfe_name, + _dwarf_hash_debug_str, + slen, + &stroffset,error); + if (res != DW_DLV_OK) { + return res; + } + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &stroffset, + sizeof(stroffset), offset_size); + data += offset_size; + } + calculated_size += offset_size; + } + break; + case DW_FORM_line_strp: { + unsigned slen = strlen(cur->dfe_name) +1; + if (write_out) { + Dwarf_Unsigned stroffset = 0; + res = _dwarf_insert_or_find_in_debug_str( + dbg, + cur->dfe_name, + _dwarf_hash_debug_line_str, + slen, + &stroffset,error); + if (res != DW_DLV_OK) { + return res; + } + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &stroffset, + sizeof(stroffset), offset_size); + data += offset_size; + } + calculated_size += offset_size; + } + break; + case DW_FORM_strp_sup: + /* Following in dwo only. */ + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: + default: + DWARF_P_DBG_ERROR(dbg, + DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); + break; + } + } + break; + case DW_LNCT_directory_index: { + switch(cform) { + case DW_FORM_data1: + calculated_size += 1; + if (write_out) { + unsigned char ub = cur->dfe_index; + *data = ub; + data += 1; + } + break; + case DW_FORM_data2: + calculated_size += DWARF_HALF_SIZE; + if (write_out) { + Dwarf_Half uh = cur->dfe_index; + memcpy(data,&uh,DWARF_HALF_SIZE); + data += DWARF_HALF_SIZE; + } + break; + case DW_FORM_udata: { + unsigned val_len = 0; + if (write_out) { + res = append_uval(cur->dfe_index, + dbg, + data, + &val_len,error); + data += val_len; + } else { + res = pretend_write_uval(cur->dfe_index, + dbg, &val_len,error); + } + if (res != DW_DLV_OK) { + return res; + } + calculated_size += val_len; + } + break; + default: + DWARF_P_DBG_ERROR(dbg, + DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); + } + } + break; + case DW_LNCT_timestamp: { + switch(cform) { + case DW_FORM_udata: { + unsigned val_len = 0; + if (write_out) { + res = append_uval(cur->dfe_timestamp, + dbg, + data, + &val_len,error); + data += val_len; + } else { + res = pretend_write_uval(cur->dfe_timestamp, + dbg, &val_len,error); + } + if (res != DW_DLV_OK) { + return res; + } + calculated_size += val_len; + } + break; + case DW_FORM_data4: { + calculated_size += DWARF_32BIT_SIZE; + if (write_out) { + ASNOUT(data,cur->dfe_timestamp, + DWARF_32BIT_SIZE); + data += DWARF_32BIT_SIZE; + } + } + break; + case DW_FORM_data8: + /* As of 2017 there is no 8 byte timestamp + defined, though it does have to happen. + before 2038. */ + calculated_size += DWARF_64BIT_SIZE; + if (write_out) { + Dwarf_Unsigned u8 = cur->dfe_index; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &u8, + sizeof(u8), DWARF_64BIT_SIZE); + data += DWARF_64BIT_SIZE; + } + break; + case DW_FORM_block: + default: + DWARF_P_DBG_ERROR(dbg, + DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); + } + } + break; + case DW_LNCT_size: { + switch(cform) { + case DW_FORM_data1: + calculated_size += 1; + if (write_out) { + unsigned char ub = cur->dfe_index; + *data = ub; + data += 1; + } + break; + case DW_FORM_data2: + calculated_size += DWARF_HALF_SIZE; + if (write_out) { + Dwarf_Half uh = cur->dfe_index; + memcpy(data,&uh,DWARF_HALF_SIZE); + + } + break; + case DW_FORM_data4: + calculated_size += DWARF_32BIT_SIZE; + if (write_out) { + ASNOUT(data,cur->dfe_index, + DWARF_32BIT_SIZE); + data += DWARF_32BIT_SIZE; + } + break; + case DW_FORM_data8: + calculated_size += DWARF_64BIT_SIZE; + if (write_out) { + Dwarf_Unsigned u8 = cur->dfe_index; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &u8, + sizeof(u8), DWARF_64BIT_SIZE); + data += DWARF_64BIT_SIZE; + } + break; + case DW_FORM_udata: { + unsigned val_len = 0; + if (write_out) { + res = append_uval(cur->dfe_size, + dbg, + data, + &val_len,error); + data += val_len; + } else { + res = pretend_write_uval(cur->dfe_size, + dbg, &val_len,error); + } + if (res != DW_DLV_OK) { + return res; + } + calculated_size += val_len; + } + break; + default: + DWARF_P_DBG_ERROR(dbg, + DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); + } + } + break; + case DW_LNCT_MD5: { + switch(cform) { + case DW_FORM_data16: + if (write_out) { + memcpy(data,cur->dfe_md5,sizeof(cur->dfe_md5)); + data += 16; + } + calculated_size += 16; + break; + default: + DWARF_P_DBG_ERROR(dbg, + DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR); + } + } + break; + default: + DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_CODE_UNKNOWN, DW_DLV_ERROR); + } + } + } + *size_out = calculated_size; + return DW_DLV_OK; +} + +static int +calculate_size_of_line_header5(Dwarf_P_Debug dbg, + struct Dwarf_P_Line_Inits_s *inits, + unsigned *prolog_size_out, + Dwarf_Error *error) +{ + unsigned prolog_size = 0; + int offset_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + int res = 0; + + prolog_size += OFFSET_PLUS_EXTENSION_SIZE + + sizeof_uhalf(dbg) + /* version # */ + sizeof_ubyte(dbg) + /* address_size */ + sizeof_ubyte(dbg) + /* segment_selector_size */ + offset_size + /* header length */ + sizeof_ubyte(dbg) + /* min_instr length */ + sizeof_ubyte(dbg) + /* maximum_operations_per_instruction */ + sizeof_ubyte(dbg) + /* default is_stmt */ + sizeof_ubyte(dbg) + /* linebase */ + sizeof_ubyte(dbg) + /* linerange */ + sizeof_ubyte(dbg); /* opcode base */ + /* For maximum_operations_per_instruction. */ + prolog_size += sizeof_ubyte(dbg); + + /* standard_opcode_lengths table len */ + prolog_size += inits->pi_opcode_base-1; + + { + unsigned fsize = 0; + res = determine_form_size(dbg, + inits->pi_directory_entry_format_count, + inits->pi_incformats, + &fsize,FALSE,0,error); + if (res != DW_DLV_OK) { + return res; + } + prolog_size += fsize; + } + { + unsigned dir_count_len = 0; + res = determine_file_content_size(dbg, + dbg->de_inc_dirs, + dbg->de_line_inits.pi_directory_entry_format_count, + dbg->de_line_inits.pi_incformats, + &dir_count_len, + FALSE,0, + error); + if (res != DW_DLV_OK) { + return res; + } + prolog_size += dir_count_len; + } + { + unsigned fsize = 0; + res = determine_form_size(dbg, + inits->pi_file_entry_format_count, + inits->pi_fileformats, + &fsize, + FALSE,0, + error); + if (res != DW_DLV_OK) { + return res; + } + prolog_size += fsize; + } + { + unsigned file_count_len = 0; + res = determine_file_content_size(dbg, + dbg->de_file_entries, + dbg->de_line_inits.pi_file_entry_format_count, + dbg->de_line_inits.pi_fileformats, + &file_count_len, + FALSE,0, + error); + if (res != DW_DLV_OK) { + return res; + } + prolog_size += file_count_len; + } + *prolog_size_out = prolog_size; + return DW_DLV_OK; +} + +/* For DWARF 2,3,4 */ +static int +calculate_size_of_line_header4(Dwarf_P_Debug dbg, + struct Dwarf_P_Line_Inits_s *inits, + unsigned *prolog_size_out, + UNUSEDARG Dwarf_Error *error) +{ + Dwarf_P_F_Entry curdir = 0; + Dwarf_P_F_Entry curentry = 0; + unsigned prolog_size = 0; + int offset_size = dbg->de_offset_size; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + + prolog_size += OFFSET_PLUS_EXTENSION_SIZE + + sizeof_uhalf(dbg) + /* version # */ + offset_size + /* header length */ + sizeof_ubyte(dbg) + /* min_instr length */ + sizeof_ubyte(dbg) + /* default is_stmt */ + sizeof_ubyte(dbg) + /* linebase */ + sizeof_ubyte(dbg) + /* linerange */ + sizeof_ubyte(dbg); /* opcode base */ + if (inits->pi_version == DW_LINE_VERSION4) { + /* For maximum_operations_per_instruction. */ + prolog_size += sizeof_ubyte(dbg); + } + /* standard_opcode_lengths table len */ + prolog_size += inits->pi_opcode_base-1; + + /* include directories */ + curdir = dbg->de_inc_dirs; + while (curdir) { + prolog_size += strlen(curdir->dfe_name) + 1; + curdir = curdir->dfe_next; + } + prolog_size++; /* last null following last directory + entry. */ + + /* file entries */ + curentry = dbg->de_file_entries; + while (curentry) { + prolog_size += + strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; + curentry = curentry->dfe_next; + } + prolog_size++; /* last null byte */ + *prolog_size_out = prolog_size; + return DW_DLV_OK; +} + + +/* Generate debug_line section + Dwarf2, dwarf3 headers are the same (DW3 acknowledges 64bit). + DWARF4 adds the maximum_operations_per_instruction field. + DWARF5 adds address size and address selector size + and replaces the entire directories/files list with + very different stuff. +*/ +static int +_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, + Dwarf_Signed * nbufs, + Dwarf_Error * error) +{ + Dwarf_P_F_Entry curdir = 0; + Dwarf_P_F_Entry curentry = 0; + Dwarf_P_Line curline = 0; + Dwarf_P_Line prevline = 0; + struct Dwarf_P_Line_Inits_s *inits = 0; + + /* all data named cur* are used to loop thru linked lists */ + + int sum_bytes = 0; + unsigned prolog_size = 0; + unsigned char *data = 0; /* holds disk form data */ + int elfsectno = 0; + unsigned char *start_line_sec = 0; /* pointer to the buffer at + section start */ + /* temps for memcpy */ + Dwarf_Unsigned du = 0; + Dwarf_Ubyte db = 0; + Dwarf_Half dh = 0; + int res = 0; + Dwarf_Half version = dbg->de_output_version; + int offset_size = dbg->de_offset_size; + Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0; + Dwarf_Ubyte address_size = dbg->de_pointer_size; + + sum_bytes = 0; + + elfsectno = dbg->de_elf_sects[DEBUG_LINE]; + + inits = &dbg->de_line_inits; + if (version < 5) { + res = calculate_size_of_line_header4(dbg,inits,&prolog_size, + error); + } else if (version == 5) { + res = calculate_size_of_line_header5(dbg,inits,&prolog_size, + error); + } else { + _dwarf_p_error(dbg, error,DW_DLE_VERSION_STAMP_ERROR ); + return DW_DLV_ERROR; + } + if (res != DW_DLV_OK) { + return res; + } + /* Allocate a chunk, put address in 'data' */ + GET_CHUNK_ERR(dbg, elfsectno, data, prolog_size, error); - GET_CHUNK(dbg, elfsectno, data, prolog_size, error); start_line_sec = data; - /* copy over the data */ + /* Copy the prologue data into 'data' */ /* total_length */ du = 0; if (extension_size) { - Dwarf_Word x = DISTINGUISHED_VALUE; + DISTINGUISHED_VALUE_ARRAY(v4); - WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x, - sizeof(x), extension_size); + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0], + SIZEOFT32, extension_size); data += extension_size; } + /* We will adjust this later, we do not know the full length + of the line_section content for this cu yet. */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), uwordb_size); - data += uwordb_size; + sizeof(du), offset_size); + data += offset_size; - dh = dbg->de_line_inits.pi_version; + dh = inits->pi_version; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, - sizeof(dh), sizeof(Dwarf_Half)); - data += sizeof(Dwarf_Half); + sizeof(dh), DWARF_HALF_SIZE); + data += DWARF_HALF_SIZE; + if (version == 5 ) { + /* address size, seg sel size now */ + db = inits->pi_address_size; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(db)); + data += sizeof(db); + db = inits->pi_segment_size; /* segment selector size */ + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(db)); + data += sizeof(db); + } - /* header length */ - du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) + - uwordb_size); { + /* header length (called prolog length in DWARF2) + This we do know, we calculated the prolog length + already and it is prolog_size so just + */ + Dwarf_Unsigned sofar = data - start_line_sec; + + du = prolog_size - sofar - offset_size; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), uwordb_size); - data += uwordb_size; + sizeof(du), offset_size); + data += offset_size; } - db = dbg->de_line_inits.pi_minimum_instruction_length; + db = inits->pi_minimum_instruction_length; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); - if (dbg->de_line_inits.pi_version == DW_LINE_VERSION4) { - db = dbg->de_line_inits.pi_maximum_operations_per_instruction; + if (inits->pi_version == 4 || inits->pi_version == 5) { + db = inits->pi_maximum_operations_per_instruction; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); } - db = dbg->de_line_inits.pi_default_is_stmt; + db = inits->pi_default_is_stmt; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); - db = dbg->de_line_inits.pi_line_base; + db = inits->pi_line_base; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); - db = dbg->de_line_inits.pi_line_range; + db = inits->pi_line_range; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); - db = dbg->de_line_inits.pi_opcode_base; + db = inits->pi_opcode_base; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len, - dbg->de_line_inits.pi_opcode_base-1, - dbg->de_line_inits.pi_opcode_base-1); - data += dbg->de_line_inits.pi_opcode_base-1; + inits->pi_opcode_base-1, + inits->pi_opcode_base-1); + data += inits->pi_opcode_base-1; + + if (version < 5) { + /* copy over include directories */ + curdir = dbg->de_inc_dirs; + while (curdir) { + strcpy((char *) data, curdir->dfe_name); + data += strlen(curdir->dfe_name) + 1; + curdir = curdir->dfe_next; + } + *data = '\0'; /* last null */ + data++; - /* copy over include directories */ - curdir = dbg->de_inc_dirs; - while (curdir) { - strcpy((char *) data, curdir->did_name); - data += strlen(curdir->did_name) + 1; - curdir = curdir->did_next; + /* copy file entries */ + curentry = dbg->de_file_entries; + while (curentry) { + strcpy((char *) data, curentry->dfe_name); + data += strlen(curentry->dfe_name) + 1; + /* copies of leb numbers, no endian issues */ + memcpy((void *) data, + (const void *) curentry->dfe_args, curentry->dfe_nbytes); + data += curentry->dfe_nbytes; + curentry = curentry->dfe_next; + } + *data = '\0'; + data++; + } else if (version == 5) { + { + unsigned fsize = 0; + res = determine_form_size(dbg, + inits->pi_directory_entry_format_count, + inits->pi_incformats, + &fsize, + TRUE,data, + error); + if (res != DW_DLV_OK) { + return res; + } + data += fsize; + } + { + unsigned dir_count_len = 0; + res = determine_file_content_size(dbg, + dbg->de_inc_dirs, + inits->pi_directory_entry_format_count, + inits->pi_incformats, + &dir_count_len, + TRUE,data, + error); + if (res != DW_DLV_OK) { + return res; + } + data += dir_count_len; + } + { + unsigned fsize = 0; + res = determine_form_size(dbg, + inits->pi_file_entry_format_count, + inits->pi_fileformats, + &fsize, + TRUE,data, + error); + if (res != DW_DLV_OK) { + return res; + } + data += fsize; + } + { + unsigned file_count_len = 0; + res = determine_file_content_size(dbg, + dbg->de_file_entries, + dbg->de_line_inits.pi_file_entry_format_count, + dbg->de_line_inits.pi_fileformats, + &file_count_len, + TRUE,data, + error); + if (res != DW_DLV_OK) { + return res; + } + data += file_count_len; + } } - *data = '\0'; /* last null */ - data++; - /* copy file entries */ - curentry = dbg->de_file_entries; - while (curentry) { - strcpy((char *) data, curentry->dfe_name); - data += strlen(curentry->dfe_name) + 1; - /* copies of leb numbers, no endian issues */ - memcpy((void *) data, - (const void *) curentry->dfe_args, curentry->dfe_nbytes); - data += curentry->dfe_nbytes; - curentry = curentry->dfe_next; + { + Dwarf_Unsigned sofar = data - start_line_sec; + if (sofar != prolog_size) { + /* We miscalculated something. */ + _dwarf_p_error(dbg, error, + DW_DLE_LINE_HEADER_LENGTH_BOTCH); + return DW_DLV_ERROR; + } + sum_bytes += prolog_size; } - *data = '\0'; - data++; - - sum_bytes += prolog_size; curline = dbg->de_lines; prevline = (Dwarf_P_Line) _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); if (prevline == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR); } _dwarf_pro_reg_init(dbg,prevline); /* generate opcodes for line numbers */ @@ -724,27 +1564,42 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) /* Advance pc to end of text section. */ addr_adv = curline->dpl_address - prevline->dpl_address; if (addr_adv > 0) { - writelen = write_opcode_uval(DW_LNS_advance_pc,dbg, + res = write_opcode_uval(DW_LNS_advance_pc,dbg, elfsectno, - addr_adv/ - dbg->de_line_inits.pi_minimum_instruction_length, + addr_adv/inits->pi_minimum_instruction_length, + &writelen, error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_address = curline->dpl_address; } /* first null byte */ db = 0; - writelen = write_ubyte(db,dbg,elfsectno,error); + res = write_ubyte(db,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* write length of extended opcode */ inst_bytes = sizeof(Dwarf_Ubyte); - writelen = write_uval(inst_bytes,dbg,elfsectno,error); + res = write_uval(inst_bytes,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* write extended opcode */ - writelen = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno,error); + res = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* reset value to original values */ @@ -758,32 +1613,48 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) /* first null byte */ db = 0; - writelen = write_ubyte(db,dbg,elfsectno,error); + res = write_ubyte(db,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* write length of extended opcode */ - inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size; - writelen = write_uval(inst_bytes,dbg,elfsectno,error); + inst_bytes = sizeof(Dwarf_Ubyte) + address_size; + res = write_uval(inst_bytes,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* write extended opcode */ - writelen = write_ubyte(DW_LNE_set_address,dbg,elfsectno,error); + res = write_ubyte(DW_LNE_set_address,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* reloc for address */ - res = dbg->de_reloc_name(dbg, DEBUG_LINE, + res = dbg->de_relocate_by_name_symbol(dbg, + DEBUG_LINE, sum_bytes, /* r_offset */ curline->dpl_r_symidx, dwarf_drt_data_reloc, - uwordb_size); + offset_size); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, DW_DLV_ERROR); } /* write offset (address) */ du = curline->dpl_address; - writelen = write_fixed_size(du,dbg,elfsectno, - upointer_size,error); + res = write_fixed_size(du,dbg,elfsectno, + address_size,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_address = curline->dpl_address; no_lns_copy = 1; @@ -798,23 +1669,42 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) unsigned val_len = 0; /* first null byte */ db = 0; - writelen = write_ubyte(db,dbg,elfsectno,error); + res = write_ubyte(db,dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* Write len of opcode + value here. */ - val_len = pretend_write_uval(curline->dpl_discriminator, - dbg, elfsectno,error) + 1; - writelen = write_uval(val_len +1,dbg,elfsectno,error); + res = pretend_write_uval(curline->dpl_discriminator, + dbg, &val_len,error); + if (res != DW_DLV_OK) { + return res; + } + val_len++; + + res = write_uval(val_len +1,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* Write opcode */ - writelen = write_ubyte(DW_LNE_set_discriminator, - dbg,elfsectno,error); + res = write_ubyte(DW_LNE_set_discriminator, + dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* Write the value itself. */ - writelen = write_uval(curline->dpl_discriminator, - dbg,elfsectno,error); + res = write_uval(curline->dpl_discriminator, + dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; no_lns_copy = 1; } @@ -822,7 +1712,7 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) } } else { unsigned writelen = 0; - if (dbg->de_line_inits.pi_opcode_base >12) { + if (inits->pi_opcode_base >12) { /* We have the newer standard opcodes DW_LNS_set_prologue_end, DW_LNS_set_epilogue_end, DW_LNS_set_isa, we do not write them if not @@ -831,48 +1721,69 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) in the line processing/reading engine, so I think no check of prevline is wanted. */ if (curline->dpl_epilogue_begin) { - writelen = write_ubyte(DW_LNS_set_epilogue_begin,dbg, - elfsectno, error); + res = write_ubyte(DW_LNS_set_epilogue_begin,dbg, + elfsectno,&writelen, error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; } if (curline->dpl_prologue_end) { - writelen = write_ubyte(DW_LNS_set_prologue_end,dbg, - elfsectno, error); + res = write_ubyte(DW_LNS_set_prologue_end,dbg, + elfsectno, &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; } if (curline->dpl_isa != prevline->dpl_isa) { - writelen = write_opcode_uval(DW_LNS_set_isa,dbg, - elfsectno, - curline->dpl_isa ,error); + res = write_opcode_uval(DW_LNS_set_isa,dbg, + elfsectno, curline->dpl_isa, + &writelen ,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; } } if (curline->dpl_file != prevline->dpl_file) { db = DW_LNS_set_file; - writelen = write_opcode_uval(db,dbg, + res = write_opcode_uval(db,dbg, elfsectno, - curline->dpl_file ,error); + curline->dpl_file,&writelen ,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_file = curline->dpl_file; } if (curline->dpl_column != prevline->dpl_column) { db = DW_LNS_set_column; - writelen = write_opcode_uval(db,dbg, - elfsectno, - curline->dpl_column ,error); + res = write_opcode_uval(db,dbg, + elfsectno, curline->dpl_column , &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_column = curline->dpl_column; } if (curline->dpl_is_stmt != prevline->dpl_is_stmt) { - writelen = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno,error); + res = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_is_stmt = curline->dpl_is_stmt; } if (curline->dpl_basic_block == true && prevline->dpl_basic_block == false) { - writelen = write_ubyte(DW_LNS_set_basic_block,dbg, - elfsectno,error); + res = write_ubyte(DW_LNS_set_basic_block,dbg, + elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_basic_block = curline->dpl_basic_block; } @@ -884,23 +1795,40 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) unsigned val_len = 0; /* first null byte */ db = 0; - writelen = write_ubyte(db,dbg,elfsectno,error); + res = write_ubyte(db,dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* Write len of opcode + value here. */ - val_len = pretend_write_uval(curline->dpl_discriminator, - dbg, elfsectno,error) + 1; - writelen = write_uval(val_len +1,dbg,elfsectno,error); + res = pretend_write_uval(curline->dpl_discriminator, + dbg, &val_len,error); + if (res != DW_DLV_OK) { + return res; + } + val_len ++; + res = write_uval(val_len +1,dbg,elfsectno, + &writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* Write opcode */ - writelen = write_ubyte(DW_LNE_set_discriminator, - dbg,elfsectno,error); + res = write_ubyte(DW_LNE_set_discriminator, + dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; /* Write the value itself. */ - writelen = write_uval(curline->dpl_discriminator, - dbg,elfsectno,error); + res = write_uval(curline->dpl_discriminator, + dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; } @@ -908,13 +1836,16 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) line_adv = (int) (curline->dpl_line - prevline->dpl_line); if ((addr_adv % MIN_INST_LENGTH) != 0) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, DW_DLV_ERROR); } - opc = _dwarf_pro_get_opc(dbg,addr_adv, line_adv); + opc = _dwarf_pro_get_opc(inits,addr_adv, line_adv); if (opc > 0) { /* Use special opcode. */ no_lns_copy = 1; - writelen = write_ubyte(opc,dbg,elfsectno,error); + res = write_ubyte(opc,dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_address = curline->dpl_address; @@ -923,24 +1854,35 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) /* opc says use standard opcodes. */ if (addr_adv > 0) { db = DW_LNS_advance_pc; - writelen = write_opcode_uval(db,dbg, + res = write_opcode_uval(db,dbg, elfsectno, - addr_adv/ - dbg->de_line_inits.pi_minimum_instruction_length, + addr_adv/inits->pi_minimum_instruction_length, + &writelen, error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_address = curline->dpl_address; } if (line_adv != 0) { db = DW_LNS_advance_line; - writelen = write_ubyte(db,dbg, + res = write_ubyte(db,dbg, elfsectno, + &writelen, error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; - writelen = write_sval(line_adv,dbg, + res = write_sval(line_adv,dbg, elfsectno, + &writelen, error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_basic_block = false; prevline->dpl_line = curline->dpl_line; @@ -950,7 +1892,10 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq generate a matrix line */ unsigned writelen = 0; - writelen = write_ubyte(DW_LNS_copy,dbg,elfsectno,error); + res = write_ubyte(DW_LNS_copy,dbg,elfsectno,&writelen,error); + if (res != DW_DLV_OK) { + return res; + } sum_bytes += writelen; prevline->dpl_basic_block = false; } @@ -958,20 +1903,23 @@ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) } /* write total length field */ - du = sum_bytes - BEGIN_LEN_SIZE; + du = sum_bytes - OFFSET_PLUS_EXTENSION_SIZE; { start_line_sec += extension_size; WRITE_UNALIGNED(dbg, (void *) start_line_sec, - (const void *) &du, sizeof(du), uwordb_size); + (const void *) &du, sizeof(du), offset_size); } - return (int) dbg->de_n_debug_sect; + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; } /* Generate debug_frame section */ static int -_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) +_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, + Dwarf_Error * error) { int elfsectno = 0; int i = 0; @@ -979,15 +1927,14 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) Dwarf_P_Cie curcie = 0; Dwarf_P_Fde curfde = 0; unsigned char *data = 0; - Dwarf_sfixed dsw = 0; Dwarf_Unsigned du = 0; Dwarf_Ubyte db = 0; long *cie_offs = 0; /* Holds byte offsets for links to fde's */ unsigned long cie_length = 0; int cie_no = 0; - int uwordb_size = dbg->de_offset_size; - int extension_size = dbg->de_64bit_extension ? 4 : 0; - int upointer_size = dbg->de_pointer_size; + Dwarf_Ubyte offset_size = dbg->de_offset_size; + Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0; + Dwarf_Ubyte address_size = dbg->de_pointer_size; Dwarf_Unsigned cur_off = 0; /* current offset of written data, held for relocation info */ @@ -995,11 +1942,10 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) curcie = dbg->de_frame_cies; cie_length = 0; - cur_off = 0; cie_offs = (long *) _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie); if (cie_offs == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } /* Generate cie number as we go along. This writes all CIEs first before any FDEs, which is rather @@ -1009,9 +1955,9 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) cie_no = 1; while (curcie) { char *code_al = 0; - int c_bytes = 0; + int codeal_bytes = 0; char *data_al = 0; - int d_bytes = 0; + int data_align_bytes = 0; int pad = 0; /* Pad for padding to align cies and fdes */ int res = 0; char buff1[ENCODE_SPACE_NEEDED]; @@ -1020,13 +1966,14 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) char *augmentation = 0; char *augmented_al = 0; long augmented_fields_length = 0; - int a_bytes = 0; + int irix_auglen_v0 = 0; + Dwarf_Half version = curcie->cie_version; res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align, - &c_bytes, + &codeal_bytes, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } /* Before April 1999, the following was using an unsigned encode. That worked ok even though the decoder used the @@ -1043,10 +1990,10 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) below is corrected signed version. */ res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align, - &d_bytes, + &data_align_bytes, buff2, sizeof(buff2)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR); } code_al = buff1; data_al = buff2; @@ -1057,83 +2004,112 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) firsttime = 0; } else { cie_offs[cie_no - 1] = cie_offs[cie_no - 2] + - (long) cie_length + BEGIN_LEN_SIZE; + (long) cie_length + OFFSET_PLUS_EXTENSION_SIZE; } cie_no++; augmentation = curcie->cie_aug; + cie_length = offset_size + /* cie_id */ + sizeof(Dwarf_Ubyte) + /* cie version */ + strlen(curcie->cie_aug) + 1 + /* augmentation */ + codeal_bytes + /* code alignment factor */ + data_align_bytes + /* data alignment factor */ + sizeof(Dwarf_Ubyte) + /* return reg address */ + curcie->cie_inst_bytes; if (dbg->de_irix_exc_augmentation && (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0)) { + /* IRIX specific. */ augmented_fields_length = 0; res = _dwarf_pro_encode_leb128_nm(augmented_fields_length, - &a_bytes, buff3, + &irix_auglen_v0, buff3, sizeof(buff3)); augmented_al = buff3; if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, + DW_DLV_ERROR); } - cie_length = uwordb_size + /* cie_id */ - sizeof(Dwarf_Ubyte) + /* cie version */ - strlen(curcie->cie_aug) + 1 + /* augmentation */ - c_bytes + /* code alignment factor */ - d_bytes + /* data alignment factor */ - sizeof(Dwarf_Ubyte) + /* return reg address */ - a_bytes + /* augmentation length */ - curcie->cie_inst_bytes; - } else { - cie_length = uwordb_size + /* cie_id */ - sizeof(Dwarf_Ubyte) + /* cie version */ - strlen(curcie->cie_aug) + 1 + /* augmentation */ - c_bytes + d_bytes + sizeof(Dwarf_Ubyte) + - /* return reg address */ curcie->cie_inst_bytes; + cie_length += irix_auglen_v0 ; /* augmentation length */ } - pad = (int) PADDING(cie_length, upointer_size); + if (version >= 4) { + /* address size, segment selector size */ + cie_length += 1 +1; + } + + pad = (int) PADDING(cie_length, address_size); cie_length += pad; - GET_CHUNK(dbg, elfsectno, data, cie_length + - BEGIN_LEN_SIZE, error); + + /* Now we have the cie length with padding, + allocate a buffer for that plus the header + length. */ + GET_CHUNK_ERR(dbg, elfsectno, data, cie_length + + OFFSET_PLUS_EXTENSION_SIZE, + error); if (extension_size) { - Dwarf_Unsigned x = DISTINGUISHED_VALUE; + DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, - (const void *) &x, - sizeof(x), extension_size); + (const void *) &v4[0], + SIZEOFT32, extension_size); data += extension_size; } du = cie_length; /* total length of cie */ WRITE_UNALIGNED(dbg, (void *) data, - (const void *) &du, sizeof(du), uwordb_size); - data += uwordb_size; + (const void *) &du, sizeof(du), offset_size); + data += offset_size; /* cie-id is a special value. */ du = DW_CIE_ID; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), uwordb_size); - data += uwordb_size; + sizeof(du), offset_size); + data += offset_size; db = curcie->cie_version; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); + strcpy((char *) data, curcie->cie_aug); data += strlen(curcie->cie_aug) + 1; - memcpy((void *) data, (const void *) code_al, c_bytes); - data += c_bytes; - memcpy((void *) data, (const void *) data_al, d_bytes); - data += d_bytes; + + if (curcie->cie_version >= 4) { + /* emit address-size, segment selector size */ + db = dbg->de_pointer_size; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + + db = dbg->de_segment_selector_size; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, + sizeof(db), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + } + + + memcpy((void *) data, (const void *) code_al, codeal_bytes); + data += codeal_bytes; + + memcpy((void *) data, (const void *) data_al, data_align_bytes); + data += data_align_bytes; + db = curcie->cie_ret_reg; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, sizeof(db), sizeof(Dwarf_Ubyte)); data += sizeof(Dwarf_Ubyte); - if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { - memcpy((void *) data, (const void *) augmented_al, a_bytes); - data += a_bytes; + if (dbg->de_irix_exc_augmentation && + strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { + + /* IRIX only */ + memcpy((void *) data, (const void *) augmented_al, + irix_auglen_v0); + data += irix_auglen_v0; } memcpy((void *) data, (const void *) curcie->cie_inst, curcie->cie_inst_bytes); data += curcie->cie_inst_bytes; + for (i = 0; i < pad; i++) { *data = DW_CFA_nop; data++; @@ -1141,7 +2117,8 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) curcie = curcie->cie_next; } /* calculate current offset */ - cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE; + cur_off = cie_offs[cie_no - 2] + cie_length + + OFFSET_PLUS_EXTENSION_SIZE; /* write out fde's */ curfde = dbg->de_frame_fdes; @@ -1150,9 +2127,9 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) long fde_length = 0; int pad2 = 0; Dwarf_P_Cie cie_ptr = 0; - Dwarf_Word cie_index = 0; + Dwarf_Unsigned cie_index = 0; /* index is a global in string.h, so don't name anything index. */ - Dwarf_Word indx = 0; + Dwarf_Unsigned indx = 0; int oet_length = 0; int afl_length = 0; int res = 0; @@ -1168,60 +2145,65 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) indx++; } if (cie_ptr == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, DW_DLV_ERROR); } - if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { + fde_length = curfde->fde_n_bytes + + OFFSET_PLUS_EXTENSION_SIZE + + /* cie pointer */ + address_size + /* initial loc */ + address_size; /* address range */ + if (dbg->de_irix_exc_augmentation && + strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { + v0_augmentation = 1; - oet_length = sizeof(Dwarf_sfixed); + oet_length = DWARF_32BIT_SIZE; /* encode the length of augmented fields. */ res = _dwarf_pro_encode_leb128_nm(oet_length, &afl_length, afl_buff, sizeof(afl_buff)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, + DW_DLV_ERROR); } - fde_length = curfde->fde_n_bytes + - BEGIN_LEN_SIZE + /* cie pointer */ - upointer_size + /* initial loc */ - upointer_size + /* address range */ + fde_length += afl_length + /* augmented field length */ oet_length; /* exception_table offset */ - } else { - fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie - pointer */ - upointer_size + /* initial loc */ - upointer_size; /* address range */ } if (curfde->fde_die) { /* IRIX/MIPS extension: - Using fde offset, generate DW_AT_MIPS_fde attribute for the + Using fde offset, generate DW_AT_MIPS_fde + attribute for the die corresponding to this fde. */ - if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, - error) < 0) { - return -1; + res = _dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, + error); + if (res != DW_DLV_OK) { + return res; } } /* store relocation for cie pointer */ - res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + - BEGIN_LEN_SIZE /* r_offset */, + + res = dbg->de_relocate_by_name_symbol(dbg, + DEBUG_FRAME, cur_off + + OFFSET_PLUS_EXTENSION_SIZE /* r_offset */, dbg->de_sect_name_idx[DEBUG_FRAME], - dwarf_drt_data_reloc, uwordb_size); + dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res ); } /* store relocation information for initial location */ - res = dbg->de_reloc_name(dbg, DEBUG_FRAME, - cur_off + BEGIN_LEN_SIZE + - upointer_size /* r_offset */, + res = dbg->de_relocate_by_name_symbol(dbg, + DEBUG_FRAME, + cur_off + OFFSET_PLUS_EXTENSION_SIZE + + address_size /* r_offset */, curfde->fde_r_symidx, - dwarf_drt_data_reloc, upointer_size); + dwarf_drt_data_reloc, address_size); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res); } /* Store the relocation information for the offset_into_exception_info field, if the offset is valid (0 @@ -1229,57 +2211,59 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) if (v0_augmentation && curfde->fde_offset_into_exception_tables >= 0) { - res = dbg->de_reloc_name(dbg, DEBUG_FRAME, + res = dbg->de_relocate_by_name_symbol(dbg, + DEBUG_FRAME, /* r_offset, where in cie this field starts */ - cur_off + BEGIN_LEN_SIZE + - uwordb_size + 2 * upointer_size + + cur_off + OFFSET_PLUS_EXTENSION_SIZE + + offset_size + 2 * address_size + afl_length, curfde->fde_exception_table_symbol, dwarf_drt_segment_rel, - sizeof(Dwarf_sfixed)); + DWARF_32BIT_SIZE); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res); } } /* adjust for padding */ - pad2 = (int) PADDING(fde_length, upointer_size); + pad2 = (int) PADDING(fde_length, address_size); fde_length += pad2; /* write out fde */ - GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE, + GET_CHUNK(dbg, elfsectno, data, fde_length + + OFFSET_PLUS_EXTENSION_SIZE, error); du = fde_length; { if (extension_size) { - Dwarf_Word x = DISTINGUISHED_VALUE; + DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, (void *) data, - (const void *) &x, - sizeof(x), extension_size); + (const void *) &v4[0], + SIZEOFT32, extension_size); data += extension_size; } /* length */ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), uwordb_size); - data += uwordb_size; + sizeof(du), offset_size); + data += offset_size; /* offset to cie */ du = cie_offs[curfde->fde_cie - 1]; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), uwordb_size); - data += uwordb_size; + sizeof(du), offset_size); + data += offset_size; du = curfde->fde_initloc; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), upointer_size); - data += upointer_size; + sizeof(du), address_size); + data += address_size; - if (dbg->de_reloc_pair && + if (dbg->de_relocate_pair_by_symbol && curfde->fde_end_symbol != 0 && curfde->fde_addr_range == 0) { /* symbolic reloc, need reloc for length What if we @@ -1287,17 +2271,17 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) part of 'if'. */ Dwarf_Unsigned val; - res = dbg->de_reloc_pair(dbg, - /* DEBUG_ARANGES, */ DEBUG_FRAME, - cur_off + 2 * uwordb_size + upointer_size, + res = dbg->de_relocate_pair_by_symbol(dbg, + DEBUG_FRAME, + cur_off + 2 * offset_size + address_size, /* r_offset */ curfde->fde_r_symidx, curfde->fde_end_symbol, dwarf_drt_first_of_length_pair, - upointer_size); + address_size); if (res != DW_DLV_OK) { { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } } @@ -1307,28 +2291,31 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) curfde->fde_initloc; WRITE_UNALIGNED(dbg, data, (const void *) &val, - sizeof(val), upointer_size); - data += upointer_size; + sizeof(val), address_size); + data += address_size; } else { du = curfde->fde_addr_range; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), upointer_size); - data += upointer_size; + sizeof(du), address_size); + data += address_size; } } if (v0_augmentation) { + /* IRIX only. */ /* write the encoded augmented field length. */ + Dwarf_Signed dsw = 0; + memcpy((void *) data, (const void *) afl_buff, afl_length); data += afl_length; /* write the offset_into_exception_tables field. */ - dsw = - (Dwarf_sfixed) curfde->fde_offset_into_exception_tables; - WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw, - sizeof(dsw), sizeof(Dwarf_sfixed)); - data += sizeof(Dwarf_sfixed); + dsw = (Dwarf_Signed)curfde->fde_offset_into_exception_tables; + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &dsw, + sizeof(dsw), DWARF_32BIT_SIZE); + data += DWARF_32BIT_SIZE; } curinst = curfde->fde_inst; @@ -1354,12 +2341,13 @@ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) *data = DW_CFA_nop; data++; } - cur_off += fde_length + uwordb_size; + cur_off += fde_length + offset_size; curfde = curfde->fde_next; } - return (int) dbg->de_n_debug_sect; + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; } /* @@ -1379,10 +2367,10 @@ marker_init(Dwarf_P_Debug dbg, sizeof(struct Dwarf_P_Marker_s) * dbg->de_marker_n_alloc); if (dbg->de_markers == NULL) { dbg->de_marker_n_alloc = 0; - return -1; + return DW_DLV_ERROR; } } - return 0; + return DW_DLV_OK; } static int @@ -1394,10 +2382,9 @@ marker_add(Dwarf_P_Debug dbg, unsigned n = dbg->de_marker_n_used++; dbg->de_markers[n].ma_offset = offset; dbg->de_markers[n].ma_marker = marker; - return 0; + return DW_DLV_OK; } - - return -1; + return DW_DLV_ERROR; } Dwarf_Signed @@ -1406,12 +2393,28 @@ dwarf_get_die_markers(Dwarf_P_Debug dbg, Dwarf_Unsigned * marker_count, Dwarf_Error * error) { - if (marker_list == NULL || marker_count == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR); - } - if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR); - } + int res = 0; + + res = dwarf_get_die_markers_a(dbg,marker_list,marker_count, + error); + if (res == DW_DLV_ERROR) { + return DW_DLV_BADADDR; + } + return 0; +} + +int +dwarf_get_die_markers_a(Dwarf_P_Debug dbg, + Dwarf_P_Marker * marker_list, /* pointer to a pointer */ + Dwarf_Unsigned * marker_count, + Dwarf_Error * error) +{ + if (marker_list == NULL || marker_count == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); + } + if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR); + } *marker_list = dbg->de_markers; *marker_count = dbg->de_marker_n_used; @@ -1439,10 +2442,10 @@ string_attr_init (Dwarf_P_Debug dbg, sizeof(struct Dwarf_P_String_Attr_s) * sect_sa->sect_sa_n_alloc); if (sect_sa->sect_sa_list == NULL) { sect_sa->sect_sa_n_alloc = 0; - return -1; + return DW_DLV_ERROR; } } - return 0; + return DW_DLV_OK; } static int @@ -1456,10 +2459,10 @@ string_attr_add (Dwarf_P_Debug dbg, unsigned n = sect_sa->sect_sa_n_used++; sect_sa->sect_sa_list[n].sa_offset = offset; sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes; - return 0; + return DW_DLV_OK; } - return -1; + return DW_DLV_ERROR; } int @@ -1513,111 +2516,631 @@ has_sibling_die_already(Dwarf_P_Die d) Dwarf_P_Attribute a = 0; for(a = d->di_attrs; a ; a = a->ar_next) { if(a->ar_attribute == DW_AT_sibling) { - return 1; + return TRUE; } } + return FALSE; +} + +/* For DW_FORM_strp we need to set the symindex so we need + to check that such applies. */ +static int +if_relocatable_string_form(Dwarf_P_Debug dbg, Dwarf_P_Attribute curattr, + int *debug_str_reloc, + Dwarf_Error *error) +{ + if (curattr->ar_rel_type == R_MIPS_NONE) { + *debug_str_reloc = 0; + return DW_DLV_OK; + } + if (curattr->ar_attribute_form != DW_FORM_strp) { + _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL); + return DW_DLV_ERROR; + } + if (curattr->ar_rel_type != dbg->de_offset_reloc) { + _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL); + return DW_DLV_ERROR; + } + *debug_str_reloc = 1; + return DW_DLV_OK; +} + +/* Tries to see if given attribute and form combination + of the attr exists in the given abbreviation. + abbrevs and attrs are sorted in attrnum order. */ +static int +_dwarf_pro_match_attr(Dwarf_P_Attribute attr, + Dwarf_P_Abbrev abbrev, int no_attr) +{ + int i = 0; + Dwarf_P_Attribute curatp = attr; + + for (i = 0; i < no_attr && curatp; i++,curatp = curatp->ar_next ) { + if (curatp->ar_attribute != abbrev->abb_attrs[i] || + curatp->ar_attribute_form != abbrev->abb_forms[i]) { + return 0; + } + /* If either is implicit_const need special + check for matching val. */ + if (curatp->ar_attribute_form == DW_FORM_implicit_const) { + if (abbrev->abb_forms[i] == DW_FORM_implicit_const) { + if (curatp->ar_implicit_const != + abbrev->abb_implicits[i]) { + return 0; + } + } else { + return 0; + } + } else { + if (abbrev->abb_forms[i] == DW_FORM_implicit_const) { + return 0; + } + } + } + return 1; +} + +static int +verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s *sortab, + int attrcount) +{ + int k = 0; + unsigned preva = 0; + struct Dwarf_Sort_Abbrev_s *ab = sortab; + + if (attrcount < 2) { + return DW_DLV_OK; + } + for(k = 0; k < attrcount; ++k,++ab) { + if (k) { + if (preva >= ab->dsa_attr) { + return DW_DLV_ERROR; + } + } + preva = ab->dsa_attr; + } + return DW_DLV_OK; +} + +static int +abcompare(const void *l_in, const void *r_in) +{ + struct Dwarf_Sort_Abbrev_s *l = + (struct Dwarf_Sort_Abbrev_s *)l_in; + struct Dwarf_Sort_Abbrev_s *r = + (struct Dwarf_Sort_Abbrev_s *)r_in; + if (l->dsa_attr < r->dsa_attr) { + return -1; + } + if (l->dsa_attr > r->dsa_attr) { + return +1; + } + /* ASSERT: This never happens in correct dwarf. */ return 0; } +/* Handles abbreviations. It takes a die, searches through + current list of abbreviations for a matching one. If it + finds one, it returns a pointer to the abbrev through + the ab_out pointer, and if it does not, + it returns a new abbrev through the ab_out pointer. + + The die->die_attrs are sorted by attribute and the curabbrev + attrs are too. + + It is up to the user of this function to + link it up to the abbreviation head. If it is a new abbrev + abb_idx has 0. */ +static int +_dwarf_pro_getabbrev(Dwarf_P_Debug dbg, + Dwarf_P_Die die, Dwarf_P_Abbrev head, + Dwarf_P_Abbrev*ab_out,Dwarf_Error *error) +{ + Dwarf_P_Abbrev curabbrev = 0; + Dwarf_P_Attribute curattr = 0; + int match = 0; + Dwarf_Unsigned *forms = 0; + Dwarf_Unsigned *attrs = 0; + Dwarf_Signed *implicits = 0; + int attrcount = die->di_n_attr; + + curabbrev = head; + /* Loop thru the currently known abbreviations needed + to see if we can share an existing abbrev. */ + while (curabbrev) { + if ((die->di_tag == curabbrev->abb_tag) && + ((die->di_child != NULL && + curabbrev->abb_children == DW_CHILDREN_yes) || + (die->di_child == NULL && + curabbrev->abb_children == DW_CHILDREN_no)) && + (attrcount == curabbrev->abb_n_attr)) { + + /* There is a chance of a match, basic + characterists match. Now Check the attrs and + forms. */ + curattr = die->di_attrs; + match = _dwarf_pro_match_attr(curattr, + curabbrev, + (int) curabbrev->abb_n_attr); + if (match == 1) { + /* This tag/children/abbrev-list matches + the incoming die needs exactly. Reuse + this abbreviation. */ + *ab_out = curabbrev; + return DW_DLV_OK; + } + } + curabbrev = curabbrev->abb_next; + } + /* no match, create new abbreviation */ + if (attrcount) { + forms = (Dwarf_Unsigned *) + _dwarf_p_get_alloc(die->di_dbg, + sizeof(Dwarf_Unsigned) * attrcount); + if (forms == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); + } + attrs = (Dwarf_Unsigned *) + _dwarf_p_get_alloc(die->di_dbg, + sizeof(Dwarf_Unsigned) * attrcount); + if (attrs == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); + } + implicits = (Dwarf_Signed *) + _dwarf_p_get_alloc(die->di_dbg, + sizeof(Dwarf_Signed) * attrcount); + if (implicits == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); + } + } + curattr = die->di_attrs; + if (forms && attrs && attrcount) { + struct Dwarf_Sort_Abbrev_s *sortab = 0; + struct Dwarf_Sort_Abbrev_s *ap = 0; + int k = 0; + int res = 0; + + sortab = (struct Dwarf_Sort_Abbrev_s *) + malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount); + if(!sortab) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); + } + /* ASSERT curattr->ar_next chain length == attrcount */ + ap = sortab; + for(; curattr; ++ap, curattr = curattr->ar_next) { + ap->dsa_attr = curattr->ar_attribute; + ap->dsa_form = curattr->ar_attribute_form; + ap->dsa_implicitvalue = curattr->ar_implicit_const; + ap->dsa_attrp = 0; + } + + qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s), + abcompare); + ap = sortab; + k = 0; + res = verify_ab_no_dups(sortab,attrcount); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg,DW_DLE_DUP_ATTR_ON_DIE,DW_DLV_ERROR); + } + for( ; k < attrcount; ++k,++ap) { + attrs[k] = ap->dsa_attr; + forms[k] = ap->dsa_form; + implicits[k] = ap->dsa_implicitvalue; + } + free(sortab); + } + + curabbrev = (Dwarf_P_Abbrev) + _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s)); + if (curabbrev == NULL) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); + } + + if (die->di_child == NULL) { + curabbrev->abb_children = DW_CHILDREN_no; + } else { + curabbrev->abb_children = DW_CHILDREN_yes; + } + curabbrev->abb_tag = die->di_tag; + curabbrev->abb_attrs = attrs; + curabbrev->abb_forms = forms; + curabbrev->abb_implicits = implicits; + curabbrev->abb_n_attr = attrcount; + curabbrev->abb_idx = 0; + curabbrev->abb_next = NULL; + *ab_out = curabbrev; + return DW_DLV_OK; +} + /* Generate debug_info and debug_abbrev sections */ + +/* DWARF 2,3,4 */ static int -_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) +generate_debuginfo_header_2(Dwarf_P_Debug dbg, + unsigned *abbrev_offset_io, + unsigned char **data_io, + int *cu_header_size_out, + Dwarf_Small **abbr_off_ptr_out, + Dwarf_Half version, + int extension_size, + Dwarf_Ubyte address_size, + Dwarf_Error * error) { - int elfsectno_of_debug_info = 0; - int abbrevsectno = 0; - unsigned char *data = 0; + unsigned abbrev_offset = 0; + unsigned char * data = 0; + int offset_size = dbg->de_offset_size; + int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; int cu_header_size = 0; - Dwarf_P_Abbrev curabbrev = 0; - Dwarf_P_Abbrev abbrev_head = 0; - Dwarf_P_Abbrev abbrev_tail = 0; - Dwarf_P_Die curdie = 0; - Dwarf_P_Die first_child = 0; - Dwarf_Word dw = 0; Dwarf_Unsigned du = 0; - Dwarf_Half dh = 0; - Dwarf_Ubyte db = 0; - Dwarf_Half version = 0; /* Need 2 byte quantity. */ - Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */ - int n_abbrevs = 0; - int res = 0; - unsigned marker_count = 0; - unsigned string_attr_count = 0; - unsigned string_attr_offset = 0; + Dwarf_Small *abbr_off_ptr = 0; - Dwarf_Small *start_info_sec = 0; + /* write cu header. abbrev_offset used to + generate relocation record below */ + abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE + + DWARF_HALF_SIZE ; - int uwordb_size = dbg->de_offset_size; - int extension_size = dbg->de_64bit_extension ? 4 : 0; + cu_header_size = abbrev_offset + + offset_size + sizeof(Dwarf_Ubyte); - abbrev_head = abbrev_tail = NULL; - elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; - - /* write cu header */ - cu_header_size = BEGIN_LEN_SIZE + - sizeof(Dwarf_Half) + /* version stamp */ - uwordb_size + /* offset into abbrev table */ - sizeof(Dwarf_Ubyte); /* size of target address */ - GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size, + GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size, error); - start_info_sec = data; if (extension_size) { - du = DISTINGUISHED_VALUE; + /* This for a dwarf-standard 64bit offset. */ + DISTINGUISHED_VALUE_ARRAY(v4); + WRITE_UNALIGNED(dbg, (void *) data, - (const void *) &du, sizeof(du), extension_size); + (const void *) &v4[0], SIZEOFT32, extension_size); data += extension_size; } + abbr_off_ptr = data; du = 0; /* length of debug_info, not counting this field itself (unknown at this point). */ WRITE_UNALIGNED(dbg, (void *) data, - (const void *) &du, sizeof(du), uwordb_size); - data += uwordb_size; + (const void *) &du, sizeof(du), offset_size); + data += offset_size; - version = CURRENT_VERSION_STAMP; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, - sizeof(version), sizeof(Dwarf_Half)); - data += sizeof(Dwarf_Half); + sizeof(version), DWARF_HALF_SIZE); + data += DWARF_HALF_SIZE; du = 0;/* offset into abbrev table, not yet known. */ WRITE_UNALIGNED(dbg, (void *) data, - (const void *) &du, sizeof(du), uwordb_size); - data += uwordb_size; + (const void *) &du, sizeof(du), offset_size); + data += offset_size; + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size, + sizeof(address_size), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); - db = dbg->de_pointer_size; + /* We have filled the chunk we got with GET_CHUNK. + At this point we + no longer dare use "data" as a + pointer any longer except to refer to that first + small chunk for the cu header to update + the section length. */ + *abbrev_offset_io = abbrev_offset; + *data_io = data; + *cu_header_size_out = cu_header_size; + *abbr_off_ptr_out = abbr_off_ptr; + return DW_DLV_OK; +} - WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, - sizeof(db), 1); +/* DWARF 5 */ +static int +generate_debuginfo_header_5(Dwarf_P_Debug dbg, + unsigned *abbrev_offset_io, + unsigned char **data_io, + int *cu_header_size_out, + Dwarf_Small **abbr_off_ptr_out, + Dwarf_Half version, + Dwarf_Ubyte unit_type, + int extension_size, + Dwarf_Ubyte address_size, + Dwarf_Error *error) +{ + int offset_size = dbg->de_offset_size; + unsigned abbrev_offset = 0; + unsigned char * data = 0; + int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; + int cu_header_size = 0; + Dwarf_Unsigned du = 0; + Dwarf_Small *abbr_off_ptr = 0; + + + /* write cu header. abbrev_offset used to + generate relocation record below */ + abbrev_offset = OFFSET_PLUS_EXTENSION_SIZE + + DWARF_HALF_SIZE + /* version stamp */ + sizeof(unit_type) + + sizeof(Dwarf_Ubyte); + cu_header_size = abbrev_offset + offset_size; + + GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size, + error); + if (extension_size) { + /* Impossible in DW5, really, is for IRIX64. But we allow it. */ + DISTINGUISHED_VALUE_ARRAY(v4); + + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &v4[0], SIZEOFT32, extension_size); + data += extension_size; + } + abbr_off_ptr = data; + du = 0; /* length of debug_info, not counting + this field itself (unknown at this point). */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), offset_size); + data += offset_size; + + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &version, + sizeof(version), DWARF_HALF_SIZE); + data += DWARF_HALF_SIZE; - /* We have filled the chunk we got with GET_CHUNK. At this point we - no longer dare use "data" or "start_info_sec" as a pointer any + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &unit_type, + sizeof(unit_type), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + + WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size, + sizeof(address_size), sizeof(Dwarf_Ubyte)); + data += sizeof(Dwarf_Ubyte); + + du = 0;/* offset into abbrev table, not yet known. */ + WRITE_UNALIGNED(dbg, (void *) data, + (const void *) &du, sizeof(du), offset_size); + data += offset_size; + + /* We have filled the chunk we got with GET_CHUNK. + At this point we + no longer dare use "data" as a pointer any longer except to refer to that first small chunk for the cu - header. */ + header to update the section length. */ + + *abbrev_offset_io = abbrev_offset; + *data_io = data; + *cu_header_size_out = cu_header_size; + *abbr_off_ptr_out = abbr_off_ptr; + return DW_DLV_OK; +} + +/* Write out debug_abbrev section */ +static int +write_out_debug_abbrev(Dwarf_P_Debug dbg, + Dwarf_P_Abbrev abbrev_head, + Dwarf_Error * error) +{ + Dwarf_P_Abbrev curabbrev = abbrev_head; + unsigned char *data = 0; + int res = 0; + int abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; + + while (curabbrev) { + int idx = 0; + unsigned lebcount = 0; + Dwarf_Ubyte db = 0; + + res = write_uval(curabbrev->abb_idx,dbg,abbrevsectno, + &lebcount,error); + if (res != DW_DLV_OK) { + return res; + } + + res = write_uval(curabbrev->abb_tag,dbg,abbrevsectno, + &lebcount,error); + if (res != DW_DLV_OK) { + return res; + } + + db = curabbrev->abb_children; + res = write_ubyte(db,dbg,abbrevsectno,&lebcount,error); + if (res != DW_DLV_OK) { + return res; + } + + /* add attributes and forms */ + for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { + res =write_uval(curabbrev->abb_attrs[idx], + dbg,abbrevsectno, + &lebcount,error); + if (res != DW_DLV_OK) { + return res; + } + res =write_uval(curabbrev->abb_forms[idx], + dbg,abbrevsectno, + &lebcount,error); + if (res != DW_DLV_OK) { + return res; + } + if (curabbrev->abb_forms[idx] == DW_FORM_implicit_const){ + res =write_sval(curabbrev->abb_implicits[idx], + dbg,abbrevsectno, + &lebcount,error); + if (res != DW_DLV_OK) { + return res; + } + } + } + /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */ + GET_CHUNK_ERR(dbg, abbrevsectno, data, 2, error); + *data = 0; + data++; + *data = 0; + + curabbrev = curabbrev->abb_next; + } + /* one zero, for end of cu, see dwarf2 sec 7.5.3 */ + GET_CHUNK_ERR(dbg, abbrevsectno, data, 1, error); + *data = 0; + return DW_DLV_OK; +} + +static int +sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die, + Dwarf_Error *error) +{ + struct Dwarf_Sort_Abbrev_s *sortab = 0; + struct Dwarf_Sort_Abbrev_s *ap = 0; + Dwarf_P_Attribute at = 0; + Dwarf_P_Attribute sorted_attrlist = 0; + Dwarf_P_Attribute sorted_tail = 0; + int attrcount = die->di_n_attr; + int res = 0; + unsigned ct = 0; + + int k = 0; + + if (attrcount < 2) { + return DW_DLV_OK; + } + + sortab = (struct Dwarf_Sort_Abbrev_s *) + malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount); + if(!sortab) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); + } + /* ASSERT at->ar_next chain length == attrcount */ + ap = sortab; + at = die->di_attrs; + for(; at; ++ap, at = at->ar_next) { + ap->dsa_attr = at->ar_attribute; + ap->dsa_form = at->ar_attribute_form; + ap->dsa_attrp = at; + ++ct; + } + qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s), + abcompare); + res = verify_ab_no_dups(sortab,attrcount); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_DUP_ATTR_ON_DIE, DW_DLV_ERROR); + } + ap = sortab; + k = 0; + for( ; k < attrcount; ++k,++ap) { + Dwarf_P_Attribute localptr = ap->dsa_attrp; + if (!sorted_attrlist) { + sorted_attrlist = localptr; + sorted_tail = sorted_attrlist; + localptr->ar_next = 0; + continue; + } + sorted_tail->ar_next = localptr; + sorted_tail = localptr; + localptr->ar_next = 0; + } + /* Now replace the list with the same pointers + but in order sorted by attribute. */ + die->di_attrs = sorted_attrlist; + free(sortab); + return DW_DLV_OK; +} + + + +static int +_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, + Dwarf_Error * error) +{ + int elfsectno_of_debug_info = 0; + unsigned char *data = 0; + int cu_header_size = 0; + Dwarf_P_Abbrev curabbrev = 0; + Dwarf_P_Abbrev abbrev_head = 0; + Dwarf_P_Abbrev abbrev_tail = 0; + Dwarf_P_Die curdie = 0; + Dwarf_P_Die first_child = 0; + Dwarf_Unsigned dw = 0; + Dwarf_Unsigned du = 0; + Dwarf_Half dh = 0; + Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */ + int n_abbrevs = 0; + unsigned abbrev_offset = 0; + int res = 0; + unsigned marker_count = 0; + unsigned string_attr_count = 0; + unsigned string_attr_offset = 0; + Dwarf_Small *abbr_off_ptr = 0; + + int offset_size = dbg->de_offset_size; + /* extension_size is oddly names. The standard calls + for a 64bit offset to have a 4 byte 0xffff + while original IRIX64 did not. + So if dbg->de_64bit_extension set this is a standard + DWARF 64bit offset and if de_64bit_extension not set + this is non-standard IRIX64 64 bit offset. */ + Dwarf_Half version = dbg->de_output_version; + int extension_size = dbg->de_64bit_extension ? 4 : 0; + + /* For now just assume DW_UT_compile FIXME */ + Dwarf_Ubyte unit_type = DW_UT_compile; + Dwarf_Ubyte address_size = 0; + + elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; + address_size = dbg->de_pointer_size; + if (version < 5) { + res = generate_debuginfo_header_2(dbg, + &abbrev_offset, + &data, + &cu_header_size, + &abbr_off_ptr, + version, extension_size, address_size, + error); + if (res != DW_DLV_OK) { + return res; + } + } else if (version == 5) { + res = generate_debuginfo_header_5(dbg, + &abbrev_offset, + &data, + &cu_header_size, + &abbr_off_ptr, + version, unit_type, extension_size, address_size, + error); + if (res != DW_DLV_OK) { + return res; + } + } else { + DWARF_P_DBG_ERROR(dbg, DW_DLE_VERSION_STAMP_ERROR, + DW_DLV_ERROR); + } curdie = dbg->de_dies; /* Create AT_macro_info if appropriate */ - if (dbg->de_first_macinfo != NULL) { - if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0) - return -1; + if( version < 5) { + if (dbg->de_first_macinfo != NULL) { + res = _dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error); + if (res != DW_DLV_OK) { + return res; + } + } + } else { + /* FIXME need to add code to emit DWARF5 macro data. */ +#if 0 + res = _dwarf_pro_add_AT_macro5_info(dbg, curdie, 0, error); +#endif } /* Create AT_stmt_list attribute if necessary */ - if (dwarf_need_debug_line_section(dbg) == TRUE) - if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0) - return -1; - + if (dwarf_need_debug_line_section(dbg) == TRUE) { + res =_dwarf_pro_add_AT_stmt_list(dbg, curdie, error); + if (res != DW_DLV_OK) { + return res; + } + } die_off = cu_header_size; /* Relocation for abbrev offset in cu header store relocation record in linked list */ - res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE + - sizeof(Dwarf_Half), - /* r_offset */ + res = dbg->de_relocate_by_name_symbol(dbg, + DEBUG_INFO, + abbrev_offset /* r_offset */, dbg->de_sect_name_idx[DEBUG_ABBREV], - dwarf_drt_data_reloc, uwordb_size); + dwarf_drt_data_reloc, offset_size); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } /* Pass 0: only top level dies, add at_sibling attribute to those @@ -1637,26 +3160,32 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) } /* Pass 1: create abbrev info, get die offsets, calc relocations */ + abbrev_head = abbrev_tail = NULL; marker_count = 0; string_attr_count = 0; while (curdie != NULL) { int nbytes = 0; Dwarf_P_Attribute curattr = 0; - Dwarf_P_Attribute new_first_attr = 0; - Dwarf_P_Attribute new_last_attr = 0; char *space = 0; int cres = 0; char buff1[ENCODE_SPACE_NEEDED]; - int i = 0; curdie->di_offset = die_off; - if (curdie->di_marker != 0) + if (curdie->di_marker != 0) { marker_count++; - - curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head); - if (curabbrev == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + } + cres =sort_die_attrs(dbg,curdie,error); + if (cres != DW_DLV_OK) { + /* DW_DLV_NO_ENTRY is impossible. */ + return cres; + } + /* Find or create a final abbrev record for the + debug_abbrev section we will write (below). */ + cres = _dwarf_pro_getabbrev(dbg,curdie, abbrev_head,&curabbrev, + error); + if (cres != DW_DLV_OK) { + return cres; } if (abbrev_head == NULL) { n_abbrevs = 1; @@ -1671,65 +3200,30 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) abbrev_tail = curabbrev; } } + /* We know the abbrev number to use now. + So create the bytes of the leb with the + value and save those bytes in di_abbrev, + we will emit in Pass 2 (below). */ cres = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes, buff1, sizeof(buff1)); if (cres != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } space = _dwarf_p_get_alloc(dbg, nbytes); if (space == NULL) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR); } memcpy(space, buff1, nbytes); curdie->di_abbrev = space; curdie->di_abbrev_nbytes = nbytes; die_off += nbytes; - /* Resorting the attributes!! */ - new_first_attr = new_last_attr = NULL; - curattr = curdie->di_attrs; - for (i = 0; i < (int)curabbrev->abb_n_attr; i++) { - Dwarf_P_Attribute cur = 0; - Dwarf_P_Attribute lastattr = 0; - - /* The following should always find an attribute! - It starts from the beginning of the remaining list - of attributes on the DIE.*/ - for (cur = lastattr = curattr; - cur && (curabbrev->abb_attrs[i] != cur->ar_attribute); - lastattr = cur, cur = cur->ar_next) - { - } - - if (!cur) { - /* This will trip with an error if, somehow, one has - managed to erroneously have multiple of - a given attribute number in a single DIE. */ - DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1); - } - - /* Remove the attribute from the old list, we - will place it on the new list. */ - if (cur == curattr) { - curattr = cur->ar_next; - } else { - lastattr->ar_next = cur->ar_next; - } - - cur->ar_next = NULL; - - /* Add the attribute'cur' to the new list. */ - if (new_first_attr == NULL) { - new_first_attr = new_last_attr = cur; - } else { - new_last_attr->ar_next = cur; - new_last_attr = cur; - } - } + /* The abbrev and DIE attr lists match, so the die + abbrevs are in the correct order, + curdie->di_attrs. */ /* Now we attach the attributes list to the die. */ - curdie->di_attrs = new_first_attr; curattr = curdie->di_attrs; while (curattr) { @@ -1748,19 +3242,39 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) curattr->ar_rel_symidx = dbg->de_sect_name_idx[DEBUG_MACINFO]; break; + /* See also: pro_forms.c for same strings attribute list. */ + case DW_AT_comp_dir: + case DW_AT_const_value: + case DW_AT_linkage_name: /* DWARF5 */ + case DW_AT_MIPS_abstract_name: + case DW_AT_MIPS_linkage_name: + case DW_AT_name: + case DW_AT_producer: { + int is_debug_str = 0; + int nres = if_relocatable_string_form(dbg,curattr, + &is_debug_str,error); + if (nres != DW_DLV_OK) { + return res; + } + if (is_debug_str) { + curattr->ar_rel_symidx = + dbg->de_sect_name_idx[DEBUG_STR]; + } + } + break; default: break; } - rres = dbg->de_reloc_name(dbg, DEBUG_INFO, + rres = dbg->de_relocate_by_name_symbol(dbg, + DEBUG_INFO, die_off + curattr->ar_rel_offset,/* r_offset */ curattr->ar_rel_symidx, dwarf_drt_data_reloc, curattr->ar_reloc_len); if (rres != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } - } if (curattr->ar_attribute_form == DW_FORM_string) { string_attr_count++; @@ -1768,29 +3282,31 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) die_off += curattr->ar_nbytes; curattr = curattr->ar_next; } - - /* depth first search */ - if (curdie->di_child) + /* Depth first access to all the DIEs. */ + if (curdie->di_child) { curdie = curdie->di_child; - else { + } else { while (curdie != NULL && curdie->di_right == NULL) { curdie = curdie->di_parent; - die_off++; /* since we are writing a null die at - the end of each sibling chain */ + /* See -nonrootsibling- below */ + if (curdie != NULL) { + die_off++; + } } - if (curdie != NULL) + if (curdie != NULL) { curdie = curdie->di_right; + } } - } /* end while (curdie != NULL) */ + } /* end while (curdie != NULL), the per-die loop */ res = marker_init(dbg, marker_count); - if (res == -1) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + if (res == DW_DLV_ERROR) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } res = string_attr_init(dbg, DEBUG_INFO, string_attr_count); - if (res == -1) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + if (res != DW_DLV_OK) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } /* Pass 2: Write out the die information Here 'data' is a @@ -1801,32 +3317,32 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) if (curdie->di_marker != 0) { res = marker_add(dbg, curdie->di_offset, curdie->di_marker); - if (res == -1) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); + if (res == DW_DLV_ERROR) { + DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR); } } /* Index to abbreviation table */ - GET_CHUNK(dbg, elfsectno_of_debug_info, + GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, curdie->di_abbrev_nbytes, error); - memcpy((void *) data, (const void *) curdie->di_abbrev, curdie->di_abbrev_nbytes); /* Attribute values - need to fill in all form attributes */ curattr = curdie->di_attrs; - string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes; - + string_attr_offset = curdie->di_offset + + curdie->di_abbrev_nbytes; while (curattr) { - GET_CHUNK(dbg, elfsectno_of_debug_info, data, + GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, (unsigned long) curattr->ar_nbytes, error); switch (curattr->ar_attribute_form) { case DW_FORM_ref1: { + Dwarf_Ubyte db = 0; if (curattr->ar_ref_die->di_offset > (unsigned) 0xff) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } db = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, @@ -1838,12 +3354,12 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffff) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR); } dh = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, - sizeof(dh), sizeof(Dwarf_Half)); + sizeof(dh), DWARF_HALF_SIZE); break; } case DW_FORM_ref_addr: @@ -1862,43 +3378,46 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) { if (curattr->ar_ref_die->di_offset > (unsigned) 0xffffffff) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, + DW_DLV_ERROR); } - dw = (Dwarf_Word) curattr->ar_ref_die->di_offset; + dw = (Dwarf_Unsigned) curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dw, - sizeof(dw), sizeof(Dwarf_ufixed)); + sizeof(dw), DWARF_32BIT_SIZE); break; } case DW_FORM_ref8: du = curattr->ar_ref_die->di_offset; WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, - sizeof(du), sizeof(Dwarf_Unsigned)); + sizeof(du), DWARF_64BIT_SIZE); break; case DW_FORM_ref_udata: - { /* unsigned leb128 offset */ + { /* unsigned leb128 offset */ - int nbytes; + int nbytesx; char buff1[ENCODE_SPACE_NEEDED]; res = _dwarf_pro_encode_leb128_nm(curattr-> ar_ref_die-> - di_offset, &nbytes, + di_offset, &nbytesx, buff1, sizeof(buff1)); if (res != DW_DLV_OK) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); + DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, + DW_DLV_ERROR); } - - memcpy(data, buff1, nbytes); + memcpy(data, buff1, nbytesx); break; } default: - memcpy((void *) data, - (const void *) curattr->ar_data, - curattr->ar_nbytes); + if(curattr->ar_nbytes) { + memcpy((void *) data, + (const void *) curattr->ar_data, + curattr->ar_nbytes); + } break; } if (curattr->ar_attribute_form == DW_FORM_string) { @@ -1909,11 +3428,22 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) } /* depth first search */ - if (curdie->di_child) + if (curdie->di_child) { curdie = curdie->di_child; - else { + } else { while (curdie != NULL && curdie->di_right == NULL) { - GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error); + /* -nonrootsibling- + A null die should only be written for terminating + siblings, not the root. Adding a terminating die + for the root will cause, after object files are + linked, warnings to be generated with newer + versions of readelf. */ + if (!curdie->di_parent) { + /* The parent is not a DIE so ending a sibling + chain makes no sense (wastes a byte). */ + break; + } + GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, 1, error); *data = '\0'; curdie = curdie->di_parent; } @@ -1922,55 +3452,83 @@ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) } } /* end while (curdir != NULL) */ - /* Write out debug_info size */ - /* Do not include length field or extension bytes */ - du = die_off - BEGIN_LEN_SIZE; - WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size), - (const void *) &du, sizeof(du), uwordb_size); + /* Write out debug_info size, now that we know it + This is back-patching the CU header we created + above. */ + du = die_off - OFFSET_PLUS_EXTENSION_SIZE; + WRITE_UNALIGNED(dbg, (void *) abbr_off_ptr, + (const void *) &du, sizeof(du), offset_size); data = 0; /* Emphasise not usable now */ - /* Write out debug_abbrev section */ - abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; - - curabbrev = abbrev_head; - while (curabbrev) { - int idx = 0; + res = write_out_debug_abbrev(dbg, + abbrev_head, error); + if (res != DW_DLV_OK) { + return res; + } - write_uval(curabbrev->abb_idx,dbg,abbrevsectno,error); - write_uval(curabbrev->abb_tag,dbg,abbrevsectno,error); + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; +} - db = curabbrev->abb_children; - write_ubyte(db,dbg,abbrevsectno,error); +static int +_dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg, + UNUSEDARG Dwarf_Signed *nbufs, + Dwarf_Error * error UNUSEDARG) +{ +#if 0 + int elfsectno_of_debug_names = dbg->de_elf_sects[DEBUG_NAMES]; + FIXME: Needs implementation + unsigned char *data = 0; - /* add attributes and forms */ - for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { - write_uval(curabbrev->abb_attrs[idx], - dbg,abbrevsectno,error); + GET_CHUNK(dbg, elfsectno_of_debug_names, data, + dbg->de_debug_names->ds_nbytes, + error); + memcpy(data,dbg->de_debug_names->ds_data,dbg->de_debug_names->ds_nbytes); +#endif + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; +} - write_uval(curabbrev->abb_forms[idx], - dbg,abbrevsectno,error); - } - /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */ - GET_CHUNK(dbg, abbrevsectno, data, 2, error); - *data = 0; - data++; - *data = 0; +static int +_dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, + Dwarf_Error * error) +{ + int elfsectno_of_debug_str = 0; + unsigned char *data = 0; - curabbrev = curabbrev->abb_next; - } + elfsectno_of_debug_str = dbg->de_elf_sects[DEBUG_STR]; + GET_CHUNK(dbg, elfsectno_of_debug_str, data, dbg->de_debug_str->ds_nbytes, + error); + memcpy(data,dbg->de_debug_str->ds_data,dbg->de_debug_str->ds_nbytes); + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; +} +static int +_dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, + Dwarf_Error * error) +{ + int elfsectno_of_debug_line_str = 0; + unsigned char *data = 0; - /* one zero, for end of cu, see dwarf2 sec 7.5.3 */ - GET_CHUNK(dbg, abbrevsectno, data, 1, error); - *data = 0; - return (int) dbg->de_n_debug_sect; + elfsectno_of_debug_line_str = dbg->de_elf_sects[DEBUG_LINE_STR]; + GET_CHUNK(dbg, elfsectno_of_debug_line_str, data, + dbg->de_debug_line_str->ds_nbytes, + error); + memcpy(data,dbg->de_debug_line_str->ds_data, + dbg->de_debug_line_str->ds_nbytes); + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; } /* Get a buffer of section data. section_idx is the elf-section number that this data applies to. - length shows length of returned data */ + length shows length of returned data + This is the original format. Hard to check for error. */ /*ARGSUSED*/ /* pretend all args used */ Dwarf_Ptr @@ -1978,32 +3536,66 @@ dwarf_get_section_bytes(Dwarf_P_Debug dbg, UNUSEDARG Dwarf_Signed dwarf_section, Dwarf_Signed * section_idx, Dwarf_Unsigned * length, Dwarf_Error * error) +{ + Dwarf_Ptr s_bytes = 0; + int res = 0; + + res = dwarf_get_section_bytes_a(dbg, + dwarf_section, + section_idx, + length, + &s_bytes, + error); + if (res == DW_DLV_ERROR) { + return (Dwarf_Ptr)DW_DLV_BADADDR; + } + if (res == DW_DLV_NO_ENTRY) { + return NULL; + } + return s_bytes; +} + +/* Get a buffer of section data. + section_idx is the elf-section number that this data applies to. + length shows length of returned data + This is the September 2016 format. Preferred. */ +int +dwarf_get_section_bytes_a(Dwarf_P_Debug dbg, + UNUSEDARG Dwarf_Signed dwarf_section, + Dwarf_Signed * section_idx, + Dwarf_Unsigned * length, + Dwarf_Ptr * section_bytes, + Dwarf_Error * error) { Dwarf_Ptr buf = 0; if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { - DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL); + DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR); } - + *section_bytes = 0; + *length = 0; if (dbg->de_debug_sects == 0) { /* no more data !! */ - return NULL; + return DW_DLV_NO_ENTRY; } if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { /* no data ever entered !! */ - return NULL; + return DW_DLV_NO_ENTRY; } *section_idx = dbg->de_debug_sects->ds_elf_sect_no; *length = dbg->de_debug_sects->ds_nbytes; buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; + /* Here is the iterator so the next call gets + the next section. */ dbg->de_debug_sects = dbg->de_debug_sects->ds_next; /* We may want to call the section stuff more than once: see dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ - return buf; + *section_bytes = buf; + return DW_DLV_OK; } /* No errors possible. */ @@ -2098,136 +3690,3 @@ _dwarf_pro_buffer(Dwarf_P_Debug dbg, return space_for_caller; } } - - -/* Given address advance and line advance, it gives - either special opcode, or a number < 0 */ -static int -_dwarf_pro_get_opc(Dwarf_P_Debug dbg,Dwarf_Unsigned addr_adv, int line_adv) -{ - int line_base = dbg->de_line_inits.pi_line_base; - int line_range = dbg->de_line_inits.pi_line_range; - Dwarf_Unsigned factored_adv = 0; - - factored_adv = addr_adv / dbg->de_line_inits.pi_minimum_instruction_length; - if (line_adv == 0 && factored_adv == 0) { - return OPC_INCS_ZERO; - } - if (line_adv >= line_base && line_adv < line_base + line_range) { - int opc = (line_adv - line_base) + (factored_adv * line_range) + - dbg->de_line_inits.pi_opcode_base; - if (opc > 255) { - return OPC_OUT_OF_RANGE; - } - return opc; - } - return LINE_OUT_OF_RANGE; -} - -/* Handles abbreviations. It takes a die, searches through - current list of abbreviations for matching one. If it - finds one, it returns a pointer to the abbrev, and if it does not, - it returns a new abbrev. It is up to the user of this function to - link it up to the abbreviation head. If it is a new abbrev - abb_idx has 0. */ -static Dwarf_P_Abbrev -_dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head) -{ - Dwarf_P_Abbrev curabbrev; - Dwarf_P_Attribute curattr; - int res1; - int nattrs; - int match; - Dwarf_ufixed *forms = 0; - Dwarf_ufixed *attrs = 0; - - curabbrev = head; - while (curabbrev) { - if ((die->di_tag == curabbrev->abb_tag) && - ((die->di_child != NULL && - curabbrev->abb_children == DW_CHILDREN_yes) || - (die->di_child == NULL && - curabbrev->abb_children == DW_CHILDREN_no)) && - (die->di_n_attr == curabbrev->abb_n_attr)) { - - /* There is a chance of a match. */ - curattr = die->di_attrs; - match = 1; /* Assume match found. */ - while (match && curattr) { - res1 = _dwarf_pro_match_attr(curattr, - curabbrev, - (int) curabbrev->abb_n_attr); - if (res1 == 0) { - match = 0; - } - curattr = curattr->ar_next; - } - if (match == 1) { - return curabbrev; - } - } - curabbrev = curabbrev->abb_next; - } - - /* no match, create new abbreviation */ - if (die->di_n_attr != 0) { - forms = (Dwarf_ufixed *) - _dwarf_p_get_alloc(die->di_dbg, - sizeof(Dwarf_ufixed) * die->di_n_attr); - if (forms == NULL) { - return NULL; - } - attrs = (Dwarf_ufixed *) - _dwarf_p_get_alloc(die->di_dbg, - sizeof(Dwarf_ufixed) * die->di_n_attr); - if (attrs == NULL) - return NULL; - } - nattrs = 0; - curattr = die->di_attrs; - while (curattr) { - attrs[nattrs] = curattr->ar_attribute; - forms[nattrs] = curattr->ar_attribute_form; - nattrs++; - curattr = curattr->ar_next; - } - - curabbrev = (Dwarf_P_Abbrev) - _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s)); - if (curabbrev == NULL) { - return NULL; - } - - if (die->di_child == NULL) { - curabbrev->abb_children = DW_CHILDREN_no; - } else { - curabbrev->abb_children = DW_CHILDREN_yes; - } - curabbrev->abb_tag = die->di_tag; - curabbrev->abb_attrs = attrs; - curabbrev->abb_forms = forms; - curabbrev->abb_n_attr = die->di_n_attr; - curabbrev->abb_idx = 0; - curabbrev->abb_next = NULL; - - return curabbrev; -} - -/* Tries to see if given attribute and form combination - exists in the given abbreviation */ -static int -_dwarf_pro_match_attr(Dwarf_P_Attribute attr, - Dwarf_P_Abbrev abbrev, int no_attr) -{ - int i; - int found = 0; - - for (i = 0; i < no_attr; i++) { - if (attr->ar_attribute == abbrev->abb_attrs[i] && - attr->ar_attribute_form == abbrev->abb_forms[i]) { - found = 1; - break; - } - } - return found; -} diff --git a/thirdparty/dwarf/pro_section.h b/thirdparty/dwarf/pro_section.h index 8ea7ded9..2c696579 100644 --- a/thirdparty/dwarf/pro_section.h +++ b/thirdparty/dwarf/pro_section.h @@ -1,6 +1,7 @@ /* Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. + Portions (C) 2016 David Anderson . All Rights Reserved. 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 @@ -76,6 +77,14 @@ struct Dwarf_P_Section_Data_s { Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno, unsigned long nbytes); +/* GET_CHUNK_ERROR is new Sept 2016 to use DW_DLV_ERROR. */ +#define GET_CHUNK_ERR(dbg,sectno,ptr,nbytes,error) \ +{ \ + (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ + if ((ptr) == NULL) { \ + DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,DW_DLV_ERROR); \ + } \ +} #define GET_CHUNK(dbg,sectno,ptr,nbytes,error) \ { \ (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \ @@ -86,15 +95,23 @@ Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno, -int - _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, +int _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, + Dwarf_Signed *nbufs, Dwarf_Error * error); -/* These are for creating ELF section type codes. +/* These are for creating ELF section type codes. + We are not trying to match any particulare + ABI's settings for section type. + In the producer, see de_callback_func() calls. + + If SHT_MIPS_DWARF was defined sometimes + that was the value taken: 0x7000001e + If it's important to someone then + passing in a string like SHT=0x7000001e + to the 'extra' argument of dwarf_producer_init() + would work nicely (leading/trailing spaces + are allowed, as is a NULL pointer instead + of a string). + One is a convenient default for testing purposes. */ -#if defined(linux) || defined(__BEOS__) || !defined(SHT_MIPS_DWARF) -/* Intel's SoftSdv accepts only this */ -#define SECTION_TYPE SHT_PROGBITS -#else -#define SECTION_TYPE SHT_MIPS_DWARF -#endif +#define SECTION_TYPE 1 /* SHT_PROGBITS in Elf. */ diff --git a/thirdparty/dwarf/pro_types.c b/thirdparty/dwarf/pro_types.c index 90accd74..6046a533 100644 --- a/thirdparty/dwarf/pro_types.c +++ b/thirdparty/dwarf/pro_types.c @@ -1,7 +1,6 @@ /* - Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright 2011 David Anderson. All Rights Reserved. + Portions Copyright 2011-2019 David Anderson. All Rights Reserved. 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 @@ -33,9 +32,16 @@ #include #endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" +#include "pro_alloc.h" #include "pro_section.h" #include "pro_types.h" +#define SIZEOFT32 4 /* This function adds another type name to the @@ -45,11 +51,30 @@ Dwarf_Unsigned dwarf_add_typename(Dwarf_P_Debug dbg, Dwarf_P_Die die, - char *type_name, Dwarf_Error * error) + char *type_name, + Dwarf_Error * error) { - return - _dwarf_add_simple_name_entry(dbg, die, type_name, - dwarf_snk_typename, error); + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, type_name, + dwarf_snk_typename, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; + +} +int +dwarf_add_typename_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *type_name, + Dwarf_Error * error) +{ + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, type_name, + dwarf_snk_typename, error); + return res; } /* @@ -59,7 +84,7 @@ dwarf_add_typename(Dwarf_P_Debug dbg, See enum dwarf_sn_kind in pro_opaque.h */ -Dwarf_Unsigned +int _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *entry_name, @@ -73,12 +98,12 @@ _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, if (dbg == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); - return (0); + return DW_DLV_ERROR; } if (die == NULL) { _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); - return (0); + return DW_DLV_ERROR; } @@ -87,13 +112,13 @@ _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, sizeof(struct Dwarf_P_Simple_nameentry_s)); if (nameentry == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1); if (name == NULL) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } strcpy(name, entry_name); @@ -112,7 +137,7 @@ _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, hdr->sn_count++; hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1; - return (1); + return DW_DLV_OK; } @@ -131,6 +156,7 @@ int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in de_elf_sects etc */ + Dwarf_Signed *nbufs, Dwarf_Error * error) { @@ -174,14 +200,13 @@ _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, /* Size of the .debug_typenames (or similar) section header. */ stream_bytes_count = extension_size + uword_size + /* Size of length field. */ - sizeof(Dwarf_Half) + /* Size of version field. */ + DWARF_HALF_SIZE + /* Size of version field. */ uword_size + /* Size of .debug_info offset. */ uword_size; /* Size of .debug_names. */ nameentry_original = hdr->sn_head; - nameentry = nameentry_original; /* add in the content size */ stream_bytes_count += hdr->sn_net_len; @@ -191,17 +216,13 @@ _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, /* Now we know how long the entire section is */ GET_CHUNK(dbg, dbg->de_elf_sects[section_index], stream_bytes, (unsigned long) stream_bytes_count, error); - if (stream_bytes == NULL) { - _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); - } cur_stream_bytes_ptr = stream_bytes; if (extension_size) { - Dwarf_Unsigned x = DISTINGUISHED_VALUE; + DISTINGUISHED_VALUE_ARRAY(v4); WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, - (const void *) &x, sizeof(x), extension_size); + (const void *)&v4[0],SIZEOFT32 , extension_size); cur_stream_bytes_ptr += extension_size; } @@ -218,8 +239,8 @@ _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &verstamp, - sizeof(verstamp), sizeof(Dwarf_Half)); - cur_stream_bytes_ptr += sizeof(Dwarf_Half); + sizeof(verstamp), DWARF_HALF_SIZE); + cur_stream_bytes_ptr += DWARF_HALF_SIZE; } /* Write the offset of the compile-unit. */ @@ -230,10 +251,10 @@ _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, /* now create the relocation for the compile_unit offset */ { - int res = dbg->de_reloc_name(dbg, + int res = dbg->de_relocate_by_name_symbol(dbg, section_index, extension_size + uword_size + - sizeof(Dwarf_Half) /* r_offset */ , + DWARF_HALF_SIZE /* r_offset */ , /* debug_info section name symbol */ dbg->de_sect_name_idx[DEBUG_INFO], dwarf_drt_data_reloc, @@ -241,7 +262,7 @@ _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, if (res != DW_DLV_OK) { _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); - return (0); + return DW_DLV_ERROR; } } @@ -270,5 +291,6 @@ _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, (const void *) &big_zero, sizeof(big_zero), uword_size); - return (int) dbg->de_n_debug_sect; + *nbufs = dbg->de_n_debug_sect; + return DW_DLV_OK; } diff --git a/thirdparty/dwarf/pro_types.h b/thirdparty/dwarf/pro_types.h index fe6325c7..f920a212 100644 --- a/thirdparty/dwarf/pro_types.h +++ b/thirdparty/dwarf/pro_types.h @@ -31,4 +31,5 @@ int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index,/* in de_elf_sects etc */ + Dwarf_Signed *nbufs_out, Dwarf_Error * error); diff --git a/thirdparty/dwarf/pro_util.h b/thirdparty/dwarf/pro_util.h index 2df08898..9c101807 100644 --- a/thirdparty/dwarf/pro_util.h +++ b/thirdparty/dwarf/pro_util.h @@ -27,12 +27,9 @@ /* Definition of sizes of types. Independent of target or host, these are. */ -#define sizeof_sbyte(dbg) sizeof(Dwarf_Sbyte) -#define sizeof_ubyte(dbg) sizeof(Dwarf_Ubyte) -#define sizeof_uhalf(dbg) sizeof(Dwarf_Half) +#define sizeof_ubyte(dbg) 1 +#define sizeof_uhalf(dbg) DWARF_HALF_SIZE /* Computes amount of padding necessary to align n to a k-boundary. */ /* Important: Assumes n, k both GREATER than zero. */ #define PADDING(n, k) ( (k)-1 - ((n)-1)%(k) ) - - diff --git a/thirdparty/dwarf/pro_vars.c b/thirdparty/dwarf/pro_vars.c index c2888d06..8ede1a1a 100644 --- a/thirdparty/dwarf/pro_vars.c +++ b/thirdparty/dwarf/pro_vars.c @@ -33,6 +33,11 @@ #include #endif #include "pro_incl.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" #include "pro_section.h" /* @@ -44,9 +49,22 @@ Dwarf_Unsigned dwarf_add_varname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *var_name, Dwarf_Error * error) { - return - _dwarf_add_simple_name_entry(dbg, die, var_name, - dwarf_snk_varname, error); + int res = 0; + res = _dwarf_add_simple_name_entry(dbg, die, var_name, + dwarf_snk_varname, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; +} +int +dwarf_add_varname_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, char *var_name, Dwarf_Error * error) +{ + int res = 0; + res = _dwarf_add_simple_name_entry(dbg, die, var_name, + dwarf_snk_varname, error); + return res; } diff --git a/thirdparty/dwarf/pro_weaks.c b/thirdparty/dwarf/pro_weaks.c index b2eecc25..668abd91 100644 --- a/thirdparty/dwarf/pro_weaks.c +++ b/thirdparty/dwarf/pro_weaks.c @@ -32,8 +32,11 @@ #ifdef HAVE_ELFACCESS_H #include #endif -#include "pro_incl.h" -#include "pro_section.h" +#include +#include "dwarf.h" +#include "libdwarf.h" +#include "pro_opaque.h" +#include "pro_error.h" /* This function adds another weak name to the @@ -45,7 +48,24 @@ dwarf_add_weakname(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *weak_name, Dwarf_Error * error) { - return - _dwarf_add_simple_name_entry(dbg, die, weak_name, - dwarf_snk_weakname, error); + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, weak_name, + dwarf_snk_weakname, error); + if (res != DW_DLV_OK) { + return 0; + } + return 1; +} + +int +dwarf_add_weakname_a(Dwarf_P_Debug dbg, + Dwarf_P_Die die, + char *weak_name, Dwarf_Error * error) +{ + int res = 0; + + res = _dwarf_add_simple_name_entry(dbg, die, weak_name, + dwarf_snk_weakname, error); + return res; }