diff options
Diffstat (limited to 'usr/src/lib/libdwarf/common/dwarf_macro.c')
-rw-r--r-- | usr/src/lib/libdwarf/common/dwarf_macro.c | 231 |
1 files changed, 122 insertions, 109 deletions
diff --git a/usr/src/lib/libdwarf/common/dwarf_macro.c b/usr/src/lib/libdwarf/common/dwarf_macro.c index e1ff976d8c..5031c1e32b 100644 --- a/usr/src/lib/libdwarf/common/dwarf_macro.c +++ b/usr/src/lib/libdwarf/common/dwarf_macro.c @@ -1,54 +1,40 @@ /* - Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. - Portions Copyright (C) 2007-2010 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 + 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. + 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 + 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. + 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 + 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. */ - - - #include "config.h" -#include "dwarf_incl.h" #include <stdio.h> #include <limits.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif /* HAVE_STDLIB_H */ +#include "dwarf_incl.h" +#include "dwarf_alloc.h" +#include "dwarf_error.h" +#include "dwarf_util.h" #include "dwarf_macro.h" @@ -56,12 +42,11 @@ #define RIGHTPAREN ')' #define SPACE ' ' -/* - Given the dwarf macro string, return a pointer to - the value. Returns pointer to 0 byte at end of string - if no value found (meaning the value is the empty string). +/* Given the dwarf macro string, return a pointer to + the value. Returns pointer to 0 byte at end of string + if no value found (meaning the value is the empty string). - Only understands well-formed dwarf macinfo strings. + Only understands well-formed dwarf macinfo strings. */ char * dwarf_find_macro_value_start(char *str) @@ -78,16 +63,16 @@ dwarf_find_macro_value_start(char *str) /* lcp+1 must be a space, and following char is the value */ return lcp + 2; case SPACE: - /* we allow extraneous spaces inside macro parameter ** - list, just in case... This is not really needed. */ + /* We allow extraneous spaces inside macro parameter ** + list, just in case... This is not really needed. */ if (!funclike) { return lcp + 1; } break; } } - /* never found value: returns pointer to the 0 byte at end of - string */ + /* Never found value: returns pointer to the 0 byte at end of + string. */ return lcp; } @@ -103,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); @@ -121,64 +106,67 @@ 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_get_alloc(dbg, DW_DLA_STRING, - new_size * sizeof(Dwarf_Signed)); - if (newbase == 0) { + (Dwarf_Signed *)_dwarf_get_alloc(dbg, DW_DLA_STRING, + new_size * sizeof(Dwarf_Signed)); + 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) { + 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; } -/* starting at macro_offset in .debug_macinfo, - if maximum_count is 0, treat as if it is infinite. - get macro data up thru - maximum_count entries or the end of a compilation - unit's entries (whichever comes first). +/* Starting at macro_offset in .debug_macinfo, + if maximum_count is 0, treat as if it is infinite. + get macro data up thru + maximum_count entries or the end of a compilation + unit's entries (whichever comes first). + + .debug_macinfo never appears in a .dwp Package File. + So offset adjustment for such is not needed. */ int @@ -190,10 +178,11 @@ dwarf_get_macro_details(Dwarf_Debug dbg, Dwarf_Error * error) { Dwarf_Small *macro_base = 0; + Dwarf_Small *macro_end = 0; Dwarf_Small *pnext = 0; Dwarf_Unsigned endloc = 0; unsigned char uc = 0; - unsigned long depth = 0; + unsigned long depth = 0; /* By section 6.3.2 Dwarf3 draft 8/9, the base file should appear as DW_MACINFO_start_file. See @@ -231,6 +220,10 @@ dwarf_get_macro_details(Dwarf_Debug dbg, free_macro_stack(dbg,&msdata); return res; } + if (!dbg->de_debug_abbrev.dss_size) { + free_macro_stack(dbg,&msdata); + return (DW_DLV_NO_ENTRY); + } macro_base = dbg->de_debug_macinfo.dss_data; if (macro_base == NULL) { @@ -241,6 +234,8 @@ dwarf_get_macro_details(Dwarf_Debug dbg, free_macro_stack(dbg,&msdata); return (DW_DLV_NO_ENTRY); } + macro_end = macro_base + dbg->de_debug_macinfo.dss_size; + /* FIXME debugfission is NOT handled here. */ pnext = macro_base + macro_offset; if (maximum_count == 0) { @@ -262,8 +257,10 @@ dwarf_get_macro_details(Dwarf_Debug dbg, return (DW_DLV_ERROR); } for (count = 0; !done && count < max_count; ++count) { - unsigned long slen; - Dwarf_Word len; + unsigned long slen = 0; + + /* Set but not used */ + UNUSEDARG Dwarf_Unsigned utemp = 0; uc = *pnext; ++pnext; /* get past the type code */ @@ -273,18 +270,25 @@ dwarf_get_macro_details(Dwarf_Debug dbg, /* line, string */ case DW_MACINFO_vendor_ext: /* number, string */ - (void) _dwarf_decode_u_leb128(pnext, &len); - - pnext += len; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, + macro_end); + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } + res = _dwarf_check_string_valid(dbg, + macro_base,pnext,macro_end, + DW_DLE_MACINFO_STRING_BAD,error); + if (res != DW_DLV_OK) { + return res; + } slen = strlen((char *) pnext) + 1; pnext += slen; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); @@ -294,17 +298,19 @@ dwarf_get_macro_details(Dwarf_Debug dbg, break; case DW_MACINFO_start_file: /* line, file index */ - (void) _dwarf_decode_u_leb128(pnext, &len); - pnext += len; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, + macro_end); + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } - (void) _dwarf_decode_u_leb128(pnext, &len); - pnext += len; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + DECODE_LEB128_UWORD_CK(pnext,utemp,dbg,error, + macro_end); + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); @@ -315,10 +321,11 @@ dwarf_get_macro_details(Dwarf_Debug dbg, case DW_MACINFO_end_file: if (--depth == 0) { - /* done = 1; no, do not stop here, at least one gcc had - the wrong depth settings in the gcc 3.4 timeframe. */ + /* done = 1; no, do not stop here, at least one gcc had + the wrong depth settings in the gcc 3.4 timeframe. */ } - break; /* no string or number here */ + /* no string or number here */ + break; case 0: /* end of cu's entries */ done = 1; @@ -339,21 +346,18 @@ 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); /* extra 2 not really needed */ space_needed = string_offset + str_space + 2; return_data = pdata = - _dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed); + (Dwarf_Small *)_dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed); latest_str_loc = pdata + string_offset; if (pdata == 0) { free_macro_stack(dbg,&msdata); @@ -367,9 +371,8 @@ dwarf_get_macro_details(Dwarf_Debug dbg, /* A series ends with a type code of 0. */ for (final_count = 0; !done && final_count < count; ++final_count) { - unsigned long slen; - Dwarf_Word len; - Dwarf_Unsigned v1; + unsigned long slen = 0; + Dwarf_Unsigned v1 = 0; Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata + (final_count * sizeof (Dwarf_Macro_Details))); @@ -392,23 +395,31 @@ dwarf_get_macro_details(Dwarf_Debug dbg, /* line, string */ case DW_MACINFO_vendor_ext: /* number, string */ - v1 = _dwarf_decode_u_leb128(pnext, &len); + DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, + macro_end); pdmd->dmd_lineno = v1; - pnext += len; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } + res = _dwarf_check_string_valid(dbg, + macro_base,pnext,macro_end, + DW_DLE_MACINFO_STRING_BAD,error); + if (res != DW_DLV_OK) { + return res; + } slen = strlen((char *) pnext) + 1; strcpy((char *) latest_str_loc, (char *) pnext); pdmd->dmd_macro = (char *) latest_str_loc; latest_str_loc += slen; pnext += slen; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, @@ -418,25 +429,27 @@ dwarf_get_macro_details(Dwarf_Debug dbg, break; case DW_MACINFO_start_file: /* Line, file index */ - v1 = _dwarf_decode_u_leb128(pnext, &len); + DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, + macro_end); pdmd->dmd_lineno = v1; - pnext += len; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT); return (DW_DLV_ERROR); } - v1 = _dwarf_decode_u_leb128(pnext, &len); + DECODE_LEB128_UWORD_CK(pnext,v1,dbg,error, + macro_end); pdmd->dmd_fileindex = v1; (void) _dwarf_macro_stack_push_index(dbg, fileindex, - &msdata); - /* We ignore the error, we just let fileindex ** be -1 when - we pop this one. */ + &msdata); + /* We ignore the error, we just let fileindex ** be -1 when + we pop this one. */ fileindex = v1; - pnext += len; - if (((pnext - macro_base)) >= dbg->de_debug_macinfo.dss_size) { + if (((Dwarf_Unsigned)(pnext - macro_base)) >= + dbg->de_debug_macinfo.dss_size) { free_macro_stack(dbg,&msdata); dwarf_dealloc(dbg, return_data, DW_DLA_STRING); _dwarf_error(dbg, error, |