summaryrefslogtreecommitdiffstats
path: root/decoder/tests/snapshot_parser_lib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:24:57 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 07:24:57 +0000
commit070852d8604cece0c31f28ff3eb8d21d9ba415fb (patch)
tree9097175a6a5b8b7e37af9a96269ac0b61a0189cd /decoder/tests/snapshot_parser_lib
parentInitial commit. (diff)
downloadlibopencsd-070852d8604cece0c31f28ff3eb8d21d9ba415fb.tar.xz
libopencsd-070852d8604cece0c31f28ff3eb8d21d9ba415fb.zip
Adding upstream version 1.3.3.upstream/1.3.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'decoder/tests/snapshot_parser_lib')
-rw-r--r--decoder/tests/snapshot_parser_lib/include/device_info.h62
-rw-r--r--decoder/tests/snapshot_parser_lib/include/device_parser.h106
-rw-r--r--decoder/tests/snapshot_parser_lib/include/ini_section_names.h88
-rw-r--r--decoder/tests/snapshot_parser_lib/include/snapshot_info.h50
-rw-r--r--decoder/tests/snapshot_parser_lib/include/snapshot_parser.h152
-rw-r--r--decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h112
-rw-r--r--decoder/tests/snapshot_parser_lib/include/snapshot_reader.h99
-rw-r--r--decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h80
-rw-r--r--decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h112
-rw-r--r--decoder/tests/snapshot_parser_lib/include/trace_snapshots.h44
-rw-r--r--decoder/tests/snapshot_parser_lib/source/device_info.cpp70
-rw-r--r--decoder/tests/snapshot_parser_lib/source/device_parser.cpp157
-rw-r--r--decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp844
-rw-r--r--decoder/tests/snapshot_parser_lib/source/snapshot_parser_util.cpp91
-rw-r--r--decoder/tests/snapshot_parser_lib/source/snapshot_reader.cpp270
-rw-r--r--decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp590
16 files changed, 2927 insertions, 0 deletions
diff --git a/decoder/tests/snapshot_parser_lib/include/device_info.h b/decoder/tests/snapshot_parser_lib/include/device_info.h
new file mode 100644
index 0000000..886aee6
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/device_info.h
@@ -0,0 +1,62 @@
+/*
+ * \file device_info.h
+ * \brief OpenCSD : Snapshot parser library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 DEVICE_INFO_H
+#define DEVICE_INFO_H
+
+#include <string>
+
+class DeviceInfo
+{
+public:
+ DeviceInfo() {};
+ DeviceInfo(const unsigned int deviceNum,
+ const std::string &iniFile);
+ virtual ~DeviceInfo() {};
+
+ std::string getIniFile() const;
+ std::string getName();
+ void setName(const std::string &n);
+ unsigned int getID() const;
+
+private:
+ unsigned int id;
+ std::string ini;
+ std::string name;
+};
+
+#endif
+
+/* End of File device_info.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/device_parser.h b/decoder/tests/snapshot_parser_lib/include/device_parser.h
new file mode 100644
index 0000000..4919501
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/device_parser.h
@@ -0,0 +1,106 @@
+/*
+ * \file device_parser.h
+ * \brief OpenCSD : Snapshot parser library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 DEVICE_PARSER_H
+#define DEVICE_PARSER_H
+
+#include "device_info.h"
+#include <memory>
+
+#include <map>
+#include <istream>
+#include <vector>
+#include <cstdint>
+
+#include "snapshot_info.h"
+
+class DeviceParser
+{
+public:
+ virtual ~DeviceParser() {};
+ typedef std::shared_ptr<DeviceInfo> DevPtr;
+ virtual DevPtr getDevice(int devNo) =0;
+ virtual void getDeviceList(std::vector<int> &devices) const = 0;
+ virtual size_t getDeviceCount() const = 0;
+
+};
+
+class SnapshotParser
+{
+public:
+ virtual ~SnapshotParser() {};
+ virtual std::string getDescription() const = 0;
+ virtual std::string getVersion() const = 0;
+};
+
+class ModernSnapshotParser : public DeviceParser, SnapshotParser
+{
+public:
+ ModernSnapshotParser( std::istream &iss);
+ ModernSnapshotParser();
+ virtual ~ModernSnapshotParser();
+
+ typedef std::shared_ptr<DeviceInfo> DevPtr;
+ DevPtr getDevice(int devNo);
+ void getDeviceList(std::vector<int> &devices) const;
+
+ bool isInitialised() const;
+ size_t getDeviceCount() const;
+
+ std::string getTraceMetadataFile() const;
+
+ // Snapshot Info
+ std::string getDescription() const;
+ std::string getVersion() const;
+
+
+private:
+ void addDevice(std::string rawName, std::string path);
+ uint32_t getUniqueDeviceID(std::string &rawName);
+
+ void addSnapshotInfo(SnapshotInfo snap);
+
+ SnapshotInfo snaphotInfo;
+
+ // map stores deviceId and associated data
+ std::map<int, DevPtr> deviceMap;
+ bool initialised;
+
+ std::string traceMetaDataIni;
+};
+
+#endif
+
+/* End of File device_parser.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/ini_section_names.h b/decoder/tests/snapshot_parser_lib/include/ini_section_names.h
new file mode 100644
index 0000000..a11fbc6
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/ini_section_names.h
@@ -0,0 +1,88 @@
+/*
+ * \file ini_section_names.h
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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.
+ */
+
+/* based on original RDDI source file 'ini_section_names.h"*/
+
+#ifndef INC_INI_SECTION_NAMES_H
+#define INC_INI_SECTION_NAMES_H
+
+/* snapshot.ini keys */
+const char* const SnapshotSectionName("snapshot");
+const char* const VersionKey("version");
+const char* const DescriptionKey("description");
+
+const char* const DeviceListSectionName("device_list");
+
+const char* const TraceSectionName("trace");
+const char* const MetadataKey("metadata");
+
+/* device .ini keys (device_N.ini or cpu_N.ini)*/
+const char* const DeviceSectionName("device");
+const char* const DeviceNameKey("name");
+const char* const DeviceClassKey("class");
+const char* const DeviceTypeKey("type");
+
+const char* const SymbolicRegsSectionName("regs");
+
+const char* const DumpFileSectionPrefix("dump");
+const size_t DumpFileSectionLen = 4;
+const char* const DumpAddressKey("address");
+const char* const DumpLengthKey("length");
+const char* const DumpOffsetKey("offset");
+const char* const DumpFileKey("file");
+const char* const DumpSpaceKey("space");
+
+/* trace.ini keys */
+const char * const TraceBuffersSectionName("trace_buffers");
+const char* const BufferListKey("buffers");
+
+const char * const BufferSectionPrefix("buffer");
+const size_t BufferSectionLen = 6;
+const char* const BufferNameKey("name");
+const char* const BufferFileKey("file");
+const char* const BufferFormatKey("format");
+
+const char * const SourceBuffersSectionName("source_buffers");
+const char * const CoreSourcesSectionName("core_trace_sources");
+
+/* deprecated / unused in trace decode */
+const char* const GlobalSectionName("global");
+const char* const CoreKey("core");
+const char* const ExtendedRegsSectionName("extendregs");
+const char* const ClustersSectionName("clusters");
+
+#endif // INC_INI_SECTION_NAMES_H
+
+/* End of File ini_section_names.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_info.h b/decoder/tests/snapshot_parser_lib/include/snapshot_info.h
new file mode 100644
index 0000000..b152c47
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/snapshot_info.h
@@ -0,0 +1,50 @@
+/*
+ * \file snapshot_info.h
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 SNAPSHOT_INFO_H_
+#define SNAPSHOT_INFO_H_
+
+#include <string>
+
+struct SnapshotInfo
+{
+ std::string version;
+ std::string description;
+};
+
+
+#endif /* SNAPSHOT_INFO_H_ */
+
+/* End of File snapshot_info.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h b/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h
new file mode 100644
index 0000000..9e5b371
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/snapshot_parser.h
@@ -0,0 +1,152 @@
+/*
+ * \file snapshot_parser.h
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 ARM_SNAPSHOT_PARSER_H_INCLUDED
+#define ARM_SNAPSHOT_PARSER_H_INCLUDED
+
+#include <cstdint>
+#include <sstream>
+#include <exception>
+#include <string>
+#include <vector>
+#include <map>
+#include <istream>
+
+#include "snapshot_parser_util.h"
+#include "snapshot_info.h"
+
+class ITraceErrorLog; // forward declare the OCSD error log interface.
+
+namespace Parser
+{
+ //! \brief Stores a parsed [dump] section
+ struct DumpDef
+ {
+ uint64_t address;
+ std::string path;
+ std::size_t length;
+ std::size_t offset;
+ std::string space;
+ };
+
+
+
+ //! \brief Stores the entire parsed device ini file
+ struct Parsed
+ {
+ Parsed() : foundGlobal() {}
+
+ bool foundGlobal;
+ std::string core;
+ std::vector<DumpDef> dumpDefs;
+ std::map<std::string,
+ std::string, // register value is stored as a string initially to cope with > 64 bit registers
+ Util::CaseInsensitiveLess> regDefs;
+ std::map<uint32_t, uint32_t> extendRegDefs;
+ std::string deviceName;
+ std::string deviceClass;
+ std::string deviceTypeName; // Cortex-Ax or ETMvN
+
+
+ };
+ /*! \brief Parse the device ini file and call back on the builder as appropriate.
+ * \param input the ini file
+ * \return parsed definitions
+ */
+ Parsed ParseSingleDevice(std::istream& input);
+
+ //! \brief Stores the entire device list
+ struct ParsedDevices
+ {
+ std::map<std::string, std::string> deviceList;
+ SnapshotInfo snapshotInfo;
+ std::string traceMetaDataName;
+ };
+
+ /*! \brief Parse the snapshot.ini file that contains the device list and call back on the builder as appropriate.
+ * \param input the ini file
+ * \return parsed definitions
+ */
+ ParsedDevices ParseDeviceList(std::istream& input);
+
+ // basic info about the buffer
+ struct TraceBufferInfo
+ {
+ std::string bufferName;
+ std::string dataFileName;
+ std::string dataFormat;
+ };
+
+ // list of buffers and associations as presented in the ini file.
+ struct ParsedTrace
+ {
+ std::vector<std::string> buffer_section_names;
+ std::vector<TraceBufferInfo> trace_buffers;
+ std::map<std::string, std::string> source_buffer_assoc; // trace source name -> trace buffer name assoc
+ std::map<std::string, std::string> cpu_source_assoc; // trace source name -> cpu_name assoc
+ };
+
+ // single buffer information containing just the assoc for the buffer
+ // -> created by processing the ini data for a single named buffer.
+ // this can then be used to create a decode tree in the decode library.
+ struct TraceBufferSourceTree
+ {
+ TraceBufferInfo buffer_info;
+ std::map<std::string, std::string> source_core_assoc; // list of source names attached to core device names (e.g. ETM_0:cpu_0)
+ };
+
+ // parse the trace metadata ini file.
+ ParsedTrace ParseTraceMetaData(std::istream& input);
+
+ // build a source tree for a single buffer
+ bool ExtractSourceTree(const std::string &buffer_name, ParsedTrace &metadata, TraceBufferSourceTree &buffer_data);
+
+ std::vector<std::string> GetBufferNameList(ParsedTrace &metadata);
+
+
+ //static ITraceErrorLog *s_pErrorLogger = 0;
+ //static ocsd_hndl_err_log_t s_errlog_handle = 0;
+ //static bool s_verbose_logging = true;
+
+ void SetIErrorLogger(ITraceErrorLog *i_err_log);
+ void SetVerboseLogging(bool verbose);
+ ITraceErrorLog *GetIErrorLogger();
+ void LogInfoStr(const std::string &logMsg);
+
+
+}
+
+#endif // ARM_SNAPSHOT_PARSER_H_INCLUDED
+
+/* End of File snapshot_parser.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h b/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h
new file mode 100644
index 0000000..d4fd6cd
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/snapshot_parser_util.h
@@ -0,0 +1,112 @@
+/*
+ * \file snapshot_parser_util.h
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 ARM_SNAPSHOT_PARSER_UTIL_H_INCLUDED
+#define ARM_SNAPSHOT_PARSER_UTIL_H_INCLUDED
+
+#include <algorithm>
+#include <string>
+#include <sstream>
+#include <iomanip>
+#include <cctype>
+#include <cstdlib>
+#include <cstdint>
+
+#include "common/ocsd_error.h"
+
+namespace Util
+{
+ //! format an address as '0xNNNNNNNN'
+ std::string MakeAddressString(uint32_t address);
+ //! format a an address as '0xNNNNNNNNNNNNNNNN'
+ std::string MakeAddressString(uint64_t address);
+
+ //! remove leading garbage from a string
+ std::string TrimLeft(const std::string& s, const std::string& ws = " \t");
+
+ //! remove trailing garbage from a string
+ std::string TrimRight(const std::string& s, const std::string& ws = " \t");
+
+ //! remove leading and trailing garbage from a string
+ std::string Trim(const std::string& s, const std::string& ws = " \t");
+
+ //! Functions to decode an integer
+ //
+ inline void ThrowUnsignedConversionError(const std::string& s)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Could not parse '" + s + "' as unsigned integer");
+ }
+
+ template <class T>
+ T DecodeUnsigned(const std::string& s)
+ {
+ char *endptr(0);
+ // Address can be up to 64 bits, ensure there is enough storage
+#ifdef WIN32
+ uint64_t result(_strtoui64(s.c_str(), &endptr, 0));
+#else
+ uint64_t result(std::strtoull(s.c_str(), &endptr, 0));
+#endif
+ if (*endptr != '\0')
+ {
+ ThrowUnsignedConversionError(s);
+ return T(); // keep compiler happy
+ }
+ return static_cast<T>(result);
+ }
+
+ class CaseInsensitiveLess
+ {
+ public:
+ bool operator() (const std::string& s1, const std::string& s2) const
+ {
+ return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), cmp);
+ }
+
+ private:
+ static bool cmp(unsigned char c1, unsigned char c2)
+ {
+ return std::tolower(c1) < std::tolower(c2);
+ }
+ };
+
+ inline bool CaseInsensitiveEquals(const std::string& s1, const std::string& s2)
+ {
+ return !CaseInsensitiveLess()(s1, s2) && !CaseInsensitiveLess()(s2, s1);
+ }
+}
+
+#endif // ARM_SNAPSHOT_PARSER_UTIL_H_INCLUDED
+
+/* End of File snapshot_parser_util.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/snapshot_reader.h b/decoder/tests/snapshot_parser_lib/include/snapshot_reader.h
new file mode 100644
index 0000000..0b3c7e5
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/snapshot_reader.h
@@ -0,0 +1,99 @@
+/*
+ * \file snapshot_reader.h
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 ARM_SNAPSHOT_READER_H_INCLUDED
+#define ARM_SNAPSHOT_READER_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+#include "snapshot_parser.h"
+
+class ITraceErrorLog;
+
+class SnapShotReader
+{
+public:
+ SnapShotReader();
+ ~SnapShotReader();
+
+ void setSnapshotDir(const std::string &dir);
+ const std::string &getSnapShotDir() const { return m_snapshotPath; };
+
+ const bool readSnapShot(); // read the snapshot dir
+
+ // true if the snapshot ini file can be found on the path.
+ const bool snapshotFound() const { return m_snapshot_found; };
+
+ const bool snapshotReadOK() const { return m_read_ok; };
+
+ void setErrorLogger(ITraceErrorLog *err_log);
+ void setVerboseOutput(const bool bVerbose) { m_verbose = bVerbose; };
+
+ bool getSourceBufferNameList(std::vector<std::string> &nameList);
+ bool getTraceBufferSourceTree(const std::string &traceBufferName, Parser::TraceBufferSourceTree &sourceTree);
+
+ bool getDeviceData(const std::string &deviceName, Parser::Parsed **devData);
+
+private:
+ void checkPath(); // see if the ini file can be opened on the current path
+ void LogInfo(const std::string &msg);
+ void LogError(const std::string &msg);
+
+
+ std::string m_snapshotPath; // snapshot directory - default to cwd.
+ bool m_snapshot_found; // true if the path supplied can be opened.
+ ITraceErrorLog *m_i_err_log;
+ ocsd_hndl_err_log_t m_errlog_handle;
+ bool m_verbose; // true for verbose output.
+ bool m_read_ok;
+
+ // list of parsed device ini files, mapped by device name .
+ // <device_name (ETM_0 | cpu_0)> : { <parsed_device_data> }
+ std::map<std::string, Parser::Parsed> m_parsed_device_list;
+
+ Parser::ParsedTrace m_parsed_trace; // the parsed trace meta data
+
+ // trace metadata rearranged as source trees, mapped by source name
+ // <source_buffer_name> : { buffer_info, {<ETM_0:cpu_0>,....} }
+ std::map<std::string, Parser::TraceBufferSourceTree> m_source_trees;
+};
+
+// the top level snapshot file name.
+const char* const SnapshotINIFilename("snapshot.ini");
+
+#endif // ARM_SNAPSHOT_READER_H_INCLUDED
+
+/* End of File snapshot_reader.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h b/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h
new file mode 100644
index 0000000..ad0823b
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/ss_key_value_names.h
@@ -0,0 +1,80 @@
+/*
+ * \file ss_key_value_names.h
+ * \brief OpenCSD : Names and Value Strings needed to interpret snapshot .ini data
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 ARM_SS_KEY_VALUE_NAMES_H_INCLUDED
+#define ARM_SS_KEY_VALUE_NAMES_H_INCLUDED
+
+/*** Core Profile Prefixes ***/
+const char * const CPUprofileA("Cortex-A");
+const char * const CPUprofileR("Cortex-R");
+const char * const CPUprofileM("Cortex-M");
+
+/*** Trace Buffer formats ***/
+const char * const BuffFmtCS("coresight"); // coresight frame formatted.
+
+/***ETM v4 ***/
+const char * const ETMv4Protocol("ETM4");
+const char * const ETMv4RegCfg("TRCCONFIGR");
+const char * const ETMv4RegIDR("TRCTRACEIDR");
+const char * const ETMv4RegAuth("TRCAUTHSTATUS");
+const char * const ETMv4RegIDR0("TRCIDR0");
+const char * const ETMv4RegIDR1("TRCIDR1");
+const char * const ETMv4RegIDR2("TRCIDR2");
+const char * const ETMv4RegIDR8("TRCIDR8");
+const char * const ETMv4RegIDR9("TRCIDR9");
+const char * const ETMv4RegIDR10("TRCIDR10");
+const char * const ETMv4RegIDR11("TRCIDR11");
+const char * const ETMv4RegIDR12("TRCIDR12");
+const char * const ETMv4RegIDR13("TRCIDR13");
+
+/*** ETE ***/
+const char *const ETEProtocol("ETE");
+const char *const ETERegDevArch("TRCDEVARCH");
+
+/*** ETMv3/PTM ***/
+const char * const ETMv3Protocol("ETM3");
+const char * const PTMProtocol("PTM1");
+const char * const PFTProtocol("PFT1");
+const char * const ETMv3PTMRegIDR("ETMIDR");
+const char * const ETMv3PTMRegCR("ETMCR");
+const char * const ETMv3PTMRegCCER("ETMCCER");
+const char * const ETMv3PTMRegTraceIDR("ETMTRACEIDR");
+
+/*** STM/ITM **/
+const char * const STMProtocol("STM");
+const char * const STMRegTCSR("STMTCSR");
+
+#endif // ARM_SS_KEY_VALUE_NAMES_H_INCLUDED
+
+/* End of File ss_key_value_names.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h b/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h
new file mode 100644
index 0000000..3c85f9d
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/ss_to_dcdtree.h
@@ -0,0 +1,112 @@
+/*
+ * \file ss_to_dcdtree.h
+ * \brief OpenCSD : Create a decode tree given a snapshot database.
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 ARM_SS_TO_DCDTREE_H_INCLUDED
+#define ARM_SS_TO_DCDTREE_H_INCLUDED
+
+#include <string>
+
+#include "opencsd.h"
+#include "snapshot_parser.h"
+#include "snapshot_reader.h"
+
+class DecodeTree;
+class ITraceErrorLog;
+
+class CreateDcdTreeFromSnapShot
+{
+public:
+ CreateDcdTreeFromSnapShot();
+ ~CreateDcdTreeFromSnapShot();
+
+ void initialise(SnapShotReader *m_pReader, ITraceErrorLog *m_pErrLogInterface);
+
+ bool createDecodeTree(const std::string &SourceBufferName, bool bPacketProcOnly, uint32_t add_create_flags = 0);
+ void destroyDecodeTree();
+ DecodeTree *getDecodeTree() const { return m_pDecodeTree; };
+ const char *getBufferFileName() const { return m_BufferFileName.c_str(); };
+
+ // TBD: add in filters for ID list, first ID found.
+
+private:
+ // create a decoder related to a core source (ETM, PTM)
+ bool createPEDecoder(const std::string &coreName, Parser::Parsed *devSrc);
+ // protocol specific core source decoders
+ bool createETMv4Decoder(const std::string &coreName, Parser::Parsed *devSrc, const bool bDataChannel = false);
+ bool createETMv3Decoder(const std::string &coreName, Parser::Parsed *devSrc);
+ bool createPTMDecoder(const std::string &coreName, Parser::Parsed *devSrc);
+ bool createETEDecoder(const std::string &coreName, Parser::Parsed *devSrc);
+ // TBD add etmv4d
+
+ // create a decoder related to a software trace source (ITM, STM)
+ bool createSTDecoder(Parser::Parsed *devSrc);
+ // protocol specific decoders
+ bool createSTMDecoder(Parser::Parsed *devSrc);
+
+ typedef struct _regs_to_access {
+ const char *pszName;
+ bool failIfMissing;
+ uint32_t *value;
+ uint32_t val_default;
+ } regs_to_access_t;
+
+ bool getRegisters(std::map<std::string, std::string, Util::CaseInsensitiveLess> &regDefs, int numRegs, regs_to_access_t *reg_access_array);
+ bool getRegByPrefix(std::map<std::string, std::string, Util::CaseInsensitiveLess> &regDefs,
+ regs_to_access_t &reg_accessor);
+ bool getCoreProfile(const std::string &coreName, ocsd_arch_version_t &arch_ver, ocsd_core_profile_t &core_prof);
+
+ void LogError(const std::string &msg);
+ void LogError(const ocsdError &err);
+
+ void processDumpfiles(std::vector<Parser::DumpDef> &dumps);
+
+
+ uint32_t m_add_create_flags;
+
+ bool m_bInit;
+ DecodeTree *m_pDecodeTree;
+ SnapShotReader *m_pReader;
+ ITraceErrorLog *m_pErrLogInterface;
+ ocsd_hndl_err_log_t m_errlog_handle;
+
+ bool m_bPacketProcOnly;
+ std::string m_BufferFileName;
+
+ CoreArchProfileMap m_arch_profiles;
+};
+
+
+#endif // ARM_SS_TO_DCDTREE_H_INCLUDED
+
+/* End of File ss_to_dcdtree.h */
diff --git a/decoder/tests/snapshot_parser_lib/include/trace_snapshots.h b/decoder/tests/snapshot_parser_lib/include/trace_snapshots.h
new file mode 100644
index 0000000..cec97a8
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/include/trace_snapshots.h
@@ -0,0 +1,44 @@
+/*
+ * \file trace_snapshots.h
+ * \brief OpenCSD : Principal include file for snapshot read and parse library.
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 ARM_TRACE_SNAPSHOTS_H_INCLUDED
+#define ARM_TRACE_SNAPSHOTS_H_INCLUDED
+
+#include "snapshot_reader.h"
+#include "snapshot_parser.h"
+#include "ss_to_dcdtree.h"
+
+#endif // ARM_TRACE_SNAPSHOTS_H_INCLUDED
+
+/* End of File trace_snapshots.h */
diff --git a/decoder/tests/snapshot_parser_lib/source/device_info.cpp b/decoder/tests/snapshot_parser_lib/source/device_info.cpp
new file mode 100644
index 0000000..c449441
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/source/device_info.cpp
@@ -0,0 +1,70 @@
+/*
+ * \file device_info.cpp
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 "device_info.h"
+
+static unsigned int unknownCount = 0;
+DeviceInfo::DeviceInfo(const unsigned int deviceNum,
+ const std::string &iniFile)
+ : ini(iniFile), id(deviceNum), name("")
+{
+
+}
+
+unsigned int DeviceInfo::getID() const
+{
+ return id;
+}
+
+std::string DeviceInfo::getIniFile() const
+{
+ return ini;
+}
+
+void DeviceInfo::setName(const std::string &n)
+{
+ name = n;
+}
+
+std::string DeviceInfo::getName()
+{
+ if (name.empty())
+ {
+ name = "UNKNOWN";
+ }
+ return name;
+}
+
+
+/* End of File device_info.cpp */
diff --git a/decoder/tests/snapshot_parser_lib/source/device_parser.cpp b/decoder/tests/snapshot_parser_lib/source/device_parser.cpp
new file mode 100644
index 0000000..3086e49
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/source/device_parser.cpp
@@ -0,0 +1,157 @@
+/*
+ * \file device_parser.cpp
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 "device_parser.h"
+
+#include "snapshot_parser.h"
+
+#include <sstream>
+#include <iostream>
+#include <string>
+#include <memory>
+#include <cstdio>
+
+#include "common/ocsd_error.h"
+
+using namespace std;
+
+ModernSnapshotParser::ModernSnapshotParser() : initialised(false), traceMetaDataIni("")
+{
+}
+
+ModernSnapshotParser::ModernSnapshotParser( std::istream &iss) : initialised(false), traceMetaDataIni("")
+{
+ Parser::ParsedDevices pd = Parser::ParseDeviceList(iss);
+ std::map<std::string, std::string> rawList = pd.deviceList;
+ std::map<std::string, std::string>::iterator it;
+ for (it = rawList.begin(); it != rawList.end(); ++it )
+ {
+ addDevice(it->first, it->second);
+ }
+ snaphotInfo = pd.snapshotInfo;
+ this->traceMetaDataIni = pd.traceMetaDataName;
+ initialised = true;
+}
+
+ModernSnapshotParser::~ModernSnapshotParser()
+{
+}
+
+void ModernSnapshotParser::addDevice(std::string rawName, std::string path)
+{
+ uint32_t deviceID = getUniqueDeviceID(rawName);
+ deviceMap[deviceID] = DevPtr(new DeviceInfo(deviceID, path));
+}
+
+uint32_t ModernSnapshotParser::getUniqueDeviceID(std::string &rawName)
+{
+ size_t pos = rawName.find_first_of("0123456789");
+ uint32_t candidate = 1;
+ if (pos != std::string::npos)
+ {
+ std::string numbers = rawName.substr(pos);
+ istringstream ist(numbers);
+ ist >> candidate;
+ }
+ while (true)
+ {
+ try
+ {
+ getDevice(candidate);
+ // didn't throw means already in list, so bad candidate
+ candidate++;
+ }
+ catch (ocsdError & /*e*/)
+ {
+ // threw, so unique ID, so this is good, leave loop
+ break;
+ }
+ }
+ return candidate;
+}
+
+bool ModernSnapshotParser::isInitialised() const
+{
+ return initialised;
+}
+
+size_t ModernSnapshotParser::getDeviceCount() const
+{
+ unsigned int deviceCount = 0;
+ if (isInitialised())
+ deviceCount = deviceMap.size();
+ return deviceCount;
+}
+
+ModernSnapshotParser::DevPtr ModernSnapshotParser::getDevice(int id)
+{
+ map<int, DevPtr>::const_iterator it(deviceMap.find(id));
+ if (it == deviceMap.end())
+ {
+ std::ostringstream ost;
+ ost << "Unknown device:" << id;
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, ost.str());
+ }
+ return it->second;
+}
+
+void ModernSnapshotParser::addSnapshotInfo(SnapshotInfo snap)
+{
+ snaphotInfo = snap;
+}
+
+void ModernSnapshotParser::getDeviceList(std::vector<int> &devices) const
+{
+ map<int, DevPtr>::const_iterator it;
+ //devices.clear();
+ for (it = deviceMap.begin(); it != deviceMap.end(); ++it)
+ devices.push_back(it->first);
+}
+
+std::string ModernSnapshotParser::getDescription() const
+{
+ return snaphotInfo.description;
+}
+
+std::string ModernSnapshotParser::getVersion() const
+{
+ return snaphotInfo.version;
+}
+
+
+std::string ModernSnapshotParser::getTraceMetadataFile() const
+{
+ return traceMetaDataIni;
+}
+
+/* End of File device_parser.cpp */
diff --git a/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp b/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp
new file mode 100644
index 0000000..4570700
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp
@@ -0,0 +1,844 @@
+/*
+ * \file snapshot_parser.cpp
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 "snapshot_parser.h"
+
+#include <memory>
+#include <algorithm>
+#include <istream>
+#include <iostream>
+#include <string>
+#include <utility>
+using namespace std;
+
+#include "snapshot_parser_util.h"
+#include "ini_section_names.h"
+using namespace Util;
+using namespace Parser;
+
+#include "opencsd.h"
+
+static ITraceErrorLog *s_pErrorLogger = 0;
+static ocsd_hndl_err_log_t s_errlog_handle = 0;
+static bool s_verbose_logging = true;
+
+/*************************************************************************
+ * Note, this file handles the parsring of the general (device specific)
+ * ini file and the (much smaller) device_list file
+ *************************************************************************/
+
+namespace ParserPrivate
+{
+ //! Handle CRLF terminators and '#' and ';' comments
+ void CleanLine(string& line)
+ {
+ string::size_type endpos = line.find_first_of("\r;#");
+ if (endpos != string::npos)
+ {
+ line.erase(endpos);
+ }
+ }
+
+ //! Split foo=bar into pair <foo, bar>
+ pair<string, string> SplitKeyValue(const string& kv)
+ {
+ string::size_type eq(kv.find('='));
+ if (eq == string::npos)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Couldn't parse '" + kv + "' as key=value");
+ }
+ return make_pair(Trim(kv.substr(0, eq)), Trim(kv.substr(eq + 1)));
+ }
+
+ //! Whether line is just tabs and spaces
+ bool IsEmpty(const string& line)
+ {
+ return TrimLeft(line) == "";
+ }
+
+ /*! \brief Whether line is of form '[header]'
+ * \param line the line
+ * \param sectionName if function returns true, returns the text between the brackets
+ */
+ bool IsSectionHeader(const string& line, string& sectionName)
+ {
+ string::size_type openBracket(line.find('['));
+ if (openBracket == string::npos)
+ {
+ return false;
+ }
+ string::size_type textStart(openBracket + 1);
+ string::size_type closeBracket(line.find(']', textStart));
+ if (closeBracket == string::npos)
+ {
+ return false;
+ }
+ sectionName.assign(Trim(line.substr(textStart, closeBracket - textStart)));
+ return true;
+ }
+
+ template <class M, class K, class V>
+ void AddUniqueKey(M& m, const K& key, const V& value, const std::string &keyStr )
+ {
+ if (!m.insert(make_pair(key, value)).second)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Duplicate key: " + keyStr);
+ }
+ }
+
+ void PreventDupes(bool& store, const string& key, const string& section)
+ {
+ if (store)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE,
+ "Duplicate " + key + " key found in "
+ + section + " section");
+ }
+ store = true;
+ }
+
+
+ /*! \class Section
+ * \brief Handle an ini file section begun with a section header ([header])
+ */
+ class Section
+ {
+ public:
+ virtual ~Section() {}
+
+ //! Notify a key=value definition
+ virtual void Define(const string& k, const string& v) = 0;
+
+ //! Notify end of section - we can't handle in dtor because misparses throw.
+ virtual void End() = 0;
+ };
+
+ //! The initial state
+ class NullSection : public Section
+ {
+ public:
+ void Define(const string& k, const string&)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Definition of '" + k + "' has no section header");
+ }
+ void End() {}
+ };
+
+ //! Silently ignore sections that are undefined
+ class IgnoredSection : public Section
+ {
+ public:
+ void Define(const string& , const string&)
+ {
+ }
+ void End() {}
+ };
+
+ //! Handle a [global] section.
+ class GlobalSection : public Section
+ {
+ public:
+ GlobalSection(Parsed& result) : m_result(result), m_got_core()
+ {
+ if (m_result.foundGlobal)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, string("Only one ") + GlobalSectionName + " section allowed");
+ }
+ m_result.foundGlobal = true;
+ }
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == CoreKey)
+ {
+ PreventDupes(m_got_core, CoreKey, GlobalSectionName);
+ m_result.core.assign(v);
+ }
+ else
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Unknown global option '" + k + '\'');
+ }
+ }
+
+ void End() {}
+
+ private:
+ Parsed& m_result;
+ bool m_got_core;
+ };
+
+ //! Handle a [dump] section
+ class DumpSection : public Section
+ {
+ public:
+ DumpSection(Parsed& result)
+ : m_result(result),
+ m_got_file(), m_got_address(), m_got_length(), m_got_offset(), m_got_space(),
+ m_address(), m_length(), m_offset(), m_file(), m_space()
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == DumpAddressKey)
+ {
+ PreventDupes(m_got_address, DumpAddressKey, DumpFileSectionPrefix);
+ m_address = DecodeUnsigned<uint64_t>(v);
+ }
+ else if (k == DumpLengthKey)
+ {
+ PreventDupes(m_got_length, DumpLengthKey, DumpFileSectionPrefix);
+ m_length = DecodeUnsigned<size_t>(v);
+ }
+ else if (k == DumpOffsetKey)
+ {
+ PreventDupes(m_got_offset, DumpOffsetKey, DumpFileSectionPrefix);
+ m_offset = DecodeUnsigned<size_t>(v);
+ }
+ else if (k == DumpFileKey)
+ {
+ PreventDupes(m_got_file, DumpFileKey, DumpFileSectionPrefix);
+ m_file = Trim(v, "\"'"); // strip quotes
+ }
+ else if (k == DumpSpaceKey)
+ {
+ PreventDupes(m_got_space, DumpSpaceKey, DumpFileSectionPrefix);
+ m_space = Trim(v, "\"'"); // strip quotes
+ }
+ else
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Unknown dump section key '" + k + '\'');
+ }
+ }
+
+ void End()
+ {
+ if (!m_got_address)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Dump section is missing mandatory address definition");
+ }
+ if (!m_got_file)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Dump section is missing mandatory file definition");
+ }
+
+ struct DumpDef add = { m_address, m_file, m_length, m_offset, m_space};
+ m_result.dumpDefs.push_back(add);
+ }
+
+ private:
+ Parsed& m_result;
+ bool m_got_file;
+ bool m_got_address;
+ bool m_got_length;
+ bool m_got_offset;
+ bool m_got_space;
+ uint64_t m_address;
+ size_t m_length;
+ size_t m_offset;
+ string m_file;
+ string m_space;
+ };
+
+ //! Handle an [extendregs] section.
+ class ExtendRegsSection : public Section
+ {
+ public:
+ ExtendRegsSection(Parsed& result) : m_result(result)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ AddUniqueKey(m_result.extendRegDefs, DecodeUnsigned<uint32_t>(k), DecodeUnsigned<uint32_t>(v),k);
+ }
+
+ void End() {}
+
+ private:
+ Parsed& m_result;
+ };
+
+ // Handle a [regs] section
+ class SymbolicRegsSection : public Section
+ {
+ public:
+ SymbolicRegsSection(Parsed& result) : m_result(result)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ const string value = Trim(v, "\"'"); // strip quotes
+ AddUniqueKey(m_result.regDefs, k, value,k);
+ }
+
+ void End() {}
+
+ private:
+ Parsed& m_result;
+ };
+
+ // Handle a [device] section
+ class DeviceSection : public Section
+ {
+ public:
+ DeviceSection(Parsed& result) : m_result(result), gotName(false), gotClass(false), gotType(false)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == DeviceNameKey)
+ {
+ PreventDupes(gotName, k, DeviceSectionName);
+ m_result.deviceName = v;
+ }
+ else if(k == DeviceClassKey)
+ {
+ PreventDupes(gotClass, k, DeviceSectionName);
+ m_result.deviceClass = v;
+ }
+ else if(k == DeviceTypeKey)
+ {
+ PreventDupes(gotType, k, DeviceSectionName);
+ m_result.deviceTypeName = v;
+ }
+ }
+
+ void End() {}
+
+ private:
+ Parsed& m_result;
+ bool gotName;
+ bool gotClass;
+ bool gotType;
+ };
+
+ //! Instantiate the appropriate handler for the section name
+ auto_ptr<Section> NewSection( const string& sectionName, Parsed& result)
+ {
+ LogInfoStr( "Start of " + sectionName + " section\n");
+
+ if (sectionName == GlobalSectionName)
+ {
+ return auto_ptr<Section>(new GlobalSection(result));
+ }
+ if (sectionName.substr(0,DumpFileSectionLen) == DumpFileSectionPrefix)
+ {
+ return auto_ptr<Section>(new DumpSection(result));
+ }
+ else if (sectionName == ExtendedRegsSectionName)
+ {
+ return auto_ptr<Section>(new ExtendRegsSection(result));
+ }
+ else if (sectionName == SymbolicRegsSectionName)
+ {
+ return auto_ptr<Section>(new SymbolicRegsSection(result));
+ }
+ else if (sectionName == DeviceSectionName)
+ {
+ return auto_ptr<Section>(new DeviceSection(result));
+ }
+ else
+ {
+ LogInfoStr("Unknown section ignored: " + sectionName + "\n");
+ return auto_ptr<Section>(new IgnoredSection);
+ }
+ }
+
+ /***** Device List file parsing *********************/
+ //! Handle a [device_list] section.
+ class DeviceListSection : public Section
+ {
+ public:
+ DeviceListSection(ParsedDevices& result) : m_result(result), nextId(1)
+ {}
+
+ void Define(const string& , const string& v)
+ {
+ // throw away supplied key - DTSL wants them monotonically increasing from 1
+ std::ostringstream id;
+ id << nextId++;
+ m_result.deviceList[id.str()] = v;
+ }
+
+ void End() {}
+
+ private:
+ ParsedDevices& m_result;
+ uint32_t nextId;
+ };
+
+ //! Instantiate the appropriate handler for the section name
+ auto_ptr<Section> NewDeviceList(const string& sectionName, ParsedDevices& result)
+ {
+ LogInfoStr("Start of " + sectionName + " section\n");
+
+ if (sectionName == DeviceListSectionName)
+ {
+ return auto_ptr<Section>(new DeviceListSection(result));
+ }
+ else
+ {
+ // ignore unexpected sections, there may be others like [trace]
+ // which RDDI doesn't care about
+ return auto_ptr<Section>(new NullSection);
+ }
+ }
+
+ // Handle a [snapshot] section
+ class SnapshotSection : public Section
+ {
+ public:
+ SnapshotSection(SnapshotInfo& result) : m_result(result), m_gotDescription(false), m_gotVersion(false)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == VersionKey)
+ {
+ PreventDupes(m_gotVersion, k, SnapshotSectionName);
+ m_result.version = v;
+ // the only valid contents of this are 1.0, as this is the version that introduced the "snapshot" section
+ if (v != "1.0" && v != "1")
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Illegal snapshot file version: " + v);
+ }
+ else if (k == DescriptionKey)
+ {
+ PreventDupes(m_gotDescription, k, SnapshotSectionName);
+ m_result.description = v;
+ }
+ }
+ SnapshotInfo getSnapshotInfo() { return m_result; }
+ void End() {}
+
+ private:
+ SnapshotInfo &m_result;
+ bool m_gotDescription;
+ bool m_gotVersion;
+
+ };
+
+ //! Instantiate the appropriate handler for the section name
+ auto_ptr<Section> NewSnapshotInfo(const string& sectionName, ParsedDevices& result)
+ {
+ LogInfoStr((std::string)"Start of " + sectionName + (std::string)" section\n");
+
+ if (sectionName == SnapshotSectionName)
+ {
+ return auto_ptr<Section>(new SnapshotSection(result.snapshotInfo));
+ }
+ else
+ {
+ // ignore unexpected sections, there may be others like [trace]
+ // which RDDI doesn't care about
+ return auto_ptr<Section>(new NullSection);
+ }
+ };
+
+ class TraceSection : public Section
+ {
+ public:
+ TraceSection(ParsedDevices& result) : m_result(result), gotName(false)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == MetadataKey)
+ {
+ PreventDupes(gotName, k, TraceSectionName);
+ m_result.traceMetaDataName = v;
+ }
+ }
+
+ void End() {}
+
+ private:
+ ParsedDevices& m_result;
+ bool gotName;
+ };
+
+ //! Instantiate the appropriate handler for the section name
+ auto_ptr<Section> NewTraceMetaData(const string& sectionName, ParsedDevices& result)
+ {
+ LogInfoStr((std::string)"Start of " + sectionName + (std::string)" section\n");
+
+ if (sectionName == TraceSectionName)
+ {
+ return auto_ptr<Section>(new TraceSection(result));
+ }
+ else
+ {
+ // ignore unexpected sections, there may be others like [trace]
+ // which RDDI doesn't care about
+ return auto_ptr<Section>(new NullSection);
+ }
+ };
+
+ class TraceBufferListSection : public Section
+ {
+ public:
+ TraceBufferListSection(ParsedTrace& result) : m_result(result), gotList(false)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == BufferListKey)
+ {
+ PreventDupes(gotList, k, TraceBuffersSectionName);
+ std::string nameList = v;
+ std::string::size_type pos;
+ while((pos = nameList.find_first_of(',')) != std::string::npos)
+ {
+ m_result.buffer_section_names.push_back(nameList.substr(0,pos));
+ nameList=nameList.substr(pos+1,std::string::npos);
+ }
+ m_result.buffer_section_names.push_back(nameList);
+ }
+ }
+
+ void End() {}
+
+ private:
+ ParsedTrace& m_result;
+ bool gotList;
+ };
+
+ //! Instantiate the appropriate handler for the section name
+
+
+ class TraceBufferSection : public Section
+ {
+ public:
+ TraceBufferSection(ParsedTrace& result, const std::string &sectionName) : m_result(result), m_sectionName(sectionName),
+ name(""), file(""), format(""), gotName(false), gotFile(false), gotFormat(false)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ if (k == BufferNameKey)
+ {
+ PreventDupes(gotName, k, m_sectionName);
+ name = v;
+ }
+ else if (k == BufferFileKey)
+ {
+ PreventDupes(gotFile, k, m_sectionName);
+ file = v;
+ }
+ else if (k == BufferFormatKey)
+ {
+ PreventDupes(gotFormat, k, m_sectionName);
+ format = v;
+ }
+ }
+
+ void End()
+ {
+ if (!gotName)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Trace Buffer section missing required buffer name");
+ }
+ if (!gotFile)
+ {
+ throw ocsdError(OCSD_ERR_SEV_ERROR, OCSD_ERR_TEST_SNAPSHOT_PARSE, "Trace Buffer section is missing mandatory file definition");
+ }
+
+ struct TraceBufferInfo info = { name, file, format };
+ m_result.trace_buffers.push_back(info);
+ }
+
+
+ private:
+ ParsedTrace& m_result;
+ std::string m_sectionName;
+ std::string name;
+ bool gotName;
+ std::string file;
+ bool gotFile;
+ std::string format;
+ bool gotFormat;
+
+ };
+
+ class TraceSourceBuffersSection : public Section
+ {
+ public:
+ TraceSourceBuffersSection(ParsedTrace& result) : m_result(result)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ // k is the source name, v is the buffer name
+ m_result.source_buffer_assoc[k] = v;
+ }
+
+ void End() {}
+
+ private:
+ ParsedTrace& m_result;
+ };
+
+ class TraceCpuSourceSection : public Section
+ {
+ public:
+ TraceCpuSourceSection(ParsedTrace& result) : m_result(result)
+ {}
+
+ void Define(const string& k, const string& v)
+ {
+ // k is the cpu name, v is the source name
+ m_result.cpu_source_assoc[v] = k;
+ }
+
+ void End() {}
+
+ private:
+ ParsedTrace& m_result;
+ };
+
+ auto_ptr<Section> NewTraceSection(const string& sectionName, ParsedTrace& result)
+ {
+ LogInfoStr((std::string)"Start of " + sectionName + (std::string)" section\n");
+
+ if (sectionName == TraceBuffersSectionName)
+ {
+ return auto_ptr<Section>(new TraceBufferListSection(result));
+ }
+ else if(sectionName == SourceBuffersSectionName)
+ {
+ return auto_ptr<Section>(new TraceSourceBuffersSection(result));
+ }
+ else if(sectionName == CoreSourcesSectionName)
+ {
+ return auto_ptr<Section>(new TraceCpuSourceSection(result));
+ }
+ else
+ {
+ // check the list of buffer sections
+ std::vector<std::string>::iterator it = result.buffer_section_names.begin();
+ bool matchedName = false;
+ while(it != result.buffer_section_names.end())
+ {
+ if(sectionName == *it)
+ {
+ return auto_ptr<Section>(new TraceBufferSection(result, sectionName));
+ }
+ it++;
+ }
+ // ignore unexpected sections,
+ return auto_ptr<Section>(new IgnoredSection);
+ }
+ };
+
+
+}
+
+using namespace ParserPrivate;
+
+Parser::Parsed Parser::ParseSingleDevice(istream& in)
+{
+ Parsed result;
+
+ string line;
+ auto_ptr<Section> section(new NullSection);
+
+ while (getline(in, line))
+ {
+ CleanLine(line); // remove LF, comments
+ string sectionName;
+
+ if (IsSectionHeader(line, sectionName))
+ {
+ // Section ends with start of next section...
+ section->End();
+ section = NewSection(sectionName, result);
+ }
+ else if (!IsEmpty(line))
+ {
+ if (dynamic_cast<IgnoredSection *>(section.get()) == NULL)
+ { // NOT an ignored section, so process it
+ pair<string, string> kv(SplitKeyValue(line));
+ section->Define(kv.first, kv.second);
+ }
+ }
+ }
+ // ... or end of file
+ section->End();
+ return result;
+}
+
+Parser::ParsedDevices Parser::ParseDeviceList(istream& in)
+{
+ ParsedDevices result;
+ result.snapshotInfo.description = "";
+ // call the original format 0.0, the device_list format 0.1 and the flexible format (including version) 1.0
+ result.snapshotInfo.version = "0.1";
+ string line;
+ auto_ptr<Section> section(new NullSection);
+
+ while (getline(in, line))
+ {
+ CleanLine(line); // remove LF, comments
+ string sectionName;
+
+ if (IsSectionHeader(line, sectionName))
+ {
+ // Section ends with start of next section...
+ section->End();
+
+ if (sectionName == SnapshotSectionName)
+ section = NewSnapshotInfo(sectionName, result);
+ else if(sectionName == TraceSectionName)
+ section = NewTraceMetaData(sectionName, result);
+ else // else rather than elseif for closer compatibility with old tests
+ section = NewDeviceList(sectionName, result);
+ }
+ else if (!IsEmpty(line) &&
+ ( dynamic_cast<DeviceListSection *>(section.get()) != NULL ||
+ dynamic_cast<SnapshotSection *>(section.get()) != NULL ||
+ dynamic_cast<TraceSection *>(section.get()) != NULL
+ )
+ )
+ {
+ pair<string, string> kv(SplitKeyValue(line));
+ section->Define(kv.first, kv.second);
+ }
+ }
+ // ... or end of file
+ section->End();
+
+ return result;
+}
+
+
+// parse the trace metadata ini file.
+ParsedTrace Parser::ParseTraceMetaData(std::istream& in)
+{
+ ParsedTrace result;
+
+ string line;
+ auto_ptr<Section> section(new NullSection);
+
+ while (getline(in, line))
+ {
+ CleanLine(line); // remove LF, comments
+ string sectionName;
+
+ if (IsSectionHeader(line, sectionName))
+ {
+ // Section ends with start of next section...
+ section->End();
+ section = NewTraceSection(sectionName, result);
+ }
+ else if (!IsEmpty(line))
+ {
+ if (dynamic_cast<IgnoredSection *>(section.get()) == NULL)
+ { // NOT an ignored section, so process it
+ pair<string, string> kv(SplitKeyValue(line));
+ section->Define(kv.first, kv.second);
+ }
+ }
+ }
+ // ... or end of file
+ section->End();
+ return result;
+}
+
+ // build a source tree for a single buffer
+bool Parser::ExtractSourceTree(const std::string &buffer_name, ParsedTrace &metadata, TraceBufferSourceTree &buffer_data)
+{
+ bool bFoundbuffer = false;
+ std::vector<TraceBufferInfo>::iterator it = metadata.trace_buffers.begin();
+
+ while((it != metadata.trace_buffers.end()) && !bFoundbuffer)
+ {
+ if(it->bufferName == buffer_name)
+ {
+ bFoundbuffer = true;
+ buffer_data.buffer_info = *it;
+ }
+ it++;
+ }
+
+ if(bFoundbuffer)
+ {
+ std::map<std::string, std::string>::iterator sbit = metadata.source_buffer_assoc.begin();
+ while(sbit != metadata.source_buffer_assoc.end())
+ {
+ if(sbit->second == buffer_data.buffer_info.bufferName)
+ {
+ // found a source in this buffer...
+ buffer_data.source_core_assoc[sbit->first] = metadata.cpu_source_assoc[sbit->first];
+ }
+ sbit++;
+ }
+ }
+ return bFoundbuffer;
+}
+
+std::vector<std::string> Parser::GetBufferNameList(ParsedTrace &metadata)
+{
+ std::vector<std::string> nameList;
+ std::vector<TraceBufferInfo>::iterator it = metadata.trace_buffers.begin();
+ while(it != metadata.trace_buffers.end())
+ {
+ nameList.push_back(it->bufferName);
+ it++;
+ }
+ return nameList;
+}
+
+void Parser::SetIErrorLogger(ITraceErrorLog *i_err_log)
+{
+ s_pErrorLogger = i_err_log;
+ if(s_pErrorLogger)
+ {
+ s_errlog_handle = s_pErrorLogger->RegisterErrorSource("snapshot_parser");
+ }
+}
+
+ITraceErrorLog *Parser::GetIErrorLogger()
+{
+ return s_pErrorLogger;
+}
+
+void Parser::LogInfoStr(const std::string &logMsg)
+{
+ if(GetIErrorLogger() && s_verbose_logging)
+ GetIErrorLogger()->LogMessage(s_errlog_handle,OCSD_ERR_SEV_INFO,logMsg);
+}
+
+void Parser::SetVerboseLogging(bool verbose)
+{
+ s_verbose_logging = verbose;
+}
+/* End of File snapshot_parser.cpp */
diff --git a/decoder/tests/snapshot_parser_lib/source/snapshot_parser_util.cpp b/decoder/tests/snapshot_parser_lib/source/snapshot_parser_util.cpp
new file mode 100644
index 0000000..b5640c0
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/source/snapshot_parser_util.cpp
@@ -0,0 +1,91 @@
+/*
+ * \file snapshot_parser_util.cpp
+ * \brief OpenCSD : Snapshot Parser Library
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 "snapshot_parser_util.h"
+
+#include <string>
+#include <sstream>
+#include <iomanip>
+#include <iterator>
+using namespace std;
+
+//#include <boost/regex.hpp>
+
+// Make "0xNNNNNNNN" for use in user messages
+string Util::MakeAddressString(uint32_t address)
+{
+ ostringstream oss;
+ oss << "0x" << hex << setw(8) << setfill('0') << address;
+ return oss.str();
+}
+
+// Make "0xNNNNNNNNNNNNNNNN" for use in user messages
+string Util::MakeAddressString(uint64_t address)
+{
+ ostringstream oss;
+ oss << "0x" << hex << setw(16) << setfill('0') << address;
+ return oss.str();
+}
+
+string Util::TrimLeft(const std::string& s, const std::string& ws)
+{
+ string out(s);
+ return out.erase(0, s.find_first_not_of(ws));
+}
+
+string Util::TrimRight(const std::string& s, const std::string& ws)
+{
+ string out(s);
+ return out.erase(s.find_last_not_of(ws) + 1);
+}
+
+string Util::Trim(const std::string& s, const std::string& ws)
+{
+ return TrimRight(TrimLeft(s, ws), ws);
+}
+
+/*bool Util::DoRegexReplace(string& original, const string& re,
+ const string& replacement)
+{
+ const string before(original);
+ const boost::regex ex(re);
+ string after;
+ boost::regex_replace(back_inserter(after), before.begin(), before.end(),
+ ex, replacement);
+ original.assign(after);
+ return before != after;
+}*/
+
+/* End of File snapshot_parser_util.cpp */
diff --git a/decoder/tests/snapshot_parser_lib/source/snapshot_reader.cpp b/decoder/tests/snapshot_parser_lib/source/snapshot_reader.cpp
new file mode 100644
index 0000000..4741e63
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/source/snapshot_reader.cpp
@@ -0,0 +1,270 @@
+/*
+ * \file snapshot_reader.cpp
+ * \brief OpenCSD :
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 "snapshot_reader.h"
+#include "snapshot_parser.h"
+#include "device_parser.h"
+
+#include "opencsd.h"
+
+#include <fstream>
+#include <iterator>
+#include <ios>
+#include <iostream>
+
+#ifdef WIN32
+#define DIR_CHAR '\\'
+#else
+#define DIR_CHAR '/'
+#endif
+
+using namespace Parser;
+
+SnapShotReader::SnapShotReader() :
+ m_snapshotPath(""),
+ m_snapshot_found(false),
+ m_i_err_log(0),
+ m_errlog_handle(0),
+ m_verbose(true),
+ m_read_ok(false)
+{
+ checkPath(); // see if default will work.
+}
+
+SnapShotReader::~SnapShotReader()
+{
+}
+
+void SnapShotReader::setSnapshotDir(const std::string &dir)
+{
+ m_snapshotPath = dir;
+ if(dir.size() > 0)
+ {
+ if(dir.at(dir.size()-1) != DIR_CHAR)
+ m_snapshotPath += DIR_CHAR;
+ }
+ m_read_ok = false;
+ checkPath();
+}
+
+const bool SnapShotReader::readSnapShot()
+{
+ bool bRead = true;
+
+ std::string iniFile = m_snapshotPath + SnapshotINIFilename;
+ std::ifstream in(iniFile.c_str());
+ std::ostringstream oss;
+
+ if(in.is_open())
+ {
+ Parser::SetVerboseLogging(m_verbose);
+ ModernSnapshotParser parser(in);
+ in.close();
+
+ if(m_verbose)
+ {
+ oss.str("");
+ oss << "Parsed snapshot.ini." << std::endl;
+ oss << "Found " << parser.getDeviceCount() << " devices." << std::endl;
+ LogInfo(oss.str());
+ }
+
+ std::vector<int> device_list;
+ parser.getDeviceList(device_list);
+
+ ModernSnapshotParser::DevPtr device;
+
+ for(size_t i = 0; i < device_list.size(); i++)
+ {
+ device = parser.getDevice(device_list[i]);
+ if(m_verbose)
+ {
+ oss.str("");
+ oss << "Device " << device.get()->getID() << ": Ini file = " << device.get()->getIniFile() << "; Name = " << device.get()->getName() << std::endl;
+ LogInfo(oss.str());
+ }
+ iniFile = m_snapshotPath + device.get()->getIniFile();
+ in.open(iniFile.c_str());
+ if(in.is_open())
+ {
+ Parser::Parsed pdev = Parser::ParseSingleDevice(in);
+ m_parsed_device_list[pdev.deviceName] = pdev; // map devices by name
+ in.close();
+
+ }
+ else
+ {
+ oss.str("");
+ oss << "Failed to open device file : " << iniFile << std::endl;
+ LogError(oss.str());
+ }
+ }
+
+ if(parser.getTraceMetadataFile().length() > 0)
+ {
+ if(m_verbose)
+ {
+ oss.str("");
+ oss << "Trace Metadata ini file found : " << parser.getTraceMetadataFile() << std::endl;
+ LogInfo(oss.str());
+ }
+
+ iniFile = m_snapshotPath + parser.getTraceMetadataFile();
+ in.open(iniFile.c_str());
+ if(in.is_open())
+ {
+ m_parsed_trace = Parser::ParseTraceMetaData(in);
+ in.close();
+ if(m_parsed_trace.trace_buffers.size()) // found one or more buffers
+ {
+ std::vector<std::string> bufferNames = GetBufferNameList(m_parsed_trace);
+ std::vector<std::string>::iterator bnit = bufferNames.begin();
+ while(bnit != bufferNames.end())
+ {
+ Parser::TraceBufferSourceTree tbst;
+ if(Parser::ExtractSourceTree(*bnit,m_parsed_trace,tbst))
+ m_source_trees[*bnit] = tbst;
+ bnit++;
+ }
+ }
+
+ }
+ else
+ {
+ oss.str("");
+ oss << "Failed to trace ini file : " << iniFile << std::endl;
+ LogError(oss.str());
+ }
+ }
+ else
+ {
+ oss.str("");
+ oss << "Trace Metadata ini file not found." << std::endl;
+ LogError(oss.str());
+ }
+
+ if(m_verbose)
+ {
+ oss.str("");
+ oss << "Done." << std::endl;
+ LogInfo(oss.str());
+ }
+ }
+ else
+ {
+ oss.str("");
+ oss << "Read Error : Failed to open " << iniFile << "." << std::endl;
+ LogError(oss.str());
+ bRead = false;
+ }
+ m_read_ok = bRead;
+ return bRead;
+}
+
+void SnapShotReader::checkPath()
+{
+ std::string iniFile = m_snapshotPath + SnapshotINIFilename;
+ std::ifstream in(iniFile.c_str());
+ m_snapshot_found = false;
+
+ if(in.is_open())
+ {
+ in.close();
+ m_snapshot_found = true;
+ }
+}
+
+void SnapShotReader::setErrorLogger(ITraceErrorLog *err_log)
+{
+ if(err_log)
+ {
+ m_i_err_log = err_log;
+ m_errlog_handle = m_i_err_log->RegisterErrorSource("snapshot_reader");
+ Parser::SetIErrorLogger(m_i_err_log);
+ }
+}
+
+void SnapShotReader::LogInfo(const std::string &msg)
+{
+ if(m_i_err_log)
+ m_i_err_log->LogMessage(m_errlog_handle, OCSD_ERR_SEV_INFO, msg);
+}
+
+void SnapShotReader::LogError(const std::string &msg)
+{
+ if(m_i_err_log)
+ {
+ ocsdError err(OCSD_ERR_SEV_ERROR,OCSD_ERR_TEST_SNAPSHOT_READ,msg);
+ m_i_err_log->LogError(m_errlog_handle,&err);
+ }
+}
+
+bool SnapShotReader::getSourceBufferNameList(std::vector<std::string> &nameList)
+{
+ nameList.clear();
+ if(snapshotFound())
+ {
+ nameList = GetBufferNameList(m_parsed_trace);
+ }
+ return (bool)(nameList.size() > 0);
+}
+
+bool SnapShotReader::getTraceBufferSourceTree(const std::string &traceBufferName, Parser::TraceBufferSourceTree &sourceTree)
+{
+ bool found = false;
+ std::map<std::string, Parser::TraceBufferSourceTree>::iterator it;
+ it = m_source_trees.find(traceBufferName);
+ if(it != m_source_trees.end())
+ {
+ sourceTree = it->second;
+ found = true;
+ }
+ return found;
+}
+
+bool SnapShotReader::getDeviceData(const std::string &deviceName, Parser::Parsed **devData)
+{
+ std::map<std::string, Parser::Parsed>::iterator it;
+
+ *devData = 0;
+ it = m_parsed_device_list.find(deviceName);
+ if(it != m_parsed_device_list.end())
+ {
+ *devData = &(it->second);
+ }
+ return (*devData != 0);
+}
+
+
+/* End of File snapshot_reader.cpp */
diff --git a/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp b/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp
new file mode 100644
index 0000000..902ce56
--- /dev/null
+++ b/decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp
@@ -0,0 +1,590 @@
+/*
+ * \file ss_to_dcdtree.cpp
+ * \brief OpenCSD :
+ *
+ * \copyright Copyright (c) 2015, ARM Limited. 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.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 "ss_to_dcdtree.h"
+#include "ss_key_value_names.h"
+
+
+CreateDcdTreeFromSnapShot::CreateDcdTreeFromSnapShot() :
+ m_bInit(false),
+ m_pDecodeTree(0),
+ m_pReader(0),
+ m_pErrLogInterface(0),
+ m_bPacketProcOnly(false),
+ m_BufferFileName("")
+{
+ m_errlog_handle = 0;
+ m_add_create_flags = 0;
+}
+
+CreateDcdTreeFromSnapShot::~CreateDcdTreeFromSnapShot()
+{
+ destroyDecodeTree();
+}
+
+void CreateDcdTreeFromSnapShot::initialise(SnapShotReader *pReader, ITraceErrorLog *pErrLogInterface)
+{
+ if((pErrLogInterface != 0) && (pReader != 0))
+ {
+ m_pReader = pReader;
+ m_pErrLogInterface = pErrLogInterface;
+ m_errlog_handle = m_pErrLogInterface->RegisterErrorSource("ss2_dcdtree");
+ m_bInit = true;
+ }
+}
+
+bool CreateDcdTreeFromSnapShot::createDecodeTree(const std::string &SourceName, bool bPacketProcOnly, uint32_t add_create_flags)
+{
+ m_add_create_flags = add_create_flags;
+ if(m_bInit)
+ {
+ if(!m_pReader->snapshotReadOK())
+ {
+ LogError("Supplied snapshot reader has not correctly read the snapshot.\n");
+ return false;
+ }
+
+ m_bPacketProcOnly = bPacketProcOnly;
+ Parser::TraceBufferSourceTree tree;
+
+ if(m_pReader->getTraceBufferSourceTree(SourceName, tree))
+ {
+ int numDecodersCreated = 0; // count how many we create - if none then give up.
+ uint32_t formatter_flags = OCSD_DFRMTR_FRAME_MEM_ALIGN;
+
+ /* make a note of the trace binary file name + path to ss directory */
+ m_BufferFileName = m_pReader->getSnapShotDir() + tree.buffer_info.dataFileName;
+
+ ocsd_dcd_tree_src_t src_format = tree.buffer_info.dataFormat == "source_data" ? OCSD_TRC_SRC_SINGLE : OCSD_TRC_SRC_FRAME_FORMATTED;
+
+ if (tree.buffer_info.dataFormat == "dstream_coresight")
+ formatter_flags = OCSD_DFRMTR_HAS_FSYNCS;
+
+ /* create the initial device tree */
+ // TBD: handle syncs / hsyncs data from TPIU
+ m_pDecodeTree = DecodeTree::CreateDecodeTree(src_format, formatter_flags);
+ if(m_pDecodeTree == 0)
+ {
+ LogError("Failed to create decode tree object\n");
+ return false;
+ }
+
+ // use our error logger - don't use the tree default.
+ m_pDecodeTree->setAlternateErrorLogger(m_pErrLogInterface);
+
+ if(!bPacketProcOnly)
+ {
+ m_pDecodeTree->createMemAccMapper();
+ }
+
+ /* run through each protocol source to this buffer... */
+ std::map<std::string, std::string>::iterator it = tree.source_core_assoc.begin();
+
+ while(it != tree.source_core_assoc.end())
+ {
+ Parser::Parsed *etm_dev, *core_dev;
+ if(m_pReader->getDeviceData(it->first,&etm_dev))
+ {
+ // found the device data for this device.
+
+ // see if we have a core name (STM / ITM not associated with a core);
+ std::string coreDevName = it->second;
+ if(coreDevName.size() > 0)
+ {
+ if(m_pReader->getDeviceData(coreDevName,&core_dev))
+ {
+ if(createPEDecoder(core_dev->deviceTypeName,etm_dev))
+ {
+ numDecodersCreated++;
+ if(!bPacketProcOnly &&(core_dev->dumpDefs.size() > 0))
+ {
+ processDumpfiles(core_dev->dumpDefs);
+ }
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << "Failed to create decoder for source " << it->first << ".\n";
+ LogError(oss.str());
+ }
+ }
+ else
+ {
+ // Could not find the device data for the core.
+ // unexpected - since we created the associations.
+ std::ostringstream oss;
+ oss << "Failed to get device data for source " << it->first << ".\n";
+ LogError(oss.str());
+ }
+ }
+ else
+ {
+ // none-core source
+ if(createSTDecoder(etm_dev))
+ {
+ numDecodersCreated++;
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << "Failed to create decoder for none core source " << it->first << ".\n";
+ LogError(oss.str());
+ }
+ }
+ }
+ else
+ {
+ // TBD: could not find the device data for the source.
+ // again unexpected - suggests ss format error.
+ std::ostringstream oss;
+ oss << "Failed to find device data for source " << it->first << ".\n";
+ LogError(oss.str());
+ }
+ if(src_format == OCSD_TRC_SRC_SINGLE)
+ it = tree.source_core_assoc.end();
+ else
+ it++;
+ }
+
+ if(numDecodersCreated == 0)
+ {
+ // nothing useful found
+ destroyDecodeTree();
+ }
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << "Failed to get parsed source tree for buffer " << SourceName << ".\n";
+ LogError(oss.str());
+ }
+ }
+ return (bool)(m_pDecodeTree != 0);
+}
+
+void CreateDcdTreeFromSnapShot::destroyDecodeTree()
+{
+ if(m_pDecodeTree)
+ DecodeTree::DestroyDecodeTree(m_pDecodeTree);
+ m_pDecodeTree = 0;
+ m_pReader = 0;
+ m_pErrLogInterface = 0;
+ m_errlog_handle = 0;
+ m_BufferFileName = "";
+}
+
+void CreateDcdTreeFromSnapShot::LogError(const std::string &msg)
+{
+ ocsdError err(OCSD_ERR_SEV_ERROR,OCSD_ERR_TEST_SS_TO_DECODER,msg);
+ m_pErrLogInterface->LogError(m_errlog_handle,&err);
+}
+
+void CreateDcdTreeFromSnapShot::LogError(const ocsdError &err)
+{
+ m_pErrLogInterface->LogError(m_errlog_handle,&err);
+}
+
+bool CreateDcdTreeFromSnapShot::createPEDecoder(const std::string &coreName, Parser::Parsed *devSrc)
+{
+ bool bCreatedDecoder = false;
+ std::string devTypeName = devSrc->deviceTypeName;
+
+ // split off .x from type name.
+ std::string::size_type pos = devTypeName.find_first_of('.');
+ if(pos != std::string::npos)
+ devTypeName = devTypeName.substr(0,pos);
+
+ // split according to protocol
+ if(devTypeName == ETMv4Protocol)
+ {
+ bCreatedDecoder = createETMv4Decoder(coreName,devSrc);
+ }
+ else if(devTypeName == ETMv3Protocol)
+ {
+ bCreatedDecoder = createETMv3Decoder(coreName,devSrc);
+ }
+ else if(devTypeName == PTMProtocol || devTypeName == PFTProtocol)
+ {
+ bCreatedDecoder = createPTMDecoder(coreName,devSrc);
+ }
+ else if (devTypeName == ETEProtocol)
+ {
+ bCreatedDecoder = createETEDecoder(coreName, devSrc);
+ }
+
+ return bCreatedDecoder;
+}
+
+// create an ETMv4 decoder based on the deviceN.ini file.
+bool CreateDcdTreeFromSnapShot::createETMv4Decoder(const std::string &coreName, Parser::Parsed *devSrc, const bool bDataChannel /* = false*/)
+{
+ bool createdDecoder = false;
+ bool configOK = true;
+
+ // generate the config data from the device data.
+ ocsd_etmv4_cfg config;
+
+ regs_to_access_t regs_to_access[] = {
+ { ETMv4RegCfg, true, &config.reg_configr, 0 },
+ { ETMv4RegIDR, true, &config.reg_traceidr, 0 },
+ { ETMv4RegIDR0, true, &config.reg_idr0, 0 },
+ { ETMv4RegIDR1, false, &config.reg_idr1, 0x4100F403 },
+ { ETMv4RegIDR2, true, &config.reg_idr2, 0 },
+ { ETMv4RegIDR8, false, &config.reg_idr8, 0 },
+ { ETMv4RegIDR9, false, &config.reg_idr9, 0 },
+ { ETMv4RegIDR10, false, &config.reg_idr10, 0 },
+ { ETMv4RegIDR11, false, &config.reg_idr11, 0 },
+ { ETMv4RegIDR12, false, &config.reg_idr12, 0 },
+ { ETMv4RegIDR13,false, &config.reg_idr13, 0 },
+ };
+
+ // extract registers
+ configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
+
+ // extract core profile
+ if(configOK)
+ configOK = getCoreProfile(coreName,config.arch_ver,config.core_prof);
+
+ // good config - generate the decoder on the tree.
+ if(configOK)
+ {
+ ocsd_err_t err = OCSD_OK;
+ EtmV4Config configObj(&config);
+ const char *decoderName = bDataChannel ? OCSD_BUILTIN_DCD_ETMV4D : OCSD_BUILTIN_DCD_ETMV4I;
+
+ err = m_pDecodeTree->createDecoder(decoderName, m_add_create_flags | (m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER),&configObj);
+
+ if(err == OCSD_OK)
+ createdDecoder = true;
+ else
+ {
+ std::string msg = "Snapshot processor : failed to create " + (std::string)decoderName + " decoder on decode tree.";
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,msg));
+ }
+ }
+
+ return createdDecoder;
+}
+
+bool CreateDcdTreeFromSnapShot::createETEDecoder(const std::string &coreName, Parser::Parsed *devSrc)
+{
+ bool createdDecoder = false;
+ bool configOK = true;
+
+ // generate the config data from the device data.
+ ocsd_ete_cfg config;
+
+ // ete regs are same names Etmv4 in places...
+ regs_to_access_t regs_to_access[] = {
+ { ETMv4RegCfg, true, &config.reg_configr, 0 },
+ { ETMv4RegIDR, true, &config.reg_traceidr, 0 },
+ { ETMv4RegIDR0, true, &config.reg_idr0, 0 },
+ { ETMv4RegIDR1, false, &config.reg_idr1, 0x4100F403 },
+ { ETMv4RegIDR2, true, &config.reg_idr2, 0 },
+ { ETMv4RegIDR8, false, &config.reg_idr8, 0 },
+ { ETERegDevArch, false, &config.reg_devarch, 0x47705A13 },
+ };
+
+ // extract registers
+ configOK = getRegisters(devSrc->regDefs, sizeof(regs_to_access) / sizeof(regs_to_access_t), regs_to_access);
+
+ // extract core profile
+ if (configOK)
+ configOK = getCoreProfile(coreName, config.arch_ver, config.core_prof);
+
+ // good config - generate the decoder on the tree.
+ if (configOK)
+ {
+ ocsd_err_t err = OCSD_OK;
+ ETEConfig configObj(&config);
+ const char *decoderName = OCSD_BUILTIN_DCD_ETE;
+
+ err = m_pDecodeTree->createDecoder(decoderName, m_add_create_flags | (m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER), &configObj);
+
+ if (err == OCSD_OK)
+ createdDecoder = true;
+ else
+ {
+ std::string msg = "Snapshot processor : failed to create " + (std::string)decoderName + " decoder on decode tree.";
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, msg));
+ }
+ }
+
+ return createdDecoder;
+}
+
+// create an ETMv3 decoder based on the register values in the deviceN.ini file.
+bool CreateDcdTreeFromSnapShot::createETMv3Decoder(const std::string &coreName, Parser::Parsed *devSrc)
+{
+ bool createdDecoder = false;
+ bool configOK = true;
+
+ // generate the config data from the device data.
+ ocsd_etmv3_cfg cfg_regs;
+
+ regs_to_access_t regs_to_access[] = {
+ { ETMv3PTMRegIDR, true, &cfg_regs.reg_idr, 0 },
+ { ETMv3PTMRegCR, true, &cfg_regs.reg_ctrl, 0 },
+ { ETMv3PTMRegCCER, true, &cfg_regs.reg_ccer, 0 },
+ { ETMv3PTMRegTraceIDR, true, &cfg_regs.reg_trc_id, 0}
+ };
+
+ // extract registers
+ configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
+
+ // extract core profile
+ if(configOK)
+ configOK = getCoreProfile(coreName,cfg_regs.arch_ver,cfg_regs.core_prof);
+
+ // good config - generate the decoder on the tree.
+ if(configOK)
+ {
+ EtmV3Config config(&cfg_regs);
+ ocsd_err_t err = OCSD_OK;
+ err = m_pDecodeTree->createDecoder(OCSD_BUILTIN_DCD_ETMV3, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&config);
+
+ if(err == OCSD_OK)
+ createdDecoder = true;
+ else
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Snapshot processor : failed to create ETMV3 decoder on decode tree."));
+ }
+ return createdDecoder;
+}
+
+bool CreateDcdTreeFromSnapShot::createPTMDecoder(const std::string &coreName, Parser::Parsed *devSrc)
+{
+ bool createdDecoder = false;
+ bool configOK = true;
+
+ // generate the config data from the device data.
+
+ ocsd_ptm_cfg config;
+
+ regs_to_access_t regs_to_access[] = {
+ { ETMv3PTMRegIDR, true, &config.reg_idr, 0 },
+ { ETMv3PTMRegCR, true, &config.reg_ctrl, 0 },
+ { ETMv3PTMRegCCER, true, &config.reg_ccer, 0 },
+ { ETMv3PTMRegTraceIDR, true, &config.reg_trc_id, 0}
+ };
+
+ // extract registers
+ configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
+
+ // extract core profile
+ if(configOK)
+ configOK = getCoreProfile(coreName,config.arch_ver,config.core_prof);
+
+ // good config - generate the decoder on the tree.
+ if(configOK)
+ {
+ PtmConfig configObj(&config);
+ ocsd_err_t err = OCSD_OK;
+ err = m_pDecodeTree->createDecoder(OCSD_BUILTIN_DCD_PTM, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&configObj);
+
+ if(err == OCSD_OK)
+ createdDecoder = true;
+ else
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Snapshot processor : failed to create PTM decoder on decode tree."));
+ }
+ return createdDecoder;
+}
+
+bool CreateDcdTreeFromSnapShot::createSTDecoder(Parser::Parsed *devSrc)
+{
+ bool bCreatedDecoder = false;
+ std::string devTypeName = devSrc->deviceTypeName;
+
+ // split off .x from type name.
+ std::string::size_type pos = devTypeName.find_first_of('.');
+ if(pos != std::string::npos)
+ devTypeName = devTypeName.substr(0,pos);
+
+ if(devTypeName == STMProtocol)
+ {
+ bCreatedDecoder = createSTMDecoder(devSrc);
+ }
+
+ return bCreatedDecoder;
+}
+
+bool CreateDcdTreeFromSnapShot::createSTMDecoder(Parser::Parsed *devSrc)
+{
+ bool createdDecoder = false;
+ bool configOK = true;
+
+ // generate the config data from the device data.
+
+ ocsd_stm_cfg config;
+
+ regs_to_access_t regs_to_access[] = {
+ { STMRegTCSR, true, &config.reg_tcsr, 0 }
+ };
+
+ configOK = getRegisters(devSrc->regDefs,sizeof(regs_to_access)/sizeof(regs_to_access_t), regs_to_access);
+ if(configOK)
+ {
+ ocsd_err_t err = OCSD_OK;
+ STMConfig configObj(&config);
+
+ err = m_pDecodeTree->createDecoder(OCSD_BUILTIN_DCD_STM, m_bPacketProcOnly ? OCSD_CREATE_FLG_PACKET_PROC : OCSD_CREATE_FLG_FULL_DECODER,&configObj);
+
+ if(err == OCSD_OK)
+ createdDecoder = true;
+ else
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,"Snapshot processor : failed to create STM decoder on decode tree."));
+ }
+
+ return createdDecoder;
+}
+
+
+
+// get a set of register values.
+bool CreateDcdTreeFromSnapShot::getRegisters(std::map<std::string, std::string, Util::CaseInsensitiveLess> &regDefs, int numRegs, regs_to_access_t *reg_access_array)
+{
+ bool regsOK = true;
+
+ for(int rv = 0; rv < numRegs; rv++)
+ {
+ if(!getRegByPrefix( regDefs,reg_access_array[rv]))
+ regsOK = false;
+ }
+ return regsOK;
+}
+
+// strip out any parts with brackets
+bool CreateDcdTreeFromSnapShot::getRegByPrefix(std::map<std::string, std::string, Util::CaseInsensitiveLess> &regDefs,
+ regs_to_access_t &reg_accessor)
+{
+ std::ostringstream oss;
+ bool bFound = false;
+ std::map<std::string, std::string, Util::CaseInsensitiveLess>::iterator it;
+ std::string prefix_cmp;
+ std::string::size_type pos;
+ std::string strval;
+
+ *reg_accessor.value = 0;
+
+ it = regDefs.begin();
+ while((it != regDefs.end()) && !bFound)
+ {
+ prefix_cmp = it->first;
+ pos = prefix_cmp.find_first_of('(');
+ if(pos != std::string::npos)
+ {
+ prefix_cmp = prefix_cmp.substr(0, pos);
+ }
+ if(prefix_cmp == reg_accessor.pszName)
+ {
+ strval = it->second;
+ bFound = true;
+ }
+ it++;
+ }
+
+ if(bFound)
+ *reg_accessor.value = strtoul(strval.c_str(),0,0);
+ else
+ {
+ ocsd_err_severity_t sev = OCSD_ERR_SEV_ERROR;
+ if(reg_accessor.failIfMissing)
+ {
+ oss << "Error:";
+ }
+ else
+ {
+ // no fail if missing - set any default and just warn.
+ bFound = true;
+ oss << "Warning: Default set for register. ";
+ sev = OCSD_ERR_SEV_WARN;
+ *reg_accessor.value = reg_accessor.val_default;
+ }
+ oss << "Missing " << reg_accessor.pszName << "\n";
+ m_pErrLogInterface->LogMessage(m_errlog_handle, sev, oss.str());
+ }
+ return bFound;
+}
+
+bool CreateDcdTreeFromSnapShot::getCoreProfile(const std::string &coreName, ocsd_arch_version_t &arch_ver, ocsd_core_profile_t &core_prof)
+{
+ bool profileOK = true;
+ ocsd_arch_profile_t ap = m_arch_profiles.getArchProfile(coreName);
+ if(ap.arch != ARCH_UNKNOWN)
+ {
+ arch_ver = ap.arch;
+ core_prof = ap.profile;
+ }
+ else
+ {
+ std::ostringstream oss;
+ oss << "Unrecognized Core name " << coreName << ". Cannot evaluate profile or architecture.";
+ LogError(oss.str());
+ profileOK = false;
+ }
+ return profileOK;
+}
+
+void CreateDcdTreeFromSnapShot::processDumpfiles(std::vector<Parser::DumpDef> &dumps)
+{
+ std::string dumpFilePathName;
+ std::vector<Parser::DumpDef>::const_iterator it;
+
+ it = dumps.begin();
+ while(it != dumps.end())
+ {
+ dumpFilePathName = m_pReader->getSnapShotDir() + it->path;
+ ocsd_file_mem_region_t region;
+ ocsd_err_t err = OCSD_OK;
+
+ region.start_address = it->address;
+ region.file_offset = it->offset;
+ region.region_size = it->length;
+
+ // ensure we respect optional length and offset parameter and
+ // allow multiple dump entries with same file name to define regions
+ if (!TrcMemAccessorFile::isExistingFileAccessor(dumpFilePathName))
+ err = m_pDecodeTree->addBinFileRegionMemAcc(&region, 1, OCSD_MEM_SPACE_ANY, dumpFilePathName);
+ else
+ err = m_pDecodeTree->updateBinFileRegionMemAcc(&region, 1, OCSD_MEM_SPACE_ANY, dumpFilePathName);
+ if(err != OCSD_OK)
+ {
+ std::ostringstream oss;
+ oss << "Failed to create memory accessor for file " << dumpFilePathName << ".";
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR,err,oss.str()));
+ }
+ it++;
+ }
+}
+
+/* End of File ss_to_dcdtree.cpp */