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 */
dwarf_get_harmless_error_list(Dwarf_Debug dbg,unsigned count,const char ** errmsg_ptrs_array,unsigned * errs_count)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
safe_strncpy(char * targ,char * src,unsigned spaceavail)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. */
dwarf_insert_harmless_error(Dwarf_Debug dbg,char * newerror)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 */
dwarf_set_harmless_error_list_size(Dwarf_Debug dbg,unsigned maxcount)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
dwarf_harmless_init(struct Dwarf_Harmless_s * dhp,unsigned size)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
dwarf_harmless_cleanout(struct Dwarf_Harmless_s * dhp)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