/* 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 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 *get_comparable_objs (); Histable *get_compare_obj (); virtual Histable * convertto (Type, Histable* = NULL) { return this; } Vector *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 */