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