diff options
Diffstat (limited to 'gprofng/src/DataObject.cc')
-rw-r--r-- | gprofng/src/DataObject.cc | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/gprofng/src/DataObject.cc b/gprofng/src/DataObject.cc new file mode 100644 index 0000000..870a531 --- /dev/null +++ b/gprofng/src/DataObject.cc @@ -0,0 +1,193 @@ +/* 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. */ + +#include "config.h" +#include <assert.h> +#include <string.h> +#include <ctype.h> + +#include "util.h" +#include "DbeSession.h" +#include "Application.h" +#include "DataObject.h" +#include "Module.h" +#include "debug.h" + +DataObject::DataObject () +{ + name = NULL; + parent = NULL; + master = NULL; + _unannotated_name = NULL; + _typename = NULL; + _instname = NULL; + scope = NULL; + EAs = new Vector<DbeEA*>; + size = 0; + offset = (uint64_t) (-1); +} + +DataObject::~DataObject () +{ + free (_unannotated_name); + free (_typename); + free (_instname); + EAs->destroy (); + delete EAs; +} + +// get_addr() doesn't return an actual address for a DataObject +// but rather synthesises an address-like identifier tuple. +// XXXX since an aggregate and its first element have identical tuples +// may need to arrange for special-purpose sorting "by address" +uint64_t +DataObject::get_addr () +{ + uint64_t addr; + if (parent && parent->get_typename ()) + addr = MAKE_ADDRESS (parent->id, offset); // element + else if (parent) + addr = MAKE_ADDRESS (parent->id, id) | 0x8000000000000000ULL; // Scalar, Unknown + else if (id == dbeSession->get_Scalars_DataObject ()->id) + addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL; // Scalar aggregate + else if (id == dbeSession->get_Unknown_DataObject ()->id) + addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL; // Unknown aggregate + else + addr = MAKE_ADDRESS (id, 0); // aggregate + return addr; +} + +Histable * +DataObject::convertto (Histable_type type, Histable *) +{ + return type == DOBJECT ? this : NULL; +} + +char +DataObject::get_offset_mark () +{ + enum + { + blocksize = 32 + }; + + if (size == 0 || offset == -1) + return '?'; // undefined + if (size > blocksize) + return '#'; // requires multiple blocks + if (size == blocksize && (offset % blocksize == 0)) + return '<'; // fits block entirely + if (offset % blocksize == 0) + return '/'; // starts block + if ((offset + size) % blocksize == 0) + return '\\'; // closes block + if (offset / blocksize == ((offset + size) / blocksize)) + return '|'; // inside block + return 'X'; // crosses blocks unnecessarily +} + +char * +DataObject::get_offset_name () +{ + char *offset_name; + if (parent && parent->get_typename ()) // element + offset_name = dbe_sprintf (GTXT ("%c%+6lld .{%s %s}"), + get_offset_mark (), (long long) offset, + _typename ? _typename : GTXT ("NO_TYPE"), + _instname ? _instname : GTXT ("-")); // "NO_NAME" + else if ((offset != -1) && (offset > 0)) // filler + offset_name = dbe_sprintf (GTXT ("%c%+6lld %s"), get_offset_mark (), + (long long) offset, get_name ()); + else if (parent) // Scalar/Unknown element + offset_name = dbe_sprintf (GTXT (" .%s"), get_unannotated_name ()); + else // aggregate + offset_name = dbe_strdup (get_name ()); + return offset_name; +} + +void +DataObject::set_dobjname (char *type_name, char *inst_name) +{ + _unannotated_name = _typename = _instname = NULL; + if (inst_name) + _instname = dbe_strdup (inst_name); + + char *buf; + if (parent == dbeSession->get_Scalars_DataObject ()) + { + if (type_name) + _typename = dbe_strdup (type_name); + _unannotated_name = dbe_sprintf (NTXT ("{%s %s}"), type_name, + inst_name ? inst_name : NTXT ("-")); + buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name); + } + else if (parent == dbeSession->get_Unknown_DataObject ()) + { + _unannotated_name = dbe_strdup (type_name); + buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name); + } + else + { + if (type_name) + _typename = dbe_strdup (type_name); + if (parent && parent->get_typename ()) + buf = dbe_sprintf (NTXT ("%s.{%s %s}"), + parent->get_name () ? parent->get_name () : NTXT ("ORPHAN"), + type_name ? type_name : NTXT ("NO_TYPE"), + inst_name ? inst_name : NTXT ("-")); // "NO_NAME" + else + buf = dbe_sprintf (NTXT ("{%s %s}"), + type_name ? type_name : NTXT ("NO_TYPE"), + inst_name ? inst_name : NTXT ("-")); // "NO_NAME" + } + name = buf; + dbeSession->dobj_updateHT (this); +} + +void +DataObject::set_name (char *string) +{ + name = dbe_strdup (string); + dbeSession->dobj_updateHT (this); +} + +DbeEA * +DataObject::find_dbeEA (Vaddr EA) +{ + DbeEA *dbeEA; + int left = 0; + int right = EAs->size () - 1; + while (left <= right) + { + int index = (left + right) / 2; + dbeEA = EAs->fetch (index); + if (EA < dbeEA->eaddr) + right = index - 1; + else if (EA > dbeEA->eaddr) + left = index + 1; + else + return dbeEA; + } + + // None found, create a new one + dbeEA = new DbeEA (this, EA); + EAs->insert (left, dbeEA); + return dbeEA; +} |