aboutsummaryrefslogtreecommitdiff
path: root/gprofng/src/Symbol.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gprofng/src/Symbol.cc')
-rw-r--r--gprofng/src/Symbol.cc226
1 files changed, 226 insertions, 0 deletions
diff --git a/gprofng/src/Symbol.cc b/gprofng/src/Symbol.cc
new file mode 100644
index 0000000..82fe788
--- /dev/null
+++ b/gprofng/src/Symbol.cc
@@ -0,0 +1,226 @@
+/* Copyright (C) 2025 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 "DbeSession.h"
+#include "Function.h"
+#include "LoadObject.h"
+#include "Module.h"
+#include "Symbol.h"
+
+
+template<> void Vector<Symbol *>::dump (const char *msg)
+{
+ if (msg == NULL)
+ msg = "#";
+ Dprintf (1, NTXT ("\n%s Vector<Symbol *> [%lld]\n"), msg, (long long) size ());
+ if (size () > 0)
+ Dprintf (1, " value | img_offset | size | flags|local_ind|\n");
+ for (long i = 0, sz = size (); i < sz; i++)
+ {
+ Symbol *sp = get (i);
+ Dprintf (1, " %3ld ", i);
+ sp->dump ();
+ }
+ if (size () > 0)
+ Dprintf (1, "===== END of Symbol::dump: %s =========\n\n", msg);
+}
+
+void
+Symbol::dump (const char *msg)
+{
+ if (msg)
+ Dprintf (1, "%s\n", msg);
+ Dprintf (1, "%8lld |%11lld |%6d |%5d |%8d |%s\n", (long long) value,
+ (long long) img_offset, (int) size, flags, local_ind,
+ name ? name : "NULL");
+}
+
+Symbol::Symbol (Vector<Symbol*> *vec)
+{
+ func = NULL;
+ lang_code = Sp_lang_unknown;
+ value = 0;
+ save = 0;
+ size = 0;
+ img_offset = 0;
+ name = NULL;
+ alias = NULL;
+ local_ind = -1;
+ flags = 0;
+ defined = false;
+ if (vec)
+ vec->append (this);
+}
+
+Symbol::~Symbol ()
+{
+ free (name);
+}
+
+static int
+cmpSym (const void *a, const void *b)
+{
+ Symbol *item1 = *((Symbol **) a);
+ Symbol *item2 = *((Symbol **) b);
+ return (item1->value > item2->value) ? 1 :
+ (item1->value == item2->value) ? 0 : -1;
+}
+
+static int
+cmpSymName (const void *a, const void *b)
+{
+ Symbol *item1 = *((Symbol **) a);
+ Symbol *item2 = *((Symbol **) b);
+ return strcmp (item1->name, item2->name);
+}
+
+Symbol *
+Symbol::get_symbol (Vector<Symbol*> *syms, uint64_t pc)
+{
+ if (syms != NULL && pc != 0)
+ {
+ Symbol *sp = new Symbol;
+ sp->value = pc;
+ long i = syms->bisearch (0, -1, &sp, cmpSym);
+ delete sp;
+ if (i != -1)
+ return syms->get (i)->cardinal ();
+ }
+ return NULL;
+}
+
+Symbol *
+Symbol::get_symbol (Vector<Symbol*> *syms, char *linker_name)
+{
+ if (syms != NULL && linker_name != NULL)
+ {
+ Symbol *sp = new Symbol;
+ sp->name = linker_name;
+ long i = syms->bisearch (0, -1, &sp, cmpSymName);
+ sp->name = NULL;
+ delete sp;
+ if (i != -1)
+ return syms->get (i)->cardinal ();
+ }
+ return NULL;
+}
+
+Vector<Symbol *> *
+Symbol::sort_by_name (Vector<Symbol *> *syms)
+{
+ if (VecSize (syms) == 0)
+ return NULL;
+ Vector<Symbol *> *symbols = syms->copy ();
+ symbols->sort (cmpSymName);
+ return symbols;
+}
+
+Vector<Symbol *> *
+Symbol::find_symbols (Vector<Symbol*> *syms, Vector<Range *> *ranges)
+{
+ // 'syms' and 'ranges' must already be sorted.
+ // return symbols matched by 'ranges'
+ if (VecSize (syms) == 0 || VecSize (ranges) == 0)
+ return NULL;
+ Vector<Symbol *> *symbols = new Vector<Symbol*> ();
+
+ // Use binary search to find a suitable index in 'syms'
+ int ind = 0;
+ uint64_t addr = ranges->get (0)->low;
+ for (int lo = 0, hi = syms->size (); lo < hi;)
+ {
+ int mid = (hi + lo) >> 1;
+ Symbol *sym = syms->get (mid);
+ if (sym->value == addr)
+ {
+ ind = mid;
+ break;
+ }
+ else if (sym->value > addr)
+ hi = mid - 1;
+ else
+ {
+ ind = mid;
+ lo = mid + 1;
+ }
+ }
+
+ for (int i = 0, r_sz = ranges->size (), sz = syms->size (); ind < sz; ind++)
+ {
+ Symbol *sym = syms->get (ind);
+ while (i < r_sz)
+ {
+ Range *r = ranges->get (i);
+ if (sym->value < r->low)
+ break;
+ if (sym->value <= r->high)
+ {
+ symbols->append (sym);
+ break;
+ }
+ i++;
+ }
+ if (i >= r_sz)
+ break;
+ }
+ if (DUMP_ELF_SYM)
+ {
+ syms->dump ( "Symbol::find_symbols: syms");
+ symbols->dump ("Symbol::find_symbols: symbols");
+ }
+ if (symbols->size () != 0)
+ return symbols;
+ delete symbols;
+ return NULL;
+}
+
+/* Create and append a new function to the 'module'.
+ * Copy attributes (size, name, etc) from Simbol, */
+Function *
+Symbol::createFunction (Module *module)
+{
+ if (func)
+ return func;
+ func = dbeSession->createFunction ();
+ func->img_fname = module->file_name;
+ func->img_offset = img_offset;
+ func->save_addr = save;
+ func->size = size;
+ func->module = module;
+ func->set_name (name);
+ module->functions->append (func);
+ module->loadobject->functions->append (func);
+ return func;
+}
+
+template<> void Vector<Range *>::dump (const char *msg)
+{
+ Dprintf (1, NTXT ("%s Vector<Range *> [%lld]\n"),
+ msg ? msg : "#", (long long) size ());
+ for (long i = 0, sz = size (); i < sz; i++)
+ {
+ Range *p = get (i);
+ Dprintf (1, "%3ld 0x%08llx 0x%08llx (%lld - %lld)\n", i,
+ (long long) p->low, (long long) p->high,
+ (long long) p->low, (long long) p->high);
+ }
+} \ No newline at end of file