Wolfgang Thallergcc16 merge934c3885 months agoHistory
1840 lines · 48.8 KB · C++
RawDownload
/* Copyright (C) 2021-2026 Free Software Foundation, Inc.   Contributed by Oracle.    This file is part of GNU Binutils.    This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3, or (at your option)   any later version.    This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.    You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, 51 Franklin Street - Fifth Floor, Boston,   MA 02110-1301, USA.  */ #include "config.h"#include <unistd.h>#include <ar.h>#include <ctype.h>#include <sys/param.h> #include "util.h"#include "DbeSession.h"#include "Experiment.h"#include "DataObject.h"#include "Function.h"#include "DbeView.h"#include "MetricList.h"#include "Module.h"#include "ClassFile.h"#include "LoadObject.h"#include "Disasm.h"#include "CompCom.h"#include "Dwarf.h"#include "DbeFile.h"#include "PathTree.h"#include "Elf.h" Module::Module (){  lang_code = Sp_lang_unknown;  flags = 0;  status = AE_NOTREAD;  openSourceFlag = AE_NOTREAD;  hexVisible = false;  disPath = NULL;  stabsPath = NULL;  stabsTmp = NULL;  disName = NULL;  stabsName = NULL;  indexStabsLink = NULL;  file_name = NULL;  functions = new Vector<Function*>;  loadobject = NULL;  dot_o_file = NULL;  main_source = dbeSession->get_Unknown_Source ();  srcContext = main_source;  includes = new Vector<SourceFile*>;  includes->append (main_source);  curr_inc = NULL;  fragmented = 0;  hwcprof = 0;  hdrOffset = 0;  hasDwarf = false;  hasStabs = false;  readStabs = false;  comComs = NULL;  infoList = NULL;  datatypes = NULL;  objStabs = NULL;  disasm = NULL;  comp_flags = NULL;  comp_dir = NULL;  linkerStabName = NULL;  disMTime = (time_t) 0;  stabsMTime = (time_t) 0;  real_timestamp = 0;  curr_timestamp = 0;  src_items = NULL;  dis_items = NULL;  data_items = NULL;  cur_dbev = NULL;  maximum = NULL;  maximum_inc = NULL;  empty = NULL;  inlinedSubr = NULL;} Module::~Module (){  removeStabsTmp ();  delete includes;  if (comComs != NULL)    {      comComs->destroy ();      delete comComs;    }  free (comp_flags);  free (comp_dir);  free (linkerStabName);  free (disPath);  free (stabsPath);  free (disName);  free (stabsName);  delete functions;  free (file_name);  if (indexStabsLink)    // Remove a link to the current module    indexStabsLink->indexStabsLink = NULL;   if (dot_o_file)    {      delete dot_o_file->dbeFile;      delete dot_o_file;    }  delete src_items;  delete dis_items;  delete disasm;  free (inlinedSubr);  if (lang_code != Sp_lang_java)    delete dbeFile; } Stabs *Module::openDebugInfo (){  setFile ();  objStabs = loadobject->openDebugInfo ();  return objStabs;} voidModule::removeStabsTmp (){  // Remove temporary *.o (got from *.a) after reading Stabs  if (stabsTmp != NULL)    {      unlink (stabsTmp);      free (stabsTmp);      stabsTmp = NULL;    }} int64_tModule::get_size (){  Function *fp;  int index;  int64_t result = 0;  Vec_loop (Function*, functions, index, fp)  {    result += fp->size;  }  return result;} boolModule::is_fortran (){  return Stabs::is_fortran (lang_code);} SourceFile *Module::findSource (const char *fname, bool create){  SourceFile *sf = NULL;  if (loadobject && loadobject->firstExp)    sf = loadobject->firstExp->get_source (fname);  if (sf == NULL)    sf = dbeSession->createSourceFile (fname);  for (int i = 0, sz = includes ? includes->size () : 0; i < sz; i++)    {      SourceFile *sf1 = includes->fetch (i);      if (sf == sf1)	return sf;    }  if (create)    {      if (includes == NULL)	includes = new Vector<SourceFile*>;      includes->append (sf);      return sf;    }  return NULL;} SourceFile *Module::setIncludeFile (char *includeFile){  curr_inc = NULL;  if (includeFile)    curr_inc = findSource (includeFile, true);  return curr_inc;} char *Module::anno_str (char *fnm){  char timebuf1[26], timebuf2[26];  const time_t real_time = (time_t) (unsigned int) real_timestamp;  const time_t curr_time = (time_t) (unsigned int) curr_timestamp;   switch (status)    {    case AE_OK:    case AE_NOTREAD:      return NULL;    case AE_NOSRC:      return dbe_sprintf (GTXT ("Source file `%s' not readable"),			  fnm ? fnm : file_name);    case AE_NOOBJ:      if (lang_code == Sp_lang_java)	{	  Emsg *emsg = get_error ();	  if (emsg)	    {	      char *s = dbe_strdup (emsg->get_msg ());	      remove_msg (emsg);	      return s;	    }	  return dbe_sprintf (GTXT ("Object file `%s.class' not readable"),			      name);	}      return dbe_sprintf (GTXT ("Object file `%s' not readable"), get_name ());    case AE_NOLOBJ:      if (lang_code == Sp_lang_java)	return dbe_sprintf (GTXT ("Object file `%s' not readable"),			    dbeFile ? dbeFile->get_name () : name);      return dbe_sprintf (GTXT ("Object file `%s' not readable"), loadobject->get_pathname ());    case AE_NOSTABS:      return dbe_sprintf (GTXT ("Error reading line-number information in object `%s'; source annotation not available"),			  stabsPath ? stabsPath : NTXT (""));    case AE_NOSYMTAB:      return dbe_sprintf (GTXT ("Error reading symbol table in object `%s'; disassembly annotation not available"),			  disPath ? disPath : NTXT (""));    case AE_TIMESRC:      return dbe_sprintf (GTXT ("Warning! Source file `%s' is newer than the experiment data"),			  main_source->dbeFile->getResolvedPath ());    case AE_TIMEDIS:      return dbe_sprintf (GTXT ("Warning! Object file `%s' is newer than the experiment data"),			  disName ? disName : NTXT (""));    case AE_TIMESTABS:      return dbe_sprintf (GTXT ("Warning! Object file `%s' is newer than the experiment data"),			  stabsName ? stabsName : NTXT (""));    case AE_TIMESTABS_DIFF:      snprintf (timebuf1, sizeof (timebuf1), NTXT ("%s"), ctime (&curr_time));      snprintf (timebuf2, sizeof (timebuf2), NTXT ("%s"), ctime (&real_time));      timebuf1[24] = timebuf2[24] = '\0';      return dbe_sprintf (GTXT ("Warning! Object file `%s' is not the same one that was linked into executable.\n"				"\tObject file: `%s'\n\tcompiled on: %s\n"				"\tExecutable contains object file compiled on: %s"),			  getResolvedObjectPath (), getResolvedObjectPath (),			  timebuf1, timebuf2);    case AE_OTHER:    default:      return dbe_strdup (GTXT ("Annotation computation error"));    }}//anno_str LoadObject *Module::createLoadObject (const char *lo_name){  LoadObject *lo = new LoadObject (lo_name);  lo->dbeFile->filetype |= DbeFile::F_DOT_O;  return lo;} static booltsIsNewer (time_t t1, time_t t2){  return t1 != 0 && t2 != 0 && t1 < t2;} Module::Anno_ErrorsModule::checkTimeStamp (bool chkDis){  /* Check the linked and the real object timestamps due to bug #4796329 */  if (real_timestamp && curr_timestamp && real_timestamp != curr_timestamp)    return AE_TIMESTABS_DIFF;   time_t srctime = main_source->getMTime ();  for (int index = 0; index < dbeSession->nexps (); index++)    {      time_t mtime = dbeSession->get_exp (index)->get_mtime ();      if (tsIsNewer (mtime, srctime))	return AE_TIMESRC;      if (tsIsNewer (mtime, stabsMTime))	return AE_TIMESTABS;      if (chkDis && tsIsNewer (mtime, disMTime))	return AE_TIMEDIS;    }  return AE_OK;}//checkTimeStamp static size_tget_ar_size (char *s, size_t len){  size_t sz = 0;  for (size_t i = 0; i < len; i++)    {      if (s[i] < '0' || s[i] > '9')	break;      sz = sz * 10 + (s[i] - '0');    }  return sz;} static voiddump_hdr_field (char *nm, char *s, size_t len){  Dprintf (DEBUG_READ_AR, NTXT ("  %s "), nm);  for (size_t i = 0; i < len; i++)    Dprintf (DEBUG_READ_AR, "%c", isprint (s[i]) ? s[i] : '?');  Dprintf (DEBUG_READ_AR, NTXT ("  "));  for (size_t i = 0; i < len; i++)    Dprintf (DEBUG_READ_AR, NTXT (" %d"), s[i]);  Dprintf (DEBUG_READ_AR, NTXT (" \n"));} static voiddump_ar_hdr (int lineNum, struct ar_hdr *hdr){  if (DEBUG_READ_AR)    {      Dprintf (DEBUG_READ_AR, NTXT ("Module::read_ar %d\n"), lineNum);      dump_hdr_field (NTXT ("ar_name"), hdr->ar_name, sizeof (hdr->ar_name));      dump_hdr_field (NTXT ("ar_date"), hdr->ar_date, sizeof (hdr->ar_date));      dump_hdr_field (NTXT ("ar_uid"), hdr->ar_uid, sizeof (hdr->ar_uid));      dump_hdr_field (NTXT ("ar_gid"), hdr->ar_gid, sizeof (hdr->ar_gid));      dump_hdr_field (NTXT ("ar_mode"), hdr->ar_mode, sizeof (hdr->ar_mode));      dump_hdr_field (NTXT ("ar_size"), hdr->ar_size, sizeof (hdr->ar_size));      dump_hdr_field (NTXT ("ar_fmag"), hdr->ar_fmag, sizeof (hdr->ar_fmag));    }} boolModule::read_ar (int ar, int obj, char *obj_base){  struct ar_hdr hdr; // Archive header  char magic[SARMAG]; // Magic string from archive  Dprintf (DEBUG_READ_AR, "Module::read_ar %d %p %s %s \n", __LINE__,	   this, STR (obj_base), STR (get_name ()));  // Check the magic string  if ((read_from_file (ar, magic, SARMAG) != SARMAG)       || strncmp (magic, ARMAG, SARMAG))    return false;   // Read and skip the first file in the archive (index file to ld)  if (read_from_file (ar, &hdr, sizeof (hdr)) != sizeof (hdr))    return false;  DEBUG_CODE dump_ar_hdr (__LINE__, &hdr);  if (lseek (ar, get_ar_size (hdr.ar_size, sizeof (hdr.ar_size)), SEEK_CUR)	     == -1)    return false;   // Read the string file where it keeps long file names (if exist)  if (read_from_file (ar, &hdr, sizeof (hdr)) != sizeof (hdr))    return false;  DEBUG_CODE dump_ar_hdr (__LINE__, &hdr);  char *longnames = NULL; // Area with names longer than ~13  size_t longnames_size = 0;  if (!strncmp (hdr.ar_name, NTXT ("//"), 2))    {      longnames_size = get_ar_size (hdr.ar_size, sizeof (hdr.ar_size));      longnames = (char *) xmalloc (longnames_size + 1);      int64_t cnt = read_from_file (ar, longnames, longnames_size);      if (cnt != (int64_t) longnames_size)	{	  free (longnames);	  return false;	}      longnames[longnames_size] = 0;    }  else    // back out, no long file names    lseek (ar, -(sizeof (hdr)), SEEK_CUR);   // Search the ar for the object file name  char ar_buf[sizeof (hdr.ar_name) + 1];  ar_buf[sizeof (hdr.ar_name)] = 0;  while (1)    {      if (read_from_file (ar, &hdr, sizeof (hdr)) != sizeof (hdr))	break;      DEBUG_CODE dump_ar_hdr (__LINE__, &hdr);      char *ar_name;      if (hdr.ar_name[0] != '/')	{ // Name is in the header	  for (size_t i = 0; i < sizeof (hdr.ar_name); i++)	    {	      if (hdr.ar_name[i] == '/')		{		  ar_buf[i] = 0;		  break;		}	      ar_buf[i] = hdr.ar_name[i];	    }	  ar_name = ar_buf;	}      else if (hdr.ar_name[1] == ' ')	{ // Name is blank	  ar_buf[0] = 0;	  ar_name = ar_buf;	}      else	{ // Name is in the string table	  if (longnames == NULL)	    break;	  size_t offset = get_ar_size (hdr.ar_name + 1,				       sizeof (hdr.ar_name) - 1);	  if (offset >= longnames_size)	    break;	  for (size_t i = offset; i < longnames_size; i++)	    {	      if (longnames[i] == '/')		{		  longnames[i] = 0;		  break;		}	    }	  ar_name = longnames + offset;	}      Dprintf (DEBUG_READ_AR, "Module::read_ar %d ar_name=%s\n", __LINE__,	       ar_name);       if (streq (ar_name, obj_base))	{ // create object file	  free (longnames);	  for (size_t objsize = get_ar_size (hdr.ar_size, sizeof (hdr.ar_size));		  objsize > 0;)	    {	      char buf[MAXPATHLEN];	      size_t n = objsize < sizeof (buf) ? objsize : sizeof (buf);	      int64_t cnt = read_from_file (ar, buf, n);	      if (cnt != (int64_t) n)		return false;	      cnt = write (obj, buf, n);	      if (cnt != (int64_t) n)		return false;	      objsize -= n;	    }	  return true;	}      if (lseek (ar, get_ar_size (hdr.ar_size, sizeof (hdr.ar_size)),		 SEEK_CUR) == -1)	break;    }  free (longnames);  return false;} static char *get_obj_name_from_lib (char *nm){  char *base = strrchr (nm, '(');  if (base)    {      size_t last = strlen (base) - 1;      if (base[last] == ')')	return base;    }  return NULL;} boolModule::setFile (){  if ((loadobject->flags & SEG_FLAG_DYNAMIC) != 0)    return true;  if ((loadobject->dbeFile->filetype & DbeFile::F_FICTION) != 0)    return false;  if ((flags & MOD_FLAG_UNKNOWN) != 0)    return true;   if (lang_code == Sp_lang_java)    {      if (dbeFile->get_need_refind ())	{	  char *fnm = dbeFile->get_location ();	  stabsPath = dbe_strdup (fnm);	  stabsName = dbe_strdup (fnm);	  disPath = dbe_strdup (fnm);	  disName = dbe_strdup (fnm);	  stabsMTime = dbeFile->sbuf.st_mtime;	}      return dbeFile->get_location () != NULL;    }   if (dbeFile == NULL)    {      char *objname = get_obj_name_from_lib (name);      if (objname)	{	  // in the format of libpath(obj)

Lines 1–500 of 1840.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t