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