diff options
author | Vladimir Mezentsev <vladimir.mezentsev@oracle.com> | 2022-03-11 08:58:31 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2022-03-11 08:58:31 +0000 |
commit | bb368aad297fe3ad40cf397e6fc85aa471429a28 (patch) | |
tree | 0ab25909b8fe789d676bbdb00d501d4d485e4afe /gprofng/src/MachineModel.cc | |
parent | a655f19af95eb685ba64f48ee8fc2b3b7a3d886a (diff) | |
download | binutils-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.cc | 317 |
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; +} |