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 <errno.h>
23 
24 #include "util.h"
25 #include "StringBuilder.h"
26 #include "Application.h"
27 #include "DbeSession.h"
28 #include "Experiment.h"
29 #include "Exp_Layout.h"
30 #include "DataObject.h"
31 #include "Elf.h"
32 #include "Function.h"
33 #include "Module.h"
34 #include "ClassFile.h"
35 #include "Stabs.h"
36 #include "LoadObject.h"
37 #include "dbe_types.h"
38 #include "DbeFile.h"
39 #include "ExpGroup.h"
40 
41 enum
42 {
43   LO_InstHTableSize     = 4096,
44   HTableSize            = 1024
45 };
46 
47 LoadObject *
create_item(const char * nm,int64_t chksum)48 LoadObject::create_item (const char *nm, int64_t chksum)
49 {
50   LoadObject *lo = new LoadObject (nm);
51   lo->checksum = chksum;
52   dbeSession->append (lo);
53   return lo;
54 }
55 
56 LoadObject *
create_item(const char * nm,const char * _runTimePath,DbeFile * df)57 LoadObject::create_item (const char *nm, const char *_runTimePath, DbeFile *df)
58 {
59   LoadObject *lo = new LoadObject (nm);
60   lo->runTimePath = dbe_strdup (_runTimePath);
61   lo->dbeFile->orig_location = dbe_strdup (_runTimePath);
62   if (df)
63     {
64       if ((df->filetype & DbeFile::F_JAR_FILE) != 0)
65 	{
66 	  if (lo->dbeFile->find_in_jar_file (nm, df->get_jar_file ()))
67 	    {
68 	      lo->dbeFile->inArchive = df->inArchive;
69 	      lo->dbeFile->container = df;
70 	    }
71 	}
72       else
73 	{
74 	  lo->dbeFile->set_location (df->get_location ());
75 	  lo->dbeFile->sbuf = df->sbuf;
76 	  lo->dbeFile->inArchive = df->inArchive;
77 	}
78     }
79   dbeSession->append (lo);
80   return lo;
81 }
82 
LoadObject(const char * loname)83 LoadObject::LoadObject (const char *loname)
84 {
85   flags = 0;
86   size = 0;
87   type = SEG_UNKNOWN;
88   isReadStabs = false;
89   need_swap_endian = false;
90   instHTable = new DbeInstr*[LO_InstHTableSize];
91   for (int i = 0; i < LO_InstHTableSize; i++)
92     instHTable[i] = NULL;
93 
94   functions = new Vector<Function*>;
95   funcHTable = new Function*[HTableSize];
96   for (int i = 0; i < HTableSize; i++)
97     funcHTable[i] = NULL;
98 
99   seg_modules = new Vector<Module*>;
100   modules = new HashMap<char*, Module*>;
101   platform = Unknown;
102   noname = dbeSession->createUnknownModule (this);
103   modules->put (noname->get_name (), noname);
104   pathname = NULL;
105   arch_name = NULL;
106   runTimePath = NULL;
107   objStabs = NULL;
108   firstExp = NULL;
109   seg_modules_map = NULL;
110   comp_funcs = NULL;
111   warnq = new Emsgqueue (NTXT ("lo_warnq"));
112   commentq = new Emsgqueue (NTXT ("lo_commentq"));
113   elf_lo = NULL;
114   elf_inited = false;
115   checksum = 0;
116   isUsed = false;
117   h_function = NULL;
118   h_instr = NULL;
119 
120   char *nm = (char *) loname;
121   if (strncmp (nm, NTXT ("./"), 2) == 0)
122     nm += 2;
123   set_name (nm);
124   dbeFile = new DbeFile (nm);
125   dbeFile->filetype |= DbeFile::F_LOADOBJ | DbeFile::F_FILE;
126 }
127 
~LoadObject()128 LoadObject::~LoadObject ()
129 {
130   delete seg_modules_map;
131   delete functions;
132   delete[] instHTable;
133   delete[] funcHTable;
134   delete seg_modules;
135   delete modules;
136   delete elf_lo;
137   free (pathname);
138   free (arch_name);
139   free (runTimePath);
140   delete objStabs;
141   delete warnq;
142   delete commentq;
143   delete h_instr;
144 }
145 
146 Elf *
get_elf()147 LoadObject::get_elf ()
148 {
149   if (elf_lo == NULL)
150     {
151       if (dbeFile->get_need_refind ())
152 	elf_inited = false;
153       if (elf_inited)
154 	return NULL;
155       elf_inited = true;
156       char *fnm = dbeFile->get_location ();
157       if (fnm == NULL)
158 	{
159 	  append_msg (CMSG_ERROR, GTXT ("Cannot find file: `%s'"),
160 		      dbeFile->get_name ());
161 	  return NULL;
162 	}
163       Elf::Elf_status st = Elf::ELF_ERR_CANT_OPEN_FILE;
164       elf_lo = Elf::elf_begin (fnm, &st);
165       if (elf_lo == NULL)
166 	switch (st)
167 	  {
168 	  case Elf::ELF_ERR_CANT_OPEN_FILE:
169 	    append_msg (CMSG_ERROR, GTXT ("Cannot open ELF file `%s'"), fnm);
170 	    break;
171 	  case Elf::ELF_ERR_BAD_ELF_FORMAT:
172 	  default:
173 	    append_msg (CMSG_ERROR, GTXT ("Cannot read ELF header of `%s'"),
174 			fnm);
175 	    break;
176 	  }
177     }
178   return elf_lo;
179 }
180 
181 Stabs *
openDebugInfo(char * fname,Stabs::Stab_status * stp)182 LoadObject::openDebugInfo (char *fname, Stabs::Stab_status *stp)
183 {
184   if (objStabs == NULL)
185     {
186       if (fname == NULL)
187 	return NULL;
188       objStabs = new Stabs (fname, get_pathname ());
189       Stabs::Stab_status st = objStabs->get_status ();
190       if ((st == Stabs::DBGD_ERR_NONE) && (checksum != 0))
191 	{
192 	  Elf *elf = get_elf ();
193 	  if (elf && (checksum != elf->elf_checksum ()))
194 	    {
195 	      char *buf = dbe_sprintf (GTXT ("*** Note: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored"),
196 				       fname);
197 	      commentq->append (new Emsg (CMSG_ERROR, buf));
198 	      delete buf;
199 	      st = Stabs::DBGD_ERR_CHK_SUM;
200 	    }
201 	}
202       if (stp)
203 	*stp = st;
204       if (st != Stabs::DBGD_ERR_NONE)
205 	{
206 	  delete objStabs;
207 	  objStabs = NULL;
208 	}
209     }
210   return objStabs;
211 }
212 
213 uint64_t
get_addr()214 LoadObject::get_addr ()
215 {
216   return MAKE_ADDRESS (seg_idx, 0);
217 }
218 
219 bool
compare(const char * _path,int64_t _checksum)220 LoadObject::compare (const char *_path, int64_t _checksum)
221 {
222   return _checksum == checksum && dbe_strcmp (_path, get_pathname ()) == 0;
223 }
224 
225 int
compare(const char * _path,const char * _runTimePath,DbeFile * df)226 LoadObject::compare (const char *_path, const char *_runTimePath, DbeFile *df)
227 {
228   int ret = 0;
229   if (dbe_strcmp (_path, get_pathname ()) != 0)
230     return ret;
231   ret |= CMP_PATH;
232   if (_runTimePath)
233     {
234       if (dbe_strcmp (_runTimePath, runTimePath) != 0)
235 	return ret;
236       ret |= CMP_RUNTIMEPATH;
237     }
238   if (df && dbeFile->compare (df))
239     ret |= CMP_CHKSUM;
240   return ret;
241 }
242 
243 void
set_platform(Platform_t pltf,int wsz)244 LoadObject::set_platform (Platform_t pltf, int wsz)
245 {
246   switch (pltf)
247     {
248     case Sparc:
249     case Sparcv9:
250     case Sparcv8plus:
251       platform = (wsz == W64) ? Sparcv9 : Sparc;
252       break;
253     case Intel:
254     case Amd64:
255       platform = (wsz == W64) ? Amd64 : Intel;
256       break;
257     default:
258       platform = pltf;
259       break;
260     }
261 };
262 
263 void
set_name(char * string)264 LoadObject::set_name (char *string)
265 {
266   char *p;
267   pathname = dbe_strdup (string);
268 
269   p = get_basename (pathname);
270   if (p[0] == '<')
271     name = dbe_strdup (p);
272   else    // set a short name  to "<basename>"
273     name = dbe_sprintf (NTXT ("<%s>"), p);
274 }
275 
276 void
dump_functions(FILE * out)277 LoadObject::dump_functions (FILE *out)
278 {
279   int index;
280   Function *fitem;
281   char *sname, *mname;
282   if (platform == Java)
283     {
284       JMethod *jmthd;
285       Vector<JMethod*> *jmethods = (Vector<JMethod*>*)functions;
286       Vec_loop (JMethod*, jmethods, index, jmthd)
287       {
288 	fprintf (out, "id %6llu, @0x%llx sz-%lld %s (module = %s)\n",
289 		 (unsigned long long) jmthd->id, (long long) jmthd->get_mid (),
290 		 (long long) jmthd->size, jmthd->get_name (),
291 		 jmthd->module ? jmthd->module->file_name : noname->file_name);
292       }
293     }
294   else
295     {
296       Vec_loop (Function*, functions, index, fitem)
297       {
298 	if (fitem->alias && fitem->alias != fitem)
299 	  fprintf (out, "id %6llu, @0x%llx -        %s == alias of '%s'\n",
300 		   (ull_t) fitem->id, (ull_t) fitem->img_offset,
301 		   fitem->get_name (), fitem->alias->get_name ());
302 	else
303 	  {
304 	    mname = fitem->module ? fitem->module->file_name : noname->file_name;
305 	    sname = fitem->getDefSrcName ();
306 	    fprintf (out,
307 		     "id %6llu, @0x%llx - 0x%llx [save 0x%llx] o-%lld sz-%lld %s (module = %s)",
308 		     (ull_t) fitem->id, (ull_t) fitem->img_offset,
309 		     (ull_t) (fitem->img_offset + fitem->size),
310 		     (ull_t) fitem->save_addr, (ull_t) fitem->img_offset,
311 		     (ll_t) fitem->size, fitem->get_name (), mname);
312 	    if (sname && !streq (sname, mname))
313 	      fprintf (out, " (Source = %s)", sname);
314 	    fprintf (out, "\n");
315 	  }
316       }
317     }
318 }
319 
320 int
get_index(Function * func)321 LoadObject::get_index (Function *func)
322 {
323   Function *fp;
324   uint64_t offset;
325   int x;
326   int left = 0;
327   int right = functions->size () - 1;
328   offset = func->img_offset;
329   while (left <= right)
330     {
331       x = (left + right) / 2;
332       fp = functions->fetch (x);
333 
334       if (left == right)
335 	{
336 	  if (offset >= fp->img_offset + fp->size)
337 	    return -1;
338 	  if (offset >= fp->img_offset)
339 	    return x;
340 	  return -1;
341 	}
342       if (offset < fp->img_offset)
343 	right = x - 1;
344       else if (offset >= fp->img_offset + fp->size)
345 	left = x + 1;
346       else
347 	return x;
348     }
349   return -1;
350 }
351 
352 char *
get_alias(Function * func)353 LoadObject::get_alias (Function *func)
354 {
355   Function *fp, *alias;
356   int index, nsize;
357   static char buf[1024];
358   if (func->img_offset == 0 || func->alias == NULL)
359     return NULL;
360   int fid = get_index (func);
361   if (fid == -1)
362     return NULL;
363 
364   nsize = functions->size ();
365   alias = func->alias;
366   for (index = fid; index < nsize; index++)
367     {
368       fp = functions->fetch (index);
369       if (fp->alias != alias)
370 	{
371 	  fid = index;
372 	  break;
373 	}
374     }
375 
376   *buf = '\0';
377   for (index--; index >= 0; index--)
378     {
379       fp = functions->fetch (index);
380       if (fp->alias != alias)
381 	break;
382       if (fp != alias)
383 	{
384 	  size_t len = strlen (buf);
385 	  if (*buf != '\0')
386 	    {
387 	      snprintf (buf + len, sizeof (buf) - len, NTXT (", "));
388 	      len = strlen (buf);
389 	    }
390 	  snprintf (buf + len, sizeof (buf) - len, "%s", fp->get_name ());
391 	}
392     }
393   return buf;
394 }
395 
396 DbeInstr*
find_dbeinstr(uint64_t file_off)397 LoadObject::find_dbeinstr (uint64_t file_off)
398 {
399   int hash = (((int) file_off) >> 2) & (LO_InstHTableSize - 1);
400   DbeInstr *instr = instHTable[hash];
401   if (instr && instr->img_offset == file_off)
402     return instr;
403   Function *fp = find_function (file_off);
404   if (fp == NULL)
405     fp = dbeSession->get_Unknown_Function ();
406   uint64_t func_off = file_off - fp->img_offset;
407   instr = fp->find_dbeinstr (0, func_off);
408   instHTable[hash] = instr;
409   return instr;
410 }
411 
412 Function *
find_function(uint64_t foff)413 LoadObject::find_function (uint64_t foff)
414 {
415   // Look up in the hash table
416   int hash = (((int) foff) >> 6) & (HTableSize - 1);
417   Function *func = funcHTable[hash];
418   if (func && foff >= func->img_offset && foff < func->img_offset + func->size)
419     return func->alias ? func->alias : func;
420 
421   // Use binary search
422   func = NULL;
423   int left = 0;
424   int right = functions->size () - 1;
425   while (left <= right)
426     {
427       int x = (left + right) / 2;
428       Function *fp = functions->fetch (x);
429       assert (fp != NULL);
430 
431       if (foff < fp->img_offset)
432 	right = x - 1;
433       else if (foff >= fp->img_offset + fp->size)
434 	left = x + 1;
435       else
436 	{
437 	  func = fp;
438 	  break;
439 	}
440     }
441 
442   // Plug the hole with a static function
443   char *func_name = NULL;
444   Size low_bound = 0, high_bound = 0;
445   if (func == NULL)
446     {
447       int last = functions->size () - 1;
448       uint64_t usize = (uint64_t) size;
449       if (foff >= usize)
450 	{
451 	  // Cannot map to this LoadObject. Probably LoadObject was changed.
452 	  if (last >= 0 && functions->fetch (last)->img_offset == usize)
453 	    {
454 	      // Function is already created
455 	      func = functions->fetch (last);
456 	      if (func->size < 0 || (uint64_t) func->size < foff - usize)
457 		func->size = foff - usize;
458 	    }
459 	  else
460 	    {
461 	      low_bound = size;
462 	      high_bound = foff;
463 	      func_name = dbe_sprintf (GTXT ("<static>@0x%llx (%s) --  no functions found"),
464 				       low_bound, name);
465 	    }
466 	}
467       else if (last < 0)
468 	{
469 	  low_bound = 0;
470 	  high_bound = size;
471 	  func_name = dbe_sprintf (GTXT ("<static>@0x%llx (%s) --  no functions found"),
472 				   low_bound, name);
473 	}
474       else if (foff < functions->fetch (0)->img_offset)
475 	{
476 	  low_bound = 0;
477 	  high_bound = functions->fetch (0)->img_offset;
478 	}
479       else
480 	{
481 	  Function *fp = functions->fetch (last);
482 	  if (foff >= fp->img_offset + fp->size)
483 	    {
484 	      low_bound = fp->img_offset + fp->size;
485 	      high_bound = size;
486 	    }
487 	  else
488 	    {
489 	      fp = functions->fetch (left);
490 	      if (foff >= fp->img_offset + fp->size)
491 		{
492 		  low_bound = fp->img_offset + fp->size;
493 		  high_bound = functions->fetch (left + 1)->img_offset;
494 		}
495 	      else
496 		{
497 		  Function *fp1 = functions->fetch (left - 1);
498 		  low_bound = fp1->img_offset + fp1->size;
499 		  high_bound = fp->img_offset;
500 		}
501 	    }
502 	}
503     }
504 
505   if (func == NULL)
506     {
507       func = dbeSession->createFunction ();
508       func->size = (unsigned) (high_bound - low_bound);
509       func->module = noname;
510       func->img_fname = get_pathname ();
511       func->img_offset = (off_t) low_bound;
512       noname->functions->append (func); // unordered
513       if (func_name == NULL)
514 	func_name = dbe_sprintf (GTXT ("<static>@0x%llx (%s)"), low_bound,
515 				 name);
516       func->set_name (func_name);
517       free (func_name);
518 
519       // now insert the function
520       functions->insert (left, func);
521     }
522 
523   // Update the hash table
524   funcHTable[hash] = func;
525   return func->alias ? func->alias : func;
526 }
527 
528 static void
fixFuncAlias(Vector<Function * > * SymLst)529 fixFuncAlias (Vector<Function*> *SymLst)
530 {
531   int ind, i, k;
532   int64_t len, bestLen, maxSize;
533   Function *sym, *bestAlias;
534 
535   // XXXX it is a clone of Stabs::fixSymtabAlias()
536   ind = SymLst->size () - 1;
537   for (i = 0; i < ind; i++)
538     {
539       bestAlias = SymLst->fetch (i);
540       if (bestAlias->img_offset == 0) // Ignore this bad symbol
541 	continue;
542       sym = SymLst->fetch (i + 1);
543       if (bestAlias->img_offset != sym->img_offset)
544 	{
545 	  if (bestAlias->size == 0
546 	      || sym->img_offset < bestAlias->img_offset + bestAlias->size)
547 	    bestAlias->size = (int) (sym->img_offset - bestAlias->img_offset);
548 	  continue;
549 	}
550 
551       // Find a "best" alias
552       bestLen = strlen (bestAlias->get_name ());
553       maxSize = bestAlias->size;
554       for (k = i + 1; k <= ind; k++)
555 	{
556 	  sym = SymLst->fetch (k);
557 	  if (bestAlias->img_offset != sym->img_offset)
558 	    { // no more aliases
559 	      if ((maxSize == 0) ||
560 		  (sym->img_offset < bestAlias->img_offset + maxSize))
561 		maxSize = sym->img_offset - bestAlias->img_offset;
562 	      break;
563 	    }
564 	  if (maxSize < sym->size)
565 	    maxSize = sym->size;
566 	  len = strlen (sym->get_name ());
567 	  if (len < bestLen)
568 	    {
569 	      bestAlias = sym;
570 	      bestLen = len;
571 	    }
572 	}
573       for (; i < k; i++)
574 	{
575 	  sym = SymLst->fetch (i);
576 	  sym->alias = bestAlias;
577 	  sym->size = maxSize;
578 	}
579       i--;
580     }
581 }
582 
583 void
post_process_functions()584 LoadObject::post_process_functions ()
585 {
586   if (flags & SEG_FLAG_DYNAMIC || platform == Java)
587     return;
588 
589   char *msg = GTXT ("Processing Load Object Data");
590   if (dbeSession->is_interactive ())
591     theApplication->set_progress (1, msg);
592 
593   // First sort the functions
594   functions->sort (func_compare);
595   fixFuncAlias (functions);
596 
597   Module *mitem;
598   int index;
599   Vec_loop (Module*, seg_modules, index, mitem)
600   {
601     mitem->functions->sort (func_compare);
602   }
603 
604   // Find any derived functions, and set their derivedNode
605   Function *fitem;
606   Vec_loop (Function*, functions, index, fitem)
607   {
608     if (dbeSession->is_interactive () && index % 5000 == 0)
609       {
610 	int percent = (int) (100.0 * index / functions->size ());
611 	theApplication->set_progress (percent, (percent != 0) ? NULL : msg);
612       }
613     fitem->findDerivedFunctions ();
614   }
615 
616   // 4987698: get the alias name for MAIN_
617   fitem = find_function (NTXT ("MAIN_"));
618   if (fitem)
619     fitem->module->read_stabs ();
620   fitem = find_function (NTXT ("@plt"));
621   if (fitem)
622     fitem->flags |= FUNC_FLAG_PLT;
623   if (dbeSession->is_interactive ())
624     theApplication->set_progress (0, NTXT (""));
625 }
626 
627 int
func_compare(const void * p1,const void * p2)628 LoadObject::func_compare (const void *p1, const void *p2)
629 {
630   Function *f1 = *(Function **) p1;
631   Function *f2 = *(Function **) p2;
632   if (f1->img_offset != f2->img_offset)
633     return f1->img_offset > f2->img_offset ? 1 : -1;
634 
635   // annotated source not available for weak symbols.
636   if ((f1->module->flags & MOD_FLAG_UNKNOWN) != 0)
637     {
638       if ((f2->module->flags & MOD_FLAG_UNKNOWN) == 0)
639 	return -1;
640     }
641   else if ((f2->module->flags & MOD_FLAG_UNKNOWN) != 0)
642     return 1;
643   return strcoll (f1->get_name (), f2->get_name ());
644 }
645 
646 Function *
find_function(char * fname)647 LoadObject::find_function (char *fname)
648 {
649   Function *fitem;
650   int index;
651   Vec_loop (Function*, functions, index, fitem)
652   {
653     if (strcmp (fitem->get_name (), fname) == 0)
654       return fitem;
655   }
656   return (Function *) NULL;
657 }
658 
659 Function *
find_function(char * fname,unsigned int chksum)660 LoadObject::find_function (char *fname, unsigned int chksum)
661 {
662   Function *fitem;
663   int index;
664   Vec_loop (Function*, functions, index, fitem)
665   {
666     if (fitem->chksum == chksum && strcmp (fitem->get_name (), fname) == 0)
667       return fitem;
668   }
669   return (Function *) NULL;
670 }
671 
672 Module *
find_module(char * mname)673 LoadObject::find_module (char *mname)
674 {
675   for (int i = 0, sz = seg_modules ? seg_modules->size () : 0; i < sz; i++)
676     {
677       Module *module = seg_modules->fetch (i);
678       if (strcmp (module->get_name (), mname) == 0)
679 	return module;
680     }
681   return (Module *) NULL;
682 }
683 
684 LoadObject::Arch_status
sync_read_stabs()685 LoadObject::sync_read_stabs ()
686 {
687   Arch_status st = ARCHIVE_SUCCESS;
688   if (!isReadStabs)
689     {
690       aquireLock ();
691       if (!isReadStabs)
692 	{
693 	  st = read_stabs ();
694 	  post_process_functions ();
695 	  isReadStabs = true;
696 	}
697       releaseLock ();
698     }
699   return st;
700 }
701 
702 LoadObject::Arch_status
read_stabs()703 LoadObject::read_stabs ()
704 {
705   if ((dbeFile->filetype & DbeFile::F_FICTION) != 0)
706     return ARCHIVE_SUCCESS;
707   Arch_status stabs_status = ARCHIVE_ERR_OPEN;
708   if (platform == Java)
709     {
710       Module *cf = NULL;
711       for (int i = 0, sz = seg_modules ? seg_modules->size () : 0; i < sz; i++)
712 	{
713 	  Module *mod = seg_modules->fetch (i);
714 	  if (mod->dbeFile
715 	      && (mod->dbeFile->filetype & DbeFile::F_JAVACLASS) != 0)
716 	    {
717 	      cf = mod;
718 	      break;
719 	    }
720 	}
721       if (cf)
722 	{
723 	  int status = cf->readFile ();
724 	  switch (status)
725 	    {
726 	    case Module::AE_OK:
727 	      stabs_status = ARCHIVE_SUCCESS;
728 	      break;
729 	    case Module::AE_NOSTABS:
730 	      stabs_status = ARCHIVE_NO_STABS;
731 	      break;
732 	    case Module::AE_NOTREAD:
733 	    default:
734 	      stabs_status = ARCHIVE_ERR_OPEN;
735 	      break;
736 	    }
737 	}
738     }
739   else if (strchr (pathname, '`'))
740     return ARCHIVE_SUCCESS;
741   else
742     {
743       Arch_status st = ARCHIVE_WRONG_ARCH;
744       Elf *elf = get_elf ();
745       if (elf == NULL)
746 	{
747 	  if (read_archive () == 0)
748 	    st = ARCHIVE_SUCCESS;
749 	  else
750 	    {
751 	      char *msg = dbe_sprintf (GTXT ("*** Warning: Can't open file: %s"),
752 				       dbeFile->get_name ());
753 	      warnq->append (new Emsg (CMSG_ERROR, msg));
754 	      delete msg;
755 	    }
756 	}
757       else if (checksum != 0 && checksum != elf->elf_checksum ())
758 	{
759 	  if (read_archive () == 0)
760 	    st = ARCHIVE_SUCCESS;
761 	  else
762 	    {
763 	      char *msg = dbe_sprintf (
764 				       GTXT ("*** Note: '%s' has an unexpected checksum value; perhaps it was rebuilt. File ignored"),
765 				       dbeFile->get_location ());
766 	      commentq->append (new Emsg (CMSG_ERROR, msg));
767 	      delete msg;
768 	    }
769 	}
770       if (st == ARCHIVE_SUCCESS)    // An old archive is used
771 	return st;
772 
773       Stabs::Stab_status status = Stabs::DBGD_ERR_CANT_OPEN_FILE;
774       char *location = dbeFile->get_location (true);
775       if (location == NULL)
776 	return ARCHIVE_ERR_OPEN;
777 
778       if (openDebugInfo (location, &status))
779 	{
780 	  status = objStabs->read_archive (this);
781 	  isRelocatable = objStabs->is_relocatable ();
782 	  size = objStabs->get_textsz ();
783 	  platform = objStabs->get_platform ();
784 	  wsize = objStabs->get_class ();
785 	}
786 
787       switch (status)
788 	{
789 	case Stabs::DBGD_ERR_NONE:
790 	  stabs_status = ARCHIVE_SUCCESS;
791 	  break;
792 	case Stabs::DBGD_ERR_CANT_OPEN_FILE:
793 	  stabs_status = ARCHIVE_ERR_OPEN;
794 	  break;
795 	case Stabs::DBGD_ERR_BAD_ELF_LIB:
796 	case Stabs::DBGD_ERR_BAD_ELF_FORMAT:
797 	  stabs_status = ARCHIVE_BAD_STABS;
798 	  break;
799 	case Stabs::DBGD_ERR_NO_STABS:
800 	  stabs_status = ARCHIVE_NO_STABS;
801 	  break;
802 	case Stabs::DBGD_ERR_NO_DWARF:
803 	  stabs_status = ARCHIVE_NO_DWARF;
804 	  break;
805 	default:
806 	  stabs_status = ARCHIVE_BAD_STABS;
807 	  break;
808 	}
809     }
810   return stabs_status;
811 }
812 
813 #define ARCH_STRLEN(s)      ((strlen(s) + 4) & ~0x3 )
814 
815 static int
offsetCmp(const void * a,const void * b)816 offsetCmp (const void *a, const void *b)
817 {
818   uint32_t o1 = ((inst_info_t *) a)->offset;
819   uint32_t o2 = ((inst_info_t *) b)->offset;
820   return o1 == o2 ? 0 : (o1 < o2 ? -1 : 1);
821 }
822 
823 int
read_archive()824 LoadObject::read_archive ()
825 {
826   if (arch_name == NULL)
827     return 1;
828   Module *mod = NULL;
829   Function *func = NULL;
830   char *buf;
831   Data_window *dwin = new Data_window (arch_name);
832   if (dwin->not_opened ())
833     {
834       delete dwin;
835       buf = dbe_sprintf (GTXT ("*** Warning: Error opening file for reading: %s: %s"),
836 			 arch_name, strerror (errno));
837       warnq->append (new Emsg (CMSG_ERROR, buf));
838       delete buf;
839       return 1;
840     }
841   dwin->need_swap_endian = need_swap_endian;
842 
843   // Prevent reading earlier archive files, which didn't support versioning.
844   int64_t offset = 0;
845   ARCH_common *cpkt = (ARCH_common*) dwin->bind (offset, sizeof (ARCH_common));
846   uint16_t v16;
847   if (cpkt)
848     {
849       v16 = (uint16_t) cpkt->type;
850       if (dwin->decode (v16) != ARCH_SEGMENT)
851 	cpkt = NULL;
852     }
853   if (cpkt == NULL)
854     {
855       buf = dbe_sprintf (GTXT ("archive file malformed %s"), arch_name);
856       warnq->append (new Emsg (CMSG_WARN, buf));
857       delete buf;
858       return 1;
859     }
860 
861   char *msg = NULL;
862   unsigned long long pointer_invalid = 0;
863   for (int64_t last_offset = -5000;;)
864     {
865       cpkt = (ARCH_common*) dwin->bind (offset, sizeof (ARCH_common));
866       if (cpkt == NULL)
867 	break;
868       v16 = (uint16_t) cpkt->size;
869       uint32_t cpktsize = dwin->decode (v16);
870       cpkt = (ARCH_common*) dwin->bind (offset, cpktsize);
871       if ((cpkt == NULL) || (cpktsize == 0))
872 	{
873 	  buf = dbe_sprintf (GTXT ("archive file malformed %s"), arch_name);
874 	  warnq->append (new Emsg (CMSG_WARN, buf));
875 	  delete buf;
876 	  break;
877 	}
878 
879       // Update the progress bar
880       if (dbeSession->is_interactive () && ((offset - last_offset) >= 5000))
881 	{
882 	  last_offset = offset;
883 	  int percent = (int) (100.0 * offset / dwin->get_fsize ());
884 	  if (msg == NULL)
885 	    msg = dbe_sprintf (GTXT ("Reading Load Object Data: %s"), name);
886 	  theApplication->set_progress (percent, (percent != 0) ? NULL : msg);
887 	}
888       char *ptr = (char *) cpkt;
889       v16 = (uint16_t) cpkt->type;
890       switch (dwin->decode (v16))
891 	{
892 	case ARCH_SEGMENT:
893 	  {
894 	    ARCH_segment *aseg = (ARCH_segment*) cpkt;
895 	    if (dwin->decode (aseg->version) != ARCH_VERSION)
896 	      {
897 		buf = dbe_sprintf (GTXT ("Archive file version mismatch for %s"), arch_name);
898 		warnq->append (new Emsg (CMSG_ERROR, buf));
899 		delete buf;
900 		if (dbeSession->is_interactive ())
901 		  theApplication->set_progress (0, "");
902 		return 1;
903 	      }
904 	    if (size == 0)
905 	      size = dwin->decode (aseg->textsz);
906 	    Platform_t pltf = (Platform_t) dwin->decode (aseg->platform);
907 	    if (pltf != Unknown)
908 	      {
909 		platform = pltf; // override if known
910 		wsize = (platform == Sparcv9 || platform == Amd64) ? W64 : W32;
911 	      }
912 	    break;
913 	  }
914 	case ARCH_MSG:
915 	  {
916 	    ARCH_message *amsg = (ARCH_message*) cpkt;
917 	    buf = status_str ((Arch_status) dwin->decode (amsg->errcode));
918 	    commentq->append (new Emsg (CMSG_ARCHIVE, buf));
919 	    free (buf);
920 	    break;
921 	  }
922 	case ARCH_INF:
923 	  {
924 	    ARCH_info *ainf = (ARCH_info*) cpkt;
925 	    Emsg *m = new Emsg (CMSG_ARCHIVE, (char*) (ainf + 1));
926 	    commentq->append (m);
927 	    break;
928 	  }
929 	case ARCH_MODULE:
930 	  {
931 	    ARCH_module *amod = (ARCH_module*) cpkt;
932 	    char *str = ((char*) amod) + sizeof (ARCH_module);
933 	    if (streq (str, SP_UNKNOWN_NAME) &&
934 		streq (str + ARCH_STRLEN (str), SP_UNKNOWN_NAME))
935 	      {
936 		mod = noname;
937 		break;
938 	      }
939 	    mod = dbeSession->createModule (this, str);
940 	    mod->lang_code = (Sp_lang_code) dwin->decode (amod->lang_code);
941 	    mod->fragmented = dwin->decode (amod->fragmented);
942 	    str += ARCH_STRLEN (str);
943 	    mod->set_file_name (dbe_strdup (str));
944 	    modules->put (get_basename (str), mod);
945 	    break;
946 	  }
947 	case ARCH_FUNCTION:
948 	  {
949 	    if (mod == NULL)
950 	      break;
951 	    ARCH_function *afnc = (ARCH_function*) cpkt;
952 	    func = dbeSession->createFunction ();
953 	    func->img_offset = dwin->decode (afnc->offset);
954 	    func->size = dwin->decode (afnc->size);
955 	    func->save_addr = dwin->decode (afnc->save_addr)
956 		    - dwin->decode (afnc->offset);
957 	    func->module = mod;
958 	    func->set_name (((char*) afnc) + sizeof (ARCH_function));
959 	    mod->functions->append (func);
960 	    functions->append (func);
961 	    break;
962 	  }
963 	case ARCH_LDINSTR:
964 	  if (mod == NULL)
965 	    break;
966 	  Dprintf (DEBUG_LOADOBJ, "LDINSTR list for %s\n", mod->get_name ());
967 	  if (mod->infoList == NULL)
968 	    mod->infoList = new Vector<inst_info_t*>;
969 	  for (memop_info_t *mp = (memop_info_t*) (ptr + sizeof (ARCH_aninfo));
970 		  (char*) mp < ptr + cpktsize; mp++)
971 	    {
972 	      memop_info_t *memop = new memop_info_t;
973 	      memop->offset = dwin->decode (mp->offset);
974 	      memop->id = dwin->decode (mp->id);
975 	      memop->signature = dwin->decode (mp->signature);
976 	      memop->datatype_id = dwin->decode (mp->datatype_id);
977 	      mod->ldMemops.append (memop);
978 
979 	      inst_info_t *instop = new inst_info_t;
980 	      instop->type = CPF_INSTR_TYPE_LD;
981 	      instop->offset = memop->offset;
982 	      instop->memop = memop;
983 	      mod->infoList->incorporate (instop, offsetCmp);
984 	      Dprintf (DEBUG_LOADOBJ,
985 		       "ld: offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n",
986 		       memop->offset, memop->id, memop->signature,
987 		       memop->datatype_id);
988 	    }
989 	  Dprintf (DEBUG_LOADOBJ, "LDINSTR list of %lld for %s\n",
990 		   (long long) mod->ldMemops.size (), mod->get_name ());
991 	  break;
992 	case ARCH_STINSTR:
993 	  if (mod == NULL)
994 	    break;
995 	  Dprintf (DEBUG_LOADOBJ, NTXT ("STINSTR list for %s\n"), mod->get_name ());
996 	  if (mod->infoList == NULL)
997 	    mod->infoList = new Vector<inst_info_t*>;
998 	  for (memop_info_t *mp = (memop_info_t*) (ptr + sizeof (ARCH_aninfo));
999 		  ((char *) mp) < ptr + cpktsize; mp++)
1000 	    {
1001 	      memop_info_t *memop = new memop_info_t;
1002 	      memop->offset = dwin->decode (mp->offset);
1003 	      memop->id = dwin->decode (mp->id);
1004 	      memop->signature = dwin->decode (mp->signature);
1005 	      memop->datatype_id = dwin->decode (mp->datatype_id);
1006 	      mod->stMemops.append (memop);
1007 
1008 	      inst_info_t *instop = new inst_info_t;
1009 	      instop->type = CPF_INSTR_TYPE_ST;
1010 	      instop->offset = memop->offset;
1011 	      instop->memop = memop;
1012 	      mod->infoList->incorporate (instop, offsetCmp);
1013 	      Dprintf (DEBUG_LOADOBJ,
1014 		       "st: offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n",
1015 		       memop->offset, memop->id, memop->signature,
1016 		       memop->datatype_id);
1017 	    }
1018 	  Dprintf (DEBUG_LOADOBJ, "STINSTR list of %lld for %s\n",
1019 		   (long long) mod->stMemops.size (), mod->get_name ());
1020 	  break;
1021 	case ARCH_PREFETCH:
1022 	  if (mod == NULL)
1023 	    break;
1024 	  Dprintf (DEBUG_LOADOBJ, "PFINSTR list for %s\n", mod->get_name ());
1025 	  if (mod->infoList == NULL)
1026 	    mod->infoList = new Vector<inst_info_t*>;
1027 	  for (memop_info_t *mp = (memop_info_t*) (ptr + sizeof (ARCH_aninfo));
1028 		  ((char*) mp) < ptr + cpkt->size; mp++)
1029 	    {
1030 	      memop_info_t *memop = new memop_info_t;
1031 	      memop->offset = dwin->decode (mp->offset);
1032 	      memop->id = dwin->decode (mp->id);
1033 	      memop->signature = dwin->decode (mp->signature);
1034 	      memop->datatype_id = dwin->decode (mp->datatype_id);
1035 	      mod->pfMemops.append (memop);
1036 
1037 	      inst_info_t *instop = new inst_info_t;
1038 	      instop->type = CPF_INSTR_TYPE_PREFETCH;
1039 	      instop->offset = memop->offset;
1040 	      instop->memop = memop;
1041 	      mod->infoList->incorporate (instop, offsetCmp);
1042 	      Dprintf (DEBUG_LOADOBJ,
1043 		       "pf: offset=0x%04x id=0x%08x sig=0x%08x dtid=0x%08x\n",
1044 		       memop->offset, memop->id, memop->signature,
1045 		       memop->datatype_id);
1046 	    }
1047 	  Dprintf (DEBUG_LOADOBJ, "PFINSTR list of %lld for %s\n",
1048 		   (long long) mod->pfMemops.size (), mod->get_name ());
1049 	  break;
1050 	case ARCH_BRTARGET:
1051 	  if (mod == NULL)
1052 	    break;
1053 	  for (target_info_t *tp = (target_info_t*) (ptr + sizeof (ARCH_aninfo));
1054 		  ((char*) tp) < ptr + cpkt->size; tp++)
1055 	    {
1056 	      target_info_t *bTarget = new target_info_t;
1057 	      bTarget->offset = dwin->decode (tp->offset);
1058 	      mod->bTargets.append (bTarget);
1059 	    }
1060 	  Dprintf (DEBUG_LOADOBJ, "BRTARGET list of %lld for %s\n",
1061 		   (long long) mod->infoList->size (), mod->get_name ());
1062 	  break;
1063 	default:
1064 	  /* Check if the prointer is valid - should be even. */
1065 	  pointer_invalid = (unsigned long long) (offset + cpktsize) & 1;
1066 	  break; // ignore unknown packets
1067 	}
1068       if (pointer_invalid)
1069 	break;
1070       offset += cpktsize;
1071     }
1072   delete msg;
1073   delete dwin;
1074 
1075   if (dbeSession->is_interactive ())
1076     theApplication->set_progress (0, NTXT (""));
1077   return 0;
1078 }
1079 
1080 char *
status_str(Arch_status rv,char *)1081 LoadObject::status_str (Arch_status rv, char */*arg*/)
1082 {
1083   switch (rv)
1084     {
1085     case ARCHIVE_SUCCESS:
1086     case ARCHIVE_EXIST:
1087       return NULL;
1088     case ARCHIVE_BAD_STABS:
1089       return dbe_sprintf (GTXT ("Error: unable to read symbol table of %s"),
1090 			  name);
1091     case ARCHIVE_ERR_SEG:
1092       return dbe_sprintf (GTXT ("Error: unable to read load object file %s"),
1093 			  pathname);
1094     case ARCHIVE_ERR_OPEN:
1095       return dbe_sprintf (GTXT ("Error: unable to open file %s"),
1096 			  pathname);
1097     case ARCHIVE_ERR_MAP:
1098       return dbe_sprintf (GTXT ("Error: unable to map file %s"),
1099 			  pathname);
1100     case ARCHIVE_WARN_CHECKSUM:
1101       return dbe_sprintf (GTXT ("Note: checksum differs from that recorded in experiment for %s"),
1102 			  name);
1103     case ARCHIVE_WARN_MTIME:
1104       return dbe_sprintf (GTXT ("Warning: last-modified time differs from that recorded in experiment for %s"),
1105 			  name);
1106     case ARCHIVE_WARN_HOST:
1107       return dbe_sprintf (GTXT ("Try running er_archive -F on the experiment, on the host where it was recorded"));
1108     case ARCHIVE_ERR_VERSION:
1109       return dbe_sprintf (GTXT ("Error: Wrong version of archive for %s"),
1110 			  pathname);
1111     case ARCHIVE_NO_STABS:
1112       return dbe_sprintf (GTXT ("Note: no stabs or dwarf information in %s"),
1113 			  name);
1114     case ARCHIVE_WRONG_ARCH:
1115 #if ARCH(SPARC)
1116       return dbe_sprintf (GTXT ("Error: file %s is built for Intel, and can't be read on SPARC"),
1117 			  name);
1118 #else
1119       return dbe_sprintf (GTXT ("Error: file %s is built for SPARC, and can't be read on Intel"),
1120 			  name);
1121 #endif
1122     case ARCHIVE_NO_LIBDWARF:
1123       return dbe_strdup (GTXT ("Warning: no libdwarf found to read DWARF symbol tables"));
1124     case ARCHIVE_NO_DWARF:
1125       return dbe_sprintf (GTXT ("Note: no DWARF symbol table in %s"), name);
1126     default:
1127       return dbe_sprintf (GTXT ("Warning: unexpected archive error %d"),
1128 			  (int) rv);
1129     }
1130 }
1131 
1132 uint32_t
get_checksum()1133 LoadObject::get_checksum ()
1134 {
1135   char *errmsg = NULL;
1136   uint32_t crcval = get_cksum (pathname, &errmsg);
1137   if (0 == crcval && errmsg)
1138     {
1139       warnq->append (new Emsg (CMSG_ERROR, errmsg));
1140       free (errmsg);
1141     }
1142   return crcval;
1143 }
1144 
1145 static char*
get_module_map_key(Module * mod)1146 get_module_map_key (Module *mod)
1147 {
1148   return mod->lang_code == Sp_lang_java ? mod->get_name () : mod->file_name;
1149 }
1150 
1151 Module *
get_comparable_Module(Module * mod)1152 LoadObject::get_comparable_Module (Module *mod)
1153 {
1154   if (mod->loadobject == this)
1155     return mod;
1156   if (get_module_map_key (mod) == NULL)
1157     return NULL;
1158   if (seg_modules_map == NULL)
1159     {
1160       seg_modules_map = new HashMap<char*, Module*>;
1161       for (int i = 0; i < seg_modules->size (); i++)
1162 	{
1163 	  Module *m = seg_modules->fetch (i);
1164 	  char *key = get_module_map_key (m);
1165 	  if (key)
1166 	    {
1167 	      seg_modules_map->put (m->file_name, m);
1168 	      char *bname = get_basename (key);
1169 	      if (bname != key)
1170 		seg_modules_map->put (bname, m);
1171 	    }
1172 	}
1173     }
1174 
1175   char *key = get_module_map_key (mod);
1176   Module *cmpMod = seg_modules_map->get (key);
1177   if (cmpMod && cmpMod->comparable_objs == NULL)
1178     return cmpMod;
1179   char *bname = get_basename (key);
1180   if (bname != key)
1181     {
1182       cmpMod = seg_modules_map->get (bname);
1183       if (cmpMod && cmpMod->comparable_objs == NULL)
1184 	return cmpMod;
1185     }
1186   return NULL;
1187 }
1188 
1189 Vector<Histable*> *
get_comparable_objs()1190 LoadObject::get_comparable_objs ()
1191 {
1192   update_comparable_objs ();
1193   if (comparable_objs || dbeSession->expGroups->size () <= 1)
1194     return comparable_objs;
1195   comparable_objs = new Vector<Histable*>(dbeSession->expGroups->size ());
1196   for (int i = 0, sz = dbeSession->expGroups->size (); i < sz; i++)
1197     {
1198       ExpGroup *gr = dbeSession->expGroups->fetch (i);
1199       Histable *h = gr->get_comparable_loadObject (this);
1200       comparable_objs->append (h);
1201       if (h)
1202 	h->comparable_objs = comparable_objs;
1203     }
1204   dump_comparable_objs ();
1205   return comparable_objs;
1206 }
1207 
1208 void
append_module(Module * mod)1209 LoadObject::append_module (Module *mod)
1210 {
1211   seg_modules->append (mod);
1212   if (seg_modules_map == NULL)
1213     seg_modules_map = new HashMap<char*, Module*>;
1214   char *key = get_module_map_key (mod);
1215   if (key)
1216     {
1217       seg_modules_map->put (key, mod);
1218       char *bname = get_basename (key);
1219       if (bname != key)
1220 	seg_modules_map->put (bname, mod);
1221     }
1222 }
1223 
1224 // LIBRARY_VISIBILITY
1225 Function *
get_hide_function()1226 LoadObject::get_hide_function ()
1227 {
1228   if (h_function == NULL)
1229     h_function = dbeSession->create_hide_function (this);
1230   return h_function;
1231 }
1232 
1233 DbeInstr *
get_hide_instr(DbeInstr * instr)1234 LoadObject::get_hide_instr (DbeInstr *instr)
1235 {
1236   if (h_instr == NULL)
1237     {
1238       Function *hf = get_hide_function ();
1239       h_instr = hf->create_hide_instr (instr);
1240     }
1241   return h_instr;
1242 }
1243