aboutsummaryrefslogtreecommitdiff
path: root/gprofng/src/DataObject.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/src/DataObject.cc')
-rw-r--r--gprofng/src/DataObject.cc193
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;
+}