1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2010 David Anderson. All Rights Reserved. 4*7fd79137SRobert Mustacchi 5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 7*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 8*7fd79137SRobert Mustacchi 9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12*7fd79137SRobert Mustacchi 13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 18*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 19*7fd79137SRobert Mustacchi 20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23*7fd79137SRobert Mustacchi USA. 24*7fd79137SRobert Mustacchi 25*7fd79137SRobert Mustacchi */ 26*7fd79137SRobert Mustacchi 27*7fd79137SRobert Mustacchi /* 28*7fd79137SRobert Mustacchi This implements _dwarf_insert_harmless_error 29*7fd79137SRobert Mustacchi and related helper functions for recording 30*7fd79137SRobert Mustacchi compiler errors that need not make the input 31*7fd79137SRobert Mustacchi unusable. 32*7fd79137SRobert Mustacchi 33*7fd79137SRobert Mustacchi Applications can use dwarf_get_harmless_error_list to 34*7fd79137SRobert Mustacchi find (and possibly print) a warning about such errors. 35*7fd79137SRobert Mustacchi 36*7fd79137SRobert Mustacchi The initial error reported here is 37*7fd79137SRobert Mustacchi DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE which was a 38*7fd79137SRobert Mustacchi bug in a specific compiler. 39*7fd79137SRobert Mustacchi 40*7fd79137SRobert Mustacchi It is a fixed length circular list to constrain 41*7fd79137SRobert Mustacchi the space used for errors. 42*7fd79137SRobert Mustacchi 43*7fd79137SRobert Mustacchi The assumption is that these errors are exceedingly 44*7fd79137SRobert Mustacchi rare, and indicate a broken compiler (the one that 45*7fd79137SRobert Mustacchi produced the object getting the error(s)). 46*7fd79137SRobert Mustacchi 47*7fd79137SRobert Mustacchi dh_maxcount is recorded internally as 1 greater than 48*7fd79137SRobert Mustacchi requested. Hiding the fact we always leave one 49*7fd79137SRobert Mustacchi slot unused (at least). So a user request for 50*7fd79137SRobert Mustacchi N slots really gives the user N usable slots. 51*7fd79137SRobert Mustacchi */ 52*7fd79137SRobert Mustacchi 53*7fd79137SRobert Mustacchi 54*7fd79137SRobert Mustacchi 55*7fd79137SRobert Mustacchi #include "config.h" 56*7fd79137SRobert Mustacchi #include "dwarf_incl.h" 57*7fd79137SRobert Mustacchi #include <stdio.h> 58*7fd79137SRobert Mustacchi #include <stdlib.h> 59*7fd79137SRobert Mustacchi #include "dwarf_frame.h" 60*7fd79137SRobert Mustacchi #include "dwarf_harmless.h" 61*7fd79137SRobert Mustacchi 62*7fd79137SRobert Mustacchi 63*7fd79137SRobert Mustacchi /* The pointers returned here through errmsg_ptrs_array 64*7fd79137SRobert Mustacchi become invalidated by any call to libdwarf. Any call. 65*7fd79137SRobert Mustacchi */ 66*7fd79137SRobert Mustacchi int dwarf_get_harmless_error_list(Dwarf_Debug dbg, 67*7fd79137SRobert Mustacchi unsigned count, 68*7fd79137SRobert Mustacchi const char ** errmsg_ptrs_array, 69*7fd79137SRobert Mustacchi unsigned * errs_count) 70*7fd79137SRobert Mustacchi { 71*7fd79137SRobert Mustacchi struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; 72*7fd79137SRobert Mustacchi if(!dhp->dh_errors) { 73*7fd79137SRobert Mustacchi dhp->dh_errs_count = 0; 74*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 75*7fd79137SRobert Mustacchi } 76*7fd79137SRobert Mustacchi if(dhp->dh_errs_count == 0) { 77*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 78*7fd79137SRobert Mustacchi } 79*7fd79137SRobert Mustacchi if(errs_count) { 80*7fd79137SRobert Mustacchi *errs_count = dhp->dh_errs_count; 81*7fd79137SRobert Mustacchi } 82*7fd79137SRobert Mustacchi if(count) { 83*7fd79137SRobert Mustacchi /* NULL terminate the array of pointers */ 84*7fd79137SRobert Mustacchi --count; 85*7fd79137SRobert Mustacchi errmsg_ptrs_array[count] = 0; 86*7fd79137SRobert Mustacchi 87*7fd79137SRobert Mustacchi if(dhp->dh_next_to_use != dhp->dh_first) { 88*7fd79137SRobert Mustacchi unsigned i = 0; 89*7fd79137SRobert Mustacchi unsigned cur = dhp->dh_first; 90*7fd79137SRobert Mustacchi for(i = 0; cur != dhp->dh_next_to_use; ++i) { 91*7fd79137SRobert Mustacchi if(i >= count ) { 92*7fd79137SRobert Mustacchi /* All output spaces are used. */ 93*7fd79137SRobert Mustacchi break; 94*7fd79137SRobert Mustacchi } 95*7fd79137SRobert Mustacchi errmsg_ptrs_array[i] = dhp->dh_errors[cur]; 96*7fd79137SRobert Mustacchi cur = (cur +1) % dhp->dh_maxcount; 97*7fd79137SRobert Mustacchi } 98*7fd79137SRobert Mustacchi errmsg_ptrs_array[i] = 0; 99*7fd79137SRobert Mustacchi } 100*7fd79137SRobert Mustacchi } 101*7fd79137SRobert Mustacchi dhp->dh_next_to_use = 0; 102*7fd79137SRobert Mustacchi dhp->dh_first = 0; 103*7fd79137SRobert Mustacchi dhp->dh_errs_count = 0; 104*7fd79137SRobert Mustacchi return DW_DLV_OK; 105*7fd79137SRobert Mustacchi } 106*7fd79137SRobert Mustacchi 107*7fd79137SRobert Mustacchi /* strncpy does not null-terminate, this does it. */ 108*7fd79137SRobert Mustacchi static void 109*7fd79137SRobert Mustacchi safe_strncpy(char *targ, char *src, unsigned spaceavail) 110*7fd79137SRobert Mustacchi { 111*7fd79137SRobert Mustacchi unsigned goodcount = spaceavail-1; 112*7fd79137SRobert Mustacchi if(spaceavail < 1) { 113*7fd79137SRobert Mustacchi return; /* impossible */ 114*7fd79137SRobert Mustacchi } 115*7fd79137SRobert Mustacchi strncpy(targ,src,goodcount); 116*7fd79137SRobert Mustacchi targ[goodcount] = 0; 117*7fd79137SRobert Mustacchi } 118*7fd79137SRobert Mustacchi 119*7fd79137SRobert Mustacchi /* Insertion made public is only for testing the harmless error code, 120*7fd79137SRobert Mustacchi it is not necessarily useful for libdwarf client code aside 121*7fd79137SRobert Mustacchi from code testing libdwarf. */ 122*7fd79137SRobert Mustacchi void dwarf_insert_harmless_error(Dwarf_Debug dbg, 123*7fd79137SRobert Mustacchi char *newerror) 124*7fd79137SRobert Mustacchi { 125*7fd79137SRobert Mustacchi struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; 126*7fd79137SRobert Mustacchi unsigned next = 0; 127*7fd79137SRobert Mustacchi unsigned cur = dhp->dh_next_to_use; 128*7fd79137SRobert Mustacchi char *msgspace; 129*7fd79137SRobert Mustacchi if(!dhp->dh_errors) { 130*7fd79137SRobert Mustacchi dhp->dh_errs_count++; 131*7fd79137SRobert Mustacchi return; 132*7fd79137SRobert Mustacchi } 133*7fd79137SRobert Mustacchi msgspace = dhp->dh_errors[cur]; 134*7fd79137SRobert Mustacchi safe_strncpy(msgspace, newerror,DW_HARMLESS_ERROR_MSG_STRING_SIZE); 135*7fd79137SRobert Mustacchi next = (cur+1) % dhp->dh_maxcount; 136*7fd79137SRobert Mustacchi dhp->dh_errs_count++; 137*7fd79137SRobert Mustacchi dhp->dh_next_to_use = next; 138*7fd79137SRobert Mustacchi if (dhp->dh_next_to_use == dhp->dh_first) { 139*7fd79137SRobert Mustacchi /* Array is full set full invariant. */ 140*7fd79137SRobert Mustacchi dhp->dh_first = (dhp->dh_first+1) % dhp->dh_maxcount; 141*7fd79137SRobert Mustacchi } 142*7fd79137SRobert Mustacchi } 143*7fd79137SRobert Mustacchi 144*7fd79137SRobert Mustacchi /* The size of the circular list of strings may be set 145*7fd79137SRobert Mustacchi and reset as desired. Returns the previous size of 146*7fd79137SRobert Mustacchi the list. If the list is shortened excess error entries 147*7fd79137SRobert Mustacchi are simply dropped. 148*7fd79137SRobert Mustacchi If the reallocation fails the list size is left unchanged. 149*7fd79137SRobert Mustacchi Do not make this a long list! 150*7fd79137SRobert Mustacchi 151*7fd79137SRobert Mustacchi Remember the maxcount we record is 1 > the user count, 152*7fd79137SRobert Mustacchi so we adjust it so it looks like the user count. 153*7fd79137SRobert Mustacchi */ 154*7fd79137SRobert Mustacchi unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg, 155*7fd79137SRobert Mustacchi unsigned maxcount ) 156*7fd79137SRobert Mustacchi { 157*7fd79137SRobert Mustacchi struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; 158*7fd79137SRobert Mustacchi unsigned prevcount = dhp->dh_maxcount; 159*7fd79137SRobert Mustacchi if(maxcount != 0) { 160*7fd79137SRobert Mustacchi ++maxcount; 161*7fd79137SRobert Mustacchi if(maxcount != dhp->dh_maxcount) { 162*7fd79137SRobert Mustacchi /* Assign transfers 'ownership' of the malloc areas 163*7fd79137SRobert Mustacchi to oldarray. */ 164*7fd79137SRobert Mustacchi struct Dwarf_Harmless_s oldarray = *dhp; 165*7fd79137SRobert Mustacchi /* Do not double increment the max, the init() func 166*7fd79137SRobert Mustacchi increments it too. */ 167*7fd79137SRobert Mustacchi dwarf_harmless_init(dhp,maxcount-1); 168*7fd79137SRobert Mustacchi if(oldarray.dh_next_to_use != oldarray.dh_first) { 169*7fd79137SRobert Mustacchi unsigned i = 0; 170*7fd79137SRobert Mustacchi for(i = oldarray.dh_first; i != oldarray.dh_next_to_use; 171*7fd79137SRobert Mustacchi i = (i+1)%oldarray.dh_maxcount) { 172*7fd79137SRobert Mustacchi dwarf_insert_harmless_error(dbg,oldarray.dh_errors[i]); 173*7fd79137SRobert Mustacchi } 174*7fd79137SRobert Mustacchi if( oldarray.dh_errs_count > dhp->dh_errs_count) { 175*7fd79137SRobert Mustacchi dhp->dh_errs_count = oldarray.dh_errs_count; 176*7fd79137SRobert Mustacchi } 177*7fd79137SRobert Mustacchi } 178*7fd79137SRobert Mustacchi dwarf_harmless_cleanout(&oldarray); 179*7fd79137SRobert Mustacchi } 180*7fd79137SRobert Mustacchi } 181*7fd79137SRobert Mustacchi return prevcount-1; 182*7fd79137SRobert Mustacchi } 183*7fd79137SRobert Mustacchi 184*7fd79137SRobert Mustacchi void 185*7fd79137SRobert Mustacchi dwarf_harmless_init(struct Dwarf_Harmless_s *dhp,unsigned size) 186*7fd79137SRobert Mustacchi { 187*7fd79137SRobert Mustacchi unsigned i = 0; 188*7fd79137SRobert Mustacchi memset(dhp,0,sizeof(*dhp)); 189*7fd79137SRobert Mustacchi dhp->dh_maxcount = size +1; 190*7fd79137SRobert Mustacchi dhp->dh_errors = (char **)malloc(sizeof( char *) *dhp->dh_maxcount); 191*7fd79137SRobert Mustacchi if (!dhp->dh_errors) { 192*7fd79137SRobert Mustacchi dhp->dh_maxcount = 0; 193*7fd79137SRobert Mustacchi return; 194*7fd79137SRobert Mustacchi } 195*7fd79137SRobert Mustacchi 196*7fd79137SRobert Mustacchi for(i = 0; i < dhp->dh_maxcount; ++i) { 197*7fd79137SRobert Mustacchi char *newstr = 198*7fd79137SRobert Mustacchi (char *)malloc(DW_HARMLESS_ERROR_MSG_STRING_SIZE); 199*7fd79137SRobert Mustacchi dhp->dh_errors[i] = newstr; 200*7fd79137SRobert Mustacchi if(!newstr) { 201*7fd79137SRobert Mustacchi dhp->dh_maxcount = 0; 202*7fd79137SRobert Mustacchi /* Let it leak, the leak is a constrained amount. */ 203*7fd79137SRobert Mustacchi dhp->dh_errors = 0; 204*7fd79137SRobert Mustacchi return; 205*7fd79137SRobert Mustacchi } 206*7fd79137SRobert Mustacchi /* We make the string content well-defined by an initial 207*7fd79137SRobert Mustacchi NUL byte, but this is not really necessary. */ 208*7fd79137SRobert Mustacchi newstr[0] = 0; 209*7fd79137SRobert Mustacchi } 210*7fd79137SRobert Mustacchi } 211*7fd79137SRobert Mustacchi 212*7fd79137SRobert Mustacchi void 213*7fd79137SRobert Mustacchi dwarf_harmless_cleanout(struct Dwarf_Harmless_s *dhp) 214*7fd79137SRobert Mustacchi { 215*7fd79137SRobert Mustacchi unsigned i = 0; 216*7fd79137SRobert Mustacchi if(!dhp->dh_errors) { 217*7fd79137SRobert Mustacchi return; 218*7fd79137SRobert Mustacchi } 219*7fd79137SRobert Mustacchi for(i = 0; i < dhp->dh_maxcount; ++i) { 220*7fd79137SRobert Mustacchi free(dhp->dh_errors[i]); 221*7fd79137SRobert Mustacchi } 222*7fd79137SRobert Mustacchi free(dhp->dh_errors); 223*7fd79137SRobert Mustacchi dhp->dh_errors = 0; 224*7fd79137SRobert Mustacchi dhp->dh_maxcount = 0; 225*7fd79137SRobert Mustacchi } 226*7fd79137SRobert Mustacchi 227