diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-06-25 17:58:31 -0700 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-07-10 12:35:15 -0700 |
commit | 4d9fdb46b215739778ebc12079842c9905586999 (patch) | |
tree | 3771cce63ac88d62941f4174ee3fa58336a95775 /usr/src/lib/libdwarf/common/dwarf_util.h | |
parent | 4c60ecf710115cd5ae61f6b97dafc7ff963259f4 (diff) | |
download | illumos-gate-4d9fdb46b215739778ebc12079842c9905586999.tar.gz |
12223 Update libdwarf to libdwarf-20200612
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib/libdwarf/common/dwarf_util.h')
-rw-r--r-- | usr/src/lib/libdwarf/common/dwarf_util.h | 581 |
1 files changed, 386 insertions, 195 deletions
diff --git a/usr/src/lib/libdwarf/common/dwarf_util.h b/usr/src/lib/libdwarf/common/dwarf_util.h index 4046bb2478..d24a3e9e82 100644 --- a/usr/src/lib/libdwarf/common/dwarf_util.h +++ b/usr/src/lib/libdwarf/common/dwarf_util.h @@ -3,59 +3,72 @@ /* Copyright (C) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. + Portions Copyright (C) 2007-2020 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. - - Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, - Mountain View, CA 94043, or: - - http://www.sgi.com - - For further information regarding this notice, see: - - http://oss.sgi.com/projects/GenInfo/NoticeExplan - -*/ -/* The address of the Free Software Foundation is - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - Boston, MA 02110-1301, USA. - SGI has moved from the Crittenden Lane address. */ - - - /* Decodes unsigned leb128 encoded numbers. - Make sure ptr is a pointer to a 1-byte type. + 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 + else falls through. */ -#define DECODE_LEB128_UWORD(ptr, value) \ - do { \ - Dwarf_Word uleblen; \ - value = _dwarf_decode_u_leb128(ptr,&uleblen); \ - ptr += uleblen; \ +#define DECODE_LEB128_UWORD_CK(ptr, value,dbg,errptr,endptr) \ + do { \ + 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); \ + if (lu_res == DW_DLV_ERROR) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + value = lu_local; \ + ptr += lu_leblen; \ + } while (0) + +#define DECODE_LEB128_UWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \ + do { \ + 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); \ + if (lu_res == DW_DLV_ERROR) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + value = lu_local; \ + ptr += lu_leblen; \ + leblen = lu_leblen; \ } while (0) /* @@ -63,69 +76,130 @@ 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; \ - value = _dwarf_decode_s_leb128(ptr,&sleblen); \ - ptr += sleblen; \ - } while(0) +#define DECODE_LEB128_SWORD_CK(ptr, value,dbg,errptr,endptr) \ + do { \ + Dwarf_Unsigned uleblen = 0; \ + Dwarf_Signed local = 0; \ + int lu_res = 0; \ + lu_res = _dwarf_decode_s_leb128_chk(ptr,&uleblen,&local,endptr); \ + if (lu_res == DW_DLV_ERROR) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + value = local; \ + ptr += uleblen; \ + } while (0) +#define DECODE_LEB128_SWORD_LEN_CK(ptr, value,leblen,dbg,errptr,endptr) \ + do { \ + Dwarf_Unsigned lu_leblen = 0; \ + Dwarf_Signed lu_local = 0; \ + int lu_res = 0; \ + lu_res = _dwarf_decode_s_leb128_chk(ptr,&lu_leblen,\ + &lu_local,endptr); \ + if (lu_res == DW_DLV_ERROR) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + leblen = lu_leblen; \ + value = lu_local; \ + ptr += lu_leblen; \ + } while (0) /* - Skips leb128_encoded numbers that are guaranteed + Skips leb128_encoded numbers that are guaranteed to be no more than 4 bytes long. Same for both signed and unsigned numbers. + + These seem bogus as they assume 4 bytes get a 4 byte + word. Wrong. FIXME + + 'return' only in case of error + else falls through. */ -#define SKIP_LEB128_WORD(ptr) \ - do{ if ((*(ptr++) & 0x80) != 0) { \ - if ((*(ptr++) & 0x80) != 0) { \ - if ((*(ptr++) & 0x80) != 0) { \ - if ((*(ptr++) & 0x80) != 0) { \ - } \ - } \ - } \ - } } while (0) - - -#define CHECK_DIE(die, error_ret_value) \ -do {if (die == NULL) { \ - _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \ - return(error_ret_value); \ - } \ - if (die->di_cu_context == NULL) { \ - _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \ - return(error_ret_value); \ - } \ - if (die->di_cu_context->cc_dbg == NULL) { \ - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ - return(error_ret_value); \ - } \ -} while (0) - - -/* +#define SKIP_LEB128_WORD_CK(ptr,dbg,errptr,endptr) \ + do { \ + if ((*(ptr++) & 0x80) != 0) { \ + if (ptr >= endptr) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + if ((*(ptr++) & 0x80) != 0) { \ + if (ptr >= endptr) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + if ((*(ptr++) & 0x80) != 0) { \ + if (ptr >= endptr) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + ptr++; \ + if (ptr >= endptr) { \ + _dwarf_error(dbg, errptr, DW_DLE_LEB_IMPROPER); \ + return DW_DLV_ERROR; \ + } \ + } \ + } \ + } \ + } while (0) + + +/* Any error found here represents a bug that cannot + be dealloc-d as the caller will not know there was no dbg */ +#define CHECK_DIE(die, error_ret_value) \ + do { \ + if (die == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DIE_NULL); \ + return(error_ret_value); \ + } \ + if (die->di_cu_context == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \ + return(error_ret_value); \ + } \ + if (die->di_cu_context->cc_dbg == NULL) { \ + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ + return(error_ret_value); \ + } \ + } while (0) + + +/* Reads 'source' for 'length' bytes from unaligned addr. Avoids any constant-in-conditional warnings and avoids a test in the generated code (for non-const cases, - which are in the majority.) + which are in the majority.) Uses a temp to avoid the test. The decl here should avoid any problem of size in the temp. This code is ENDIAN DEPENDENT The memcpy args are the endian issue. + + Does not update the 'source' field. + + for READ_UNALIGNED_CK the error code refers to host endianness. */ 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; \ +#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_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) @@ -137,21 +211,33 @@ 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); \ - } \ - } while (0) +#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; \ + } \ + dbg->de_copy_word( (char *)(&_ltmp) , \ + source, length) ; \ + dest = (desttype)_ltmp; \ + } while (0) /* @@ -162,12 +248,13 @@ 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 + (length-1)) < 0) {\ - memcpy((char *)&dest+length, \ - "\xff\xff\xff\xff\xff\xff\xff\xff", \ - sizeof(dest) - length); \ - } \ +#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 */ @@ -175,95 +262,143 @@ typedef Dwarf_Unsigned BIGGEST_UINT; /* - READ_AREA LENGTH reads the length (the older way - of pure 32 or 64 bit - or the new proposed dwarfv2.1 64bit-extension way) + READ_AREA LENGTH reads the length (the older way + of pure 32 or 64 bit + or the dwarf v3 64bit-extension way) + + It reads the bits from where rw_src_data_p points to + and updates the rw_src_data_p to point past what was just read. - It reads the bits from where rw_src_data_p points to - and updates the rw_src_data_p to point past what was just read. + It updates w_length_size (to the size of an offset, either 4 or 8) + and w_exten_size (set 0 unless this frame has the DWARF3 + and later 64bit + extension, in which case w_exten_size is set to 4). - It updates w_length_size (to the size of an offset, either 4 or 8) - and w_exten_size (set 0 unless this frame has the DWARF3,4 64bit - extension, in which case w_exten_size is set to 4). + r_dbg is just the current dbg pointer. + w_target is the output length field. + r_targtype is the output type. Always Dwarf_Unsigned so far. - r_dbg is just the current dbg pointer. - w_target is the output length field. - r_targtype is the output type. Always Dwarf_Unsigned so far. - */ -/* This one handles the v2.1 64bit extension - and 32bit (and MIPS fixed 64 bit via the - dwarf_init-set r_dbg->de_length_size).. - It does not recognize any but the one distingushed value - (the only one with defined meaning). - It assumes that no CU will have a length - 0xffffffxx (32bit length) - or - 0xffffffxx xxxxxxxx (64bit length) - which makes possible auto-detection of the extension. - - This depends on knowing that only a non-zero length - is legitimate (AFAICT), and for IRIX non-standard -64 - dwarf that the first 32 bits of the 64bit offset will be - zero (because the compiler could not handle a truly large - value as of Jan 2003 and because no app has that much debug - info anyway, at least not in the IRIX case). - - At present not testing for '64bit elf' here as that - does not seem necessary (none of the 64bit length seems - appropriate unless it's ident[EI_CLASS] == ELFCLASS64). +/* This one handles the v3 64bit extension + and 32bit (and SGI/MIPS fixed 64 bit via the + dwarf_init-set r_dbg->de_length_size).. + It does not recognize any but the one distingushed value + (the only one with defined meaning). + It assumes that no CU will have a length + 0xffffffxx (32bit length) + or + 0xffffffxx xxxxxxxx (64bit length) + which makes possible auto-detection of the extension. + + This depends on knowing that only a non-zero length + is legitimate (AFAICT), and for IRIX non-standard -64 + dwarf that the first 32 bits of the 64bit offset will be + zero (because the compiler could not handle a truly large + value as of Jan 2003 and because no app has that much debug + info anyway, at least not in the IRIX case). + + At present not testing for '64bit elf' here as that + does not seem necessary (none of the 64bit length seems + appropriate unless it's ident[EI_CLASS] == ELFCLASS64). */ -# 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) { \ - /* 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 { \ - /* 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) - -Dwarf_Unsigned -_dwarf_decode_u_leb128(Dwarf_Small * leb128, - Dwarf_Word * leb128_length); - -Dwarf_Signed -_dwarf_decode_s_leb128(Dwarf_Small * leb128, - Dwarf_Word * leb128_length); - -Dwarf_Unsigned +/* 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. */ +#define READ_AREA_LENGTH_CK(r_dbg,w_target,r_targtype, \ + rw_src_data_p,w_length_size,w_exten_size,w_error, \ + r_sectionlen,r_endptr) \ + do { \ + READ_UNALIGNED_CK(r_dbg,w_target,r_targtype, \ + rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE, \ + w_error,r_endptr); \ + 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_CK(r_dbg,w_target,r_targtype, \ + rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE,\ + w_error,r_endptr); \ + if (w_target > r_sectionlen) { \ + _dwarf_error(r_dbg,w_error, \ + DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE); \ + return DW_DLV_ERROR; \ + } \ + 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_CK(r_dbg,w_target,r_targtype,\ + rw_src_data_p, \ + DISTINGUISHED_VALUE_OFFSET_SIZE, \ + w_error,r_endptr); \ + if (w_target > r_sectionlen) { \ + _dwarf_error(r_dbg,w_error, \ + DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\ + return DW_DLV_ERROR; \ + } \ + 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 { \ + if (w_target > r_sectionlen) { \ + _dwarf_error(r_dbg,w_error, \ + DW_DLE_HEADER_LEN_BIGGER_THAN_SECSIZE);\ + return DW_DLV_ERROR; \ + } \ + /* 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) + + +/* 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_Unsigned * leb128_length, + Dwarf_Unsigned *outval,Dwarf_Byte_Ptr endptr); + +int _dwarf_format_TAG_err_msg(Dwarf_Debug dbg, + Dwarf_Unsigned tag,const char *m, + Dwarf_Error *error); + + +int _dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, + Dwarf_Unsigned * leb128_length, + Dwarf_Signed *outval, Dwarf_Byte_Ptr endptr); + +int _dwarf_get_size_of_val(Dwarf_Debug dbg, Dwarf_Unsigned form, + Dwarf_Half cu_version, Dwarf_Half address_size, - Dwarf_Small * val_ptr, - int v_length_size); + Dwarf_Small * val_ptr, + int v_length_size, + Dwarf_Unsigned *size_out, + Dwarf_Small *section_end_ptr, + Dwarf_Error *error); struct Dwarf_Hash_Table_Entry_s; /* This single struct is the base for the hash table. The intent is that once the total_abbrev_count across all the entries is greater than 10*current_table_entry_count one should build a new Dwarf_Hash_Table_Base_s, rehash - all the existing entries, and delete the old table and entries. + all the existing entries, and delete the old table and entries. (10 is a heuristic, nothing magic about it, but once the count gets to 30 or 40 times current_table_entry_count things really slow down a lot. One (500MB) application had @@ -272,15 +407,15 @@ struct Dwarf_Hash_Table_Entry_s; increase linearly so the hashing is perfect always. */ struct Dwarf_Hash_Table_s { - unsigned long tb_table_entry_count; - unsigned long tb_total_abbrev_count; - /* Each table entry is a list of abbreviations. */ - struct Dwarf_Hash_Table_Entry_s *tb_entries; + unsigned long tb_table_entry_count; + unsigned long tb_total_abbrev_count; + /* Each table entry is a list of abbreviations. */ + struct Dwarf_Hash_Table_Entry_s *tb_entries; }; /* This struct is used to build a hash table for the - abbreviation codes for a compile-unit. + abbreviation codes for a compile-unit. */ struct Dwarf_Hash_Table_Entry_s { Dwarf_Abbrev_List at_head; @@ -288,24 +423,80 @@ struct Dwarf_Hash_Table_Entry_s { -Dwarf_Abbrev_List -_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, - Dwarf_Unsigned code); +int _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, + Dwarf_Unsigned code, + Dwarf_Abbrev_List *list_out,Dwarf_Error *error); /* return 1 if string ends before 'endptr' else ** return 0 meaning string is not properly terminated. ** Presumption is the 'endptr' pts to end of some dwarf section data. */ -int _dwarf_string_valid(void *startptr, void *endptr); +int _dwarf_check_string_valid(Dwarf_Debug dbg,void *areaptr, + 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, + Dwarf_Unsigned *area_length_out, + Dwarf_Error *error); -Dwarf_Unsigned _dwarf_length_of_cu_header(Dwarf_Debug, - Dwarf_Unsigned offset); -Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug); +Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug,Dwarf_Bool dinfo); int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error); +int _dwarf_load_debug_types(Dwarf_Debug dbg, Dwarf_Error *error); void _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg, struct Dwarf_Hash_Table_s* hash_table); int _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die); +int _dwarf_reference_outside_section(Dwarf_Die die, + Dwarf_Small * startaddr, + Dwarf_Small * pastend); +void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, + Dwarf_Debug dbgt,Dwarf_Error *errt); + +int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out, + const char **comp_name_out, + Dwarf_Error *error); + +int _dwarf_what_section_are_we(Dwarf_Debug dbg, + Dwarf_Small *our_pointer, + const char ** section_name_out, + Dwarf_Small **sec_start_ptr_out, + Dwarf_Unsigned *sec_len_out, + Dwarf_Small **sec_end_ptr_out, + Dwarf_Error *error); + +/* wrappers return either DW_DLV_OK or DW_DLV_ERROR. + Never DW_DLV_NO_ENTRY. */ +int +_dwarf_read_unaligned_ck_wrapper(Dwarf_Debug dbg, + Dwarf_Unsigned *out_value, + Dwarf_Small *readfrom, + int readlength, + Dwarf_Small *end_arange, + Dwarf_Error *err); +int +_dwarf_read_area_length_ck_wrapper(Dwarf_Debug dbg, + Dwarf_Unsigned *out_value, + Dwarf_Small **readfrom, + int * length_size_out, + int * exten_size_out, + Dwarf_Unsigned sectionlength, + Dwarf_Small *endsection, + Dwarf_Error *err); +int +_dwarf_leb128_uword_wrapper(Dwarf_Debug dbg, + Dwarf_Small ** startptr, + Dwarf_Small * endptr, + Dwarf_Unsigned *out_value, + Dwarf_Error * error); +int +_dwarf_leb128_sword_wrapper(Dwarf_Debug dbg, + Dwarf_Small ** startptr, + Dwarf_Small * endptr, + Dwarf_Signed *out_value, + Dwarf_Error * error); + + #endif /* DWARF_UTIL_H */ |