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