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