Wolfgang Thallergcc16 merge934c3885 months agoHistory
1162 lines · 25.7 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 <assert.h>#include <string.h>#include <ctype.h> #include "demangle.h"#include "util.h"#include "DbeSession.h"#include "Function.h"#include "Module.h"#include "LoadObject.h"#include "Settings.h"#include "DbeFile.h"#include "DbeView.h" struct SrcInfo{  DbeLine *src_line;  SrcInfo *included_from;  SrcInfo *next;}; struct PCInfo{  int64_t offset;  int64_t size;  SrcInfo *src_info;}; Function::Function (uint64_t _id){  id = _id;  instr_id = id << 32;  derivedNode = NULL;  module = NULL;  line_first = line_last = -1;  isOutlineFunction = false;  name = NULL;  mangled_name = NULL;  match_name = NULL;  comparable_name = NULL;  img_fname = NULL;  img_offset = 0;  chksum = 0;  flags = 0;  size = 0;  save_addr = FUNC_NO_SAVE;  linetab = NULL;  def_source = NULL;  indexStabsLink = NULL;  elfSym = NULL;  sources = NULL;  instrs = new Vector<DbeInstr*>;  addrs = NULL;  name_buf = NULL;  current_name_format = Histable::NA;  curr_srcinfo = NULL;  curr_srcfile = NULL;  srcinfo_list = NULL;  defaultDbeLine = NULL;  usrfunc = NULL;  alias = NULL;  instHTable = NULL;  addrIndexHTable = NULL;  isUsed = false;  isHideFunc = false;  inlinedSubr = NULL;  inlinedSubrCnt = 0;} Function::~Function (){  free (mangled_name);  free (match_name);  free (comparable_name);  free (name_buf);  Destroy (linetab);  Destroy (instrs);   while (srcinfo_list)    {      SrcInfo *t = srcinfo_list;      srcinfo_list = t->next;      delete t;    }  delete sources;  delete addrs;  delete[] instHTable;  delete[] addrIndexHTable;  if (indexStabsLink)    // Remove a link to the current function    indexStabsLink->indexStabsLink = NULL;} char *Function::get_name (NameFormat nfmt){  if (nfmt == Histable::NA)    {      DbeView *dbeView = dbeSession->getView (0);      if (dbeView)	nfmt = dbeView->get_name_format ();    }  if (name_buf && (nfmt == current_name_format || nfmt == Histable::NA))    return name_buf;  free (name_buf);  current_name_format = nfmt;   bool soname_fmt = Histable::soname_fmt (nfmt);  int fname_fmt = Histable::fname_fmt (nfmt);  if (fname_fmt == Histable::MANGLED)    name_buf = xstrdup (mangled_name);  else    {      if (module && module->is_fortran ()	  && (streq (name, "MAIN") || streq (name, "MAIN_")))	name_buf = xstrdup (match_name);      else	name_buf = xstrdup (name);       if (fname_fmt == Histable::SHORT)	{	  int i = get_paren (name_buf);	  if (i != -1)	    name_buf[i] = (char) 0;	}    }  if (soname_fmt)    {      char *fname = dbe_sprintf (NTXT ("%s [%s]"), name_buf, module->loadobject->get_name ());      free (name_buf);      name_buf = fname;    }  return name_buf;} uint64_tFunction::get_addr (){  LoadObject *lo = module ? module->loadobject : NULL;  int seg_idx = lo ? lo->seg_idx : -1;  return MAKE_ADDRESS (seg_idx, img_offset);} Histable *Function::convertto (Histable_type type, Histable *obj){  Histable *res = NULL;  SourceFile *source = (SourceFile*) obj;  switch (type)    {    case INSTR:      res = find_dbeinstr (0, 0);      break;    case LINE:      {	// mapPCtoLine will implicitly read line info if necessary	res = mapPCtoLine (0, source);	break;      }    case FUNCTION:      res = this;      break;    case SOURCEFILE:      res = def_source;      break;    default:      assert (0);    }  return res;} voidFunction::set_name (char *string){  if (string == NULL)    return;  set_mangled_name (string);   // strip away any globalization prefix, and save result for matching  char *mname = string;  if (strncmp (string, "$X", 2) == 0 || strncmp (string, ".X", 2) == 0)    {      // name was globalized      char *n = strchr (string + 2, (int) '.');      if (n != NULL)	mname = n + 1;    }  set_match_name (mname);  name = NULL;  if (module)    {      if (name == NULL && *match_name == '_')	{	  int flag = DMGL_PARAMS;	  if (module->lang_code == Sp_lang_java)	    flag |= DMGL_JAVA;	  name = cplus_demangle (match_name, flag);	}    }  if (name == NULL)     // got demangled string    name = dbe_strdup (match_name);  set_comparable_name (name);} voidFunction::set_mangled_name (const char *string){  if (string)    {      free (mangled_name);      mangled_name = dbe_strdup (string);    }} voidFunction::set_match_name (const char *string){  if (string)    {      free (match_name);      match_name = dbe_strdup (string);    }} voidFunction::set_comparable_name (const char *string){  if (string)    {      free (comparable_name);      comparable_name = dbe_strdup (string);       // remove blanks from comparable_name      for (char *s = comparable_name, *s1 = comparable_name;;)	{	  if (*s == 0)	    {	      *s1 = 0;	      break;	    }	  else if (*s != ' ')	    {	      *s1 = *s;	      s1++;	    }	  s++;	}    }} //  This function looks at the name of a function, and determines whether//	or not it may be a derived function -- outline, mtask, or clone --//	If it is, it writes the function name as demangled,//	and sets a pointer to the function from which it was derivedvoidFunction::findDerivedFunctions () {  MPFuncTypes ftype;  int index;  Function *fitem;  unsigned long long line_no;  char *namefmt;  char *subname = mangled_name;  char *demname;   // see if we've already done this  if ((flags & FUNC_FLAG_RESDER) != 0)      return;   // set flag for future  flags = flags | FUNC_FLAG_RESDER;  if (module == NULL)    return;  if (*subname != '_' || subname[1] != '$')   // Not a specially named function    return;   // look for the current versions of naming  if (strncmp (subname + 2, NTXT ("d1"), 2) == 0)    // doall function    ftype = MPF_DOALL;  else if (strncmp (subname + 2, "p1", 2) == 0)     // parallel region function    ftype = MPF_PAR;  else if (strncmp (subname + 2, "l1", 2) == 0)     // single thread loop setup    ftype = MPF_DOALL;  else if (strncmp (subname + 2, "s1", 2) == 0)     // parallel section function    ftype = MPF_SECT;  else if (strncmp (subname + 2, "t1", 2) == 0)     // task function    ftype = MPF_TASK;  else if (strncmp (subname + 2, "o1", 2) == 0)     // outline function    {      ftype = MPF_OUTL;      isOutlineFunction = true;   }  else if (strncmp (subname + 2, "c1", 2) == 0)     // clone function    ftype = MPF_CLONE;  else    // Not an encoded name, just return    return;   // we know it's one of the above prefixes  char *sub = dbe_strdup (name + 4); // starting with base-26 number  char *p = sub;   // skip the base-26 number, and extract the line number  while (isalpha ((int) (*p)) != 0 && *p != 0)    p++;  line_no = atoll (p);   // skip past the number to to the .  while (*p != '.' && *p != 0)    p++;  if (*p == 0)    {      // can't be right      free (sub);      return;    }  // skip the trailing .  p++;  subname = p;  bool foundmatch = false;   // Find the function from which it is derived -- the one that matched subname  Vec_loop (Function*, module->functions, index, fitem)  {    if (streq (subname, fitem->mangled_name))      { // found it	foundmatch = true;	usrfunc = fitem; 	// set the derived node	if ((fitem->flags & FUNC_FLAG_RESDER) == 0)	  // ensure that it, too, is resolved if derived	  fitem->findDerivedFunctions (); 	// Build a demangled name	switch (ftype)	  {	  case MPF_OUTL:	    isOutlineFunction = true;	    namefmt = GTXT ("%s -- outline code from line %lld [%s]");	    derivedNode = fitem->find_dbeinstr (PCLineFlag, line_no);	    break;	  case MPF_PAR:	    namefmt = GTXT ("%s -- OMP parallel region from line %lld [%s]");	    break;	  case MPF_DOALL:	    namefmt = GTXT ("%s -- Parallel loop from line %lld [%s]");	    break;	  case MPF_SECT:	    namefmt = GTXT ("%s -- OMP sections from line %lld [%s]");	    break;	  case MPF_CLONE:	    // Note that clones are handled differently -- no line number and	    //	clones are NOT shown as called from the original	    //	so after constructing the name, just return	    //	later, establish link from clone to parent	    demname = dbe_sprintf (GTXT ("%s -- cloned version [%s]"),				   fitem->get_name (), name);	    free (name);	    // set the name to the demangled version	    name = demname;	    free (sub);	    derivedNode = fitem->find_dbeinstr (PCLineFlag, line_no);	    return;	  case MPF_TASK:	    namefmt = GTXT ("%s -- OMP task from line %lld [%s]");	    break;	  default:	    free (sub);	    return; 	  } 	// Finally, construct the demangled name	demname = dbe_sprintf (namefmt, fitem->get_name (), line_no, name);	free (name);	name = demname;	setLineFirst ((int) line_no);	break;      }  }   if (foundmatch == false && ftype == MPF_OUTL)    {      // Even if derived node was not found, we can demangle      demname = dbe_sprintf (GTXT ("%s -- outline code [%s]"), subname,			     mangled_name);      free (name);      name = demname;    }  free (sub);} SrcInfo *Function::new_srcInfo (){  SrcInfo *t = new SrcInfo ();  t->src_line = NULL;  t->included_from = NULL;  t->next = srcinfo_list;  srcinfo_list = t;  return t;} voidFunction::pushSrcFile (SourceFile* source, int /*lineno*/){  // create new file stack  if (curr_srcfile == NULL)    {      curr_srcfile = source;      return;    }   SrcInfo *src_info = new_srcInfo ();  // In the ideal world, we need a DbeLine(III) here,  // but right now it would make us later believe that there are  // instructions generated for #include lines. To avoid that,  // we ask for a DbeLine(II).  src_info->src_line = curr_srcfile->find_dbeline (this, 0 /*lineno*/);  if (src_info->src_line)    {      src_info->included_from = curr_srcinfo;      curr_srcinfo = src_info;    }  curr_srcfile = source;  setSource ();} SourceFile *Function::popSrcFile (){  if (curr_srcinfo != NULL)    {      curr_srcfile = curr_srcinfo->src_line->sourceFile;      curr_srcinfo = curr_srcinfo->included_from;    }  else    curr_srcfile = NULL;  return curr_srcfile;} voidFunction::copy_PCInfo (Function *from){  if (line_first <= 0)    line_first = from->line_first;  if (line_last <= 0)    line_last = from->line_last;  if (def_source == NULL)    def_source = from->def_source;  for (int i = 0, sz = from->linetab ? from->linetab->size () : 0; i < sz; i++)    {      PCInfo *pcinf = from->linetab->fetch (i);      DbeLine *dbeLine = pcinf->src_info->src_line;      add_PC_info (pcinf->offset, dbeLine->lineno, dbeLine->sourceFile);    }} voidFunction::add_PC_info (uint64_t offset, int lineno, SourceFile *cur_src){  if (lineno <= 0 || size < 0 || offset >= (uint64_t) size)    return;  if (cur_src == NULL)    cur_src = curr_srcfile ? curr_srcfile : def_source;  if (linetab == NULL)    linetab = new Vector<PCInfo*>;   int left = 0;  int right = linetab->size () - 1;  DbeLine *dbeline;  while (left <= right)    {      int x = (left + right) / 2;      PCInfo *pcinf = linetab->fetch (x);      uint64_t pcinf_offset = ((uint64_t) pcinf->offset);      if (offset == pcinf_offset)	{

Lines 1–500 of 1162.

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