aboutsummaryrefslogtreecommitdiff
path: root/gprofng/src/MachineModel.cc
diff options
context:
space:
mode:
authorVladimir Mezentsev <vladimir.mezentsev@oracle.com>2022-03-11 08:58:31 +0000
committerNick Clifton <nickc@redhat.com>2022-03-11 08:58:31 +0000
commitbb368aad297fe3ad40cf397e6fc85aa471429a28 (patch)
tree0ab25909b8fe789d676bbdb00d501d4d485e4afe /gprofng/src/MachineModel.cc
parenta655f19af95eb685ba64f48ee8fc2b3b7a3d886a (diff)
downloadbinutils-bb368aad297fe3ad40cf397e6fc85aa471429a28.zip
binutils-bb368aad297fe3ad40cf397e6fc85aa471429a28.tar.gz
binutils-bb368aad297fe3ad40cf397e6fc85aa471429a28.tar.bz2
gprofng: a new GNU profiler
top-level * Makefile.def: Add gprofng module. * configure.ac: Add --enable-gprofng option. * src-release.sh: Add gprofng. * Makefile.in: Regenerate. * configure: Regenerate. * gprofng: New directory. binutils * MAINTAINERS: Add gprofng maintainer. * README-how-to-make-a-release: Add gprofng. include. * collectorAPI.h: New file. * libcollector.h: New file. * libfcollector.h: New file.
Diffstat (limited to 'gprofng/src/MachineModel.cc')
-rw-r--r--gprofng/src/MachineModel.cc317
1 files changed, 317 insertions, 0 deletions
diff --git a/gprofng/src/MachineModel.cc b/gprofng/src/MachineModel.cc
new file mode 100644
index 0000000..15f493a
--- /dev/null
+++ b/gprofng/src/MachineModel.cc
@@ -0,0 +1,317 @@
+/* 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 <string.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include "DbeSession.h"
+#include "Command.h"
+#include "Application.h"
+#include "MemorySpace.h"
+#include "i18n.h"
+
+#define MAXARGS 20
+
+static const char *LIBNAME = "../lib/analyzer/lib/machinemodels";
+
+char *
+DbeSession::find_mach_model (char *name)
+{
+ // Read current working directory to see if it's there
+ if (name[0] == '/')
+ {
+ // Absolute path given
+ char *path = dbe_sprintf (NTXT ("%s.ermm"), name);
+ if (access (path, R_OK | F_OK) == 0)
+ return path;
+ free (path);
+ // Don't try anywhere else
+ return NULL;
+ }
+
+ char *path = dbe_sprintf (NTXT ("./%s.ermm"), name);
+ if (access (path, R_OK | F_OK) == 0)
+ return path;
+ free (path);
+
+
+ // Read the user's home directory to see if it's there
+ char *home = getenv (NTXT ("HOME"));
+ if (home != NULL)
+ {
+ path = dbe_sprintf (NTXT ("%s/%s.ermm"), home, name);
+ if (access (path, R_OK | F_OK) == 0)
+ return path;
+ free (path);
+ }
+ if (strchr (name, (int) '/') != NULL)
+ // name has a slash; don't look in system installation directory
+ return NULL;
+
+ // Read system installation directory to see if it's there
+ path = dbe_sprintf ("%s/%s/%s.ermm", theApplication->get_run_dir (),
+ LIBNAME, name);
+ if (access (path, R_OK | F_OK) == 0)
+ return path;
+ free (path);
+ return NULL;
+}
+
+// Handle the definitions from a machinemodel file
+// Return value is NULL if it was OK, or an error message if not
+char *
+DbeSession::load_mach_model (char *_name)
+{
+ CmdType cmd_type;
+ int arg_count, cparam;
+ char *cmd, *end_cmd;
+ char *arglist[MAXARGS];
+ char *ret = NULL;
+ char *path = NULL;
+ FILE *fptr = NULL;
+
+ // Does name have .ermm suffix? If so, strip it away
+ char *name = dbe_strdup (_name);
+ size_t len = strlen (name);
+ if (len > 5 && strcmp (name + len - 5, ".ermm") == 0)
+ name[len - 5] = 0;
+
+ if ((mach_model_loaded != NULL) && (strcmp (name, mach_model_loaded) == 0))
+ {
+ ret = dbe_sprintf (GTXT ("Machine model %s is already loaded\n"), name);
+ free (name);
+ return ret;
+ }
+ else if (mach_model_loaded == NULL && len == 0)
+ {
+ ret = dbe_sprintf (GTXT ("No Machine model is loaded\n"));
+ free (name);
+ return ret;
+ }
+
+ if (len != 0)
+ {
+ // zero-length just means unload any previously loaded model; only look if non-zero
+ path = find_mach_model (name);
+ if (path == NULL)
+ {
+ ret = dbe_sprintf (GTXT ("Machine model %s not found\n"), name);
+ free (name);
+ return ret;
+ }
+ fptr = fopen (path, NTXT ("r"));
+ if (fptr == NULL)
+ {
+ ret = dbe_sprintf (GTXT ("Open of Machine model %s, file %s failed\n"), name, path);
+ free (path);
+ free (name);
+ return ret;
+ }
+ }
+
+ // We are now committed to make the new machine model the loaded one;
+ // Delete any MemoryObjects from any previously loaded machinemodel
+ if (dbeSession->mach_model_loaded != NULL)
+ {
+ Vector <char *> *oldobjs = MemorySpace::getMachineModelMemObjs
+ (dbeSession->mach_model_loaded);
+ for (int i = 0; i < oldobjs->size (); i++)
+ MemorySpace::mobj_delete (oldobjs->fetch (i));
+ delete oldobjs;
+ free (mach_model_loaded);
+ }
+ if (len == 0)
+ {
+ mach_model_loaded = NULL;
+ free (name);
+ // and there's no "loading" to do; just return
+ return NULL;
+ }
+ else
+ mach_model_loaded = name;
+
+ int line_no = 0;
+ end_cmd = NULL;
+
+ while (!feof (fptr))
+ {
+ char *script = read_line (fptr);
+ if (script == NULL)
+ continue;
+
+ line_no++;
+ strtok (script, NTXT ("\n"));
+
+ // extract the command
+ cmd = strtok (script, NTXT (" \t"));
+ if (cmd == NULL || *cmd == '#' || *cmd == '\n')
+ {
+ free (script);
+ continue;
+ }
+
+ char *remainder = strtok (NULL, NTXT ("\n"));
+ // now extract the arguments
+ int nargs = 0;
+ for (;;)
+ {
+ if (nargs >= MAXARGS)
+ {
+ ret = dbe_sprintf (GTXT ("Warning: more than %d arguments to %s command, line %d\n"),
+ MAXARGS, cmd, line_no);
+ continue;
+ }
+
+ char *nextarg = strtok (remainder, NTXT ("\n"));
+
+ if (nextarg == NULL || *nextarg == '#')
+ // either the end of the line, or a comment indicator
+ break;
+ arglist[nargs++] = parse_qstring (nextarg, &end_cmd);
+ remainder = end_cmd;
+ if (remainder == NULL)
+ break;
+
+ // skip any blanks or tabs to get to next argument
+ while ((*remainder == ' ') || (*remainder == '\t'))
+ remainder++;
+ }
+
+ cmd_type = Command::get_command (cmd, arg_count, cparam);
+ // check for extra arguments
+ if (cmd_type != UNKNOWN_CMD && cmd_type != INDXOBJDEF && nargs > arg_count)
+ ret = dbe_sprintf (GTXT ("Warning: extra arguments to %s command, line %d\n"),
+ cmd, line_no);
+ if (nargs < arg_count)
+ {
+ ret = dbe_sprintf (GTXT ("Error: missing arguments to %s command, line %d\n"),
+ cmd, line_no);
+
+ // ignore this command
+ free (script);
+ continue;
+ }
+
+ switch (cmd_type)
+ {
+ case INDXOBJDEF:
+ {
+ char *err = dbeSession->indxobj_define (arglist[0], NULL,
+ arglist[1], (nargs >= 3) ? PTXT (arglist[2]) : NULL,
+ (nargs >= 4) ? PTXT (arglist[3]) : NULL);
+ if (err != NULL)
+ ret = dbe_sprintf (GTXT (" %s: line %d `%s %s %s'\n"),
+ err, line_no, cmd, arglist[0], arglist[1]);
+ break;
+ }
+ case COMMENT:
+ // ignore the line
+ break;
+ default:
+ {
+ // unexpected command in a machinemodel file
+ ret = dbe_sprintf (GTXT ("Unexpected command in machinemodel file %s on line %d: `%.64s'\n"),
+ path, line_no, cmd);
+ break;
+ }
+ }
+ free (script);
+ }
+ fclose (fptr);
+ return ret;
+}
+
+Vector<char*> *
+DbeSession::list_mach_models ()
+{
+ Vector<char*> *model_names = new Vector<char*>();
+
+ // Open the current directory to read the entries there
+ DIR *dir = opendir (NTXT ("."));
+ if (dir != NULL)
+ {
+ struct dirent *entry = NULL;
+ while ((entry = readdir (dir)) != NULL)
+ {
+ size_t len = strlen (entry->d_name);
+ if (len < 5 || strcmp (entry->d_name + len - 5, ".ermm") != 0)
+ continue;
+ char *model = dbe_strdup (entry->d_name);
+
+ // remove the .ermm suffix
+ model[len - 5] = 0;
+
+ // add to vector
+ model_names->append (dbe_strdup (model));
+ }
+ closedir (dir);
+ }
+
+ // Read the user's home directory to list the models there
+ char *home = getenv ("HOME");
+ if (home != NULL)
+ {
+ dir = opendir (home);
+ if (dir != NULL)
+ {
+ struct dirent *entry = NULL;
+ while ((entry = readdir (dir)) != NULL)
+ {
+ size_t len = strlen (entry->d_name);
+ if (len < 5 || strcmp (entry->d_name + len - 5, ".ermm") != 0)
+ continue;
+ char *model = dbe_strdup (entry->d_name);
+
+ // remove the .ermm suffix
+ model[len - 5] = 0;
+
+ // add to vector
+ model_names->append (dbe_strdup (model));
+ }
+ closedir (dir);
+ }
+ }
+
+ // Read system installation directory to list the models there
+ char *sysdir = dbe_sprintf ("%s/%s", theApplication->get_run_dir (), LIBNAME);
+
+ dir = opendir (sysdir);
+ if (dir != NULL)
+ {
+ struct dirent *entry = NULL;
+ while ((entry = readdir (dir)) != NULL)
+ {
+ size_t len = strlen (entry->d_name);
+ if (len < 5 || strcmp (entry->d_name + len - 5, ".ermm") != 0)
+ continue;
+ char *model = dbe_strdup (entry->d_name);
+
+ // remove the .ermm suffix
+ model[len - 5] = 0;
+
+ // add to vector
+ model_names->append (dbe_strdup (model));
+ }
+ closedir (dir);
+ }
+ return model_names;
+}