blob: c4cf85475c5ff5bcd21133a11a1eb9e674de390d [file] [log] [blame]
/* Copyright (C) 2021 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. */
#ifndef _HISTABLE_H
#define _HISTABLE_H
//
// The Histable class hierarchy is used to build up a representation of
// the codeobjects (functions, modules, loadObjects, etc.) that make up the
// text address space of a program. The hierarchy is as follows:
//
// Histable (public)
// LoadObject (public)
// Module (public)
// Function (public)
//
// Dataobjects are objects from the data address space of a program.
// The reason for calling the base class "Histable" is because these
// objects are all valid objects for computing histograms on.
// A Histable object represents an object in the program text or data.
#include "dbe_structs.h"
#include "Emsg.h"
#include "Expression.h"
class DataObject;
class Function;
class SourceFile;
class DbeFile;
class DbeLine;
template <class ITEM> class Vector;
class Histable
{
friend class Hist_data;
public:
enum Type
{
INSTR, LINE, FUNCTION, MODULE, LOADOBJECT,
EADDR, MEMOBJ, INDEXOBJ, PAGE, DOBJECT,
SOURCEFILE, IOACTFILE, IOACTVFD, IOCALLSTACK,
HEAPCALLSTACK, EXPERIMENT, OTHER
};
// NameFormat for functions and function based objects
enum NameFormat
{
NA, LONG, SHORT, MANGLED, SONAME = 0x10
};
static NameFormat
make_fmt (int fnfmt, bool sofmt = false)
{
return (NameFormat) (sofmt ? fnfmt | SONAME : fnfmt);
}
static int
fname_fmt (NameFormat fmt)
{
return (fmt & ~SONAME);
}
static bool
soname_fmt (NameFormat fmt)
{
return (fmt & SONAME);
}
Histable ();
char *dump ();
virtual ~Histable ();
virtual char *
get_name (NameFormat = NA)
{
return name; // Return the name of the object
}
virtual void
set_name (char * _name)
{
name = _name;
}
virtual void set_name_from_context (Expression::Context *) { }
virtual Type get_type () = 0;
virtual int64_t
get_size ()
{
return 0;
}
virtual uint64_t
get_addr ()
{
return 0ULL;
}
virtual Vector<Histable*> *get_comparable_objs ();
Histable *get_compare_obj ();
virtual Histable *
convertto (Type, Histable* = NULL)
{
return this;
}
Vector<Histable*> *comparable_objs;
int64_t id; // A unique id of this object, within its specific Type
protected:
char *name; // Object name
int phaseCompareIdx;
void update_comparable_objs ();
void dump_comparable_objs ();
char *type_to_string ();
void delete_comparable_objs ();
};
typedef Histable::Type Histable_type;
// An Other object represents some random histable object
class Other : public Histable
{
public:
virtual Type
get_type ()
{
return OTHER;
}
uint64_t value64;
uint32_t tag;
};
// DbeInstr represents an instruction.
//
// Used by Analyzer for: Disassembly, PCs, Timeline, and Event tabs.
//
class DbeInstr : public Histable
{
public:
DbeInstr (uint64_t _id, int _flags, Function *_func, uint64_t _addr);
virtual Type
get_type ()
{
return INSTR;
}
virtual char *get_name (NameFormat = NA);
virtual int64_t get_size ();
virtual uint64_t get_addr ();
virtual Histable *convertto (Type type, Histable *obj = NULL);
DbeLine *mapPCtoLine (SourceFile *sf);
void add_inlined_info (StringBuilder *sb);
char *get_descriptor ();
int pc_cmp (DbeInstr *instr2);
uint64_t addr;
uint64_t img_offset; // file offset of the image
int flags;
Function *func;
int lineno;
int inlinedInd;
int64_t size;
bool isUsed;
private:
NameFormat current_name_format;
};
class DbeEA : public Histable
{
public:
DbeEA (DataObject *_dobj, Vaddr _eaddr)
{
dobj = _dobj;
eaddr = _eaddr;
};
virtual Type
get_type ()
{
return EADDR;
};
virtual int64_t
get_size ()
{
return 1;
};
virtual uint64_t
get_addr ()
{
return eaddr;
};
virtual char *get_name (NameFormat = NA);
virtual Histable *convertto (Type type, Histable *obj = NULL);
DataObject *dobj;
Vaddr eaddr;
};
// DbeLine represents a line in a source file.
//
// For each top-level DbeLine instance, there are three DbeLine subtypes:
//
// A The top-level DbeLine is associated with a sourceFile & lineno, but
// not any particular function. This form of DbeLine is used
// to represent Analyzer Source tab lines.
//
// B Function-specific lines, those associated with a function in addition
// to the the sourceFile & lineno, are stored in a linked list.
// (see "dbeline_func_next").
// This subtype is used to differentiate a line found in #included source
// that is referenced by multiple functions.
// It is used in the Analyzer Lines tab.
//
// C Function-specific "lines" that don't have line number info are referenced
// from each linked-list element's "dbeline_func_pseudo" field.
// This subtype is needed when a binary doesn't identify line numbers.
// It is used in the Analyzer Lines tab.
//
// When the user switches views between tabs, a selected object in the old
// tab must be translated to an approprate object in the new tab.
// When switching to the Source Tab, the top-level DbeLine (dbeline_base)
// should be used.
// When switching to the Lines Tab, a function-specific dbeline_func_*
// should be used.
//
class DbeLine : public Histable
{
public:
enum Flag
{
OMPPRAGMA = 1
};
DbeLine (Function *_func, SourceFile *sf, int _lineno);
virtual ~DbeLine ();
virtual char *get_name (NameFormat = NA);
virtual int64_t get_size ();
virtual uint64_t get_addr ();
virtual Histable *convertto (Type type, Histable *obj = NULL);
void init_Offset (uint64_t p_offset);
int line_cmp (DbeLine *dbl);
virtual Type
get_type ()
{
return LINE;
}
void
set_flag (Flag flag)
{
flags |= flag;
}
bool
is_set (Flag flag)
{
return (flags & flag) != 0;
}
Function *func; // note: will be NULL in the base (head) dbeline
int lineno;
int64_t size;
SourceFile *sourceFile; // Default source file
SourceFile *include; // included source file or NULL
DbeLine *dbeline_base;
// Head of list, a dbeline associated with sourceFile & lineno, but not func:
// dbeline_base->lineno: non-zero
// dbeline_base->sourceFile: non-null
// dbeline_base->func: NULL
// dbeline_base->dbeline_base: this
// dbeline_base->dbeline_func_next: first func-specific dbeline
DbeLine *dbeline_func_next;
// If non-null, pointer to a function-specific dbeline where:
// dbeline_func_next->lineno: same as dbeline_base->lineno
// dbeline_func_next->sourceFile: same as dbeline_base->sourceFile
// dbeline_func_next->func: pointer to unique function
// dbeline_func_next->dbeline_base: head of the linked list.
// dbeline_func_next->dbeline_func_next: next function-specific dbeline.
private:
int current_name_format;
int64_t offset;
int flags;
};
class HistableFile : public Histable, public DbeMessages
{
public:
HistableFile ();
bool isUsed;
DbeFile *dbeFile;
};
#endif /* _HISTABLE_H */