1 /* Copyright (C) 2021 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 "util.h"
23 #include "ExpGroup.h"
24 #include "Experiment.h"
25 #include "LoadObject.h"
26 #include "DbeSession.h"
27 
28 //////////////////////////////////////////////////////////
29 //  class ExpGroup
30 
31 int ExpGroup::phaseCompareIdx = 0;
32 
ExpGroup(char * nm)33 ExpGroup::ExpGroup (char *nm)
34 {
35   name = dbe_strdup (nm);
36   canonical_path (name);
37   exps = new Vector<Experiment*>;
38   founder = NULL;
39   groupId = 0;
40   phaseCompareIdx++;
41   loadObjs = NULL;
42   loadObjsMap = NULL;
43 }
44 
~ExpGroup()45 ExpGroup::~ExpGroup ()
46 {
47   phaseCompareIdx++;
48   free (name);
49   delete exps;
50   delete loadObjs;
51   delete loadObjsMap;
52 }
53 
54 void
append(Experiment * exp)55 ExpGroup::append (Experiment *exp)
56 {
57   for (int i = 0, sz = exps->size (); i < sz; i++)
58     {
59       Experiment *e = exps->fetch (i);
60       if (exp == e)
61 	return;
62     }
63   exps->append (exp);
64   if (exps->size () == 1)
65     founder = exp;
66 }
67 
68 void
drop_experiment(Experiment * exp)69 ExpGroup::drop_experiment (Experiment *exp)
70 {
71   for (int i = 0, sz = exps->size (); i < sz; i++)
72     {
73       Experiment *e = exps->fetch (i);
74       if (exp == e)
75 	{
76 	  exps->remove (i);
77 	  break;
78 	}
79     }
80   if (founder == exp)
81     founder = NULL;
82 }
83 
84 Vector<Experiment*> *
get_founders()85 ExpGroup::get_founders ()
86 {
87   Vector<Experiment*> *expList = NULL;
88   for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
89     {
90       Experiment *exp = exps->fetch (i);
91       if (exp->founder_exp == NULL)
92 	{
93 	  if (expList == NULL)
94 	    expList = new Vector<Experiment*>;
95 	  expList->append (exp);
96 	}
97     }
98   return expList;
99 }
100 
101 void
create_list_of_loadObjects()102 ExpGroup::create_list_of_loadObjects ()
103 {
104   if (loadObjs == NULL)
105     {
106       loadObjs = new Vector<LoadObject*>();
107       loadObjsMap = new DefaultMap<LoadObject*, int>();
108       for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
109 	{
110 	  Experiment *exp = exps->fetch (i);
111 	  for (int i1 = 0, sz1 = VecSize(exp->loadObjs); i1 < sz1; i1++)
112 	    {
113 	      LoadObject *lo = exp->loadObjs->fetch (i1);
114 	      if (!loadObjsMap->get (lo))
115 		{
116 		  loadObjs->append (lo);
117 		  loadObjsMap->put (lo, loadObjs->size ());
118 		}
119 	    }
120 	}
121     }
122 }
123 
124 LoadObject *
get_comparable_loadObject(LoadObject * lo)125 ExpGroup::get_comparable_loadObject (LoadObject *lo)
126 {
127   create_list_of_loadObjects ();
128   if (loadObjsMap->get (lo))
129     return lo;
130   if ((lo->flags & SEG_FLAG_EXE) != 0)
131     if (dbeSession->expGroups->size () == dbeSession->nexps ())
132       for (int i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
133 	{
134 	  LoadObject *lobj = loadObjs->fetch (i);
135 	  if ((lobj->flags & SEG_FLAG_EXE) != 0)
136 	    return lobj;
137 	}
138 
139   long first_ind = -1;
140   char *bname = get_basename (lo->get_pathname ());
141   for (long i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
142     {
143       LoadObject *lobj = loadObjs->get (i);
144       if (lobj->comparable_objs == NULL
145 	  && strcmp (bname, get_basename (lobj->get_pathname ())) == 0)
146 	{
147 	  if (lo->platform == lobj->platform)
148 	    {
149 	      if ((lo->flags & SEG_FLAG_DYNAMIC) != 0)
150 		{
151 		  if (dbe_strcmp (lo->firstExp->uarglist,
152 				  lobj->firstExp->uarglist) == 0)
153 		    return lobj;
154 		}
155 	      else
156 		return lobj;
157 	    }
158 	  if (first_ind == -1)
159 	    first_ind = i;
160 	}
161     }
162   return first_ind == -1 ? NULL : loadObjs->get (first_ind);
163 }
164