summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorRafael Roquetto <rafael.roquetto@kdab.com>2017-02-01 17:32:13 -0200
committerSérgio Martins <sergio.martins@kdab.com>2018-01-28 19:17:02 +0000
commit48bce2e8f0d787342f3e0f86335460fa25e8ac8f (patch)
tree038af77f6e112f6c9a348a386e9c1eaff3aeab47 /src/tools
parent2b7de16fbe399daa00986f2d32d05cfe51966b66 (diff)
Support for LTTNG and ETW tracing
This commit introduces minimal support for instrumentation within Qt. Currently, only LTTNG/Linux and ETW/Windows are supported. Change-Id: I59b48cf83acf5532a998bb493e6379e9177e14c8 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/tracegen/etw.cpp228
-rw-r--r--src/tools/tracegen/etw.h48
-rw-r--r--src/tools/tracegen/helpers.cpp92
-rw-r--r--src/tools/tracegen/helpers.h57
-rw-r--r--src/tools/tracegen/lttng.cpp215
-rw-r--r--src/tools/tracegen/lttng.h48
-rw-r--r--src/tools/tracegen/panic.cpp59
-rw-r--r--src/tools/tracegen/panic.h45
-rw-r--r--src/tools/tracegen/provider.cpp304
-rw-r--r--src/tools/tracegen/provider.h95
-rw-r--r--src/tools/tracegen/qtheaders.cpp51
-rw-r--r--src/tools/tracegen/qtheaders.h45
-rw-r--r--src/tools/tracegen/tracegen.cpp109
-rw-r--r--src/tools/tracegen/tracegen.pro21
14 files changed, 1417 insertions, 0 deletions
diff --git a/src/tools/tracegen/etw.cpp b/src/tools/tracegen/etw.cpp
new file mode 100644
index 0000000000..07f2d114b6
--- /dev/null
+++ b/src/tools/tracegen/etw.cpp
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "etw.h"
+#include "provider.h"
+#include "helpers.h"
+#include "qtheaders.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <quuid.h>
+
+static inline QString providerVar(const QString &providerName)
+{
+ return providerName + QLatin1String("_provider");
+}
+
+static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
+{
+ const QString &name = field.name;
+
+ switch (field.backendType) {
+ case Tracepoint::Field::QtString:
+ stream << "TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>("
+ << name << ".utf16()), " << name << ".size(), \"" << name << "\")";
+ return;
+ case Tracepoint::Field::QtByteArray:
+ stream << "TraceLoggingBinary(" << name << ".constData(), "
+ << name << ".size(), \"" << name << "\")";
+ return;
+ case Tracepoint::Field::QtUrl:
+ stream << "TraceLoggingValue(" << name << ".toEncoded().constData(), \"" << name << "\")";
+ return;
+ case Tracepoint::Field::QtRect:
+ stream << "TraceLoggingValue(" << name << ".x(), \"x\"), "
+ << "TraceLoggingValue(" << name << ".y(), \"y\"), "
+ << "TraceLoggingValue(" << name << ".width(), \"width\"), "
+ << "TraceLoggingValue(" << name << ".height(), \"height\")";
+ return;
+ default:
+ break;
+ }
+
+ stream << "TraceLoggingValue(" << name << ", \"" << name << "\")";
+}
+
+static QString createGuid(const QUuid &uuid)
+{
+ QString guid;
+
+ QTextStream stream(&guid);
+
+ hex(stream);
+
+ stream << "("
+ << "0x" << uuid.data1 << ", "
+ << "0x" << uuid.data2 << ", "
+ << "0x" << uuid.data3 << ", "
+ << "0x" << uuid.data4[0] << ", "
+ << "0x" << uuid.data4[1] << ", "
+ << "0x" << uuid.data4[2] << ", "
+ << "0x" << uuid.data4[3] << ", "
+ << "0x" << uuid.data4[4] << ", "
+ << "0x" << uuid.data4[5] << ", "
+ << "0x" << uuid.data4[6] << ", "
+ << "0x" << uuid.data4[7]
+ << ")";
+
+ return guid;
+}
+
+static void writePrologue(QTextStream &stream, const QString &fileName, const QString &providerName)
+{
+ QUuid uuid = QUuid::createUuidV5(QUuid(), providerName.toLocal8Bit());
+
+ const QString provider = providerVar(providerName);
+ const QString guard = includeGuard(fileName);
+ const QString guid = createGuid(uuid);
+ const QString guidString = uuid.toString();
+
+ stream << "#ifndef " << guard << "\n"
+ << "#define " << guard << "\n"
+ << "#include <windows.h>\n"
+ << "#include <TraceLoggingProvider.h>\n";
+
+ /* TraceLogging API macros cannot deal with UTF8
+ * source files, so we work around it like this
+ */
+ stream << "#undef _TlgPragmaUtf8Begin\n"
+ "#undef _TlgPragmaUtf8End\n"
+ "#define _TlgPragmaUtf8Begin\n"
+ "#define _TlgPragmaUtf8End\n";
+
+ stream << qtHeaders();
+
+ stream << "\n";
+
+ stream << "#ifdef TRACEPOINT_DEFINE\n"
+ << "/* " << guidString << " */\n"
+ << "TRACELOGGING_DEFINE_PROVIDER(" << provider << ", \""
+ << providerName <<"\", " << guid << ");\n\n";
+
+ stream << "static inline void registerProvider()\n"
+ << "{\n"
+ << " TraceLoggingRegister(" << provider << ");\n"
+ << "}\n\n";
+
+ stream << "static inline void unregisterProvider()\n"
+ << "{\n"
+ << " TraceLoggingUnregister(" << provider << ");\n"
+ << "}\n";
+
+ stream << "Q_CONSTRUCTOR_FUNCTION(registerProvider)\n"
+ << "Q_DESTRUCTOR_FUNCTION(unregisterProvider)\n\n";
+
+ stream << "#else\n"
+ << "TRACELOGGING_DECLARE_PROVIDER(" << provider << ");\n"
+ << "#endif // TRACEPOINT_DEFINE\n\n";
+}
+
+static void writeEpilogue(QTextStream &stream, const QString &fileName)
+{
+ stream << "\n#endif // " << includeGuard(fileName) << "\n"
+ << "#include <private/qtrace_p.h>\n";
+}
+
+static void writeWrapper(QTextStream &stream, const Tracepoint &tracepoint,
+ const QString &providerName)
+{
+ const QString argList = formatFunctionSignature(tracepoint.args);
+ const QString paramList = formatParameterList(tracepoint.args, ETW);
+ const QString &name = tracepoint.name;
+ const QString includeGuard = QStringLiteral("TP_%1_%2").arg(providerName).arg(name).toUpper();
+ const QString provider = providerVar(providerName);
+
+ stream << "\n";
+
+ stream << "inline void trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " TraceLoggingWrite(" << provider << ", \"" << name << "\"";
+
+ for (const Tracepoint::Field &field : tracepoint.fields) {
+ stream << ",\n";
+ stream << " ";
+ writeEtwMacro(stream, field);
+ }
+
+ stream << ");\n"
+ << "}\n\n";
+
+ stream << "inline void do_trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " trace_" << name << "(" << paramList << ");\n"
+ << "}\n";
+
+ stream << "inline bool trace_" << name << "_enabled()\n"
+ << "{\n"
+ << " return TraceLoggingProviderEnabled(" << provider << ", 0, 0);\n"
+ << "}\n";
+}
+
+static void writeTracepoints(QTextStream &stream, const Provider &provider)
+{
+ if (provider.tracepoints.isEmpty())
+ return;
+
+ const QString includeGuard = QStringLiteral("TP_%1_PROVIDER").arg(provider.name).toUpper();
+
+ stream << "#if !defined(" << includeGuard << ") && !defined(TRACEPOINT_DEFINE)\n"
+ << "#define " << includeGuard << "\n"
+ << "namespace QtPrivate {\n";
+
+ for (const Tracepoint &t : provider.tracepoints)
+ writeWrapper(stream, t, provider.name);
+
+ stream << "} // namespace QtPrivate\n"
+ << "#endif // " << includeGuard << "\n\n";
+}
+
+void writeEtw(QFile &file, const Provider &provider)
+{
+ QTextStream stream(&file);
+
+ const QString fileName = QFileInfo(file.fileName()).fileName();
+
+ writePrologue(stream, fileName, provider.name);
+ writeTracepoints(stream, provider);
+ writeEpilogue(stream, fileName);
+}
+
diff --git a/src/tools/tracegen/etw.h b/src/tools/tracegen/etw.h
new file mode 100644
index 0000000000..5fc9b57eaa
--- /dev/null
+++ b/src/tools/tracegen/etw.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ETW_H
+#define ETW_H
+
+struct Provider;
+class QFile;
+
+void writeEtw(QFile &device, const Provider &p);
+
+#endif // ETW_H
diff --git a/src/tools/tracegen/helpers.cpp b/src/tools/tracegen/helpers.cpp
new file mode 100644
index 0000000000..f0ac7ed47f
--- /dev/null
+++ b/src/tools/tracegen/helpers.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpers.h"
+#include <qdebug.h>
+
+QString includeGuard(const QString &filename)
+{
+ QString guard = filename.toUpper();
+
+ for (int i = 0; i < guard.size(); ++i) {
+ if (!guard.at(i).isLetterOrNumber())
+ guard[i] = QChar('_');
+ }
+
+ return guard;
+}
+
+template <typename T>
+static QString joinArguments(const QVector<Tracepoint::Argument> &args, T joinFunction)
+{
+ QString ret;
+ bool first = true;
+
+ for (const Tracepoint::Argument &arg : args) {
+ if (!first)
+ ret += QLatin1String(", ");
+
+ ret += joinFunction(arg);
+
+ first = false;
+ }
+
+ return ret;
+}
+
+QString formatFunctionSignature(const QVector<Tracepoint::Argument> &args)
+{
+ return joinArguments(args, [](const Tracepoint::Argument &arg) {
+ return QStringLiteral("%1 %2").arg(arg.type).arg(arg.name);
+ });
+}
+
+QString formatParameterList(const QVector<Tracepoint::Argument> &args, ParamType type)
+{
+ if (type == LTTNG) {
+ QString ret;
+
+ for (const Tracepoint::Argument &arg : args)
+ ret += QLatin1String(", ") + arg.name;
+
+ return ret;
+ }
+
+ return joinArguments(args, [](const Tracepoint::Argument &arg) { return arg.name; });
+}
diff --git a/src/tools/tracegen/helpers.h b/src/tools/tracegen/helpers.h
new file mode 100644
index 0000000000..77f16a0da6
--- /dev/null
+++ b/src/tools/tracegen/helpers.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPERS_H
+#define HELPERS_H
+
+#include "provider.h"
+
+#include <qvector.h>
+#include <qstring.h>
+
+enum ParamType {
+ LTTNG,
+ ETW
+};
+
+QString includeGuard(const QString &filename);
+QString formatFunctionSignature(const QVector<Tracepoint::Argument> &args);
+QString formatParameterList(const QVector<Tracepoint::Argument> &args, ParamType type);
+
+#endif // HELPERS_H
diff --git a/src/tools/tracegen/lttng.cpp b/src/tools/tracegen/lttng.cpp
new file mode 100644
index 0000000000..6c0d8cc88b
--- /dev/null
+++ b/src/tools/tracegen/lttng.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lttng.h"
+#include "provider.h"
+#include "helpers.h"
+#include "panic.h"
+#include "qtheaders.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <qdebug.h>
+
+static void writeCtfMacro(QTextStream &stream, const Tracepoint::Field &field)
+{
+ const QString &paramType = field.paramType;
+ const QString &name = field.name;
+ const QString &seqLen = field.seqLen;
+ const int arrayLen = field.arrayLen;
+
+ switch (field.backendType) {
+ case Tracepoint::Field::Array:
+ stream << "ctf_array(" <<paramType << ", "
+ << name << ", " << name << ", " << arrayLen << ")";
+ return;
+ case Tracepoint::Field::Sequence:
+ stream << "ctf_sequence(" << paramType
+ << ", " << name << ", " << name
+ << ", unsigned int, " << seqLen << ")";
+ return;
+ case Tracepoint::Field::Integer:
+ stream << "ctf_integer(" << paramType << ", " << name << ", " << name << ")";
+ return;
+ case Tracepoint::Field::Float:
+ stream << "ctf_float(" << paramType << ", " << name << ", " << name << ")";
+ return;
+ case Tracepoint::Field::String:
+ stream << "ctf_string(" << name << ", " << name << ")";
+ return;
+ case Tracepoint::Field::QtString:
+ stream << "ctf_sequence(const ushort, " << name << ", "
+ << name << ".utf16(), unsigned int, " << name << ".size())";
+ return;
+ case Tracepoint::Field::QtByteArray:
+ stream << "ctf_sequence(const char, " << name << ", "
+ << name << ".constData(), unsigned int, " << name << ".size())";
+ return;
+ case Tracepoint::Field::QtUrl:
+ stream << "ctf_sequence(const char, " << name << ", "
+ << name << ".toEncoded().constData(), unsigned int, "
+ << name << ".toEncoded().size())";
+ return;
+ case Tracepoint::Field::QtRect:
+ stream << "ctf_integer(int, x, " << name << ".x()) "
+ << "ctf_integer(int, y, " << name << ".y()) "
+ << "ctf_integer(int, width, " << name << ".width()) "
+ << "ctf_integer(int, height, " << name << ".height()) ";
+ return;
+ case Tracepoint::Field::Unknown:
+ panic("Cannot deduce CTF type for '%s %s", qPrintable(paramType), qPrintable(name));
+ break;
+ }
+}
+
+static void writePrologue(QTextStream &stream, const QString &fileName, const QString &providerName)
+{
+ stream << "#undef TRACEPOINT_PROVIDER\n";
+ stream << "#define TRACEPOINT_PROVIDER " << providerName << "\n\n";
+
+ stream << qtHeaders();
+
+ const QString guard = includeGuard(fileName);
+
+ stream << "\n";
+
+ /* the first guard is the usual one, the second is required
+ * by LTTNG to force the re-evaluation of TRACEPOINT_* macros
+ */
+ stream << "#if !defined(" << guard << ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n";
+
+ stream << "#define " << guard << "\n\n"
+ << "#undef TRACEPOINT_INCLUDE\n"
+ << "#define TRACEPOINT_INCLUDE \"" << fileName << "\"\n\n";
+
+ stream << "#include <lttng/tracepoint.h>\n\n";
+}
+
+static void writeEpilogue(QTextStream &stream, const QString &fileName)
+{
+ stream << "\n";
+ stream << "#endif // " << includeGuard(fileName) << "\n"
+ << "#include <lttng/tracepoint-event.h>\n"
+ << "#include <private/qtrace_p.h>\n";
+}
+
+static void writeWrapper(QTextStream &stream,
+ const Tracepoint &tracepoint, const QString &providerName)
+{
+ const QString argList = formatFunctionSignature(tracepoint.args);
+ const QString paramList = formatParameterList(tracepoint.args, LTTNG);
+ const QString &name = tracepoint.name;
+ const QString includeGuard = QStringLiteral("TP_%1_%2").arg(providerName).arg(name).toUpper();
+
+ /* prevents the redefinion of the inline wrapper functions
+ * once LTTNG recursively includes this header file
+ */
+ stream << "\n"
+ << "#ifndef " << includeGuard << "\n"
+ << "#define " << includeGuard << "\n"
+ << "namespace QtPrivate {\n";
+
+ stream << "inline void trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " tracepoint(" << providerName << ", " << name << paramList << ");\n"
+ << "}\n";
+
+ stream << "inline void do_trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " do_tracepoint(" << providerName << ", " << name << paramList << ");\n"
+ << "}\n";
+
+ stream << "inline bool trace_" << name << "_enabled()\n"
+ << "{\n"
+ << " return tracepoint_enabled(" << providerName << ", " << name << ");\n"
+ << "}\n";
+
+ stream << "} // namespace QtPrivate\n"
+ << "#endif // " << includeGuard << "\n\n";
+}
+
+static void writeTracepoint(QTextStream &stream,
+ const Tracepoint &tracepoint, const QString &providerName)
+{
+ stream << "TRACEPOINT_EVENT(\n"
+ << " " << providerName << ",\n"
+ << " " << tracepoint.name << ",\n"
+ << " TP_ARGS(";
+
+ const char *comma = nullptr;
+
+ for (const Tracepoint::Argument &arg : tracepoint.args) {
+ stream << comma << arg.type << ", " << arg.name;
+ comma = ", ";
+ }
+
+ stream << "),\n"
+ << " TP_FIELDS(";
+
+ const char *newline = nullptr;
+
+ for (const Tracepoint::Field &f : tracepoint.fields) {
+ stream << newline;
+ writeCtfMacro(stream, f);
+ newline = "\n ";
+ }
+
+ stream << ")\n)\n\n";
+}
+
+static void writeTracepoints(QTextStream &stream, const Provider &provider)
+{
+ for (const Tracepoint &t : provider.tracepoints) {
+ writeTracepoint(stream, t, provider.name);
+ writeWrapper(stream, t, provider.name);
+ }
+}
+
+void writeLttng(QFile &file, const Provider &provider)
+{
+ QTextStream stream(&file);
+
+ const QString fileName = QFileInfo(file.fileName()).fileName();
+
+ writePrologue(stream, fileName, provider.name);
+ writeTracepoints(stream, provider);
+ writeEpilogue(stream, fileName);
+}
diff --git a/src/tools/tracegen/lttng.h b/src/tools/tracegen/lttng.h
new file mode 100644
index 0000000000..0307b375bc
--- /dev/null
+++ b/src/tools/tracegen/lttng.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LTTNG_H
+#define LTTNG_H
+
+struct Provider;
+class QFile;
+
+void writeLttng(QFile &device, const Provider &p);
+
+#endif // LTTNG_H
diff --git a/src/tools/tracegen/panic.cpp b/src/tools/tracegen/panic.cpp
new file mode 100644
index 0000000000..d1e207764e
--- /dev/null
+++ b/src/tools/tracegen/panic.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "panic.h"
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+
+void panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "tracegen: fatal: ");
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ fputc('\n', stderr);
+
+ exit(EXIT_FAILURE);
+}
diff --git a/src/tools/tracegen/panic.h b/src/tools/tracegen/panic.h
new file mode 100644
index 0000000000..c6b195af00
--- /dev/null
+++ b/src/tools/tracegen/panic.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PANIC_H
+#define PANIC_H
+
+void panic(const char *fmt, ...);
+
+#endif // PANIC_H
diff --git a/src/tools/tracegen/provider.cpp b/src/tools/tracegen/provider.cpp
new file mode 100644
index 0000000000..00e105377e
--- /dev/null
+++ b/src/tools/tracegen/provider.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "provider.h"
+#include "panic.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <qstring.h>
+
+#ifdef TRACEGEN_DEBUG
+#include <qdebug.h>
+
+static void dumpTracepoint(const Tracepoint &t)
+{
+ qDebug() << "=== BEGIN TRACEPOINT ===";
+ qDebug() << "name:" << t.name;
+ qDebug() << "ARGS\n";
+
+ int j = 0;
+
+ for (auto i = t.args.constBegin(); i != t.args.constEnd(); ++i) {
+ qDebug() << "ARG[" << j << "] type:" << i->type;
+ qDebug() << "ARG[" << j << "] name:" << i->name;
+ qDebug() << "ARG[" << j << "] arrayLen:" << i->arrayLen;
+ ++j;
+ }
+
+ qDebug() << "\nFIELDS\n";
+
+ j = 0;
+
+ for (auto i = t.fields.constBegin(); i != t.fields.constEnd(); ++i) {
+ qDebug() << "FIELD[" << j << "] backend_type" << static_cast<int>(i->backendType);
+ qDebug() << "FIELD[" << j << "] param_type" << i->paramType;
+ qDebug() << "FIELD[" << j << "] name" << i->name;
+ qDebug() << "FIELD[" << j << "] arrayLen" << i->arrayLen;
+ qDebug() << "FIELD[" << j << "] seqLen" << i->seqLen;
+ ++j;
+ }
+
+ qDebug() << "=== END TRACEPOINT ===\n";
+
+}
+#endif
+
+static inline int arrayLength(const QString &rawType)
+{
+ /* matches the length of an ordinary array type
+ * Ex: foo[10] yields '10'
+ */
+ static const QRegExp rx(QStringLiteral(".*\\[([0-9]+)\\].*"));
+
+ if (!rx.exactMatch(rawType.trimmed()))
+ return 0;
+
+ return rx.cap(1).toInt();
+}
+
+static inline QString sequenceLength(const QString &rawType)
+{
+ /* matches the identifier pointing to length of a CTF sequence type, which is
+ * a dynamic sized array.
+ * Ex: in qcoreapplication_foo(const char[len], some_string, unsigned int, * len)
+ * it will match the 'len' part of 'const char[len]')
+ */
+ static const QRegExp rx(QStringLiteral(".*\\[([A-Za-z_][A-Za-z_0-9]*)\\].*"));
+
+ if (!rx.exactMatch(rawType.trimmed()))
+ return QString();
+
+ return rx.cap(1);
+}
+
+static QString decayArrayToPointer(QString type)
+{
+ /* decays an array to a pointer, i.e., if 'type' holds int[10],
+ * this function returns 'int *'
+ */
+ static QRegExp rx(QStringLiteral("\\[(.+)\\]"));
+
+ rx.setMinimal(true);
+ return type.replace(rx, QStringLiteral("*"));
+}
+
+static QString removeBraces(QString type)
+{
+ static const QRegExp rx(QStringLiteral("\\[.*\\]"));
+
+ return type.remove(rx);
+}
+
+static Tracepoint::Field::BackendType backendType(QString rawType)
+{
+ static const struct {
+ const char *type;
+ Tracepoint::Field::BackendType backendType;
+ } typeTable[] = {
+ { "bool", Tracepoint::Field::Integer },
+ { "short_int", Tracepoint::Field::Integer },
+ { "signed_short", Tracepoint::Field::Integer },
+ { "signed_short_int", Tracepoint::Field::Integer },
+ { "unsigned_short", Tracepoint::Field::Integer },
+ { "unsigned_short_int", Tracepoint::Field::Integer },
+ { "int", Tracepoint::Field::Integer },
+ { "signed", Tracepoint::Field::Integer },
+ { "signed_int", Tracepoint::Field::Integer },
+ { "unsigned", Tracepoint::Field::Integer },
+ { "unsigned_int", Tracepoint::Field::Integer },
+ { "long", Tracepoint::Field::Integer },
+ { "long_int", Tracepoint::Field::Integer },
+ { "signed_long", Tracepoint::Field::Integer },
+ { "signed_long_int", Tracepoint::Field::Integer },
+ { "unsigned_long", Tracepoint::Field::Integer },
+ { "unsigned_long_int", Tracepoint::Field::Integer },
+ { "long_long", Tracepoint::Field::Integer },
+ { "long_long_int", Tracepoint::Field::Integer },
+ { "signed_long_long", Tracepoint::Field::Integer },
+ { "signed_long_long_int", Tracepoint::Field::Integer },
+ { "unsigned_long_long", Tracepoint::Field::Integer },
+ { "char", Tracepoint::Field::Integer },
+ { "float", Tracepoint::Field::Float },
+ { "double", Tracepoint::Field::Float },
+ { "long_double", Tracepoint::Field::Float },
+ { "char_ptr", Tracepoint::Field::String },
+ { "QString", Tracepoint::Field::QtString },
+ { "QByteArray", Tracepoint::Field::QtByteArray },
+ { "QUrl", Tracepoint::Field::QtUrl },
+ { "QRect", Tracepoint::Field::QtRect }
+ };
+
+ auto backendType = [](const QString &rawType) {
+
+ static const size_t tableSize = sizeof (typeTable) / sizeof (typeTable[0]);
+
+ for (size_t i = 0; i < tableSize; ++i) {
+ if (rawType == QLatin1String(typeTable[i].type))
+ return typeTable[i].backendType;
+ }
+
+ return Tracepoint::Field::Unknown;
+ };
+
+ if (arrayLength(rawType) > 0)
+ return Tracepoint::Field::Array;
+
+ if (!sequenceLength(rawType).isNull())
+ return Tracepoint::Field::Sequence;
+
+ static const QRegExp constMatch(QStringLiteral("\\bconst\\b"));
+ rawType.remove(constMatch);
+ rawType.remove(QLatin1Char('&'));
+
+ static const QRegExp ptrMatch(QStringLiteral("\\s*\\*\\s*"));
+ rawType.replace(ptrMatch, QStringLiteral("_ptr"));
+ rawType = rawType.trimmed();
+ rawType.replace(QStringLiteral(" "), QStringLiteral("_"));
+
+ return backendType(rawType.trimmed());
+}
+
+static Tracepoint parseTracepoint(const QString &name, const QStringList &args,
+ const QString &fileName, const int lineNumber)
+{
+ Tracepoint t;
+ t.name = name;
+
+ if (args.isEmpty())
+ return t;
+
+ auto i = args.constBegin();
+ auto end = args.constEnd();
+ int argc = 0;
+
+ static const QRegExp rx(QStringLiteral("(.*)\\b([A-Za-z_][A-Za-z0-9_]*)$"));
+
+ while (i != end) {
+ rx.exactMatch(*i);
+
+ const QString type = rx.cap(1).trimmed();
+
+ if (type.isNull()) {
+ panic("Missing parameter type for argument %d of %s (%s:%d)",
+ argc, qPrintable(name), qPrintable(fileName), lineNumber);
+ }
+
+ const QString name = rx.cap(2).trimmed();
+
+ if (name.isNull()) {
+ panic("Missing parameter name for argument %d of %s (%s:%d)",
+ argc, qPrintable(name), qPrintable(fileName), lineNumber);
+ }
+
+ int arrayLen = arrayLength(type);
+
+ Tracepoint::Argument a;
+ a.arrayLen = arrayLen;
+ a.name = name;
+ a.type = decayArrayToPointer(type);
+
+ t.args << std::move(a);
+
+ Tracepoint::Field f;
+ f.backendType = backendType(type);
+ f.paramType = removeBraces(type);
+ f.name = name;
+ f.arrayLen = arrayLen;
+ f.seqLen = sequenceLength(type);
+
+ t.fields << std::move(f);
+
+ ++i;
+ }
+
+ return t;
+}
+
+Provider parseProvider(const QString &filename)
+{
+ QFile f(filename);
+
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ panic("Cannot open %s: %s", qPrintable(filename), qPrintable(f.errorString()));
+
+ QTextStream s(&f);
+
+ static const QRegExp tracedef(QStringLiteral("([A-Za-z][A-Za-z0-9_]*)\\((.*)\\)"));
+
+ int lineNumber = 0;
+
+ Provider provider;
+ provider.name = QFileInfo(filename).baseName();
+
+ for (;;) {
+ QString line = s.readLine().trimmed();
+
+ if (line.isNull())
+ break;
+
+ if (line.isEmpty() || line.startsWith(QStringLiteral("#"))) {
+ ++lineNumber;
+ continue;
+ }
+
+ if (tracedef.exactMatch(line)) {
+ const QString name = tracedef.cap(1);
+ QStringList args = tracedef.cap(2).split(QStringLiteral(","), QString::SkipEmptyParts);
+
+ if (args.at(0).isNull())
+ args.clear();
+
+ provider.tracepoints << parseTracepoint(name, args, filename, lineNumber);
+ } else {
+ panic("Syntax error whilre processing %s on line %d", qPrintable(filename), lineNumber);
+ }
+
+ ++lineNumber;
+ }
+
+#ifdef TRACEGEN_DEBUG
+ for (auto i = provider.tracepoints.constBegin(); i != provider.tracepoints.constEnd(); ++i)
+ dumpTracepoint(*i);
+#endif
+
+ return provider;
+}
diff --git a/src/tools/tracegen/provider.h b/src/tools/tracegen/provider.h
new file mode 100644
index 0000000000..d8cbd2662d
--- /dev/null
+++ b/src/tools/tracegen/provider.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROVIDER_H
+#define PROVIDER_H
+
+#include <qvector.h>
+#include <qstring.h>
+#include <qtypeinfo.h>
+
+struct Tracepoint
+{
+ struct Argument
+ {
+ QString type;
+ QString name;
+ int arrayLen;
+ };
+
+ struct Field
+ {
+ enum BackendType {
+ Array,
+ Sequence,
+ Integer,
+ Float,
+ String,
+ QtString,
+ QtByteArray,
+ QtUrl,
+ QtRect,
+ Unknown
+ };
+
+ BackendType backendType;
+ QString paramType;
+ QString name;
+ int arrayLen;
+ QString seqLen;
+ };
+
+ QString name;
+ QVector<Argument> args;
+ QVector<Field> fields;
+};
+
+struct Provider
+{
+ QString name;
+ QVector<Tracepoint> tracepoints;
+};
+
+Provider parseProvider(const QString &filename);
+
+Q_DECLARE_TYPEINFO(Tracepoint::Argument, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(Tracepoint::Field, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(Tracepoint, Q_MOVABLE_TYPE);
+
+#endif // PROVIDER_H
diff --git a/src/tools/tracegen/qtheaders.cpp b/src/tools/tracegen/qtheaders.cpp
new file mode 100644
index 0000000000..eec3488a6d
--- /dev/null
+++ b/src/tools/tracegen/qtheaders.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtheaders.h"
+
+const char *qtHeaders()
+{
+ static const char headers[] = ""
+ "#include <QString>\n"
+ "#include <QByteArray>\n"
+ "#include <QUrl>\n"
+ "#include <QRect>\n";
+
+ return headers;
+}
diff --git a/src/tools/tracegen/qtheaders.h b/src/tools/tracegen/qtheaders.h
new file mode 100644
index 0000000000..b80d374ca8
--- /dev/null
+++ b/src/tools/tracegen/qtheaders.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTHEADERS_H
+#define QTHEADERS_H
+
+const char *qtHeaders();
+
+#endif // QTHEADERS_H
diff --git a/src/tools/tracegen/tracegen.cpp b/src/tools/tracegen/tracegen.cpp
new file mode 100644
index 0000000000..978fe406d0
--- /dev/null
+++ b/src/tools/tracegen/tracegen.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "provider.h"
+#include "lttng.h"
+#include "etw.h"
+#include "panic.h"
+
+#include <qstring.h>
+#include <qfile.h>
+
+enum class Target
+{
+ LTTNG,
+ ETW
+};
+
+static inline void usage(int status)
+{
+ printf("Usage: tracegen <lttng|etw> <input file> <output file>\n");
+ exit(status);
+}
+
+static void parseArgs(int argc, char *argv[], Target *target, QString *inFile, QString *outFile)
+{
+ if (argc == 1)
+ usage(EXIT_SUCCESS);
+ if (argc != 4)
+ usage(EXIT_FAILURE);
+
+ const char *targetString = argv[1];
+
+ if (qstrcmp(targetString, "lttng") == 0) {
+ *target = Target::LTTNG;
+ } else if (qstrcmp(targetString, "etw") == 0) {
+ *target = Target::ETW;
+ } else {
+ fprintf(stderr, "Invalid target: %s\n", targetString);
+ usage(EXIT_FAILURE);
+ }
+
+ *inFile = QLatin1String(argv[2]);
+ *outFile = QLatin1String(argv[3]);
+}
+
+int main(int argc, char *argv[])
+{
+ Target target = Target::LTTNG;
+ QString inFile;
+ QString outFile;
+
+ parseArgs(argc, argv, &target, &inFile, &outFile);
+
+ Provider p = parseProvider(inFile);
+
+ QFile out(outFile);
+
+ if (!out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ panic("Cannot open '%s' for writing: %s",
+ qPrintable(outFile), qPrintable(out.errorString()));
+ }
+
+ switch (target) {
+ case Target::LTTNG:
+ writeLttng(out, p);
+ break;
+ case Target::ETW:
+ writeEtw(out, p);
+ break;
+ }
+
+ return 0;
+}
diff --git a/src/tools/tracegen/tracegen.pro b/src/tools/tracegen/tracegen.pro
new file mode 100644
index 0000000000..20f0bb2914
--- /dev/null
+++ b/src/tools/tracegen/tracegen.pro
@@ -0,0 +1,21 @@
+option(host_build)
+CONFIG += force_bootstrap
+
+SOURCES += \
+ etw.cpp \
+ helpers.cpp \
+ lttng.cpp \
+ panic.cpp \
+ provider.cpp \
+ qtheaders.cpp \
+ tracegen.cpp
+
+HEADERS += \
+ etw.h \
+ helpers.h \
+ lttng.h \
+ panic.h \
+ provider.h \
+ qtheaders.h
+
+load(qt_tool)