xref: /titanic_51/usr/src/lib/libdwarf/common/dwarf_harmless.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
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