1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright (c) 2019-2020, David Anderson
3*4d9fdb46SRobert Mustacchi All rights reserved.
4*4d9fdb46SRobert Mustacchi 
5*4d9fdb46SRobert Mustacchi Redistribution and use in source and binary forms, with
6*4d9fdb46SRobert Mustacchi or without modification, are permitted provided that the
7*4d9fdb46SRobert Mustacchi following conditions are met:
8*4d9fdb46SRobert Mustacchi 
9*4d9fdb46SRobert Mustacchi     Redistributions of source code must retain the above
10*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
11*4d9fdb46SRobert Mustacchi     disclaimer.
12*4d9fdb46SRobert Mustacchi 
13*4d9fdb46SRobert Mustacchi     Redistributions in binary form must reproduce the above
14*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
15*4d9fdb46SRobert Mustacchi     disclaimer in the documentation and/or other materials
16*4d9fdb46SRobert Mustacchi     provided with the distribution.
17*4d9fdb46SRobert Mustacchi 
18*4d9fdb46SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19*4d9fdb46SRobert Mustacchi CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*4d9fdb46SRobert Mustacchi INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*4d9fdb46SRobert Mustacchi OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*4d9fdb46SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23*4d9fdb46SRobert Mustacchi CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*4d9fdb46SRobert Mustacchi SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*4d9fdb46SRobert Mustacchi NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*4d9fdb46SRobert Mustacchi LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4d9fdb46SRobert Mustacchi HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*4d9fdb46SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*4d9fdb46SRobert Mustacchi OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*4d9fdb46SRobert Mustacchi EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
31*4d9fdb46SRobert Mustacchi 
32*4d9fdb46SRobert Mustacchi #include "config.h"
33*4d9fdb46SRobert Mustacchi #include <stdio.h>
34*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
35*4d9fdb46SRobert Mustacchi #include <malloc.h>
36*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
37*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDDEF_H
38*4d9fdb46SRobert Mustacchi #include <stddef.h> /* ptrdiff_t */
39*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDDEF_H */
40*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
41*4d9fdb46SRobert Mustacchi #include <stdlib.h>
42*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
43*4d9fdb46SRobert Mustacchi #include <string.h>
44*4d9fdb46SRobert Mustacchi #ifdef HAVE_ELF_H
45*4d9fdb46SRobert Mustacchi #include <elf.h>
46*4d9fdb46SRobert Mustacchi #endif /* HAVE_ELF_H */
47*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNISTD_H
48*4d9fdb46SRobert Mustacchi #include <unistd.h> /* getcwd */
49*4d9fdb46SRobert Mustacchi #endif /* HAVE_UNISTD_H */
50*4d9fdb46SRobert Mustacchi #if 0
51*4d9fdb46SRobert Mustacchi #include <sys/types.h> /* for open() */
52*4d9fdb46SRobert Mustacchi #include <sys/stat.h> /* for open() */
53*4d9fdb46SRobert Mustacchi #include <fcntl.h> /* for open() */
54*4d9fdb46SRobert Mustacchi #include <errno.h>
55*4d9fdb46SRobert Mustacchi #endif
56*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
57*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
58*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
59*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
60*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
61*4d9fdb46SRobert Mustacchi #include "dwarf_debuglink.h"
62*4d9fdb46SRobert Mustacchi 
63*4d9fdb46SRobert Mustacchi #ifndef O_BINARY
64*4d9fdb46SRobert Mustacchi #define O_BINARY 0
65*4d9fdb46SRobert Mustacchi #endif /* O_BINARY */
66*4d9fdb46SRobert Mustacchi 
67*4d9fdb46SRobert Mustacchi #define MINBUFLEN 1000
68*4d9fdb46SRobert Mustacchi #define TRUE  1
69*4d9fdb46SRobert Mustacchi #define FALSE 0
70*4d9fdb46SRobert Mustacchi 
71*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNUSED_ATTRIBUTE
72*4d9fdb46SRobert Mustacchi #define  UNUSEDARG __attribute__ ((unused))
73*4d9fdb46SRobert Mustacchi #else
74*4d9fdb46SRobert Mustacchi #define  UNUSEDARG
75*4d9fdb46SRobert Mustacchi #endif
76*4d9fdb46SRobert Mustacchi 
77*4d9fdb46SRobert Mustacchi 
78*4d9fdb46SRobert Mustacchi #if _WIN32
79*4d9fdb46SRobert Mustacchi #define NULL_DEVICE_NAME "NUL"
80*4d9fdb46SRobert Mustacchi #else
81*4d9fdb46SRobert Mustacchi #define NULL_DEVICE_NAME "/dev/null"
82*4d9fdb46SRobert Mustacchi #endif /* _WIN32 */
83*4d9fdb46SRobert Mustacchi 
84*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
85*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s)                         \
86*4d9fdb46SRobert Mustacchi     do {                                        \
87*4d9fdb46SRobert Mustacchi         unsigned tbyte = sizeof(t) - sizeof(s); \
88*4d9fdb46SRobert Mustacchi         t = 0;                                  \
89*4d9fdb46SRobert Mustacchi         func(((char *)&t)+tbyte ,&s[0],sizeof(s));  \
90*4d9fdb46SRobert Mustacchi     } while (0)
91*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
92*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s)                         \
93*4d9fdb46SRobert Mustacchi     do {                                        \
94*4d9fdb46SRobert Mustacchi         t = 0;                                  \
95*4d9fdb46SRobert Mustacchi         func(&t,&s[0],sizeof(s));               \
96*4d9fdb46SRobert Mustacchi     } while (0)
97*4d9fdb46SRobert Mustacchi #endif /* end LITTLE- BIG-ENDIAN */
98*4d9fdb46SRobert Mustacchi 
99*4d9fdb46SRobert Mustacchi static int
100*4d9fdb46SRobert Mustacchi extract_buildid(Dwarf_Debug dbg,
101*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s * pbuildid,
102*4d9fdb46SRobert Mustacchi     unsigned        *type_returned,
103*4d9fdb46SRobert Mustacchi     char           **owner_name_returned,
104*4d9fdb46SRobert Mustacchi     unsigned char  **build_id_returned,
105*4d9fdb46SRobert Mustacchi     unsigned        *build_id_length_returned,
106*4d9fdb46SRobert Mustacchi     Dwarf_Error *error);
107*4d9fdb46SRobert Mustacchi 
108*4d9fdb46SRobert Mustacchi struct joins_s {
109*4d9fdb46SRobert Mustacchi     char * js_fullpath;
110*4d9fdb46SRobert Mustacchi     dwarfstring js_dirname;
111*4d9fdb46SRobert Mustacchi     dwarfstring js_basepath;
112*4d9fdb46SRobert Mustacchi     dwarfstring js_basename;
113*4d9fdb46SRobert Mustacchi     dwarfstring js_cwd;
114*4d9fdb46SRobert Mustacchi     dwarfstring js_originalfullpath;
115*4d9fdb46SRobert Mustacchi     dwarfstring js_tmp;
116*4d9fdb46SRobert Mustacchi     dwarfstring js_tmp2;
117*4d9fdb46SRobert Mustacchi     dwarfstring js_tmpdeb;
118*4d9fdb46SRobert Mustacchi     dwarfstring js_tmp3;
119*4d9fdb46SRobert Mustacchi     dwarfstring js_buildid;
120*4d9fdb46SRobert Mustacchi     dwarfstring js_buildid_filename;
121*4d9fdb46SRobert Mustacchi };
122*4d9fdb46SRobert Mustacchi 
123*4d9fdb46SRobert Mustacchi #if 0
124*4d9fdb46SRobert Mustacchi int
125*4d9fdb46SRobert Mustacchi _dwarf_check_string_valid(
126*4d9fdb46SRobert Mustacchi     void *areaptr,
127*4d9fdb46SRobert Mustacchi     void *strptr,
128*4d9fdb46SRobert Mustacchi     void *areaendptr,
129*4d9fdb46SRobert Mustacchi     int suggested_error,
130*4d9fdb46SRobert Mustacchi     int *errcode)
131*4d9fdb46SRobert Mustacchi {
132*4d9fdb46SRobert Mustacchi     Dwarf_Small *start = areaptr;
133*4d9fdb46SRobert Mustacchi     Dwarf_Small *p = strptr;
134*4d9fdb46SRobert Mustacchi     Dwarf_Small *end = areaendptr;
135*4d9fdb46SRobert Mustacchi     ptrdiff_t diff =  0;
136*4d9fdb46SRobert Mustacchi 
137*4d9fdb46SRobert Mustacchi     if (p < start) {
138*4d9fdb46SRobert Mustacchi         diff = start - p;
139*4d9fdb46SRobert Mustacchi #ifdef  TESTING
140*4d9fdb46SRobert Mustacchi         printf("Error  string start  pointer error: loc %"
141*4d9fdb46SRobert Mustacchi             DW_PR_DSs
142*4d9fdb46SRobert Mustacchi             " bytes before available area \n",(Dwarf_Signed)diff);
143*4d9fdb46SRobert Mustacchi #endif  /* TESTING */
144*4d9fdb46SRobert Mustacchi         *errcode = suggested_error;
145*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
146*4d9fdb46SRobert Mustacchi     }
147*4d9fdb46SRobert Mustacchi     if (p >= end) {
148*4d9fdb46SRobert Mustacchi         diff = p - start;
149*4d9fdb46SRobert Mustacchi #ifdef  TESTING
150*4d9fdb46SRobert Mustacchi         printf("Error  string end  pointer error, not terminated %"
151*4d9fdb46SRobert Mustacchi             " before end of area. Length:  "
152*4d9fdb46SRobert Mustacchi             DW_PR_DSs  "\n",(Dwarf_Signed)diff);
153*4d9fdb46SRobert Mustacchi #endif  /* TESTING */
154*4d9fdb46SRobert Mustacchi         *errcode = suggested_error;
155*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
156*4d9fdb46SRobert Mustacchi     }
157*4d9fdb46SRobert Mustacchi     while (p < end) {
158*4d9fdb46SRobert Mustacchi         if (*p == 0) {
159*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
160*4d9fdb46SRobert Mustacchi         }
161*4d9fdb46SRobert Mustacchi         ++p;
162*4d9fdb46SRobert Mustacchi     }
163*4d9fdb46SRobert Mustacchi     diff =  p - start;
164*4d9fdb46SRobert Mustacchi #ifdef  TESTING
165*4d9fdb46SRobert Mustacchi     printf("Error string not terminated error:  not ended after %"
166*4d9fdb46SRobert Mustacchi         DW_PR_DSs " bytes (past end of available bytes)\n",
167*4d9fdb46SRobert Mustacchi         (Dwarf_Signed)diff);
168*4d9fdb46SRobert Mustacchi #endif  /* TESTING */
169*4d9fdb46SRobert Mustacchi     *errcode = DW_DLE_STRING_NOT_TERMINATED;
170*4d9fdb46SRobert Mustacchi     return DW_DLV_ERROR;
171*4d9fdb46SRobert Mustacchi }
172*4d9fdb46SRobert Mustacchi #endif
173*4d9fdb46SRobert Mustacchi 
174*4d9fdb46SRobert Mustacchi 
175*4d9fdb46SRobert Mustacchi #if 0
176*4d9fdb46SRobert Mustacchi static int
177*4d9fdb46SRobert Mustacchi does_file_exist(char *f)
178*4d9fdb46SRobert Mustacchi {
179*4d9fdb46SRobert Mustacchi     int fd = 0;
180*4d9fdb46SRobert Mustacchi 
181*4d9fdb46SRobert Mustacchi     fd = open(f,O_RDONLY|O_BINARY);
182*4d9fdb46SRobert Mustacchi     if (fd < 0) {
183*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
184*4d9fdb46SRobert Mustacchi     }
185*4d9fdb46SRobert Mustacchi     /* Here we could derive the crc to validate the file. */
186*4d9fdb46SRobert Mustacchi     close(fd);
187*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
188*4d9fdb46SRobert Mustacchi }
189*4d9fdb46SRobert Mustacchi #endif
190*4d9fdb46SRobert Mustacchi 
191*4d9fdb46SRobert Mustacchi 
192*4d9fdb46SRobert Mustacchi static void
construct_js(struct joins_s * js)193*4d9fdb46SRobert Mustacchi construct_js(struct joins_s * js)
194*4d9fdb46SRobert Mustacchi {
195*4d9fdb46SRobert Mustacchi     memset(js,0,sizeof(struct joins_s));
196*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_basename);
197*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_dirname);
198*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_basepath);
199*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_cwd);
200*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_originalfullpath);
201*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_tmp);
202*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_tmp2);
203*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_tmpdeb);
204*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_tmp3);
205*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_buildid);
206*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&js->js_buildid_filename);
207*4d9fdb46SRobert Mustacchi }
208*4d9fdb46SRobert Mustacchi static void
destruct_js(struct joins_s * js)209*4d9fdb46SRobert Mustacchi destruct_js(struct joins_s * js)
210*4d9fdb46SRobert Mustacchi {
211*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_dirname);
212*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_basepath);
213*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_basename);
214*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_cwd);
215*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_originalfullpath);
216*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_tmp);
217*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_tmp2);
218*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_tmpdeb);
219*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_tmp3);
220*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_buildid);
221*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&js->js_buildid_filename);
222*4d9fdb46SRobert Mustacchi }
223*4d9fdb46SRobert Mustacchi 
224*4d9fdb46SRobert Mustacchi static char joinchar = '/';
225*4d9fdb46SRobert Mustacchi static char* joinstr = "/";
226*4d9fdb46SRobert Mustacchi 
227*4d9fdb46SRobert Mustacchi int
_dwarf_pathjoinl(dwarfstring * target,dwarfstring * input)228*4d9fdb46SRobert Mustacchi _dwarf_pathjoinl(dwarfstring *target,dwarfstring * input)
229*4d9fdb46SRobert Mustacchi {
230*4d9fdb46SRobert Mustacchi     char *inputs = dwarfstring_string(input);
231*4d9fdb46SRobert Mustacchi     char *targ = dwarfstring_string(target);
232*4d9fdb46SRobert Mustacchi     size_t targlen = 0;
233*4d9fdb46SRobert Mustacchi 
234*4d9fdb46SRobert Mustacchi     if (!dwarfstring_strlen(target)) {
235*4d9fdb46SRobert Mustacchi         dwarfstring_append(target,dwarfstring_string(input));
236*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
237*4d9fdb46SRobert Mustacchi     }
238*4d9fdb46SRobert Mustacchi     targlen = dwarfstring_strlen(target);
239*4d9fdb46SRobert Mustacchi     targ = dwarfstring_string(target);
240*4d9fdb46SRobert Mustacchi     if (targ[targlen-1] != joinchar) {
241*4d9fdb46SRobert Mustacchi         if (*inputs != joinchar) {
242*4d9fdb46SRobert Mustacchi             dwarfstring_append(target,joinstr);
243*4d9fdb46SRobert Mustacchi             dwarfstring_append(target,inputs);
244*4d9fdb46SRobert Mustacchi         } else {
245*4d9fdb46SRobert Mustacchi             dwarfstring_append(target,inputs);
246*4d9fdb46SRobert Mustacchi         }
247*4d9fdb46SRobert Mustacchi     } else {
248*4d9fdb46SRobert Mustacchi         if (*inputs != joinchar) {
249*4d9fdb46SRobert Mustacchi             dwarfstring_append(target,inputs);
250*4d9fdb46SRobert Mustacchi         } else {
251*4d9fdb46SRobert Mustacchi             dwarfstring_append(target,inputs+1);
252*4d9fdb46SRobert Mustacchi         }
253*4d9fdb46SRobert Mustacchi     }
254*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
255*4d9fdb46SRobert Mustacchi }
256*4d9fdb46SRobert Mustacchi /*  ASSERT: the last character in s is not a /  */
257*4d9fdb46SRobert Mustacchi static size_t
mydirlen(char * s)258*4d9fdb46SRobert Mustacchi mydirlen(char *s)
259*4d9fdb46SRobert Mustacchi {
260*4d9fdb46SRobert Mustacchi     char *cp = 0;
261*4d9fdb46SRobert Mustacchi     char *lastjoinchar = 0;
262*4d9fdb46SRobert Mustacchi     size_t count =0;
263*4d9fdb46SRobert Mustacchi 
264*4d9fdb46SRobert Mustacchi     for(cp = s ; *cp ; ++cp,++count)  {
265*4d9fdb46SRobert Mustacchi         if (*cp == joinchar) {
266*4d9fdb46SRobert Mustacchi             lastjoinchar = cp;
267*4d9fdb46SRobert Mustacchi         }
268*4d9fdb46SRobert Mustacchi     }
269*4d9fdb46SRobert Mustacchi     if (lastjoinchar) {
270*4d9fdb46SRobert Mustacchi         /* we know diff is postive in all cases */
271*4d9fdb46SRobert Mustacchi         ptrdiff_t diff =  lastjoinchar - s;
272*4d9fdb46SRobert Mustacchi         /* count the last join as mydirlen. */
273*4d9fdb46SRobert Mustacchi         return (size_t)(diff+1);
274*4d9fdb46SRobert Mustacchi     }
275*4d9fdb46SRobert Mustacchi     return 0;
276*4d9fdb46SRobert Mustacchi }
277*4d9fdb46SRobert Mustacchi 
278*4d9fdb46SRobert Mustacchi struct dwarfstring_list_s {
279*4d9fdb46SRobert Mustacchi     dwarfstring                dl_string;
280*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s *dl_next;
281*4d9fdb46SRobert Mustacchi };
282*4d9fdb46SRobert Mustacchi 
283*4d9fdb46SRobert Mustacchi static void
dwarfstring_list_constructor(struct dwarfstring_list_s * l)284*4d9fdb46SRobert Mustacchi dwarfstring_list_constructor(struct dwarfstring_list_s *l)
285*4d9fdb46SRobert Mustacchi {
286*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&l->dl_string);
287*4d9fdb46SRobert Mustacchi     l->dl_next = 0;
288*4d9fdb46SRobert Mustacchi }
289*4d9fdb46SRobert Mustacchi 
290*4d9fdb46SRobert Mustacchi static int
dwarfstring_list_add_new(struct dwarfstring_list_s * base_entry,struct dwarfstring_list_s * prev,dwarfstring * input,struct dwarfstring_list_s ** new_out,int * errcode)291*4d9fdb46SRobert Mustacchi dwarfstring_list_add_new(struct dwarfstring_list_s * base_entry,
292*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s *prev,
293*4d9fdb46SRobert Mustacchi     dwarfstring * input,
294*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s ** new_out,
295*4d9fdb46SRobert Mustacchi     int *errcode)
296*4d9fdb46SRobert Mustacchi {
297*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s *next = 0;
298*4d9fdb46SRobert Mustacchi     if(prev) {
299*4d9fdb46SRobert Mustacchi         next = ( struct dwarfstring_list_s *)
300*4d9fdb46SRobert Mustacchi         malloc(sizeof(struct dwarfstring_list_s));
301*4d9fdb46SRobert Mustacchi         if (!next) {
302*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
303*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
304*4d9fdb46SRobert Mustacchi         }
305*4d9fdb46SRobert Mustacchi         dwarfstring_list_constructor(next);
306*4d9fdb46SRobert Mustacchi     } else {
307*4d9fdb46SRobert Mustacchi         next = base_entry;
308*4d9fdb46SRobert Mustacchi     }
309*4d9fdb46SRobert Mustacchi     dwarfstring_append(&next->dl_string,
310*4d9fdb46SRobert Mustacchi         dwarfstring_string(input));
311*4d9fdb46SRobert Mustacchi     if (prev) {
312*4d9fdb46SRobert Mustacchi         prev->dl_next = next;
313*4d9fdb46SRobert Mustacchi     }
314*4d9fdb46SRobert Mustacchi     *new_out = next;
315*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
316*4d9fdb46SRobert Mustacchi }
317*4d9fdb46SRobert Mustacchi 
318*4d9fdb46SRobert Mustacchi /*  destructs passed in entry (does not free it) and all
319*4d9fdb46SRobert Mustacchi     those on the dl_next list (those are freed). */
320*4d9fdb46SRobert Mustacchi static void
dwarfstring_list_destructor(struct dwarfstring_list_s * l)321*4d9fdb46SRobert Mustacchi dwarfstring_list_destructor(struct dwarfstring_list_s *l)
322*4d9fdb46SRobert Mustacchi {
323*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s *curl = l;
324*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s *nextl = l;
325*4d9fdb46SRobert Mustacchi 
326*4d9fdb46SRobert Mustacchi     nextl = curl->dl_next;
327*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&curl->dl_string);
328*4d9fdb46SRobert Mustacchi     curl->dl_next = 0;
329*4d9fdb46SRobert Mustacchi     curl = nextl;
330*4d9fdb46SRobert Mustacchi     for( ; curl ; curl = nextl) {
331*4d9fdb46SRobert Mustacchi         nextl = curl->dl_next;
332*4d9fdb46SRobert Mustacchi         dwarfstring_destructor(&curl->dl_string);
333*4d9fdb46SRobert Mustacchi         curl->dl_next = 0;
334*4d9fdb46SRobert Mustacchi         free(curl);
335*4d9fdb46SRobert Mustacchi     }
336*4d9fdb46SRobert Mustacchi }
337*4d9fdb46SRobert Mustacchi 
338*4d9fdb46SRobert Mustacchi static void
build_buildid_filename(dwarfstring * target,unsigned buildid_length,unsigned char * buildid)339*4d9fdb46SRobert Mustacchi build_buildid_filename(dwarfstring *target,
340*4d9fdb46SRobert Mustacchi     unsigned buildid_length,
341*4d9fdb46SRobert Mustacchi     unsigned char *buildid)
342*4d9fdb46SRobert Mustacchi {
343*4d9fdb46SRobert Mustacchi     dwarfstring tmp;
344*4d9fdb46SRobert Mustacchi     unsigned bu = 0;
345*4d9fdb46SRobert Mustacchi     unsigned char *cp  = 0;
346*4d9fdb46SRobert Mustacchi 
347*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&tmp);
348*4d9fdb46SRobert Mustacchi     cp = buildid;
349*4d9fdb46SRobert Mustacchi     for (bu = 0; bu < buildid_length; ++bu ,++cp) {
350*4d9fdb46SRobert Mustacchi         dwarfstring_append_printf_u(&tmp, "%02x",*cp);
351*4d9fdb46SRobert Mustacchi         if (bu == 0) {
352*4d9fdb46SRobert Mustacchi             dwarfstring_append(&tmp,"/");
353*4d9fdb46SRobert Mustacchi         }
354*4d9fdb46SRobert Mustacchi     }
355*4d9fdb46SRobert Mustacchi     dwarfstring_append(&tmp,".debug");
356*4d9fdb46SRobert Mustacchi     _dwarf_pathjoinl(target,&tmp);
357*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&tmp);
358*4d9fdb46SRobert Mustacchi     return;
359*4d9fdb46SRobert Mustacchi }
360*4d9fdb46SRobert Mustacchi 
361*4d9fdb46SRobert Mustacchi #if 0
362*4d9fdb46SRobert Mustacchi static void
363*4d9fdb46SRobert Mustacchi dump_bytes(const char *msg,unsigned char * start, unsigned len)
364*4d9fdb46SRobert Mustacchi {
365*4d9fdb46SRobert Mustacchi     Dwarf_Small *end = start + len;
366*4d9fdb46SRobert Mustacchi     Dwarf_Small *cur = start;
367*4d9fdb46SRobert Mustacchi     printf("%s (0x%lx) ",msg,(unsigned long)start);
368*4d9fdb46SRobert Mustacchi     for (; cur < end; cur++) {
369*4d9fdb46SRobert Mustacchi         printf("%02x", *cur);
370*4d9fdb46SRobert Mustacchi     }
371*4d9fdb46SRobert Mustacchi     printf("\n");
372*4d9fdb46SRobert Mustacchi }
373*4d9fdb46SRobert Mustacchi #endif
374*4d9fdb46SRobert Mustacchi 
375*4d9fdb46SRobert Mustacchi 
376*4d9fdb46SRobert Mustacchi /*  New September 2019.  Access to the GNU section named
377*4d9fdb46SRobert Mustacchi     .gnu_debuglink
378*4d9fdb46SRobert Mustacchi     See
379*4d9fdb46SRobert Mustacchi     https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
380*4d9fdb46SRobert Mustacchi 
381*4d9fdb46SRobert Mustacchi */
_dwarf_construct_linkedto_path(char ** global_prefixes_in,unsigned length_global_prefixes_in,char * pathname_in,char * link_string_in,dwarfstring * link_string_fullpath_out,UNUSEDARG unsigned char * crc_in,unsigned char * buildid,unsigned buildid_length,char *** paths_out,unsigned * paths_out_length,int * errcode)382*4d9fdb46SRobert Mustacchi int _dwarf_construct_linkedto_path(
383*4d9fdb46SRobert Mustacchi    char         **global_prefixes_in,
384*4d9fdb46SRobert Mustacchi    unsigned       length_global_prefixes_in,
385*4d9fdb46SRobert Mustacchi    char          *pathname_in,
386*4d9fdb46SRobert Mustacchi    char          *link_string_in, /* from debug link */
387*4d9fdb46SRobert Mustacchi    dwarfstring * link_string_fullpath_out,
388*4d9fdb46SRobert Mustacchi    UNUSEDARG unsigned char *crc_in, /* from debug_link, 4 bytes */
389*4d9fdb46SRobert Mustacchi    unsigned char *buildid, /* from gnu buildid */
390*4d9fdb46SRobert Mustacchi    unsigned       buildid_length, /* from gnu buildid */
391*4d9fdb46SRobert Mustacchi    char        ***paths_out,
392*4d9fdb46SRobert Mustacchi    unsigned      *paths_out_length,
393*4d9fdb46SRobert Mustacchi    int *errcode)
394*4d9fdb46SRobert Mustacchi {
395*4d9fdb46SRobert Mustacchi     char * depath = pathname_in;
396*4d9fdb46SRobert Mustacchi     int res = 0;
397*4d9fdb46SRobert Mustacchi     struct joins_s joind;
398*4d9fdb46SRobert Mustacchi     size_t dirnamelen = 0;
399*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s base_dwlist;
400*4d9fdb46SRobert Mustacchi     struct dwarfstring_list_s *last_entry = 0;
401*4d9fdb46SRobert Mustacchi     unsigned global_prefix_number = 0;
402*4d9fdb46SRobert Mustacchi 
403*4d9fdb46SRobert Mustacchi     dwarfstring_list_constructor(&base_dwlist);
404*4d9fdb46SRobert Mustacchi     construct_js(&joind);
405*4d9fdb46SRobert Mustacchi     build_buildid_filename(&joind.js_buildid_filename,
406*4d9fdb46SRobert Mustacchi         buildid_length, buildid);
407*4d9fdb46SRobert Mustacchi     dirnamelen = mydirlen(depath);
408*4d9fdb46SRobert Mustacchi     if (dirnamelen) {
409*4d9fdb46SRobert Mustacchi         dwarfstring_append_length(&joind.js_dirname,
410*4d9fdb46SRobert Mustacchi             depath,dirnamelen);
411*4d9fdb46SRobert Mustacchi     }
412*4d9fdb46SRobert Mustacchi     dwarfstring_append(&joind.js_basepath,depath+dirnamelen);
413*4d9fdb46SRobert Mustacchi     dwarfstring_append(&joind.js_basename,link_string_in);
414*4d9fdb46SRobert Mustacchi     if (depath[0] != joinchar) {
415*4d9fdb46SRobert Mustacchi         char  buffer[2000];
416*4d9fdb46SRobert Mustacchi #ifdef TESTING
417*4d9fdb46SRobert Mustacchi         buffer[0] = 0;
418*4d9fdb46SRobert Mustacchi         /*  For testing lets use a fake (consistent)
419*4d9fdb46SRobert Mustacchi             base dir.  */
420*4d9fdb46SRobert Mustacchi         strcpy(buffer,"/fake/dir/path");
421*4d9fdb46SRobert Mustacchi #else
422*4d9fdb46SRobert Mustacchi         unsigned buflen= sizeof(buffer);
423*4d9fdb46SRobert Mustacchi         char *wdret = 0;
424*4d9fdb46SRobert Mustacchi 
425*4d9fdb46SRobert Mustacchi         buffer[0] = 0;
426*4d9fdb46SRobert Mustacchi         wdret = getcwd(buffer,buflen);
427*4d9fdb46SRobert Mustacchi         if (!wdret) {
428*4d9fdb46SRobert Mustacchi             printf("getcwd() issue. Do nothing. "
429*4d9fdb46SRobert Mustacchi                 " line  %d %s\n",__LINE__,__FILE__);
430*4d9fdb46SRobert Mustacchi             dwarfstring_list_destructor(&base_dwlist);
431*4d9fdb46SRobert Mustacchi             destruct_js(&joind);
432*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
433*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
434*4d9fdb46SRobert Mustacchi         }
435*4d9fdb46SRobert Mustacchi #endif /* TESTING */
436*4d9fdb46SRobert Mustacchi         dwarfstring_append(&joind.js_cwd,buffer);
437*4d9fdb46SRobert Mustacchi         buffer[0] = 0;
438*4d9fdb46SRobert Mustacchi     }
439*4d9fdb46SRobert Mustacchi 
440*4d9fdb46SRobert Mustacchi     {
441*4d9fdb46SRobert Mustacchi         /*  Builds the full path to the original
442*4d9fdb46SRobert Mustacchi             executable, but absent executable name. */
443*4d9fdb46SRobert Mustacchi         dwarfstring_append(&joind.js_originalfullpath,
444*4d9fdb46SRobert Mustacchi             dwarfstring_string(&joind.js_cwd));
445*4d9fdb46SRobert Mustacchi         _dwarf_pathjoinl(&joind.js_originalfullpath,
446*4d9fdb46SRobert Mustacchi             &joind.js_dirname);
447*4d9fdb46SRobert Mustacchi         _dwarf_pathjoinl(&joind.js_originalfullpath,
448*4d9fdb46SRobert Mustacchi             &joind.js_basepath);
449*4d9fdb46SRobert Mustacchi #ifdef TESTING
450*4d9fdb46SRobert Mustacchi         printf("originalfullpath    : %s\n",
451*4d9fdb46SRobert Mustacchi             dwarfstring_string(&joind.js_originalfullpath));
452*4d9fdb46SRobert Mustacchi #endif
453*4d9fdb46SRobert Mustacchi     }
454*4d9fdb46SRobert Mustacchi     {
455*4d9fdb46SRobert Mustacchi         /*  There is perhaps a directory prefix in the
456*4d9fdb46SRobert Mustacchi             incoming pathname.
457*4d9fdb46SRobert Mustacchi             So we add that to js_cwd. */
458*4d9fdb46SRobert Mustacchi         res = _dwarf_pathjoinl(&joind.js_cwd,
459*4d9fdb46SRobert Mustacchi             &joind.js_dirname);
460*4d9fdb46SRobert Mustacchi         /* This is used in a couple search paths. */
461*4d9fdb46SRobert Mustacchi     }
462*4d9fdb46SRobert Mustacchi     for (global_prefix_number = 0;
463*4d9fdb46SRobert Mustacchi         buildid_length &&
464*4d9fdb46SRobert Mustacchi         (global_prefix_number < length_global_prefixes_in);
465*4d9fdb46SRobert Mustacchi         ++global_prefix_number) {
466*4d9fdb46SRobert Mustacchi         char * prefix = 0;
467*4d9fdb46SRobert Mustacchi 
468*4d9fdb46SRobert Mustacchi         prefix = global_prefixes_in[global_prefix_number];
469*4d9fdb46SRobert Mustacchi         dwarfstring_reset(&joind.js_buildid);
470*4d9fdb46SRobert Mustacchi         dwarfstring_append(&joind.js_buildid,prefix);
471*4d9fdb46SRobert Mustacchi         _dwarf_pathjoinl(&joind.js_buildid,
472*4d9fdb46SRobert Mustacchi             &joind.js_buildid_filename);
473*4d9fdb46SRobert Mustacchi         if (!strcmp(dwarfstring_string(&joind.js_originalfullpath),
474*4d9fdb46SRobert Mustacchi             dwarfstring_string(&joind.js_buildid))) {
475*4d9fdb46SRobert Mustacchi #ifdef TESTING
476*4d9fdb46SRobert Mustacchi             printf("duplicated output string %s\n",
477*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&joind.js_buildid));
478*4d9fdb46SRobert Mustacchi #endif /* TESTING */
479*4d9fdb46SRobert Mustacchi             /* duplicated name. spurious match. */
480*4d9fdb46SRobert Mustacchi         } else {
481*4d9fdb46SRobert Mustacchi             struct dwarfstring_list_s *now_last = 0;
482*4d9fdb46SRobert Mustacchi             res = dwarfstring_list_add_new(
483*4d9fdb46SRobert Mustacchi                 &base_dwlist,
484*4d9fdb46SRobert Mustacchi                 last_entry,&joind.js_buildid,
485*4d9fdb46SRobert Mustacchi                 &now_last,errcode);
486*4d9fdb46SRobert Mustacchi             if(res != DW_DLV_OK) {
487*4d9fdb46SRobert Mustacchi                 dwarfstring_list_destructor(&base_dwlist);
488*4d9fdb46SRobert Mustacchi                 destruct_js(&joind);
489*4d9fdb46SRobert Mustacchi                 return res;
490*4d9fdb46SRobert Mustacchi             }
491*4d9fdb46SRobert Mustacchi             last_entry = now_last;
492*4d9fdb46SRobert Mustacchi         }
493*4d9fdb46SRobert Mustacchi     }
494*4d9fdb46SRobert Mustacchi     if (link_string_in) {
495*4d9fdb46SRobert Mustacchi         /* js_cwd is a leading / directory name. */
496*4d9fdb46SRobert Mustacchi         {
497*4d9fdb46SRobert Mustacchi             dwarfstring_reset(&joind.js_tmp);
498*4d9fdb46SRobert Mustacchi             dwarfstring_append(&joind.js_tmp,
499*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&joind.js_cwd));
500*4d9fdb46SRobert Mustacchi             /* If we add basename do we find what we look for? */
501*4d9fdb46SRobert Mustacchi             res = _dwarf_pathjoinl(&joind.js_tmp,&joind.js_basename);
502*4d9fdb46SRobert Mustacchi             /* We return the original link as full path this way. */
503*4d9fdb46SRobert Mustacchi             dwarfstring_append(link_string_fullpath_out,
504*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&joind.js_tmp));
505*4d9fdb46SRobert Mustacchi             if (!strcmp(dwarfstring_string(&joind.js_originalfullpath),
506*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&joind.js_tmp))) {
507*4d9fdb46SRobert Mustacchi #ifdef TESTING
508*4d9fdb46SRobert Mustacchi                 printf("duplicated output string %s\n",
509*4d9fdb46SRobert Mustacchi                     dwarfstring_string(&joind.js_tmp));
510*4d9fdb46SRobert Mustacchi #endif /* TESTING */
511*4d9fdb46SRobert Mustacchi                 /* duplicated name. spurious match. */
512*4d9fdb46SRobert Mustacchi             } else if (res == DW_DLV_OK) {
513*4d9fdb46SRobert Mustacchi                 struct dwarfstring_list_s *now_last = 0;
514*4d9fdb46SRobert Mustacchi                 res = dwarfstring_list_add_new(
515*4d9fdb46SRobert Mustacchi                     &base_dwlist,
516*4d9fdb46SRobert Mustacchi                     last_entry,&joind.js_tmp,
517*4d9fdb46SRobert Mustacchi                     &now_last,errcode);
518*4d9fdb46SRobert Mustacchi                 if(res != DW_DLV_OK) {
519*4d9fdb46SRobert Mustacchi                     dwarfstring_list_destructor(&base_dwlist);
520*4d9fdb46SRobert Mustacchi                     destruct_js(&joind);
521*4d9fdb46SRobert Mustacchi                     return res;
522*4d9fdb46SRobert Mustacchi                 }
523*4d9fdb46SRobert Mustacchi                 last_entry = now_last;
524*4d9fdb46SRobert Mustacchi             }
525*4d9fdb46SRobert Mustacchi         }
526*4d9fdb46SRobert Mustacchi         {
527*4d9fdb46SRobert Mustacchi             dwarfstring_reset(&joind.js_tmp2);
528*4d9fdb46SRobert Mustacchi             dwarfstring_reset(&joind.js_tmpdeb);
529*4d9fdb46SRobert Mustacchi 
530*4d9fdb46SRobert Mustacchi             dwarfstring_append(&joind.js_tmp2,
531*4d9fdb46SRobert Mustacchi                 dwarfstring_string(&joind.js_cwd));
532*4d9fdb46SRobert Mustacchi             dwarfstring_append(&joind.js_tmpdeb,".debug");
533*4d9fdb46SRobert Mustacchi             res = _dwarf_pathjoinl(&joind.js_tmp2,&joind.js_tmpdeb);
534*4d9fdb46SRobert Mustacchi             if (res == DW_DLV_OK) {
535*4d9fdb46SRobert Mustacchi                 res = _dwarf_pathjoinl(&joind.js_tmp2,
536*4d9fdb46SRobert Mustacchi                     &joind.js_basename);
537*4d9fdb46SRobert Mustacchi                 /*  this the second search path
538*4d9fdb46SRobert Mustacchi                     after global directories
539*4d9fdb46SRobert Mustacchi                     search for nn/nnnnn....debug.   */
540*4d9fdb46SRobert Mustacchi                 if (!strcmp(dwarfstring_string(
541*4d9fdb46SRobert Mustacchi                     &joind.js_originalfullpath),
542*4d9fdb46SRobert Mustacchi                     dwarfstring_string(&joind.js_tmp2))) {
543*4d9fdb46SRobert Mustacchi #ifdef TESTING
544*4d9fdb46SRobert Mustacchi                 printf("duplicated output string %s\n",
545*4d9fdb46SRobert Mustacchi                     dwarfstring_string(&joind.js_tmp2));
546*4d9fdb46SRobert Mustacchi #endif /* TESTING */
547*4d9fdb46SRobert Mustacchi                     /* duplicated name. spurious match. */
548*4d9fdb46SRobert Mustacchi                 } else if(res == DW_DLV_OK) {
549*4d9fdb46SRobert Mustacchi                     struct dwarfstring_list_s *now_last = 0;
550*4d9fdb46SRobert Mustacchi                     res = dwarfstring_list_add_new(
551*4d9fdb46SRobert Mustacchi                         &base_dwlist,
552*4d9fdb46SRobert Mustacchi                         last_entry,&joind.js_tmp2,
553*4d9fdb46SRobert Mustacchi                         &now_last,errcode);
554*4d9fdb46SRobert Mustacchi                     if(res != DW_DLV_OK) {
555*4d9fdb46SRobert Mustacchi                         dwarfstring_list_destructor(&base_dwlist);
556*4d9fdb46SRobert Mustacchi                         destruct_js(&joind);
557*4d9fdb46SRobert Mustacchi                         return res;
558*4d9fdb46SRobert Mustacchi                     }
559*4d9fdb46SRobert Mustacchi                     last_entry = now_last;
560*4d9fdb46SRobert Mustacchi                 }
561*4d9fdb46SRobert Mustacchi             }
562*4d9fdb46SRobert Mustacchi         }
563*4d9fdb46SRobert Mustacchi         /*  Not found above, now look in the global locations. */
564*4d9fdb46SRobert Mustacchi         for (global_prefix_number = 0;
565*4d9fdb46SRobert Mustacchi             global_prefix_number < length_global_prefixes_in;
566*4d9fdb46SRobert Mustacchi             ++global_prefix_number) {
567*4d9fdb46SRobert Mustacchi             char * prefix = global_prefixes_in[global_prefix_number];
568*4d9fdb46SRobert Mustacchi 
569*4d9fdb46SRobert Mustacchi             dwarfstring_reset(&joind.js_tmp3);
570*4d9fdb46SRobert Mustacchi             dwarfstring_append(&joind.js_tmp3, prefix);
571*4d9fdb46SRobert Mustacchi             res = _dwarf_pathjoinl(&joind.js_tmp3, &joind.js_cwd);
572*4d9fdb46SRobert Mustacchi             if (res == DW_DLV_OK) {
573*4d9fdb46SRobert Mustacchi                 res = _dwarf_pathjoinl(&joind.js_tmp3,
574*4d9fdb46SRobert Mustacchi                     &joind.js_basename);
575*4d9fdb46SRobert Mustacchi                 if (!strcmp(dwarfstring_string(
576*4d9fdb46SRobert Mustacchi                     &joind.js_originalfullpath),
577*4d9fdb46SRobert Mustacchi                     dwarfstring_string(&joind.js_tmp3))) {
578*4d9fdb46SRobert Mustacchi                     /* duplicated name. spurious match. */
579*4d9fdb46SRobert Mustacchi #ifdef TESTING
580*4d9fdb46SRobert Mustacchi                     printf("duplicated output string %s\n",
581*4d9fdb46SRobert Mustacchi                         dwarfstring_string(&joind.js_tmp3));
582*4d9fdb46SRobert Mustacchi #endif /* TESTING */
583*4d9fdb46SRobert Mustacchi                 } else if (res == DW_DLV_OK) {
584*4d9fdb46SRobert Mustacchi                     struct dwarfstring_list_s *now_last = 0;
585*4d9fdb46SRobert Mustacchi                     res = dwarfstring_list_add_new(
586*4d9fdb46SRobert Mustacchi                         &base_dwlist,
587*4d9fdb46SRobert Mustacchi                         last_entry,&joind.js_tmp3,
588*4d9fdb46SRobert Mustacchi                         &now_last,errcode);
589*4d9fdb46SRobert Mustacchi                     if(res != DW_DLV_OK) {
590*4d9fdb46SRobert Mustacchi                         dwarfstring_list_destructor(&base_dwlist);
591*4d9fdb46SRobert Mustacchi                         destruct_js(&joind);
592*4d9fdb46SRobert Mustacchi                         return res;
593*4d9fdb46SRobert Mustacchi                     }
594*4d9fdb46SRobert Mustacchi                     last_entry = now_last;
595*4d9fdb46SRobert Mustacchi                 }
596*4d9fdb46SRobert Mustacchi             }
597*4d9fdb46SRobert Mustacchi         }
598*4d9fdb46SRobert Mustacchi     }
599*4d9fdb46SRobert Mustacchi 
600*4d9fdb46SRobert Mustacchi     {
601*4d9fdb46SRobert Mustacchi         struct dwarfstring_list_s *cur = 0;
602*4d9fdb46SRobert Mustacchi         char **resultfullstring = 0;
603*4d9fdb46SRobert Mustacchi 
604*4d9fdb46SRobert Mustacchi         unsigned long count = 0;
605*4d9fdb46SRobert Mustacchi         unsigned long pointerarraysize = 0;
606*4d9fdb46SRobert Mustacchi         unsigned long sumstringlengths = 0;
607*4d9fdb46SRobert Mustacchi         unsigned long totalareasize = 0;
608*4d9fdb46SRobert Mustacchi         unsigned long setptrindex = 0;
609*4d9fdb46SRobert Mustacchi         unsigned long setstrindex = 0;
610*4d9fdb46SRobert Mustacchi 
611*4d9fdb46SRobert Mustacchi         cur = &base_dwlist;
612*4d9fdb46SRobert Mustacchi         for ( ; cur ; cur = cur->dl_next) {
613*4d9fdb46SRobert Mustacchi             ++count;
614*4d9fdb46SRobert Mustacchi             pointerarraysize += sizeof(void *);
615*4d9fdb46SRobert Mustacchi             sumstringlengths +=
616*4d9fdb46SRobert Mustacchi                 dwarfstring_strlen(&cur->dl_string) +1;
617*4d9fdb46SRobert Mustacchi         }
618*4d9fdb46SRobert Mustacchi         /*  Make a final null pointer in the pointer array. */
619*4d9fdb46SRobert Mustacchi         pointerarraysize += sizeof(void *);
620*4d9fdb46SRobert Mustacchi         totalareasize = pointerarraysize + sumstringlengths +8;
621*4d9fdb46SRobert Mustacchi         resultfullstring = (char **)malloc(totalareasize);
622*4d9fdb46SRobert Mustacchi         setstrindex = pointerarraysize;
623*4d9fdb46SRobert Mustacchi         if(!resultfullstring) {
624*4d9fdb46SRobert Mustacchi #ifdef TESTING
625*4d9fdb46SRobert Mustacchi             printf("Malloc fail making final paths. Length %lu"
626*4d9fdb46SRobert Mustacchi                 " bytes.\n",totalareasize);
627*4d9fdb46SRobert Mustacchi #endif /* TESTING */
628*4d9fdb46SRobert Mustacchi             dwarfstring_list_destructor(&base_dwlist);
629*4d9fdb46SRobert Mustacchi             destruct_js(&joind);
630*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_ALLOC_FAIL;
631*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
632*4d9fdb46SRobert Mustacchi         }
633*4d9fdb46SRobert Mustacchi         memset(resultfullstring,0,totalareasize);
634*4d9fdb46SRobert Mustacchi         cur = &base_dwlist;
635*4d9fdb46SRobert Mustacchi 
636*4d9fdb46SRobert Mustacchi         for ( ; cur ; cur = cur->dl_next,++setptrindex) {
637*4d9fdb46SRobert Mustacchi             char **iptr = (char **)((char *)resultfullstring +
638*4d9fdb46SRobert Mustacchi                 setptrindex*sizeof(void *));
639*4d9fdb46SRobert Mustacchi             char *sptr = (char*)resultfullstring + setstrindex;
640*4d9fdb46SRobert Mustacchi 
641*4d9fdb46SRobert Mustacchi             strcpy(sptr,dwarfstring_string(&cur->dl_string));
642*4d9fdb46SRobert Mustacchi             setstrindex += dwarfstring_strlen(&cur->dl_string)+1;
643*4d9fdb46SRobert Mustacchi             *iptr = sptr;
644*4d9fdb46SRobert Mustacchi         }
645*4d9fdb46SRobert Mustacchi         *paths_out = resultfullstring;
646*4d9fdb46SRobert Mustacchi         *paths_out_length = count;
647*4d9fdb46SRobert Mustacchi     }
648*4d9fdb46SRobert Mustacchi     dwarfstring_list_destructor(&base_dwlist);
649*4d9fdb46SRobert Mustacchi     destruct_js(&joind);
650*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
651*4d9fdb46SRobert Mustacchi }
652*4d9fdb46SRobert Mustacchi 
653*4d9fdb46SRobert Mustacchi static int
extract_debuglink(Dwarf_Debug dbg,struct Dwarf_Section_s * pdebuglink,char ** name_returned,unsigned char ** crc_returned,Dwarf_Error * error)654*4d9fdb46SRobert Mustacchi extract_debuglink(Dwarf_Debug dbg,
655*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s * pdebuglink,
656*4d9fdb46SRobert Mustacchi     char ** name_returned,  /* static storage, do not free */
657*4d9fdb46SRobert Mustacchi     unsigned char ** crc_returned,   /* 32bit crc , do not free */
658*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
659*4d9fdb46SRobert Mustacchi {
660*4d9fdb46SRobert Mustacchi     Dwarf_Small *ptr = 0;
661*4d9fdb46SRobert Mustacchi     Dwarf_Small *endptr = 0;
662*4d9fdb46SRobert Mustacchi     unsigned namelen = 0;
663*4d9fdb46SRobert Mustacchi     unsigned m = 0;
664*4d9fdb46SRobert Mustacchi     unsigned incr = 0;
665*4d9fdb46SRobert Mustacchi     Dwarf_Small *crcptr = 0;
666*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
667*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secsize = 0;
668*4d9fdb46SRobert Mustacchi 
669*4d9fdb46SRobert Mustacchi     if (!pdebuglink->dss_data) {
670*4d9fdb46SRobert Mustacchi         res = _dwarf_load_section(dbg, pdebuglink,error);
671*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
672*4d9fdb46SRobert Mustacchi             return res;
673*4d9fdb46SRobert Mustacchi         }
674*4d9fdb46SRobert Mustacchi     }
675*4d9fdb46SRobert Mustacchi     secsize = pdebuglink->dss_size;
676*4d9fdb46SRobert Mustacchi     ptr = pdebuglink->dss_data;
677*4d9fdb46SRobert Mustacchi     endptr = ptr + secsize;
678*4d9fdb46SRobert Mustacchi 
679*4d9fdb46SRobert Mustacchi     res = _dwarf_check_string_valid(dbg,ptr,
680*4d9fdb46SRobert Mustacchi         ptr, endptr,  DW_DLE_FORM_STRING_BAD_STRING,
681*4d9fdb46SRobert Mustacchi         error);
682*4d9fdb46SRobert Mustacchi     if ( res != DW_DLV_OK) {
683*4d9fdb46SRobert Mustacchi         return res;
684*4d9fdb46SRobert Mustacchi     }
685*4d9fdb46SRobert Mustacchi     namelen = (unsigned)strlen((const char*)ptr);
686*4d9fdb46SRobert Mustacchi     m = (namelen+1) %4;
687*4d9fdb46SRobert Mustacchi     if (m) {
688*4d9fdb46SRobert Mustacchi         incr = 4 - m;
689*4d9fdb46SRobert Mustacchi     }
690*4d9fdb46SRobert Mustacchi     crcptr = (unsigned char *)ptr +namelen +1 +incr;
691*4d9fdb46SRobert Mustacchi     if ((crcptr +4) != (unsigned char*)endptr) {
692*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_CORRUPT_GNU_DEBUGLINK);
693*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
694*4d9fdb46SRobert Mustacchi     }
695*4d9fdb46SRobert Mustacchi     *name_returned = (char *)ptr;
696*4d9fdb46SRobert Mustacchi     *crc_returned = crcptr;
697*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
698*4d9fdb46SRobert Mustacchi }
699*4d9fdb46SRobert Mustacchi 
700*4d9fdb46SRobert Mustacchi 
701*4d9fdb46SRobert Mustacchi /*  The definition of .note.gnu.buildid contents (also
702*4d9fdb46SRobert Mustacchi     used for other GNU .note.gnu.  sections too. */
703*4d9fdb46SRobert Mustacchi struct buildid_s {
704*4d9fdb46SRobert Mustacchi     char bu_ownernamesize[4];
705*4d9fdb46SRobert Mustacchi     char bu_buildidsize[4];
706*4d9fdb46SRobert Mustacchi     char bu_type[4];
707*4d9fdb46SRobert Mustacchi     char bu_owner[1];
708*4d9fdb46SRobert Mustacchi };
709*4d9fdb46SRobert Mustacchi 
710*4d9fdb46SRobert Mustacchi static int
extract_buildid(Dwarf_Debug dbg,struct Dwarf_Section_s * pbuildid,unsigned * type_returned,char ** owner_name_returned,unsigned char ** build_id_returned,unsigned * build_id_length_returned,Dwarf_Error * error)711*4d9fdb46SRobert Mustacchi extract_buildid(Dwarf_Debug dbg,
712*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s * pbuildid,
713*4d9fdb46SRobert Mustacchi     unsigned       * type_returned,
714*4d9fdb46SRobert Mustacchi     char           **owner_name_returned,
715*4d9fdb46SRobert Mustacchi     unsigned char  **build_id_returned,
716*4d9fdb46SRobert Mustacchi     unsigned       * build_id_length_returned,
717*4d9fdb46SRobert Mustacchi     Dwarf_Error     *error)
718*4d9fdb46SRobert Mustacchi {
719*4d9fdb46SRobert Mustacchi     Dwarf_Small * ptr = 0;
720*4d9fdb46SRobert Mustacchi     Dwarf_Small * endptr = 0;
721*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
722*4d9fdb46SRobert Mustacchi     struct buildid_s *bu = 0;
723*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned namesize = 0;
724*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned descrsize = 0;
725*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned type = 0;
726*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned finalsize;
727*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secsize = 0;
728*4d9fdb46SRobert Mustacchi 
729*4d9fdb46SRobert Mustacchi     if (!pbuildid->dss_data) {
730*4d9fdb46SRobert Mustacchi         res = _dwarf_load_section(dbg, pbuildid,error);
731*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
732*4d9fdb46SRobert Mustacchi             return res;
733*4d9fdb46SRobert Mustacchi         }
734*4d9fdb46SRobert Mustacchi     }
735*4d9fdb46SRobert Mustacchi     secsize = pbuildid->dss_size;
736*4d9fdb46SRobert Mustacchi     ptr = pbuildid->dss_data;
737*4d9fdb46SRobert Mustacchi     if (secsize < sizeof(struct buildid_s)) {
738*4d9fdb46SRobert Mustacchi #ifdef  TESTING
739*4d9fdb46SRobert Mustacchi         printf("ERROR section .note.gnu.build-id too small: "
740*4d9fdb46SRobert Mustacchi             " section length: 0x%" DW_PR_DUx
741*4d9fdb46SRobert Mustacchi             " minimum struct size 0x%" DW_PR_DUx  "\n",
742*4d9fdb46SRobert Mustacchi             secsize,(Dwarf_Unsigned) sizeof(struct buildid_s));
743*4d9fdb46SRobert Mustacchi #endif /* TESTING */
744*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_CORRUPT_NOTE_GNU_DEBUGID);
745*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
746*4d9fdb46SRobert Mustacchi     }
747*4d9fdb46SRobert Mustacchi     endptr = ptr + secsize;
748*4d9fdb46SRobert Mustacchi     /*  We hold gh_content till all is closed
749*4d9fdb46SRobert Mustacchi         as we return pointers into it
750*4d9fdb46SRobert Mustacchi         if all goes well. */
751*4d9fdb46SRobert Mustacchi     bu = (struct buildid_s *)ptr;
752*4d9fdb46SRobert Mustacchi     ASNAR(dbg->de_copy_word,namesize, bu->bu_ownernamesize);
753*4d9fdb46SRobert Mustacchi     ASNAR(dbg->de_copy_word,descrsize,bu->bu_buildidsize);
754*4d9fdb46SRobert Mustacchi     ASNAR(dbg->de_copy_word,type,     bu->bu_type);
755*4d9fdb46SRobert Mustacchi     if (descrsize != 20) {
756*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_CORRUPT_NOTE_GNU_DEBUGID);
757*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
758*4d9fdb46SRobert Mustacchi     }
759*4d9fdb46SRobert Mustacchi     res = _dwarf_check_string_valid(dbg,
760*4d9fdb46SRobert Mustacchi         (Dwarf_Small *)&bu->bu_owner[0],
761*4d9fdb46SRobert Mustacchi         (Dwarf_Small *)&bu->bu_owner[0],
762*4d9fdb46SRobert Mustacchi         endptr,
763*4d9fdb46SRobert Mustacchi         DW_DLE_CORRUPT_GNU_DEBUGID_STRING,
764*4d9fdb46SRobert Mustacchi         error);
765*4d9fdb46SRobert Mustacchi     if ( res != DW_DLV_OK) {
766*4d9fdb46SRobert Mustacchi         return res;
767*4d9fdb46SRobert Mustacchi     }
768*4d9fdb46SRobert Mustacchi     if ((strlen(bu->bu_owner) +1) != namesize) {
769*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error, DW_DLE_CORRUPT_GNU_DEBUGID_STRING);
770*4d9fdb46SRobert Mustacchi         return res;
771*4d9fdb46SRobert Mustacchi     }
772*4d9fdb46SRobert Mustacchi 
773*4d9fdb46SRobert Mustacchi     finalsize = sizeof(struct buildid_s)-1 + namesize + descrsize;
774*4d9fdb46SRobert Mustacchi     if (finalsize > secsize) {
775*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error, DW_DLE_CORRUPT_GNU_DEBUGID_SIZE);
776*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
777*4d9fdb46SRobert Mustacchi     }
778*4d9fdb46SRobert Mustacchi     *type_returned = type;
779*4d9fdb46SRobert Mustacchi     *owner_name_returned = &bu->bu_owner[0];
780*4d9fdb46SRobert Mustacchi     *build_id_length_returned = descrsize;
781*4d9fdb46SRobert Mustacchi     *build_id_returned = (unsigned char *)ptr +
782*4d9fdb46SRobert Mustacchi         sizeof(struct buildid_s)-1 + namesize;
783*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
784*4d9fdb46SRobert Mustacchi }
785*4d9fdb46SRobert Mustacchi 
786*4d9fdb46SRobert Mustacchi /* */
dwarf_gnu_debuglink(Dwarf_Debug dbg,char ** debuglink_path_returned,unsigned char ** crc_returned,char ** debuglink_fullpath_returned,unsigned * debuglink_fullpath_length_returned,unsigned * buildid_type_returned,char ** buildid_owner_name_returned,unsigned char ** buildid_returned,unsigned * buildid_length_returned,char *** paths_returned,unsigned * paths_count_returned,Dwarf_Error * error)787*4d9fdb46SRobert Mustacchi int dwarf_gnu_debuglink(Dwarf_Debug dbg,
788*4d9fdb46SRobert Mustacchi     char     **  debuglink_path_returned,
789*4d9fdb46SRobert Mustacchi     unsigned char **  crc_returned,
790*4d9fdb46SRobert Mustacchi     char     **  debuglink_fullpath_returned,
791*4d9fdb46SRobert Mustacchi     unsigned *   debuglink_fullpath_length_returned,
792*4d9fdb46SRobert Mustacchi 
793*4d9fdb46SRobert Mustacchi     unsigned *   buildid_type_returned ,
794*4d9fdb46SRobert Mustacchi     char     **  buildid_owner_name_returned,
795*4d9fdb46SRobert Mustacchi     unsigned char ** buildid_returned,
796*4d9fdb46SRobert Mustacchi     unsigned *   buildid_length_returned,
797*4d9fdb46SRobert Mustacchi     char     *** paths_returned,
798*4d9fdb46SRobert Mustacchi     unsigned   * paths_count_returned,
799*4d9fdb46SRobert Mustacchi     Dwarf_Error* error)
800*4d9fdb46SRobert Mustacchi {
801*4d9fdb46SRobert Mustacchi     dwarfstring debuglink_fullpath;
802*4d9fdb46SRobert Mustacchi     int linkres = DW_DLV_ERROR;
803*4d9fdb46SRobert Mustacchi     int res = DW_DLV_ERROR;
804*4d9fdb46SRobert Mustacchi     char * pathname = 0;
805*4d9fdb46SRobert Mustacchi     int buildidres = 0;
806*4d9fdb46SRobert Mustacchi     int errcode = 0;
807*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s * pdebuglink = 0;
808*4d9fdb46SRobert Mustacchi     struct Dwarf_Section_s * pbuildid = 0;
809*4d9fdb46SRobert Mustacchi 
810*4d9fdb46SRobert Mustacchi     if(!dbg) {
811*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_DBG_NULL);
812*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
813*4d9fdb46SRobert Mustacchi     }
814*4d9fdb46SRobert Mustacchi     if (dbg->de_gnu_debuglink.dss_size) {
815*4d9fdb46SRobert Mustacchi         pdebuglink = &dbg->de_gnu_debuglink;
816*4d9fdb46SRobert Mustacchi     }
817*4d9fdb46SRobert Mustacchi     if (dbg->de_note_gnu_buildid.dss_size) {
818*4d9fdb46SRobert Mustacchi         pbuildid = &dbg->de_note_gnu_buildid;
819*4d9fdb46SRobert Mustacchi     }
820*4d9fdb46SRobert Mustacchi     if (!pdebuglink && !pbuildid) {
821*4d9fdb46SRobert Mustacchi         return DW_DLV_NO_ENTRY;
822*4d9fdb46SRobert Mustacchi     }
823*4d9fdb46SRobert Mustacchi     if (pdebuglink) {
824*4d9fdb46SRobert Mustacchi         linkres = extract_debuglink(dbg,
825*4d9fdb46SRobert Mustacchi             pdebuglink,
826*4d9fdb46SRobert Mustacchi             debuglink_path_returned,
827*4d9fdb46SRobert Mustacchi             crc_returned,
828*4d9fdb46SRobert Mustacchi             error);
829*4d9fdb46SRobert Mustacchi         if (linkres == DW_DLV_ERROR) {
830*4d9fdb46SRobert Mustacchi             return linkres;
831*4d9fdb46SRobert Mustacchi         }
832*4d9fdb46SRobert Mustacchi     }
833*4d9fdb46SRobert Mustacchi     if (pbuildid) {
834*4d9fdb46SRobert Mustacchi         buildidres = extract_buildid(dbg,
835*4d9fdb46SRobert Mustacchi             pbuildid,
836*4d9fdb46SRobert Mustacchi             buildid_type_returned,
837*4d9fdb46SRobert Mustacchi             buildid_owner_name_returned,
838*4d9fdb46SRobert Mustacchi             buildid_returned,
839*4d9fdb46SRobert Mustacchi             buildid_length_returned,
840*4d9fdb46SRobert Mustacchi             error);
841*4d9fdb46SRobert Mustacchi         if (buildidres == DW_DLV_ERROR) {
842*4d9fdb46SRobert Mustacchi             return buildidres;
843*4d9fdb46SRobert Mustacchi         }
844*4d9fdb46SRobert Mustacchi     }
845*4d9fdb46SRobert Mustacchi 
846*4d9fdb46SRobert Mustacchi     dwarfstring_constructor(&debuglink_fullpath);
847*4d9fdb46SRobert Mustacchi     pathname = (char *)dbg->de_path;
848*4d9fdb46SRobert Mustacchi     if (pathname && paths_returned) {
849*4d9fdb46SRobert Mustacchi         res =  _dwarf_construct_linkedto_path(
850*4d9fdb46SRobert Mustacchi             (char **)dbg->de_gnu_global_paths,
851*4d9fdb46SRobert Mustacchi             dbg->de_gnu_global_path_count,
852*4d9fdb46SRobert Mustacchi             pathname,
853*4d9fdb46SRobert Mustacchi             *debuglink_path_returned,
854*4d9fdb46SRobert Mustacchi             &debuglink_fullpath,
855*4d9fdb46SRobert Mustacchi             *crc_returned,
856*4d9fdb46SRobert Mustacchi             *buildid_returned,
857*4d9fdb46SRobert Mustacchi             *buildid_length_returned,
858*4d9fdb46SRobert Mustacchi             paths_returned,
859*4d9fdb46SRobert Mustacchi             paths_count_returned,
860*4d9fdb46SRobert Mustacchi             &errcode);
861*4d9fdb46SRobert Mustacchi         if(res != DW_DLV_OK) {
862*4d9fdb46SRobert Mustacchi             dwarfstring_destructor(&debuglink_fullpath);
863*4d9fdb46SRobert Mustacchi             return res;
864*4d9fdb46SRobert Mustacchi         }
865*4d9fdb46SRobert Mustacchi         if (dwarfstring_strlen(&debuglink_fullpath)) {
866*4d9fdb46SRobert Mustacchi             *debuglink_fullpath_returned =
867*4d9fdb46SRobert Mustacchi                 strdup(dwarfstring_string(&debuglink_fullpath));
868*4d9fdb46SRobert Mustacchi             *debuglink_fullpath_length_returned =
869*4d9fdb46SRobert Mustacchi                 dwarfstring_strlen(&debuglink_fullpath);
870*4d9fdb46SRobert Mustacchi         }
871*4d9fdb46SRobert Mustacchi     } else if (paths_count_returned) {
872*4d9fdb46SRobert Mustacchi         *paths_count_returned = 0;
873*4d9fdb46SRobert Mustacchi     }
874*4d9fdb46SRobert Mustacchi     dwarfstring_destructor(&debuglink_fullpath);
875*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
876*4d9fdb46SRobert Mustacchi }
877*4d9fdb46SRobert Mustacchi 
878*4d9fdb46SRobert Mustacchi /*  This should be rarely called and most likely
879*4d9fdb46SRobert Mustacchi     only once (at dbg init time from dwarf_generic_init.c,
880*4d9fdb46SRobert Mustacchi     see set_global_paths_init()).
881*4d9fdb46SRobert Mustacchi     Maybe once or twice later.
882*4d9fdb46SRobert Mustacchi */
883*4d9fdb46SRobert Mustacchi int
dwarf_add_debuglink_global_path(Dwarf_Debug dbg,const char * pathname,Dwarf_Error * error)884*4d9fdb46SRobert Mustacchi dwarf_add_debuglink_global_path(Dwarf_Debug dbg,
885*4d9fdb46SRobert Mustacchi     const char *pathname,
886*4d9fdb46SRobert Mustacchi     Dwarf_Error *error)
887*4d9fdb46SRobert Mustacchi {
888*4d9fdb46SRobert Mustacchi     unsigned    glpath_count_in = 0;
889*4d9fdb46SRobert Mustacchi     unsigned    glpath_count_out = 0;
890*4d9fdb46SRobert Mustacchi     const char **glpaths = 0;
891*4d9fdb46SRobert Mustacchi     const char * path1 = 0;
892*4d9fdb46SRobert Mustacchi 
893*4d9fdb46SRobert Mustacchi     glpath_count_in = dbg->de_gnu_global_path_count;
894*4d9fdb46SRobert Mustacchi     glpath_count_out = glpath_count_in+1;
895*4d9fdb46SRobert Mustacchi     glpaths = (const char **)malloc(sizeof(char *)*
896*4d9fdb46SRobert Mustacchi         glpath_count_out);
897*4d9fdb46SRobert Mustacchi     if (!glpaths) {
898*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
899*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
900*4d9fdb46SRobert Mustacchi     }
901*4d9fdb46SRobert Mustacchi     if (glpath_count_in) {
902*4d9fdb46SRobert Mustacchi         memcpy(glpaths, dbg->de_gnu_global_paths,
903*4d9fdb46SRobert Mustacchi             sizeof(char *)*glpath_count_in);
904*4d9fdb46SRobert Mustacchi     }
905*4d9fdb46SRobert Mustacchi     path1 = strdup(pathname);
906*4d9fdb46SRobert Mustacchi     if (!path1) {
907*4d9fdb46SRobert Mustacchi         free(glpaths);
908*4d9fdb46SRobert Mustacchi         _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
909*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
910*4d9fdb46SRobert Mustacchi     }
911*4d9fdb46SRobert Mustacchi     free((char *)dbg->de_gnu_global_paths);
912*4d9fdb46SRobert Mustacchi     glpaths[glpath_count_in] = path1;
913*4d9fdb46SRobert Mustacchi     dbg->de_gnu_global_paths = (const char **)glpaths;
914*4d9fdb46SRobert Mustacchi     dbg->de_gnu_global_path_count = glpath_count_out;
915*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
916*4d9fdb46SRobert Mustacchi }
917