xref: /netbsd-src/external/gpl3/binutils/dist/gprofng/src/ArchiveExp.cc (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
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 <stdio.h>
23 #include <unistd.h>
24 
25 #include "util.h"
26 #include "DbeSession.h"
27 #include "LoadObject.h"
28 #include "ArchiveExp.h"
29 #include "DbeFile.h"
30 #include "CallStack.h"
31 #include "gp-archive.h"
32 #include "Function.h"
33 #include "Module.h"
34 
ArchiveExp(char * path)35 ArchiveExp::ArchiveExp (char *path) : Experiment ()
36 {
37   force_flag = false;
38   copyso_flag = false;
39   use_fndr_archives = true;
40   status = find_expdir (path);
41   if (status == SUCCESS)
42     read_log_file ();
43 }
44 
~ArchiveExp()45 ArchiveExp::~ArchiveExp () { }
46 
47 void
read_data(int s_option)48 ArchiveExp::read_data (int s_option)
49 {
50   read_archives ();
51   read_map_file ();
52   if (read_java_classes_file () == SUCCESS)
53     {
54       for (int i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
55 	{
56 	  LoadObject *lo = loadObjs->get (i);
57 	  Dprintf (DEBUG_ARCHIVE, NTXT ("%s:%d loadObjs[%d]=%-25s %s\n"),
58 		   get_basename (__FILE__), (int) __LINE__, i,
59 		   STR (lo->get_name ()), STR (lo->get_pathname ()));
60 	  if ((lo->dbeFile->filetype & DbeFile::F_JAVACLASS) == 0)
61 	    continue;
62 	  lo->isUsed = true;
63 	  if ((s_option & ARCH_EXE_ONLY) != 0)
64 	    continue;
65 	  lo->sync_read_stabs ();
66 	}
67     }
68   if ((s_option & (ARCH_USED_EXE_ONLY | ARCH_USED_SRC_ONLY)) != 0)
69     {
70       read_frameinfo_file ();
71       resolveFrameInfo = true;
72       Vector<DataDescriptor*> *ddscr = getDataDescriptors ();
73       delete ddscr; // getDataDescriptors() forces reading of experiment data
74       CallStack *callStack = callTree ();
75       if (callStack)
76 	{
77 	  if (DEBUG_ARCHIVE)
78 	    {
79 	      Dprintf (DEBUG_ARCHIVE, NTXT ("stacks=%p\n"), callStack);
80 	      callStack->print (NULL);
81 	    }
82 	  for (int n = 0;; n++)
83 	    {
84 	      CallStackNode *node = callStack->get_node (n);
85 	      if (node == NULL)
86 		break;
87 	      do
88 		{
89 		  Histable *h = node->get_instr ();
90 		  Histable::Type t = h->get_type ();
91 		  if (t == Histable::INSTR)
92 		    {
93 		      DbeInstr *dbeInstr = (DbeInstr *) h;
94 		      if (!dbeInstr->isUsed)
95 			{
96 			  Function *func = (Function *) dbeInstr->convertto (Histable::FUNCTION);
97 			  if (!func->isUsed)
98 			    {
99 			      func->isUsed = true;
100 			      func->module->isUsed = true;
101 			      func->module->loadobject->isUsed = true;
102 			    }
103 			  DbeLine *dbeLine = (DbeLine *) dbeInstr->convertto (Histable::LINE);
104 			  if (dbeLine)
105 			    dbeLine->sourceFile->isUsed = true;
106 			}
107 		    }
108 		  else if (t == Histable::LINE)
109 		    {
110 		      DbeLine * dbeLine = (DbeLine *) h;
111 		      dbeLine->sourceFile->isUsed = true;
112 		    }
113 		  node = node->ancestor;
114 		}
115 	      while (node);
116 	    }
117 	}
118     }
119 }
120 
121 char *
createLinkToFndrArchive(LoadObject * lo,int)122 ArchiveExp::createLinkToFndrArchive (LoadObject *lo, int /* hide_msg */)
123 {
124   // For example, archives of libc.so will be:
125   //  <exp>/archives/<libc.so_check_sum>
126   //  <exp>/M_r0.er/archives/libc.so_<hash> -> ../../archives/<libc.so_check_sum>
127   if (!create_dir (get_fndr_arch_name ()))
128     {
129       fprintf (stderr, GTXT ("Unable to create directory `%s'\n"), get_fndr_arch_name ());
130       return NULL;
131     }
132   uint32_t checksum = lo->get_checksum ();
133   char *linkName = dbe_sprintf (NTXT ("../../%s/%u"), SP_ARCHIVES_DIR, checksum);
134   char *nm = lo->get_pathname ();
135   char *symLinkName = getNameInArchive (nm, false);
136   if (symlink (linkName, symLinkName) != 0)
137     {
138       fprintf (stderr, GTXT ("Unable to create link `%s' -> `%s'\n"),
139 	       symLinkName, linkName);
140       free (linkName);
141       free (symLinkName);
142       return NULL;
143     }
144   free (linkName);
145   free (symLinkName);
146 
147   // Return a full path inside founder archive:
148   return dbe_sprintf (NTXT ("%s/%u"), get_fndr_arch_name (), checksum);
149 }
150