]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/src/DbeFile.cc
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gprofng / src / DbeFile.cc
CommitLineData
fd67aa11 1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
bb368aad
VM
2 Contributed by Oracle.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21#include "config.h"
22#include "util.h"
23#include "DbeSession.h"
24#include "Experiment.h"
25#include "DbeFile.h"
26#include "ExpGroup.h"
27#include "DbeJarFile.h"
28
29DbeFile::DbeFile (const char *filename)
30{
31 filetype = 0;
32 name = dbe_strdup (filename);
33 name = canonical_path (name);
34 orig_location = NULL;
35 location = NULL;
36 location_info = NULL;
37 jarFile = NULL;
38 container = NULL;
39 need_refind = true;
40 inArchive = false;
41 sbuf.st_atim.tv_sec = 0;
42 experiment = NULL;
43}
44
45DbeFile::~DbeFile ()
46{
47 free (name);
48 free (location);
49 free (orig_location);
50 free (location_info);
51}
52
53void
54DbeFile::set_need_refind (bool val)
55{
56 if (val != need_refind)
57 {
58 free (location_info);
59 location_info = NULL;
60 need_refind = val;
61 }
62}
63
64void
65DbeFile::set_location (const char *filename)
66{
67 free (location);
68 location = NULL;
69 if (filename)
70 {
71 if (strncmp (filename, NTXT ("./"), 2) == 0)
72 filename += 2;
73 location = canonical_path (dbe_strdup (filename));
74 }
75 free (location_info);
76 location_info = NULL;
77 set_need_refind (false);
78}
79
80char *
81DbeFile::get_location_info ()
82{
83 if (location_info == NULL)
84 {
85 char *fnm = get_name ();
86 char *loc = get_location ();
87 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location_info: %s %s\n"),
88 STR (fnm), STR (loc));
89 if (loc == NULL)
90 {
91 if (filetype & F_FICTION)
92 location_info = dbe_strdup (fnm);
93 else
94 location_info = dbe_sprintf (GTXT ("%s (not found)"),
95 get_relative_path (fnm));
96 }
97 else
98 {
99 char *r_fnm = get_relative_path (fnm);
100 char *r_loc = get_relative_path (loc);
101 if (strcmp (r_fnm, r_loc) == 0)
102 location_info = dbe_strdup (r_fnm);
103 else
104 {
105 char *bname = get_basename (r_fnm);
106 if (strcmp (bname, r_loc) == 0) // found in current directory
107 location_info = dbe_strdup (bname);
108 else
109 location_info = dbe_sprintf (GTXT ("%s (found as %s)"), bname, r_loc);
110 }
111 }
112 }
113 return location_info;
114}
115
116char *
117DbeFile::getResolvedPath ()
118{
119 if (get_location ())
120 return location;
121 return name;
122}
123
124DbeFile *
125DbeFile::getJarDbeFile (char *fnm, int sym)
126{
127 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::getJarDbeFile: %s fnm='%s' sym=%d\n"),
128 STR (name), STR (fnm), sym);
129 DbeFile *df = NULL;
130 if (sym)
131 {
132 char *s = strchr (fnm, sym);
133 if (s)
134 {
135 s = dbe_strndup (fnm, s - fnm);
136 df = dbeSession->getDbeFile (s, F_JAR_FILE | F_FILE);
137 free (s);
138 }
139 }
140 if (df == NULL)
141 df = dbeSession->getDbeFile (fnm, F_JAR_FILE | F_FILE);
142 if (df && (df->experiment == NULL))
143 df->experiment = experiment;
144 return df;
145}
146
147char *
148DbeFile::get_location (bool find_needed)
149{
150 Dprintf (DEBUG_DBE_FILE, NTXT ("get_location 0x%x %s\n"), filetype, STR (name));
151 if (!find_needed)
152 return need_refind ? NULL : location;
153 if (location || !need_refind)
154 return location;
155 set_need_refind (false);
156 if ((filetype & F_FICTION) != 0)
157 return NULL;
158 if (filetype == F_DIR_OR_JAR)
159 {
160 find_in_archives (name);
161 if (location)
162 {
163 filetype |= F_JAR_FILE | F_FILE;
164 return location;
165 }
166 find_in_pathmap (name);
167 if (location)
168 return location;
169 if (check_access (name) == F_DIRECTORY)
170 {
171 filetype |= F_DIRECTORY;
172 set_location (name);
173 return location;
174 }
175 }
176
177 if ((filetype & F_FILE) != 0)
178 {
179 if (experiment)
180 {
181 char *fnm = experiment->checkFileInArchive (name, false);
182 if (fnm)
183 {
184 set_location (fnm);
185 inArchive = true;
186 sbuf.st_mtime = 0; // Don't check timestamps
187 free (fnm);
188 return location;
189 }
190 if ((filetype & F_JAVACLASS) != 0)
191 {
192 if (orig_location)
193 {
194 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d name='%s' orig_location='%s'\n"),
195 (int) __LINE__, name, orig_location);
196 // Parse a fileName attribute. There are 4 possibilities:
197 // file:<Class_Name>
198 // file:<name_of_jar_or_zip_file>
199 // jar:file:<name_of_jar_or_zip_file>!<Class_Name>
200 // zip:<name_of_jar_or_zip_file>!<Class_Name>
201 DbeFile *jar_df = NULL;
202 if (strncmp (orig_location, NTXT ("zip:"), 4) == 0)
203 jar_df = getJarDbeFile (orig_location + 4, '!');
204 else if (strncmp (orig_location, NTXT ("jar:file:"), 9) == 0)
205 jar_df = getJarDbeFile (orig_location + 9, '!');
206 else if (strncmp (orig_location, NTXT ("file:"), 5) == 0
207 && isJarOrZip (orig_location + 5))
208 jar_df = getJarDbeFile (orig_location + 5, 0);
209 if (jar_df)
210 {
211 if (find_in_jar_file (name, jar_df->get_jar_file ()))
212 {
213 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' location='%s' jar='%s'\n"),
214 (int) __LINE__, name, STR (location), STR (jar_df->get_location ()));
215 inArchive = jar_df->inArchive;
216 container = jar_df;
217 return location;
218 }
219 }
220 if (strncmp (orig_location, NTXT ("file:"), 5) == 0
221 && !isJarOrZip (orig_location + 5))
222 {
223 DbeFile *df = new DbeFile (orig_location + 5);
224 df->filetype = DbeFile::F_FILE;
225 df->experiment = experiment;
226 fnm = df->get_location ();
227 if (fnm)
228 {
229 set_location (fnm);
230 inArchive = df->inArchive;
231 sbuf.st_mtime = df->sbuf.st_mtime;
232 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' orig_location='%s' location='%s'\n"),
233 (int) __LINE__, name, orig_location, fnm);
234 delete df;
235 return location;
236 }
237 delete df;
238 }
239 }
240 fnm = dbe_sprintf (NTXT ("%s/%s/%s"), experiment->get_expt_name (), SP_DYNAMIC_CLASSES, name);
241 if (find_file (fnm))
242 {
243 inArchive = true;
244 sbuf.st_mtime = 0; // Don't check timestamps
245 Dprintf (DEBUG_DBE_FILE, NTXT ("DbeFile::get_location:%d FOUND name='%s' location='%s'\n"),
246 (int) __LINE__, name, fnm);
247 free (fnm);
248 return location;
249 }
250 free (fnm);
251 }
252 }
253 }
254
255 if (dbeSession->archive_mode)
256 {
257 find_file (name);
258 if (location)
259 return location;
260 }
261
262 bool inPathMap = find_in_pathmap (name);
263 if (location)
264 return location;
265 find_in_setpath (name, dbeSession->get_search_path ());
266 if (location)
267 return location;
268 if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
269 {
270 find_in_classpath (name, dbeSession->get_classpath ());
271 if (location)
272 return location;
273 }
274 if (!inPathMap)
275 find_file (name);
276 Dprintf (DEBUG_DBE_FILE && (location == NULL),
277 "DbeFile::get_location:%d NOT FOUND name='%s'\n", __LINE__, name);
278 return location;
279}
280
281int
282DbeFile::check_access (const char *filename)
283{
284 if (filename == NULL)
285 return F_NOT_FOUND;
286 int st = dbe_stat (filename, &sbuf);
287 Dprintf (DEBUG_DBE_FILE, NTXT ("check_access: %d 0x%x %s\n"), st, filetype, filename);
288 if (st == 0)
289 {
290 if (S_ISDIR (sbuf.st_mode))
291 return F_DIRECTORY;
292 else if (S_ISREG (sbuf.st_mode))
293 return F_FILE;
294 return F_UNKNOWN; // Symbolic link or unknown type of file
295 }
296 sbuf.st_atim.tv_sec = 0;
297 sbuf.st_mtime = 0; // Don't check timestamps
298 return F_NOT_FOUND; // File not found
299}
300
301bool
302DbeFile::isJarOrZip (const char *fnm)
303{
304 size_t len = strlen (fnm) - 4;
305 return len > 0 && (strcmp (fnm + len, NTXT (".jar")) == 0
306 || strcmp (fnm + len, NTXT (".zip")) == 0);
307}
308
309char *
310DbeFile::find_file (const char *filename)
311{
312 switch (check_access (filename))
313 {
314 case F_DIRECTORY:
315 if (filetype == F_DIR_OR_JAR)
316 filetype |= F_DIRECTORY;
317 if ((filetype & F_DIRECTORY) != 0)
318 set_location (filename);
319 break;
320 case F_FILE:
321 if (filetype == F_DIR_OR_JAR)
322 {
323 filetype |= F_FILE;
324 if (isJarOrZip (filename))
325 filetype |= F_JAR_FILE;
326 }
327 if ((filetype & F_DIRECTORY) == 0)
328 set_location (filename);
329 break;
330 }
331 return location;
332}
333
334DbeJarFile *
335DbeFile::get_jar_file ()
336{
337 if (jarFile == NULL)
338 {
339 char *fnm = get_location ();
340 if (fnm)
341 jarFile = dbeSession->get_JarFile (fnm);
342 }
343 return jarFile;
344}
345
346char *
347DbeFile::find_package_name (const char *filename, const char *dirname)
348{
349 char *nm = dbe_sprintf (NTXT ("%s/%s"), dirname, filename);
350 if (!find_in_pathmap (nm))
351 find_file (nm);
352 free (nm);
353 return location;
354}
355
356char *
357DbeFile::find_in_directory (const char *filename, const char *dirname)
358{
359 if (filename && dirname)
360 {
361 char *nm = dbe_sprintf (NTXT ("%s/%s"), dirname, filename);
362 find_file (nm);
363 free (nm);
364 }
365 return location;
366}
367
368char *
369DbeFile::find_in_jar_file (const char *filename, DbeJarFile *jfile)
370{
371 // Read .jar or .zip
372 if (jfile == NULL)
373 return NULL;
374 int entry = jfile->get_entry (filename);
375 if (entry >= 0)
376 {
377 char *fnm = dbeSession->get_tmp_file_name (filename, true);
378 long long fsize = jfile->copy (fnm, entry);
379 if (fsize >= 0)
380 {
381 dbeSession->tmp_files->append (fnm);
382 set_location (fnm);
383 sbuf.st_size = fsize;
384 sbuf.st_mtime = 0; // Don't check timestamps
385 fnm = NULL;
386 }
387 free (fnm);
388 }
389 return location;
390}
391
392bool
393DbeFile::find_in_pathmap (char *filename)
394{
395 Vector<pathmap_t*> *pathmaps = dbeSession->get_pathmaps ();
396 bool inPathMap = false;
397 if (strncmp (filename, NTXT ("./"), 2) == 0)
398 filename += 2;
399 for (int i = 0, sz = pathmaps ? pathmaps->size () : 0; i < sz; i++)
400 {
401 pathmap_t *pmp = pathmaps->fetch (i);
402 size_t len = strlen (pmp->old_prefix);
403 if (strncmp (pmp->old_prefix, filename, len) == 0
404 && (filename[len] == '/' || filename[len] == '\0'))
405 {
406 inPathMap = true;
407 if (find_in_directory (filename + len, pmp->new_prefix))
408 {
409 return inPathMap;
410 }
411 }
412 }
413 return inPathMap;
414}
415
416void
417DbeFile::find_in_archives (char *filename)
418{
419 for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
420 {
421 ExpGroup *gr = dbeSession->expGroups->fetch (i1);
422 if (gr->founder)
423 {
424 char *nm = gr->founder->checkFileInArchive (filename, false);
425 if (nm)
426 {
427 find_file (nm);
428 if (location)
429 {
430 sbuf.st_mtime = 0; // Don't check timestamps
431 return;
432 }
433 }
434 }
435 }
436}
437
438void
439DbeFile::find_in_setpath (char *filename, Vector<char*> *searchPath)
440{
441 char *base = get_basename (filename);
442 for (int i = 0, sz = searchPath ? searchPath->size () : 0; i < sz; i++)
443 {
444 char *spath = searchPath->fetch (i);
445 // Check file in each experiment directory
446 if (streq (spath, "$") || streq (spath, NTXT ("$expts")))
447 {
448 // find only in founders and only LoadObj.
449 for (int i1 = 0, sz1 = dbeSession->expGroups->size (); i1 < sz1; i1++)
450 {
451 ExpGroup *gr = dbeSession->expGroups->fetch (i1);
452 char *exp_name = gr->founder->get_expt_name ();
453 if (gr->founder)
454 {
455 if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
456 {
457 // Find with the package name
458 if (find_in_directory (filename, exp_name))
459 return;
460 }
461 if (find_in_directory (base, exp_name))
462 return;
463 }
464 }
465 continue;
466 }
467 DbeFile *df = dbeSession->getDbeFile (spath, DbeFile::F_DIR_OR_JAR);
468 if (df->get_location () == NULL)
469 continue;
470 if ((filetype & (F_JAVACLASS | F_JAVA_SOURCE)) != 0)
471 {
472 if ((df->filetype & F_JAR_FILE) != 0)
473 {
474 if (find_in_jar_file (filename, df->get_jar_file ()))
475 {
476 container = df;
477 return;
478 }
479 continue;
480 }
481 else if ((df->filetype & F_DIRECTORY) != 0)
482 // Find with the package name
483 if (find_package_name (filename, spath))
484 return;
485 }
486 if ((df->filetype & F_DIRECTORY) != 0)
487 if (find_in_directory (base, df->get_location ()))
488 return;
489 }
490}
491
492void
493DbeFile::find_in_classpath (char *filename, Vector<DbeFile*> *classPath)
494{
495 for (int i = 0, sz = classPath ? classPath->size () : 0; i < sz; i++)
496 {
497 DbeFile *df = classPath->fetch (i);
498 if (df->get_location () == NULL)
499 continue;
500 if ((df->filetype & F_JAR_FILE) != 0)
501 {
502 if (find_in_jar_file (filename, df->get_jar_file ()))
503 {
504 container = df;
505 return;
506 }
507 }
508 else if ((df->filetype & F_DIRECTORY) != 0)
509 // Find with the package name
510 if (find_package_name (filename, df->get_name ()))
511 return;
512 }
513}
514
576d2c97 515dbe_stat_t *
bb368aad
VM
516DbeFile::get_stat ()
517{
518 if (sbuf.st_atim.tv_sec == 0)
519 {
520 int st = check_access (get_location (false));
521 if (st == F_NOT_FOUND)
522 return NULL;
523 }
524 return &sbuf;
525}
526
527bool
528DbeFile::compare (DbeFile *df)
529{
530 if (df == NULL)
531 return false;
576d2c97
VM
532 dbe_stat_t *st1 = get_stat ();
533 dbe_stat_t *st2 = df->get_stat ();
bb368aad
VM
534 if (st1 == NULL || st2 == NULL)
535 return false;
536 if (st1->st_size != st2->st_size)
537 return false;
538 if (st1->st_mtim.tv_sec != st2->st_mtim.tv_sec)
539 return false;
540 return true;
541}