[PATCH 1/2] covoar: Add symbol set reader and ELF data parser to covoar.
Joel Sherrill
joel at rtems.org
Thu Apr 26 22:51:48 UTC 2018
>
> 8 insertions(+), 11 deletions(-)
> create mode 100644 tester/covoar/SymbolSet.cpp
> create mode 100644 tester/covoar/SymbolSet.h
> create mode 100644 tester/covoar/SymbolSetReader.cpp
> create mode 100644 tester/covoar/SymbolSetReader.h
>
> diff --git a/tester/covoar/SymbolSet.cpp b/tester/covoar/SymbolSet.cpp
> new file mode 100644
> index 0000000..dfa0fa1
> --- /dev/null
> +++ b/tester/covoar/SymbolSet.cpp
> @@ -0,0 +1,153 @@
> +/*
> + * Copyright 2014 Krzysztof Miesowicz (krzysztof.miesowicz at gmail.com)
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <iostream>
> +#include <fstream>
> +#include <cstdio>
> +
> +#include "SymbolSet.h"
> +
> +#include "rld.h"
> +#include "rld-process.h"
> +#include "rld-symbols.h"
> +#include "rld-files.h"
> +
> +namespace Symbols
> +{
> + SymbolSet::SymbolSet ()
> + {
> + }
> +
> + SymbolSet::~SymbolSet ()
> + {
> + }
> +
> + std::string SymbolSet::parseElfDataLine (std::string line)
> + {
> + std::string symbol = "";
> + int funcStartPos = 64;
> + if (line.find ("STT_FUNC") != std::string::npos)
> + {
> + symbol = line.substr (funcStartPos);
> + symbol = symbol.substr (0, symbol.find (' '));
> + }
> + return symbol;
> + }
> +
> + std::string SymbolSet::getLibname (std::string libPath)
> + {
> + std::string libname = "", base = "", temp;
> + size_t pos = libPath.find_last_of ('/');
> + if (pos != std::string::npos)
> + {
> + temp = libPath.substr (0, pos);
> + libname = libPath.substr (pos + 1);
> + }
> + pos = temp.find_last_of ('/');
> + if (pos != std::string::npos)
> + {
> + base = temp.substr (pos + 1);
> + }
> + return base + "/" + libname;
> + }
> +
> + void SymbolSet::parseElfData (rld::process::tempfile& elfData,
> + const std::string& lib)
> + {
> + std::string line, symbol;
> + elfData.open( true );
> + while ( true )
> + {
> + elfData.read_line (line);
> + if ( line.empty() ) break;
> + symbol = parseElfDataLine (line);
> + if (symbol.length () > 0)
> + {
> + symbols.push_back (symbol + " " + getLibname (lib));
> + }
> + }
> + }
> +
> + void SymbolSet::generateSymbolFile (rld::process::tempfile& filePath,
> + std::string target)
> + {
> + rld::files::cache kernel;
> + rld::symbols::table symbolsTable;
> +
> + for (std::string lib : libraries)
> + {
> + /*
> + * Load the symbols from the kernel.
> + */
> + try
> + {
> + /*
> + * Load the kernel ELF file symbol table.
> + */
> + kernel.open ();
> + kernel.add (lib);
> + kernel.load_symbols (symbolsTable, true);
> +
> + /*
> + * Create a symbols file.
> + */
> + std::ofstream mout;
> + mout.open (filePath.name().c_str());
> + if (!mout.is_open ())
> + throw rld::error ("map file open failed", "map");
> + mout << "RTEMS Kernel Symbols Map" << std::endl
> + << " kernel: " << lib << std::endl
> + << std::endl;
> + rld::symbols::output (mout, symbolsTable);
> + mout.close ();
> + }
> + catch (...)
> + {
> + kernel.close ();
> + throw;
> + }
> +
> + kernel.close ();
> +
> + try
> + {
> + parseElfData (filePath, lib);
> + }
> + catch (std::exception& e)
> + {
> + std::cout << "ERROR while parsing symbols output: " << e.what ()
> + << std::endl;
> + }
> + filePath.close ();
> + }
> +
> + std::ofstream outputFile (filePath.name ());
> + for (std::string symbol : symbols)
> + outputFile << symbol << std::endl;
> + outputFile.close ();
> + }
> +}
> diff --git a/tester/covoar/SymbolSet.h b/tester/covoar/SymbolSet.h
> new file mode 100644
> index 0000000..20d7327
> --- /dev/null
> +++ b/tester/covoar/SymbolSet.h
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2014 Krzysztof Miesowicz (krzysztof.miesowicz at gmail.com)
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> notice,
> + * this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> + * this list of conditions and the following disclaimer in the
> documentation
> + * and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> "AS IS"
> + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
> THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE
> + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
> BE
> + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
> THE
> + * POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef SYMBOLSET_H_
> +#define SYMBOLSET_H_
> +
> +#include <string>
> +#include <vector>
> +
> +#include "rld-process.h"
> +
> +namespace Symbols
> +{
> + class SymbolSet
> + {
> + public:
> + SymbolSet ();
> + virtual ~SymbolSet ();
> +
> + const std::string getName () const
> + {
> + return name;
> + }
> +
> + void setName (const std::string& name)
> + {
> + this->name = name;
> + }
> +
> + const std::vector<std::string> getLibraries () const
> + {
> + return libraries;
> + }
> +
> + void addLibrary (std::string libraryPath)
> + {
> + libraries.push_back (libraryPath);
> + }
> +
> + void generateSymbolFile (rld::process::tempfile& filePath,
> + std::string target);
> +
> + private:
> + std::string name;
> + std::vector<std::string> libraries;
> + std::vector<std::string> symbols;
> +
> + std::string parseElfDataLine (std::string line);
> + std::string getLibname (std::string libPath);
> + void parseElfData (rld::process::tempfile& elfData,
> + const std::string& lib);
> + };
> +}
> +
> +#endif /* SYMBOLSET_H_ */
> diff --git a/tester/covoar/SymbolSetReader.cpp b/tester/covoar/
> SymbolSetReader.cpp
> new file mode 100644
> index 0000000..886e256
> --- /dev/null
> +++ b/tester/covoar/SymbolSetReader.cpp
> @@ -0,0 +1,82 @@
> +/*
> + * SymbolSetReader.cpp
> + *
> + * Created on: Aug 5, 2014
> + * Author: Krzysztof Mięsowicz <krzysztof.miesowicz at gmail.com>
> + */
> +
> +#include "SymbolSetReader.h"
> +#include "iostream"
> +#include "fstream"
> +
> +namespace Symbols {
> +
> +SymbolSetReader::SymbolSetReader() {
> + // TODO Auto-generated constructor stub
> +
> +}
> +
> +SymbolSetReader::~SymbolSetReader() {
> + // TODO Auto-generated destructor stub
> +}
> +
> +std::vector<SymbolSet> SymbolSetReader::readSetFile(string filepath) {
> + std::vector<SymbolSet> setList { };
> + ifstream file(filepath);
> + string line;
> + while (getline(file, line)) {
> + if (line.find("symbolset:") != std::string::npos) {
> + setList.emplace_back();
> + } else if (line.length() > 0) {
> +
> + auto pair = parseLine(line);
> +
> + if(pair.first == "name") {
> + if (setList.empty()) {
> + setList.emplace_back();
> + }
> + setList.rbegin()->setName(pair.second);
> + continue;
> + }
> + if(pair.first == "lib") {
> + setList.rbegin()->addLibrary(pair.second);
> + continue;
> + }
> +
> + std::cout << "Invalid entry in configuration file
> : " << line << endl;
> + break;
> + }
> + }
> + file.close();
> + return setList;
> +}
> +
> +std::pair<string, string> SymbolSetReader::parseLine(string line) {
> + size_t delimeterPosition = line.find('=');
> +
> + if (delimeterPosition != std::string::npos) {
> + string key = line.substr(0, delimeterPosition);
> + string value = line.substr(delimeterPosition + 1);
> + return {trim(key), trim(value)};
> + }
> +
> + return {"",""};
> +}
> +
> +string& SymbolSetReader::trim(string& str) {
> + // trim trailing spaces
> + size_t endpos = str.find_last_not_of(" \t\n\r");
> + if (string::npos != endpos) {
> + str = str.substr(0, endpos + 1);
> + }
> +
> + // trim leading spaces
> + size_t startpos = str.find_first_not_of(" \t\n\r");
> + if (string::npos != startpos) {
> + str = str.substr(startpos);
> + }
> +
> + return str;
> +}
> +
> +} /* namespace Symbols */
> diff --git a/tester/covoar/SymbolSetReader.h b/tester/covoar/
> SymbolSetReader.h
> new file mode 100644
> index 0000000..24e83cf
> --- /dev/null
> +++ b/tester/covoar/SymbolSetReader.h
> @@ -0,0 +1,34 @@
> +/*
> + * SymbolSetReader.h
> + *
> + * Created on: Aug 5, 2014
> + * Author: Krzysztof Mięsowicz <krzysztof.miesowicz at gmail.com>
> + */
> +
> +#ifndef SYMBOLSETREADER_H_
> +#define SYMBOLSETREADER_H_
> +
> +#include <string>
> +#include <vector>
> +#include <utility>
> +#include "SymbolSet.h"
> +
> +using namespace std;
> +
> +namespace Symbols {
> +
> +class SymbolSetReader {
> +public:
> + SymbolSetReader();
> + virtual ~SymbolSetReader();
> +
> + vector<SymbolSet> readSetFile(string filepath);
> +protected:
> + pair<string, string> parseLine(string line);
> +private:
> + string& trim(string& str);
> +};
> +
> +} /* namespace Symbols */
> +
> +#endif /* SYMBOLSETREADER_H_ */
> diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
> index c36b00a..9d00428 100644
> --- a/tester/covoar/covoar.cc
> +++ b/tester/covoar/covoar.cc
> @@ -22,6 +22,8 @@
> #include "ReportsBase.h"
> #include "TargetFactory.h"
> #include "GcovData.h"
> +#include "SymbolSetReader.h"
> +#include "SymbolSet.h"
>
> #include "rld-process.h"
>
> @@ -44,6 +46,7 @@ std::list<Coverage::ExecutableInfo*>
> executablesToAnalyze;
> const char* explanations = NULL;
> char* progname;
> const char* symbolsFile = NULL;
> +const char* symbolSetFile = NULL;
> const char* gcnosFileName = NULL;
> char gcnoFileName[FILE_NAME_LENGTH];
> char gcdaFileName[FILE_NAME_LENGTH];
> @@ -51,7 +54,7 @@ char
> gcovBashCommand[256];
> const char* target = NULL;
> const char* format = NULL;
> FILE* gcnosFile = NULL;
> -Gcov::GcovData* gcovFile;
> +Gcov::GcovData* gcovFile;
>
> /*
> * Print program usage message
> @@ -70,13 +73,15 @@ void usage()
> "(RTEMS, QEMU, TSIM or Skyeye)\n"
> " -E EXPLANATIONS - name of file with explanations\n"
> " -s SYMBOLS_FILE - name of file with symbols of
> interest\n"
> + " -S SYMBOL_SET_FILE - path to symbol_sets.cfg\n"
> " -1 EXECUTABLE - name of executable to get symbols
> from\n"
> " -e EXE_EXTENSION - extension of the executables to
> analyze\n"
> " -c COVERAGEFILE_EXTENSION - extension of the coverage files to
> analyze\n"
> " -g GCNOS_LIST - name of file with list of *.gcno
> files\n"
> " -p PROJECT_NAME - name of the project\n"
> " -C ConfigurationFileName - name of configuration file\n"
> - " -O Output_Directory - name of output directory (default=."
> + " -O Output_Directory - name of output directory (default=.\n"
> + " -d debug - disable cleaning of tempfiles."
> "\n",
> progname,
> progname
> @@ -134,6 +139,7 @@ int main(
> const char* singleExecutable = NULL;
> rld::process::tempfile objdumpFile( ".dmp" );
> rld::process::tempfile err( ".err" );
> + rld::process::tempfile syms( ".syms" );
> bool debug = false;
> std::string option;
>
> @@ -144,7 +150,7 @@ int main(
> //
> progname = argv[0];
>
> - while ((opt = getopt(argc, argv, "1:L:e:c:g:E:f:s:T:O:p:v:d")) != -1) {
> + while ((opt = getopt(argc, argv, "1:L:e:c:g:E:f:s:S:T:O:p:v:d")) !=
> -1) {
> switch (opt) {
> case '1': singleExecutable = optarg; break;
> case 'L': dynamicLibrary = optarg; break;
> @@ -154,6 +160,7 @@ int main(
> case 'E': explanations = optarg; break;
> case 'f': format = optarg; break;
> case 's': symbolsFile = optarg; break;
> + case 'S': symbolSetFile = optarg; break;
> case 'T': target = optarg; break;
> case 'O': outputDirectory = optarg; break;
> case 'v': Verbose = true; break;
> @@ -187,6 +194,14 @@ int main(
> }
>
> /*
> + * Validate that we have a symbols of interest file.
> + */
> + if ( !symbolSetFile ) {
> + option = "symbol set file -S";
> + throw option;
> + }
> +
> + /*
> * Has path to explanations.txt been specified.
> */
> if ( !explanations ) {
> @@ -354,14 +369,34 @@ int main(
>
> // Create the set of desired symbols.
> SymbolsToAnalyze = new Coverage::DesiredSymbols();
> - SymbolsToAnalyze->load( symbolsFile );
>
I am having trouble seeing what happened to the DesiredSymbols class. Is
it no longer needed? Did we change the class from which SymbolsToAnalyze
is derived but provide all the same needed interfaces?
I'm having trouble seeing how the new class fits in. Help me.
> - if (Verbose) {
> - fprintf(
> - stderr,
> - "Analyzing %u symbols\n",
> - (unsigned int) SymbolsToAnalyze->set.size()
> - );
> +
> + if ( symbolsFile ) {
> + SymbolsToAnalyze->load( symbolsFile );
> +
> + if (Verbose) {
> + fprintf(
> + stderr,
> + "Analyzing %u symbols\n",
> + (unsigned int) SymbolsToAnalyze->set.size()
> + );
> + }
> }
> + /*
> + *Read symbol configuration file and load needed symbols
> + */
> + if ( symbolSetFile ) {
> + std::cout << "Reading configuration symbol set file: " <<
> symbolSetFile
> + << std::endl;
> + Symbols::SymbolSetReader ssr;
> + std::vector<Symbols::SymbolSet> symbolSets = ssr.readSetFile(
> symbolSetFile );
> + Symbols::SymbolSet& set = symbolSets[0];
> + std::cout << "Generating symbol file for " + set.getName() <<
> std::endl;
> + set.generateSymbolFile( syms, target );
> + SymbolsToAnalyze->load( syms.name().c_str() );
> + }
> + if ( Verbose )
> + std::cout << "Analyzing " + SymbolsToAnalyze->set.size()
> + << "symbols" << std::endl;
>
> // Create explanations.
> AllExplanations = new Coverage::Explanations();
> @@ -524,6 +559,8 @@ int main(
> objdumpFile.keep();
> err.override( "objdump_exec_log" );
> err.keep();
> + syms.override( "symbols_list" );
> + syms.keep();
> }
> return 0;
> }
> diff --git a/tester/covoar/wscript b/tester/covoar/wscript
> index 9db4815..1cda734 100644
> --- a/tester/covoar/wscript
> +++ b/tester/covoar/wscript
> @@ -104,7 +104,9 @@ def build(bld):
> 'Target_lm32.cc',
> 'Target_m68k.cc',
> 'Target_powerpc.cc',
> - 'Target_sparc.cc'],
> + 'Target_sparc.cc',
> + 'SymbolSet.cpp',
> + 'SymbolSetReader.cpp'],
> cflags = ['-O2', '-g'],
> cxxflags = ['-std=c++11', '-O2', '-g'],
> includes = ['.'] + rtl_includes)
> --
> 2.7.4
>
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180426/10b2431d/attachment-0002.html>
More information about the devel
mailing list